Line data Source code
1 : // shared_ptr and weak_ptr implementation -*- C++ -*-
2 :
3 : // Copyright (C) 2007-2018 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
45 : * This is an internal header file, included by other library headers.
46 : * Do not attempt to use it directly. @headername{memory}
47 : */
48 :
49 : #ifndef _SHARED_PTR_H
50 : #define _SHARED_PTR_H 1
51 :
52 : #include <bits/shared_ptr_base.h>
53 :
54 : namespace std _GLIBCXX_VISIBILITY(default)
55 : {
56 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
57 :
58 : /**
59 : * @addtogroup pointer_abstractions
60 : * @{
61 : */
62 :
63 : /// 20.7.2.2.11 shared_ptr I/O
64 : template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
65 : inline std::basic_ostream<_Ch, _Tr>&
66 : operator<<(std::basic_ostream<_Ch, _Tr>& __os,
67 : const __shared_ptr<_Tp, _Lp>& __p)
68 : {
69 : __os << __p.get();
70 : return __os;
71 : }
72 :
73 : template<typename _Del, typename _Tp, _Lock_policy _Lp>
74 : inline _Del*
75 : get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
76 : {
77 : #if __cpp_rtti
78 : return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
79 : #else
80 : return 0;
81 : #endif
82 : }
83 :
84 : /// 20.7.2.2.10 shared_ptr get_deleter
85 : template<typename _Del, typename _Tp>
86 : inline _Del*
87 : get_deleter(const shared_ptr<_Tp>& __p) noexcept
88 : {
89 : #if __cpp_rtti
90 : return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
91 : #else
92 : return 0;
93 : #endif
94 : }
95 :
96 : /**
97 : * @brief A smart pointer with reference-counted copy semantics.
98 : *
99 : * The object pointed to is deleted when the last shared_ptr pointing to
100 : * it is destroyed or reset.
101 : */
102 : template<typename _Tp>
103 724 : class shared_ptr : public __shared_ptr<_Tp>
104 : {
105 : template<typename... _Args>
106 : using _Constructible = typename enable_if<
107 : is_constructible<__shared_ptr<_Tp>, _Args...>::value
108 : >::type;
109 :
110 : template<typename _Arg>
111 : using _Assignable = typename enable_if<
112 : is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
113 : >::type;
114 :
115 : public:
116 :
117 : using element_type = typename __shared_ptr<_Tp>::element_type;
118 :
119 : #if __cplusplus > 201402L
120 : # define __cpp_lib_shared_ptr_weak_type 201606
121 : using weak_type = weak_ptr<_Tp>;
122 : #endif
123 : /**
124 : * @brief Construct an empty %shared_ptr.
125 : * @post use_count()==0 && get()==0
126 : */
127 405 : constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
128 :
129 700 : shared_ptr(const shared_ptr&) noexcept = default;
130 :
131 : /**
132 : * @brief Construct a %shared_ptr that owns the pointer @a __p.
133 : * @param __p A pointer that is convertible to element_type*.
134 : * @post use_count() == 1 && get() == __p
135 : * @throw std::bad_alloc, in which case @c delete @a __p is called.
136 : */
137 : template<typename _Yp, typename = _Constructible<_Yp*>>
138 : explicit
139 : shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
140 :
141 : /**
142 : * @brief Construct a %shared_ptr that owns the pointer @a __p
143 : * and the deleter @a __d.
144 : * @param __p A pointer.
145 : * @param __d A deleter.
146 : * @post use_count() == 1 && get() == __p
147 : * @throw std::bad_alloc, in which case @a __d(__p) is called.
148 : *
149 : * Requirements: _Deleter's copy constructor and destructor must
150 : * not throw
151 : *
152 : * __shared_ptr will release __p by calling __d(__p)
153 : */
154 : template<typename _Yp, typename _Deleter,
155 : typename = _Constructible<_Yp*, _Deleter>>
156 : shared_ptr(_Yp* __p, _Deleter __d)
157 : : __shared_ptr<_Tp>(__p, std::move(__d)) { }
158 :
159 : /**
160 : * @brief Construct a %shared_ptr that owns a null pointer
161 : * and the deleter @a __d.
162 : * @param __p A null pointer constant.
163 : * @param __d A deleter.
164 : * @post use_count() == 1 && get() == __p
165 : * @throw std::bad_alloc, in which case @a __d(__p) is called.
166 : *
167 : * Requirements: _Deleter's copy constructor and destructor must
168 : * not throw
169 : *
170 : * The last owner will call __d(__p)
171 : */
172 : template<typename _Deleter>
173 : shared_ptr(nullptr_t __p, _Deleter __d)
174 : : __shared_ptr<_Tp>(__p, std::move(__d)) { }
175 :
176 : /**
177 : * @brief Construct a %shared_ptr that owns the pointer @a __p
178 : * and the deleter @a __d.
179 : * @param __p A pointer.
180 : * @param __d A deleter.
181 : * @param __a An allocator.
182 : * @post use_count() == 1 && get() == __p
183 : * @throw std::bad_alloc, in which case @a __d(__p) is called.
184 : *
185 : * Requirements: _Deleter's copy constructor and destructor must
186 : * not throw _Alloc's copy constructor and destructor must not
187 : * throw.
188 : *
189 : * __shared_ptr will release __p by calling __d(__p)
190 : */
191 : template<typename _Yp, typename _Deleter, typename _Alloc,
192 : typename = _Constructible<_Yp*, _Deleter, _Alloc>>
193 : shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
194 : : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
195 :
196 : /**
197 : * @brief Construct a %shared_ptr that owns a null pointer
198 : * and the deleter @a __d.
199 : * @param __p A null pointer constant.
200 : * @param __d A deleter.
201 : * @param __a An allocator.
202 : * @post use_count() == 1 && get() == __p
203 : * @throw std::bad_alloc, in which case @a __d(__p) is called.
204 : *
205 : * Requirements: _Deleter's copy constructor and destructor must
206 : * not throw _Alloc's copy constructor and destructor must not
207 : * throw.
208 : *
209 : * The last owner will call __d(__p)
210 : */
211 : template<typename _Deleter, typename _Alloc>
212 : shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
213 : : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
214 :
215 : // Aliasing constructor
216 :
217 : /**
218 : * @brief Constructs a %shared_ptr instance that stores @a __p
219 : * and shares ownership with @a __r.
220 : * @param __r A %shared_ptr.
221 : * @param __p A pointer that will remain valid while @a *__r is valid.
222 : * @post get() == __p && use_count() == __r.use_count()
223 : *
224 : * This can be used to construct a @c shared_ptr to a sub-object
225 : * of an object managed by an existing @c shared_ptr.
226 : *
227 : * @code
228 : * shared_ptr< pair<int,int> > pii(new pair<int,int>());
229 : * shared_ptr<int> pi(pii, &pii->first);
230 : * assert(pii.use_count() == 2);
231 : * @endcode
232 : */
233 : template<typename _Yp>
234 : shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
235 : : __shared_ptr<_Tp>(__r, __p) { }
236 :
237 : /**
238 : * @brief If @a __r is empty, constructs an empty %shared_ptr;
239 : * otherwise construct a %shared_ptr that shares ownership
240 : * with @a __r.
241 : * @param __r A %shared_ptr.
242 : * @post get() == __r.get() && use_count() == __r.use_count()
243 : */
244 : template<typename _Yp,
245 : typename = _Constructible<const shared_ptr<_Yp>&>>
246 : shared_ptr(const shared_ptr<_Yp>& __r) noexcept
247 : : __shared_ptr<_Tp>(__r) { }
248 :
249 : /**
250 : * @brief Move-constructs a %shared_ptr instance from @a __r.
251 : * @param __r A %shared_ptr rvalue.
252 : * @post *this contains the old value of @a __r, @a __r is empty.
253 : */
254 : shared_ptr(shared_ptr&& __r) noexcept
255 : : __shared_ptr<_Tp>(std::move(__r)) { }
256 :
257 : /**
258 : * @brief Move-constructs a %shared_ptr instance from @a __r.
259 : * @param __r A %shared_ptr rvalue.
260 : * @post *this contains the old value of @a __r, @a __r is empty.
261 : */
262 : template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
263 282 : shared_ptr(shared_ptr<_Yp>&& __r) noexcept
264 282 : : __shared_ptr<_Tp>(std::move(__r)) { }
265 :
266 : /**
267 : * @brief Constructs a %shared_ptr that shares ownership with @a __r
268 : * and stores a copy of the pointer stored in @a __r.
269 : * @param __r A weak_ptr.
270 : * @post use_count() == __r.use_count()
271 : * @throw bad_weak_ptr when __r.expired(),
272 : * in which case the constructor has no effect.
273 : */
274 : template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
275 : explicit shared_ptr(const weak_ptr<_Yp>& __r)
276 : : __shared_ptr<_Tp>(__r) { }
277 :
278 : #if _GLIBCXX_USE_DEPRECATED
279 : #pragma GCC diagnostic push
280 : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
281 : template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
282 : shared_ptr(auto_ptr<_Yp>&& __r);
283 : #pragma GCC diagnostic pop
284 : #endif
285 :
286 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
287 : // 2399. shared_ptr's constructor from unique_ptr should be constrained
288 : template<typename _Yp, typename _Del,
289 : typename = _Constructible<unique_ptr<_Yp, _Del>>>
290 : shared_ptr(unique_ptr<_Yp, _Del>&& __r)
291 : : __shared_ptr<_Tp>(std::move(__r)) { }
292 :
293 : #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
294 : // This non-standard constructor exists to support conversions that
295 : // were possible in C++11 and C++14 but are ill-formed in C++17.
296 : // If an exception is thrown this constructor has no effect.
297 : template<typename _Yp, typename _Del,
298 : _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
299 : shared_ptr(unique_ptr<_Yp, _Del>&& __r)
300 : : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
301 : #endif
302 :
303 : /**
304 : * @brief Construct an empty %shared_ptr.
305 : * @post use_count() == 0 && get() == nullptr
306 : */
307 : constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
308 :
309 : shared_ptr& operator=(const shared_ptr&) noexcept = default;
310 :
311 : template<typename _Yp>
312 : _Assignable<const shared_ptr<_Yp>&>
313 : operator=(const shared_ptr<_Yp>& __r) noexcept
314 : {
315 : this->__shared_ptr<_Tp>::operator=(__r);
316 : return *this;
317 : }
318 :
319 : #if _GLIBCXX_USE_DEPRECATED
320 : #pragma GCC diagnostic push
321 : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
322 : template<typename _Yp>
323 : _Assignable<auto_ptr<_Yp>>
324 : operator=(auto_ptr<_Yp>&& __r)
325 : {
326 : this->__shared_ptr<_Tp>::operator=(std::move(__r));
327 : return *this;
328 : }
329 : #pragma GCC diagnostic pop
330 : #endif
331 :
332 : shared_ptr&
333 358 : operator=(shared_ptr&& __r) noexcept
334 : {
335 358 : this->__shared_ptr<_Tp>::operator=(std::move(__r));
336 358 : return *this;
337 : }
338 :
339 : template<class _Yp>
340 : _Assignable<shared_ptr<_Yp>>
341 : operator=(shared_ptr<_Yp>&& __r) noexcept
342 : {
343 : this->__shared_ptr<_Tp>::operator=(std::move(__r));
344 : return *this;
345 : }
346 :
347 : template<typename _Yp, typename _Del>
348 : _Assignable<unique_ptr<_Yp, _Del>>
349 : operator=(unique_ptr<_Yp, _Del>&& __r)
350 : {
351 : this->__shared_ptr<_Tp>::operator=(std::move(__r));
352 : return *this;
353 : }
354 :
355 : private:
356 : // This constructor is non-standard, it is used by allocate_shared.
357 : template<typename _Alloc, typename... _Args>
358 1460 : shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
359 1460 : : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
360 1460 : { }
361 :
362 : template<typename _Yp, typename _Alloc, typename... _Args>
363 : friend shared_ptr<_Yp>
364 : allocate_shared(const _Alloc& __a, _Args&&... __args);
365 :
366 : // This constructor is non-standard, it is used by weak_ptr::lock().
367 636 : shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
368 636 : : __shared_ptr<_Tp>(__r, std::nothrow) { }
369 :
370 : friend class weak_ptr<_Tp>;
371 : };
372 :
373 : #if __cpp_deduction_guides >= 201606
374 : template<typename _Tp>
375 : shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
376 : template<typename _Tp, typename _Del>
377 : shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;
378 : #endif
379 :
380 : // 20.7.2.2.7 shared_ptr comparisons
381 : template<typename _Tp, typename _Up>
382 : inline bool
383 89 : operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
384 89 : { return __a.get() == __b.get(); }
385 :
386 : template<typename _Tp>
387 : inline bool
388 : operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
389 : { return !__a; }
390 :
391 : template<typename _Tp>
392 : inline bool
393 : operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
394 : { return !__a; }
395 :
396 : template<typename _Tp, typename _Up>
397 : inline bool
398 : operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
399 : { return __a.get() != __b.get(); }
400 :
401 : template<typename _Tp>
402 : inline bool
403 : operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
404 : { return (bool)__a; }
405 :
406 : template<typename _Tp>
407 : inline bool
408 : operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
409 : { return (bool)__a; }
410 :
411 : template<typename _Tp, typename _Up>
412 : inline bool
413 175 : operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
414 : {
415 : using _Tp_elt = typename shared_ptr<_Tp>::element_type;
416 : using _Up_elt = typename shared_ptr<_Up>::element_type;
417 : using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
418 175 : return less<_Vp>()(__a.get(), __b.get());
419 : }
420 :
421 : template<typename _Tp>
422 : inline bool
423 : operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
424 : {
425 : using _Tp_elt = typename shared_ptr<_Tp>::element_type;
426 : return less<_Tp_elt*>()(__a.get(), nullptr);
427 : }
428 :
429 : template<typename _Tp>
430 : inline bool
431 : operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
432 : {
433 : using _Tp_elt = typename shared_ptr<_Tp>::element_type;
434 : return less<_Tp_elt*>()(nullptr, __a.get());
435 : }
436 :
437 : template<typename _Tp, typename _Up>
438 : inline bool
439 : operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
440 : { return !(__b < __a); }
441 :
442 : template<typename _Tp>
443 : inline bool
444 : operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
445 : { return !(nullptr < __a); }
446 :
447 : template<typename _Tp>
448 : inline bool
449 : operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
450 : { return !(__a < nullptr); }
451 :
452 : template<typename _Tp, typename _Up>
453 : inline bool
454 : operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
455 : { return (__b < __a); }
456 :
457 : template<typename _Tp>
458 : inline bool
459 : operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
460 : { return nullptr < __a; }
461 :
462 : template<typename _Tp>
463 : inline bool
464 : operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
465 : { return __a < nullptr; }
466 :
467 : template<typename _Tp, typename _Up>
468 : inline bool
469 : operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
470 : { return !(__a < __b); }
471 :
472 : template<typename _Tp>
473 : inline bool
474 : operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
475 : { return !(__a < nullptr); }
476 :
477 : template<typename _Tp>
478 : inline bool
479 : operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
480 : { return !(nullptr < __a); }
481 :
482 : template<typename _Tp>
483 : struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>>
484 : { };
485 :
486 : // 20.7.2.2.8 shared_ptr specialized algorithms.
487 : template<typename _Tp>
488 : inline void
489 : swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
490 : { __a.swap(__b); }
491 :
492 : // 20.7.2.2.9 shared_ptr casts.
493 : template<typename _Tp, typename _Up>
494 : inline shared_ptr<_Tp>
495 : static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
496 : {
497 : using _Sp = shared_ptr<_Tp>;
498 : return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
499 : }
500 :
501 : template<typename _Tp, typename _Up>
502 : inline shared_ptr<_Tp>
503 : const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
504 : {
505 : using _Sp = shared_ptr<_Tp>;
506 : return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
507 : }
508 :
509 : template<typename _Tp, typename _Up>
510 : inline shared_ptr<_Tp>
511 : dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
512 : {
513 : using _Sp = shared_ptr<_Tp>;
514 : if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
515 : return _Sp(__r, __p);
516 : return _Sp();
517 : }
518 :
519 : #if __cplusplus > 201402L
520 : template<typename _Tp, typename _Up>
521 : inline shared_ptr<_Tp>
522 : reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
523 : {
524 : using _Sp = shared_ptr<_Tp>;
525 : return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
526 : }
527 : #endif
528 :
529 : /**
530 : * @brief A smart pointer with weak semantics.
531 : *
532 : * With forwarding constructors and assignment operators.
533 : */
534 : template<typename _Tp>
535 92 : class weak_ptr : public __weak_ptr<_Tp>
536 : {
537 : template<typename _Arg>
538 : using _Constructible = typename enable_if<
539 : is_constructible<__weak_ptr<_Tp>, _Arg>::value
540 : >::type;
541 :
542 : template<typename _Arg>
543 : using _Assignable = typename enable_if<
544 : is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
545 : >::type;
546 :
547 : public:
548 : constexpr weak_ptr() noexcept = default;
549 :
550 : template<typename _Yp,
551 : typename = _Constructible<const shared_ptr<_Yp>&>>
552 167 : weak_ptr(const shared_ptr<_Yp>& __r) noexcept
553 167 : : __weak_ptr<_Tp>(__r) { }
554 :
555 : weak_ptr(const weak_ptr&) noexcept = default;
556 :
557 : template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
558 : weak_ptr(const weak_ptr<_Yp>& __r) noexcept
559 : : __weak_ptr<_Tp>(__r) { }
560 :
561 256 : weak_ptr(weak_ptr&&) noexcept = default;
562 :
563 : template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
564 : weak_ptr(weak_ptr<_Yp>&& __r) noexcept
565 : : __weak_ptr<_Tp>(std::move(__r)) { }
566 :
567 : weak_ptr&
568 : operator=(const weak_ptr& __r) noexcept = default;
569 :
570 : template<typename _Yp>
571 : _Assignable<const weak_ptr<_Yp>&>
572 : operator=(const weak_ptr<_Yp>& __r) noexcept
573 : {
574 : this->__weak_ptr<_Tp>::operator=(__r);
575 : return *this;
576 : }
577 :
578 : template<typename _Yp>
579 : _Assignable<const shared_ptr<_Yp>&>
580 : operator=(const shared_ptr<_Yp>& __r) noexcept
581 : {
582 : this->__weak_ptr<_Tp>::operator=(__r);
583 : return *this;
584 : }
585 :
586 : weak_ptr&
587 : operator=(weak_ptr&& __r) noexcept = default;
588 :
589 : template<typename _Yp>
590 : _Assignable<weak_ptr<_Yp>>
591 : operator=(weak_ptr<_Yp>&& __r) noexcept
592 : {
593 : this->__weak_ptr<_Tp>::operator=(std::move(__r));
594 : return *this;
595 : }
596 :
597 : shared_ptr<_Tp>
598 636 : lock() const noexcept
599 636 : { return shared_ptr<_Tp>(*this, std::nothrow); }
600 : };
601 :
602 : #if __cpp_deduction_guides >= 201606
603 : template<typename _Tp>
604 : weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
605 : #endif
606 :
607 : // 20.7.2.3.6 weak_ptr specialized algorithms.
608 : template<typename _Tp>
609 : inline void
610 0 : swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
611 0 : { __a.swap(__b); }
612 :
613 :
614 : /// Primary template owner_less
615 : template<typename _Tp = void>
616 : struct owner_less;
617 :
618 : /// Void specialization of owner_less
619 : template<>
620 : struct owner_less<void> : _Sp_owner_less<void, void>
621 : { };
622 :
623 : /// Partial specialization of owner_less for shared_ptr.
624 : template<typename _Tp>
625 : struct owner_less<shared_ptr<_Tp>>
626 : : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
627 : { };
628 :
629 : /// Partial specialization of owner_less for weak_ptr.
630 : template<typename _Tp>
631 : struct owner_less<weak_ptr<_Tp>>
632 : : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
633 : { };
634 :
635 : /**
636 : * @brief Base class allowing use of member function shared_from_this.
637 : */
638 : template<typename _Tp>
639 : class enable_shared_from_this
640 : {
641 : protected:
642 : constexpr enable_shared_from_this() noexcept { }
643 :
644 : enable_shared_from_this(const enable_shared_from_this&) noexcept { }
645 :
646 : enable_shared_from_this&
647 : operator=(const enable_shared_from_this&) noexcept
648 : { return *this; }
649 :
650 : ~enable_shared_from_this() { }
651 :
652 : public:
653 : shared_ptr<_Tp>
654 : shared_from_this()
655 : { return shared_ptr<_Tp>(this->_M_weak_this); }
656 :
657 : shared_ptr<const _Tp>
658 : shared_from_this() const
659 : { return shared_ptr<const _Tp>(this->_M_weak_this); }
660 :
661 : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
662 : #define __cpp_lib_enable_shared_from_this 201603
663 : weak_ptr<_Tp>
664 : weak_from_this() noexcept
665 : { return this->_M_weak_this; }
666 :
667 : weak_ptr<const _Tp>
668 : weak_from_this() const noexcept
669 : { return this->_M_weak_this; }
670 : #endif
671 :
672 : private:
673 : template<typename _Tp1>
674 : void
675 : _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
676 : { _M_weak_this._M_assign(__p, __n); }
677 :
678 : // Found by ADL when this is an associated class.
679 : friend const enable_shared_from_this*
680 : __enable_shared_from_this_base(const __shared_count<>&,
681 : const enable_shared_from_this* __p)
682 : { return __p; }
683 :
684 : template<typename, _Lock_policy>
685 : friend class __shared_ptr;
686 :
687 : mutable weak_ptr<_Tp> _M_weak_this;
688 : };
689 :
690 : /**
691 : * @brief Create an object that is owned by a shared_ptr.
692 : * @param __a An allocator.
693 : * @param __args Arguments for the @a _Tp object's constructor.
694 : * @return A shared_ptr that owns the newly created object.
695 : * @throw An exception thrown from @a _Alloc::allocate or from the
696 : * constructor of @a _Tp.
697 : *
698 : * A copy of @a __a will be used to allocate memory for the shared_ptr
699 : * and the new object.
700 : */
701 : template<typename _Tp, typename _Alloc, typename... _Args>
702 : inline shared_ptr<_Tp>
703 1460 : allocate_shared(const _Alloc& __a, _Args&&... __args)
704 : {
705 : return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
706 1460 : std::forward<_Args>(__args)...);
707 : }
708 :
709 : /**
710 : * @brief Create an object that is owned by a shared_ptr.
711 : * @param __args Arguments for the @a _Tp object's constructor.
712 : * @return A shared_ptr that owns the newly created object.
713 : * @throw std::bad_alloc, or an exception thrown from the
714 : * constructor of @a _Tp.
715 : */
716 : template<typename _Tp, typename... _Args>
717 : inline shared_ptr<_Tp>
718 1460 : make_shared(_Args&&... __args)
719 : {
720 : typedef typename std::remove_cv<_Tp>::type _Tp_nc;
721 : return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
722 1460 : std::forward<_Args>(__args)...);
723 : }
724 :
725 : /// std::hash specialization for shared_ptr.
726 : template<typename _Tp>
727 : struct hash<shared_ptr<_Tp>>
728 : : public __hash_base<size_t, shared_ptr<_Tp>>
729 : {
730 : size_t
731 : operator()(const shared_ptr<_Tp>& __s) const noexcept
732 : {
733 : return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
734 : }
735 : };
736 :
737 : // @} group pointer_abstractions
738 :
739 : _GLIBCXX_END_NAMESPACE_VERSION
740 : } // namespace
741 :
742 : #endif // _SHARED_PTR_H
|