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