]>
Commit | Line | Data |
---|---|---|
5b9daa7e | 1 | // shared_ptr and weak_ptr implementation -*- C++ -*- |
b758b22a | 2 | |
ab65a4c7 | 3 | // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
b758b22a BK |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free | |
6 | // software; you can redistribute it and/or modify it under the | |
7 | // terms of the GNU General Public License as published by the | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
b758b22a BK |
9 | // any later version. |
10 | ||
11 | // This library is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | ||
748086b7 JJ |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
b758b22a | 24 | |
8e32aa11 BK |
25 | // GCC Note: Based on files from version 1.32.0 of the Boost library. |
26 | ||
b758b22a BK |
27 | // shared_count.hpp |
28 | // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. | |
29 | ||
30 | // shared_ptr.hpp | |
31 | // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes. | |
32 | // Copyright (C) 2001, 2002, 2003 Peter Dimov | |
33 | ||
34 | // weak_ptr.hpp | |
35 | // Copyright (C) 2001, 2002, 2003 Peter Dimov | |
36 | ||
37 | // enable_shared_from_this.hpp | |
38 | // Copyright (C) 2002 Peter Dimov | |
39 | ||
40 | // Distributed under the Boost Software License, Version 1.0. (See | |
41 | // accompanying file LICENSE_1_0.txt or copy at | |
42 | // http://www.boost.org/LICENSE_1_0.txt) | |
43 | ||
640cbe76 | 44 | /** @file bits/shared_ptr.h |
b758b22a | 45 | * This is an internal header file, included by other library headers. |
f910786b | 46 | * Do not attempt to use it directly. @headername{memory} |
b758b22a BK |
47 | */ |
48 | ||
32fdf2f4 JW |
49 | #ifndef _SHARED_PTR_H |
50 | #define _SHARED_PTR_H 1 | |
51 | ||
8e32aa11 | 52 | #include <bits/shared_ptr_base.h> |
aaf0ca6f | 53 | |
12ffa228 BK |
54 | namespace std _GLIBCXX_VISIBILITY(default) |
55 | { | |
56 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
5b9daa7e BK |
57 | |
58 | /** | |
59 | * @addtogroup pointer_abstractions | |
60 | * @{ | |
61 | */ | |
62 | ||
8e32aa11 BK |
63 | /// 2.2.3.7 shared_ptr I/O |
64 | template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp> | |
d779a591 | 65 | inline std::basic_ostream<_Ch, _Tr>& |
8e32aa11 BK |
66 | operator<<(std::basic_ostream<_Ch, _Tr>& __os, |
67 | const __shared_ptr<_Tp, _Lp>& __p) | |
a25ce4db | 68 | { |
8e32aa11 BK |
69 | __os << __p.get(); |
70 | return __os; | |
a25ce4db | 71 | } |
459f9f82 | 72 | |
8e32aa11 BK |
73 | /// 2.2.3.10 shared_ptr get_deleter (experimental) |
74 | template<typename _Del, typename _Tp, _Lock_policy _Lp> | |
75 | inline _Del* | |
76 | get_deleter(const __shared_ptr<_Tp, _Lp>& __p) | |
70826946 JW |
77 | { |
78 | #ifdef __GXX_RTTI | |
79 | return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del))); | |
80 | #else | |
81 | return 0; | |
82 | #endif | |
83 | } | |
b758b22a | 84 | |
a15024e6 | 85 | |
8e32aa11 BK |
86 | /** |
87 | * @brief A smart pointer with reference-counted copy semantics. | |
88 | * | |
89 | * The object pointed to is deleted when the last shared_ptr pointing to | |
90 | * it is destroyed or reset. | |
91 | */ | |
c8bd30dd | 92 | template<typename _Tp> |
8e32aa11 | 93 | class shared_ptr : public __shared_ptr<_Tp> |
459f9f82 | 94 | { |
459f9f82 | 95 | public: |
8e32aa11 BK |
96 | /** |
97 | * @brief Construct an empty %shared_ptr. | |
459f9f82 PC |
98 | * @post use_count()==0 && get()==0 |
99 | */ | |
be9d3d73 PC |
100 | constexpr shared_ptr() |
101 | : __shared_ptr<_Tp>() { } | |
b758b22a | 102 | |
8e32aa11 BK |
103 | /** |
104 | * @brief Construct a %shared_ptr that owns the pointer @a __p. | |
c8bd30dd PC |
105 | * @param __p A pointer that is convertible to element_type*. |
106 | * @post use_count() == 1 && get() == __p | |
107 | * @throw std::bad_alloc, in which case @c delete @a __p is called. | |
459f9f82 PC |
108 | */ |
109 | template<typename _Tp1> | |
be9d3d73 PC |
110 | explicit shared_ptr(_Tp1* __p) |
111 | : __shared_ptr<_Tp>(__p) { } | |
b758b22a | 112 | |
8e32aa11 BK |
113 | /** |
114 | * @brief Construct a %shared_ptr that owns the pointer @a __p | |
c8bd30dd PC |
115 | * and the deleter @a __d. |
116 | * @param __p A pointer. | |
117 | * @param __d A deleter. | |
118 | * @post use_count() == 1 && get() == __p | |
119 | * @throw std::bad_alloc, in which case @a __d(__p) is called. | |
8e32aa11 BK |
120 | * |
121 | * Requirements: _Deleter's copy constructor and destructor must | |
122 | * not throw | |
123 | * | |
124 | * __shared_ptr will release __p by calling __d(__p) | |
459f9f82 | 125 | */ |
d779a591 | 126 | template<typename _Tp1, typename _Deleter> |
403b89a8 PC |
127 | shared_ptr(_Tp1* __p, _Deleter __d) |
128 | : __shared_ptr<_Tp>(__p, __d) { } | |
8e32aa11 | 129 | |
6d00745b JW |
130 | /** |
131 | * @brief Construct a %shared_ptr that owns a null pointer | |
132 | * and the deleter @a __d. | |
133 | * @param __p A null pointer constant. | |
134 | * @param __d A deleter. | |
135 | * @post use_count() == 1 && get() == __p | |
136 | * @throw std::bad_alloc, in which case @a __d(__p) is called. | |
137 | * | |
138 | * Requirements: _Deleter's copy constructor and destructor must | |
139 | * not throw | |
140 | * | |
141 | * The last owner will call __d(__p) | |
142 | */ | |
143 | template<typename _Deleter> | |
144 | shared_ptr(nullptr_t __p, _Deleter __d) | |
145 | : __shared_ptr<_Tp>(__p, __d) { } | |
146 | ||
8e32aa11 BK |
147 | /** |
148 | * @brief Construct a %shared_ptr that owns the pointer @a __p | |
aaf0ca6f JW |
149 | * and the deleter @a __d. |
150 | * @param __p A pointer. | |
151 | * @param __d A deleter. | |
152 | * @param __a An allocator. | |
153 | * @post use_count() == 1 && get() == __p | |
154 | * @throw std::bad_alloc, in which case @a __d(__p) is called. | |
8e32aa11 BK |
155 | * |
156 | * Requirements: _Deleter's copy constructor and destructor must | |
157 | * not throw _Alloc's copy constructor and destructor must not | |
158 | * throw. | |
159 | * | |
160 | * __shared_ptr will release __p by calling __d(__p) | |
aaf0ca6f JW |
161 | */ |
162 | template<typename _Tp1, typename _Deleter, typename _Alloc> | |
403b89a8 PC |
163 | shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a) |
164 | : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } | |
8e32aa11 | 165 | |
6d00745b JW |
166 | /** |
167 | * @brief Construct a %shared_ptr that owns a null pointer | |
168 | * and the deleter @a __d. | |
169 | * @param __p A null pointer constant. | |
170 | * @param __d A deleter. | |
171 | * @param __a An allocator. | |
172 | * @post use_count() == 1 && get() == __p | |
173 | * @throw std::bad_alloc, in which case @a __d(__p) is called. | |
174 | * | |
175 | * Requirements: _Deleter's copy constructor and destructor must | |
176 | * not throw _Alloc's copy constructor and destructor must not | |
177 | * throw. | |
178 | * | |
179 | * The last owner will call __d(__p) | |
180 | */ | |
181 | template<typename _Deleter, typename _Alloc> | |
403b89a8 PC |
182 | shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a) |
183 | : __shared_ptr<_Tp>(__p, __d, std::move(__a)) { } | |
6d00745b | 184 | |
8e32aa11 | 185 | // Aliasing constructor |
aaf0ca6f | 186 | |
8e32aa11 BK |
187 | /** |
188 | * @brief Constructs a %shared_ptr instance that stores @a __p | |
aaf0ca6f | 189 | * and shares ownership with @a __r. |
8e32aa11 | 190 | * @param __r A %shared_ptr. |
aaf0ca6f JW |
191 | * @param __p A pointer that will remain valid while @a *__r is valid. |
192 | * @post get() == __p && use_count() == __r.use_count() | |
193 | * | |
194 | * This can be used to construct a @c shared_ptr to a sub-object | |
195 | * of an object managed by an existing @c shared_ptr. | |
196 | * | |
197 | * @code | |
198 | * shared_ptr< pair<int,int> > pii(new pair<int,int>()); | |
199 | * shared_ptr<int> pi(pii, &pii->first); | |
200 | * assert(pii.use_count() == 2); | |
201 | * @endcode | |
202 | */ | |
203 | template<typename _Tp1> | |
8e32aa11 BK |
204 | shared_ptr(const shared_ptr<_Tp1>& __r, _Tp* __p) |
205 | : __shared_ptr<_Tp>(__r, __p) { } | |
206 | ||
207 | /** | |
208 | * @brief If @a __r is empty, constructs an empty %shared_ptr; | |
209 | * otherwise construct a %shared_ptr that shares ownership | |
c8bd30dd | 210 | * with @a __r. |
8e32aa11 | 211 | * @param __r A %shared_ptr. |
c8bd30dd | 212 | * @post get() == __r.get() && use_count() == __r.use_count() |
459f9f82 | 213 | */ |
5aadb69b PC |
214 | template<typename _Tp1, typename = typename |
215 | std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> | |
216 | shared_ptr(const shared_ptr<_Tp1>& __r) | |
217 | : __shared_ptr<_Tp>(__r) { } | |
459f9f82 | 218 | |
8e32aa11 BK |
219 | /** |
220 | * @brief Move-constructs a %shared_ptr instance from @a __r. | |
221 | * @param __r A %shared_ptr rvalue. | |
aaf0ca6f JW |
222 | * @post *this contains the old value of @a __r, @a __r is empty. |
223 | */ | |
8e32aa11 BK |
224 | shared_ptr(shared_ptr&& __r) |
225 | : __shared_ptr<_Tp>(std::move(__r)) { } | |
aaf0ca6f | 226 | |
8e32aa11 BK |
227 | /** |
228 | * @brief Move-constructs a %shared_ptr instance from @a __r. | |
229 | * @param __r A %shared_ptr rvalue. | |
aaf0ca6f JW |
230 | * @post *this contains the old value of @a __r, @a __r is empty. |
231 | */ | |
5aadb69b PC |
232 | template<typename _Tp1, typename = typename |
233 | std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> | |
8e32aa11 BK |
234 | shared_ptr(shared_ptr<_Tp1>&& __r) |
235 | : __shared_ptr<_Tp>(std::move(__r)) { } | |
236 | ||
237 | /** | |
238 | * @brief Constructs a %shared_ptr that shares ownership with @a __r | |
c8bd30dd PC |
239 | * and stores a copy of the pointer stored in @a __r. |
240 | * @param __r A weak_ptr. | |
241 | * @post use_count() == __r.use_count() | |
242 | * @throw bad_weak_ptr when __r.expired(), | |
459f9f82 PC |
243 | * in which case the constructor has no effect. |
244 | */ | |
245 | template<typename _Tp1> | |
8e32aa11 | 246 | explicit shared_ptr(const weak_ptr<_Tp1>& __r) |
459f9f82 | 247 | : __shared_ptr<_Tp>(__r) { } |
c8bd30dd | 248 | |
640cbe76 | 249 | #if _GLIBCXX_DEPRECATED |
459f9f82 | 250 | template<typename _Tp1> |
8e32aa11 | 251 | shared_ptr(std::auto_ptr<_Tp1>&& __r) |
640cbe76 | 252 | : __shared_ptr<_Tp>(std::move(__r)) { } |
40abbf1f | 253 | #endif |
459f9f82 | 254 | |
640cbe76 | 255 | template<typename _Tp1, typename _Del> |
28de604e | 256 | shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r) |
640cbe76 | 257 | : __shared_ptr<_Tp>(std::move(__r)) { } |
459f9f82 | 258 | |
6d00745b JW |
259 | /** |
260 | * @brief Construct an empty %shared_ptr. | |
261 | * @param __p A null pointer constant. | |
262 | * @post use_count() == 0 && get() == nullptr | |
263 | */ | |
be9d3d73 PC |
264 | constexpr shared_ptr(nullptr_t __p) |
265 | : __shared_ptr<_Tp>(__p) { } | |
6d00745b | 266 | |
459f9f82 | 267 | template<typename _Tp1> |
8e32aa11 BK |
268 | shared_ptr& |
269 | operator=(const shared_ptr<_Tp1>& __r) // never throws | |
270 | { | |
459f9f82 PC |
271 | this->__shared_ptr<_Tp>::operator=(__r); |
272 | return *this; | |
273 | } | |
a25ce4db | 274 | |
640cbe76 | 275 | #if _GLIBCXX_DEPRECATED |
459f9f82 | 276 | template<typename _Tp1> |
8e32aa11 BK |
277 | shared_ptr& |
278 | operator=(std::auto_ptr<_Tp1>&& __r) | |
279 | { | |
640cbe76 | 280 | this->__shared_ptr<_Tp>::operator=(std::move(__r)); |
459f9f82 PC |
281 | return *this; |
282 | } | |
40abbf1f | 283 | #endif |
aaf0ca6f | 284 | |
aaf0ca6f JW |
285 | shared_ptr& |
286 | operator=(shared_ptr&& __r) | |
287 | { | |
8e32aa11 BK |
288 | this->__shared_ptr<_Tp>::operator=(std::move(__r)); |
289 | return *this; | |
aaf0ca6f | 290 | } |
8e32aa11 | 291 | |
aaf0ca6f | 292 | template<class _Tp1> |
8e32aa11 BK |
293 | shared_ptr& |
294 | operator=(shared_ptr<_Tp1>&& __r) | |
295 | { | |
296 | this->__shared_ptr<_Tp>::operator=(std::move(__r)); | |
297 | return *this; | |
298 | } | |
aaf0ca6f | 299 | |
640cbe76 | 300 | template<typename _Tp1, typename _Del> |
8e32aa11 BK |
301 | shared_ptr& |
302 | operator=(std::unique_ptr<_Tp1, _Del>&& __r) | |
303 | { | |
640cbe76 JW |
304 | this->__shared_ptr<_Tp>::operator=(std::move(__r)); |
305 | return *this; | |
306 | } | |
307 | ||
aaf0ca6f JW |
308 | private: |
309 | // This constructor is non-standard, it is used by allocate_shared. | |
310 | template<typename _Alloc, typename... _Args> | |
403b89a8 PC |
311 | shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a, |
312 | _Args&&... __args) | |
8e32aa11 BK |
313 | : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...) |
314 | { } | |
aaf0ca6f JW |
315 | |
316 | template<typename _Tp1, typename _Alloc, typename... _Args> | |
8e32aa11 | 317 | friend shared_ptr<_Tp1> |
403b89a8 | 318 | allocate_shared(const _Alloc& __a, _Args&&... __args); |
459f9f82 | 319 | }; |
b758b22a | 320 | |
8dd5e93a JW |
321 | // 20.8.13.2.7 shared_ptr comparisons |
322 | template<typename _Tp1, typename _Tp2> | |
323 | inline bool | |
324 | operator==(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) | |
325 | { return __a.get() == __b.get(); } | |
326 | ||
3abeaf8f PC |
327 | template<typename _Tp> |
328 | inline bool | |
329 | operator==(const shared_ptr<_Tp>& __a, nullptr_t) | |
330 | { return __a.get() == nullptr; } | |
331 | ||
332 | template<typename _Tp> | |
333 | inline bool | |
334 | operator==(nullptr_t, const shared_ptr<_Tp>& __b) | |
335 | { return nullptr == __b.get(); } | |
336 | ||
8dd5e93a JW |
337 | template<typename _Tp1, typename _Tp2> |
338 | inline bool | |
339 | operator!=(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) | |
340 | { return __a.get() != __b.get(); } | |
341 | ||
3abeaf8f PC |
342 | template<typename _Tp> |
343 | inline bool | |
344 | operator!=(const shared_ptr<_Tp>& __a, nullptr_t) | |
345 | { return __a.get() != nullptr; } | |
346 | ||
347 | template<typename _Tp> | |
348 | inline bool | |
349 | operator!=(nullptr_t, const shared_ptr<_Tp>& __b) | |
350 | { return nullptr != __b.get(); } | |
351 | ||
8dd5e93a JW |
352 | template<typename _Tp1, typename _Tp2> |
353 | inline bool | |
354 | operator<(const shared_ptr<_Tp1>& __a, const shared_ptr<_Tp2>& __b) | |
355 | { return __a.get() < __b.get(); } | |
356 | ||
357 | template<typename _Tp> | |
8e32aa11 | 358 | struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>> |
8dd5e93a JW |
359 | { }; |
360 | ||
361 | // 20.8.13.2.9 shared_ptr specialized algorithms. | |
640cbe76 JW |
362 | template<typename _Tp> |
363 | inline void | |
8dd5e93a | 364 | swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) |
640cbe76 JW |
365 | { __a.swap(__b); } |
366 | ||
8dd5e93a | 367 | // 20.8.13.2.10 shared_ptr casts. |
c8bd30dd | 368 | template<typename _Tp, typename _Tp1> |
aaf0ca6f | 369 | inline shared_ptr<_Tp> |
c8bd30dd | 370 | static_pointer_cast(const shared_ptr<_Tp1>& __r) |
640cbe76 | 371 | { return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get())); } |
c8bd30dd PC |
372 | |
373 | template<typename _Tp, typename _Tp1> | |
aaf0ca6f | 374 | inline shared_ptr<_Tp> |
c8bd30dd | 375 | const_pointer_cast(const shared_ptr<_Tp1>& __r) |
640cbe76 | 376 | { return shared_ptr<_Tp>(__r, const_cast<_Tp*>(__r.get())); } |
c8bd30dd PC |
377 | |
378 | template<typename _Tp, typename _Tp1> | |
aaf0ca6f | 379 | inline shared_ptr<_Tp> |
c8bd30dd | 380 | dynamic_pointer_cast(const shared_ptr<_Tp1>& __r) |
aaf0ca6f | 381 | { |
aaf0ca6f | 382 | if (_Tp* __p = dynamic_cast<_Tp*>(__r.get())) |
8e32aa11 | 383 | return shared_ptr<_Tp>(__r, __p); |
aaf0ca6f | 384 | return shared_ptr<_Tp>(); |
aaf0ca6f | 385 | } |
c8bd30dd PC |
386 | |
387 | ||
8e32aa11 BK |
388 | /** |
389 | * @brief A smart pointer with weak semantics. | |
390 | * | |
5b9daa7e BK |
391 | * With forwarding constructors and assignment operators. |
392 | */ | |
c8bd30dd | 393 | template<typename _Tp> |
8e32aa11 | 394 | class weak_ptr : public __weak_ptr<_Tp> |
c8bd30dd PC |
395 | { |
396 | public: | |
be9d3d73 PC |
397 | constexpr weak_ptr() |
398 | : __weak_ptr<_Tp>() { } | |
8e32aa11 | 399 | |
5aadb69b PC |
400 | template<typename _Tp1, typename = typename |
401 | std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> | |
8e32aa11 | 402 | weak_ptr(const weak_ptr<_Tp1>& __r) |
c8bd30dd PC |
403 | : __weak_ptr<_Tp>(__r) { } |
404 | ||
5aadb69b PC |
405 | template<typename _Tp1, typename = typename |
406 | std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type> | |
8e32aa11 | 407 | weak_ptr(const shared_ptr<_Tp1>& __r) |
c8bd30dd PC |
408 | : __weak_ptr<_Tp>(__r) { } |
409 | ||
410 | template<typename _Tp1> | |
8e32aa11 BK |
411 | weak_ptr& |
412 | operator=(const weak_ptr<_Tp1>& __r) // never throws | |
413 | { | |
c8bd30dd PC |
414 | this->__weak_ptr<_Tp>::operator=(__r); |
415 | return *this; | |
416 | } | |
417 | ||
418 | template<typename _Tp1> | |
8e32aa11 BK |
419 | weak_ptr& |
420 | operator=(const shared_ptr<_Tp1>& __r) // never throws | |
421 | { | |
c8bd30dd PC |
422 | this->__weak_ptr<_Tp>::operator=(__r); |
423 | return *this; | |
424 | } | |
425 | ||
426 | shared_ptr<_Tp> | |
427 | lock() const // never throws | |
428 | { | |
429 | #ifdef __GTHREADS | |
430 | if (this->expired()) | |
431 | return shared_ptr<_Tp>(); | |
432 | ||
bc2631e0 | 433 | __try |
c8bd30dd PC |
434 | { |
435 | return shared_ptr<_Tp>(*this); | |
436 | } | |
bc2631e0 | 437 | __catch(const bad_weak_ptr&) |
c8bd30dd PC |
438 | { |
439 | return shared_ptr<_Tp>(); | |
440 | } | |
441 | #else | |
8e32aa11 | 442 | return this->expired() ? shared_ptr<_Tp>() : shared_ptr<_Tp>(*this); |
c8bd30dd PC |
443 | #endif |
444 | } | |
445 | }; | |
446 | ||
8dd5e93a JW |
447 | // 20.8.13.3.7 weak_ptr specialized algorithms. |
448 | template<typename _Tp> | |
449 | inline void | |
450 | swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) | |
451 | { __a.swap(__b); } | |
452 | ||
8e32aa11 BK |
453 | |
454 | /// Primary template owner_less | |
455 | template<typename _Tp> | |
456 | struct owner_less; | |
457 | ||
458 | /// Partial specialization of owner_less for shared_ptr. | |
8dd5e93a JW |
459 | template<typename _Tp> |
460 | struct owner_less<shared_ptr<_Tp>> | |
461 | : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>> | |
462 | { }; | |
463 | ||
8e32aa11 | 464 | /// Partial specialization of owner_less for weak_ptr. |
8dd5e93a JW |
465 | template<typename _Tp> |
466 | struct owner_less<weak_ptr<_Tp>> | |
467 | : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>> | |
468 | { }; | |
469 | ||
8e32aa11 | 470 | /** |
5b9daa7e BK |
471 | * @brief Base class allowing use of member function shared_from_this. |
472 | */ | |
459f9f82 | 473 | template<typename _Tp> |
c8bd30dd | 474 | class enable_shared_from_this |
459f9f82 PC |
475 | { |
476 | protected: | |
be9d3d73 | 477 | constexpr enable_shared_from_this() { } |
8e32aa11 | 478 | |
c8bd30dd PC |
479 | enable_shared_from_this(const enable_shared_from_this&) { } |
480 | ||
481 | enable_shared_from_this& | |
482 | operator=(const enable_shared_from_this&) | |
483 | { return *this; } | |
484 | ||
485 | ~enable_shared_from_this() { } | |
486 | ||
487 | public: | |
488 | shared_ptr<_Tp> | |
489 | shared_from_this() | |
490 | { return shared_ptr<_Tp>(this->_M_weak_this); } | |
491 | ||
492 | shared_ptr<const _Tp> | |
493 | shared_from_this() const | |
494 | { return shared_ptr<const _Tp>(this->_M_weak_this); } | |
495 | ||
496 | private: | |
497 | template<typename _Tp1> | |
8e32aa11 BK |
498 | void |
499 | _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const | |
500 | { _M_weak_this._M_assign(__p, __n); } | |
c8bd30dd PC |
501 | |
502 | template<typename _Tp1> | |
8e32aa11 BK |
503 | friend void |
504 | __enable_shared_from_this_helper(const __shared_count<>& __pn, | |
c8bd30dd PC |
505 | const enable_shared_from_this* __pe, |
506 | const _Tp1* __px) | |
8e32aa11 | 507 | { |
c8bd30dd PC |
508 | if (__pe != 0) |
509 | __pe->_M_weak_assign(const_cast<_Tp1*>(__px), __pn); | |
510 | } | |
511 | ||
512 | mutable weak_ptr<_Tp> _M_weak_this; | |
459f9f82 | 513 | }; |
c8bd30dd | 514 | |
8e32aa11 BK |
515 | /** |
516 | * @brief Create an object that is owned by a shared_ptr. | |
aaf0ca6f JW |
517 | * @param __a An allocator. |
518 | * @param __args Arguments for the @a _Tp object's constructor. | |
519 | * @return A shared_ptr that owns the newly created object. | |
520 | * @throw An exception thrown from @a _Alloc::allocate or from the | |
521 | * constructor of @a _Tp. | |
522 | * | |
523 | * A copy of @a __a will be used to allocate memory for the shared_ptr | |
524 | * and the new object. | |
525 | */ | |
526 | template<typename _Tp, typename _Alloc, typename... _Args> | |
527 | inline shared_ptr<_Tp> | |
403b89a8 | 528 | allocate_shared(const _Alloc& __a, _Args&&... __args) |
aaf0ca6f | 529 | { |
403b89a8 | 530 | return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a, |
8e32aa11 | 531 | std::forward<_Args>(__args)...); |
aaf0ca6f JW |
532 | } |
533 | ||
8e32aa11 BK |
534 | /** |
535 | * @brief Create an object that is owned by a shared_ptr. | |
aaf0ca6f JW |
536 | * @param __args Arguments for the @a _Tp object's constructor. |
537 | * @return A shared_ptr that owns the newly created object. | |
538 | * @throw std::bad_alloc, or an exception thrown from the | |
539 | * constructor of @a _Tp. | |
540 | */ | |
541 | template<typename _Tp, typename... _Args> | |
542 | inline shared_ptr<_Tp> | |
543 | make_shared(_Args&&... __args) | |
544 | { | |
545 | typedef typename std::remove_const<_Tp>::type _Tp_nc; | |
546 | return allocate_shared<_Tp>(std::allocator<_Tp_nc>(), | |
8e32aa11 | 547 | std::forward<_Args>(__args)...); |
aaf0ca6f | 548 | } |
aaf0ca6f | 549 | |
b0e788cc PC |
550 | /// std::hash specialization for shared_ptr. |
551 | template<typename _Tp> | |
552 | struct hash<shared_ptr<_Tp>> | |
553 | : public std::unary_function<shared_ptr<_Tp>, size_t> | |
554 | { | |
555 | size_t | |
556 | operator()(const shared_ptr<_Tp>& __s) const | |
557 | { return std::hash<_Tp*>()(__s.get()); } | |
558 | }; | |
559 | ||
5b9daa7e BK |
560 | // @} group pointer_abstractions |
561 | ||
12ffa228 BK |
562 | _GLIBCXX_END_NAMESPACE_VERSION |
563 | } // namespace | |
32fdf2f4 JW |
564 | |
565 | #endif // _SHARED_PTR_H |