libcwdversion 2.0.0
The C++ Debugging Support Library
Loading...
Searching...
No Matches
lockable_auto_ptr.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2000-2005, 2018, 2020, 2026 Carlo Wood
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
9
10#ifndef LIBCWD_LOCKABLE_AUTO_PTR_H
11#define LIBCWD_LOCKABLE_AUTO_PTR_H
12
13// This header file is really part of libcw, and must be allowed to be used
14// without that libcwd installed or used.
15#ifndef CWDEBUG
16#ifndef LIBCWD_ASSERT
17#define LIBCWD_ASSERT(...)
18#endif
19#else // CWDEBUG
20#include "LIBCWD_ASSERT.h"
21#endif // CWDEBUG
22
23namespace libcwd {
24
25//===================================================================================================
26// class lockable_auto_ptr
27//
28// An 'auto_ptr' with lockable ownership.
29//
30// When the `lockable_auto_ptr' is not locked it behaves the same as
31// an 'auto_ptr': Ownership of the object it points to is transfered
32// when the `lockable_auto_ptr' is copied or assigned to another
33// `lockable_auto_ptr'. The object it points to is deleted when the
34// `lockable_auto_ptr' that owns it is destructed.
35//
36// When the `lockable_auto_ptr' is locked, then the ownership is
37// not transfered, but stays on the same (locked) `lockable_auto_ptr'.
38//
39
40template <class X, bool array = false> // Use array == true when `ptr' was allocated with new [].
41class lockable_auto_ptr
42{
43 using element_type = X;
44
45 private:
46 template <class Y, bool ARRAY>
47 friend class lockable_auto_ptr;
48 X* ptr_; // Pointer to object of type X, or NULL when not pointing to anything.
49 bool locked_; // Set if this lockable_auto_ptr object is locked.
50 mutable bool owner_; // Set if this lockable_auto_ptr object is the owner of the object that
51 // `ptr_' points too.
52
53 public:
54 //-----------------------------------------------------------------------------------------------
55 // Constructors
56 //
57
58 explicit lockable_auto_ptr(X* p = 0) : ptr_(p), locked_(false), owner_(p) { }
59 // Explicit constructor that creates a lockable_auto_ptr pointing to `p'.
60
61 lockable_auto_ptr(lockable_auto_ptr const& r) : ptr_(r.ptr_), locked_(false), owner_(r.owner_ && !r.locked_)
62 {
63 if (!r.locked_)
64 r.owner_ = 0;
65 }
66 // The default copy constructor.
67
68 template <class Y>
69 lockable_auto_ptr(lockable_auto_ptr<Y, array> const& r) : ptr_(r.ptr_), locked_(false), owner_(r.owner_ && !r.locked_)
70 {
71 if (!r.locked_)
72 r.owner_ = 0;
73 }
74 // Constructor to copy a lockable_auto_ptr that point to an object derived from X.
75
76 //-----------------------------------------------------------------------------------------------
77 // Operators
78 //
79
80 template <class Y>
81 lockable_auto_ptr& operator=(lockable_auto_ptr<Y, array> const& r);
82
83 lockable_auto_ptr& operator=(lockable_auto_ptr const& r) { return operator= <X>(r); }
84 // The default assignment operator.
85
86 //-----------------------------------------------------------------------------------------------
87 // Destructor
88 //
89
90 ~lockable_auto_ptr()
91 {
92 if (owner_)
93 {
94 if (array)
95 delete[] ptr_;
96 else
97 delete ptr_;
98 }
99 }
100
101 //-----------------------------------------------------------------------------------------------
102 // Accessors
103 //
104
105 X& operator*() const { return *ptr_; }
106 // Access the object that this `lockable_auto_ptr' points to.
107
108 X* operator->() const { return ptr_; }
109 // Access the object that this `lockable_auto_ptr' points to.
110
111 X* get() const { return ptr_; }
112 // Return the pointer itself.
113
114 bool strict_owner() const
115 {
116 LIBCWD_ASSERT(is_owner());
117 return locked_;
118 }
119 // Returns `true' when this object is the strict owner.
120 // You should only call this when this object is the owner.
121
122#ifdef CWDEBUG
123 bool is_owner() const { return owner_; }
124 // Don't use this except for debug testing.
125#endif
126
127 //-----------------------------------------------------------------------------------------------
128 // Manipulators
129 //
130
131 void reset()
132 {
133 bool owns = owner_;
134 owner_ = 0;
135 if (owns)
136 {
137 if (array)
138 delete[] ptr_;
139 else
140 delete ptr_;
141 }
142 ptr_ = NULL;
143 }
144 // Get rid of object, if any.
145
146 X* release() const
147 {
148 LIBCWD_ASSERT(is_owner());
149 owner_ = 0;
150 return ptr_;
151 }
152 // Release this object of its ownership (the caller is now responsible for deleting it if
153 // this object was the owner). You should only call this when this object is the owner.
154
155 void lock()
156 {
157 LIBCWD_ASSERT(is_owner());
158 locked_ = true;
159 }
160 // Lock the ownership.
161 // You should only call this when this object is the owner.
162
163 void unlock() { locked_ = false; }
164 // Unlock the ownership (if any).
165};
166
167template <class X, bool array>
168template <class Y>
169lockable_auto_ptr<X, array>& lockable_auto_ptr<X, array>::operator=(lockable_auto_ptr<Y, array> const& r)
170{
171 if ((void*)&r != (void*)this)
172 {
173 if (owner_)
174 {
175 if (array)
176 delete[] ptr_;
177 else
178 delete ptr_;
179 }
180 ptr_ = r.ptr_;
181 if (r.locked_)
182 owner_ = 0;
183 else
184 {
185 owner_ = r.owner_;
186 r.owner_ = 0;
187 }
188 }
189 return *this;
190}
191
192} // namespace libcwd
193
194#endif // LIBCWD_LOCKABLE_AUTO_PTR_H
namespace for libcwd.