Library of Assembled Shared Sources
shared_ptr.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2023 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_SHARED_PTR_H
44#define LASS_GUARDIAN_OF_INCLUSION_UTIL_SHARED_PTR_H
45
46#include "util_common.h"
47#include "smart_ptr_policies.h"
48
49namespace lass
50{
51namespace util
52{
53
54template
55<
56 typename T,
57 template <typename, typename> class StoragePolicy = ObjectStorage,
58 typename CounterPolicy = DefaultCounter
59>
60class SharedPtr: public StoragePolicy<T, CounterPolicy>
61{
62public:
63
64 typedef T TPointee;
65 typedef StoragePolicy<T, CounterPolicy> TStoragePolicy;
66 typedef CounterPolicy TCounterPolicy;
67 typedef typename TStoragePolicy::TStorage TStorage;
68 typedef typename TStoragePolicy::TPointer TPointer;
69 typedef typename TStoragePolicy::TReference TReference;
70 typedef typename TCounterPolicy::TCount TCount;
71
72 template <typename U> struct Rebind
73 {
74 typedef SharedPtr<U, StoragePolicy, CounterPolicy> Type;
75 };
76
77 SharedPtr():
78 TStoragePolicy()
79 {
80 }
81 explicit SharedPtr(TPointer p):
82 TStoragePolicy(p)
83 {
84 if (!isEmpty())
85 {
86 CounterPolicy::init(TStoragePolicy::storage());
87 }
88 }
89 SharedPtr(const SharedPtr& other):
90 TStoragePolicy(other)
91 {
92 if (!isEmpty())
93 {
94 CounterPolicy::increment(TStoragePolicy::storage());
95 }
96 }
97
98 SharedPtr(SharedPtr&& other) noexcept:
99 TStoragePolicy(std::move(other))
100 {
101 LASS_ASSERT(other.isEmpty());
102 }
103
104 template <typename U> SharedPtr(const SharedPtr<U, StoragePolicy, CounterPolicy>& other):
105 TStoragePolicy(other)
106 {
107 if (!isEmpty())
108 {
109 CounterPolicy::increment(TStoragePolicy::storage());
110 }
111 }
112
113 ~SharedPtr()
114 {
115 if (!isEmpty() && CounterPolicy::decrement(TStoragePolicy::storage()))
116 {
117 CounterPolicy::dispose(TStoragePolicy::storage());
118 TStoragePolicy::dispose();
119 }
120 }
121
122 SharedPtr& operator=(const SharedPtr& other)
123 {
124 SharedPtr temp(other);
125 swap(temp);
126 return *this;
127 }
128
129 SharedPtr& operator=(SharedPtr&& other) noexcept
130 {
131 SharedPtr temp(std::forward<SharedPtr>(other));
132 LASS_ASSERT(other.isEmpty());
133 swap(temp);
134 return *this;
135 }
136
137 void reset(TPointer p = 0)
138 {
139 SharedPtr temp(p);
140 swap(temp);
141 }
142
143 template <typename U> SharedPtr(std::unique_ptr<U>&& p) :
144 TStoragePolicy(p.get())
145 {
146 if (!isEmpty())
147 {
148 CounterPolicy::init(TStoragePolicy::storage());
149 }
150 p.release();
151 }
152 template <typename U> void reset(std::unique_ptr<U>&& p)
153 {
154 SharedPtr temp(std::forward<std::unique_ptr<U>>(p));
155 LASS_ASSERT(!p);
156 swap(temp);
157 }
158
159 void swap(SharedPtr& other)
160 {
161 TStoragePolicy::swap(other);
162 }
163
164 TPointer get() const
165 {
166 return TStoragePolicy::pointer();
167 }
168 TPointer operator->() const
169 {
170 LASS_ASSERT(get());
171 return get();
172 }
173 TReference operator*() const
174 {
175 LASS_ASSERT(get());
176 return *get();
177 }
178 TReference operator[](size_t i) const
179 {
180 LASS_ASSERT(get());
181 return TStoragePolicy::at(i);
182 }
183
184 const TCount count() const
185 {
186 return isEmpty() ? 0 : TCounterPolicy::count(TStoragePolicy::storage());
187 }
188 bool isEmpty() const
189 {
190 return TStoragePolicy::isNull();
191 }
192 bool operator!() const
193 {
194 return isEmpty();
195 }
196 explicit operator bool() const
197 {
198 return !isEmpty();
199 }
200
201 /** returns reference to storage pointer */
202 const TStorage& storage() const
203 {
204 return TStoragePolicy::storage();
205 }
206 /** returns reference to storage pointer */
207 TStorage& storage()
208 {
209 return TStoragePolicy::storage();
210 }
211
212 template <typename U>
213 const SharedPtr<U, StoragePolicy, CounterPolicy> staticCast() const
214 {
215 return SharedPtr<U, StoragePolicy, CounterPolicy>(TStoragePolicy::template staticCast<U>());
216 }
217
218 template <typename U>
219 const SharedPtr<U, StoragePolicy, CounterPolicy> dynamicCast() const
220 {
221 return SharedPtr<U, StoragePolicy, CounterPolicy>(TStoragePolicy::template dynamicCast<U>());
222 }
223
224 template <typename U>
225 const SharedPtr<U, StoragePolicy, CounterPolicy> constCast() const
226 {
227 return SharedPtr<U, StoragePolicy, CounterPolicy>(TStoragePolicy::template constCast<U>());
228 }
229
230private:
231
232 template <typename U, template <typename, typename> class S, typename C> friend class SharedPtr;
233
234 SharedPtr(const TStoragePolicy& storage):
235 TStoragePolicy(storage)
236 {
237 if (!isEmpty())
238 {
239 CounterPolicy::increment(TStoragePolicy::storage());
240 }
241 }
242};
243
244template <typename T1, template <typename, typename> class S1, typename C1, typename T2, template <typename, typename> class S2, typename C2>
245bool operator==(const SharedPtr<T1, S1, C1>& a, const SharedPtr<T2, S2, C2>& b)
246{
247 return a.get() == b.get();
248}
249
250template <typename T1, template <typename, typename> class S1, typename C1, typename T2, template <typename, typename> class S2, typename C2>
251bool operator!=(const SharedPtr<T1, S1, C1>& a, const SharedPtr<T2, S2, C2>& b)
252{
253 return !(a == b);
254}
255
256template <typename T, template <typename, typename> class S, typename C>
257bool operator==(const SharedPtr<T, S, C>& a, std::nullptr_t)
258{
259 return !a;
260}
261
262template <typename T, template <typename, typename> class S, typename C>
263bool operator!=(const SharedPtr<T, S, C>& a, std::nullptr_t)
264{
265 return static_cast<bool>(a);
266}
267
268template <typename T, template <typename, typename> class S, typename C>
269bool operator==(std::nullptr_t, const SharedPtr<T, S, C>& b)
270{
271 return !b;
272}
273
274template <typename T, template <typename, typename> class S, typename C>
275bool operator!=(std::nullptr_t, const SharedPtr<T, S, C>& b)
276{
277 return static_cast<bool>(b);
278}
279
280}
281}
282
283#endif
284
285// EOF
The default counter for the shared pointers, implementation of CounterPolicy concept.
Default storage policy for single objects, implementation of StoragePolicy concept.
general utility, debug facilities, ...
Library for Assembled Shared Sources.
Definition config.h:53