138fd1498Szrj // shared_ptr and weak_ptr implementation -*- C++ -*-
238fd1498Szrj
338fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc.
438fd1498Szrj //
538fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free
638fd1498Szrj // software; you can redistribute it and/or modify it under the
738fd1498Szrj // terms of the GNU General Public License as published by the
838fd1498Szrj // Free Software Foundation; either version 3, or (at your option)
938fd1498Szrj // any later version.
1038fd1498Szrj
1138fd1498Szrj // This library is distributed in the hope that it will be useful,
1238fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
1338fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1438fd1498Szrj // GNU General Public License for more details.
1538fd1498Szrj
1638fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional
1738fd1498Szrj // permissions described in the GCC Runtime Library Exception, version
1838fd1498Szrj // 3.1, as published by the Free Software Foundation.
1938fd1498Szrj
2038fd1498Szrj // You should have received a copy of the GNU General Public License and
2138fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program;
2238fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2338fd1498Szrj // <http://www.gnu.org/licenses/>.
2438fd1498Szrj
2538fd1498Szrj // GCC Note: Based on files from version 1.32.0 of the Boost library.
2638fd1498Szrj
2738fd1498Szrj // shared_count.hpp
2838fd1498Szrj // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
2938fd1498Szrj
3038fd1498Szrj // shared_ptr.hpp
3138fd1498Szrj // Copyright (C) 1998, 1999 Greg Colvin and Beman Dawes.
3238fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov
3338fd1498Szrj
3438fd1498Szrj // weak_ptr.hpp
3538fd1498Szrj // Copyright (C) 2001, 2002, 2003 Peter Dimov
3638fd1498Szrj
3738fd1498Szrj // enable_shared_from_this.hpp
3838fd1498Szrj // Copyright (C) 2002 Peter Dimov
3938fd1498Szrj
4038fd1498Szrj // Distributed under the Boost Software License, Version 1.0. (See
4138fd1498Szrj // accompanying file LICENSE_1_0.txt or copy at
4238fd1498Szrj // http://www.boost.org/LICENSE_1_0.txt)
4338fd1498Szrj
4438fd1498Szrj /** @file
4538fd1498Szrj * This is an internal header file, included by other library headers.
4638fd1498Szrj * Do not attempt to use it directly. @headername{memory}
4738fd1498Szrj */
4838fd1498Szrj
4938fd1498Szrj #ifndef _SHARED_PTR_H
5038fd1498Szrj #define _SHARED_PTR_H 1
5138fd1498Szrj
5238fd1498Szrj #include <bits/shared_ptr_base.h>
5338fd1498Szrj
_GLIBCXX_VISIBILITY(default)5438fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default)
5538fd1498Szrj {
5638fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION
5738fd1498Szrj
5838fd1498Szrj /**
5938fd1498Szrj * @addtogroup pointer_abstractions
6038fd1498Szrj * @{
6138fd1498Szrj */
6238fd1498Szrj
6338fd1498Szrj /// 20.7.2.2.11 shared_ptr I/O
6438fd1498Szrj template<typename _Ch, typename _Tr, typename _Tp, _Lock_policy _Lp>
6538fd1498Szrj inline std::basic_ostream<_Ch, _Tr>&
6638fd1498Szrj operator<<(std::basic_ostream<_Ch, _Tr>& __os,
6738fd1498Szrj const __shared_ptr<_Tp, _Lp>& __p)
6838fd1498Szrj {
6938fd1498Szrj __os << __p.get();
7038fd1498Szrj return __os;
7138fd1498Szrj }
7238fd1498Szrj
7338fd1498Szrj template<typename _Del, typename _Tp, _Lock_policy _Lp>
7438fd1498Szrj inline _Del*
7538fd1498Szrj get_deleter(const __shared_ptr<_Tp, _Lp>& __p) noexcept
7638fd1498Szrj {
7738fd1498Szrj #if __cpp_rtti
7838fd1498Szrj return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
7938fd1498Szrj #else
8038fd1498Szrj return 0;
8138fd1498Szrj #endif
8238fd1498Szrj }
8338fd1498Szrj
8438fd1498Szrj /// 20.7.2.2.10 shared_ptr get_deleter
8538fd1498Szrj template<typename _Del, typename _Tp>
8638fd1498Szrj inline _Del*
8738fd1498Szrj get_deleter(const shared_ptr<_Tp>& __p) noexcept
8838fd1498Szrj {
8938fd1498Szrj #if __cpp_rtti
9038fd1498Szrj return static_cast<_Del*>(__p._M_get_deleter(typeid(_Del)));
9138fd1498Szrj #else
9238fd1498Szrj return 0;
9338fd1498Szrj #endif
9438fd1498Szrj }
9538fd1498Szrj
9638fd1498Szrj /**
9738fd1498Szrj * @brief A smart pointer with reference-counted copy semantics.
9838fd1498Szrj *
9938fd1498Szrj * The object pointed to is deleted when the last shared_ptr pointing to
10038fd1498Szrj * it is destroyed or reset.
10138fd1498Szrj */
10238fd1498Szrj template<typename _Tp>
10338fd1498Szrj class shared_ptr : public __shared_ptr<_Tp>
10438fd1498Szrj {
10538fd1498Szrj template<typename... _Args>
10638fd1498Szrj using _Constructible = typename enable_if<
10738fd1498Szrj is_constructible<__shared_ptr<_Tp>, _Args...>::value
10838fd1498Szrj >::type;
10938fd1498Szrj
11038fd1498Szrj template<typename _Arg>
11138fd1498Szrj using _Assignable = typename enable_if<
11238fd1498Szrj is_assignable<__shared_ptr<_Tp>&, _Arg>::value, shared_ptr&
11338fd1498Szrj >::type;
11438fd1498Szrj
11538fd1498Szrj public:
11638fd1498Szrj
11738fd1498Szrj using element_type = typename __shared_ptr<_Tp>::element_type;
11838fd1498Szrj
11938fd1498Szrj #if __cplusplus > 201402L
12038fd1498Szrj # define __cpp_lib_shared_ptr_weak_type 201606
12138fd1498Szrj using weak_type = weak_ptr<_Tp>;
12238fd1498Szrj #endif
12338fd1498Szrj /**
12438fd1498Szrj * @brief Construct an empty %shared_ptr.
12538fd1498Szrj * @post use_count()==0 && get()==0
12638fd1498Szrj */
12738fd1498Szrj constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
12838fd1498Szrj
12938fd1498Szrj shared_ptr(const shared_ptr&) noexcept = default;
13038fd1498Szrj
13138fd1498Szrj /**
13238fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p.
13338fd1498Szrj * @param __p A pointer that is convertible to element_type*.
13438fd1498Szrj * @post use_count() == 1 && get() == __p
13538fd1498Szrj * @throw std::bad_alloc, in which case @c delete @a __p is called.
13638fd1498Szrj */
13738fd1498Szrj template<typename _Yp, typename = _Constructible<_Yp*>>
13838fd1498Szrj explicit
13938fd1498Szrj shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
14038fd1498Szrj
14138fd1498Szrj /**
14238fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p
14338fd1498Szrj * and the deleter @a __d.
14438fd1498Szrj * @param __p A pointer.
14538fd1498Szrj * @param __d A deleter.
14638fd1498Szrj * @post use_count() == 1 && get() == __p
14738fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called.
14838fd1498Szrj *
14938fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must
15038fd1498Szrj * not throw
15138fd1498Szrj *
15238fd1498Szrj * __shared_ptr will release __p by calling __d(__p)
15338fd1498Szrj */
15438fd1498Szrj template<typename _Yp, typename _Deleter,
15538fd1498Szrj typename = _Constructible<_Yp*, _Deleter>>
15638fd1498Szrj shared_ptr(_Yp* __p, _Deleter __d)
15738fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d)) { }
15838fd1498Szrj
15938fd1498Szrj /**
16038fd1498Szrj * @brief Construct a %shared_ptr that owns a null pointer
16138fd1498Szrj * and the deleter @a __d.
16238fd1498Szrj * @param __p A null pointer constant.
16338fd1498Szrj * @param __d A deleter.
16438fd1498Szrj * @post use_count() == 1 && get() == __p
16538fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called.
16638fd1498Szrj *
16738fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must
16838fd1498Szrj * not throw
16938fd1498Szrj *
17038fd1498Szrj * The last owner will call __d(__p)
17138fd1498Szrj */
17238fd1498Szrj template<typename _Deleter>
17338fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d)
17438fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d)) { }
17538fd1498Szrj
17638fd1498Szrj /**
17738fd1498Szrj * @brief Construct a %shared_ptr that owns the pointer @a __p
17838fd1498Szrj * and the deleter @a __d.
17938fd1498Szrj * @param __p A pointer.
18038fd1498Szrj * @param __d A deleter.
18138fd1498Szrj * @param __a An allocator.
18238fd1498Szrj * @post use_count() == 1 && get() == __p
18338fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called.
18438fd1498Szrj *
18538fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must
18638fd1498Szrj * not throw _Alloc's copy constructor and destructor must not
18738fd1498Szrj * throw.
18838fd1498Szrj *
18938fd1498Szrj * __shared_ptr will release __p by calling __d(__p)
19038fd1498Szrj */
19138fd1498Szrj template<typename _Yp, typename _Deleter, typename _Alloc,
19238fd1498Szrj typename = _Constructible<_Yp*, _Deleter, _Alloc>>
19338fd1498Szrj shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
19438fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
19538fd1498Szrj
19638fd1498Szrj /**
19738fd1498Szrj * @brief Construct a %shared_ptr that owns a null pointer
19838fd1498Szrj * and the deleter @a __d.
19938fd1498Szrj * @param __p A null pointer constant.
20038fd1498Szrj * @param __d A deleter.
20138fd1498Szrj * @param __a An allocator.
20238fd1498Szrj * @post use_count() == 1 && get() == __p
20338fd1498Szrj * @throw std::bad_alloc, in which case @a __d(__p) is called.
20438fd1498Szrj *
20538fd1498Szrj * Requirements: _Deleter's copy constructor and destructor must
20638fd1498Szrj * not throw _Alloc's copy constructor and destructor must not
20738fd1498Szrj * throw.
20838fd1498Szrj *
20938fd1498Szrj * The last owner will call __d(__p)
21038fd1498Szrj */
21138fd1498Szrj template<typename _Deleter, typename _Alloc>
21238fd1498Szrj shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
21338fd1498Szrj : __shared_ptr<_Tp>(__p, std::move(__d), std::move(__a)) { }
21438fd1498Szrj
21538fd1498Szrj // Aliasing constructor
21638fd1498Szrj
21738fd1498Szrj /**
21838fd1498Szrj * @brief Constructs a %shared_ptr instance that stores @a __p
21938fd1498Szrj * and shares ownership with @a __r.
22038fd1498Szrj * @param __r A %shared_ptr.
22138fd1498Szrj * @param __p A pointer that will remain valid while @a *__r is valid.
22238fd1498Szrj * @post get() == __p && use_count() == __r.use_count()
22338fd1498Szrj *
22438fd1498Szrj * This can be used to construct a @c shared_ptr to a sub-object
22538fd1498Szrj * of an object managed by an existing @c shared_ptr.
22638fd1498Szrj *
22738fd1498Szrj * @code
22838fd1498Szrj * shared_ptr< pair<int,int> > pii(new pair<int,int>());
22938fd1498Szrj * shared_ptr<int> pi(pii, &pii->first);
23038fd1498Szrj * assert(pii.use_count() == 2);
23138fd1498Szrj * @endcode
23238fd1498Szrj */
23338fd1498Szrj template<typename _Yp>
23438fd1498Szrj shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
23538fd1498Szrj : __shared_ptr<_Tp>(__r, __p) { }
23638fd1498Szrj
23738fd1498Szrj /**
23838fd1498Szrj * @brief If @a __r is empty, constructs an empty %shared_ptr;
23938fd1498Szrj * otherwise construct a %shared_ptr that shares ownership
24038fd1498Szrj * with @a __r.
24138fd1498Szrj * @param __r A %shared_ptr.
24238fd1498Szrj * @post get() == __r.get() && use_count() == __r.use_count()
24338fd1498Szrj */
24438fd1498Szrj template<typename _Yp,
24538fd1498Szrj typename = _Constructible<const shared_ptr<_Yp>&>>
24638fd1498Szrj shared_ptr(const shared_ptr<_Yp>& __r) noexcept
24738fd1498Szrj : __shared_ptr<_Tp>(__r) { }
24838fd1498Szrj
24938fd1498Szrj /**
25038fd1498Szrj * @brief Move-constructs a %shared_ptr instance from @a __r.
25138fd1498Szrj * @param __r A %shared_ptr rvalue.
25238fd1498Szrj * @post *this contains the old value of @a __r, @a __r is empty.
25338fd1498Szrj */
25438fd1498Szrj shared_ptr(shared_ptr&& __r) noexcept
25538fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { }
25638fd1498Szrj
25738fd1498Szrj /**
25838fd1498Szrj * @brief Move-constructs a %shared_ptr instance from @a __r.
25938fd1498Szrj * @param __r A %shared_ptr rvalue.
26038fd1498Szrj * @post *this contains the old value of @a __r, @a __r is empty.
26138fd1498Szrj */
26238fd1498Szrj template<typename _Yp, typename = _Constructible<shared_ptr<_Yp>>>
26338fd1498Szrj shared_ptr(shared_ptr<_Yp>&& __r) noexcept
26438fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { }
26538fd1498Szrj
26638fd1498Szrj /**
26738fd1498Szrj * @brief Constructs a %shared_ptr that shares ownership with @a __r
26838fd1498Szrj * and stores a copy of the pointer stored in @a __r.
26938fd1498Szrj * @param __r A weak_ptr.
27038fd1498Szrj * @post use_count() == __r.use_count()
27138fd1498Szrj * @throw bad_weak_ptr when __r.expired(),
27238fd1498Szrj * in which case the constructor has no effect.
27338fd1498Szrj */
27438fd1498Szrj template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
27538fd1498Szrj explicit shared_ptr(const weak_ptr<_Yp>& __r)
27638fd1498Szrj : __shared_ptr<_Tp>(__r) { }
27738fd1498Szrj
27838fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
27938fd1498Szrj #pragma GCC diagnostic push
28038fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
28138fd1498Szrj template<typename _Yp, typename = _Constructible<auto_ptr<_Yp>>>
28238fd1498Szrj shared_ptr(auto_ptr<_Yp>&& __r);
28338fd1498Szrj #pragma GCC diagnostic pop
28438fd1498Szrj #endif
28538fd1498Szrj
28638fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS
28738fd1498Szrj // 2399. shared_ptr's constructor from unique_ptr should be constrained
28838fd1498Szrj template<typename _Yp, typename _Del,
28938fd1498Szrj typename = _Constructible<unique_ptr<_Yp, _Del>>>
29038fd1498Szrj shared_ptr(unique_ptr<_Yp, _Del>&& __r)
29138fd1498Szrj : __shared_ptr<_Tp>(std::move(__r)) { }
29238fd1498Szrj
29338fd1498Szrj #if __cplusplus <= 201402L && _GLIBCXX_USE_DEPRECATED
29438fd1498Szrj // This non-standard constructor exists to support conversions that
29538fd1498Szrj // were possible in C++11 and C++14 but are ill-formed in C++17.
29638fd1498Szrj // If an exception is thrown this constructor has no effect.
29738fd1498Szrj template<typename _Yp, typename _Del,
29838fd1498Szrj _Constructible<unique_ptr<_Yp, _Del>, __sp_array_delete>* = 0>
29938fd1498Szrj shared_ptr(unique_ptr<_Yp, _Del>&& __r)
30038fd1498Szrj : __shared_ptr<_Tp>(std::move(__r), __sp_array_delete()) { }
30138fd1498Szrj #endif
30238fd1498Szrj
30338fd1498Szrj /**
30438fd1498Szrj * @brief Construct an empty %shared_ptr.
30538fd1498Szrj * @post use_count() == 0 && get() == nullptr
30638fd1498Szrj */
30738fd1498Szrj constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
30838fd1498Szrj
30938fd1498Szrj shared_ptr& operator=(const shared_ptr&) noexcept = default;
31038fd1498Szrj
31138fd1498Szrj template<typename _Yp>
31238fd1498Szrj _Assignable<const shared_ptr<_Yp>&>
31338fd1498Szrj operator=(const shared_ptr<_Yp>& __r) noexcept
31438fd1498Szrj {
31538fd1498Szrj this->__shared_ptr<_Tp>::operator=(__r);
31638fd1498Szrj return *this;
31738fd1498Szrj }
31838fd1498Szrj
31938fd1498Szrj #if _GLIBCXX_USE_DEPRECATED
32038fd1498Szrj #pragma GCC diagnostic push
32138fd1498Szrj #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
32238fd1498Szrj template<typename _Yp>
32338fd1498Szrj _Assignable<auto_ptr<_Yp>>
32438fd1498Szrj operator=(auto_ptr<_Yp>&& __r)
32538fd1498Szrj {
32638fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r));
32738fd1498Szrj return *this;
32838fd1498Szrj }
32938fd1498Szrj #pragma GCC diagnostic pop
33038fd1498Szrj #endif
33138fd1498Szrj
33238fd1498Szrj shared_ptr&
33338fd1498Szrj operator=(shared_ptr&& __r) noexcept
33438fd1498Szrj {
33538fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r));
33638fd1498Szrj return *this;
33738fd1498Szrj }
33838fd1498Szrj
33938fd1498Szrj template<class _Yp>
34038fd1498Szrj _Assignable<shared_ptr<_Yp>>
34138fd1498Szrj operator=(shared_ptr<_Yp>&& __r) noexcept
34238fd1498Szrj {
34338fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r));
34438fd1498Szrj return *this;
34538fd1498Szrj }
34638fd1498Szrj
34738fd1498Szrj template<typename _Yp, typename _Del>
34838fd1498Szrj _Assignable<unique_ptr<_Yp, _Del>>
34938fd1498Szrj operator=(unique_ptr<_Yp, _Del>&& __r)
35038fd1498Szrj {
35138fd1498Szrj this->__shared_ptr<_Tp>::operator=(std::move(__r));
35238fd1498Szrj return *this;
35338fd1498Szrj }
35438fd1498Szrj
35538fd1498Szrj private:
35638fd1498Szrj // This constructor is non-standard, it is used by allocate_shared.
35738fd1498Szrj template<typename _Alloc, typename... _Args>
358*58e805e6Szrj shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
359*58e805e6Szrj : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
36038fd1498Szrj { }
36138fd1498Szrj
36238fd1498Szrj template<typename _Yp, typename _Alloc, typename... _Args>
36338fd1498Szrj friend shared_ptr<_Yp>
36438fd1498Szrj allocate_shared(const _Alloc& __a, _Args&&... __args);
36538fd1498Szrj
36638fd1498Szrj // This constructor is non-standard, it is used by weak_ptr::lock().
36738fd1498Szrj shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
36838fd1498Szrj : __shared_ptr<_Tp>(__r, std::nothrow) { }
36938fd1498Szrj
37038fd1498Szrj friend class weak_ptr<_Tp>;
37138fd1498Szrj };
37238fd1498Szrj
37338fd1498Szrj #if __cpp_deduction_guides >= 201606
37438fd1498Szrj template<typename _Tp>
37538fd1498Szrj shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
37638fd1498Szrj template<typename _Tp, typename _Del>
37738fd1498Szrj shared_ptr(unique_ptr<_Tp, _Del>) -> shared_ptr<_Tp>;
37838fd1498Szrj #endif
37938fd1498Szrj
38038fd1498Szrj // 20.7.2.2.7 shared_ptr comparisons
38138fd1498Szrj template<typename _Tp, typename _Up>
38238fd1498Szrj inline bool
38338fd1498Szrj operator==(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
38438fd1498Szrj { return __a.get() == __b.get(); }
38538fd1498Szrj
38638fd1498Szrj template<typename _Tp>
38738fd1498Szrj inline bool
38838fd1498Szrj operator==(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
38938fd1498Szrj { return !__a; }
39038fd1498Szrj
39138fd1498Szrj template<typename _Tp>
39238fd1498Szrj inline bool
39338fd1498Szrj operator==(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
39438fd1498Szrj { return !__a; }
39538fd1498Szrj
39638fd1498Szrj template<typename _Tp, typename _Up>
39738fd1498Szrj inline bool
39838fd1498Szrj operator!=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
39938fd1498Szrj { return __a.get() != __b.get(); }
40038fd1498Szrj
40138fd1498Szrj template<typename _Tp>
40238fd1498Szrj inline bool
40338fd1498Szrj operator!=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
40438fd1498Szrj { return (bool)__a; }
40538fd1498Szrj
40638fd1498Szrj template<typename _Tp>
40738fd1498Szrj inline bool
40838fd1498Szrj operator!=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
40938fd1498Szrj { return (bool)__a; }
41038fd1498Szrj
41138fd1498Szrj template<typename _Tp, typename _Up>
41238fd1498Szrj inline bool
41338fd1498Szrj operator<(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
41438fd1498Szrj {
41538fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type;
41638fd1498Szrj using _Up_elt = typename shared_ptr<_Up>::element_type;
41738fd1498Szrj using _Vp = typename common_type<_Tp_elt*, _Up_elt*>::type;
41838fd1498Szrj return less<_Vp>()(__a.get(), __b.get());
41938fd1498Szrj }
42038fd1498Szrj
42138fd1498Szrj template<typename _Tp>
42238fd1498Szrj inline bool
42338fd1498Szrj operator<(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
42438fd1498Szrj {
42538fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type;
42638fd1498Szrj return less<_Tp_elt*>()(__a.get(), nullptr);
42738fd1498Szrj }
42838fd1498Szrj
42938fd1498Szrj template<typename _Tp>
43038fd1498Szrj inline bool
43138fd1498Szrj operator<(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
43238fd1498Szrj {
43338fd1498Szrj using _Tp_elt = typename shared_ptr<_Tp>::element_type;
43438fd1498Szrj return less<_Tp_elt*>()(nullptr, __a.get());
43538fd1498Szrj }
43638fd1498Szrj
43738fd1498Szrj template<typename _Tp, typename _Up>
43838fd1498Szrj inline bool
43938fd1498Szrj operator<=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
44038fd1498Szrj { return !(__b < __a); }
44138fd1498Szrj
44238fd1498Szrj template<typename _Tp>
44338fd1498Szrj inline bool
44438fd1498Szrj operator<=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
44538fd1498Szrj { return !(nullptr < __a); }
44638fd1498Szrj
44738fd1498Szrj template<typename _Tp>
44838fd1498Szrj inline bool
44938fd1498Szrj operator<=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
45038fd1498Szrj { return !(__a < nullptr); }
45138fd1498Szrj
45238fd1498Szrj template<typename _Tp, typename _Up>
45338fd1498Szrj inline bool
45438fd1498Szrj operator>(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
45538fd1498Szrj { return (__b < __a); }
45638fd1498Szrj
45738fd1498Szrj template<typename _Tp>
45838fd1498Szrj inline bool
45938fd1498Szrj operator>(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
46038fd1498Szrj { return nullptr < __a; }
46138fd1498Szrj
46238fd1498Szrj template<typename _Tp>
46338fd1498Szrj inline bool
46438fd1498Szrj operator>(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
46538fd1498Szrj { return __a < nullptr; }
46638fd1498Szrj
46738fd1498Szrj template<typename _Tp, typename _Up>
46838fd1498Szrj inline bool
46938fd1498Szrj operator>=(const shared_ptr<_Tp>& __a, const shared_ptr<_Up>& __b) noexcept
47038fd1498Szrj { return !(__a < __b); }
47138fd1498Szrj
47238fd1498Szrj template<typename _Tp>
47338fd1498Szrj inline bool
47438fd1498Szrj operator>=(const shared_ptr<_Tp>& __a, nullptr_t) noexcept
47538fd1498Szrj { return !(__a < nullptr); }
47638fd1498Szrj
47738fd1498Szrj template<typename _Tp>
47838fd1498Szrj inline bool
47938fd1498Szrj operator>=(nullptr_t, const shared_ptr<_Tp>& __a) noexcept
48038fd1498Szrj { return !(nullptr < __a); }
48138fd1498Szrj
48238fd1498Szrj template<typename _Tp>
48338fd1498Szrj struct less<shared_ptr<_Tp>> : public _Sp_less<shared_ptr<_Tp>>
48438fd1498Szrj { };
48538fd1498Szrj
48638fd1498Szrj // 20.7.2.2.8 shared_ptr specialized algorithms.
48738fd1498Szrj template<typename _Tp>
48838fd1498Szrj inline void
48938fd1498Szrj swap(shared_ptr<_Tp>& __a, shared_ptr<_Tp>& __b) noexcept
49038fd1498Szrj { __a.swap(__b); }
49138fd1498Szrj
49238fd1498Szrj // 20.7.2.2.9 shared_ptr casts.
49338fd1498Szrj template<typename _Tp, typename _Up>
49438fd1498Szrj inline shared_ptr<_Tp>
49538fd1498Szrj static_pointer_cast(const shared_ptr<_Up>& __r) noexcept
49638fd1498Szrj {
49738fd1498Szrj using _Sp = shared_ptr<_Tp>;
49838fd1498Szrj return _Sp(__r, static_cast<typename _Sp::element_type*>(__r.get()));
49938fd1498Szrj }
50038fd1498Szrj
50138fd1498Szrj template<typename _Tp, typename _Up>
50238fd1498Szrj inline shared_ptr<_Tp>
50338fd1498Szrj const_pointer_cast(const shared_ptr<_Up>& __r) noexcept
50438fd1498Szrj {
50538fd1498Szrj using _Sp = shared_ptr<_Tp>;
50638fd1498Szrj return _Sp(__r, const_cast<typename _Sp::element_type*>(__r.get()));
50738fd1498Szrj }
50838fd1498Szrj
50938fd1498Szrj template<typename _Tp, typename _Up>
51038fd1498Szrj inline shared_ptr<_Tp>
51138fd1498Szrj dynamic_pointer_cast(const shared_ptr<_Up>& __r) noexcept
51238fd1498Szrj {
51338fd1498Szrj using _Sp = shared_ptr<_Tp>;
51438fd1498Szrj if (auto* __p = dynamic_cast<typename _Sp::element_type*>(__r.get()))
51538fd1498Szrj return _Sp(__r, __p);
51638fd1498Szrj return _Sp();
51738fd1498Szrj }
51838fd1498Szrj
51938fd1498Szrj #if __cplusplus > 201402L
52038fd1498Szrj template<typename _Tp, typename _Up>
52138fd1498Szrj inline shared_ptr<_Tp>
52238fd1498Szrj reinterpret_pointer_cast(const shared_ptr<_Up>& __r) noexcept
52338fd1498Szrj {
52438fd1498Szrj using _Sp = shared_ptr<_Tp>;
52538fd1498Szrj return _Sp(__r, reinterpret_cast<typename _Sp::element_type*>(__r.get()));
52638fd1498Szrj }
52738fd1498Szrj #endif
52838fd1498Szrj
52938fd1498Szrj /**
53038fd1498Szrj * @brief A smart pointer with weak semantics.
53138fd1498Szrj *
53238fd1498Szrj * With forwarding constructors and assignment operators.
53338fd1498Szrj */
53438fd1498Szrj template<typename _Tp>
53538fd1498Szrj class weak_ptr : public __weak_ptr<_Tp>
53638fd1498Szrj {
53738fd1498Szrj template<typename _Arg>
53838fd1498Szrj using _Constructible = typename enable_if<
53938fd1498Szrj is_constructible<__weak_ptr<_Tp>, _Arg>::value
54038fd1498Szrj >::type;
54138fd1498Szrj
54238fd1498Szrj template<typename _Arg>
54338fd1498Szrj using _Assignable = typename enable_if<
54438fd1498Szrj is_assignable<__weak_ptr<_Tp>&, _Arg>::value, weak_ptr&
54538fd1498Szrj >::type;
54638fd1498Szrj
54738fd1498Szrj public:
54838fd1498Szrj constexpr weak_ptr() noexcept = default;
54938fd1498Szrj
55038fd1498Szrj template<typename _Yp,
55138fd1498Szrj typename = _Constructible<const shared_ptr<_Yp>&>>
55238fd1498Szrj weak_ptr(const shared_ptr<_Yp>& __r) noexcept
55338fd1498Szrj : __weak_ptr<_Tp>(__r) { }
55438fd1498Szrj
55538fd1498Szrj weak_ptr(const weak_ptr&) noexcept = default;
55638fd1498Szrj
55738fd1498Szrj template<typename _Yp, typename = _Constructible<const weak_ptr<_Yp>&>>
55838fd1498Szrj weak_ptr(const weak_ptr<_Yp>& __r) noexcept
55938fd1498Szrj : __weak_ptr<_Tp>(__r) { }
56038fd1498Szrj
56138fd1498Szrj weak_ptr(weak_ptr&&) noexcept = default;
56238fd1498Szrj
56338fd1498Szrj template<typename _Yp, typename = _Constructible<weak_ptr<_Yp>>>
56438fd1498Szrj weak_ptr(weak_ptr<_Yp>&& __r) noexcept
56538fd1498Szrj : __weak_ptr<_Tp>(std::move(__r)) { }
56638fd1498Szrj
56738fd1498Szrj weak_ptr&
56838fd1498Szrj operator=(const weak_ptr& __r) noexcept = default;
56938fd1498Szrj
57038fd1498Szrj template<typename _Yp>
57138fd1498Szrj _Assignable<const weak_ptr<_Yp>&>
57238fd1498Szrj operator=(const weak_ptr<_Yp>& __r) noexcept
57338fd1498Szrj {
57438fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r);
57538fd1498Szrj return *this;
57638fd1498Szrj }
57738fd1498Szrj
57838fd1498Szrj template<typename _Yp>
57938fd1498Szrj _Assignable<const shared_ptr<_Yp>&>
58038fd1498Szrj operator=(const shared_ptr<_Yp>& __r) noexcept
58138fd1498Szrj {
58238fd1498Szrj this->__weak_ptr<_Tp>::operator=(__r);
58338fd1498Szrj return *this;
58438fd1498Szrj }
58538fd1498Szrj
58638fd1498Szrj weak_ptr&
58738fd1498Szrj operator=(weak_ptr&& __r) noexcept = default;
58838fd1498Szrj
58938fd1498Szrj template<typename _Yp>
59038fd1498Szrj _Assignable<weak_ptr<_Yp>>
59138fd1498Szrj operator=(weak_ptr<_Yp>&& __r) noexcept
59238fd1498Szrj {
59338fd1498Szrj this->__weak_ptr<_Tp>::operator=(std::move(__r));
59438fd1498Szrj return *this;
59538fd1498Szrj }
59638fd1498Szrj
59738fd1498Szrj shared_ptr<_Tp>
59838fd1498Szrj lock() const noexcept
59938fd1498Szrj { return shared_ptr<_Tp>(*this, std::nothrow); }
60038fd1498Szrj };
60138fd1498Szrj
60238fd1498Szrj #if __cpp_deduction_guides >= 201606
60338fd1498Szrj template<typename _Tp>
60438fd1498Szrj weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
60538fd1498Szrj #endif
60638fd1498Szrj
60738fd1498Szrj // 20.7.2.3.6 weak_ptr specialized algorithms.
60838fd1498Szrj template<typename _Tp>
60938fd1498Szrj inline void
61038fd1498Szrj swap(weak_ptr<_Tp>& __a, weak_ptr<_Tp>& __b) noexcept
61138fd1498Szrj { __a.swap(__b); }
61238fd1498Szrj
61338fd1498Szrj
61438fd1498Szrj /// Primary template owner_less
61538fd1498Szrj template<typename _Tp = void>
61638fd1498Szrj struct owner_less;
61738fd1498Szrj
61838fd1498Szrj /// Void specialization of owner_less
61938fd1498Szrj template<>
62038fd1498Szrj struct owner_less<void> : _Sp_owner_less<void, void>
62138fd1498Szrj { };
62238fd1498Szrj
62338fd1498Szrj /// Partial specialization of owner_less for shared_ptr.
62438fd1498Szrj template<typename _Tp>
62538fd1498Szrj struct owner_less<shared_ptr<_Tp>>
62638fd1498Szrj : public _Sp_owner_less<shared_ptr<_Tp>, weak_ptr<_Tp>>
62738fd1498Szrj { };
62838fd1498Szrj
62938fd1498Szrj /// Partial specialization of owner_less for weak_ptr.
63038fd1498Szrj template<typename _Tp>
63138fd1498Szrj struct owner_less<weak_ptr<_Tp>>
63238fd1498Szrj : public _Sp_owner_less<weak_ptr<_Tp>, shared_ptr<_Tp>>
63338fd1498Szrj { };
63438fd1498Szrj
63538fd1498Szrj /**
63638fd1498Szrj * @brief Base class allowing use of member function shared_from_this.
63738fd1498Szrj */
63838fd1498Szrj template<typename _Tp>
63938fd1498Szrj class enable_shared_from_this
64038fd1498Szrj {
64138fd1498Szrj protected:
64238fd1498Szrj constexpr enable_shared_from_this() noexcept { }
64338fd1498Szrj
64438fd1498Szrj enable_shared_from_this(const enable_shared_from_this&) noexcept { }
64538fd1498Szrj
64638fd1498Szrj enable_shared_from_this&
64738fd1498Szrj operator=(const enable_shared_from_this&) noexcept
64838fd1498Szrj { return *this; }
64938fd1498Szrj
65038fd1498Szrj ~enable_shared_from_this() { }
65138fd1498Szrj
65238fd1498Szrj public:
65338fd1498Szrj shared_ptr<_Tp>
65438fd1498Szrj shared_from_this()
65538fd1498Szrj { return shared_ptr<_Tp>(this->_M_weak_this); }
65638fd1498Szrj
65738fd1498Szrj shared_ptr<const _Tp>
65838fd1498Szrj shared_from_this() const
65938fd1498Szrj { return shared_ptr<const _Tp>(this->_M_weak_this); }
66038fd1498Szrj
66138fd1498Szrj #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
66238fd1498Szrj #define __cpp_lib_enable_shared_from_this 201603
66338fd1498Szrj weak_ptr<_Tp>
66438fd1498Szrj weak_from_this() noexcept
66538fd1498Szrj { return this->_M_weak_this; }
66638fd1498Szrj
66738fd1498Szrj weak_ptr<const _Tp>
66838fd1498Szrj weak_from_this() const noexcept
66938fd1498Szrj { return this->_M_weak_this; }
67038fd1498Szrj #endif
67138fd1498Szrj
67238fd1498Szrj private:
67338fd1498Szrj template<typename _Tp1>
67438fd1498Szrj void
67538fd1498Szrj _M_weak_assign(_Tp1* __p, const __shared_count<>& __n) const noexcept
67638fd1498Szrj { _M_weak_this._M_assign(__p, __n); }
67738fd1498Szrj
67838fd1498Szrj // Found by ADL when this is an associated class.
67938fd1498Szrj friend const enable_shared_from_this*
68038fd1498Szrj __enable_shared_from_this_base(const __shared_count<>&,
68138fd1498Szrj const enable_shared_from_this* __p)
68238fd1498Szrj { return __p; }
68338fd1498Szrj
68438fd1498Szrj template<typename, _Lock_policy>
68538fd1498Szrj friend class __shared_ptr;
68638fd1498Szrj
68738fd1498Szrj mutable weak_ptr<_Tp> _M_weak_this;
68838fd1498Szrj };
68938fd1498Szrj
69038fd1498Szrj /**
69138fd1498Szrj * @brief Create an object that is owned by a shared_ptr.
69238fd1498Szrj * @param __a An allocator.
69338fd1498Szrj * @param __args Arguments for the @a _Tp object's constructor.
69438fd1498Szrj * @return A shared_ptr that owns the newly created object.
69538fd1498Szrj * @throw An exception thrown from @a _Alloc::allocate or from the
69638fd1498Szrj * constructor of @a _Tp.
69738fd1498Szrj *
69838fd1498Szrj * A copy of @a __a will be used to allocate memory for the shared_ptr
69938fd1498Szrj * and the new object.
70038fd1498Szrj */
70138fd1498Szrj template<typename _Tp, typename _Alloc, typename... _Args>
70238fd1498Szrj inline shared_ptr<_Tp>
70338fd1498Szrj allocate_shared(const _Alloc& __a, _Args&&... __args)
70438fd1498Szrj {
705*58e805e6Szrj return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
70638fd1498Szrj std::forward<_Args>(__args)...);
70738fd1498Szrj }
70838fd1498Szrj
70938fd1498Szrj /**
71038fd1498Szrj * @brief Create an object that is owned by a shared_ptr.
71138fd1498Szrj * @param __args Arguments for the @a _Tp object's constructor.
71238fd1498Szrj * @return A shared_ptr that owns the newly created object.
71338fd1498Szrj * @throw std::bad_alloc, or an exception thrown from the
71438fd1498Szrj * constructor of @a _Tp.
71538fd1498Szrj */
71638fd1498Szrj template<typename _Tp, typename... _Args>
71738fd1498Szrj inline shared_ptr<_Tp>
71838fd1498Szrj make_shared(_Args&&... __args)
71938fd1498Szrj {
720*58e805e6Szrj typedef typename std::remove_cv<_Tp>::type _Tp_nc;
72138fd1498Szrj return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
72238fd1498Szrj std::forward<_Args>(__args)...);
72338fd1498Szrj }
72438fd1498Szrj
72538fd1498Szrj /// std::hash specialization for shared_ptr.
72638fd1498Szrj template<typename _Tp>
72738fd1498Szrj struct hash<shared_ptr<_Tp>>
72838fd1498Szrj : public __hash_base<size_t, shared_ptr<_Tp>>
72938fd1498Szrj {
73038fd1498Szrj size_t
73138fd1498Szrj operator()(const shared_ptr<_Tp>& __s) const noexcept
73238fd1498Szrj {
73338fd1498Szrj return std::hash<typename shared_ptr<_Tp>::element_type*>()(__s.get());
73438fd1498Szrj }
73538fd1498Szrj };
73638fd1498Szrj
73738fd1498Szrj // @} group pointer_abstractions
73838fd1498Szrj
73938fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION
74038fd1498Szrj } // namespace
74138fd1498Szrj
74238fd1498Szrj #endif // _SHARED_PTR_H
743