1 // shared_ptr and weak_ptr implementation -*- C++ -*-
3 // Copyright (C) 2007-2018 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 // GCC Note: Based on files from version 1.32.0 of the Boost library.
28 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
31 // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
32 // Copyright (C) 2001, 2002, 2003 Peter Dimov
35 // Copyright (C) 2001, 2002, 2003 Peter Dimov
37 // enable_shared_from_this.hpp
38 // Copyright (C) 2002 Peter Dimov
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)
45 * This is an internal header file, included by other library headers.
46 * Do not attempt to use it directly. @headername{memory}
50 #define _SHARED_PTR_H 1
52 #include <bits/shared_ptr_base.h>
54 namespace std
_GLIBCXX_VISIBILITY(default)
56 _GLIBCXX_BEGIN_NAMESPACE_VERSION
59 * @addtogroup pointer_abstractions
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
)
73 template<typename _Del
, typename _Tp
, _Lock_policy _Lp
>
75 get_deleter(const __shared_ptr
<_Tp
, _Lp
>& __p
) noexcept
78 return static_cast<_Del
*>(__p
._M_get_deleter(typeid(_Del
)));
84 /// 20.7.2.2.10 shared_ptr get_deleter
85 template<typename _Del
, typename _Tp
>
87 get_deleter(const shared_ptr
<_Tp
>& __p
) noexcept
90 return static_cast<_Del
*>(__p
._M_get_deleter(typeid(_Del
)));
97 * @brief A smart pointer with reference-counted copy semantics.
99 * The object pointed to is deleted when the last shared_ptr pointing to
100 * it is destroyed or reset.
102 template<typename _Tp
>
103 class shared_ptr
: public __shared_ptr
<_Tp
>
105 template<typename
... _Args
>
106 using _Constructible
= typename enable_if
<
107 is_constructible
<__shared_ptr
<_Tp
>, _Args
...>::value
110 template<typename _Arg
>
111 using _Assignable
= typename enable_if
<
112 is_assignable
<__shared_ptr
<_Tp
>&, _Arg
>::value
, shared_ptr
&
117 using element_type
= typename __shared_ptr
<_Tp
>::element_type
;
119 #if __cplusplus > 201402L
120 # define __cpp_lib_shared_ptr_weak_type 201606
121 using weak_type
= weak_ptr
<_Tp
>;
124 * @brief Construct an empty %shared_ptr.
125 * @post use_count()==0 && get()==0
127 constexpr shared_ptr() noexcept
: __shared_ptr
<_Tp
>() { }
129 shared_ptr(const shared_ptr
&) noexcept
= default;
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.
137 template<typename _Yp
, typename
= _Constructible
<_Yp
*>>
139 shared_ptr(_Yp
* __p
) : __shared_ptr
<_Tp
>(__p
) { }
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.
149 * Requirements: _Deleter's copy constructor and destructor must
152 * __shared_ptr will release __p by calling __d(__p)
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
)) { }
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.
167 * Requirements: _Deleter's copy constructor and destructor must
170 * The last owner will call __d(__p)
172 template<typename _Deleter
>
173 shared_ptr(nullptr_t __p
, _Deleter __d
)
174 : __shared_ptr
<_Tp
>(__p
, std::move(__d
)) { }
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.
185 * Requirements: _Deleter's copy constructor and destructor must
186 * not throw _Alloc's copy constructor and destructor must not
189 * __shared_ptr will release __p by calling __d(__p)
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
)) { }
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.
205 * Requirements: _Deleter's copy constructor and destructor must
206 * not throw _Alloc's copy constructor and destructor must not
209 * The last owner will call __d(__p)
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
)) { }
215 // Aliasing constructor
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()
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.
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);
233 template<typename _Yp
>
234 shared_ptr(const shared_ptr
<_Yp
>& __r
, element_type
* __p
) noexcept
235 : __shared_ptr
<_Tp
>(__r
, __p
) { }
238 * @brief If @a __r is empty, constructs an empty %shared_ptr;
239 * otherwise construct a %shared_ptr that shares ownership
241 * @param __r A %shared_ptr.
242 * @post get() == __r.get() && use_count() == __r.use_count()
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
) { }
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.
254 shared_ptr(shared_ptr
&& __r
) noexcept
255 : __shared_ptr
<_Tp
>(std::move(__r
)) { }
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.
262 template<typename _Yp
, typename
= _Constructible
<shared_ptr
<_Yp
>>>
263 shared_ptr(shared_ptr
<_Yp
>&& __r
) noexcept
264 : __shared_ptr
<_Tp
>(std::move(__r
)) { }
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.
274 template<typename _Yp
, typename
= _Constructible
<const weak_ptr
<_Yp
>&>>
275 explicit shared_ptr(const weak_ptr
<_Yp
>& __r
)
276 : __shared_ptr
<_Tp
>(__r
) { }
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
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
)) { }
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()) { }
304 * @brief Construct an empty %shared_ptr.
305 * @post use_count() == 0 && get() == nullptr
307 constexpr shared_ptr(nullptr_t
) noexcept
: shared_ptr() { }
309 shared_ptr
& operator=(const shared_ptr
&) noexcept
= default;
311 template<typename _Yp
>
312 _Assignable
<const shared_ptr
<_Yp
>&>
313 operator=(const shared_ptr
<_Yp
>& __r
) noexcept
315 this->__shared_ptr
<_Tp
>::operator=(__r
);
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
)
326 this->__shared_ptr
<_Tp
>::operator=(std::move(__r
));
329 #pragma GCC diagnostic pop
333 operator=(shared_ptr
&& __r
) noexcept
335 this->__shared_ptr
<_Tp
>::operator=(std::move(__r
));
340 _Assignable
<shared_ptr
<_Yp
>>
341 operator=(shared_ptr
<_Yp
>&& __r
) noexcept
343 this->__shared_ptr
<_Tp
>::operator=(std::move(__r
));
347 template<typename _Yp
, typename _Del
>
348 _Assignable
<unique_ptr
<_Yp
, _Del
>>
349 operator=(unique_ptr
<_Yp
, _Del
>&& __r
)
351 this->__shared_ptr
<_Tp
>::operator=(std::move(__r
));
356 // This constructor is non-standard, it is used by allocate_shared.
357 template<typename _Alloc
, typename
... _Args
>
358 shared_ptr(_Sp_make_shared_tag __tag
, const _Alloc
& __a
,
360 : __shared_ptr
<_Tp
>(__tag
, __a
, std::forward
<_Args
>(__args
)...)
363 template<typename _Yp
, typename _Alloc
, typename
... _Args
>
364 friend shared_ptr
<_Yp
>
365 allocate_shared(const _Alloc
& __a
, _Args
&&... __args
);
367 // This constructor is non-standard, it is used by weak_ptr::lock().
368 shared_ptr(const weak_ptr
<_Tp
>& __r
, std::nothrow_t
)
369 : __shared_ptr
<_Tp
>(__r
, std::nothrow
) { }
371 friend class weak_ptr
<_Tp
>;
374 #if __cpp_deduction_guides >= 201606
375 template<typename _Tp
>
376 shared_ptr(weak_ptr
<_Tp
>) -> shared_ptr
<_Tp
>;
377 template<typename _Tp
, typename _Del
>
378 shared_ptr(unique_ptr
<_Tp
, _Del
>) -> shared_ptr
<_Tp
>;
381 // 20.7.2.2.7 shared_ptr comparisons
382 template<typename _Tp
, typename _Up
>
384 operator==(const shared_ptr
<_Tp
>& __a
, const shared_ptr
<_Up
>& __b
) noexcept
385 { return __a
.get() == __b
.get(); }
387 template<typename _Tp
>
389 operator==(const shared_ptr
<_Tp
>& __a
, nullptr_t
) noexcept
392 template<typename _Tp
>
394 operator==(nullptr_t
, const shared_ptr
<_Tp
>& __a
) noexcept
397 template<typename _Tp
, typename _Up
>
399 operator!=(const shared_ptr
<_Tp
>& __a
, const shared_ptr
<_Up
>& __b
) noexcept
400 { return __a
.get() != __b
.get(); }
402 template<typename _Tp
>
404 operator!=(const shared_ptr
<_Tp
>& __a
, nullptr_t
) noexcept
405 { return (bool)__a
; }
407 template<typename _Tp
>
409 operator!=(nullptr_t
, const shared_ptr
<_Tp
>& __a
) noexcept
410 { return (bool)__a
; }
412 template<typename _Tp
, typename _Up
>
414 operator<(const shared_ptr
<_Tp
>& __a
, const shared_ptr
<_Up
>& __b
) noexcept
416 using _Tp_elt
= typename shared_ptr
<_Tp
>::element_type
;
417 using _Up_elt
= typename shared_ptr
<_Up
>::element_type
;
418 using _Vp
= typename common_type
<_Tp_elt
*, _Up_elt
*>::type
;
419 return less
<_Vp
>()(__a
.get(), __b
.get());
422 template<typename _Tp
>
424 operator<(const shared_ptr
<_Tp
>& __a
, nullptr_t
) noexcept
426 using _Tp_elt
= typename shared_ptr
<_Tp
>::element_type
;
427 return less
<_Tp_elt
*>()(__a
.get(), nullptr);
430 template<typename _Tp
>
432 operator<(nullptr_t
, const shared_ptr
<_Tp
>& __a
) noexcept
434 using _Tp_elt
= typename shared_ptr
<_Tp
>::element_type
;
435 return less
<_Tp_elt
*>()(nullptr, __a
.get());
438 template<typename _Tp
, typename _Up
>
440 operator<=(const shared_ptr
<_Tp
>& __a
, const shared_ptr
<_Up
>& __b
) noexcept
441 { return !(__b
< __a
); }
443 template<typename _Tp
>
445 operator<=(const shared_ptr
<_Tp
>& __a
, nullptr_t
) noexcept
446 { return !(nullptr < __a
); }
448 template<typename _Tp
>
450 operator<=(nullptr_t
, const shared_ptr
<_Tp
>& __a
) noexcept
451 { return !(__a
< nullptr); }
453 template<typename _Tp
, typename _Up
>
455 operator>(const shared_ptr
<_Tp
>& __a
, const shared_ptr
<_Up
>& __b
) noexcept
456 { return (__b
< __a
); }
458 template<typename _Tp
>
460 operator>(const shared_ptr
<_Tp
>& __a
, nullptr_t
) noexcept
461 { return nullptr < __a
; }
463 template<typename _Tp
>
465 operator>(nullptr_t
, const shared_ptr
<_Tp
>& __a
) noexcept
466 { return __a
< nullptr; }
468 template<typename _Tp
, typename _Up
>
470 operator>=(const shared_ptr
<_Tp
>& __a
, const shared_ptr
<_Up
>& __b
) noexcept
471 { return !(__a
< __b
); }
473 template<typename _Tp
>
475 operator>=(const shared_ptr
<_Tp
>& __a
, nullptr_t
) noexcept
476 { return !(__a
< nullptr); }
478 template<typename _Tp
>
480 operator>=(nullptr_t
, const shared_ptr
<_Tp
>& __a
) noexcept
481 { return !(nullptr < __a
); }
483 // 20.7.2.2.8 shared_ptr specialized algorithms.
484 template<typename _Tp
>
486 swap(shared_ptr
<_Tp
>& __a
, shared_ptr
<_Tp
>& __b
) noexcept
489 // 20.7.2.2.9 shared_ptr casts.
490 template<typename _Tp
, typename _Up
>
491 inline shared_ptr
<_Tp
>
492 static_pointer_cast(const shared_ptr
<_Up
>& __r
) noexcept
494 using _Sp
= shared_ptr
<_Tp
>;
495 return _Sp(__r
, static_cast<typename
_Sp::element_type
*>(__r
.get()));
498 template<typename _Tp
, typename _Up
>
499 inline shared_ptr
<_Tp
>
500 const_pointer_cast(const shared_ptr
<_Up
>& __r
) noexcept
502 using _Sp
= shared_ptr
<_Tp
>;
503 return _Sp(__r
, const_cast<typename
_Sp::element_type
*>(__r
.get()));
506 template<typename _Tp
, typename _Up
>
507 inline shared_ptr
<_Tp
>
508 dynamic_pointer_cast(const shared_ptr
<_Up
>& __r
) noexcept
510 using _Sp
= shared_ptr
<_Tp
>;
511 if (auto* __p
= dynamic_cast<typename
_Sp::element_type
*>(__r
.get()))
512 return _Sp(__r
, __p
);
516 #if __cplusplus > 201402L
517 template<typename _Tp
, typename _Up
>
518 inline shared_ptr
<_Tp
>
519 reinterpret_pointer_cast(const shared_ptr
<_Up
>& __r
) noexcept
521 using _Sp
= shared_ptr
<_Tp
>;
522 return _Sp(__r
, reinterpret_cast<typename
_Sp::element_type
*>(__r
.get()));
527 * @brief A smart pointer with weak semantics.
529 * With forwarding constructors and assignment operators.
531 template<typename _Tp
>
532 class weak_ptr
: public __weak_ptr
<_Tp
>
534 template<typename _Arg
>
535 using _Constructible
= typename enable_if
<
536 is_constructible
<__weak_ptr
<_Tp
>, _Arg
>::value
539 template<typename _Arg
>
540 using _Assignable
= typename enable_if
<
541 is_assignable
<__weak_ptr
<_Tp
>&, _Arg
>::value
, weak_ptr
&
545 constexpr weak_ptr() noexcept
= default;
547 template<typename _Yp
,
548 typename
= _Constructible
<const shared_ptr
<_Yp
>&>>
549 weak_ptr(const shared_ptr
<_Yp
>& __r
) noexcept
550 : __weak_ptr
<_Tp
>(__r
) { }
552 weak_ptr(const weak_ptr
&) noexcept
= default;
554 template<typename _Yp
, typename
= _Constructible
<const weak_ptr
<_Yp
>&>>
555 weak_ptr(const weak_ptr
<_Yp
>& __r
) noexcept
556 : __weak_ptr
<_Tp
>(__r
) { }
558 weak_ptr(weak_ptr
&&) noexcept
= default;
560 template<typename _Yp
, typename
= _Constructible
<weak_ptr
<_Yp
>>>
561 weak_ptr(weak_ptr
<_Yp
>&& __r
) noexcept
562 : __weak_ptr
<_Tp
>(std::move(__r
)) { }
565 operator=(const weak_ptr
& __r
) noexcept
= default;
567 template<typename _Yp
>
568 _Assignable
<const weak_ptr
<_Yp
>&>
569 operator=(const weak_ptr
<_Yp
>& __r
) noexcept
571 this->__weak_ptr
<_Tp
>::operator=(__r
);
575 template<typename _Yp
>
576 _Assignable
<const shared_ptr
<_Yp
>&>
577 operator=(const shared_ptr
<_Yp
>& __r
) noexcept
579 this->__weak_ptr
<_Tp
>::operator=(__r
);
584 operator=(weak_ptr
&& __r
) noexcept
= default;
586 template<typename _Yp
>
587 _Assignable
<weak_ptr
<_Yp
>>
588 operator=(weak_ptr
<_Yp
>&& __r
) noexcept
590 this->__weak_ptr
<_Tp
>::operator=(std::move(__r
));
595 lock() const noexcept
596 { return shared_ptr
<_Tp
>(*this, std::nothrow
); }
599 #if __cpp_deduction_guides >= 201606
600 template<typename _Tp
>
601 weak_ptr(shared_ptr
<_Tp
>) -> weak_ptr
<_Tp
>;
604 // 20.7.2.3.6 weak_ptr specialized algorithms.
605 template<typename _Tp
>
607 swap(weak_ptr
<_Tp
>& __a
, weak_ptr
<_Tp
>& __b
) noexcept
611 /// Primary template owner_less
612 template<typename _Tp
= void>
615 /// Void specialization of owner_less
617 struct owner_less
<void> : _Sp_owner_less
<void, void>
620 /// Partial specialization of owner_less for shared_ptr.
621 template<typename _Tp
>
622 struct owner_less
<shared_ptr
<_Tp
>>
623 : public _Sp_owner_less
<shared_ptr
<_Tp
>, weak_ptr
<_Tp
>>
626 /// Partial specialization of owner_less for weak_ptr.
627 template<typename _Tp
>
628 struct owner_less
<weak_ptr
<_Tp
>>
629 : public _Sp_owner_less
<weak_ptr
<_Tp
>, shared_ptr
<_Tp
>>
633 * @brief Base class allowing use of member function shared_from_this.
635 template<typename _Tp
>
636 class enable_shared_from_this
639 constexpr enable_shared_from_this() noexcept
{ }
641 enable_shared_from_this(const enable_shared_from_this
&) noexcept
{ }
643 enable_shared_from_this
&
644 operator=(const enable_shared_from_this
&) noexcept
647 ~enable_shared_from_this() { }
652 { return shared_ptr
<_Tp
>(this->_M_weak_this
); }
654 shared_ptr
<const _Tp
>
655 shared_from_this() const
656 { return shared_ptr
<const _Tp
>(this->_M_weak_this
); }
658 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
659 #define __cpp_lib_enable_shared_from_this 201603
661 weak_from_this() noexcept
662 { return this->_M_weak_this
; }
665 weak_from_this() const noexcept
666 { return this->_M_weak_this
; }
670 template<typename _Tp1
>
672 _M_weak_assign(_Tp1
* __p
, const __shared_count
<>& __n
) const noexcept
673 { _M_weak_this
._M_assign(__p
, __n
); }
675 // Found by ADL when this is an associated class.
676 friend const enable_shared_from_this
*
677 __enable_shared_from_this_base(const __shared_count
<>&,
678 const enable_shared_from_this
* __p
)
681 template<typename
, _Lock_policy
>
682 friend class __shared_ptr
;
684 mutable weak_ptr
<_Tp
> _M_weak_this
;
688 * @brief Create an object that is owned by a shared_ptr.
689 * @param __a An allocator.
690 * @param __args Arguments for the @a _Tp object's constructor.
691 * @return A shared_ptr that owns the newly created object.
692 * @throw An exception thrown from @a _Alloc::allocate or from the
693 * constructor of @a _Tp.
695 * A copy of @a __a will be used to allocate memory for the shared_ptr
696 * and the new object.
698 template<typename _Tp
, typename _Alloc
, typename
... _Args
>
699 inline shared_ptr
<_Tp
>
700 allocate_shared(const _Alloc
& __a
, _Args
&&... __args
)
702 return shared_ptr
<_Tp
>(_Sp_make_shared_tag(), __a
,
703 std::forward
<_Args
>(__args
)...);
707 * @brief Create an object that is owned by a shared_ptr.
708 * @param __args Arguments for the @a _Tp object's constructor.
709 * @return A shared_ptr that owns the newly created object.
710 * @throw std::bad_alloc, or an exception thrown from the
711 * constructor of @a _Tp.
713 template<typename _Tp
, typename
... _Args
>
714 inline shared_ptr
<_Tp
>
715 make_shared(_Args
&&... __args
)
717 typedef typename
std::remove_cv
<_Tp
>::type _Tp_nc
;
718 return std::allocate_shared
<_Tp
>(std::allocator
<_Tp_nc
>(),
719 std::forward
<_Args
>(__args
)...);
722 /// std::hash specialization for shared_ptr.
723 template<typename _Tp
>
724 struct hash
<shared_ptr
<_Tp
>>
725 : public __hash_base
<size_t, shared_ptr
<_Tp
>>
728 operator()(const shared_ptr
<_Tp
>& __s
) const noexcept
730 return std::hash
<typename shared_ptr
<_Tp
>::element_type
*>()(__s
.get());
734 // @} group pointer_abstractions
736 _GLIBCXX_END_NAMESPACE_VERSION
739 #endif // _SHARED_PTR_H