xref: /llvm-project-15.0.7/libcxx/include/memory (revision 092e8a7e)
13e519524SHoward Hinnant// -*- C++ -*-
23e519524SHoward Hinnant//===-------------------------- memory ------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_MEMORY
113e519524SHoward Hinnant#define _LIBCPP_MEMORY
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    memory synopsis
153e519524SHoward Hinnant
163e519524SHoward Hinnantnamespace std
173e519524SHoward Hinnant{
183e519524SHoward Hinnant
193e519524SHoward Hinnantstruct allocator_arg_t { };
2040a01d53SMarshall Clowinline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
213e519524SHoward Hinnant
223e519524SHoward Hinnanttemplate <class T, class Alloc> struct uses_allocator;
233e519524SHoward Hinnant
243e519524SHoward Hinnanttemplate <class Ptr>
253e519524SHoward Hinnantstruct pointer_traits
263e519524SHoward Hinnant{
273e519524SHoward Hinnant    typedef Ptr pointer;
283e519524SHoward Hinnant    typedef <details> element_type;
293e519524SHoward Hinnant    typedef <details> difference_type;
303e519524SHoward Hinnant
313e519524SHoward Hinnant    template <class U> using rebind = <details>;
323e519524SHoward Hinnant
333e519524SHoward Hinnant    static pointer pointer_to(<details>);
343e519524SHoward Hinnant};
353e519524SHoward Hinnant
363739fe79SHoward Hinnanttemplate <class T>
373739fe79SHoward Hinnantstruct pointer_traits<T*>
383739fe79SHoward Hinnant{
393739fe79SHoward Hinnant    typedef T* pointer;
403739fe79SHoward Hinnant    typedef T element_type;
413739fe79SHoward Hinnant    typedef ptrdiff_t difference_type;
423739fe79SHoward Hinnant
433739fe79SHoward Hinnant    template <class U> using rebind = U*;
443739fe79SHoward Hinnant
4572720269SLouis Dionne    static pointer pointer_to(<details>) noexcept; // constexpr in C++20
463739fe79SHoward Hinnant};
473739fe79SHoward Hinnant
4832952747SEric Fiseliertemplate <class T> constexpr T* to_address(T* p) noexcept; // C++20
49f6326736SMarek Kurdejtemplate <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // C++20
5032952747SEric Fiselier
513e519524SHoward Hinnanttemplate <class Alloc>
523e519524SHoward Hinnantstruct allocator_traits
533e519524SHoward Hinnant{
543e519524SHoward Hinnant    typedef Alloc                        allocator_type;
553e519524SHoward Hinnant    typedef typename allocator_type::value_type
563e519524SHoward Hinnant                                         value_type;
573e519524SHoward Hinnant
583e519524SHoward Hinnant    typedef Alloc::pointer | value_type* pointer;
593e519524SHoward Hinnant    typedef Alloc::const_pointer
603e519524SHoward Hinnant          | pointer_traits<pointer>::rebind<const value_type>
613e519524SHoward Hinnant                                         const_pointer;
623e519524SHoward Hinnant    typedef Alloc::void_pointer
633e519524SHoward Hinnant          | pointer_traits<pointer>::rebind<void>
643e519524SHoward Hinnant                                         void_pointer;
653e519524SHoward Hinnant    typedef Alloc::const_void_pointer
663e519524SHoward Hinnant          | pointer_traits<pointer>::rebind<const void>
673e519524SHoward Hinnant                                         const_void_pointer;
683e519524SHoward Hinnant    typedef Alloc::difference_type
69a4a1ef1fSHoward Hinnant          | pointer_traits<pointer>::difference_type
70a4a1ef1fSHoward Hinnant                                         difference_type;
71a4a1ef1fSHoward Hinnant    typedef Alloc::size_type
72a4a1ef1fSHoward Hinnant          | make_unsigned<difference_type>::type
73a4a1ef1fSHoward Hinnant                                         size_type;
743e519524SHoward Hinnant    typedef Alloc::propagate_on_container_copy_assignment
753e519524SHoward Hinnant          | false_type                   propagate_on_container_copy_assignment;
763e519524SHoward Hinnant    typedef Alloc::propagate_on_container_move_assignment
773e519524SHoward Hinnant          | false_type                   propagate_on_container_move_assignment;
783e519524SHoward Hinnant    typedef Alloc::propagate_on_container_swap
793e519524SHoward Hinnant          | false_type                   propagate_on_container_swap;
8031a47313SMarshall Clow    typedef Alloc::is_always_equal
8131a47313SMarshall Clow          | is_empty                     is_always_equal;
823e519524SHoward Hinnant
835b1e5b43SMichael Park    template <class T> using rebind_alloc  = Alloc::rebind<T>::other | Alloc<T, Args...>;
843e519524SHoward Hinnant    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
853e519524SHoward Hinnant
860724f8bfSLouis Dionne    static pointer allocate(allocator_type& a, size_type n);                          // constexpr and [[nodiscard]] in C++20
870724f8bfSLouis Dionne    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20
883e519524SHoward Hinnant
890724f8bfSLouis Dionne    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20
903e519524SHoward Hinnant
913e519524SHoward Hinnant    template <class T, class... Args>
920724f8bfSLouis Dionne    static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20
933e519524SHoward Hinnant
943e519524SHoward Hinnant    template <class T>
950724f8bfSLouis Dionne    static void destroy(allocator_type& a, T* p); // constexpr in C++20
963e519524SHoward Hinnant
970724f8bfSLouis Dionne    static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20
980724f8bfSLouis Dionne    static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20
993e519524SHoward Hinnant};
1003e519524SHoward Hinnant
1013e519524SHoward Hinnanttemplate <>
1025b1e5b43SMichael Parkclass allocator<void> // deprecated in C++17, removed in C++20
1033e519524SHoward Hinnant{
1043e519524SHoward Hinnantpublic:
1053e519524SHoward Hinnant    typedef void*                                 pointer;
1063e519524SHoward Hinnant    typedef const void*                           const_pointer;
1073e519524SHoward Hinnant    typedef void                                  value_type;
1083e519524SHoward Hinnant
1093e519524SHoward Hinnant    template <class _Up> struct rebind {typedef allocator<_Up> other;};
1103e519524SHoward Hinnant};
1113e519524SHoward Hinnant
1123e519524SHoward Hinnanttemplate <class T>
1133e519524SHoward Hinnantclass allocator
1143e519524SHoward Hinnant{
1153e519524SHoward Hinnantpublic:
116316d336dSLouis Dionne    typedef size_t    size_type;
117316d336dSLouis Dionne    typedef ptrdiff_t difference_type;
1185b1e5b43SMichael Park    typedef T*        pointer;                           // deprecated in C++17, removed in C++20
1195b1e5b43SMichael Park    typedef const T*  const_pointer;                     // deprecated in C++17, removed in C++20
1205b1e5b43SMichael Park    typedef typename add_lvalue_reference<T>::type
1215b1e5b43SMichael Park                      reference;                         // deprecated in C++17, removed in C++20
1225b1e5b43SMichael Park    typedef typename add_lvalue_reference<const T>::type
1235b1e5b43SMichael Park                      const_reference;                   // deprecated in C++17, removed in C++20
1245b1e5b43SMichael Park
1253e519524SHoward Hinnant    typedef T         value_type;
1263e519524SHoward Hinnant
1275b1e5b43SMichael Park    template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20
1285b1e5b43SMichael Park
1295b1e5b43SMichael Park    typedef true_type propagate_on_container_move_assignment;
1305b1e5b43SMichael Park    typedef true_type is_always_equal;
1313e519524SHoward Hinnant
132e0742c4aSMarshall Clow    constexpr allocator() noexcept;                      // constexpr in C++20
133e0742c4aSMarshall Clow    constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
134e0742c4aSMarshall Clow    template <class U>
135e0742c4aSMarshall Clow      constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
1360724f8bfSLouis Dionne    ~allocator();                                        // constexpr in C++20
1375b1e5b43SMichael Park    pointer address(reference x) const noexcept;             // deprecated in C++17, removed in C++20
1385b1e5b43SMichael Park    const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20
1395b1e5b43SMichael Park    T* allocate(size_t n, const void* hint);          // deprecated in C++17, removed in C++20
1400724f8bfSLouis Dionne    T* allocate(size_t n);                              // constexpr in C++20
1410724f8bfSLouis Dionne    void deallocate(T* p, size_t n) noexcept;           // constexpr in C++20
1425b1e5b43SMichael Park    size_type max_size() const noexcept;              // deprecated in C++17, removed in C++20
1433739fe79SHoward Hinnant    template<class U, class... Args>
1445b1e5b43SMichael Park        void construct(U* p, Args&&... args);         // deprecated in C++17, removed in C++20
1453739fe79SHoward Hinnant    template <class U>
1465b1e5b43SMichael Park        void destroy(U* p);                           // deprecated in C++17, removed in C++20
1473e519524SHoward Hinnant};
1483e519524SHoward Hinnant
1493e519524SHoward Hinnanttemplate <class T, class U>
1500724f8bfSLouis Dionnebool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
1513e519524SHoward Hinnant
1523e519524SHoward Hinnanttemplate <class T, class U>
1530724f8bfSLouis Dionnebool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
1543e519524SHoward Hinnant
1553e519524SHoward Hinnanttemplate <class OutputIterator, class T>
1563e519524SHoward Hinnantclass raw_storage_iterator
1573e519524SHoward Hinnant    : public iterator<output_iterator_tag,
1583e519524SHoward Hinnant                      T,                               // purposefully not C++03
1593e519524SHoward Hinnant                      ptrdiff_t,                       // purposefully not C++03
1603e519524SHoward Hinnant                      T*,                              // purposefully not C++03
1613e519524SHoward Hinnant                      raw_storage_iterator&>           // purposefully not C++03
1623e519524SHoward Hinnant{
1633e519524SHoward Hinnantpublic:
1643e519524SHoward Hinnant    explicit raw_storage_iterator(OutputIterator x);
1653e519524SHoward Hinnant    raw_storage_iterator& operator*();
1663e519524SHoward Hinnant    raw_storage_iterator& operator=(const T& element);
1673e519524SHoward Hinnant    raw_storage_iterator& operator++();
1683e519524SHoward Hinnant    raw_storage_iterator  operator++(int);
1693e519524SHoward Hinnant};
1703e519524SHoward Hinnant
1713739fe79SHoward Hinnanttemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
1723739fe79SHoward Hinnanttemplate <class T> void               return_temporary_buffer(T* p) noexcept;
1733739fe79SHoward Hinnant
1743739fe79SHoward Hinnanttemplate <class T> T* addressof(T& r) noexcept;
1751c7fe126SMarshall Clowtemplate <class T> T* addressof(const T&& r) noexcept = delete;
1763e519524SHoward Hinnant
1773e519524SHoward Hinnanttemplate <class InputIterator, class ForwardIterator>
1783e519524SHoward HinnantForwardIterator
1793e519524SHoward Hinnantuninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
1803e519524SHoward Hinnant
1813739fe79SHoward Hinnanttemplate <class InputIterator, class Size, class ForwardIterator>
1823739fe79SHoward HinnantForwardIterator
1833739fe79SHoward Hinnantuninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
1843739fe79SHoward Hinnant
1853e519524SHoward Hinnanttemplate <class ForwardIterator, class T>
1863e519524SHoward Hinnantvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
1873e519524SHoward Hinnant
1883e519524SHoward Hinnanttemplate <class ForwardIterator, class Size, class T>
18948d05bd2SHoward HinnantForwardIterator
19048d05bd2SHoward Hinnantuninitialized_fill_n(ForwardIterator first, Size n, const T& x);
1913e519524SHoward Hinnant
1920724f8bfSLouis Dionnetemplate <class T, class ...Args>
1930724f8bfSLouis Dionneconstexpr T* construct_at(T* location, Args&& ...args); // since C++20
1940724f8bfSLouis Dionne
195e4d9c316SEric Fiseliertemplate <class T>
1960724f8bfSLouis Dionnevoid destroy_at(T* location); // constexpr in C++20
197e4d9c316SEric Fiselier
198e4d9c316SEric Fiseliertemplate <class ForwardIterator>
1990724f8bfSLouis Dionnevoid destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20
200e4d9c316SEric Fiselier
201e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size>
2020724f8bfSLouis DionneForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20
203e4d9c316SEric Fiselier
204e4d9c316SEric Fiseliertemplate <class InputIterator, class ForwardIterator>
205e4d9c316SEric Fiselier ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
206e4d9c316SEric Fiselier
207e4d9c316SEric Fiseliertemplate <class InputIterator, class Size, class ForwardIterator>
208e4d9c316SEric Fiselier pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
209e4d9c316SEric Fiselier
210e4d9c316SEric Fiseliertemplate <class ForwardIterator>
211e4d9c316SEric Fiselier void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
212e4d9c316SEric Fiselier
213e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size>
214e4d9c316SEric Fiselier ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
215e4d9c316SEric Fiselier
216e4d9c316SEric Fiseliertemplate <class ForwardIterator>
217e4d9c316SEric Fiselier void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
218e4d9c316SEric Fiselier
219e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size>
220e4d9c316SEric Fiselier ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
221e4d9c316SEric Fiselier
222ea5cd3b4SLouis Dionnetemplate <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17
2233e519524SHoward Hinnant
2243e519524SHoward Hinnanttemplate<class X>
225ea5cd3b4SLouis Dionneclass auto_ptr                                  // deprecated in C++11, removed in C++17
2263e519524SHoward Hinnant{
2273e519524SHoward Hinnantpublic:
2283e519524SHoward Hinnant    typedef X element_type;
2293e519524SHoward Hinnant
2303e519524SHoward Hinnant    explicit auto_ptr(X* p =0) throw();
2313e519524SHoward Hinnant    auto_ptr(auto_ptr&) throw();
2323e519524SHoward Hinnant    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
2333e519524SHoward Hinnant    auto_ptr& operator=(auto_ptr&) throw();
2343e519524SHoward Hinnant    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
2353e519524SHoward Hinnant    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
2363e519524SHoward Hinnant    ~auto_ptr() throw();
2373e519524SHoward Hinnant
2383e519524SHoward Hinnant    typename add_lvalue_reference<X>::type operator*() const throw();
2393e519524SHoward Hinnant    X* operator->() const throw();
2403e519524SHoward Hinnant    X* get() const throw();
2413e519524SHoward Hinnant    X* release() throw();
2423e519524SHoward Hinnant    void reset(X* p =0) throw();
2433e519524SHoward Hinnant
2443e519524SHoward Hinnant    auto_ptr(auto_ptr_ref<X>) throw();
2453e519524SHoward Hinnant    template<class Y> operator auto_ptr_ref<Y>() throw();
2463e519524SHoward Hinnant    template<class Y> operator auto_ptr<Y>() throw();
2473e519524SHoward Hinnant};
2483e519524SHoward Hinnant
24920cc2a42SHoward Hinnanttemplate <class T>
25020cc2a42SHoward Hinnantstruct default_delete
25120cc2a42SHoward Hinnant{
2523739fe79SHoward Hinnant    constexpr default_delete() noexcept = default;
2533739fe79SHoward Hinnant    template <class U> default_delete(const default_delete<U>&) noexcept;
25420cc2a42SHoward Hinnant
2553739fe79SHoward Hinnant    void operator()(T*) const noexcept;
25620cc2a42SHoward Hinnant};
25720cc2a42SHoward Hinnant
25820cc2a42SHoward Hinnanttemplate <class T>
25920cc2a42SHoward Hinnantstruct default_delete<T[]>
26020cc2a42SHoward Hinnant{
2613739fe79SHoward Hinnant    constexpr default_delete() noexcept = default;
2623739fe79SHoward Hinnant    void operator()(T*) const noexcept;
26320cc2a42SHoward Hinnant    template <class U> void operator()(U*) const = delete;
26420cc2a42SHoward Hinnant};
26520cc2a42SHoward Hinnant
26620cc2a42SHoward Hinnanttemplate <class T, class D = default_delete<T>>
26720cc2a42SHoward Hinnantclass unique_ptr
26820cc2a42SHoward Hinnant{
26920cc2a42SHoward Hinnantpublic:
27020cc2a42SHoward Hinnant    typedef see below pointer;
27120cc2a42SHoward Hinnant    typedef T element_type;
27220cc2a42SHoward Hinnant    typedef D deleter_type;
27320cc2a42SHoward Hinnant
27420cc2a42SHoward Hinnant    // constructors
2753739fe79SHoward Hinnant    constexpr unique_ptr() noexcept;
2763739fe79SHoward Hinnant    explicit unique_ptr(pointer p) noexcept;
2773739fe79SHoward Hinnant    unique_ptr(pointer p, see below d1) noexcept;
2783739fe79SHoward Hinnant    unique_ptr(pointer p, see below d2) noexcept;
2793739fe79SHoward Hinnant    unique_ptr(unique_ptr&& u) noexcept;
2803739fe79SHoward Hinnant    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
28120cc2a42SHoward Hinnant    template <class U, class E>
2823739fe79SHoward Hinnant        unique_ptr(unique_ptr<U, E>&& u) noexcept;
28320cc2a42SHoward Hinnant    template <class U>
284e67179bcSMarshall Clow        unique_ptr(auto_ptr<U>&& u) noexcept;       // removed in C++17
28520cc2a42SHoward Hinnant
28620cc2a42SHoward Hinnant    // destructor
28720cc2a42SHoward Hinnant    ~unique_ptr();
28820cc2a42SHoward Hinnant
28920cc2a42SHoward Hinnant    // assignment
2903739fe79SHoward Hinnant    unique_ptr& operator=(unique_ptr&& u) noexcept;
2913739fe79SHoward Hinnant    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
2923739fe79SHoward Hinnant    unique_ptr& operator=(nullptr_t) noexcept;
29320cc2a42SHoward Hinnant
29420cc2a42SHoward Hinnant    // observers
29520cc2a42SHoward Hinnant    typename add_lvalue_reference<T>::type operator*() const;
2963739fe79SHoward Hinnant    pointer operator->() const noexcept;
2973739fe79SHoward Hinnant    pointer get() const noexcept;
2983739fe79SHoward Hinnant    deleter_type& get_deleter() noexcept;
2993739fe79SHoward Hinnant    const deleter_type& get_deleter() const noexcept;
3003739fe79SHoward Hinnant    explicit operator bool() const noexcept;
30120cc2a42SHoward Hinnant
30220cc2a42SHoward Hinnant    // modifiers
3033739fe79SHoward Hinnant    pointer release() noexcept;
3043739fe79SHoward Hinnant    void reset(pointer p = pointer()) noexcept;
3053739fe79SHoward Hinnant    void swap(unique_ptr& u) noexcept;
30620cc2a42SHoward Hinnant};
30720cc2a42SHoward Hinnant
30820cc2a42SHoward Hinnanttemplate <class T, class D>
30920cc2a42SHoward Hinnantclass unique_ptr<T[], D>
31020cc2a42SHoward Hinnant{
31120cc2a42SHoward Hinnantpublic:
31220cc2a42SHoward Hinnant    typedef implementation-defined pointer;
31320cc2a42SHoward Hinnant    typedef T element_type;
31420cc2a42SHoward Hinnant    typedef D deleter_type;
31520cc2a42SHoward Hinnant
31620cc2a42SHoward Hinnant    // constructors
3173739fe79SHoward Hinnant    constexpr unique_ptr() noexcept;
3183739fe79SHoward Hinnant    explicit unique_ptr(pointer p) noexcept;
3193739fe79SHoward Hinnant    unique_ptr(pointer p, see below d) noexcept;
3203739fe79SHoward Hinnant    unique_ptr(pointer p, see below d) noexcept;
3213739fe79SHoward Hinnant    unique_ptr(unique_ptr&& u) noexcept;
3223739fe79SHoward Hinnant    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
32320cc2a42SHoward Hinnant
32420cc2a42SHoward Hinnant    // destructor
325b3371f6fSHoward Hinnant    ~unique_ptr();
32620cc2a42SHoward Hinnant
32720cc2a42SHoward Hinnant    // assignment
3283739fe79SHoward Hinnant    unique_ptr& operator=(unique_ptr&& u) noexcept;
3293739fe79SHoward Hinnant    unique_ptr& operator=(nullptr_t) noexcept;
33020cc2a42SHoward Hinnant
33120cc2a42SHoward Hinnant    // observers
33220cc2a42SHoward Hinnant    T& operator[](size_t i) const;
3333739fe79SHoward Hinnant    pointer get() const noexcept;
3343739fe79SHoward Hinnant    deleter_type& get_deleter() noexcept;
3353739fe79SHoward Hinnant    const deleter_type& get_deleter() const noexcept;
3363739fe79SHoward Hinnant    explicit operator bool() const noexcept;
33720cc2a42SHoward Hinnant
33820cc2a42SHoward Hinnant    // modifiers
3393739fe79SHoward Hinnant    pointer release() noexcept;
3403739fe79SHoward Hinnant    void reset(pointer p = pointer()) noexcept;
3413739fe79SHoward Hinnant    void reset(nullptr_t) noexcept;
34220cc2a42SHoward Hinnant  template <class U> void reset(U) = delete;
3433739fe79SHoward Hinnant    void swap(unique_ptr& u) noexcept;
34420cc2a42SHoward Hinnant};
34520cc2a42SHoward Hinnant
34620cc2a42SHoward Hinnanttemplate <class T, class D>
3473739fe79SHoward Hinnant    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
34820cc2a42SHoward Hinnant
34920cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
35020cc2a42SHoward Hinnant    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
35120cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
35220cc2a42SHoward Hinnant    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
35320cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
35420cc2a42SHoward Hinnant    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
35520cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
35620cc2a42SHoward Hinnant    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
35720cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
35820cc2a42SHoward Hinnant    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
35920cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
36020cc2a42SHoward Hinnant    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
36120cc2a42SHoward Hinnant
3623739fe79SHoward Hinnanttemplate <class T, class D>
3633739fe79SHoward Hinnant    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3643739fe79SHoward Hinnanttemplate <class T, class D>
3653739fe79SHoward Hinnant    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3663739fe79SHoward Hinnanttemplate <class T, class D>
3673739fe79SHoward Hinnant    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3683739fe79SHoward Hinnanttemplate <class T, class D>
3693739fe79SHoward Hinnant    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3703739fe79SHoward Hinnant
3713739fe79SHoward Hinnanttemplate <class T, class D>
3723739fe79SHoward Hinnant    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
3733739fe79SHoward Hinnanttemplate <class T, class D>
3743739fe79SHoward Hinnant    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
3753739fe79SHoward Hinnanttemplate <class T, class D>
3763739fe79SHoward Hinnant    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
3773739fe79SHoward Hinnanttemplate <class T, class D>
3783739fe79SHoward Hinnant    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
3793739fe79SHoward Hinnanttemplate <class T, class D>
3803739fe79SHoward Hinnant    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
3813739fe79SHoward Hinnanttemplate <class T, class D>
3823739fe79SHoward Hinnant    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
3833739fe79SHoward Hinnanttemplate <class T, class D>
3843739fe79SHoward Hinnant    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
3853739fe79SHoward Hinnanttemplate <class T, class D>
3863739fe79SHoward Hinnant    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
3873739fe79SHoward Hinnant
38820cc2a42SHoward Hinnantclass bad_weak_ptr
38920cc2a42SHoward Hinnant    : public std::exception
39020cc2a42SHoward Hinnant{
3913739fe79SHoward Hinnant    bad_weak_ptr() noexcept;
39220cc2a42SHoward Hinnant};
39320cc2a42SHoward Hinnant
39428d8ba5fSMarshall Clowtemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
39528d8ba5fSMarshall Clowtemplate<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
39628d8ba5fSMarshall Clowtemplate<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
39728d8ba5fSMarshall Clow
39848f36539SMarshall Clowtemplate<class E, class T, class Y, class D>
39948f36539SMarshall Clow    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
40048f36539SMarshall Clow
40120cc2a42SHoward Hinnanttemplate<class T>
40220cc2a42SHoward Hinnantclass shared_ptr
40320cc2a42SHoward Hinnant{
40420cc2a42SHoward Hinnantpublic:
40520cc2a42SHoward Hinnant    typedef T element_type;
40668436a9bSEric Fiselier    typedef weak_ptr<T> weak_type; // C++17
40720cc2a42SHoward Hinnant
40820cc2a42SHoward Hinnant    // constructors:
4093739fe79SHoward Hinnant    constexpr shared_ptr() noexcept;
41020cc2a42SHoward Hinnant    template<class Y> explicit shared_ptr(Y* p);
41120cc2a42SHoward Hinnant    template<class Y, class D> shared_ptr(Y* p, D d);
41220cc2a42SHoward Hinnant    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
41320cc2a42SHoward Hinnant    template <class D> shared_ptr(nullptr_t p, D d);
41420cc2a42SHoward Hinnant    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
4153739fe79SHoward Hinnant    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
4163739fe79SHoward Hinnant    shared_ptr(const shared_ptr& r) noexcept;
4173739fe79SHoward Hinnant    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
4183739fe79SHoward Hinnant    shared_ptr(shared_ptr&& r) noexcept;
4193739fe79SHoward Hinnant    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
42020cc2a42SHoward Hinnant    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
421e67179bcSMarshall Clow    template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
42220cc2a42SHoward Hinnant    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
42320cc2a42SHoward Hinnant    shared_ptr(nullptr_t) : shared_ptr() { }
42420cc2a42SHoward Hinnant
42520cc2a42SHoward Hinnant    // destructor:
42620cc2a42SHoward Hinnant    ~shared_ptr();
42720cc2a42SHoward Hinnant
42820cc2a42SHoward Hinnant    // assignment:
4293739fe79SHoward Hinnant    shared_ptr& operator=(const shared_ptr& r) noexcept;
4303739fe79SHoward Hinnant    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
4313739fe79SHoward Hinnant    shared_ptr& operator=(shared_ptr&& r) noexcept;
43220cc2a42SHoward Hinnant    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
433e67179bcSMarshall Clow    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
43420cc2a42SHoward Hinnant    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
43520cc2a42SHoward Hinnant
43620cc2a42SHoward Hinnant    // modifiers:
4373739fe79SHoward Hinnant    void swap(shared_ptr& r) noexcept;
4383739fe79SHoward Hinnant    void reset() noexcept;
43920cc2a42SHoward Hinnant    template<class Y> void reset(Y* p);
44020cc2a42SHoward Hinnant    template<class Y, class D> void reset(Y* p, D d);
44120cc2a42SHoward Hinnant    template<class Y, class D, class A> void reset(Y* p, D d, A a);
44220cc2a42SHoward Hinnant
4433739fe79SHoward Hinnant    // observers:
4443739fe79SHoward Hinnant    T* get() const noexcept;
4453739fe79SHoward Hinnant    T& operator*() const noexcept;
4463739fe79SHoward Hinnant    T* operator->() const noexcept;
4473739fe79SHoward Hinnant    long use_count() const noexcept;
4483739fe79SHoward Hinnant    bool unique() const noexcept;
4493739fe79SHoward Hinnant    explicit operator bool() const noexcept;
45036bc7178SMarshall Clow    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
45136bc7178SMarshall Clow    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
45220cc2a42SHoward Hinnant};
45320cc2a42SHoward Hinnant
45483564056SLogan Smithtemplate<class T>
45583564056SLogan Smithshared_ptr(weak_ptr<T>) -> shared_ptr<T>;
45683564056SLogan Smithtemplate<class T, class D>
45783564056SLogan Smithshared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
45883564056SLogan Smith
45920cc2a42SHoward Hinnant// shared_ptr comparisons:
46020cc2a42SHoward Hinnanttemplate<class T, class U>
4613739fe79SHoward Hinnant    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
46220cc2a42SHoward Hinnanttemplate<class T, class U>
4633739fe79SHoward Hinnant    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
46420cc2a42SHoward Hinnanttemplate<class T, class U>
4653739fe79SHoward Hinnant    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
46620cc2a42SHoward Hinnanttemplate<class T, class U>
4673739fe79SHoward Hinnant    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
46820cc2a42SHoward Hinnanttemplate<class T, class U>
4693739fe79SHoward Hinnant    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
47020cc2a42SHoward Hinnanttemplate<class T, class U>
4713739fe79SHoward Hinnant    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4723739fe79SHoward Hinnant
4733739fe79SHoward Hinnanttemplate <class T>
4743739fe79SHoward Hinnant    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
4753739fe79SHoward Hinnanttemplate <class T>
4763739fe79SHoward Hinnant    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
4773739fe79SHoward Hinnanttemplate <class T>
4783739fe79SHoward Hinnant    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
4793739fe79SHoward Hinnanttemplate <class T>
4803739fe79SHoward Hinnant    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
4813739fe79SHoward Hinnanttemplate <class T>
4823739fe79SHoward Hinnant    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
4833739fe79SHoward Hinnanttemplate <class T>
4843739fe79SHoward Hinnantbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
4853739fe79SHoward Hinnanttemplate <class T>
4863739fe79SHoward Hinnant    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
4873739fe79SHoward Hinnanttemplate <class T>
4883739fe79SHoward Hinnant    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
4893739fe79SHoward Hinnanttemplate <class T>
4903739fe79SHoward Hinnant    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
4913739fe79SHoward Hinnanttemplate <class T>
4923739fe79SHoward Hinnant    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
4933739fe79SHoward Hinnanttemplate <class T>
4943739fe79SHoward Hinnant    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
4953739fe79SHoward Hinnanttemplate <class T>
4963739fe79SHoward Hinnant    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;
49720cc2a42SHoward Hinnant
49820cc2a42SHoward Hinnant// shared_ptr specialized algorithms:
4993739fe79SHoward Hinnanttemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
50020cc2a42SHoward Hinnant
50120cc2a42SHoward Hinnant// shared_ptr casts:
50220cc2a42SHoward Hinnanttemplate<class T, class U>
5033739fe79SHoward Hinnant    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
50420cc2a42SHoward Hinnanttemplate<class T, class U>
5053739fe79SHoward Hinnant    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
50620cc2a42SHoward Hinnanttemplate<class T, class U>
5073739fe79SHoward Hinnant    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
50820cc2a42SHoward Hinnant
50920cc2a42SHoward Hinnant// shared_ptr I/O:
51020cc2a42SHoward Hinnanttemplate<class E, class T, class Y>
51120cc2a42SHoward Hinnant    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
51220cc2a42SHoward Hinnant
51320cc2a42SHoward Hinnant// shared_ptr get_deleter:
5143739fe79SHoward Hinnanttemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
51520cc2a42SHoward Hinnant
51620cc2a42SHoward Hinnanttemplate<class T, class... Args>
51720cc2a42SHoward Hinnant    shared_ptr<T> make_shared(Args&&... args);
51820cc2a42SHoward Hinnanttemplate<class T, class A, class... Args>
51920cc2a42SHoward Hinnant    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
52020cc2a42SHoward Hinnant
52120cc2a42SHoward Hinnanttemplate<class T>
52220cc2a42SHoward Hinnantclass weak_ptr
52320cc2a42SHoward Hinnant{
52420cc2a42SHoward Hinnantpublic:
52520cc2a42SHoward Hinnant    typedef T element_type;
52620cc2a42SHoward Hinnant
52720cc2a42SHoward Hinnant    // constructors
5283739fe79SHoward Hinnant    constexpr weak_ptr() noexcept;
5293739fe79SHoward Hinnant    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
5303739fe79SHoward Hinnant    weak_ptr(weak_ptr const& r) noexcept;
5313739fe79SHoward Hinnant    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
5324703f763SMarshall Clow    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
5334703f763SMarshall Clow    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
53420cc2a42SHoward Hinnant
53520cc2a42SHoward Hinnant    // destructor
53620cc2a42SHoward Hinnant    ~weak_ptr();
53720cc2a42SHoward Hinnant
53820cc2a42SHoward Hinnant    // assignment
5393739fe79SHoward Hinnant    weak_ptr& operator=(weak_ptr const& r) noexcept;
5403739fe79SHoward Hinnant    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
5413739fe79SHoward Hinnant    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
5424703f763SMarshall Clow    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
5434703f763SMarshall Clow    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
54420cc2a42SHoward Hinnant
54520cc2a42SHoward Hinnant    // modifiers
5463739fe79SHoward Hinnant    void swap(weak_ptr& r) noexcept;
5473739fe79SHoward Hinnant    void reset() noexcept;
54820cc2a42SHoward Hinnant
54920cc2a42SHoward Hinnant    // observers
5503739fe79SHoward Hinnant    long use_count() const noexcept;
5513739fe79SHoward Hinnant    bool expired() const noexcept;
5523739fe79SHoward Hinnant    shared_ptr<T> lock() const noexcept;
55336bc7178SMarshall Clow    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
55436bc7178SMarshall Clow    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
55520cc2a42SHoward Hinnant};
55620cc2a42SHoward Hinnant
55783564056SLogan Smithtemplate<class T>
55883564056SLogan Smithweak_ptr(shared_ptr<T>) -> weak_ptr<T>;
55983564056SLogan Smith
56020cc2a42SHoward Hinnant// weak_ptr specialized algorithms:
5613739fe79SHoward Hinnanttemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
56220cc2a42SHoward Hinnant
56320cc2a42SHoward Hinnant// class owner_less:
56420cc2a42SHoward Hinnanttemplate<class T> struct owner_less;
56520cc2a42SHoward Hinnant
56620cc2a42SHoward Hinnanttemplate<class T>
56720cc2a42SHoward Hinnantstruct owner_less<shared_ptr<T> >
56820cc2a42SHoward Hinnant    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
56920cc2a42SHoward Hinnant{
57020cc2a42SHoward Hinnant    typedef bool result_type;
57136bc7178SMarshall Clow    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
57236bc7178SMarshall Clow    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
57336bc7178SMarshall Clow    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
57420cc2a42SHoward Hinnant};
57520cc2a42SHoward Hinnant
57620cc2a42SHoward Hinnanttemplate<class T>
57720cc2a42SHoward Hinnantstruct owner_less<weak_ptr<T> >
57820cc2a42SHoward Hinnant    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
57920cc2a42SHoward Hinnant{
58020cc2a42SHoward Hinnant    typedef bool result_type;
58136bc7178SMarshall Clow    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
58236bc7178SMarshall Clow    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
58336bc7178SMarshall Clow    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
58436bc7178SMarshall Clow};
58536bc7178SMarshall Clow
58636bc7178SMarshall Clowtemplate <>  // Added in C++14
58736bc7178SMarshall Clowstruct owner_less<void>
58836bc7178SMarshall Clow{
58936bc7178SMarshall Clow    template <class _Tp, class _Up>
59036bc7178SMarshall Clow    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
59136bc7178SMarshall Clow    template <class _Tp, class _Up>
59236bc7178SMarshall Clow    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
59336bc7178SMarshall Clow    template <class _Tp, class _Up>
59436bc7178SMarshall Clow    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
59536bc7178SMarshall Clow    template <class _Tp, class _Up>
59636bc7178SMarshall Clow    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
59736bc7178SMarshall Clow
59836bc7178SMarshall Clow    typedef void is_transparent;
59920cc2a42SHoward Hinnant};
60020cc2a42SHoward Hinnant
60120cc2a42SHoward Hinnanttemplate<class T>
60220cc2a42SHoward Hinnantclass enable_shared_from_this
60320cc2a42SHoward Hinnant{
60420cc2a42SHoward Hinnantprotected:
6053739fe79SHoward Hinnant    constexpr enable_shared_from_this() noexcept;
6063739fe79SHoward Hinnant    enable_shared_from_this(enable_shared_from_this const&) noexcept;
6073739fe79SHoward Hinnant    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
60820cc2a42SHoward Hinnant    ~enable_shared_from_this();
60920cc2a42SHoward Hinnantpublic:
61020cc2a42SHoward Hinnant    shared_ptr<T> shared_from_this();
61120cc2a42SHoward Hinnant    shared_ptr<T const> shared_from_this() const;
61220cc2a42SHoward Hinnant};
61320cc2a42SHoward Hinnant
61420cc2a42SHoward Hinnanttemplate<class T>
61520cc2a42SHoward Hinnant    bool atomic_is_lock_free(const shared_ptr<T>* p);
61620cc2a42SHoward Hinnanttemplate<class T>
61720cc2a42SHoward Hinnant    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
61820cc2a42SHoward Hinnanttemplate<class T>
61920cc2a42SHoward Hinnant    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
62020cc2a42SHoward Hinnanttemplate<class T>
62120cc2a42SHoward Hinnant    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
62220cc2a42SHoward Hinnanttemplate<class T>
62320cc2a42SHoward Hinnant    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
62420cc2a42SHoward Hinnanttemplate<class T>
62520cc2a42SHoward Hinnant    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
62620cc2a42SHoward Hinnanttemplate<class T>
62720cc2a42SHoward Hinnant    shared_ptr<T>
62820cc2a42SHoward Hinnant    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
62920cc2a42SHoward Hinnanttemplate<class T>
63020cc2a42SHoward Hinnant    bool
63120cc2a42SHoward Hinnant    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
63220cc2a42SHoward Hinnanttemplate<class T>
63320cc2a42SHoward Hinnant    bool
63420cc2a42SHoward Hinnant    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
63520cc2a42SHoward Hinnanttemplate<class T>
63620cc2a42SHoward Hinnant    bool
63720cc2a42SHoward Hinnant    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
63820cc2a42SHoward Hinnant                                          shared_ptr<T> w, memory_order success,
63920cc2a42SHoward Hinnant                                          memory_order failure);
64020cc2a42SHoward Hinnanttemplate<class T>
64120cc2a42SHoward Hinnant    bool
64220cc2a42SHoward Hinnant    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
64320cc2a42SHoward Hinnant                                            shared_ptr<T> w, memory_order success,
64420cc2a42SHoward Hinnant                                            memory_order failure);
64520cc2a42SHoward Hinnant// Hash support
64620cc2a42SHoward Hinnanttemplate <class T> struct hash;
64720cc2a42SHoward Hinnanttemplate <class T, class D> struct hash<unique_ptr<T, D> >;
64820cc2a42SHoward Hinnanttemplate <class T> struct hash<shared_ptr<T> >;
64920cc2a42SHoward Hinnant
65040a01d53SMarshall Clowtemplate <class T, class Alloc>
65140a01d53SMarshall Clow  inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
65240a01d53SMarshall Clow
65320cc2a42SHoward Hinnant// Pointer safety
65420cc2a42SHoward Hinnantenum class pointer_safety { relaxed, preferred, strict };
65520cc2a42SHoward Hinnantvoid declare_reachable(void *p);
65620cc2a42SHoward Hinnanttemplate <class T> T *undeclare_reachable(T *p);
65720cc2a42SHoward Hinnantvoid declare_no_pointers(char *p, size_t n);
65820cc2a42SHoward Hinnantvoid undeclare_no_pointers(char *p, size_t n);
6593739fe79SHoward Hinnantpointer_safety get_pointer_safety() noexcept;
66020cc2a42SHoward Hinnant
6613e519524SHoward Hinnantvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space);
6623e519524SHoward Hinnant
6633e519524SHoward Hinnant}  // std
6643e519524SHoward Hinnant
6653e519524SHoward Hinnant*/
6663e519524SHoward Hinnant
6673e519524SHoward Hinnant#include <__config>
6682eadbc86SLouis Dionne#include <__availability>
6693e519524SHoward Hinnant#include <type_traits>
6703e519524SHoward Hinnant#include <typeinfo>
6713e519524SHoward Hinnant#include <cstddef>
6723e519524SHoward Hinnant#include <cstdint>
6733e519524SHoward Hinnant#include <new>
6743e519524SHoward Hinnant#include <utility>
6753e519524SHoward Hinnant#include <limits>
6763e519524SHoward Hinnant#include <iterator>
6773e519524SHoward Hinnant#include <__functional_base>
678e3163f5aSHoward Hinnant#include <iosfwd>
679a87b5e34SHoward Hinnant#include <tuple>
6804524d6e7SEric Fiselier#include <stdexcept>
6819741d6c9SHoward Hinnant#include <cstring>
682749adebaSEric Fiselier#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
683d77851e8SHoward Hinnant#  include <atomic>
684d77851e8SHoward Hinnant#endif
685f56972e2SMarshall Clow#include <version>
686d77851e8SHoward Hinnant
687073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6883e519524SHoward Hinnant#pragma GCC system_header
689073458b1SHoward Hinnant#endif
6903e519524SHoward Hinnant
691a016efb1SEric Fiselier_LIBCPP_PUSH_MACROS
692a016efb1SEric Fiselier#include <__undef_macros>
693a016efb1SEric Fiselier
694a016efb1SEric Fiselier
6953e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
6963e519524SHoward Hinnant
6971faf289eSEric Fiseliertemplate <class _ValueType>
698dc7200b4SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY
6991faf289eSEric Fiselier_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
7001faf289eSEric Fiselier#if !defined(_LIBCPP_HAS_NO_THREADS) && \
7011faf289eSEric Fiselier    defined(__ATOMIC_RELAXED) &&        \
702ae62727aSRichard Smith    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
7031faf289eSEric Fiselier    return __atomic_load_n(__value, __ATOMIC_RELAXED);
7041faf289eSEric Fiselier#else
7051faf289eSEric Fiselier    return *__value;
7061faf289eSEric Fiselier#endif
7071faf289eSEric Fiselier}
7081faf289eSEric Fiselier
709224264adSKuba Breckatemplate <class _ValueType>
710dc7200b4SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY
711224264adSKuba Brecka_ValueType __libcpp_acquire_load(_ValueType const* __value) {
712224264adSKuba Brecka#if !defined(_LIBCPP_HAS_NO_THREADS) && \
713224264adSKuba Brecka    defined(__ATOMIC_ACQUIRE) &&        \
714ae62727aSRichard Smith    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
715224264adSKuba Brecka    return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
716224264adSKuba Brecka#else
717224264adSKuba Brecka    return *__value;
718224264adSKuba Brecka#endif
719224264adSKuba Brecka}
720224264adSKuba Brecka
7211c7fe126SMarshall Clow// addressof moved to <type_traits>
72264ec101eSDouglas Gregor
7233e519524SHoward Hinnanttemplate <class _Tp> class allocator;
7243e519524SHoward Hinnant
7255b1e5b43SMichael Park#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
7263e519524SHoward Hinnanttemplate <>
7275b1e5b43SMichael Parkclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<void>
7283e519524SHoward Hinnant{
7293e519524SHoward Hinnantpublic:
7303e519524SHoward Hinnant    typedef void*             pointer;
7313e519524SHoward Hinnant    typedef const void*       const_pointer;
7323e519524SHoward Hinnant    typedef void              value_type;
7333e519524SHoward Hinnant
7343e519524SHoward Hinnant    template <class _Up> struct rebind {typedef allocator<_Up> other;};
7353e519524SHoward Hinnant};
7363e519524SHoward Hinnant
73721fa1887SHoward Hinnanttemplate <>
7385b1e5b43SMichael Parkclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 allocator<const void>
73921fa1887SHoward Hinnant{
74021fa1887SHoward Hinnantpublic:
74121fa1887SHoward Hinnant    typedef const void*       pointer;
74221fa1887SHoward Hinnant    typedef const void*       const_pointer;
74321fa1887SHoward Hinnant    typedef const void        value_type;
74421fa1887SHoward Hinnant
74521fa1887SHoward Hinnant    template <class _Up> struct rebind {typedef allocator<_Up> other;};
74621fa1887SHoward Hinnant};
7475b1e5b43SMichael Park#endif
74821fa1887SHoward Hinnant
7493e519524SHoward Hinnant// pointer_traits
7503e519524SHoward Hinnant
751b082f11fSMarshall Clowtemplate <class _Tp, class = void>
752b082f11fSMarshall Clowstruct __has_element_type : false_type {};
753b082f11fSMarshall Clow
7543e519524SHoward Hinnanttemplate <class _Tp>
755b082f11fSMarshall Clowstruct __has_element_type<_Tp,
756b082f11fSMarshall Clow              typename __void_t<typename _Tp::element_type>::type> : true_type {};
7573e519524SHoward Hinnant
7583e519524SHoward Hinnanttemplate <class _Ptr, bool = __has_element_type<_Ptr>::value>
7593e519524SHoward Hinnantstruct __pointer_traits_element_type;
7603e519524SHoward Hinnant
7613e519524SHoward Hinnanttemplate <class _Ptr>
7623e519524SHoward Hinnantstruct __pointer_traits_element_type<_Ptr, true>
7633e519524SHoward Hinnant{
76414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::element_type type;
7653e519524SHoward Hinnant};
7663e519524SHoward Hinnant
7673e519524SHoward Hinnanttemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>
7683e519524SHoward Hinnantstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>
7693e519524SHoward Hinnant{
77014d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::element_type type;
7713e519524SHoward Hinnant};
7723e519524SHoward Hinnant
7733e519524SHoward Hinnanttemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>
7743e519524SHoward Hinnantstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>
7753e519524SHoward Hinnant{
77614d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE _Tp type;
7773e519524SHoward Hinnant};
7783e519524SHoward Hinnant
779b082f11fSMarshall Clowtemplate <class _Tp, class = void>
780b082f11fSMarshall Clowstruct __has_difference_type : false_type {};
781b082f11fSMarshall Clow
7823e519524SHoward Hinnanttemplate <class _Tp>
783b082f11fSMarshall Clowstruct __has_difference_type<_Tp,
784b082f11fSMarshall Clow            typename __void_t<typename _Tp::difference_type>::type> : true_type {};
7853e519524SHoward Hinnant
7863e519524SHoward Hinnanttemplate <class _Ptr, bool = __has_difference_type<_Ptr>::value>
7873e519524SHoward Hinnantstruct __pointer_traits_difference_type
7883e519524SHoward Hinnant{
78914d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE ptrdiff_t type;
7903e519524SHoward Hinnant};
7913e519524SHoward Hinnant
7923e519524SHoward Hinnanttemplate <class _Ptr>
7933e519524SHoward Hinnantstruct __pointer_traits_difference_type<_Ptr, true>
7943e519524SHoward Hinnant{
79514d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::difference_type type;
7963e519524SHoward Hinnant};
7973e519524SHoward Hinnant
7983e519524SHoward Hinnanttemplate <class _Tp, class _Up>
79930cbdcb5SLouis Dionnestruct __has_rebind
80030cbdcb5SLouis Dionne{
80130cbdcb5SLouis Dionneprivate:
80230cbdcb5SLouis Dionne    struct __two {char __lx; char __lxx;};
80330cbdcb5SLouis Dionne    template <class _Xp> static __two __test(...);
804c030ba64SLouis Dionne    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
80530cbdcb5SLouis Dionne    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
806c030ba64SLouis Dionne    _LIBCPP_SUPPRESS_DEPRECATED_POP
80730cbdcb5SLouis Dionnepublic:
80830cbdcb5SLouis Dionne    static const bool value = sizeof(__test<_Tp>(0)) == 1;
80930cbdcb5SLouis Dionne};
8103e519524SHoward Hinnant
8113e519524SHoward Hinnanttemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
8123e519524SHoward Hinnantstruct __pointer_traits_rebind
8133e519524SHoward Hinnant{
81454613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
81514d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up> type;
8163e519524SHoward Hinnant#else
81714d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
8183e519524SHoward Hinnant#endif
8193e519524SHoward Hinnant};
8203e519524SHoward Hinnant
8213e519524SHoward Hinnanttemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
8223e519524SHoward Hinnantstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>
8233e519524SHoward Hinnant{
82454613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
82514d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
8263e519524SHoward Hinnant#else
82714d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
8283e519524SHoward Hinnant#endif
8293e519524SHoward Hinnant};
8303e519524SHoward Hinnant
8313e519524SHoward Hinnanttemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
8323e519524SHoward Hinnantstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>
8333e519524SHoward Hinnant{
8343e519524SHoward Hinnant    typedef _Sp<_Up, _Args...> type;
8353e519524SHoward Hinnant};
8363e519524SHoward Hinnant
8373e519524SHoward Hinnanttemplate <class _Ptr>
838e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS pointer_traits
8393e519524SHoward Hinnant{
8403e519524SHoward Hinnant    typedef _Ptr                                                     pointer;
8413e519524SHoward Hinnant    typedef typename __pointer_traits_element_type<pointer>::type    element_type;
8423e519524SHoward Hinnant    typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
8433e519524SHoward Hinnant
84454613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
845f7384975SHoward Hinnant    template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
8463e519524SHoward Hinnant#else
8473e519524SHoward Hinnant    template <class _Up> struct rebind
8483e519524SHoward Hinnant        {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};
84954613ab4SEric Fiselier#endif  // _LIBCPP_CXX03_LANG
8503e519524SHoward Hinnant
8513e519524SHoward Hinnantprivate:
8523e519524SHoward Hinnant    struct __nat {};
8533e519524SHoward Hinnantpublic:
854848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
8553e519524SHoward Hinnant    static pointer pointer_to(typename conditional<is_void<element_type>::value,
8563e519524SHoward Hinnant                                           __nat, element_type>::type& __r)
8573e519524SHoward Hinnant        {return pointer::pointer_to(__r);}
8583e519524SHoward Hinnant};
8593e519524SHoward Hinnant
8603e519524SHoward Hinnanttemplate <class _Tp>
861e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
8623e519524SHoward Hinnant{
8633e519524SHoward Hinnant    typedef _Tp*      pointer;
8643e519524SHoward Hinnant    typedef _Tp       element_type;
8653e519524SHoward Hinnant    typedef ptrdiff_t difference_type;
8663e519524SHoward Hinnant
86754613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
8683e519524SHoward Hinnant    template <class _Up> using rebind = _Up*;
8693e519524SHoward Hinnant#else
8703e519524SHoward Hinnant    template <class _Up> struct rebind {typedef _Up* other;};
8713e519524SHoward Hinnant#endif
8723e519524SHoward Hinnant
8733e519524SHoward Hinnantprivate:
8743e519524SHoward Hinnant    struct __nat {};
8753e519524SHoward Hinnantpublic:
87672720269SLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
8773e519524SHoward Hinnant    static pointer pointer_to(typename conditional<is_void<element_type>::value,
8783739fe79SHoward Hinnant                                      __nat, element_type>::type& __r) _NOEXCEPT
879ce48a113SHoward Hinnant        {return _VSTD::addressof(__r);}
8803e519524SHoward Hinnant};
8813e519524SHoward Hinnant
8821c813407SEric Fiseliertemplate <class _From, class _To>
8831c813407SEric Fiselierstruct __rebind_pointer {
88454613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
8851c813407SEric Fiselier    typedef typename pointer_traits<_From>::template rebind<_To>        type;
8861c813407SEric Fiselier#else
8871c813407SEric Fiselier    typedef typename pointer_traits<_From>::template rebind<_To>::other type;
8881c813407SEric Fiselier#endif
8891c813407SEric Fiselier};
8901c813407SEric Fiselier
8910724f8bfSLouis Dionne// construct_at
8920724f8bfSLouis Dionne
8930724f8bfSLouis Dionne#if _LIBCPP_STD_VER > 17
8940724f8bfSLouis Dionne
8950724f8bfSLouis Dionnetemplate<class _Tp>
8960724f8bfSLouis Dionne_LIBCPP_CONSTEXPR_AFTER_CXX17 void* __voidify(_Tp& __ptr) noexcept {
8970724f8bfSLouis Dionne    return const_cast<void*>(static_cast<const volatile void*>(_VSTD::addressof(__ptr)));
8980724f8bfSLouis Dionne}
8990724f8bfSLouis Dionne
9000724f8bfSLouis Dionnetemplate<class _Tp, class ..._Args, class = decltype(
9010724f8bfSLouis Dionne    ::new (_VSTD::declval<void*>()) _Tp(_VSTD::declval<_Args>()...)
9020724f8bfSLouis Dionne)>
9030724f8bfSLouis Dionne_LIBCPP_INLINE_VISIBILITY
9040724f8bfSLouis Dionneconstexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
9050724f8bfSLouis Dionne    _LIBCPP_ASSERT(__location, "null pointer given to construct_at");
9060724f8bfSLouis Dionne    return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
9070724f8bfSLouis Dionne}
9080724f8bfSLouis Dionne
9090724f8bfSLouis Dionne#endif
9100724f8bfSLouis Dionne
9110724f8bfSLouis Dionne// destroy_at
9120724f8bfSLouis Dionne
9130724f8bfSLouis Dionne#if _LIBCPP_STD_VER > 14
9140724f8bfSLouis Dionne
9150724f8bfSLouis Dionnetemplate <class _Tp>
9160724f8bfSLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9170724f8bfSLouis Dionnevoid destroy_at(_Tp* __loc) {
9180724f8bfSLouis Dionne    _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
9190724f8bfSLouis Dionne    __loc->~_Tp();
9200724f8bfSLouis Dionne}
9210724f8bfSLouis Dionne
9220724f8bfSLouis Dionne#endif
9230724f8bfSLouis Dionne
9243e519524SHoward Hinnant// allocator_traits
9253e519524SHoward Hinnant
926b082f11fSMarshall Clowtemplate <class _Tp, class = void>
927b082f11fSMarshall Clowstruct __has_pointer_type : false_type {};
9283e519524SHoward Hinnant
9293e519524SHoward Hinnanttemplate <class _Tp>
930b082f11fSMarshall Clowstruct __has_pointer_type<_Tp,
931b082f11fSMarshall Clow          typename __void_t<typename _Tp::pointer>::type> : true_type {};
9323e519524SHoward Hinnant
9333e519524SHoward Hinnantnamespace __pointer_type_imp
9343e519524SHoward Hinnant{
9353e519524SHoward Hinnant
9363e519524SHoward Hinnanttemplate <class _Tp, class _Dp, bool = __has_pointer_type<_Dp>::value>
9373e519524SHoward Hinnantstruct __pointer_type
9383e519524SHoward Hinnant{
93914d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Dp::pointer type;
9403e519524SHoward Hinnant};
9413e519524SHoward Hinnant
9423e519524SHoward Hinnanttemplate <class _Tp, class _Dp>
9433e519524SHoward Hinnantstruct __pointer_type<_Tp, _Dp, false>
9443e519524SHoward Hinnant{
94514d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE _Tp* type;
9463e519524SHoward Hinnant};
9473e519524SHoward Hinnant
948a4a1ef1fSHoward Hinnant}  // __pointer_type_imp
9493e519524SHoward Hinnant
9503e519524SHoward Hinnanttemplate <class _Tp, class _Dp>
9513e519524SHoward Hinnantstruct __pointer_type
9523e519524SHoward Hinnant{
95314d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
9543e519524SHoward Hinnant};
9553e519524SHoward Hinnant
956b082f11fSMarshall Clowtemplate <class _Tp, class = void>
957b082f11fSMarshall Clowstruct __has_const_pointer : false_type {};
958b082f11fSMarshall Clow
9593e519524SHoward Hinnanttemplate <class _Tp>
960b082f11fSMarshall Clowstruct __has_const_pointer<_Tp,
961b082f11fSMarshall Clow            typename __void_t<typename _Tp::const_pointer>::type> : true_type {};
9623e519524SHoward Hinnant
9633e519524SHoward Hinnanttemplate <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>
9643e519524SHoward Hinnantstruct __const_pointer
9653e519524SHoward Hinnant{
96614d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::const_pointer type;
9673e519524SHoward Hinnant};
9683e519524SHoward Hinnant
9693e519524SHoward Hinnanttemplate <class _Tp, class _Ptr, class _Alloc>
9703e519524SHoward Hinnantstruct __const_pointer<_Tp, _Ptr, _Alloc, false>
9713e519524SHoward Hinnant{
97254613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
97314d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const _Tp> type;
9743e519524SHoward Hinnant#else
9753e519524SHoward Hinnant    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp>::other type;
9763e519524SHoward Hinnant#endif
9773e519524SHoward Hinnant};
9783e519524SHoward Hinnant
979b082f11fSMarshall Clowtemplate <class _Tp, class = void>
980b082f11fSMarshall Clowstruct __has_void_pointer : false_type {};
981b082f11fSMarshall Clow
9823e519524SHoward Hinnanttemplate <class _Tp>
983b082f11fSMarshall Clowstruct __has_void_pointer<_Tp,
984b082f11fSMarshall Clow               typename __void_t<typename _Tp::void_pointer>::type> : true_type {};
9853e519524SHoward Hinnant
9863e519524SHoward Hinnanttemplate <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>
9873e519524SHoward Hinnantstruct __void_pointer
9883e519524SHoward Hinnant{
98914d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::void_pointer type;
9903e519524SHoward Hinnant};
9913e519524SHoward Hinnant
9923e519524SHoward Hinnanttemplate <class _Ptr, class _Alloc>
9933e519524SHoward Hinnantstruct __void_pointer<_Ptr, _Alloc, false>
9943e519524SHoward Hinnant{
99554613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
99614d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<void> type;
9973e519524SHoward Hinnant#else
99814d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<void>::other type;
9993e519524SHoward Hinnant#endif
10003e519524SHoward Hinnant};
10013e519524SHoward Hinnant
1002b082f11fSMarshall Clowtemplate <class _Tp, class = void>
1003b082f11fSMarshall Clowstruct __has_const_void_pointer : false_type {};
1004b082f11fSMarshall Clow
10053e519524SHoward Hinnanttemplate <class _Tp>
1006b082f11fSMarshall Clowstruct __has_const_void_pointer<_Tp,
1007b082f11fSMarshall Clow            typename __void_t<typename _Tp::const_void_pointer>::type> : true_type {};
10083e519524SHoward Hinnant
10093e519524SHoward Hinnanttemplate <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>
10103e519524SHoward Hinnantstruct __const_void_pointer
10113e519524SHoward Hinnant{
101214d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::const_void_pointer type;
10133e519524SHoward Hinnant};
10143e519524SHoward Hinnant
10153e519524SHoward Hinnanttemplate <class _Ptr, class _Alloc>
10163e519524SHoward Hinnantstruct __const_void_pointer<_Ptr, _Alloc, false>
10173e519524SHoward Hinnant{
101854613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
101914d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const void> type;
10203e519524SHoward Hinnant#else
102114d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const void>::other type;
10223e519524SHoward Hinnant#endif
10233e519524SHoward Hinnant};
10243e519524SHoward Hinnant
10250068c591SEric Fiselier
10260068c591SEric Fiseliertemplate <bool _UsePointerTraits> struct __to_address_helper;
10270068c591SEric Fiselier
10280068c591SEric Fiseliertemplate <> struct __to_address_helper<true> {
10290068c591SEric Fiselier    template <class _Pointer>
1030d586f92cSArthur O'Dwyer    using __return_type = decltype(pointer_traits<_Pointer>::to_address(_VSTD::declval<const _Pointer&>()));
10310068c591SEric Fiselier
10320068c591SEric Fiselier    template <class _Pointer>
10330068c591SEric Fiselier    _LIBCPP_CONSTEXPR
10340068c591SEric Fiselier    static __return_type<_Pointer>
10350068c591SEric Fiselier    __do_it(const _Pointer &__p) _NOEXCEPT { return pointer_traits<_Pointer>::to_address(__p); }
10360068c591SEric Fiselier};
10370068c591SEric Fiselier
10380068c591SEric Fiseliertemplate <class _Pointer, bool _Dummy = true>
10390068c591SEric Fiselierusing __choose_to_address = __to_address_helper<_IsValidExpansion<__to_address_helper<_Dummy>::template __return_type, _Pointer>::value>;
10400068c591SEric Fiselier
10410068c591SEric Fiselier
1042c003db1fSHoward Hinnanttemplate <class _Tp>
104332952747SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1044c003db1fSHoward Hinnant_Tp*
10450068c591SEric Fiselier__to_address(_Tp* __p) _NOEXCEPT
10463e519524SHoward Hinnant{
10470068c591SEric Fiselier    static_assert(!is_function<_Tp>::value, "_Tp is a function type");
10483e519524SHoward Hinnant    return __p;
10493e519524SHoward Hinnant}
10503e519524SHoward Hinnant
10513e519524SHoward Hinnanttemplate <class _Pointer>
10520068c591SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
10530068c591SEric Fiseliertypename __choose_to_address<_Pointer>::template __return_type<_Pointer>
10540068c591SEric Fiselier__to_address(const _Pointer& __p) _NOEXCEPT {
10550068c591SEric Fiselier  return __choose_to_address<_Pointer>::__do_it(__p);
105632952747SEric Fiselier}
105732952747SEric Fiselier
10580068c591SEric Fiseliertemplate <> struct __to_address_helper<false> {
10590068c591SEric Fiselier    template <class _Pointer>
10600068c591SEric Fiselier    using __return_type = typename pointer_traits<_Pointer>::element_type*;
106132952747SEric Fiselier
10620068c591SEric Fiselier    template <class _Pointer>
10630068c591SEric Fiselier    _LIBCPP_CONSTEXPR
10640068c591SEric Fiselier    static __return_type<_Pointer>
1065d586f92cSArthur O'Dwyer    __do_it(const _Pointer &__p) _NOEXCEPT { return _VSTD::__to_address(__p.operator->()); }
10660068c591SEric Fiselier};
10670068c591SEric Fiselier
10680068c591SEric Fiselier
10690068c591SEric Fiselier#if _LIBCPP_STD_VER > 17
107032952747SEric Fiseliertemplate <class _Tp>
107132952747SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY constexpr
107232952747SEric Fiselier_Tp*
107332952747SEric Fiselierto_address(_Tp* __p) _NOEXCEPT
107432952747SEric Fiselier{
107532952747SEric Fiselier    static_assert(!is_function_v<_Tp>, "_Tp is a function type");
107632952747SEric Fiselier    return __p;
107732952747SEric Fiselier}
107832952747SEric Fiselier
107932952747SEric Fiseliertemplate <class _Pointer>
1080f6326736SMarek Kurdejinline _LIBCPP_INLINE_VISIBILITY constexpr
108132952747SEric Fiselierauto
108232952747SEric Fiselierto_address(const _Pointer& __p) _NOEXCEPT
108332952747SEric Fiselier{
10840068c591SEric Fiselier    return _VSTD::__to_address(__p);
108532952747SEric Fiselier}
108632952747SEric Fiselier#endif
10873e519524SHoward Hinnant
1088b082f11fSMarshall Clowtemplate <class _Tp, class = void>
1089b082f11fSMarshall Clowstruct __has_size_type : false_type {};
1090b082f11fSMarshall Clow
10913e519524SHoward Hinnanttemplate <class _Tp>
1092b082f11fSMarshall Clowstruct __has_size_type<_Tp,
1093b082f11fSMarshall Clow               typename __void_t<typename _Tp::size_type>::type> : true_type {};
10943e519524SHoward Hinnant
1095a4a1ef1fSHoward Hinnanttemplate <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
10963e519524SHoward Hinnantstruct __size_type
10973e519524SHoward Hinnant{
109814d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename make_unsigned<_DiffType>::type type;
10993e519524SHoward Hinnant};
11003e519524SHoward Hinnant
1101a4a1ef1fSHoward Hinnanttemplate <class _Alloc, class _DiffType>
1102a4a1ef1fSHoward Hinnantstruct __size_type<_Alloc, _DiffType, true>
11033e519524SHoward Hinnant{
110414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::size_type type;
11053e519524SHoward Hinnant};
11063e519524SHoward Hinnant
1107b082f11fSMarshall Clowtemplate <class _Tp, class = void>
1108b082f11fSMarshall Clowstruct __has_propagate_on_container_copy_assignment : false_type {};
1109b082f11fSMarshall Clow
11103e519524SHoward Hinnanttemplate <class _Tp>
1111b082f11fSMarshall Clowstruct __has_propagate_on_container_copy_assignment<_Tp,
1112b082f11fSMarshall Clow    typename __void_t<typename _Tp::propagate_on_container_copy_assignment>::type>
1113b082f11fSMarshall Clow        : true_type {};
11143e519524SHoward Hinnant
11153e519524SHoward Hinnanttemplate <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
11163e519524SHoward Hinnantstruct __propagate_on_container_copy_assignment
11173e519524SHoward Hinnant{
111814d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE false_type type;
11193e519524SHoward Hinnant};
11203e519524SHoward Hinnant
11213e519524SHoward Hinnanttemplate <class _Alloc>
11223e519524SHoward Hinnantstruct __propagate_on_container_copy_assignment<_Alloc, true>
11233e519524SHoward Hinnant{
112414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_copy_assignment type;
11253e519524SHoward Hinnant};
11263e519524SHoward Hinnant
1127b082f11fSMarshall Clowtemplate <class _Tp, class = void>
1128b082f11fSMarshall Clowstruct __has_propagate_on_container_move_assignment : false_type {};
1129b082f11fSMarshall Clow
11303e519524SHoward Hinnanttemplate <class _Tp>
1131b082f11fSMarshall Clowstruct __has_propagate_on_container_move_assignment<_Tp,
1132b082f11fSMarshall Clow           typename __void_t<typename _Tp::propagate_on_container_move_assignment>::type>
1133b082f11fSMarshall Clow               : true_type {};
11343e519524SHoward Hinnant
11353e519524SHoward Hinnanttemplate <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
11363e519524SHoward Hinnantstruct __propagate_on_container_move_assignment
11373e519524SHoward Hinnant{
11383e519524SHoward Hinnant    typedef false_type type;
11393e519524SHoward Hinnant};
11403e519524SHoward Hinnant
11413e519524SHoward Hinnanttemplate <class _Alloc>
11423e519524SHoward Hinnantstruct __propagate_on_container_move_assignment<_Alloc, true>
11433e519524SHoward Hinnant{
114414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_move_assignment type;
11453e519524SHoward Hinnant};
11463e519524SHoward Hinnant
1147b082f11fSMarshall Clowtemplate <class _Tp, class = void>
1148b082f11fSMarshall Clowstruct __has_propagate_on_container_swap : false_type {};
1149b082f11fSMarshall Clow
11503e519524SHoward Hinnanttemplate <class _Tp>
1151b082f11fSMarshall Clowstruct __has_propagate_on_container_swap<_Tp,
1152b082f11fSMarshall Clow           typename __void_t<typename _Tp::propagate_on_container_swap>::type>
1153b082f11fSMarshall Clow               : true_type {};
11543e519524SHoward Hinnant
11553e519524SHoward Hinnanttemplate <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
11563e519524SHoward Hinnantstruct __propagate_on_container_swap
11573e519524SHoward Hinnant{
11583e519524SHoward Hinnant    typedef false_type type;
11593e519524SHoward Hinnant};
11603e519524SHoward Hinnant
11613e519524SHoward Hinnanttemplate <class _Alloc>
11623e519524SHoward Hinnantstruct __propagate_on_container_swap<_Alloc, true>
11633e519524SHoward Hinnant{
116414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_swap type;
11653e519524SHoward Hinnant};
11663e519524SHoward Hinnant
1167b082f11fSMarshall Clowtemplate <class _Tp, class = void>
1168b082f11fSMarshall Clowstruct __has_is_always_equal : false_type {};
1169b082f11fSMarshall Clow
117031a47313SMarshall Clowtemplate <class _Tp>
1171b082f11fSMarshall Clowstruct __has_is_always_equal<_Tp,
1172b082f11fSMarshall Clow           typename __void_t<typename _Tp::is_always_equal>::type>
1173b082f11fSMarshall Clow               : true_type {};
117431a47313SMarshall Clow
117531a47313SMarshall Clowtemplate <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
117631a47313SMarshall Clowstruct __is_always_equal
117731a47313SMarshall Clow{
117814d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _VSTD::is_empty<_Alloc>::type type;
117931a47313SMarshall Clow};
118031a47313SMarshall Clow
118131a47313SMarshall Clowtemplate <class _Alloc>
118231a47313SMarshall Clowstruct __is_always_equal<_Alloc, true>
118331a47313SMarshall Clow{
118414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::is_always_equal type;
118531a47313SMarshall Clow};
118631a47313SMarshall Clow
11873e519524SHoward Hinnanttemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
11883e519524SHoward Hinnantstruct __has_rebind_other
11893e519524SHoward Hinnant{
11903e519524SHoward Hinnantprivate:
119154d333a6SHoward Hinnant    struct __two {char __lx; char __lxx;};
11923e519524SHoward Hinnant    template <class _Xp> static __two __test(...);
11935b1e5b43SMichael Park    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
11943e519524SHoward Hinnant    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>::other* = 0);
11955b1e5b43SMichael Park    _LIBCPP_SUPPRESS_DEPRECATED_POP
11963e519524SHoward Hinnantpublic:
11973e519524SHoward Hinnant    static const bool value = sizeof(__test<_Tp>(0)) == 1;
11983e519524SHoward Hinnant};
11993e519524SHoward Hinnant
12003e519524SHoward Hinnanttemplate <class _Tp, class _Up>
12013e519524SHoward Hinnantstruct __has_rebind_other<_Tp, _Up, false>
12023e519524SHoward Hinnant{
12033e519524SHoward Hinnant    static const bool value = false;
12043e519524SHoward Hinnant};
12053e519524SHoward Hinnant
12063e519524SHoward Hinnanttemplate <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>
12073e519524SHoward Hinnantstruct __allocator_traits_rebind
12083e519524SHoward Hinnant{
12095b1e5b43SMichael Park    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
121014d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
12115b1e5b43SMichael Park    _LIBCPP_SUPPRESS_DEPRECATED_POP
12123e519524SHoward Hinnant};
12133e519524SHoward Hinnant
12143e519524SHoward Hinnanttemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
12153e519524SHoward Hinnantstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>
12163e519524SHoward Hinnant{
12175b1e5b43SMichael Park    _LIBCPP_SUPPRESS_DEPRECATED_PUSH
121814d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;
12195b1e5b43SMichael Park    _LIBCPP_SUPPRESS_DEPRECATED_POP
12203e519524SHoward Hinnant};
12213e519524SHoward Hinnant
12223e519524SHoward Hinnanttemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
12233e519524SHoward Hinnantstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
12243e519524SHoward Hinnant{
122514d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE _Alloc<_Up, _Args...> type;
12263e519524SHoward Hinnant};
12273e519524SHoward Hinnant
122854613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
12293e519524SHoward Hinnant
12305b1e5b43SMichael Park_LIBCPP_SUPPRESS_DEPRECATED_PUSH
12313e519524SHoward Hinnanttemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
12323e519524SHoward Hinnantauto
12333e519524SHoward Hinnant__has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
12349f8fef95SEric Fiselier    -> decltype((void)__a.allocate(__sz, __p), true_type());
12355b1e5b43SMichael Park_LIBCPP_SUPPRESS_DEPRECATED_POP
12363e519524SHoward Hinnant
12373e519524SHoward Hinnanttemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
12383e519524SHoward Hinnantauto
12393e519524SHoward Hinnant__has_allocate_hint_test(const _Alloc& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
12403e519524SHoward Hinnant    -> false_type;
12413e519524SHoward Hinnant
12423e519524SHoward Hinnanttemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
12433e519524SHoward Hinnantstruct __has_allocate_hint
12445b1e5b43SMichael Park    : decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(),
12453e519524SHoward Hinnant                                               declval<_SizeType>(),
12465b1e5b43SMichael Park                                               declval<_ConstVoidPtr>()))
12473e519524SHoward Hinnant{
12483e519524SHoward Hinnant};
12493e519524SHoward Hinnant
125054613ab4SEric Fiselier#else  // _LIBCPP_CXX03_LANG
12513e519524SHoward Hinnant
12523e519524SHoward Hinnanttemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
12533e519524SHoward Hinnantstruct __has_allocate_hint
12543e519524SHoward Hinnant    : true_type
12553e519524SHoward Hinnant{
12563e519524SHoward Hinnant};
12573e519524SHoward Hinnant
125854613ab4SEric Fiselier#endif  // _LIBCPP_CXX03_LANG
12593e519524SHoward Hinnant
12606e48a6e4Szoecarver_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1261a521532aSzoecarvertemplate <class _Alloc, class ..._Args,
1262a521532aSzoecarver    class = decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Args>()...))>
1263a521532aSzoecarverstatic true_type __test_has_construct(int);
12646e48a6e4Szoecarver_LIBCPP_SUPPRESS_DEPRECATED_POP
12656e48a6e4Szoecarver
1266a521532aSzoecarvertemplate <class _Alloc, class...>
1267a521532aSzoecarverstatic false_type __test_has_construct(...);
1268a521532aSzoecarver
1269a521532aSzoecarvertemplate <class _Alloc, class ..._Args>
1270a521532aSzoecarverstruct __has_construct : decltype(__test_has_construct<_Alloc, _Args...>(0)) {};
1271a521532aSzoecarver
127254613ab4SEric Fiselier#if !defined(_LIBCPP_CXX03_LANG)
12733e519524SHoward Hinnant
12745b1e5b43SMichael Park_LIBCPP_SUPPRESS_DEPRECATED_PUSH
12753e519524SHoward Hinnanttemplate <class _Alloc, class _Pointer>
12763e519524SHoward Hinnantauto
12773e519524SHoward Hinnant__has_destroy_test(_Alloc&& __a, _Pointer&& __p)
12783e519524SHoward Hinnant    -> decltype(__a.destroy(__p), true_type());
12795b1e5b43SMichael Park_LIBCPP_SUPPRESS_DEPRECATED_POP
12803e519524SHoward Hinnant
12813e519524SHoward Hinnanttemplate <class _Alloc, class _Pointer>
12823e519524SHoward Hinnantauto
12833e519524SHoward Hinnant__has_destroy_test(const _Alloc& __a, _Pointer&& __p)
12843e519524SHoward Hinnant    -> false_type;
12853e519524SHoward Hinnant
12863e519524SHoward Hinnanttemplate <class _Alloc, class _Pointer>
12873e519524SHoward Hinnantstruct __has_destroy
12885b1e5b43SMichael Park    : decltype(_VSTD::__has_destroy_test(declval<_Alloc>(),
12895b1e5b43SMichael Park                                         declval<_Pointer>()))
12903e519524SHoward Hinnant{
12913e519524SHoward Hinnant};
12923e519524SHoward Hinnant
12935b1e5b43SMichael Park_LIBCPP_SUPPRESS_DEPRECATED_PUSH
12943e519524SHoward Hinnanttemplate <class _Alloc>
12953e519524SHoward Hinnantauto
12963e519524SHoward Hinnant__has_max_size_test(_Alloc&& __a)
12973e519524SHoward Hinnant    -> decltype(__a.max_size(), true_type());
12985b1e5b43SMichael Park_LIBCPP_SUPPRESS_DEPRECATED_POP
12993e519524SHoward Hinnant
13003e519524SHoward Hinnanttemplate <class _Alloc>
13013e519524SHoward Hinnantauto
13023e519524SHoward Hinnant__has_max_size_test(const volatile _Alloc& __a)
13033e519524SHoward Hinnant    -> false_type;
13043e519524SHoward Hinnant
13053e519524SHoward Hinnanttemplate <class _Alloc>
13063e519524SHoward Hinnantstruct __has_max_size
13075b1e5b43SMichael Park    : decltype(_VSTD::__has_max_size_test(declval<_Alloc&>()))
13083e519524SHoward Hinnant{
13093e519524SHoward Hinnant};
13103e519524SHoward Hinnant
13113e519524SHoward Hinnanttemplate <class _Alloc>
13123e519524SHoward Hinnantauto
13133e519524SHoward Hinnant__has_select_on_container_copy_construction_test(_Alloc&& __a)
13143e519524SHoward Hinnant    -> decltype(__a.select_on_container_copy_construction(), true_type());
13153e519524SHoward Hinnant
13163e519524SHoward Hinnanttemplate <class _Alloc>
13173e519524SHoward Hinnantauto
13183e519524SHoward Hinnant__has_select_on_container_copy_construction_test(const volatile _Alloc& __a)
13193e519524SHoward Hinnant    -> false_type;
13203e519524SHoward Hinnant
13213e519524SHoward Hinnanttemplate <class _Alloc>
13223e519524SHoward Hinnantstruct __has_select_on_container_copy_construction
13235b1e5b43SMichael Park    : decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>()))
13243e519524SHoward Hinnant{
13253e519524SHoward Hinnant};
13263e519524SHoward Hinnant
132754613ab4SEric Fiselier#else  // _LIBCPP_CXX03_LANG
13283e519524SHoward Hinnant
1329e7652f5cSVolodymyr Sapsaitemplate <class _Alloc, class _Pointer, class = void>
1330e7652f5cSVolodymyr Sapsaistruct __has_destroy : false_type {};
13313e519524SHoward Hinnant
13323e519524SHoward Hinnanttemplate <class _Alloc, class _Pointer>
1333e7652f5cSVolodymyr Sapsaistruct __has_destroy<_Alloc, _Pointer, typename __void_t<
1334e7652f5cSVolodymyr Sapsai    decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()))
1335d586f92cSArthur O'Dwyer>::type> : true_type {};
13363e519524SHoward Hinnant
13373e519524SHoward Hinnanttemplate <class _Alloc>
13383e519524SHoward Hinnantstruct __has_max_size
13393e519524SHoward Hinnant    : true_type
13403e519524SHoward Hinnant{
13413e519524SHoward Hinnant};
13423e519524SHoward Hinnant
13433e519524SHoward Hinnanttemplate <class _Alloc>
13443e519524SHoward Hinnantstruct __has_select_on_container_copy_construction
13453e519524SHoward Hinnant    : false_type
13463e519524SHoward Hinnant{
13473e519524SHoward Hinnant};
13483e519524SHoward Hinnant
134954613ab4SEric Fiselier#endif  // _LIBCPP_CXX03_LANG
13503e519524SHoward Hinnant
1351a4a1ef1fSHoward Hinnanttemplate <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value>
1352a4a1ef1fSHoward Hinnantstruct __alloc_traits_difference_type
1353a4a1ef1fSHoward Hinnant{
135414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::difference_type type;
1355a4a1ef1fSHoward Hinnant};
1356a4a1ef1fSHoward Hinnant
1357a4a1ef1fSHoward Hinnanttemplate <class _Alloc, class _Ptr>
1358a4a1ef1fSHoward Hinnantstruct __alloc_traits_difference_type<_Alloc, _Ptr, true>
1359a4a1ef1fSHoward Hinnant{
136014d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::difference_type type;
1361a4a1ef1fSHoward Hinnant};
1362a4a1ef1fSHoward Hinnant
1363fb0e1908SVolodymyr Sapsaitemplate <class _Tp>
1364fb0e1908SVolodymyr Sapsaistruct __is_default_allocator : false_type {};
1365fb0e1908SVolodymyr Sapsai
1366fb0e1908SVolodymyr Sapsaitemplate <class _Tp>
1367fb0e1908SVolodymyr Sapsaistruct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {};
1368fb0e1908SVolodymyr Sapsai
13692a573784SEric Fiselier
13702a573784SEric Fiselier
13712a573784SEric Fiseliertemplate <class _Alloc,
13722a573784SEric Fiselier    bool = __has_construct<_Alloc, typename _Alloc::value_type*,  typename _Alloc::value_type&&>::value && !__is_default_allocator<_Alloc>::value
13732a573784SEric Fiselier    >
13742a573784SEric Fiselierstruct __is_cpp17_move_insertable;
13752a573784SEric Fiseliertemplate <class _Alloc>
1376d586f92cSArthur O'Dwyerstruct __is_cpp17_move_insertable<_Alloc, true> : true_type {};
13772a573784SEric Fiseliertemplate <class _Alloc>
1378d586f92cSArthur O'Dwyerstruct __is_cpp17_move_insertable<_Alloc, false> : is_move_constructible<typename _Alloc::value_type> {};
13792a573784SEric Fiselier
13802a573784SEric Fiseliertemplate <class _Alloc,
13812a573784SEric Fiselier    bool = __has_construct<_Alloc, typename _Alloc::value_type*, const typename _Alloc::value_type&>::value && !__is_default_allocator<_Alloc>::value
13822a573784SEric Fiselier    >
13832a573784SEric Fiselierstruct __is_cpp17_copy_insertable;
13842a573784SEric Fiseliertemplate <class _Alloc>
13852a573784SEric Fiselierstruct __is_cpp17_copy_insertable<_Alloc, true> : __is_cpp17_move_insertable<_Alloc> {};
13862a573784SEric Fiseliertemplate <class _Alloc>
13872a573784SEric Fiselierstruct __is_cpp17_copy_insertable<_Alloc, false> : integral_constant<bool,
1388d586f92cSArthur O'Dwyer    is_copy_constructible<typename _Alloc::value_type>::value &&
13892a573784SEric Fiselier    __is_cpp17_move_insertable<_Alloc>::value>
13902a573784SEric Fiselier  {};
13912a573784SEric Fiselier
13922a573784SEric Fiselier
13932a573784SEric Fiselier
13943e519524SHoward Hinnanttemplate <class _Alloc>
1395e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS allocator_traits
13963e519524SHoward Hinnant{
13973e519524SHoward Hinnant    typedef _Alloc                              allocator_type;
13983e519524SHoward Hinnant    typedef typename allocator_type::value_type value_type;
13993e519524SHoward Hinnant
14003e519524SHoward Hinnant    typedef typename __pointer_type<value_type, allocator_type>::type pointer;
14013e519524SHoward Hinnant    typedef typename __const_pointer<value_type, pointer, allocator_type>::type const_pointer;
14023e519524SHoward Hinnant    typedef typename __void_pointer<pointer, allocator_type>::type void_pointer;
14033e519524SHoward Hinnant    typedef typename __const_void_pointer<pointer, allocator_type>::type const_void_pointer;
14043e519524SHoward Hinnant
1405a4a1ef1fSHoward Hinnant    typedef typename __alloc_traits_difference_type<allocator_type, pointer>::type difference_type;
1406a4a1ef1fSHoward Hinnant    typedef typename __size_type<allocator_type, difference_type>::type size_type;
14073e519524SHoward Hinnant
14083e519524SHoward Hinnant    typedef typename __propagate_on_container_copy_assignment<allocator_type>::type
14093e519524SHoward Hinnant                     propagate_on_container_copy_assignment;
14103e519524SHoward Hinnant    typedef typename __propagate_on_container_move_assignment<allocator_type>::type
14113e519524SHoward Hinnant                     propagate_on_container_move_assignment;
14123e519524SHoward Hinnant    typedef typename __propagate_on_container_swap<allocator_type>::type
14133e519524SHoward Hinnant                     propagate_on_container_swap;
141431a47313SMarshall Clow    typedef typename __is_always_equal<allocator_type>::type
141531a47313SMarshall Clow                     is_always_equal;
14163e519524SHoward Hinnant
141754613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
14183e519524SHoward Hinnant    template <class _Tp> using rebind_alloc =
1419f7384975SHoward Hinnant                  typename __allocator_traits_rebind<allocator_type, _Tp>::type;
14203e519524SHoward Hinnant    template <class _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp> >;
142154613ab4SEric Fiselier#else  // _LIBCPP_CXX03_LANG
14223e519524SHoward Hinnant    template <class _Tp> struct rebind_alloc
14233e519524SHoward Hinnant        {typedef typename __allocator_traits_rebind<allocator_type, _Tp>::type other;};
14243e519524SHoward Hinnant    template <class _Tp> struct rebind_traits
14253e519524SHoward Hinnant        {typedef allocator_traits<typename rebind_alloc<_Tp>::other> other;};
142654613ab4SEric Fiselier#endif  // _LIBCPP_CXX03_LANG
14273e519524SHoward Hinnant
14280724f8bfSLouis Dionne    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14293e519524SHoward Hinnant    static pointer allocate(allocator_type& __a, size_type __n)
14303e519524SHoward Hinnant        {return __a.allocate(__n);}
14310724f8bfSLouis Dionne    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14323e519524SHoward Hinnant    static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
14339ffacf3dSEric Fiselier        {return __allocate(__a, __n, __hint,
14343e519524SHoward Hinnant            __has_allocate_hint<allocator_type, size_type, const_void_pointer>());}
14353e519524SHoward Hinnant
14360724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14373739fe79SHoward Hinnant    static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT
14383e519524SHoward Hinnant        {__a.deallocate(__p, __n);}
14393e519524SHoward Hinnant
14403e519524SHoward Hinnant    template <class _Tp, class... _Args>
14410724f8bfSLouis Dionne        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14423e519524SHoward Hinnant        static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)
1443981f31acSMarshall Clow            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
1444ce48a113SHoward Hinnant                         __a, __p, _VSTD::forward<_Args>(__args)...);}
14453e519524SHoward Hinnant
14463e519524SHoward Hinnant    template <class _Tp>
14470724f8bfSLouis Dionne        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14483e519524SHoward Hinnant        static void destroy(allocator_type& __a, _Tp* __p)
14493e519524SHoward Hinnant            {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}
14503e519524SHoward Hinnant
14510724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
145206fbed03SMarshall Clow    static size_type max_size(const allocator_type& __a) _NOEXCEPT
14533e519524SHoward Hinnant        {return __max_size(__has_max_size<const allocator_type>(), __a);}
14543e519524SHoward Hinnant
14550724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14563e519524SHoward Hinnant    static allocator_type
14573e519524SHoward Hinnant        select_on_container_copy_construction(const allocator_type& __a)
14589ffacf3dSEric Fiselier            {return __select_on_container_copy_construction(
14593e519524SHoward Hinnant                __has_select_on_container_copy_construction<const allocator_type>(),
14603e519524SHoward Hinnant                __a);}
14613e519524SHoward Hinnant
14623e519524SHoward Hinnantprivate:
14630724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14649ffacf3dSEric Fiselier    static pointer __allocate(allocator_type& __a, size_type __n,
14653e519524SHoward Hinnant        const_void_pointer __hint, true_type)
14665b1e5b43SMichael Park        {
14675b1e5b43SMichael Park            _LIBCPP_SUPPRESS_DEPRECATED_PUSH
14685b1e5b43SMichael Park            return __a.allocate(__n, __hint);
14695b1e5b43SMichael Park            _LIBCPP_SUPPRESS_DEPRECATED_POP
14705b1e5b43SMichael Park        }
14710724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14729ffacf3dSEric Fiselier    static pointer __allocate(allocator_type& __a, size_type __n,
1473c206366fSHoward Hinnant        const_void_pointer, false_type)
14743e519524SHoward Hinnant        {return __a.allocate(__n);}
14753e519524SHoward Hinnant
14763e519524SHoward Hinnant    template <class _Tp, class... _Args>
14770724f8bfSLouis Dionne        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14783e519524SHoward Hinnant        static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args)
14795b1e5b43SMichael Park            {
14805b1e5b43SMichael Park                _LIBCPP_SUPPRESS_DEPRECATED_PUSH
14815b1e5b43SMichael Park                __a.construct(__p, _VSTD::forward<_Args>(__args)...);
14825b1e5b43SMichael Park                _LIBCPP_SUPPRESS_DEPRECATED_POP
14835b1e5b43SMichael Park            }
14845b1e5b43SMichael Park
14853e519524SHoward Hinnant    template <class _Tp, class... _Args>
14860724f8bfSLouis Dionne        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14873e519524SHoward Hinnant        static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)
14883e519524SHoward Hinnant            {
14890724f8bfSLouis Dionne#if _LIBCPP_STD_VER > 17
14900724f8bfSLouis Dionne                _VSTD::construct_at(__p, _VSTD::forward<_Args>(__args)...);
14910724f8bfSLouis Dionne#else
1492ce48a113SHoward Hinnant                ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
14930724f8bfSLouis Dionne#endif
14943e519524SHoward Hinnant            }
14953e519524SHoward Hinnant
14963e519524SHoward Hinnant    template <class _Tp>
14970724f8bfSLouis Dionne        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
14983e519524SHoward Hinnant        static void __destroy(true_type, allocator_type& __a, _Tp* __p)
14995b1e5b43SMichael Park            {
15005b1e5b43SMichael Park                _LIBCPP_SUPPRESS_DEPRECATED_PUSH
15015b1e5b43SMichael Park                __a.destroy(__p);
15025b1e5b43SMichael Park                _LIBCPP_SUPPRESS_DEPRECATED_POP
15035b1e5b43SMichael Park            }
15043e519524SHoward Hinnant    template <class _Tp>
15050724f8bfSLouis Dionne        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15063e519524SHoward Hinnant        static void __destroy(false_type, allocator_type&, _Tp* __p)
15073e519524SHoward Hinnant            {
15080724f8bfSLouis Dionne#if _LIBCPP_STD_VER > 17
15090724f8bfSLouis Dionne                _VSTD::destroy_at(__p);
15100724f8bfSLouis Dionne#else
15113e519524SHoward Hinnant                __p->~_Tp();
15120724f8bfSLouis Dionne#endif
15133e519524SHoward Hinnant            }
15143e519524SHoward Hinnant
15150724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1516fa40ee77SMarshall Clow    static size_type __max_size(true_type, const allocator_type& __a) _NOEXCEPT
15175b1e5b43SMichael Park            {
15185b1e5b43SMichael Park                _LIBCPP_SUPPRESS_DEPRECATED_PUSH
15195b1e5b43SMichael Park                return __a.max_size();
15205b1e5b43SMichael Park                _LIBCPP_SUPPRESS_DEPRECATED_POP
15215b1e5b43SMichael Park            }
15225b1e5b43SMichael Park
15230724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1524fa40ee77SMarshall Clow    static size_type __max_size(false_type, const allocator_type&) _NOEXCEPT
1525b631c243SMarshall Clow            {return numeric_limits<size_type>::max() / sizeof(value_type);}
15263e519524SHoward Hinnant
15270724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15283e519524SHoward Hinnant    static allocator_type
15299ffacf3dSEric Fiselier        __select_on_container_copy_construction(true_type, const allocator_type& __a)
15303e519524SHoward Hinnant            {return __a.select_on_container_copy_construction();}
15310724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15323e519524SHoward Hinnant    static allocator_type
15339ffacf3dSEric Fiselier        __select_on_container_copy_construction(false_type, const allocator_type& __a)
15343e519524SHoward Hinnant            {return __a;}
15353e519524SHoward Hinnant};
15363e519524SHoward Hinnant
15371f508014SMarshall Clowtemplate <class _Traits, class _Tp>
15381f508014SMarshall Clowstruct __rebind_alloc_helper
15391f508014SMarshall Clow{
154054613ab4SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
154114d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename _Traits::template rebind_alloc<_Tp>        type;
15421f508014SMarshall Clow#else
15431f508014SMarshall Clow    typedef typename _Traits::template rebind_alloc<_Tp>::other type;
15441f508014SMarshall Clow#endif
15451f508014SMarshall Clow};
15461f508014SMarshall Clow
15473e519524SHoward Hinnant// allocator
15483e519524SHoward Hinnant
15493e519524SHoward Hinnanttemplate <class _Tp>
1550e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS allocator
15513e519524SHoward Hinnant{
15523e519524SHoward Hinnantpublic:
1553316d336dSLouis Dionne    typedef size_t      size_type;
1554316d336dSLouis Dionne    typedef ptrdiff_t   difference_type;
15553e519524SHoward Hinnant    typedef _Tp         value_type;
1556b58f59cdSHoward Hinnant    typedef true_type   propagate_on_container_move_assignment;
155731a47313SMarshall Clow    typedef true_type   is_always_equal;
1558b58f59cdSHoward Hinnant
1559e0742c4aSMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1560e0742c4aSMarshall Clow    allocator() _NOEXCEPT { }
1561e0742c4aSMarshall Clow
1562e0742c4aSMarshall Clow    template <class _Up>
1563e0742c4aSMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1564e0742c4aSMarshall Clow    allocator(const allocator<_Up>&) _NOEXCEPT { }
1565e0742c4aSMarshall Clow
15660724f8bfSLouis Dionne    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15672404ed02SLouis Dionne    _Tp* allocate(size_t __n) {
15680724f8bfSLouis Dionne        if (__n > allocator_traits<allocator>::max_size(*this))
15690fc8cec7SMarshall Clow            __throw_length_error("allocator<T>::allocate(size_t n)"
15700fc8cec7SMarshall Clow                                 " 'n' exceeds maximum supported size");
1571d092c912SLouis Dionne        if (__libcpp_is_constant_evaluated()) {
1572d092c912SLouis Dionne            return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
1573d092c912SLouis Dionne        } else {
15745b1e5b43SMichael Park            return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
15754cec709eSMarshall Clow        }
1576d092c912SLouis Dionne    }
15775b1e5b43SMichael Park
15780724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
15792404ed02SLouis Dionne    void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
1580d092c912SLouis Dionne        if (__libcpp_is_constant_evaluated()) {
1581d092c912SLouis Dionne            ::operator delete(__p);
1582d092c912SLouis Dionne        } else {
15832404ed02SLouis Dionne            _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
15842404ed02SLouis Dionne        }
1585d092c912SLouis Dionne    }
15865b1e5b43SMichael Park
15872404ed02SLouis Dionne    // C++20 Removed members
15885b1e5b43SMichael Park#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
15892404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp*       pointer;
15902404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
15912404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp&       reference;
15922404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
15932404ed02SLouis Dionne
15942404ed02SLouis Dionne    template <class _Up>
15952404ed02SLouis Dionne    struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
15962404ed02SLouis Dionne        typedef allocator<_Up> other;
15972404ed02SLouis Dionne    };
15982404ed02SLouis Dionne
15992404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
16002404ed02SLouis Dionne    pointer address(reference __x) const _NOEXCEPT {
16012404ed02SLouis Dionne        return _VSTD::addressof(__x);
16022404ed02SLouis Dionne    }
16032404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
16042404ed02SLouis Dionne    const_pointer address(const_reference __x) const _NOEXCEPT {
16052404ed02SLouis Dionne        return _VSTD::addressof(__x);
16062404ed02SLouis Dionne    }
16072404ed02SLouis Dionne
16082404ed02SLouis Dionne    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
16092404ed02SLouis Dionne    _Tp* allocate(size_t __n, const void*) {
16102404ed02SLouis Dionne        return allocate(__n);
16112404ed02SLouis Dionne    }
16122404ed02SLouis Dionne
16132404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
16142404ed02SLouis Dionne        return size_type(~0) / sizeof(_Tp);
16152404ed02SLouis Dionne    }
16165b1e5b43SMichael Park
16173e519524SHoward Hinnant    template <class _Up, class... _Args>
16185b1e5b43SMichael Park    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
16192404ed02SLouis Dionne    void construct(_Up* __p, _Args&&... __args) {
1620ce48a113SHoward Hinnant        ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
16213e519524SHoward Hinnant    }
16222404ed02SLouis Dionne
16232404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
16242404ed02SLouis Dionne    void destroy(pointer __p) {
16252404ed02SLouis Dionne        __p->~_Tp();
16262404ed02SLouis Dionne    }
16275b1e5b43SMichael Park#endif
16283e519524SHoward Hinnant};
16293e519524SHoward Hinnant
16308e25104bSHoward Hinnanttemplate <class _Tp>
1631e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
16328e25104bSHoward Hinnant{
16338e25104bSHoward Hinnantpublic:
1634316d336dSLouis Dionne    typedef size_t      size_type;
1635316d336dSLouis Dionne    typedef ptrdiff_t   difference_type;
163630444adcSHoward Hinnant    typedef const _Tp   value_type;
16378e25104bSHoward Hinnant    typedef true_type   propagate_on_container_move_assignment;
1638f43a42d5SMarshall Clow    typedef true_type   is_always_equal;
16398e25104bSHoward Hinnant
1640e0742c4aSMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1641e0742c4aSMarshall Clow    allocator() _NOEXCEPT { }
1642e0742c4aSMarshall Clow
1643e0742c4aSMarshall Clow    template <class _Up>
1644e0742c4aSMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1645e0742c4aSMarshall Clow    allocator(const allocator<_Up>&) _NOEXCEPT { }
1646e0742c4aSMarshall Clow
16470724f8bfSLouis Dionne    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
16482404ed02SLouis Dionne    const _Tp* allocate(size_t __n) {
16490724f8bfSLouis Dionne        if (__n > allocator_traits<allocator>::max_size(*this))
16500fc8cec7SMarshall Clow            __throw_length_error("allocator<const T>::allocate(size_t n)"
16510fc8cec7SMarshall Clow                                 " 'n' exceeds maximum supported size");
1652d092c912SLouis Dionne        if (__libcpp_is_constant_evaluated()) {
1653d092c912SLouis Dionne            return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
1654d092c912SLouis Dionne        } else {
16555b1e5b43SMichael Park            return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
16564cec709eSMarshall Clow        }
1657d092c912SLouis Dionne    }
16585b1e5b43SMichael Park
16590724f8bfSLouis Dionne    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
16602404ed02SLouis Dionne    void deallocate(const _Tp* __p, size_t __n) {
1661d092c912SLouis Dionne        if (__libcpp_is_constant_evaluated()) {
1662d092c912SLouis Dionne            ::operator delete(const_cast<_Tp*>(__p));
1663d092c912SLouis Dionne        } else {
16642404ed02SLouis Dionne            _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
16652404ed02SLouis Dionne        }
1666d092c912SLouis Dionne    }
16675b1e5b43SMichael Park
16682404ed02SLouis Dionne    // C++20 Removed members
16695b1e5b43SMichael Park#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
16702404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
16712404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
16722404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
16732404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
16742404ed02SLouis Dionne
16752404ed02SLouis Dionne    template <class _Up>
16762404ed02SLouis Dionne    struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
16772404ed02SLouis Dionne        typedef allocator<_Up> other;
16782404ed02SLouis Dionne    };
16792404ed02SLouis Dionne
16802404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
16812404ed02SLouis Dionne    const_pointer address(const_reference __x) const _NOEXCEPT {
16822404ed02SLouis Dionne        return _VSTD::addressof(__x);
16832404ed02SLouis Dionne    }
16842404ed02SLouis Dionne
16852404ed02SLouis Dionne    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
16862404ed02SLouis Dionne    const _Tp* allocate(size_t __n, const void*) {
16872404ed02SLouis Dionne        return allocate(__n);
16882404ed02SLouis Dionne    }
16892404ed02SLouis Dionne
16902404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
16912404ed02SLouis Dionne        return size_type(~0) / sizeof(_Tp);
16922404ed02SLouis Dionne    }
16935b1e5b43SMichael Park
16948e25104bSHoward Hinnant    template <class _Up, class... _Args>
16955b1e5b43SMichael Park    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
16962404ed02SLouis Dionne    void construct(_Up* __p, _Args&&... __args) {
16978e25104bSHoward Hinnant        ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
16988e25104bSHoward Hinnant    }
1699bff1bfc6SHoward Hinnant
17002404ed02SLouis Dionne    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
17012404ed02SLouis Dionne    void destroy(pointer __p) {
17022404ed02SLouis Dionne        __p->~_Tp();
17032404ed02SLouis Dionne    }
17045b1e5b43SMichael Park#endif
17058e25104bSHoward Hinnant};
17068e25104bSHoward Hinnant
17073e519524SHoward Hinnanttemplate <class _Tp, class _Up>
17080724f8bfSLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
17093739fe79SHoward Hinnantbool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
17103e519524SHoward Hinnant
17113e519524SHoward Hinnanttemplate <class _Tp, class _Up>
17120724f8bfSLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
17133739fe79SHoward Hinnantbool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
17143e519524SHoward Hinnant
1715d9a4f936SLouis Dionnetemplate <class _Alloc, class _Ptr>
1716d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY
1717d9a4f936SLouis Dionnevoid __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) {
1718d9a4f936SLouis Dionne    static_assert(__is_cpp17_move_insertable<_Alloc>::value,
1719d9a4f936SLouis Dionne        "The specified type does not meet the requirements of Cpp17MoveInsertible");
1720d9a4f936SLouis Dionne    typedef allocator_traits<_Alloc> _Traits;
1721d9a4f936SLouis Dionne    for (; __begin1 != __end1; ++__begin1, (void)++__begin2) {
1722d9a4f936SLouis Dionne        _Traits::construct(__a, _VSTD::__to_address(__begin2),
1723d9a4f936SLouis Dionne#ifdef _LIBCPP_NO_EXCEPTIONS
1724d9a4f936SLouis Dionne            _VSTD::move(*__begin1)
1725d9a4f936SLouis Dionne#else
1726d9a4f936SLouis Dionne            _VSTD::move_if_noexcept(*__begin1)
1727d9a4f936SLouis Dionne#endif
1728d9a4f936SLouis Dionne        );
1729d9a4f936SLouis Dionne    }
1730d9a4f936SLouis Dionne}
1731d9a4f936SLouis Dionne
1732d9a4f936SLouis Dionnetemplate <class _Alloc, class _Tp, typename enable_if<
1733d9a4f936SLouis Dionne    (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) &&
1734d9a4f936SLouis Dionne    is_trivially_move_constructible<_Tp>::value
1735d9a4f936SLouis Dionne>::type>
1736d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY
1737d9a4f936SLouis Dionnevoid __construct_forward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) {
1738d9a4f936SLouis Dionne    ptrdiff_t _Np = __end1 - __begin1;
1739d9a4f936SLouis Dionne    if (_Np > 0) {
1740d9a4f936SLouis Dionne        _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
1741d9a4f936SLouis Dionne        __begin2 += _Np;
1742d9a4f936SLouis Dionne    }
1743d9a4f936SLouis Dionne}
1744d9a4f936SLouis Dionne
1745d9a4f936SLouis Dionnetemplate <class _Alloc, class _Iter, class _Ptr>
1746d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY
1747d9a4f936SLouis Dionnevoid __construct_range_forward(_Alloc& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) {
1748d9a4f936SLouis Dionne    typedef allocator_traits<_Alloc> _Traits;
1749d9a4f936SLouis Dionne    for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) {
1750d9a4f936SLouis Dionne        _Traits::construct(__a, _VSTD::__to_address(__begin2), *__begin1);
1751d9a4f936SLouis Dionne    }
1752d9a4f936SLouis Dionne}
1753d9a4f936SLouis Dionne
1754d9a4f936SLouis Dionnetemplate <class _Alloc, class _Source, class _Dest,
1755d9a4f936SLouis Dionne          class _RawSource = typename remove_const<_Source>::type,
1756d9a4f936SLouis Dionne          class _RawDest = typename remove_const<_Dest>::type,
1757d9a4f936SLouis Dionne          class =
1758d9a4f936SLouis Dionne    typename enable_if<
1759d9a4f936SLouis Dionne        is_trivially_copy_constructible<_Dest>::value &&
1760d9a4f936SLouis Dionne        is_same<_RawSource, _RawDest>::value &&
1761d9a4f936SLouis Dionne        (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value)
1762d9a4f936SLouis Dionne    >::type>
1763d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY
1764d9a4f936SLouis Dionnevoid __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) {
1765d9a4f936SLouis Dionne    ptrdiff_t _Np = __end1 - __begin1;
1766d9a4f936SLouis Dionne    if (_Np > 0) {
1767d9a4f936SLouis Dionne        _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest));
1768d9a4f936SLouis Dionne        __begin2 += _Np;
1769d9a4f936SLouis Dionne    }
1770d9a4f936SLouis Dionne}
1771d9a4f936SLouis Dionne
1772d9a4f936SLouis Dionnetemplate <class _Alloc, class _Ptr>
1773d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY
1774d9a4f936SLouis Dionnevoid __construct_backward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) {
1775d9a4f936SLouis Dionne    static_assert(__is_cpp17_move_insertable<_Alloc>::value,
1776d9a4f936SLouis Dionne        "The specified type does not meet the requirements of Cpp17MoveInsertable");
1777d9a4f936SLouis Dionne    typedef allocator_traits<_Alloc> _Traits;
1778d9a4f936SLouis Dionne    while (__end1 != __begin1) {
1779d9a4f936SLouis Dionne        _Traits::construct(__a, _VSTD::__to_address(__end2 - 1),
1780d9a4f936SLouis Dionne#ifdef _LIBCPP_NO_EXCEPTIONS
1781d9a4f936SLouis Dionne            _VSTD::move(*--__end1)
1782d9a4f936SLouis Dionne#else
1783d9a4f936SLouis Dionne            _VSTD::move_if_noexcept(*--__end1)
1784d9a4f936SLouis Dionne#endif
1785d9a4f936SLouis Dionne        );
1786d9a4f936SLouis Dionne        --__end2;
1787d9a4f936SLouis Dionne    }
1788d9a4f936SLouis Dionne}
1789d9a4f936SLouis Dionne
1790d9a4f936SLouis Dionnetemplate <class _Alloc, class _Tp, class = typename enable_if<
1791d9a4f936SLouis Dionne    (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) &&
1792d9a4f936SLouis Dionne    is_trivially_move_constructible<_Tp>::value
1793d9a4f936SLouis Dionne>::type>
1794d9a4f936SLouis Dionne_LIBCPP_INLINE_VISIBILITY
1795d9a4f936SLouis Dionnevoid __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) {
1796d9a4f936SLouis Dionne    ptrdiff_t _Np = __end1 - __begin1;
1797d9a4f936SLouis Dionne    __end2 -= _Np;
1798d9a4f936SLouis Dionne    if (_Np > 0)
1799d9a4f936SLouis Dionne        _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
1800d9a4f936SLouis Dionne}
1801d9a4f936SLouis Dionne
18023e519524SHoward Hinnanttemplate <class _OutputIterator, class _Tp>
1803e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS raw_storage_iterator
18043e519524SHoward Hinnant    : public iterator<output_iterator_tag,
18053e519524SHoward Hinnant                      _Tp,                                         // purposefully not C++03
18063e519524SHoward Hinnant                      ptrdiff_t,                                   // purposefully not C++03
18073e519524SHoward Hinnant                      _Tp*,                                        // purposefully not C++03
18083e519524SHoward Hinnant                      raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03
18093e519524SHoward Hinnant{
18103e519524SHoward Hinnantprivate:
18113e519524SHoward Hinnant    _OutputIterator __x_;
18123e519524SHoward Hinnantpublic:
18133e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
18143e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
18153e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
1816fa8ce345SMarshall Clow        {::new(_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
18172603b075SMarshall Clow#if _LIBCPP_STD_VER >= 14
18182603b075SMarshall Clow    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
1819fa8ce345SMarshall Clow        {::new(_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
18202603b075SMarshall Clow#endif
18213e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
18223e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator  operator++(int)
18233e519524SHoward Hinnant        {raw_storage_iterator __t(*this); ++__x_; return __t;}
1824783b372aSMarshall Clow#if _LIBCPP_STD_VER >= 14
1825783b372aSMarshall Clow    _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
1826783b372aSMarshall Clow#endif
18273e519524SHoward Hinnant};
18283e519524SHoward Hinnant
18293e519524SHoward Hinnanttemplate <class _Tp>
1830c65d39a4SRoman Lebedev_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
18313e519524SHoward Hinnantpair<_Tp*, ptrdiff_t>
18323739fe79SHoward Hinnantget_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
18333e519524SHoward Hinnant{
18343e519524SHoward Hinnant    pair<_Tp*, ptrdiff_t> __r(0, 0);
18353e519524SHoward Hinnant    const ptrdiff_t __m = (~ptrdiff_t(0) ^
18363e519524SHoward Hinnant                           ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
18373e519524SHoward Hinnant                           / sizeof(_Tp);
18383e519524SHoward Hinnant    if (__n > __m)
18393e519524SHoward Hinnant        __n = __m;
18403e519524SHoward Hinnant    while (__n > 0)
18413e519524SHoward Hinnant    {
184243245b1fSEric Fiselier#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
1843d108bf85SEric Fiselier    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
18444e3195c9SRichard Smith        {
1845d586f92cSArthur O'Dwyer            align_val_t __al =
1846d586f92cSArthur O'Dwyer                align_val_t(alignment_of<_Tp>::value);
18474e3195c9SRichard Smith            __r.first = static_cast<_Tp*>(::operator new(
18484e3195c9SRichard Smith                __n * sizeof(_Tp), __al, nothrow));
18494e3195c9SRichard Smith        } else {
18504e3195c9SRichard Smith            __r.first = static_cast<_Tp*>(::operator new(
18514e3195c9SRichard Smith                __n * sizeof(_Tp), nothrow));
18524e3195c9SRichard Smith        }
18534e3195c9SRichard Smith#else
1854d108bf85SEric Fiselier    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
18554e3195c9SRichard Smith        {
18564e3195c9SRichard Smith            // Since aligned operator new is unavailable, return an empty
18574e3195c9SRichard Smith            // buffer rather than one with invalid alignment.
18584e3195c9SRichard Smith            return __r;
18594e3195c9SRichard Smith        }
18604e3195c9SRichard Smith
18613e519524SHoward Hinnant        __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
18624e3195c9SRichard Smith#endif
18634e3195c9SRichard Smith
18643e519524SHoward Hinnant        if (__r.first)
18653e519524SHoward Hinnant        {
18663e519524SHoward Hinnant            __r.second = __n;
18673e519524SHoward Hinnant            break;
18683e519524SHoward Hinnant        }
18693e519524SHoward Hinnant        __n /= 2;
18703e519524SHoward Hinnant    }
18713e519524SHoward Hinnant    return __r;
18723e519524SHoward Hinnant}
18733e519524SHoward Hinnant
18743e519524SHoward Hinnanttemplate <class _Tp>
18753e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
18764e3195c9SRichard Smithvoid return_temporary_buffer(_Tp* __p) _NOEXCEPT
18774e3195c9SRichard Smith{
1878d108bf85SEric Fiselier  _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
18794e3195c9SRichard Smith}
18803e519524SHoward Hinnant
1881e67179bcSMarshall Clow#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
18823e519524SHoward Hinnanttemplate <class _Tp>
1883ea5cd3b4SLouis Dionnestruct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
18843e519524SHoward Hinnant{
18853e519524SHoward Hinnant    _Tp* __ptr_;
18863e519524SHoward Hinnant};
18873e519524SHoward Hinnant
18883e519524SHoward Hinnanttemplate<class _Tp>
1889ea5cd3b4SLouis Dionneclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
18903e519524SHoward Hinnant{
18913e519524SHoward Hinnantprivate:
18923e519524SHoward Hinnant    _Tp* __ptr_;
18933e519524SHoward Hinnantpublic:
18943e519524SHoward Hinnant    typedef _Tp element_type;
18953e519524SHoward Hinnant
1896585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {}
1897585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {}
1898585a3cc3SDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT
18993e519524SHoward Hinnant        : __ptr_(__p.release()) {}
1900585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT
19013e519524SHoward Hinnant        {reset(__p.release()); return *this;}
1902585a3cc3SDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT
19033e519524SHoward Hinnant        {reset(__p.release()); return *this;}
1904585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT
19053e519524SHoward Hinnant        {reset(__p.__ptr_); return *this;}
1906585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;}
19073e519524SHoward Hinnant
1908585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT
19093e519524SHoward Hinnant        {return *__ptr_;}
1910585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;}
1911585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;}
1912585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT
19133e519524SHoward Hinnant    {
19143e519524SHoward Hinnant        _Tp* __t = __ptr_;
1915527a7fdfSBruce Mitchener        __ptr_ = nullptr;
19163e519524SHoward Hinnant        return __t;
19173e519524SHoward Hinnant    }
1918585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT
19193e519524SHoward Hinnant    {
19203e519524SHoward Hinnant        if (__ptr_ != __p)
19213e519524SHoward Hinnant            delete __ptr_;
19223e519524SHoward Hinnant        __ptr_ = __p;
19233e519524SHoward Hinnant    }
19243e519524SHoward Hinnant
1925585a3cc3SDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
1926585a3cc3SDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT
19273e519524SHoward Hinnant        {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
1928585a3cc3SDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT
19293e519524SHoward Hinnant        {return auto_ptr<_Up>(release());}
19303e519524SHoward Hinnant};
19313e519524SHoward Hinnant
19323e519524SHoward Hinnanttemplate <>
1933ea5cd3b4SLouis Dionneclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
19343e519524SHoward Hinnant{
19353e519524SHoward Hinnantpublic:
19363e519524SHoward Hinnant    typedef void element_type;
19373e519524SHoward Hinnant};
1938e67179bcSMarshall Clow#endif
19393e519524SHoward Hinnant
19400fa118a9SEric Fiselier// Tag used to default initialize one or both of the pair's elements.
19410fa118a9SEric Fiselierstruct __default_init_tag {};
1942549545b6SEric Fiselierstruct __value_init_tag {};
19430fa118a9SEric Fiselier
1944c88580c4SEric Fiseliertemplate <class _Tp, int _Idx,
1945c88580c4SEric Fiselier          bool _CanBeEmptyBase =
1946c88580c4SEric Fiselier              is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
1947c88580c4SEric Fiselierstruct __compressed_pair_elem {
1948c88580c4SEric Fiselier  typedef _Tp _ParamT;
1949c88580c4SEric Fiselier  typedef _Tp& reference;
1950c88580c4SEric Fiselier  typedef const _Tp& const_reference;
19513e519524SHoward Hinnant
1952549545b6SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
19530fa118a9SEric Fiselier  __compressed_pair_elem(__default_init_tag) {}
1954549545b6SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1955549545b6SEric Fiselier  __compressed_pair_elem(__value_init_tag) : __value_() {}
19563e519524SHoward Hinnant
1957c88580c4SEric Fiselier  template <class _Up, class = typename enable_if<
19588948264eSEric Fiselier      !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
19598948264eSEric Fiselier  >::type>
19609dae972cSAlex Lorenz  _LIBCPP_INLINE_VISIBILITY
1961549545b6SEric Fiselier  _LIBCPP_CONSTEXPR explicit
1962c88580c4SEric Fiselier  __compressed_pair_elem(_Up&& __u)
19630b485f3eSEric Fiselier      : __value_(_VSTD::forward<_Up>(__u))
19640b485f3eSEric Fiselier    {
19650b485f3eSEric Fiselier    }
19663e519524SHoward Hinnant
1967549545b6SEric Fiselier
1968549545b6SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
1969c88580c4SEric Fiselier  template <class... _Args, size_t... _Indexes>
1970c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
1971c88580c4SEric Fiselier  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
1972c88580c4SEric Fiselier                         __tuple_indices<_Indexes...>)
1973c88580c4SEric Fiselier      : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
1974c88580c4SEric Fiselier#endif
19753e519524SHoward Hinnant
1976549545b6SEric Fiselier
19779dae972cSAlex Lorenz  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
19789dae972cSAlex Lorenz  _LIBCPP_INLINE_VISIBILITY
1979c88580c4SEric Fiselier  const_reference __get() const _NOEXCEPT { return __value_; }
19803e519524SHoward Hinnant
19813e519524SHoward Hinnantprivate:
1982c88580c4SEric Fiselier  _Tp __value_;
19833e519524SHoward Hinnant};
19843e519524SHoward Hinnant
1985c88580c4SEric Fiseliertemplate <class _Tp, int _Idx>
1986c88580c4SEric Fiselierstruct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
1987c88580c4SEric Fiselier  typedef _Tp _ParamT;
1988c88580c4SEric Fiselier  typedef _Tp& reference;
1989c88580c4SEric Fiselier  typedef const _Tp& const_reference;
1990c88580c4SEric Fiselier  typedef _Tp __value_type;
19913e519524SHoward Hinnant
1992549545b6SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
1993549545b6SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1994549545b6SEric Fiselier  __compressed_pair_elem(__default_init_tag) {}
1995549545b6SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1996549545b6SEric Fiselier  __compressed_pair_elem(__value_init_tag) : __value_type() {}
19973e519524SHoward Hinnant
1998c88580c4SEric Fiselier  template <class _Up, class = typename enable_if<
19998948264eSEric Fiselier        !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
20008948264eSEric Fiselier  >::type>
20019dae972cSAlex Lorenz  _LIBCPP_INLINE_VISIBILITY
2002549545b6SEric Fiselier  _LIBCPP_CONSTEXPR explicit
2003c88580c4SEric Fiselier  __compressed_pair_elem(_Up&& __u)
20040b485f3eSEric Fiselier      : __value_type(_VSTD::forward<_Up>(__u))
20050b485f3eSEric Fiselier  {}
20063e519524SHoward Hinnant
2007549545b6SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
2008c88580c4SEric Fiselier  template <class... _Args, size_t... _Indexes>
2009c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
2010c88580c4SEric Fiselier  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
2011c88580c4SEric Fiselier                         __tuple_indices<_Indexes...>)
2012c88580c4SEric Fiselier      : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
2013c88580c4SEric Fiselier#endif
20143e519524SHoward Hinnant
20159dae972cSAlex Lorenz  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
20169dae972cSAlex Lorenz  _LIBCPP_INLINE_VISIBILITY
2017c88580c4SEric Fiselier  const_reference __get() const _NOEXCEPT { return *this; }
20183e519524SHoward Hinnant};
20193e519524SHoward Hinnant
20203e519524SHoward Hinnanttemplate <class _T1, class _T2>
2021c88580c4SEric Fiselierclass __compressed_pair : private __compressed_pair_elem<_T1, 0>,
2022c88580c4SEric Fiselier                          private __compressed_pair_elem<_T2, 1> {
202314d48692SEric Fiselier  typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T1, 0> _Base1;
202414d48692SEric Fiselier  typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T2, 1> _Base2;
2025c88580c4SEric Fiselier
2026c88580c4SEric Fiselier  // NOTE: This static assert should never fire because __compressed_pair
2027c88580c4SEric Fiselier  // is *almost never* used in a scenario where it's possible for T1 == T2.
2028c88580c4SEric Fiselier  // (The exception is std::function where it is possible that the function
2029c88580c4SEric Fiselier  //  object and the allocator have the same type).
2030b411e9ceSEric Fiselier  static_assert((!is_same<_T1, _T2>::value),
2031e181a6aeSArthur O'Dwyer    "__compressed_pair cannot be instantiated when T1 and T2 are the same type; "
2032c88580c4SEric Fiselier    "The current implementation is NOT ABI-compatible with the previous "
2033c88580c4SEric Fiselier    "implementation for this configuration");
2034c88580c4SEric Fiselier
20353e519524SHoward Hinnantpublic:
20368948264eSEric Fiselier    template <bool _Dummy = true,
20378948264eSEric Fiselier      class = typename enable_if<
20388948264eSEric Fiselier          __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
20398948264eSEric Fiselier          __dependent_type<is_default_constructible<_T2>, _Dummy>::value
20408948264eSEric Fiselier      >::type
20418948264eSEric Fiselier  >
2042a87b5e34SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
2043549545b6SEric Fiselier  _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
2044a87b5e34SHoward Hinnant
2045c88580c4SEric Fiselier  template <class _U1, class _U2>
2046549545b6SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2047c88580c4SEric Fiselier  __compressed_pair(_U1&& __t1, _U2&& __t2)
2048d586f92cSArthur O'Dwyer      : _Base1(_VSTD::forward<_U1>(__t1)), _Base2(_VSTD::forward<_U2>(__t2)) {}
2049a87b5e34SHoward Hinnant
2050549545b6SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
2051a87b5e34SHoward Hinnant  template <class... _Args1, class... _Args2>
2052c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
2053a87b5e34SHoward Hinnant  __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
2054a87b5e34SHoward Hinnant                    tuple<_Args2...> __second_args)
2055c88580c4SEric Fiselier      : _Base1(__pc, _VSTD::move(__first_args),
2056c88580c4SEric Fiselier               typename __make_tuple_indices<sizeof...(_Args1)>::type()),
2057c88580c4SEric Fiselier        _Base2(__pc, _VSTD::move(__second_args),
2058c88580c4SEric Fiselier               typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
2059c88580c4SEric Fiselier#endif
2060c88580c4SEric Fiselier
2061c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2062c88580c4SEric Fiselier  typename _Base1::reference first() _NOEXCEPT {
2063c88580c4SEric Fiselier    return static_cast<_Base1&>(*this).__get();
2064c88580c4SEric Fiselier  }
2065c88580c4SEric Fiselier
2066c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2067c88580c4SEric Fiselier  typename _Base1::const_reference first() const _NOEXCEPT {
2068c88580c4SEric Fiselier    return static_cast<_Base1 const&>(*this).__get();
2069c88580c4SEric Fiselier  }
2070c88580c4SEric Fiselier
2071c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2072c88580c4SEric Fiselier  typename _Base2::reference second() _NOEXCEPT {
2073c88580c4SEric Fiselier    return static_cast<_Base2&>(*this).__get();
2074c88580c4SEric Fiselier  }
2075c88580c4SEric Fiselier
2076c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2077c88580c4SEric Fiselier  typename _Base2::const_reference second() const _NOEXCEPT {
2078c88580c4SEric Fiselier    return static_cast<_Base2 const&>(*this).__get();
2079c88580c4SEric Fiselier  }
2080c88580c4SEric Fiselier
2081c88580c4SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2082c88580c4SEric Fiselier  void swap(__compressed_pair& __x)
20833739fe79SHoward Hinnant    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
2084afa72ed4SMarshall Clow               __is_nothrow_swappable<_T2>::value)
2085c88580c4SEric Fiselier  {
2086d586f92cSArthur O'Dwyer    using _VSTD::swap;
2087c88580c4SEric Fiselier    swap(first(), __x.first());
2088c88580c4SEric Fiselier    swap(second(), __x.second());
2089c88580c4SEric Fiselier  }
20903e519524SHoward Hinnant};
20913e519524SHoward Hinnant
20923e519524SHoward Hinnanttemplate <class _T1, class _T2>
20933e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2094c88580c4SEric Fiseliervoid swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
20953739fe79SHoward Hinnant    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
2096c88580c4SEric Fiselier               __is_nothrow_swappable<_T2>::value) {
2097c88580c4SEric Fiselier  __x.swap(__y);
2098c88580c4SEric Fiselier}
20993e519524SHoward Hinnant
21008e25104bSHoward Hinnant// default_delete
21018e25104bSHoward Hinnant
21023e519524SHoward Hinnanttemplate <class _Tp>
2103030d19bdSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS default_delete {
210472d0d603SErik Pilkington    static_assert(!is_function<_Tp>::value,
210572d0d603SErik Pilkington                  "default_delete cannot be instantiated for function types");
2106030d19bdSEric Fiselier#ifndef _LIBCPP_CXX03_LANG
2107fb2bd4a9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
2108c0937e8aSHoward Hinnant#else
2109030d19bdSEric Fiselier  _LIBCPP_INLINE_VISIBILITY default_delete() {}
2110c0937e8aSHoward Hinnant#endif
21113e519524SHoward Hinnant  template <class _Up>
2112030d19bdSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2113030d19bdSEric Fiselier  default_delete(const default_delete<_Up>&,
2114030d19bdSEric Fiselier                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
2115030d19bdSEric Fiselier                     0) _NOEXCEPT {}
2116030d19bdSEric Fiselier
2117030d19bdSEric Fiselier  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
2118030d19bdSEric Fiselier    static_assert(sizeof(_Tp) > 0,
2119030d19bdSEric Fiselier                  "default_delete can not delete incomplete type");
2120030d19bdSEric Fiselier    static_assert(!is_void<_Tp>::value,
2121030d19bdSEric Fiselier                  "default_delete can not delete incomplete type");
21223e519524SHoward Hinnant    delete __ptr;
21233e519524SHoward Hinnant  }
21243e519524SHoward Hinnant};
21253e519524SHoward Hinnant
21263e519524SHoward Hinnanttemplate <class _Tp>
2127030d19bdSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
2128030d19bdSEric Fiselierprivate:
2129e4097ad7SHoward Hinnant  template <class _Up>
2130030d19bdSEric Fiselier  struct _EnableIfConvertible
2131030d19bdSEric Fiselier      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
2132030d19bdSEric Fiselier
2133030d19bdSEric Fiselierpublic:
2134030d19bdSEric Fiselier#ifndef _LIBCPP_CXX03_LANG
2135fb2bd4a9SEric Fiselier  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
2136030d19bdSEric Fiselier#else
2137030d19bdSEric Fiselier  _LIBCPP_INLINE_VISIBILITY default_delete() {}
2138030d19bdSEric Fiselier#endif
2139030d19bdSEric Fiselier
2140e4097ad7SHoward Hinnant  template <class _Up>
2141e4097ad7SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
2142030d19bdSEric Fiselier  default_delete(const default_delete<_Up[]>&,
2143030d19bdSEric Fiselier                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
2144030d19bdSEric Fiselier
2145030d19bdSEric Fiselier  template <class _Up>
2146030d19bdSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2147030d19bdSEric Fiselier  typename _EnableIfConvertible<_Up>::type
2148030d19bdSEric Fiselier  operator()(_Up* __ptr) const _NOEXCEPT {
2149030d19bdSEric Fiselier    static_assert(sizeof(_Tp) > 0,
2150030d19bdSEric Fiselier                  "default_delete can not delete incomplete type");
2151030d19bdSEric Fiselier    static_assert(!is_void<_Tp>::value,
2152030d19bdSEric Fiselier                  "default_delete can not delete void type");
21533e519524SHoward Hinnant    delete[] __ptr;
21543e519524SHoward Hinnant  }
21553e519524SHoward Hinnant};
21563e519524SHoward Hinnant
215747272722SEric Fiseliertemplate <class _Deleter>
215847272722SEric Fiselierstruct __unique_ptr_deleter_sfinae {
215947272722SEric Fiselier  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
216047272722SEric Fiselier  typedef const _Deleter& __lval_ref_type;
216147272722SEric Fiselier  typedef _Deleter&& __good_rval_ref_type;
216247272722SEric Fiselier  typedef true_type __enable_rval_overload;
216347272722SEric Fiselier};
216447272722SEric Fiselier
216547272722SEric Fiseliertemplate <class _Deleter>
216647272722SEric Fiselierstruct __unique_ptr_deleter_sfinae<_Deleter const&> {
216747272722SEric Fiselier  typedef const _Deleter& __lval_ref_type;
216847272722SEric Fiselier  typedef const _Deleter&& __bad_rval_ref_type;
216947272722SEric Fiselier  typedef false_type __enable_rval_overload;
217047272722SEric Fiselier};
217147272722SEric Fiselier
217247272722SEric Fiseliertemplate <class _Deleter>
217347272722SEric Fiselierstruct __unique_ptr_deleter_sfinae<_Deleter&> {
217447272722SEric Fiselier  typedef _Deleter& __lval_ref_type;
217547272722SEric Fiselier  typedef _Deleter&& __bad_rval_ref_type;
217647272722SEric Fiselier  typedef false_type __enable_rval_overload;
217747272722SEric Fiselier};
217847272722SEric Fiselier
217976887bc4SVy Nguyen#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
218076887bc4SVy Nguyen#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
218176887bc4SVy Nguyen#else
218276887bc4SVy Nguyen#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
218376887bc4SVy Nguyen#endif
218476887bc4SVy Nguyen
21853e519524SHoward Hinnanttemplate <class _Tp, class _Dp = default_delete<_Tp> >
218676887bc4SVy Nguyenclass _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
21873e519524SHoward Hinnantpublic:
21883e519524SHoward Hinnant  typedef _Tp element_type;
21893e519524SHoward Hinnant  typedef _Dp deleter_type;
219014d48692SEric Fiselier  typedef _LIBCPP_NODEBUG_TYPE typename __pointer_type<_Tp, deleter_type>::type pointer;
219147272722SEric Fiselier
219247272722SEric Fiselier  static_assert(!is_rvalue_reference<deleter_type>::value,
219347272722SEric Fiselier                "the specified deleter type cannot be an rvalue reference");
219447272722SEric Fiselier
21953e519524SHoward Hinnantprivate:
21963e519524SHoward Hinnant  __compressed_pair<pointer, deleter_type> __ptr_;
21973e519524SHoward Hinnant
21983e519524SHoward Hinnant  struct __nat { int __for_bool_; };
21993e519524SHoward Hinnant
220014d48692SEric Fiselier  typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
22013e519524SHoward Hinnant
220247272722SEric Fiselier  template <bool _Dummy>
220314d48692SEric Fiselier  using _LValRefType _LIBCPP_NODEBUG_TYPE =
220492e61e93SEric Fiselier      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
220547272722SEric Fiselier
220647272722SEric Fiselier  template <bool _Dummy>
220714d48692SEric Fiselier  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
220892e61e93SEric Fiselier      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
220947272722SEric Fiselier
221047272722SEric Fiselier  template <bool _Dummy>
221114d48692SEric Fiselier  using _BadRValRefType _LIBCPP_NODEBUG_TYPE  =
221292e61e93SEric Fiselier      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
221347272722SEric Fiselier
221447272722SEric Fiselier  template <bool _Dummy, class _Deleter = typename __dependent_type<
221547272722SEric Fiselier                             __identity<deleter_type>, _Dummy>::type>
221614d48692SEric Fiselier  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
221747272722SEric Fiselier      typename enable_if<is_default_constructible<_Deleter>::value &&
221847272722SEric Fiselier                         !is_pointer<_Deleter>::value>::type;
221947272722SEric Fiselier
222047272722SEric Fiselier  template <class _ArgType>
222114d48692SEric Fiselier  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
222247272722SEric Fiselier      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
222347272722SEric Fiselier
222447272722SEric Fiselier  template <class _UPtr, class _Up>
222514d48692SEric Fiselier  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
222647272722SEric Fiselier      is_convertible<typename _UPtr::pointer, pointer>::value &&
222747272722SEric Fiselier      !is_array<_Up>::value
222847272722SEric Fiselier  >::type;
222947272722SEric Fiselier
223047272722SEric Fiselier  template <class _UDel>
223114d48692SEric Fiselier  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
223247272722SEric Fiselier      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
223347272722SEric Fiselier      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
223447272722SEric Fiselier    >::type;
223547272722SEric Fiselier
223647272722SEric Fiselier  template <class _UDel>
223747272722SEric Fiselier  using _EnableIfDeleterAssignable = typename enable_if<
223847272722SEric Fiselier      is_assignable<_Dp&, _UDel&&>::value
223947272722SEric Fiselier    >::type;
224047272722SEric Fiselier
224147272722SEric Fiselierpublic:
224247272722SEric Fiselier  template <bool _Dummy = true,
224347272722SEric Fiselier            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
224447272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2245549545b6SEric Fiselier  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
224647272722SEric Fiselier
224747272722SEric Fiselier  template <bool _Dummy = true,
224847272722SEric Fiselier            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
224947272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2250549545b6SEric Fiselier  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
225147272722SEric Fiselier
225247272722SEric Fiselier  template <bool _Dummy = true,
225347272722SEric Fiselier            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
225447272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2255549545b6SEric Fiselier  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
225647272722SEric Fiselier
225747272722SEric Fiselier  template <bool _Dummy = true,
225847272722SEric Fiselier            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
225947272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2260fb2bd4a9SEric Fiselier  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
22613e519524SHoward Hinnant      : __ptr_(__p, __d) {}
22623e519524SHoward Hinnant
226347272722SEric Fiselier  template <bool _Dummy = true,
226447272722SEric Fiselier            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
22653e519524SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
2266fb2bd4a9SEric Fiselier  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
226747272722SEric Fiselier      : __ptr_(__p, _VSTD::move(__d)) {
226847272722SEric Fiselier    static_assert(!is_reference<deleter_type>::value,
226947272722SEric Fiselier                  "rvalue deleter bound to reference");
227047272722SEric Fiselier  }
227147272722SEric Fiselier
227247272722SEric Fiselier  template <bool _Dummy = true,
227347272722SEric Fiselier            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
227447272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
227547272722SEric Fiselier  unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
227647272722SEric Fiselier
227747272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2278fb2bd4a9SEric Fiselier  unique_ptr(unique_ptr&& __u) _NOEXCEPT
227947272722SEric Fiselier      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
228047272722SEric Fiselier  }
228147272722SEric Fiselier
228247272722SEric Fiselier  template <class _Up, class _Ep,
228347272722SEric Fiselier      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
228447272722SEric Fiselier      class = _EnableIfDeleterConvertible<_Ep>
228547272722SEric Fiselier  >
228647272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
228747272722SEric Fiselier  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
2288ce48a113SHoward Hinnant      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
22893e519524SHoward Hinnant
2290e67179bcSMarshall Clow#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
22913e519524SHoward Hinnant  template <class _Up>
229247272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
229347272722SEric Fiselier  unique_ptr(auto_ptr<_Up>&& __p,
229447272722SEric Fiselier             typename enable_if<is_convertible<_Up*, _Tp*>::value &&
22953e519524SHoward Hinnant                                    is_same<_Dp, default_delete<_Tp> >::value,
229647272722SEric Fiselier                                __nat>::type = __nat()) _NOEXCEPT
2297549545b6SEric Fiselier      : __ptr_(__p.release(), __default_init_tag()) {}
2298e67179bcSMarshall Clow#endif
22993e519524SHoward Hinnant
230047272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
230147272722SEric Fiselier  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
23023e519524SHoward Hinnant    reset(__u.release());
2303ce48a113SHoward Hinnant    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
23043e519524SHoward Hinnant    return *this;
23053e519524SHoward Hinnant  }
23063e519524SHoward Hinnant
230747272722SEric Fiselier  template <class _Up, class _Ep,
230847272722SEric Fiselier      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
230947272722SEric Fiselier      class = _EnableIfDeleterAssignable<_Ep>
231047272722SEric Fiselier  >
23113e519524SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
231247272722SEric Fiselier  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
23133e519524SHoward Hinnant    reset(__u.release());
2314ce48a113SHoward Hinnant    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
23153e519524SHoward Hinnant    return *this;
23163e519524SHoward Hinnant  }
23173e519524SHoward Hinnant
2318e67179bcSMarshall Clow#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
23193e519524SHoward Hinnant  template <class _Up>
23203e519524SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
232147272722SEric Fiselier      typename enable_if<is_convertible<_Up*, _Tp*>::value &&
23223e519524SHoward Hinnant                             is_same<_Dp, default_delete<_Tp> >::value,
232347272722SEric Fiselier                         unique_ptr&>::type
232447272722SEric Fiselier      operator=(auto_ptr<_Up> __p) {
232547272722SEric Fiselier    reset(__p.release());
232647272722SEric Fiselier    return *this;
232747272722SEric Fiselier  }
2328e67179bcSMarshall Clow#endif
23293e519524SHoward Hinnant
2330fb2bd4a9SEric Fiselier#ifdef _LIBCPP_CXX03_LANG
2331fb2bd4a9SEric Fiselier  unique_ptr(unique_ptr const&) = delete;
2332fb2bd4a9SEric Fiselier  unique_ptr& operator=(unique_ptr const&) = delete;
2333fb2bd4a9SEric Fiselier#endif
2334fb2bd4a9SEric Fiselier
2335fb2bd4a9SEric Fiselier
233647272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
233747272722SEric Fiselier  ~unique_ptr() { reset(); }
233847272722SEric Fiselier
233947272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
234047272722SEric Fiselier  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
23413e519524SHoward Hinnant    reset();
23423e519524SHoward Hinnant    return *this;
23433e519524SHoward Hinnant  }
23443e519524SHoward Hinnant
2345f2f2d8b9SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
234647272722SEric Fiselier  typename add_lvalue_reference<_Tp>::type
234747272722SEric Fiselier  operator*() const {
234847272722SEric Fiselier    return *__ptr_.first();
234947272722SEric Fiselier  }
235047272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
235147272722SEric Fiselier  pointer operator->() const _NOEXCEPT {
235247272722SEric Fiselier    return __ptr_.first();
235347272722SEric Fiselier  }
235447272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
235547272722SEric Fiselier  pointer get() const _NOEXCEPT {
235647272722SEric Fiselier    return __ptr_.first();
235747272722SEric Fiselier  }
235847272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
235947272722SEric Fiselier  deleter_type& get_deleter() _NOEXCEPT {
236047272722SEric Fiselier    return __ptr_.second();
236147272722SEric Fiselier  }
236247272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
236347272722SEric Fiselier  const deleter_type& get_deleter() const _NOEXCEPT {
236447272722SEric Fiselier    return __ptr_.second();
236547272722SEric Fiselier  }
236647272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
236747272722SEric Fiselier  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
236847272722SEric Fiselier    return __ptr_.first() != nullptr;
236947272722SEric Fiselier  }
23703e519524SHoward Hinnant
237147272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
237247272722SEric Fiselier  pointer release() _NOEXCEPT {
23733e519524SHoward Hinnant    pointer __t = __ptr_.first();
23743e519524SHoward Hinnant    __ptr_.first() = pointer();
23753e519524SHoward Hinnant    return __t;
23763e519524SHoward Hinnant  }
23773e519524SHoward Hinnant
237847272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
237947272722SEric Fiselier  void reset(pointer __p = pointer()) _NOEXCEPT {
23803e519524SHoward Hinnant    pointer __tmp = __ptr_.first();
23813e519524SHoward Hinnant    __ptr_.first() = __p;
23823e519524SHoward Hinnant    if (__tmp)
23833e519524SHoward Hinnant      __ptr_.second()(__tmp);
23843e519524SHoward Hinnant  }
23853e519524SHoward Hinnant
238647272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
238747272722SEric Fiselier  void swap(unique_ptr& __u) _NOEXCEPT {
238847272722SEric Fiselier    __ptr_.swap(__u.__ptr_);
238947272722SEric Fiselier  }
23903e519524SHoward Hinnant};
23913e519524SHoward Hinnant
239247272722SEric Fiselier
23933e519524SHoward Hinnanttemplate <class _Tp, class _Dp>
239476887bc4SVy Nguyenclass _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
23953e519524SHoward Hinnantpublic:
23963e519524SHoward Hinnant  typedef _Tp element_type;
23973e519524SHoward Hinnant  typedef _Dp deleter_type;
23983e519524SHoward Hinnant  typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
239947272722SEric Fiselier
24003e519524SHoward Hinnantprivate:
24013e519524SHoward Hinnant  __compressed_pair<pointer, deleter_type> __ptr_;
24023e519524SHoward Hinnant
240392e61e93SEric Fiselier  template <class _From>
240492e61e93SEric Fiselier  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
24053e519524SHoward Hinnant
240692e61e93SEric Fiselier  template <class _FromElem>
240792e61e93SEric Fiselier  struct _CheckArrayPointerConversion<_FromElem*>
240892e61e93SEric Fiselier      : integral_constant<bool,
240992e61e93SEric Fiselier          is_same<_FromElem*, pointer>::value ||
241092e61e93SEric Fiselier            (is_same<pointer, element_type*>::value &&
241192e61e93SEric Fiselier             is_convertible<_FromElem(*)[], element_type(*)[]>::value)
241292e61e93SEric Fiselier      >
241392e61e93SEric Fiselier  {};
241447272722SEric Fiselier
241592e61e93SEric Fiselier  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
241647272722SEric Fiselier
241747272722SEric Fiselier  template <bool _Dummy>
241814d48692SEric Fiselier  using _LValRefType _LIBCPP_NODEBUG_TYPE =
241992e61e93SEric Fiselier      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
242047272722SEric Fiselier
242147272722SEric Fiselier  template <bool _Dummy>
242214d48692SEric Fiselier  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
242392e61e93SEric Fiselier      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
242447272722SEric Fiselier
242547272722SEric Fiselier  template <bool _Dummy>
242614d48692SEric Fiselier  using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
242792e61e93SEric Fiselier      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
242847272722SEric Fiselier
242947272722SEric Fiselier  template <bool _Dummy, class _Deleter = typename __dependent_type<
243047272722SEric Fiselier                             __identity<deleter_type>, _Dummy>::type>
243114d48692SEric Fiselier  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE  =
243247272722SEric Fiselier      typename enable_if<is_default_constructible<_Deleter>::value &&
243347272722SEric Fiselier                         !is_pointer<_Deleter>::value>::type;
243447272722SEric Fiselier
243547272722SEric Fiselier  template <class _ArgType>
243614d48692SEric Fiselier  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
243747272722SEric Fiselier      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
24383e519524SHoward Hinnant
243922747e62SLogan Chien  template <class _Pp>
244014d48692SEric Fiselier  using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
244192e61e93SEric Fiselier      _CheckArrayPointerConversion<_Pp>::value
244247272722SEric Fiselier  >::type;
244347272722SEric Fiselier
244447272722SEric Fiselier  template <class _UPtr, class _Up,
244547272722SEric Fiselier        class _ElemT = typename _UPtr::element_type>
244614d48692SEric Fiselier  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
244747272722SEric Fiselier      is_array<_Up>::value &&
244847272722SEric Fiselier      is_same<pointer, element_type*>::value &&
244947272722SEric Fiselier      is_same<typename _UPtr::pointer, _ElemT*>::value &&
245047272722SEric Fiselier      is_convertible<_ElemT(*)[], element_type(*)[]>::value
245147272722SEric Fiselier    >::type;
245247272722SEric Fiselier
245347272722SEric Fiselier  template <class _UDel>
245414d48692SEric Fiselier  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
245547272722SEric Fiselier      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
245647272722SEric Fiselier      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
245747272722SEric Fiselier    >::type;
245847272722SEric Fiselier
245947272722SEric Fiselier  template <class _UDel>
246014d48692SEric Fiselier  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE  = typename enable_if<
246147272722SEric Fiselier      is_assignable<_Dp&, _UDel&&>::value
246247272722SEric Fiselier    >::type;
246347272722SEric Fiselier
246447272722SEric Fiselierpublic:
246547272722SEric Fiselier  template <bool _Dummy = true,
246647272722SEric Fiselier            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
246747272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2468549545b6SEric Fiselier  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
246947272722SEric Fiselier
247047272722SEric Fiselier  template <bool _Dummy = true,
247147272722SEric Fiselier            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
247247272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2473549545b6SEric Fiselier  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
247447272722SEric Fiselier
247547272722SEric Fiselier  template <class _Pp, bool _Dummy = true,
247647272722SEric Fiselier            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
247747272722SEric Fiselier            class = _EnableIfPointerConvertible<_Pp> >
247847272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2479fb2bd4a9SEric Fiselier  explicit unique_ptr(_Pp __p) _NOEXCEPT
2480549545b6SEric Fiselier      : __ptr_(__p, __default_init_tag()) {}
248147272722SEric Fiselier
248247272722SEric Fiselier  template <class _Pp, bool _Dummy = true,
248347272722SEric Fiselier            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
248447272722SEric Fiselier            class = _EnableIfPointerConvertible<_Pp> >
248547272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2486fb2bd4a9SEric Fiselier  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
24873e519524SHoward Hinnant      : __ptr_(__p, __d) {}
24883e519524SHoward Hinnant
248947272722SEric Fiselier  template <bool _Dummy = true,
249047272722SEric Fiselier            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
249147272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2492fb2bd4a9SEric Fiselier  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
249347272722SEric Fiselier      : __ptr_(nullptr, __d) {}
24943e519524SHoward Hinnant
249547272722SEric Fiselier  template <class _Pp, bool _Dummy = true,
249647272722SEric Fiselier            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
249747272722SEric Fiselier            class = _EnableIfPointerConvertible<_Pp> >
249847272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2499fb2bd4a9SEric Fiselier  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
250047272722SEric Fiselier      : __ptr_(__p, _VSTD::move(__d)) {
250147272722SEric Fiselier    static_assert(!is_reference<deleter_type>::value,
250247272722SEric Fiselier                  "rvalue deleter bound to reference");
25033e519524SHoward Hinnant  }
25043e519524SHoward Hinnant
250547272722SEric Fiselier  template <bool _Dummy = true,
250647272722SEric Fiselier            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
250747272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2508fb2bd4a9SEric Fiselier  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
250947272722SEric Fiselier      : __ptr_(nullptr, _VSTD::move(__d)) {
251047272722SEric Fiselier    static_assert(!is_reference<deleter_type>::value,
251147272722SEric Fiselier                  "rvalue deleter bound to reference");
25123e519524SHoward Hinnant  }
25133e519524SHoward Hinnant
251447272722SEric Fiselier  template <class _Pp, bool _Dummy = true,
251547272722SEric Fiselier            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
251647272722SEric Fiselier            class = _EnableIfPointerConvertible<_Pp> >
251747272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
251847272722SEric Fiselier  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
25193e519524SHoward Hinnant
252047272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2521fb2bd4a9SEric Fiselier  unique_ptr(unique_ptr&& __u) _NOEXCEPT
252247272722SEric Fiselier      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
252347272722SEric Fiselier  }
252447272722SEric Fiselier
252547272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
2526fb2bd4a9SEric Fiselier  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
25273e519524SHoward Hinnant    reset(__u.release());
2528ce48a113SHoward Hinnant    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
25293e519524SHoward Hinnant    return *this;
25303e519524SHoward Hinnant  }
2531e4097ad7SHoward Hinnant
253247272722SEric Fiselier  template <class _Up, class _Ep,
253347272722SEric Fiselier      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
253447272722SEric Fiselier      class = _EnableIfDeleterConvertible<_Ep>
253547272722SEric Fiselier  >
2536e4097ad7SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
2537fb2bd4a9SEric Fiselier  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
253886321b2bSEric Fiselier      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
253947272722SEric Fiselier  }
2540e4097ad7SHoward Hinnant
254147272722SEric Fiselier  template <class _Up, class _Ep,
254247272722SEric Fiselier      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
254347272722SEric Fiselier      class = _EnableIfDeleterAssignable<_Ep>
254447272722SEric Fiselier  >
2545e4097ad7SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
2546e4097ad7SHoward Hinnant  unique_ptr&
2547fb2bd4a9SEric Fiselier  operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
2548e4097ad7SHoward Hinnant    reset(__u.release());
2549e4097ad7SHoward Hinnant    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
2550e4097ad7SHoward Hinnant    return *this;
2551e4097ad7SHoward Hinnant  }
25523e519524SHoward Hinnant
2553fb2bd4a9SEric Fiselier#ifdef _LIBCPP_CXX03_LANG
2554fb2bd4a9SEric Fiselier  unique_ptr(unique_ptr const&) = delete;
2555fb2bd4a9SEric Fiselier  unique_ptr& operator=(unique_ptr const&) = delete;
2556fb2bd4a9SEric Fiselier#endif
25573e519524SHoward Hinnant
255847272722SEric Fiselierpublic:
255947272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
256047272722SEric Fiselier  ~unique_ptr() { reset(); }
256147272722SEric Fiselier
256247272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
256347272722SEric Fiselier  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
25643e519524SHoward Hinnant    reset();
25653e519524SHoward Hinnant    return *this;
25663e519524SHoward Hinnant  }
25673e519524SHoward Hinnant
2568f2f2d8b9SHoward Hinnant  _LIBCPP_INLINE_VISIBILITY
256947272722SEric Fiselier  typename add_lvalue_reference<_Tp>::type
257047272722SEric Fiselier  operator[](size_t __i) const {
257147272722SEric Fiselier    return __ptr_.first()[__i];
257247272722SEric Fiselier  }
257347272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
257447272722SEric Fiselier  pointer get() const _NOEXCEPT {
257547272722SEric Fiselier    return __ptr_.first();
257647272722SEric Fiselier  }
25773e519524SHoward Hinnant
257847272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
257947272722SEric Fiselier  deleter_type& get_deleter() _NOEXCEPT {
258047272722SEric Fiselier    return __ptr_.second();
258147272722SEric Fiselier  }
258247272722SEric Fiselier
258347272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
258447272722SEric Fiselier  const deleter_type& get_deleter() const _NOEXCEPT {
258547272722SEric Fiselier    return __ptr_.second();
258647272722SEric Fiselier  }
258747272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
258847272722SEric Fiselier  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
258947272722SEric Fiselier    return __ptr_.first() != nullptr;
259047272722SEric Fiselier  }
259147272722SEric Fiselier
259247272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
259347272722SEric Fiselier  pointer release() _NOEXCEPT {
25943e519524SHoward Hinnant    pointer __t = __ptr_.first();
25953e519524SHoward Hinnant    __ptr_.first() = pointer();
25963e519524SHoward Hinnant    return __t;
25973e519524SHoward Hinnant  }
25983e519524SHoward Hinnant
259922747e62SLogan Chien  template <class _Pp>
260022747e62SLogan Chien  _LIBCPP_INLINE_VISIBILITY
260147272722SEric Fiselier  typename enable_if<
260292e61e93SEric Fiselier      _CheckArrayPointerConversion<_Pp>::value
260347272722SEric Fiselier  >::type
260447272722SEric Fiselier  reset(_Pp __p) _NOEXCEPT {
26053e519524SHoward Hinnant    pointer __tmp = __ptr_.first();
26063e519524SHoward Hinnant    __ptr_.first() = __p;
26073e519524SHoward Hinnant    if (__tmp)
26083e519524SHoward Hinnant      __ptr_.second()(__tmp);
26093e519524SHoward Hinnant  }
261047272722SEric Fiselier
261147272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
261247272722SEric Fiselier  void reset(nullptr_t = nullptr) _NOEXCEPT {
26133e519524SHoward Hinnant    pointer __tmp = __ptr_.first();
26143e519524SHoward Hinnant    __ptr_.first() = nullptr;
26153e519524SHoward Hinnant    if (__tmp)
26163e519524SHoward Hinnant      __ptr_.second()(__tmp);
26173e519524SHoward Hinnant  }
26183e519524SHoward Hinnant
261947272722SEric Fiselier  _LIBCPP_INLINE_VISIBILITY
262047272722SEric Fiselier  void swap(unique_ptr& __u) _NOEXCEPT {
262147272722SEric Fiselier    __ptr_.swap(__u.__ptr_);
262247272722SEric Fiselier  }
26233e519524SHoward Hinnant
26243e519524SHoward Hinnant};
26253e519524SHoward Hinnant
26263e519524SHoward Hinnanttemplate <class _Tp, class _Dp>
26273e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2628f07dd8d0SEric Fiseliertypename enable_if<
2629f07dd8d0SEric Fiselier    __is_swappable<_Dp>::value,
26303e519524SHoward Hinnant    void
2631f07dd8d0SEric Fiselier>::type
26323739fe79SHoward Hinnantswap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
26333e519524SHoward Hinnant
26343e519524SHoward Hinnanttemplate <class _T1, class _D1, class _T2, class _D2>
26353e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
26363e519524SHoward Hinnantbool
26373e519524SHoward Hinnantoperator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
26383e519524SHoward Hinnant
26393e519524SHoward Hinnanttemplate <class _T1, class _D1, class _T2, class _D2>
26403e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
26413e519524SHoward Hinnantbool
26423e519524SHoward Hinnantoperator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
26433e519524SHoward Hinnant
26443e519524SHoward Hinnanttemplate <class _T1, class _D1, class _T2, class _D2>
26453e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
26463e519524SHoward Hinnantbool
264767f39647SHoward Hinnantoperator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
264867f39647SHoward Hinnant{
264967f39647SHoward Hinnant    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
265067f39647SHoward Hinnant    typedef typename unique_ptr<_T2, _D2>::pointer _P2;
26516fe361c1SEric Fiselier    typedef typename common_type<_P1, _P2>::type _Vp;
26526fe361c1SEric Fiselier    return less<_Vp>()(__x.get(), __y.get());
265367f39647SHoward Hinnant}
26543e519524SHoward Hinnant
26553e519524SHoward Hinnanttemplate <class _T1, class _D1, class _T2, class _D2>
26563e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
26573e519524SHoward Hinnantbool
26583e519524SHoward Hinnantoperator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
26593e519524SHoward Hinnant
26603e519524SHoward Hinnanttemplate <class _T1, class _D1, class _T2, class _D2>
26613e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
26623e519524SHoward Hinnantbool
26633e519524SHoward Hinnantoperator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
26643e519524SHoward Hinnant
26653e519524SHoward Hinnanttemplate <class _T1, class _D1, class _T2, class _D2>
26663e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
26673e519524SHoward Hinnantbool
26683e519524SHoward Hinnantoperator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
26693e519524SHoward Hinnant
267067f39647SHoward Hinnanttemplate <class _T1, class _D1>
267167f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
267267f39647SHoward Hinnantbool
2673c0937e8aSHoward Hinnantoperator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
267467f39647SHoward Hinnant{
267567f39647SHoward Hinnant    return !__x;
267667f39647SHoward Hinnant}
267767f39647SHoward Hinnant
267867f39647SHoward Hinnanttemplate <class _T1, class _D1>
267967f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
268067f39647SHoward Hinnantbool
2681c0937e8aSHoward Hinnantoperator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
268267f39647SHoward Hinnant{
268367f39647SHoward Hinnant    return !__x;
268467f39647SHoward Hinnant}
268567f39647SHoward Hinnant
268667f39647SHoward Hinnanttemplate <class _T1, class _D1>
268767f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
268867f39647SHoward Hinnantbool
2689c0937e8aSHoward Hinnantoperator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
269067f39647SHoward Hinnant{
269167f39647SHoward Hinnant    return static_cast<bool>(__x);
269267f39647SHoward Hinnant}
269367f39647SHoward Hinnant
269467f39647SHoward Hinnanttemplate <class _T1, class _D1>
269567f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
269667f39647SHoward Hinnantbool
2697c0937e8aSHoward Hinnantoperator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
269867f39647SHoward Hinnant{
269967f39647SHoward Hinnant    return static_cast<bool>(__x);
270067f39647SHoward Hinnant}
270167f39647SHoward Hinnant
270267f39647SHoward Hinnanttemplate <class _T1, class _D1>
270367f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
270467f39647SHoward Hinnantbool
270567f39647SHoward Hinnantoperator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
270667f39647SHoward Hinnant{
270767f39647SHoward Hinnant    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
270867f39647SHoward Hinnant    return less<_P1>()(__x.get(), nullptr);
270967f39647SHoward Hinnant}
271067f39647SHoward Hinnant
271167f39647SHoward Hinnanttemplate <class _T1, class _D1>
271267f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
271367f39647SHoward Hinnantbool
271467f39647SHoward Hinnantoperator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
271567f39647SHoward Hinnant{
271667f39647SHoward Hinnant    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
271767f39647SHoward Hinnant    return less<_P1>()(nullptr, __x.get());
271867f39647SHoward Hinnant}
271967f39647SHoward Hinnant
272067f39647SHoward Hinnanttemplate <class _T1, class _D1>
272167f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
272267f39647SHoward Hinnantbool
272367f39647SHoward Hinnantoperator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
272467f39647SHoward Hinnant{
272567f39647SHoward Hinnant    return nullptr < __x;
272667f39647SHoward Hinnant}
272767f39647SHoward Hinnant
272867f39647SHoward Hinnanttemplate <class _T1, class _D1>
272967f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
273067f39647SHoward Hinnantbool
273167f39647SHoward Hinnantoperator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
273267f39647SHoward Hinnant{
273367f39647SHoward Hinnant    return __x < nullptr;
273467f39647SHoward Hinnant}
273567f39647SHoward Hinnant
273667f39647SHoward Hinnanttemplate <class _T1, class _D1>
273767f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
273867f39647SHoward Hinnantbool
273967f39647SHoward Hinnantoperator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
274067f39647SHoward Hinnant{
274167f39647SHoward Hinnant    return !(nullptr < __x);
274267f39647SHoward Hinnant}
274367f39647SHoward Hinnant
274467f39647SHoward Hinnanttemplate <class _T1, class _D1>
274567f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
274667f39647SHoward Hinnantbool
274767f39647SHoward Hinnantoperator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
274867f39647SHoward Hinnant{
274967f39647SHoward Hinnant    return !(__x < nullptr);
275067f39647SHoward Hinnant}
275167f39647SHoward Hinnant
275267f39647SHoward Hinnanttemplate <class _T1, class _D1>
275367f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
275467f39647SHoward Hinnantbool
275567f39647SHoward Hinnantoperator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
275667f39647SHoward Hinnant{
275767f39647SHoward Hinnant    return !(__x < nullptr);
275867f39647SHoward Hinnant}
275967f39647SHoward Hinnant
276067f39647SHoward Hinnanttemplate <class _T1, class _D1>
276167f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
276267f39647SHoward Hinnantbool
276367f39647SHoward Hinnantoperator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
276467f39647SHoward Hinnant{
276567f39647SHoward Hinnant    return !(nullptr < __x);
276667f39647SHoward Hinnant}
276767f39647SHoward Hinnant
276828d8ba5fSMarshall Clow#if _LIBCPP_STD_VER > 11
276928d8ba5fSMarshall Clow
277028d8ba5fSMarshall Clowtemplate<class _Tp>
277128d8ba5fSMarshall Clowstruct __unique_if
277228d8ba5fSMarshall Clow{
277328d8ba5fSMarshall Clow    typedef unique_ptr<_Tp> __unique_single;
277428d8ba5fSMarshall Clow};
277528d8ba5fSMarshall Clow
277628d8ba5fSMarshall Clowtemplate<class _Tp>
277728d8ba5fSMarshall Clowstruct __unique_if<_Tp[]>
277828d8ba5fSMarshall Clow{
277928d8ba5fSMarshall Clow    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
278028d8ba5fSMarshall Clow};
278128d8ba5fSMarshall Clow
278228d8ba5fSMarshall Clowtemplate<class _Tp, size_t _Np>
278328d8ba5fSMarshall Clowstruct __unique_if<_Tp[_Np]>
278428d8ba5fSMarshall Clow{
278528d8ba5fSMarshall Clow    typedef void __unique_array_known_bound;
278628d8ba5fSMarshall Clow};
278728d8ba5fSMarshall Clow
278828d8ba5fSMarshall Clowtemplate<class _Tp, class... _Args>
278995ddb530SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
279028d8ba5fSMarshall Clowtypename __unique_if<_Tp>::__unique_single
279128d8ba5fSMarshall Clowmake_unique(_Args&&... __args)
279228d8ba5fSMarshall Clow{
279328d8ba5fSMarshall Clow    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
279428d8ba5fSMarshall Clow}
279528d8ba5fSMarshall Clow
279628d8ba5fSMarshall Clowtemplate<class _Tp>
279795ddb530SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY
279828d8ba5fSMarshall Clowtypename __unique_if<_Tp>::__unique_array_unknown_bound
279928d8ba5fSMarshall Clowmake_unique(size_t __n)
280028d8ba5fSMarshall Clow{
280128d8ba5fSMarshall Clow    typedef typename remove_extent<_Tp>::type _Up;
280228d8ba5fSMarshall Clow    return unique_ptr<_Tp>(new _Up[__n]());
280328d8ba5fSMarshall Clow}
280428d8ba5fSMarshall Clow
280528d8ba5fSMarshall Clowtemplate<class _Tp, class... _Args>
280628d8ba5fSMarshall Clow    typename __unique_if<_Tp>::__unique_array_known_bound
280728d8ba5fSMarshall Clow    make_unique(_Args&&...) = delete;
280828d8ba5fSMarshall Clow
280928d8ba5fSMarshall Clow#endif  // _LIBCPP_STD_VER > 11
281028d8ba5fSMarshall Clow
2811d1803b6cSHoward Hinnanttemplate <class _Tp, class _Dp>
2812f9127593SEric Fiselier#ifdef _LIBCPP_CXX03_LANG
2813e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
2814f9127593SEric Fiselier#else
2815f9127593SEric Fiselierstruct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
2816f9127593SEric Fiselier    unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
2817f9127593SEric Fiselier#endif
2818d1803b6cSHoward Hinnant{
2819d1803b6cSHoward Hinnant    typedef unique_ptr<_Tp, _Dp> argument_type;
2820d1803b6cSHoward Hinnant    typedef size_t               result_type;
2821848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
28227c803385SMarshall Clow    result_type operator()(const argument_type& __ptr) const
2823d1803b6cSHoward Hinnant    {
2824d1803b6cSHoward Hinnant        typedef typename argument_type::pointer pointer;
2825d1803b6cSHoward Hinnant        return hash<pointer>()(__ptr.get());
2826d1803b6cSHoward Hinnant    }
2827d1803b6cSHoward Hinnant};
2828d1803b6cSHoward Hinnant
28293e519524SHoward Hinnantstruct __destruct_n
28303e519524SHoward Hinnant{
28313e519524SHoward Hinnantprivate:
28329ffacf3dSEric Fiselier    size_t __size_;
28333e519524SHoward Hinnant
28343e519524SHoward Hinnant    template <class _Tp>
28353739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
28369ffacf3dSEric Fiselier        {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
28373e519524SHoward Hinnant
28383e519524SHoward Hinnant    template <class _Tp>
28393739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
28403e519524SHoward Hinnant        {}
28413e519524SHoward Hinnant
28423739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
28439ffacf3dSEric Fiselier        {++__size_;}
28443739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
28453e519524SHoward Hinnant        {}
28463e519524SHoward Hinnant
28473739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
28489ffacf3dSEric Fiselier        {__size_ = __s;}
28493739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
28503e519524SHoward Hinnant        {}
28513e519524SHoward Hinnantpublic:
28523739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
28539ffacf3dSEric Fiselier        : __size_(__s) {}
28543e519524SHoward Hinnant
28553e519524SHoward Hinnant    template <class _Tp>
2856527a7fdfSBruce Mitchener    _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT
2857ca740483SHoward Hinnant        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
28583e519524SHoward Hinnant
28593e519524SHoward Hinnant    template <class _Tp>
28603739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
2861ca740483SHoward Hinnant        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
28623e519524SHoward Hinnant
28633e519524SHoward Hinnant    template <class _Tp>
28643739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
2865ca740483SHoward Hinnant        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
28663e519524SHoward Hinnant};
28673e519524SHoward Hinnant
28683e519524SHoward Hinnanttemplate <class _Alloc>
28693e519524SHoward Hinnantclass __allocator_destructor
28703e519524SHoward Hinnant{
287114d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits;
28723e519524SHoward Hinnantpublic:
287314d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer;
287414d48692SEric Fiselier    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type;
28753e519524SHoward Hinnantprivate:
28763e519524SHoward Hinnant    _Alloc& __alloc_;
28773e519524SHoward Hinnant    size_type __s_;
28783e519524SHoward Hinnantpublic:
28793e519524SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
28803739fe79SHoward Hinnant             _NOEXCEPT
28813e519524SHoward Hinnant        : __alloc_(__a), __s_(__s) {}
2882848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
28833739fe79SHoward Hinnant    void operator()(pointer __p) _NOEXCEPT
28843739fe79SHoward Hinnant        {__alloc_traits::deallocate(__alloc_, __p, __s_);}
28853e519524SHoward Hinnant};
28863e519524SHoward Hinnant
28873e519524SHoward Hinnanttemplate <class _InputIterator, class _ForwardIterator>
28883e519524SHoward Hinnant_ForwardIterator
28893e519524SHoward Hinnantuninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
28903e519524SHoward Hinnant{
28913e519524SHoward Hinnant    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2892b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2893b34b4819SHoward Hinnant    _ForwardIterator __s = __r;
2894b34b4819SHoward Hinnant    try
2895b34b4819SHoward Hinnant    {
2896b34b4819SHoward Hinnant#endif
2897a00932bdSMarshall Clow        for (; __f != __l; ++__f, (void) ++__r)
2898a00932bdSMarshall Clow            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
2899b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2900b34b4819SHoward Hinnant    }
2901b34b4819SHoward Hinnant    catch (...)
2902b34b4819SHoward Hinnant    {
2903b34b4819SHoward Hinnant        for (; __s != __r; ++__s)
2904b34b4819SHoward Hinnant            __s->~value_type();
2905b34b4819SHoward Hinnant        throw;
2906b34b4819SHoward Hinnant    }
2907b34b4819SHoward Hinnant#endif
29083e519524SHoward Hinnant    return __r;
29093e519524SHoward Hinnant}
29103e519524SHoward Hinnant
29113e519524SHoward Hinnanttemplate <class _InputIterator, class _Size, class _ForwardIterator>
29123e519524SHoward Hinnant_ForwardIterator
29133e519524SHoward Hinnantuninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
29143e519524SHoward Hinnant{
29153e519524SHoward Hinnant    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2916b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2917b34b4819SHoward Hinnant    _ForwardIterator __s = __r;
2918b34b4819SHoward Hinnant    try
2919b34b4819SHoward Hinnant    {
2920b34b4819SHoward Hinnant#endif
2921a00932bdSMarshall Clow        for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
2922a00932bdSMarshall Clow            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
2923b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2924b34b4819SHoward Hinnant    }
2925b34b4819SHoward Hinnant    catch (...)
2926b34b4819SHoward Hinnant    {
2927b34b4819SHoward Hinnant        for (; __s != __r; ++__s)
2928b34b4819SHoward Hinnant            __s->~value_type();
2929b34b4819SHoward Hinnant        throw;
2930b34b4819SHoward Hinnant    }
2931b34b4819SHoward Hinnant#endif
29323e519524SHoward Hinnant    return __r;
29333e519524SHoward Hinnant}
29343e519524SHoward Hinnant
29353e519524SHoward Hinnanttemplate <class _ForwardIterator, class _Tp>
29363e519524SHoward Hinnantvoid
29373e519524SHoward Hinnantuninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
29383e519524SHoward Hinnant{
29393e519524SHoward Hinnant    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2940b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2941b34b4819SHoward Hinnant    _ForwardIterator __s = __f;
2942b34b4819SHoward Hinnant    try
2943b34b4819SHoward Hinnant    {
2944b34b4819SHoward Hinnant#endif
2945b34b4819SHoward Hinnant        for (; __f != __l; ++__f)
2946a00932bdSMarshall Clow            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
2947b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2948b34b4819SHoward Hinnant    }
2949b34b4819SHoward Hinnant    catch (...)
2950b34b4819SHoward Hinnant    {
2951b34b4819SHoward Hinnant        for (; __s != __f; ++__s)
2952b34b4819SHoward Hinnant            __s->~value_type();
2953b34b4819SHoward Hinnant        throw;
2954b34b4819SHoward Hinnant    }
2955b34b4819SHoward Hinnant#endif
29563e519524SHoward Hinnant}
29573e519524SHoward Hinnant
29583e519524SHoward Hinnanttemplate <class _ForwardIterator, class _Size, class _Tp>
295948d05bd2SHoward Hinnant_ForwardIterator
29603e519524SHoward Hinnantuninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
29613e519524SHoward Hinnant{
29623e519524SHoward Hinnant    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
2963b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2964b34b4819SHoward Hinnant    _ForwardIterator __s = __f;
2965b34b4819SHoward Hinnant    try
2966b34b4819SHoward Hinnant    {
2967b34b4819SHoward Hinnant#endif
2968a00932bdSMarshall Clow        for (; __n > 0; ++__f, (void) --__n)
2969a00932bdSMarshall Clow            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
2970b34b4819SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
2971b34b4819SHoward Hinnant    }
2972b34b4819SHoward Hinnant    catch (...)
2973b34b4819SHoward Hinnant    {
2974b34b4819SHoward Hinnant        for (; __s != __f; ++__s)
2975b34b4819SHoward Hinnant            __s->~value_type();
2976b34b4819SHoward Hinnant        throw;
2977b34b4819SHoward Hinnant    }
2978b34b4819SHoward Hinnant#endif
297948d05bd2SHoward Hinnant    return __f;
29803e519524SHoward Hinnant}
29813e519524SHoward Hinnant
2982e4d9c316SEric Fiselier#if _LIBCPP_STD_VER > 14
2983e4d9c316SEric Fiselier
2984e4d9c316SEric Fiseliertemplate <class _ForwardIterator>
29850724f8bfSLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2986e4d9c316SEric Fiseliervoid destroy(_ForwardIterator __first, _ForwardIterator __last) {
2987e4d9c316SEric Fiselier    for (; __first != __last; ++__first)
2988e4d9c316SEric Fiselier        _VSTD::destroy_at(_VSTD::addressof(*__first));
2989e4d9c316SEric Fiselier}
2990e4d9c316SEric Fiselier
2991e4d9c316SEric Fiseliertemplate <class _ForwardIterator, class _Size>
29920724f8bfSLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
2993e4d9c316SEric Fiselier_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
2994e4d9c316SEric Fiselier    for (; __n > 0; (void)++__first, --__n)
2995e4d9c316SEric Fiselier        _VSTD::destroy_at(_VSTD::addressof(*__first));
2996e4d9c316SEric Fiselier    return __first;
2997e4d9c316SEric Fiselier}
2998e4d9c316SEric Fiselier
2999e778d10cSEric Fiseliertemplate <class _ForwardIterator>
3000e778d10cSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
3001e778d10cSEric Fiseliervoid uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
3002e778d10cSEric Fiselier    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3003e778d10cSEric Fiselier    auto __idx = __first;
3004e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3005e778d10cSEric Fiselier    try {
3006e778d10cSEric Fiselier#endif
3007e778d10cSEric Fiselier    for (; __idx != __last; ++__idx)
3008e778d10cSEric Fiselier        ::new((void*)_VSTD::addressof(*__idx)) _Vt;
3009e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3010e778d10cSEric Fiselier    } catch (...) {
3011e778d10cSEric Fiselier        _VSTD::destroy(__first, __idx);
3012e778d10cSEric Fiselier        throw;
3013e778d10cSEric Fiselier    }
3014e778d10cSEric Fiselier#endif
3015e778d10cSEric Fiselier}
3016e778d10cSEric Fiselier
3017e778d10cSEric Fiseliertemplate <class _ForwardIterator, class _Size>
3018e778d10cSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
3019e778d10cSEric Fiselier_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
3020e778d10cSEric Fiselier    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3021e778d10cSEric Fiselier    auto __idx = __first;
3022e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3023e778d10cSEric Fiselier    try {
3024e778d10cSEric Fiselier#endif
3025e778d10cSEric Fiselier    for (; __n > 0; (void)++__idx, --__n)
3026e778d10cSEric Fiselier        ::new((void*)_VSTD::addressof(*__idx)) _Vt;
3027e778d10cSEric Fiselier    return __idx;
3028e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3029e778d10cSEric Fiselier    } catch (...) {
3030e778d10cSEric Fiselier        _VSTD::destroy(__first, __idx);
3031e778d10cSEric Fiselier        throw;
3032e778d10cSEric Fiselier    }
3033e778d10cSEric Fiselier#endif
3034e778d10cSEric Fiselier}
3035e778d10cSEric Fiselier
3036e778d10cSEric Fiselier
3037e778d10cSEric Fiseliertemplate <class _ForwardIterator>
3038e778d10cSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
3039e778d10cSEric Fiseliervoid uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
3040e778d10cSEric Fiselier    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3041e778d10cSEric Fiselier    auto __idx = __first;
3042e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3043e778d10cSEric Fiselier    try {
3044e778d10cSEric Fiselier#endif
3045e778d10cSEric Fiselier    for (; __idx != __last; ++__idx)
3046e778d10cSEric Fiselier        ::new((void*)_VSTD::addressof(*__idx)) _Vt();
3047e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3048e778d10cSEric Fiselier    } catch (...) {
3049e778d10cSEric Fiselier        _VSTD::destroy(__first, __idx);
3050e778d10cSEric Fiselier        throw;
3051e778d10cSEric Fiselier    }
3052e778d10cSEric Fiselier#endif
3053e778d10cSEric Fiselier}
3054e778d10cSEric Fiselier
3055e778d10cSEric Fiseliertemplate <class _ForwardIterator, class _Size>
3056e778d10cSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
3057e778d10cSEric Fiselier_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
3058e778d10cSEric Fiselier    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3059e778d10cSEric Fiselier    auto __idx = __first;
3060e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3061e778d10cSEric Fiselier    try {
3062e778d10cSEric Fiselier#endif
3063e778d10cSEric Fiselier    for (; __n > 0; (void)++__idx, --__n)
3064e778d10cSEric Fiselier        ::new((void*)_VSTD::addressof(*__idx)) _Vt();
3065e778d10cSEric Fiselier    return __idx;
3066e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3067e778d10cSEric Fiselier    } catch (...) {
3068e778d10cSEric Fiselier        _VSTD::destroy(__first, __idx);
3069e778d10cSEric Fiselier        throw;
3070e778d10cSEric Fiselier    }
3071e778d10cSEric Fiselier#endif
3072e778d10cSEric Fiselier}
3073e778d10cSEric Fiselier
3074e778d10cSEric Fiselier
3075e778d10cSEric Fiseliertemplate <class _InputIt, class _ForwardIt>
3076e778d10cSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
3077e778d10cSEric Fiselier_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
3078e778d10cSEric Fiselier    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
3079e778d10cSEric Fiselier    auto __idx = __first_res;
3080e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3081e778d10cSEric Fiselier    try {
3082e778d10cSEric Fiselier#endif
3083e778d10cSEric Fiselier    for (; __first != __last; (void)++__idx, ++__first)
3084d586f92cSArthur O'Dwyer        ::new((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
3085e778d10cSEric Fiselier    return __idx;
3086e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3087e778d10cSEric Fiselier    } catch (...) {
3088e778d10cSEric Fiselier        _VSTD::destroy(__first_res, __idx);
3089e778d10cSEric Fiselier        throw;
3090e778d10cSEric Fiselier    }
3091e778d10cSEric Fiselier#endif
3092e778d10cSEric Fiselier}
3093e778d10cSEric Fiselier
3094e778d10cSEric Fiseliertemplate <class _InputIt, class _Size, class _ForwardIt>
3095e778d10cSEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
3096e778d10cSEric Fiselierpair<_InputIt, _ForwardIt>
3097e778d10cSEric Fiselieruninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
3098e778d10cSEric Fiselier    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
3099e778d10cSEric Fiselier    auto __idx = __first_res;
3100e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3101e778d10cSEric Fiselier    try {
3102e778d10cSEric Fiselier#endif
3103e778d10cSEric Fiselier    for (; __n > 0; ++__idx, (void)++__first, --__n)
3104d586f92cSArthur O'Dwyer        ::new((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
3105e778d10cSEric Fiselier    return {__first, __idx};
3106e778d10cSEric Fiselier#ifndef _LIBCPP_NO_EXCEPTIONS
3107e778d10cSEric Fiselier    } catch (...) {
3108e778d10cSEric Fiselier        _VSTD::destroy(__first_res, __idx);
3109e778d10cSEric Fiselier        throw;
3110e778d10cSEric Fiselier    }
3111e778d10cSEric Fiselier#endif
3112e778d10cSEric Fiselier}
3113e778d10cSEric Fiselier
3114e778d10cSEric Fiselier
3115e4d9c316SEric Fiselier#endif // _LIBCPP_STD_VER > 14
3116e4d9c316SEric Fiselier
3117f08de52dSKevin Hu// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
3118f08de52dSKevin Hu// should be sufficient for thread safety.
31193c35491fSEric Fiselier// See https://bugs.llvm.org/show_bug.cgi?id=22803
3120f08de52dSKevin Hu#if defined(__clang__) && __has_builtin(__atomic_add_fetch)          \
3121f08de52dSKevin Hu                       && defined(__ATOMIC_RELAXED)                  \
3122f08de52dSKevin Hu                       && defined(__ATOMIC_ACQ_REL)
3123f08de52dSKevin Hu#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
3124ae62727aSRichard Smith#elif defined(_LIBCPP_COMPILER_GCC)
3125f08de52dSKevin Hu#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
3126f08de52dSKevin Hu#endif
3127f08de52dSKevin Hu
3128f08de52dSKevin Hutemplate <class _Tp>
3129f08de52dSKevin Huinline _LIBCPP_INLINE_VISIBILITY _Tp
3130f08de52dSKevin Hu__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
3131f08de52dSKevin Hu{
3132f08de52dSKevin Hu#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
3133f08de52dSKevin Hu    return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
3134f08de52dSKevin Hu#else
3135f08de52dSKevin Hu    return __t += 1;
3136f08de52dSKevin Hu#endif
3137f08de52dSKevin Hu}
3138f08de52dSKevin Hu
3139f08de52dSKevin Hutemplate <class _Tp>
3140f08de52dSKevin Huinline _LIBCPP_INLINE_VISIBILITY _Tp
3141f08de52dSKevin Hu__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
3142f08de52dSKevin Hu{
3143f08de52dSKevin Hu#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
3144f08de52dSKevin Hu    return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
3145f08de52dSKevin Hu#else
3146f08de52dSKevin Hu    return __t -= 1;
3147f08de52dSKevin Hu#endif
3148f08de52dSKevin Hu}
3149f08de52dSKevin Hu
3150848a5374SHoward Hinnantclass _LIBCPP_EXCEPTION_ABI bad_weak_ptr
31513e519524SHoward Hinnant    : public std::exception
31523e519524SHoward Hinnant{
31533e519524SHoward Hinnantpublic:
3154585a3cc3SDimitry Andric    bad_weak_ptr() _NOEXCEPT = default;
3155585a3cc3SDimitry Andric    bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
31563739fe79SHoward Hinnant    virtual ~bad_weak_ptr() _NOEXCEPT;
31573739fe79SHoward Hinnant    virtual const char* what() const  _NOEXCEPT;
31583e519524SHoward Hinnant};
31593e519524SHoward Hinnant
3160dc7200b4SLouis Dionne_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
3161d437fa5cSMarshall Clowvoid __throw_bad_weak_ptr()
3162d437fa5cSMarshall Clow{
3163d437fa5cSMarshall Clow#ifndef _LIBCPP_NO_EXCEPTIONS
3164d437fa5cSMarshall Clow    throw bad_weak_ptr();
3165d437fa5cSMarshall Clow#else
3166d437fa5cSMarshall Clow    _VSTD::abort();
3167d437fa5cSMarshall Clow#endif
3168d437fa5cSMarshall Clow}
3169d437fa5cSMarshall Clow
3170e2f2d1edSEric Fiseliertemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
31713e519524SHoward Hinnant
3172f0544c20SHoward Hinnantclass _LIBCPP_TYPE_VIS __shared_count
31733e519524SHoward Hinnant{
31743e519524SHoward Hinnant    __shared_count(const __shared_count&);
31753e519524SHoward Hinnant    __shared_count& operator=(const __shared_count&);
31763e519524SHoward Hinnant
31773e519524SHoward Hinnantprotected:
31783e519524SHoward Hinnant    long __shared_owners_;
31793e519524SHoward Hinnant    virtual ~__shared_count();
31803e519524SHoward Hinnantprivate:
31813739fe79SHoward Hinnant    virtual void __on_zero_shared() _NOEXCEPT = 0;
31823e519524SHoward Hinnant
31833e519524SHoward Hinnantpublic:
3184848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
31853739fe79SHoward Hinnant    explicit __shared_count(long __refs = 0) _NOEXCEPT
31863e519524SHoward Hinnant        : __shared_owners_(__refs) {}
31873e519524SHoward Hinnant
3188c8e84ff2SLouis Dionne#if defined(_LIBCPP_BUILDING_LIBRARY) && \
318911f60453SEric Fiselier    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
3190a480c28bSEric Fiselier    void __add_shared() _NOEXCEPT;
3191a480c28bSEric Fiselier    bool __release_shared() _NOEXCEPT;
3192f08de52dSKevin Hu#else
3193f08de52dSKevin Hu    _LIBCPP_INLINE_VISIBILITY
3194f08de52dSKevin Hu    void __add_shared() _NOEXCEPT {
3195f08de52dSKevin Hu      __libcpp_atomic_refcount_increment(__shared_owners_);
3196f08de52dSKevin Hu    }
3197f08de52dSKevin Hu    _LIBCPP_INLINE_VISIBILITY
3198f08de52dSKevin Hu    bool __release_shared() _NOEXCEPT {
3199f08de52dSKevin Hu      if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
3200f08de52dSKevin Hu        __on_zero_shared();
3201f08de52dSKevin Hu        return true;
3202f08de52dSKevin Hu      }
3203f08de52dSKevin Hu      return false;
3204f08de52dSKevin Hu    }
3205f08de52dSKevin Hu#endif
3206848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
32071faf289eSEric Fiselier    long use_count() const _NOEXCEPT {
32081faf289eSEric Fiselier        return __libcpp_relaxed_load(&__shared_owners_) + 1;
32091faf289eSEric Fiselier    }
32103e519524SHoward Hinnant};
32113e519524SHoward Hinnant
3212f0544c20SHoward Hinnantclass _LIBCPP_TYPE_VIS __shared_weak_count
32133e519524SHoward Hinnant    : private __shared_count
32143e519524SHoward Hinnant{
32153e519524SHoward Hinnant    long __shared_weak_owners_;
32163e519524SHoward Hinnant
32173e519524SHoward Hinnantpublic:
3218848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
32193739fe79SHoward Hinnant    explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
32203e519524SHoward Hinnant        : __shared_count(__refs),
32213e519524SHoward Hinnant          __shared_weak_owners_(__refs) {}
32223e519524SHoward Hinnantprotected:
32233e519524SHoward Hinnant    virtual ~__shared_weak_count();
32243e519524SHoward Hinnant
32253e519524SHoward Hinnantpublic:
3226c8e84ff2SLouis Dionne#if defined(_LIBCPP_BUILDING_LIBRARY) && \
322711f60453SEric Fiselier    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
3228a480c28bSEric Fiselier    void __add_shared() _NOEXCEPT;
3229a480c28bSEric Fiselier    void __add_weak() _NOEXCEPT;
3230a480c28bSEric Fiselier    void __release_shared() _NOEXCEPT;
3231f08de52dSKevin Hu#else
3232f08de52dSKevin Hu    _LIBCPP_INLINE_VISIBILITY
3233f08de52dSKevin Hu    void __add_shared() _NOEXCEPT {
3234f08de52dSKevin Hu      __shared_count::__add_shared();
3235f08de52dSKevin Hu    }
3236f08de52dSKevin Hu    _LIBCPP_INLINE_VISIBILITY
3237f08de52dSKevin Hu    void __add_weak() _NOEXCEPT {
3238f08de52dSKevin Hu      __libcpp_atomic_refcount_increment(__shared_weak_owners_);
3239f08de52dSKevin Hu    }
3240f08de52dSKevin Hu    _LIBCPP_INLINE_VISIBILITY
3241f08de52dSKevin Hu    void __release_shared() _NOEXCEPT {
3242f08de52dSKevin Hu      if (__shared_count::__release_shared())
3243f08de52dSKevin Hu        __release_weak();
3244f08de52dSKevin Hu    }
3245f08de52dSKevin Hu#endif
32463739fe79SHoward Hinnant    void __release_weak() _NOEXCEPT;
3247848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
32483739fe79SHoward Hinnant    long use_count() const _NOEXCEPT {return __shared_count::use_count();}
32493739fe79SHoward Hinnant    __shared_weak_count* lock() _NOEXCEPT;
32503e519524SHoward Hinnant
32513739fe79SHoward Hinnant    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
32523e519524SHoward Hinnantprivate:
32533739fe79SHoward Hinnant    virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
32543e519524SHoward Hinnant};
32553e519524SHoward Hinnant
32563e519524SHoward Hinnanttemplate <class _Tp, class _Dp, class _Alloc>
32573e519524SHoward Hinnantclass __shared_ptr_pointer
32583e519524SHoward Hinnant    : public __shared_weak_count
32593e519524SHoward Hinnant{
32603e519524SHoward Hinnant    __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
32613e519524SHoward Hinnantpublic:
3262848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
32633e519524SHoward Hinnant    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
3264ce48a113SHoward Hinnant        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
32653e519524SHoward Hinnant
326654b409fdSHoward Hinnant#ifndef _LIBCPP_NO_RTTI
32673739fe79SHoward Hinnant    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
326854b409fdSHoward Hinnant#endif
32693e519524SHoward Hinnant
32703e519524SHoward Hinnantprivate:
32713739fe79SHoward Hinnant    virtual void __on_zero_shared() _NOEXCEPT;
32723739fe79SHoward Hinnant    virtual void __on_zero_shared_weak() _NOEXCEPT;
32733e519524SHoward Hinnant};
32743e519524SHoward Hinnant
327554b409fdSHoward Hinnant#ifndef _LIBCPP_NO_RTTI
327654b409fdSHoward Hinnant
32773e519524SHoward Hinnanttemplate <class _Tp, class _Dp, class _Alloc>
32783e519524SHoward Hinnantconst void*
32793739fe79SHoward Hinnant__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
32803e519524SHoward Hinnant{
32819c973b9fSEric Fiselier    return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
32823e519524SHoward Hinnant}
32833e519524SHoward Hinnant
3284b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_RTTI
328554b409fdSHoward Hinnant
32863e519524SHoward Hinnanttemplate <class _Tp, class _Dp, class _Alloc>
32873e519524SHoward Hinnantvoid
32883739fe79SHoward Hinnant__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
32893e519524SHoward Hinnant{
32903e519524SHoward Hinnant    __data_.first().second()(__data_.first().first());
32913e519524SHoward Hinnant    __data_.first().second().~_Dp();
32923e519524SHoward Hinnant}
32933e519524SHoward Hinnant
32943e519524SHoward Hinnanttemplate <class _Tp, class _Dp, class _Alloc>
32953e519524SHoward Hinnantvoid
32963739fe79SHoward Hinnant__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
32973e519524SHoward Hinnant{
32986fe361c1SEric Fiselier    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
32996fe361c1SEric Fiselier    typedef allocator_traits<_Al> _ATraits;
3300319be722SEric Fiselier    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
3301319be722SEric Fiselier
33026fe361c1SEric Fiselier    _Al __a(__data_.second());
33033e519524SHoward Hinnant    __data_.second().~_Alloc();
3304319be722SEric Fiselier    __a.deallocate(_PTraits::pointer_to(*this), 1);
33053e519524SHoward Hinnant}
33063e519524SHoward Hinnant
33073e519524SHoward Hinnanttemplate <class _Tp, class _Alloc>
3308*092e8a7eSLouis Dionnestruct __shared_ptr_emplace
3309*092e8a7eSLouis Dionne    : __shared_weak_count
33103e519524SHoward Hinnant{
3311*092e8a7eSLouis Dionne    _LIBCPP_HIDE_FROM_ABI
3312*092e8a7eSLouis Dionne    explicit __shared_ptr_emplace(_Alloc __a)
3313*092e8a7eSLouis Dionne        :  __data_(_VSTD::move(__a), __value_init_tag())
3314*092e8a7eSLouis Dionne    { }
33153e519524SHoward Hinnant
3316*092e8a7eSLouis Dionne    template <class ..._Args>
3317*092e8a7eSLouis Dionne    _LIBCPP_HIDE_FROM_ABI
3318*092e8a7eSLouis Dionne    explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
3319a3c28ccdSLouis Dionne#ifndef _LIBCPP_CXX03_LANG
3320a87b5e34SHoward Hinnant        : __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
3321*092e8a7eSLouis Dionne                  _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...))
3322a3c28ccdSLouis Dionne#else
3323*092e8a7eSLouis Dionne        : __data_(__a, _Tp(_VSTD::forward<_Args>(__args)...))
3324a3c28ccdSLouis Dionne#endif
3325*092e8a7eSLouis Dionne    { }
3326*092e8a7eSLouis Dionne
3327*092e8a7eSLouis Dionne    _LIBCPP_HIDE_FROM_ABI
3328*092e8a7eSLouis Dionne    _Tp* __get_elem() _NOEXCEPT { return _VSTD::addressof(__data_.second()); }
3329*092e8a7eSLouis Dionne
3330*092e8a7eSLouis Dionne    _LIBCPP_HIDE_FROM_ABI
3331*092e8a7eSLouis Dionne    _Alloc& __get_alloc() _NOEXCEPT { return __data_.first(); }
33323e519524SHoward Hinnant
33333e519524SHoward Hinnantprivate:
3334*092e8a7eSLouis Dionne    virtual void __on_zero_shared() _NOEXCEPT {
333502af1109SLouis Dionne        __get_elem()->~_Tp();
33363e519524SHoward Hinnant    }
33373e519524SHoward Hinnant
3338*092e8a7eSLouis Dionne    virtual void __on_zero_shared_weak() _NOEXCEPT {
3339*092e8a7eSLouis Dionne        using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
3340*092e8a7eSLouis Dionne        using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
3341*092e8a7eSLouis Dionne        _ControlBlockAlloc __tmp(__get_alloc());
334202af1109SLouis Dionne        __get_alloc().~_Alloc();
3343*092e8a7eSLouis Dionne        allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
3344*092e8a7eSLouis Dionne            pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
33453e519524SHoward Hinnant    }
33463e519524SHoward Hinnant
3347*092e8a7eSLouis Dionne    __compressed_pair<_Alloc, _Tp> __data_;
3348*092e8a7eSLouis Dionne};
3349*092e8a7eSLouis Dionne
335072d0d603SErik Pilkingtonstruct __shared_ptr_dummy_rebind_allocator_type;
335172d0d603SErik Pilkingtontemplate <>
335272d0d603SErik Pilkingtonclass _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
335372d0d603SErik Pilkington{
335472d0d603SErik Pilkingtonpublic:
335572d0d603SErik Pilkington    template <class _Other>
335672d0d603SErik Pilkington    struct rebind
335772d0d603SErik Pilkington    {
335872d0d603SErik Pilkington        typedef allocator<_Other> other;
335972d0d603SErik Pilkington    };
336072d0d603SErik Pilkington};
336172d0d603SErik Pilkington
3362e2f2d1edSEric Fiseliertemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
33633e519524SHoward Hinnant
3364ce195fb2Szoecarvertemplate<class _Tp, class _Up>
3365ce195fb2Szoecarverstruct __compatible_with
3366ce195fb2Szoecarver#if _LIBCPP_STD_VER > 14
3367ce195fb2Szoecarver    : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
3368ce195fb2Szoecarver#else
3369ce195fb2Szoecarver    : is_convertible<_Tp*, _Up*> {};
3370ce195fb2Szoecarver#endif // _LIBCPP_STD_VER > 14
3371ce195fb2Szoecarver
337276887bc4SVy Nguyen#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
337376887bc4SVy Nguyen#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
337476887bc4SVy Nguyen#else
337576887bc4SVy Nguyen#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
337676887bc4SVy Nguyen#endif
337776887bc4SVy Nguyen
33783e519524SHoward Hinnanttemplate<class _Tp>
337976887bc4SVy Nguyenclass _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
33803e519524SHoward Hinnant{
33813e519524SHoward Hinnantpublic:
338268436a9bSEric Fiselier#if _LIBCPP_STD_VER > 14
338368436a9bSEric Fiselier    typedef weak_ptr<_Tp> weak_type;
3384ce195fb2Szoecarver    typedef remove_extent_t<_Tp> element_type;
3385ce195fb2Szoecarver#else
3386ce195fb2Szoecarver    typedef _Tp element_type;
338768436a9bSEric Fiselier#endif
3388ce195fb2Szoecarver
33893e519524SHoward Hinnantprivate:
33903e519524SHoward Hinnant    element_type*      __ptr_;
33913e519524SHoward Hinnant    __shared_weak_count* __cntrl_;
33923e519524SHoward Hinnant
33933e519524SHoward Hinnant    struct __nat {int __for_bool_;};
33943e519524SHoward Hinnantpublic:
3395906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
3396c0937e8aSHoward Hinnant    _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
3397906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
3398c0937e8aSHoward Hinnant    _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
339922747e62SLogan Chien    template<class _Yp>
340022747e62SLogan Chien        explicit shared_ptr(_Yp* __p,
3401ce195fb2Szoecarver                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
340222747e62SLogan Chien    template<class _Yp, class _Dp>
340322747e62SLogan Chien        shared_ptr(_Yp* __p, _Dp __d,
3404ce195fb2Szoecarver                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
340522747e62SLogan Chien    template<class _Yp, class _Dp, class _Alloc>
340622747e62SLogan Chien        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
3407ce195fb2Szoecarver                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
34083e519524SHoward Hinnant    template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
34093e519524SHoward Hinnant    template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
3410906c872dSEvgeniy Stepanov    template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
3411906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
34123739fe79SHoward Hinnant    shared_ptr(const shared_ptr& __r) _NOEXCEPT;
34133e519524SHoward Hinnant    template<class _Yp>
3414906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
34153e519524SHoward Hinnant        shared_ptr(const shared_ptr<_Yp>& __r,
3416ce195fb2Szoecarver                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
34173739fe79SHoward Hinnant                       _NOEXCEPT;
3418906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
34193739fe79SHoward Hinnant    shared_ptr(shared_ptr&& __r) _NOEXCEPT;
3420906c872dSEvgeniy Stepanov    template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r,
3421ce195fb2Szoecarver                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
34223739fe79SHoward Hinnant                       _NOEXCEPT;
34233e519524SHoward Hinnant    template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
3424dc83e779SMarshall Clow                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
3425e67179bcSMarshall Clow#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
342622747e62SLogan Chien    template<class _Yp>
342722747e62SLogan Chien        shared_ptr(auto_ptr<_Yp>&& __r,
342822747e62SLogan Chien                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
3429e67179bcSMarshall Clow#endif
343022747e62SLogan Chien    template <class _Yp, class _Dp>
34318e25104bSHoward Hinnant        shared_ptr(unique_ptr<_Yp, _Dp>&&,
343222747e62SLogan Chien                   typename enable_if
34338e25104bSHoward Hinnant                   <
343422747e62SLogan Chien                       !is_lvalue_reference<_Dp>::value &&
34358e25104bSHoward Hinnant                       !is_array<_Yp>::value &&
343622747e62SLogan Chien                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
343722747e62SLogan Chien                       __nat
343822747e62SLogan Chien                   >::type = __nat());
343922747e62SLogan Chien    template <class _Yp, class _Dp>
34408e25104bSHoward Hinnant        shared_ptr(unique_ptr<_Yp, _Dp>&&,
344122747e62SLogan Chien                   typename enable_if
344222747e62SLogan Chien                   <
344322747e62SLogan Chien                       is_lvalue_reference<_Dp>::value &&
344422747e62SLogan Chien                       !is_array<_Yp>::value &&
344522747e62SLogan Chien                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
344622747e62SLogan Chien                       __nat
344722747e62SLogan Chien                   >::type = __nat());
34483e519524SHoward Hinnant
34493e519524SHoward Hinnant    ~shared_ptr();
34503e519524SHoward Hinnant
3451906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
34523739fe79SHoward Hinnant    shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
34538e25104bSHoward Hinnant    template<class _Yp>
34548e25104bSHoward Hinnant        typename enable_if
34558e25104bSHoward Hinnant        <
3456ce195fb2Szoecarver            __compatible_with<_Yp, element_type>::value,
34578e25104bSHoward Hinnant            shared_ptr&
34588e25104bSHoward Hinnant        >::type
3459906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
34608e25104bSHoward Hinnant        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
3461906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
34623739fe79SHoward Hinnant    shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
34638e25104bSHoward Hinnant    template<class _Yp>
34648e25104bSHoward Hinnant        typename enable_if
34658e25104bSHoward Hinnant        <
3466ce195fb2Szoecarver            __compatible_with<_Yp, element_type>::value,
3467ce195fb2Szoecarver            shared_ptr&
34688e25104bSHoward Hinnant        >::type
3469906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
34708e25104bSHoward Hinnant        operator=(shared_ptr<_Yp>&& __r);
3471e67179bcSMarshall Clow#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
34728e25104bSHoward Hinnant    template<class _Yp>
347389dd1dd2SEric Fiselier        _LIBCPP_INLINE_VISIBILITY
34748e25104bSHoward Hinnant        typename enable_if
34758e25104bSHoward Hinnant        <
34768e25104bSHoward Hinnant            !is_array<_Yp>::value &&
34778e25104bSHoward Hinnant            is_convertible<_Yp*, element_type*>::value,
347884f996fbSHoward Hinnant            shared_ptr
347984f996fbSHoward Hinnant        >::type&
34808e25104bSHoward Hinnant        operator=(auto_ptr<_Yp>&& __r);
3481e67179bcSMarshall Clow#endif
34828e25104bSHoward Hinnant    template <class _Yp, class _Dp>
34838e25104bSHoward Hinnant        typename enable_if
34848e25104bSHoward Hinnant        <
34858e25104bSHoward Hinnant            !is_array<_Yp>::value &&
34868e25104bSHoward Hinnant            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
34878e25104bSHoward Hinnant            shared_ptr&
34888e25104bSHoward Hinnant        >::type
3489906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
34908e25104bSHoward Hinnant        operator=(unique_ptr<_Yp, _Dp>&& __r);
34913e519524SHoward Hinnant
3492906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
34933739fe79SHoward Hinnant    void swap(shared_ptr& __r) _NOEXCEPT;
3494906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
34953739fe79SHoward Hinnant    void reset() _NOEXCEPT;
34968e25104bSHoward Hinnant    template<class _Yp>
34978e25104bSHoward Hinnant        typename enable_if
34988e25104bSHoward Hinnant        <
3499ce195fb2Szoecarver            __compatible_with<_Yp, element_type>::value,
35008e25104bSHoward Hinnant            void
35018e25104bSHoward Hinnant        >::type
3502906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
35038e25104bSHoward Hinnant        reset(_Yp* __p);
35048e25104bSHoward Hinnant    template<class _Yp, class _Dp>
35058e25104bSHoward Hinnant        typename enable_if
35068e25104bSHoward Hinnant        <
3507ce195fb2Szoecarver            __compatible_with<_Yp, element_type>::value,
35088e25104bSHoward Hinnant            void
35098e25104bSHoward Hinnant        >::type
3510906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
35118e25104bSHoward Hinnant        reset(_Yp* __p, _Dp __d);
35128e25104bSHoward Hinnant    template<class _Yp, class _Dp, class _Alloc>
35138e25104bSHoward Hinnant        typename enable_if
35148e25104bSHoward Hinnant        <
3515ce195fb2Szoecarver            __compatible_with<_Yp, element_type>::value,
35168e25104bSHoward Hinnant            void
35178e25104bSHoward Hinnant        >::type
3518906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
35198e25104bSHoward Hinnant        reset(_Yp* __p, _Dp __d, _Alloc __a);
35203e519524SHoward Hinnant
3521848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
35223739fe79SHoward Hinnant    element_type* get() const _NOEXCEPT {return __ptr_;}
3523848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
35243739fe79SHoward Hinnant    typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
35253739fe79SHoward Hinnant        {return *__ptr_;}
3526848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
3527ce195fb2Szoecarver    element_type* operator->() const _NOEXCEPT
3528ce195fb2Szoecarver    {
3529ce195fb2Szoecarver        static_assert(!_VSTD::is_array<_Tp>::value,
3530ce195fb2Szoecarver                      "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
3531ce195fb2Szoecarver        return __ptr_;
3532ce195fb2Szoecarver    }
3533848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
35343739fe79SHoward Hinnant    long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
3535848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
35363739fe79SHoward Hinnant    bool unique() const _NOEXCEPT {return use_count() == 1;}
3537848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
3538527a7fdfSBruce Mitchener    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != nullptr;}
3539c003db1fSHoward Hinnant    template <class _Up>
3540848a5374SHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
354136bc7178SMarshall Clow        bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
35423e519524SHoward Hinnant        {return __cntrl_ < __p.__cntrl_;}
3543c003db1fSHoward Hinnant    template <class _Up>
3544848a5374SHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
354536bc7178SMarshall Clow        bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
35463e519524SHoward Hinnant        {return __cntrl_ < __p.__cntrl_;}
3547d77851e8SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
3548d77851e8SHoward Hinnant    bool
3549d77851e8SHoward Hinnant    __owner_equivalent(const shared_ptr& __p) const
3550d77851e8SHoward Hinnant        {return __cntrl_ == __p.__cntrl_;}
35513e519524SHoward Hinnant
3552ce195fb2Szoecarver#if _LIBCPP_STD_VER > 14
3553ce195fb2Szoecarver    typename add_lvalue_reference<element_type>::type
3554ce195fb2Szoecarver    _LIBCPP_INLINE_VISIBILITY
3555ce195fb2Szoecarver    operator[](ptrdiff_t __i) const
3556ce195fb2Szoecarver    {
3557ce195fb2Szoecarver            static_assert(_VSTD::is_array<_Tp>::value,
3558ce195fb2Szoecarver                          "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
3559ce195fb2Szoecarver            return __ptr_[__i];
3560ce195fb2Szoecarver    }
3561ce195fb2Szoecarver#endif
3562ce195fb2Szoecarver
356354b409fdSHoward Hinnant#ifndef _LIBCPP_NO_RTTI
35643e519524SHoward Hinnant    template <class _Dp>
3565848a5374SHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
35663739fe79SHoward Hinnant        _Dp* __get_deleter() const _NOEXCEPT
35674a911c86SMarshall Clow            {return static_cast<_Dp*>(__cntrl_
35684a911c86SMarshall Clow                    ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
35694a911c86SMarshall Clow                      : nullptr);}
3570b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_RTTI
35713e519524SHoward Hinnant
357240c47680SZoe Carver    template<class _Yp, class _CntrlBlk>
357340c47680SZoe Carver    static shared_ptr<_Tp>
357421d4050eSzoecarver    __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
357540c47680SZoe Carver    {
357640c47680SZoe Carver        shared_ptr<_Tp> __r;
357740c47680SZoe Carver        __r.__ptr_ = __p;
357840c47680SZoe Carver        __r.__cntrl_ = __cntrl;
357940c47680SZoe Carver        __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
358040c47680SZoe Carver        return __r;
358140c47680SZoe Carver    }
3582471bbb6eSZoe Carver
35833e519524SHoward Hinnantprivate:
358472d0d603SErik Pilkington    template <class _Yp, bool = is_function<_Yp>::value>
358572d0d603SErik Pilkington        struct __shared_ptr_default_allocator
358672d0d603SErik Pilkington        {
358772d0d603SErik Pilkington            typedef allocator<_Yp> type;
358872d0d603SErik Pilkington        };
358972d0d603SErik Pilkington
359072d0d603SErik Pilkington    template <class _Yp>
359172d0d603SErik Pilkington        struct __shared_ptr_default_allocator<_Yp, true>
359272d0d603SErik Pilkington        {
359372d0d603SErik Pilkington            typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
359472d0d603SErik Pilkington        };
35953e519524SHoward Hinnant
359639005d30SEric Fiselier    template <class _Yp, class _OrigPtr>
3597848a5374SHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
3598f09df772SEric Fiselier        typename enable_if<is_convertible<_OrigPtr*,
3599f09df772SEric Fiselier                                          const enable_shared_from_this<_Yp>*
3600f09df772SEric Fiselier        >::value,
3601f09df772SEric Fiselier            void>::type
360239005d30SEric Fiselier        __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
360339005d30SEric Fiselier                           _OrigPtr* __ptr) _NOEXCEPT
36043e519524SHoward Hinnant        {
360539005d30SEric Fiselier            typedef typename remove_cv<_Yp>::type _RawYp;
360688f5bfdcSEric Fiselier            if (__e && __e->__weak_this_.expired())
360755112defSMarshall Clow            {
360839005d30SEric Fiselier                __e->__weak_this_ = shared_ptr<_RawYp>(*this,
360939005d30SEric Fiselier                    const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
361055112defSMarshall Clow            }
36113e519524SHoward Hinnant        }
36123e519524SHoward Hinnant
361372d0d603SErik Pilkington    _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
36143e519524SHoward Hinnant
3615ce195fb2Szoecarver    template <class, class _Yp>
3616ce195fb2Szoecarver        struct __shared_ptr_default_delete
3617ce195fb2Szoecarver            : default_delete<_Yp> {};
3618ce195fb2Szoecarver
3619ce195fb2Szoecarver    template <class _Yp, class _Un, size_t _Sz>
3620ce195fb2Szoecarver        struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
3621ce195fb2Szoecarver            : default_delete<_Yp[]> {};
3622ce195fb2Szoecarver
3623ce195fb2Szoecarver    template <class _Yp, class _Un>
3624ce195fb2Szoecarver        struct __shared_ptr_default_delete<_Yp[], _Un>
3625ce195fb2Szoecarver            : default_delete<_Yp[]> {};
3626ce195fb2Szoecarver
3627e2f2d1edSEric Fiselier    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
3628e2f2d1edSEric Fiselier    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
36293e519524SHoward Hinnant};
36303e519524SHoward Hinnant
363183564056SLogan Smith#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
363283564056SLogan Smithtemplate<class _Tp>
363383564056SLogan Smithshared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
363483564056SLogan Smithtemplate<class _Tp, class _Dp>
363583564056SLogan Smithshared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
363683564056SLogan Smith#endif
3637f09df772SEric Fiselier
36383e519524SHoward Hinnanttemplate<class _Tp>
3639906c872dSEvgeniy Stepanovinline
3640c0937e8aSHoward Hinnant_LIBCPP_CONSTEXPR
36413739fe79SHoward Hinnantshared_ptr<_Tp>::shared_ptr() _NOEXCEPT
3642527a7fdfSBruce Mitchener    : __ptr_(nullptr),
3643527a7fdfSBruce Mitchener      __cntrl_(nullptr)
36443e519524SHoward Hinnant{
36453e519524SHoward Hinnant}
36463e519524SHoward Hinnant
36473e519524SHoward Hinnanttemplate<class _Tp>
3648906c872dSEvgeniy Stepanovinline
3649c0937e8aSHoward Hinnant_LIBCPP_CONSTEXPR
36503739fe79SHoward Hinnantshared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
3651527a7fdfSBruce Mitchener    : __ptr_(nullptr),
3652527a7fdfSBruce Mitchener      __cntrl_(nullptr)
36533e519524SHoward Hinnant{
36543e519524SHoward Hinnant}
36553e519524SHoward Hinnant
36563e519524SHoward Hinnanttemplate<class _Tp>
365722747e62SLogan Chientemplate<class _Yp>
365822747e62SLogan Chienshared_ptr<_Tp>::shared_ptr(_Yp* __p,
3659ce195fb2Szoecarver                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
36603e519524SHoward Hinnant    : __ptr_(__p)
36613e519524SHoward Hinnant{
36623e519524SHoward Hinnant    unique_ptr<_Yp> __hold(__p);
366372d0d603SErik Pilkington    typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
3664ce195fb2Szoecarver    typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
3665ce195fb2Szoecarver    __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
36663e519524SHoward Hinnant    __hold.release();
366739005d30SEric Fiselier    __enable_weak_this(__p, __p);
36683e519524SHoward Hinnant}
36693e519524SHoward Hinnant
36703e519524SHoward Hinnanttemplate<class _Tp>
367122747e62SLogan Chientemplate<class _Yp, class _Dp>
367222747e62SLogan Chienshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
3673ce195fb2Szoecarver                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
36743e519524SHoward Hinnant    : __ptr_(__p)
36753e519524SHoward Hinnant{
36763e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
36773e519524SHoward Hinnant    try
36783e519524SHoward Hinnant    {
3679b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
368072d0d603SErik Pilkington        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
368172d0d603SErik Pilkington        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
368272d0d603SErik Pilkington        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
368339005d30SEric Fiselier        __enable_weak_this(__p, __p);
36843e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
36853e519524SHoward Hinnant    }
36863e519524SHoward Hinnant    catch (...)
36873e519524SHoward Hinnant    {
36883e519524SHoward Hinnant        __d(__p);
36893e519524SHoward Hinnant        throw;
36903e519524SHoward Hinnant    }
3691b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
36923e519524SHoward Hinnant}
36933e519524SHoward Hinnant
36943e519524SHoward Hinnanttemplate<class _Tp>
36953e519524SHoward Hinnanttemplate<class _Dp>
36963e519524SHoward Hinnantshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
3697527a7fdfSBruce Mitchener    : __ptr_(nullptr)
36983e519524SHoward Hinnant{
36993e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
37003e519524SHoward Hinnant    try
37013e519524SHoward Hinnant    {
3702b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
370372d0d603SErik Pilkington        typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
370472d0d603SErik Pilkington        typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
370572d0d603SErik Pilkington        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
37063e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
37073e519524SHoward Hinnant    }
37083e519524SHoward Hinnant    catch (...)
37093e519524SHoward Hinnant    {
37103e519524SHoward Hinnant        __d(__p);
37113e519524SHoward Hinnant        throw;
37123e519524SHoward Hinnant    }
3713b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
37143e519524SHoward Hinnant}
37153e519524SHoward Hinnant
37163e519524SHoward Hinnanttemplate<class _Tp>
371722747e62SLogan Chientemplate<class _Yp, class _Dp, class _Alloc>
371822747e62SLogan Chienshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
3719ce195fb2Szoecarver                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
37203e519524SHoward Hinnant    : __ptr_(__p)
37213e519524SHoward Hinnant{
37223e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
37233e519524SHoward Hinnant    try
37243e519524SHoward Hinnant    {
3725b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
37263e519524SHoward Hinnant        typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
3727319be722SEric Fiselier        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
37283e519524SHoward Hinnant        typedef __allocator_destructor<_A2> _D2;
37293e519524SHoward Hinnant        _A2 __a2(__a);
37303e519524SHoward Hinnant        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
3731319be722SEric Fiselier        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
3732319be722SEric Fiselier            _CntrlBlk(__p, __d, __a);
3733319be722SEric Fiselier        __cntrl_ = _VSTD::addressof(*__hold2.release());
373439005d30SEric Fiselier        __enable_weak_this(__p, __p);
37353e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
37363e519524SHoward Hinnant    }
37373e519524SHoward Hinnant    catch (...)
37383e519524SHoward Hinnant    {
37393e519524SHoward Hinnant        __d(__p);
37403e519524SHoward Hinnant        throw;
37413e519524SHoward Hinnant    }
3742b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
37433e519524SHoward Hinnant}
37443e519524SHoward Hinnant
37453e519524SHoward Hinnanttemplate<class _Tp>
37463e519524SHoward Hinnanttemplate<class _Dp, class _Alloc>
37473e519524SHoward Hinnantshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
3748527a7fdfSBruce Mitchener    : __ptr_(nullptr)
37493e519524SHoward Hinnant{
37503e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
37513e519524SHoward Hinnant    try
37523e519524SHoward Hinnant    {
3753b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
37543e519524SHoward Hinnant        typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
3755319be722SEric Fiselier        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
37563e519524SHoward Hinnant        typedef __allocator_destructor<_A2> _D2;
37573e519524SHoward Hinnant        _A2 __a2(__a);
37583e519524SHoward Hinnant        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
3759319be722SEric Fiselier        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
3760319be722SEric Fiselier            _CntrlBlk(__p, __d, __a);
3761319be722SEric Fiselier        __cntrl_ = _VSTD::addressof(*__hold2.release());
37623e519524SHoward Hinnant#ifndef _LIBCPP_NO_EXCEPTIONS
37633e519524SHoward Hinnant    }
37643e519524SHoward Hinnant    catch (...)
37653e519524SHoward Hinnant    {
37663e519524SHoward Hinnant        __d(__p);
37673e519524SHoward Hinnant        throw;
37683e519524SHoward Hinnant    }
3769b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_EXCEPTIONS
37703e519524SHoward Hinnant}
37713e519524SHoward Hinnant
37723e519524SHoward Hinnanttemplate<class _Tp>
37733e519524SHoward Hinnanttemplate<class _Yp>
3774906c872dSEvgeniy Stepanovinline
37753739fe79SHoward Hinnantshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
37763e519524SHoward Hinnant    : __ptr_(__p),
37773e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
37783e519524SHoward Hinnant{
37793e519524SHoward Hinnant    if (__cntrl_)
37803e519524SHoward Hinnant        __cntrl_->__add_shared();
37813e519524SHoward Hinnant}
37823e519524SHoward Hinnant
37833e519524SHoward Hinnanttemplate<class _Tp>
3784906c872dSEvgeniy Stepanovinline
37853739fe79SHoward Hinnantshared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
37863e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
37873e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
37883e519524SHoward Hinnant{
37893e519524SHoward Hinnant    if (__cntrl_)
37903e519524SHoward Hinnant        __cntrl_->__add_shared();
37913e519524SHoward Hinnant}
37923e519524SHoward Hinnant
37933e519524SHoward Hinnanttemplate<class _Tp>
37943e519524SHoward Hinnanttemplate<class _Yp>
3795906c872dSEvgeniy Stepanovinline
37963e519524SHoward Hinnantshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
3797ce195fb2Szoecarver                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
37983739fe79SHoward Hinnant         _NOEXCEPT
37993e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
38003e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
38013e519524SHoward Hinnant{
38023e519524SHoward Hinnant    if (__cntrl_)
38033e519524SHoward Hinnant        __cntrl_->__add_shared();
38043e519524SHoward Hinnant}
38053e519524SHoward Hinnant
38063e519524SHoward Hinnanttemplate<class _Tp>
3807906c872dSEvgeniy Stepanovinline
38083739fe79SHoward Hinnantshared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
38093e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
38103e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
38113e519524SHoward Hinnant{
3812527a7fdfSBruce Mitchener    __r.__ptr_ = nullptr;
3813527a7fdfSBruce Mitchener    __r.__cntrl_ = nullptr;
38143e519524SHoward Hinnant}
38153e519524SHoward Hinnant
38163e519524SHoward Hinnanttemplate<class _Tp>
38173e519524SHoward Hinnanttemplate<class _Yp>
3818906c872dSEvgeniy Stepanovinline
38193e519524SHoward Hinnantshared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
3820ce195fb2Szoecarver                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
38213739fe79SHoward Hinnant         _NOEXCEPT
38223e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
38233e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
38243e519524SHoward Hinnant{
3825527a7fdfSBruce Mitchener    __r.__ptr_ = nullptr;
3826527a7fdfSBruce Mitchener    __r.__cntrl_ = nullptr;
38273e519524SHoward Hinnant}
38283e519524SHoward Hinnant
3829e67179bcSMarshall Clow#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
38303e519524SHoward Hinnanttemplate<class _Tp>
383122747e62SLogan Chientemplate<class _Yp>
383222747e62SLogan Chienshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
383322747e62SLogan Chien                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
38343e519524SHoward Hinnant    : __ptr_(__r.get())
38353e519524SHoward Hinnant{
38363e519524SHoward Hinnant    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
38373e519524SHoward Hinnant    __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
383839005d30SEric Fiselier    __enable_weak_this(__r.get(), __r.get());
38393e519524SHoward Hinnant    __r.release();
38403e519524SHoward Hinnant}
3841e67179bcSMarshall Clow#endif
38423e519524SHoward Hinnant
38433e519524SHoward Hinnanttemplate<class _Tp>
384422747e62SLogan Chientemplate <class _Yp, class _Dp>
38453e519524SHoward Hinnantshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
384622747e62SLogan Chien                            typename enable_if
384722747e62SLogan Chien                            <
384822747e62SLogan Chien                                !is_lvalue_reference<_Dp>::value &&
384922747e62SLogan Chien                                !is_array<_Yp>::value &&
385022747e62SLogan Chien                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
385122747e62SLogan Chien                                __nat
385222747e62SLogan Chien                            >::type)
38533e519524SHoward Hinnant    : __ptr_(__r.get())
38543e519524SHoward Hinnant{
3855c34f847bSMarshall Clow#if _LIBCPP_STD_VER > 11
3856c34f847bSMarshall Clow    if (__ptr_ == nullptr)
3857c34f847bSMarshall Clow        __cntrl_ = nullptr;
3858c34f847bSMarshall Clow    else
3859c34f847bSMarshall Clow#endif
3860c34f847bSMarshall Clow    {
386172d0d603SErik Pilkington        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
386272d0d603SErik Pilkington        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
386372d0d603SErik Pilkington        __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
386439005d30SEric Fiselier        __enable_weak_this(__r.get(), __r.get());
3865c34f847bSMarshall Clow    }
38663e519524SHoward Hinnant    __r.release();
38673e519524SHoward Hinnant}
38683e519524SHoward Hinnant
38693e519524SHoward Hinnanttemplate<class _Tp>
387022747e62SLogan Chientemplate <class _Yp, class _Dp>
38713e519524SHoward Hinnantshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
387222747e62SLogan Chien                            typename enable_if
387322747e62SLogan Chien                            <
387422747e62SLogan Chien                                is_lvalue_reference<_Dp>::value &&
387522747e62SLogan Chien                                !is_array<_Yp>::value &&
387622747e62SLogan Chien                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
387722747e62SLogan Chien                                __nat
387822747e62SLogan Chien                            >::type)
38793e519524SHoward Hinnant    : __ptr_(__r.get())
38803e519524SHoward Hinnant{
3881c34f847bSMarshall Clow#if _LIBCPP_STD_VER > 11
3882c34f847bSMarshall Clow    if (__ptr_ == nullptr)
3883c34f847bSMarshall Clow        __cntrl_ = nullptr;
3884c34f847bSMarshall Clow    else
3885c34f847bSMarshall Clow#endif
3886c34f847bSMarshall Clow    {
388772d0d603SErik Pilkington        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
38883e519524SHoward Hinnant        typedef __shared_ptr_pointer<_Yp*,
38893e519524SHoward Hinnant                                     reference_wrapper<typename remove_reference<_Dp>::type>,
389072d0d603SErik Pilkington                                     _AllocT > _CntrlBlk;
3891092a57f5SLogan Smith        __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
389239005d30SEric Fiselier        __enable_weak_this(__r.get(), __r.get());
3893c34f847bSMarshall Clow    }
38943e519524SHoward Hinnant    __r.release();
38953e519524SHoward Hinnant}
38963e519524SHoward Hinnant
3897471bbb6eSZoe Carvertemplate<class _Tp>
38983e519524SHoward Hinnantshared_ptr<_Tp>::~shared_ptr()
38993e519524SHoward Hinnant{
39003e519524SHoward Hinnant    if (__cntrl_)
39013e519524SHoward Hinnant        __cntrl_->__release_shared();
39023e519524SHoward Hinnant}
39033e519524SHoward Hinnant
39043e519524SHoward Hinnanttemplate<class _Tp>
3905906c872dSEvgeniy Stepanovinline
39063e519524SHoward Hinnantshared_ptr<_Tp>&
39073739fe79SHoward Hinnantshared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
39083e519524SHoward Hinnant{
39093e519524SHoward Hinnant    shared_ptr(__r).swap(*this);
39103e519524SHoward Hinnant    return *this;
39113e519524SHoward Hinnant}
39123e519524SHoward Hinnant
39133e519524SHoward Hinnanttemplate<class _Tp>
39143e519524SHoward Hinnanttemplate<class _Yp>
3915906c872dSEvgeniy Stepanovinline
39168e25104bSHoward Hinnanttypename enable_if
39178e25104bSHoward Hinnant<
3918ce195fb2Szoecarver    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
39193e519524SHoward Hinnant    shared_ptr<_Tp>&
39208e25104bSHoward Hinnant>::type
39213739fe79SHoward Hinnantshared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
39223e519524SHoward Hinnant{
39233e519524SHoward Hinnant    shared_ptr(__r).swap(*this);
39243e519524SHoward Hinnant    return *this;
39253e519524SHoward Hinnant}
39263e519524SHoward Hinnant
39273e519524SHoward Hinnanttemplate<class _Tp>
3928906c872dSEvgeniy Stepanovinline
39293e519524SHoward Hinnantshared_ptr<_Tp>&
39303739fe79SHoward Hinnantshared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
39313e519524SHoward Hinnant{
3932ce48a113SHoward Hinnant    shared_ptr(_VSTD::move(__r)).swap(*this);
39333e519524SHoward Hinnant    return *this;
39343e519524SHoward Hinnant}
39353e519524SHoward Hinnant
39363e519524SHoward Hinnanttemplate<class _Tp>
39373e519524SHoward Hinnanttemplate<class _Yp>
3938906c872dSEvgeniy Stepanovinline
39398e25104bSHoward Hinnanttypename enable_if
39408e25104bSHoward Hinnant<
3941ce195fb2Szoecarver    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
39423e519524SHoward Hinnant    shared_ptr<_Tp>&
39438e25104bSHoward Hinnant>::type
39443e519524SHoward Hinnantshared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
39453e519524SHoward Hinnant{
3946ce48a113SHoward Hinnant    shared_ptr(_VSTD::move(__r)).swap(*this);
39473e519524SHoward Hinnant    return *this;
39483e519524SHoward Hinnant}
39493e519524SHoward Hinnant
3950e67179bcSMarshall Clow#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
39513e519524SHoward Hinnanttemplate<class _Tp>
39523e519524SHoward Hinnanttemplate<class _Yp>
3953906c872dSEvgeniy Stepanovinline
39548e25104bSHoward Hinnanttypename enable_if
39558e25104bSHoward Hinnant<
39568e25104bSHoward Hinnant    !is_array<_Yp>::value &&
3957dc83e779SMarshall Clow    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
395884f996fbSHoward Hinnant    shared_ptr<_Tp>
395984f996fbSHoward Hinnant>::type&
39603e519524SHoward Hinnantshared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
39613e519524SHoward Hinnant{
3962ce48a113SHoward Hinnant    shared_ptr(_VSTD::move(__r)).swap(*this);
39633e519524SHoward Hinnant    return *this;
39643e519524SHoward Hinnant}
3965e67179bcSMarshall Clow#endif
39663e519524SHoward Hinnant
39673e519524SHoward Hinnanttemplate<class _Tp>
39683e519524SHoward Hinnanttemplate <class _Yp, class _Dp>
3969906c872dSEvgeniy Stepanovinline
39708e25104bSHoward Hinnanttypename enable_if
39718e25104bSHoward Hinnant<
39728e25104bSHoward Hinnant    !is_array<_Yp>::value &&
3973dc83e779SMarshall Clow    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
3974dc83e779SMarshall Clow                   typename shared_ptr<_Tp>::element_type*>::value,
39753e519524SHoward Hinnant    shared_ptr<_Tp>&
39768e25104bSHoward Hinnant>::type
39773e519524SHoward Hinnantshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
39783e519524SHoward Hinnant{
3979ce48a113SHoward Hinnant    shared_ptr(_VSTD::move(__r)).swap(*this);
39803e519524SHoward Hinnant    return *this;
39813e519524SHoward Hinnant}
39823e519524SHoward Hinnant
39833e519524SHoward Hinnanttemplate<class _Tp>
3984906c872dSEvgeniy Stepanovinline
39853e519524SHoward Hinnantvoid
39863739fe79SHoward Hinnantshared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
39873e519524SHoward Hinnant{
3988ce48a113SHoward Hinnant    _VSTD::swap(__ptr_, __r.__ptr_);
3989ce48a113SHoward Hinnant    _VSTD::swap(__cntrl_, __r.__cntrl_);
39903e519524SHoward Hinnant}
39913e519524SHoward Hinnant
39923e519524SHoward Hinnanttemplate<class _Tp>
3993906c872dSEvgeniy Stepanovinline
39943e519524SHoward Hinnantvoid
39953739fe79SHoward Hinnantshared_ptr<_Tp>::reset() _NOEXCEPT
39963e519524SHoward Hinnant{
39973e519524SHoward Hinnant    shared_ptr().swap(*this);
39983e519524SHoward Hinnant}
39993e519524SHoward Hinnant
40003e519524SHoward Hinnanttemplate<class _Tp>
40013e519524SHoward Hinnanttemplate<class _Yp>
4002906c872dSEvgeniy Stepanovinline
40038e25104bSHoward Hinnanttypename enable_if
40048e25104bSHoward Hinnant<
4005ce195fb2Szoecarver    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
40063e519524SHoward Hinnant    void
40078e25104bSHoward Hinnant>::type
40083e519524SHoward Hinnantshared_ptr<_Tp>::reset(_Yp* __p)
40093e519524SHoward Hinnant{
40103e519524SHoward Hinnant    shared_ptr(__p).swap(*this);
40113e519524SHoward Hinnant}
40123e519524SHoward Hinnant
40133e519524SHoward Hinnanttemplate<class _Tp>
40143e519524SHoward Hinnanttemplate<class _Yp, class _Dp>
4015906c872dSEvgeniy Stepanovinline
40168e25104bSHoward Hinnanttypename enable_if
40178e25104bSHoward Hinnant<
4018ce195fb2Szoecarver    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
40193e519524SHoward Hinnant    void
40208e25104bSHoward Hinnant>::type
40213e519524SHoward Hinnantshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
40223e519524SHoward Hinnant{
40233e519524SHoward Hinnant    shared_ptr(__p, __d).swap(*this);
40243e519524SHoward Hinnant}
40253e519524SHoward Hinnant
40263e519524SHoward Hinnanttemplate<class _Tp>
40273e519524SHoward Hinnanttemplate<class _Yp, class _Dp, class _Alloc>
4028906c872dSEvgeniy Stepanovinline
40298e25104bSHoward Hinnanttypename enable_if
40308e25104bSHoward Hinnant<
4031ce195fb2Szoecarver    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
40323e519524SHoward Hinnant    void
40338e25104bSHoward Hinnant>::type
40343e519524SHoward Hinnantshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
40353e519524SHoward Hinnant{
40363e519524SHoward Hinnant    shared_ptr(__p, __d, __a).swap(*this);
40373e519524SHoward Hinnant}
40383e519524SHoward Hinnant
40393e519524SHoward Hinnanttemplate<class _Tp, class ..._Args>
40403e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
40418e25104bSHoward Hinnanttypename enable_if
40428e25104bSHoward Hinnant<
40438e25104bSHoward Hinnant    !is_array<_Tp>::value,
40443e519524SHoward Hinnant    shared_ptr<_Tp>
40458e25104bSHoward Hinnant>::type
40463e519524SHoward Hinnantmake_shared(_Args&& ...__args)
40473e519524SHoward Hinnant{
404840c47680SZoe Carver    static_assert(is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared");
404940c47680SZoe Carver    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
405040c47680SZoe Carver    typedef allocator<_CntrlBlk> _A2;
405140c47680SZoe Carver    typedef __allocator_destructor<_A2> _D2;
405240c47680SZoe Carver
405340c47680SZoe Carver    _A2 __a2;
405440c47680SZoe Carver    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
405540c47680SZoe Carver    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
405640c47680SZoe Carver
405702af1109SLouis Dionne    _Tp *__ptr = __hold2->__get_elem();
405840c47680SZoe Carver    return shared_ptr<_Tp>::__create_with_control_block(__ptr, __hold2.release());
40593e519524SHoward Hinnant}
40603e519524SHoward Hinnant
40613e519524SHoward Hinnanttemplate<class _Tp, class _Alloc, class ..._Args>
40623e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
40638e25104bSHoward Hinnanttypename enable_if
40648e25104bSHoward Hinnant<
40658e25104bSHoward Hinnant    !is_array<_Tp>::value,
40663e519524SHoward Hinnant    shared_ptr<_Tp>
40678e25104bSHoward Hinnant>::type
40683e519524SHoward Hinnantallocate_shared(const _Alloc& __a, _Args&& ...__args)
40693e519524SHoward Hinnant{
407028d38a25Szoecarver    static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared");
407128d38a25Szoecarver
407228d38a25Szoecarver    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
407328d38a25Szoecarver    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
407428d38a25Szoecarver    typedef __allocator_destructor<_A2> _D2;
407528d38a25Szoecarver
407628d38a25Szoecarver    _A2 __a2(__a);
407728d38a25Szoecarver    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
407828d38a25Szoecarver    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
407928d38a25Szoecarver        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
408028d38a25Szoecarver
408102af1109SLouis Dionne    typename shared_ptr<_Tp>::element_type *__p = __hold2->__get_elem();
408228d38a25Szoecarver    return shared_ptr<_Tp>::__create_with_control_block(__p, _VSTD::addressof(*__hold2.release()));
40833e519524SHoward Hinnant}
40843e519524SHoward Hinnant
40853e519524SHoward Hinnanttemplate<class _Tp, class _Up>
40863e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
40873e519524SHoward Hinnantbool
40883739fe79SHoward Hinnantoperator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
40893e519524SHoward Hinnant{
40903e519524SHoward Hinnant    return __x.get() == __y.get();
40913e519524SHoward Hinnant}
40923e519524SHoward Hinnant
40933e519524SHoward Hinnanttemplate<class _Tp, class _Up>
40943e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
40953e519524SHoward Hinnantbool
40963739fe79SHoward Hinnantoperator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
40973e519524SHoward Hinnant{
40983e519524SHoward Hinnant    return !(__x == __y);
40993e519524SHoward Hinnant}
41003e519524SHoward Hinnant
41013e519524SHoward Hinnanttemplate<class _Tp, class _Up>
41023e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
41033e519524SHoward Hinnantbool
41043739fe79SHoward Hinnantoperator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
41053e519524SHoward Hinnant{
4106c0db0729SMarshall Clow#if _LIBCPP_STD_VER <= 11
41076fe361c1SEric Fiselier    typedef typename common_type<_Tp*, _Up*>::type _Vp;
41086fe361c1SEric Fiselier    return less<_Vp>()(__x.get(), __y.get());
4109c0db0729SMarshall Clow#else
4110c0db0729SMarshall Clow    return less<>()(__x.get(), __y.get());
4111c0db0729SMarshall Clow#endif
4112c0db0729SMarshall Clow
411367f39647SHoward Hinnant}
411467f39647SHoward Hinnant
411567f39647SHoward Hinnanttemplate<class _Tp, class _Up>
411667f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
411767f39647SHoward Hinnantbool
411867f39647SHoward Hinnantoperator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
411967f39647SHoward Hinnant{
412067f39647SHoward Hinnant    return __y < __x;
412167f39647SHoward Hinnant}
412267f39647SHoward Hinnant
412367f39647SHoward Hinnanttemplate<class _Tp, class _Up>
412467f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
412567f39647SHoward Hinnantbool
412667f39647SHoward Hinnantoperator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
412767f39647SHoward Hinnant{
412867f39647SHoward Hinnant    return !(__y < __x);
412967f39647SHoward Hinnant}
413067f39647SHoward Hinnant
413167f39647SHoward Hinnanttemplate<class _Tp, class _Up>
413267f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
413367f39647SHoward Hinnantbool
413467f39647SHoward Hinnantoperator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
413567f39647SHoward Hinnant{
413667f39647SHoward Hinnant    return !(__x < __y);
413767f39647SHoward Hinnant}
413867f39647SHoward Hinnant
413967f39647SHoward Hinnanttemplate<class _Tp>
414067f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
414167f39647SHoward Hinnantbool
414267f39647SHoward Hinnantoperator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
414367f39647SHoward Hinnant{
414467f39647SHoward Hinnant    return !__x;
414567f39647SHoward Hinnant}
414667f39647SHoward Hinnant
414767f39647SHoward Hinnanttemplate<class _Tp>
414867f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
414967f39647SHoward Hinnantbool
415067f39647SHoward Hinnantoperator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
415167f39647SHoward Hinnant{
415267f39647SHoward Hinnant    return !__x;
415367f39647SHoward Hinnant}
415467f39647SHoward Hinnant
415567f39647SHoward Hinnanttemplate<class _Tp>
415667f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
415767f39647SHoward Hinnantbool
415867f39647SHoward Hinnantoperator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
415967f39647SHoward Hinnant{
416067f39647SHoward Hinnant    return static_cast<bool>(__x);
416167f39647SHoward Hinnant}
416267f39647SHoward Hinnant
416367f39647SHoward Hinnanttemplate<class _Tp>
416467f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
416567f39647SHoward Hinnantbool
416667f39647SHoward Hinnantoperator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
416767f39647SHoward Hinnant{
416867f39647SHoward Hinnant    return static_cast<bool>(__x);
416967f39647SHoward Hinnant}
417067f39647SHoward Hinnant
417167f39647SHoward Hinnanttemplate<class _Tp>
417267f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
417367f39647SHoward Hinnantbool
417467f39647SHoward Hinnantoperator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
417567f39647SHoward Hinnant{
417667f39647SHoward Hinnant    return less<_Tp*>()(__x.get(), nullptr);
417767f39647SHoward Hinnant}
417867f39647SHoward Hinnant
417967f39647SHoward Hinnanttemplate<class _Tp>
418067f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
418167f39647SHoward Hinnantbool
418267f39647SHoward Hinnantoperator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
418367f39647SHoward Hinnant{
418467f39647SHoward Hinnant    return less<_Tp*>()(nullptr, __x.get());
418567f39647SHoward Hinnant}
418667f39647SHoward Hinnant
418767f39647SHoward Hinnanttemplate<class _Tp>
418867f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
418967f39647SHoward Hinnantbool
419067f39647SHoward Hinnantoperator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
419167f39647SHoward Hinnant{
419267f39647SHoward Hinnant    return nullptr < __x;
419367f39647SHoward Hinnant}
419467f39647SHoward Hinnant
419567f39647SHoward Hinnanttemplate<class _Tp>
419667f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
419767f39647SHoward Hinnantbool
419867f39647SHoward Hinnantoperator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
419967f39647SHoward Hinnant{
420067f39647SHoward Hinnant    return __x < nullptr;
420167f39647SHoward Hinnant}
420267f39647SHoward Hinnant
420367f39647SHoward Hinnanttemplate<class _Tp>
420467f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
420567f39647SHoward Hinnantbool
420667f39647SHoward Hinnantoperator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
420767f39647SHoward Hinnant{
420867f39647SHoward Hinnant    return !(nullptr < __x);
420967f39647SHoward Hinnant}
421067f39647SHoward Hinnant
421167f39647SHoward Hinnanttemplate<class _Tp>
421267f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
421367f39647SHoward Hinnantbool
421467f39647SHoward Hinnantoperator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
421567f39647SHoward Hinnant{
421667f39647SHoward Hinnant    return !(__x < nullptr);
421767f39647SHoward Hinnant}
421867f39647SHoward Hinnant
421967f39647SHoward Hinnanttemplate<class _Tp>
422067f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
422167f39647SHoward Hinnantbool
422267f39647SHoward Hinnantoperator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
422367f39647SHoward Hinnant{
422467f39647SHoward Hinnant    return !(__x < nullptr);
422567f39647SHoward Hinnant}
422667f39647SHoward Hinnant
422767f39647SHoward Hinnanttemplate<class _Tp>
422867f39647SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
422967f39647SHoward Hinnantbool
423067f39647SHoward Hinnantoperator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
423167f39647SHoward Hinnant{
423267f39647SHoward Hinnant    return !(nullptr < __x);
42333e519524SHoward Hinnant}
42343e519524SHoward Hinnant
42353e519524SHoward Hinnanttemplate<class _Tp>
42363e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
42373e519524SHoward Hinnantvoid
42383739fe79SHoward Hinnantswap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
42393e519524SHoward Hinnant{
42403e519524SHoward Hinnant    __x.swap(__y);
42413e519524SHoward Hinnant}
42423e519524SHoward Hinnant
42433e519524SHoward Hinnanttemplate<class _Tp, class _Up>
42443e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
42453e519524SHoward Hinnantshared_ptr<_Tp>
42463739fe79SHoward Hinnantstatic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
42473e519524SHoward Hinnant{
4248ce195fb2Szoecarver    return shared_ptr<_Tp>(__r,
4249ce195fb2Szoecarver                           static_cast<
4250ce195fb2Szoecarver                               typename shared_ptr<_Tp>::element_type*>(__r.get()));
42513e519524SHoward Hinnant}
42523e519524SHoward Hinnant
42533e519524SHoward Hinnanttemplate<class _Tp, class _Up>
42543e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
42553e519524SHoward Hinnantshared_ptr<_Tp>
42563739fe79SHoward Hinnantdynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
42573e519524SHoward Hinnant{
4258ce195fb2Szoecarver    typedef typename shared_ptr<_Tp>::element_type _ET;
4259ce195fb2Szoecarver    _ET* __p = dynamic_cast<_ET*>(__r.get());
42603e519524SHoward Hinnant    return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
42613e519524SHoward Hinnant}
42623e519524SHoward Hinnant
42633e519524SHoward Hinnanttemplate<class _Tp, class _Up>
42643e519524SHoward Hinnantshared_ptr<_Tp>
42653739fe79SHoward Hinnantconst_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
42663e519524SHoward Hinnant{
4267ce195fb2Szoecarver    typedef typename shared_ptr<_Tp>::element_type _RTp;
42688e25104bSHoward Hinnant    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
42693e519524SHoward Hinnant}
42703e519524SHoward Hinnant
4271ce195fb2Szoecarvertemplate<class _Tp, class _Up>
4272ce195fb2Szoecarvershared_ptr<_Tp>
4273ce195fb2Szoecarverreinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
4274ce195fb2Szoecarver{
4275ce195fb2Szoecarver    return shared_ptr<_Tp>(__r,
4276ce195fb2Szoecarver                           reinterpret_cast<
4277ce195fb2Szoecarver                               typename shared_ptr<_Tp>::element_type*>(__r.get()));
4278ce195fb2Szoecarver}
4279ce195fb2Szoecarver
428054b409fdSHoward Hinnant#ifndef _LIBCPP_NO_RTTI
428154b409fdSHoward Hinnant
42823e519524SHoward Hinnanttemplate<class _Dp, class _Tp>
42833e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
42843e519524SHoward Hinnant_Dp*
42853739fe79SHoward Hinnantget_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
42863e519524SHoward Hinnant{
42873e519524SHoward Hinnant    return __p.template __get_deleter<_Dp>();
42883e519524SHoward Hinnant}
42893e519524SHoward Hinnant
4290b3371f6fSHoward Hinnant#endif  // _LIBCPP_NO_RTTI
429154b409fdSHoward Hinnant
42923e519524SHoward Hinnanttemplate<class _Tp>
429376887bc4SVy Nguyenclass _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
42943e519524SHoward Hinnant{
42953e519524SHoward Hinnantpublic:
42963e519524SHoward Hinnant    typedef _Tp element_type;
42973e519524SHoward Hinnantprivate:
42983e519524SHoward Hinnant    element_type*        __ptr_;
42993e519524SHoward Hinnant    __shared_weak_count* __cntrl_;
43003e519524SHoward Hinnant
43013e519524SHoward Hinnantpublic:
4302906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
4303c0937e8aSHoward Hinnant    _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
4304906c872dSEvgeniy Stepanov    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
43053739fe79SHoward Hinnant                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
43063739fe79SHoward Hinnant                        _NOEXCEPT;
4307906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
43083739fe79SHoward Hinnant    weak_ptr(weak_ptr const& __r) _NOEXCEPT;
4309906c872dSEvgeniy Stepanov    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
43103739fe79SHoward Hinnant                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
43113739fe79SHoward Hinnant                         _NOEXCEPT;
43123e519524SHoward Hinnant
4313906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
43148e25104bSHoward Hinnant    weak_ptr(weak_ptr&& __r) _NOEXCEPT;
4315906c872dSEvgeniy Stepanov    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
43168e25104bSHoward Hinnant                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
43178e25104bSHoward Hinnant                         _NOEXCEPT;
43183e519524SHoward Hinnant    ~weak_ptr();
43193e519524SHoward Hinnant
4320906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
43213739fe79SHoward Hinnant    weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
43228e25104bSHoward Hinnant    template<class _Yp>
43238e25104bSHoward Hinnant        typename enable_if
43248e25104bSHoward Hinnant        <
43258e25104bSHoward Hinnant            is_convertible<_Yp*, element_type*>::value,
43268e25104bSHoward Hinnant            weak_ptr&
43278e25104bSHoward Hinnant        >::type
4328906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
43298e25104bSHoward Hinnant        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
43308e25104bSHoward Hinnant
4331906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
43328e25104bSHoward Hinnant    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
43338e25104bSHoward Hinnant    template<class _Yp>
43348e25104bSHoward Hinnant        typename enable_if
43358e25104bSHoward Hinnant        <
43368e25104bSHoward Hinnant            is_convertible<_Yp*, element_type*>::value,
43378e25104bSHoward Hinnant            weak_ptr&
43388e25104bSHoward Hinnant        >::type
4339906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
43408e25104bSHoward Hinnant        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
43418e25104bSHoward Hinnant
43428e25104bSHoward Hinnant    template<class _Yp>
43438e25104bSHoward Hinnant        typename enable_if
43448e25104bSHoward Hinnant        <
43458e25104bSHoward Hinnant            is_convertible<_Yp*, element_type*>::value,
43468e25104bSHoward Hinnant            weak_ptr&
43478e25104bSHoward Hinnant        >::type
4348906c872dSEvgeniy Stepanov        _LIBCPP_INLINE_VISIBILITY
43498e25104bSHoward Hinnant        operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
43503e519524SHoward Hinnant
4351906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
43523739fe79SHoward Hinnant    void swap(weak_ptr& __r) _NOEXCEPT;
4353906c872dSEvgeniy Stepanov    _LIBCPP_INLINE_VISIBILITY
43543739fe79SHoward Hinnant    void reset() _NOEXCEPT;
43553e519524SHoward Hinnant
4356848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
43573739fe79SHoward Hinnant    long use_count() const _NOEXCEPT
43583739fe79SHoward Hinnant        {return __cntrl_ ? __cntrl_->use_count() : 0;}
4359848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
43603739fe79SHoward Hinnant    bool expired() const _NOEXCEPT
4361527a7fdfSBruce Mitchener        {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
43623739fe79SHoward Hinnant    shared_ptr<_Tp> lock() const _NOEXCEPT;
4363848a5374SHoward Hinnant    template<class _Up>
4364848a5374SHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
436536bc7178SMarshall Clow        bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
43663e519524SHoward Hinnant        {return __cntrl_ < __r.__cntrl_;}
4367848a5374SHoward Hinnant    template<class _Up>
4368848a5374SHoward Hinnant        _LIBCPP_INLINE_VISIBILITY
436936bc7178SMarshall Clow        bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
43703e519524SHoward Hinnant        {return __cntrl_ < __r.__cntrl_;}
43713e519524SHoward Hinnant
4372e2f2d1edSEric Fiselier    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
4373e2f2d1edSEric Fiselier    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
43743e519524SHoward Hinnant};
43753e519524SHoward Hinnant
437683564056SLogan Smith#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
437783564056SLogan Smithtemplate<class _Tp>
437883564056SLogan Smithweak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
437983564056SLogan Smith#endif
438083564056SLogan Smith
43813e519524SHoward Hinnanttemplate<class _Tp>
4382906c872dSEvgeniy Stepanovinline
4383c0937e8aSHoward Hinnant_LIBCPP_CONSTEXPR
43843739fe79SHoward Hinnantweak_ptr<_Tp>::weak_ptr() _NOEXCEPT
4385527a7fdfSBruce Mitchener    : __ptr_(nullptr),
4386527a7fdfSBruce Mitchener      __cntrl_(nullptr)
43873e519524SHoward Hinnant{
43883e519524SHoward Hinnant}
43893e519524SHoward Hinnant
43903e519524SHoward Hinnanttemplate<class _Tp>
4391906c872dSEvgeniy Stepanovinline
43923739fe79SHoward Hinnantweak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
43933e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
43943e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
43953e519524SHoward Hinnant{
43963e519524SHoward Hinnant    if (__cntrl_)
43973e519524SHoward Hinnant        __cntrl_->__add_weak();
43983e519524SHoward Hinnant}
43993e519524SHoward Hinnant
44003e519524SHoward Hinnanttemplate<class _Tp>
44013e519524SHoward Hinnanttemplate<class _Yp>
4402906c872dSEvgeniy Stepanovinline
44033e519524SHoward Hinnantweak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
44045eb6bdfaSHoward Hinnant                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
44053739fe79SHoward Hinnant                         _NOEXCEPT
44063e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
44073e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
44083e519524SHoward Hinnant{
44093e519524SHoward Hinnant    if (__cntrl_)
44103e519524SHoward Hinnant        __cntrl_->__add_weak();
44113e519524SHoward Hinnant}
44123e519524SHoward Hinnant
44133e519524SHoward Hinnanttemplate<class _Tp>
44143e519524SHoward Hinnanttemplate<class _Yp>
4415906c872dSEvgeniy Stepanovinline
44163e519524SHoward Hinnantweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
44175eb6bdfaSHoward Hinnant                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
44183739fe79SHoward Hinnant         _NOEXCEPT
44193e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
44203e519524SHoward Hinnant      __cntrl_(__r.__cntrl_)
44213e519524SHoward Hinnant{
44223e519524SHoward Hinnant    if (__cntrl_)
44233e519524SHoward Hinnant        __cntrl_->__add_weak();
44243e519524SHoward Hinnant}
44253e519524SHoward Hinnant
44268e25104bSHoward Hinnanttemplate<class _Tp>
4427906c872dSEvgeniy Stepanovinline
44288e25104bSHoward Hinnantweak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
44298e25104bSHoward Hinnant    : __ptr_(__r.__ptr_),
44308e25104bSHoward Hinnant      __cntrl_(__r.__cntrl_)
44318e25104bSHoward Hinnant{
4432527a7fdfSBruce Mitchener    __r.__ptr_ = nullptr;
4433527a7fdfSBruce Mitchener    __r.__cntrl_ = nullptr;
44348e25104bSHoward Hinnant}
44358e25104bSHoward Hinnant
44368e25104bSHoward Hinnanttemplate<class _Tp>
44378e25104bSHoward Hinnanttemplate<class _Yp>
4438906c872dSEvgeniy Stepanovinline
44398e25104bSHoward Hinnantweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
44408e25104bSHoward Hinnant                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
44418e25104bSHoward Hinnant         _NOEXCEPT
44428e25104bSHoward Hinnant    : __ptr_(__r.__ptr_),
44438e25104bSHoward Hinnant      __cntrl_(__r.__cntrl_)
44448e25104bSHoward Hinnant{
4445527a7fdfSBruce Mitchener    __r.__ptr_ = nullptr;
4446527a7fdfSBruce Mitchener    __r.__cntrl_ = nullptr;
44478e25104bSHoward Hinnant}
44488e25104bSHoward Hinnant
44493e519524SHoward Hinnanttemplate<class _Tp>
44503e519524SHoward Hinnantweak_ptr<_Tp>::~weak_ptr()
44513e519524SHoward Hinnant{
44523e519524SHoward Hinnant    if (__cntrl_)
44533e519524SHoward Hinnant        __cntrl_->__release_weak();
44543e519524SHoward Hinnant}
44553e519524SHoward Hinnant
44563e519524SHoward Hinnanttemplate<class _Tp>
4457906c872dSEvgeniy Stepanovinline
44583e519524SHoward Hinnantweak_ptr<_Tp>&
44593739fe79SHoward Hinnantweak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
44603e519524SHoward Hinnant{
44613e519524SHoward Hinnant    weak_ptr(__r).swap(*this);
44623e519524SHoward Hinnant    return *this;
44633e519524SHoward Hinnant}
44643e519524SHoward Hinnant
44653e519524SHoward Hinnanttemplate<class _Tp>
44663e519524SHoward Hinnanttemplate<class _Yp>
4467906c872dSEvgeniy Stepanovinline
44688e25104bSHoward Hinnanttypename enable_if
44698e25104bSHoward Hinnant<
44708e25104bSHoward Hinnant    is_convertible<_Yp*, _Tp*>::value,
44713e519524SHoward Hinnant    weak_ptr<_Tp>&
44728e25104bSHoward Hinnant>::type
44733739fe79SHoward Hinnantweak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
44743e519524SHoward Hinnant{
44753e519524SHoward Hinnant    weak_ptr(__r).swap(*this);
44763e519524SHoward Hinnant    return *this;
44773e519524SHoward Hinnant}
44783e519524SHoward Hinnant
44798e25104bSHoward Hinnanttemplate<class _Tp>
4480906c872dSEvgeniy Stepanovinline
44818e25104bSHoward Hinnantweak_ptr<_Tp>&
44828e25104bSHoward Hinnantweak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
44838e25104bSHoward Hinnant{
44848e25104bSHoward Hinnant    weak_ptr(_VSTD::move(__r)).swap(*this);
44858e25104bSHoward Hinnant    return *this;
44868e25104bSHoward Hinnant}
44878e25104bSHoward Hinnant
44883e519524SHoward Hinnanttemplate<class _Tp>
44893e519524SHoward Hinnanttemplate<class _Yp>
4490906c872dSEvgeniy Stepanovinline
44918e25104bSHoward Hinnanttypename enable_if
44928e25104bSHoward Hinnant<
44938e25104bSHoward Hinnant    is_convertible<_Yp*, _Tp*>::value,
44943e519524SHoward Hinnant    weak_ptr<_Tp>&
44958e25104bSHoward Hinnant>::type
44968e25104bSHoward Hinnantweak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
44978e25104bSHoward Hinnant{
44988e25104bSHoward Hinnant    weak_ptr(_VSTD::move(__r)).swap(*this);
44998e25104bSHoward Hinnant    return *this;
45008e25104bSHoward Hinnant}
45018e25104bSHoward Hinnant
45028e25104bSHoward Hinnanttemplate<class _Tp>
45038e25104bSHoward Hinnanttemplate<class _Yp>
4504906c872dSEvgeniy Stepanovinline
45058e25104bSHoward Hinnanttypename enable_if
45068e25104bSHoward Hinnant<
45078e25104bSHoward Hinnant    is_convertible<_Yp*, _Tp*>::value,
45088e25104bSHoward Hinnant    weak_ptr<_Tp>&
45098e25104bSHoward Hinnant>::type
45103739fe79SHoward Hinnantweak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
45113e519524SHoward Hinnant{
45123e519524SHoward Hinnant    weak_ptr(__r).swap(*this);
45133e519524SHoward Hinnant    return *this;
45143e519524SHoward Hinnant}
45153e519524SHoward Hinnant
45163e519524SHoward Hinnanttemplate<class _Tp>
4517906c872dSEvgeniy Stepanovinline
45183e519524SHoward Hinnantvoid
45193739fe79SHoward Hinnantweak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
45203e519524SHoward Hinnant{
4521ce48a113SHoward Hinnant    _VSTD::swap(__ptr_, __r.__ptr_);
4522ce48a113SHoward Hinnant    _VSTD::swap(__cntrl_, __r.__cntrl_);
45233e519524SHoward Hinnant}
45243e519524SHoward Hinnant
45253e519524SHoward Hinnanttemplate<class _Tp>
45263e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
45273e519524SHoward Hinnantvoid
45283739fe79SHoward Hinnantswap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
45293e519524SHoward Hinnant{
45303e519524SHoward Hinnant    __x.swap(__y);
45313e519524SHoward Hinnant}
45323e519524SHoward Hinnant
45333e519524SHoward Hinnanttemplate<class _Tp>
4534906c872dSEvgeniy Stepanovinline
45353e519524SHoward Hinnantvoid
45363739fe79SHoward Hinnantweak_ptr<_Tp>::reset() _NOEXCEPT
45373e519524SHoward Hinnant{
45383e519524SHoward Hinnant    weak_ptr().swap(*this);
45393e519524SHoward Hinnant}
45403e519524SHoward Hinnant
45413e519524SHoward Hinnanttemplate<class _Tp>
45423e519524SHoward Hinnanttemplate<class _Yp>
45433e519524SHoward Hinnantshared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
4544dc83e779SMarshall Clow                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
45453e519524SHoward Hinnant    : __ptr_(__r.__ptr_),
45463e519524SHoward Hinnant      __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
45473e519524SHoward Hinnant{
4548527a7fdfSBruce Mitchener    if (__cntrl_ == nullptr)
4549d437fa5cSMarshall Clow        __throw_bad_weak_ptr();
45503e519524SHoward Hinnant}
45513e519524SHoward Hinnant
45523e519524SHoward Hinnanttemplate<class _Tp>
45533e519524SHoward Hinnantshared_ptr<_Tp>
45543739fe79SHoward Hinnantweak_ptr<_Tp>::lock() const _NOEXCEPT
45553e519524SHoward Hinnant{
45563e519524SHoward Hinnant    shared_ptr<_Tp> __r;
45573e519524SHoward Hinnant    __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
45583e519524SHoward Hinnant    if (__r.__cntrl_)
45593e519524SHoward Hinnant        __r.__ptr_ = __ptr_;
45603e519524SHoward Hinnant    return __r;
45613e519524SHoward Hinnant}
45623e519524SHoward Hinnant
4563183c010cSMarshall Clow#if _LIBCPP_STD_VER > 14
4564183c010cSMarshall Clowtemplate <class _Tp = void> struct owner_less;
4565183c010cSMarshall Clow#else
45663e519524SHoward Hinnanttemplate <class _Tp> struct owner_less;
4567183c010cSMarshall Clow#endif
45683e519524SHoward Hinnant
45693e519524SHoward Hinnanttemplate <class _Tp>
4570e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
45713e519524SHoward Hinnant    : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
45723e519524SHoward Hinnant{
45733e519524SHoward Hinnant    typedef bool result_type;
4574848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
457536bc7178SMarshall Clow    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
45763e519524SHoward Hinnant        {return __x.owner_before(__y);}
4577848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
457836bc7178SMarshall Clow    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
45793e519524SHoward Hinnant        {return __x.owner_before(__y);}
4580848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
458136bc7178SMarshall Clow    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
45823e519524SHoward Hinnant        {return __x.owner_before(__y);}
45833e519524SHoward Hinnant};
45843e519524SHoward Hinnant
45853e519524SHoward Hinnanttemplate <class _Tp>
4586e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
45873e519524SHoward Hinnant    : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
45883e519524SHoward Hinnant{
45893e519524SHoward Hinnant    typedef bool result_type;
4590848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
459136bc7178SMarshall Clow    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
45923e519524SHoward Hinnant        {return __x.owner_before(__y);}
4593848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
459436bc7178SMarshall Clow    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
45953e519524SHoward Hinnant        {return __x.owner_before(__y);}
4596848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
459736bc7178SMarshall Clow    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
45983e519524SHoward Hinnant        {return __x.owner_before(__y);}
45993e519524SHoward Hinnant};
46003e519524SHoward Hinnant
4601183c010cSMarshall Clow#if _LIBCPP_STD_VER > 14
4602183c010cSMarshall Clowtemplate <>
4603e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS owner_less<void>
4604183c010cSMarshall Clow{
4605183c010cSMarshall Clow    template <class _Tp, class _Up>
4606183c010cSMarshall Clow    _LIBCPP_INLINE_VISIBILITY
460736bc7178SMarshall Clow    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
4608183c010cSMarshall Clow        {return __x.owner_before(__y);}
4609183c010cSMarshall Clow    template <class _Tp, class _Up>
4610183c010cSMarshall Clow    _LIBCPP_INLINE_VISIBILITY
461136bc7178SMarshall Clow    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
4612183c010cSMarshall Clow        {return __x.owner_before(__y);}
4613183c010cSMarshall Clow    template <class _Tp, class _Up>
4614183c010cSMarshall Clow    _LIBCPP_INLINE_VISIBILITY
461536bc7178SMarshall Clow    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
4616183c010cSMarshall Clow        {return __x.owner_before(__y);}
4617183c010cSMarshall Clow    template <class _Tp, class _Up>
4618183c010cSMarshall Clow    _LIBCPP_INLINE_VISIBILITY
461936bc7178SMarshall Clow    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
4620183c010cSMarshall Clow        {return __x.owner_before(__y);}
4621183c010cSMarshall Clow    typedef void is_transparent;
4622183c010cSMarshall Clow};
4623183c010cSMarshall Clow#endif
4624183c010cSMarshall Clow
46253e519524SHoward Hinnanttemplate<class _Tp>
4626e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS enable_shared_from_this
46273e519524SHoward Hinnant{
46283e519524SHoward Hinnant    mutable weak_ptr<_Tp> __weak_this_;
46293e519524SHoward Hinnantprotected:
4630c0937e8aSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
46313739fe79SHoward Hinnant    enable_shared_from_this() _NOEXCEPT {}
4632848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
46333739fe79SHoward Hinnant    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
4634848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
46353739fe79SHoward Hinnant    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
46363739fe79SHoward Hinnant        {return *this;}
4637848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
46383e519524SHoward Hinnant    ~enable_shared_from_this() {}
46393e519524SHoward Hinnantpublic:
4640848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
46413739fe79SHoward Hinnant    shared_ptr<_Tp> shared_from_this()
46423739fe79SHoward Hinnant        {return shared_ptr<_Tp>(__weak_this_);}
4643848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
46443739fe79SHoward Hinnant    shared_ptr<_Tp const> shared_from_this() const
46453739fe79SHoward Hinnant        {return shared_ptr<const _Tp>(__weak_this_);}
46463e519524SHoward Hinnant
464788f5bfdcSEric Fiselier#if _LIBCPP_STD_VER > 14
464888f5bfdcSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
464988f5bfdcSEric Fiselier    weak_ptr<_Tp> weak_from_this() _NOEXCEPT
465088f5bfdcSEric Fiselier       { return __weak_this_; }
465188f5bfdcSEric Fiselier
465288f5bfdcSEric Fiselier    _LIBCPP_INLINE_VISIBILITY
465388f5bfdcSEric Fiselier    weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
465488f5bfdcSEric Fiselier        { return __weak_this_; }
465588f5bfdcSEric Fiselier#endif // _LIBCPP_STD_VER > 14
465688f5bfdcSEric Fiselier
46573e519524SHoward Hinnant    template <class _Up> friend class shared_ptr;
46583e519524SHoward Hinnant};
46593e519524SHoward Hinnant
4660d1803b6cSHoward Hinnanttemplate <class _Tp>
4661e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
4662d1803b6cSHoward Hinnant{
4663d1803b6cSHoward Hinnant    typedef shared_ptr<_Tp>      argument_type;
4664d1803b6cSHoward Hinnant    typedef size_t               result_type;
4665f9127593SEric Fiselier
4666848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
46673739fe79SHoward Hinnant    result_type operator()(const argument_type& __ptr) const _NOEXCEPT
4668d1803b6cSHoward Hinnant    {
4669ce195fb2Szoecarver        return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
4670d1803b6cSHoward Hinnant    }
4671d1803b6cSHoward Hinnant};
4672d1803b6cSHoward Hinnant
4673c003db1fSHoward Hinnanttemplate<class _CharT, class _Traits, class _Yp>
4674e3163f5aSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4675e3163f5aSHoward Hinnantbasic_ostream<_CharT, _Traits>&
4676c003db1fSHoward Hinnantoperator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
4677e3163f5aSHoward Hinnant
4678df93bad1SEric Fiselier
4679df93bad1SEric Fiselier#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
4680d77851e8SHoward Hinnant
4681f0544c20SHoward Hinnantclass _LIBCPP_TYPE_VIS __sp_mut
4682d77851e8SHoward Hinnant{
468354d333a6SHoward Hinnant    void* __lx;
4684d77851e8SHoward Hinnantpublic:
4685d77851e8SHoward Hinnant    void lock() _NOEXCEPT;
4686d77851e8SHoward Hinnant    void unlock() _NOEXCEPT;
4687d77851e8SHoward Hinnant
4688d77851e8SHoward Hinnantprivate:
4689d77851e8SHoward Hinnant    _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
4690d77851e8SHoward Hinnant    __sp_mut(const __sp_mut&);
4691d77851e8SHoward Hinnant    __sp_mut& operator=(const __sp_mut&);
4692d77851e8SHoward Hinnant
46936e41256fSHoward Hinnant    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
4694d77851e8SHoward Hinnant};
4695d77851e8SHoward Hinnant
4696e9c66ad9SMehdi Amini_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4697e9c66ad9SMehdi Amini__sp_mut& __get_sp_mut(const void*);
4698d77851e8SHoward Hinnant
4699d77851e8SHoward Hinnanttemplate <class _Tp>
4700d77851e8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4701d77851e8SHoward Hinnantbool
4702d77851e8SHoward Hinnantatomic_is_lock_free(const shared_ptr<_Tp>*)
4703d77851e8SHoward Hinnant{
4704d77851e8SHoward Hinnant    return false;
4705d77851e8SHoward Hinnant}
4706d77851e8SHoward Hinnant
4707d77851e8SHoward Hinnanttemplate <class _Tp>
4708e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4709d77851e8SHoward Hinnantshared_ptr<_Tp>
4710d77851e8SHoward Hinnantatomic_load(const shared_ptr<_Tp>* __p)
4711d77851e8SHoward Hinnant{
4712d77851e8SHoward Hinnant    __sp_mut& __m = __get_sp_mut(__p);
4713d77851e8SHoward Hinnant    __m.lock();
4714d77851e8SHoward Hinnant    shared_ptr<_Tp> __q = *__p;
4715d77851e8SHoward Hinnant    __m.unlock();
4716d77851e8SHoward Hinnant    return __q;
4717d77851e8SHoward Hinnant}
4718d77851e8SHoward Hinnant
4719d77851e8SHoward Hinnanttemplate <class _Tp>
4720d77851e8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4721e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4722d77851e8SHoward Hinnantshared_ptr<_Tp>
4723d77851e8SHoward Hinnantatomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
4724d77851e8SHoward Hinnant{
4725d77851e8SHoward Hinnant    return atomic_load(__p);
4726d77851e8SHoward Hinnant}
4727d77851e8SHoward Hinnant
4728d77851e8SHoward Hinnanttemplate <class _Tp>
4729e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4730d77851e8SHoward Hinnantvoid
4731d77851e8SHoward Hinnantatomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
4732d77851e8SHoward Hinnant{
4733d77851e8SHoward Hinnant    __sp_mut& __m = __get_sp_mut(__p);
4734d77851e8SHoward Hinnant    __m.lock();
4735d77851e8SHoward Hinnant    __p->swap(__r);
4736d77851e8SHoward Hinnant    __m.unlock();
4737d77851e8SHoward Hinnant}
4738d77851e8SHoward Hinnant
4739d77851e8SHoward Hinnanttemplate <class _Tp>
4740d77851e8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4741e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4742d77851e8SHoward Hinnantvoid
4743d77851e8SHoward Hinnantatomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
4744d77851e8SHoward Hinnant{
4745d77851e8SHoward Hinnant    atomic_store(__p, __r);
4746d77851e8SHoward Hinnant}
4747d77851e8SHoward Hinnant
4748d77851e8SHoward Hinnanttemplate <class _Tp>
4749e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4750d77851e8SHoward Hinnantshared_ptr<_Tp>
4751d77851e8SHoward Hinnantatomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
4752d77851e8SHoward Hinnant{
4753d77851e8SHoward Hinnant    __sp_mut& __m = __get_sp_mut(__p);
4754d77851e8SHoward Hinnant    __m.lock();
4755d77851e8SHoward Hinnant    __p->swap(__r);
4756d77851e8SHoward Hinnant    __m.unlock();
4757d77851e8SHoward Hinnant    return __r;
4758d77851e8SHoward Hinnant}
4759d77851e8SHoward Hinnant
4760d77851e8SHoward Hinnanttemplate <class _Tp>
4761d77851e8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4762e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4763d77851e8SHoward Hinnantshared_ptr<_Tp>
4764d77851e8SHoward Hinnantatomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
4765d77851e8SHoward Hinnant{
4766d77851e8SHoward Hinnant    return atomic_exchange(__p, __r);
4767d77851e8SHoward Hinnant}
4768d77851e8SHoward Hinnant
4769d77851e8SHoward Hinnanttemplate <class _Tp>
4770e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4771d77851e8SHoward Hinnantbool
4772d77851e8SHoward Hinnantatomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
4773d77851e8SHoward Hinnant{
47743379baebSMarshall Clow    shared_ptr<_Tp> __temp;
4775d77851e8SHoward Hinnant    __sp_mut& __m = __get_sp_mut(__p);
4776d77851e8SHoward Hinnant    __m.lock();
4777d77851e8SHoward Hinnant    if (__p->__owner_equivalent(*__v))
4778d77851e8SHoward Hinnant    {
47793379baebSMarshall Clow        _VSTD::swap(__temp, *__p);
4780d77851e8SHoward Hinnant        *__p = __w;
4781d77851e8SHoward Hinnant        __m.unlock();
4782d77851e8SHoward Hinnant        return true;
4783d77851e8SHoward Hinnant    }
47843379baebSMarshall Clow    _VSTD::swap(__temp, *__v);
4785d77851e8SHoward Hinnant    *__v = *__p;
4786d77851e8SHoward Hinnant    __m.unlock();
4787d77851e8SHoward Hinnant    return false;
4788d77851e8SHoward Hinnant}
4789d77851e8SHoward Hinnant
4790d77851e8SHoward Hinnanttemplate <class _Tp>
4791d77851e8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4792e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4793d77851e8SHoward Hinnantbool
4794d77851e8SHoward Hinnantatomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
4795d77851e8SHoward Hinnant{
4796d77851e8SHoward Hinnant    return atomic_compare_exchange_strong(__p, __v, __w);
4797d77851e8SHoward Hinnant}
4798d77851e8SHoward Hinnant
4799d77851e8SHoward Hinnanttemplate <class _Tp>
4800d77851e8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4801e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4802d77851e8SHoward Hinnantbool
4803d77851e8SHoward Hinnantatomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
4804d77851e8SHoward Hinnant                                        shared_ptr<_Tp> __w, memory_order, memory_order)
4805d77851e8SHoward Hinnant{
4806d77851e8SHoward Hinnant    return atomic_compare_exchange_strong(__p, __v, __w);
4807d77851e8SHoward Hinnant}
4808d77851e8SHoward Hinnant
4809d77851e8SHoward Hinnanttemplate <class _Tp>
4810d77851e8SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
4811e9c66ad9SMehdi Amini_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
4812d77851e8SHoward Hinnantbool
4813d77851e8SHoward Hinnantatomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
4814d77851e8SHoward Hinnant                                      shared_ptr<_Tp> __w, memory_order, memory_order)
4815d77851e8SHoward Hinnant{
4816d77851e8SHoward Hinnant    return atomic_compare_exchange_weak(__p, __v, __w);
4817d77851e8SHoward Hinnant}
4818d77851e8SHoward Hinnant
4819df93bad1SEric Fiselier#endif  // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
4820d77851e8SHoward Hinnant
48213e519524SHoward Hinnant//enum class
4822528600c4SEric Fiselier#if defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
4823528600c4SEric Fiselier# ifndef _LIBCPP_CXX03_LANG
4824528600c4SEric Fiselierenum class pointer_safety : unsigned char {
4825528600c4SEric Fiselier  relaxed,
4826528600c4SEric Fiselier  preferred,
4827528600c4SEric Fiselier  strict
4828528600c4SEric Fiselier};
4829528600c4SEric Fiselier# endif
4830528600c4SEric Fiselier#else
48316e41256fSHoward Hinnantstruct _LIBCPP_TYPE_VIS pointer_safety
48323e519524SHoward Hinnant{
483354d333a6SHoward Hinnant    enum __lx
48343e519524SHoward Hinnant    {
48353e519524SHoward Hinnant        relaxed,
48363e519524SHoward Hinnant        preferred,
48373e519524SHoward Hinnant        strict
48383e519524SHoward Hinnant    };
48393e519524SHoward Hinnant
484054d333a6SHoward Hinnant    __lx __v_;
48413e519524SHoward Hinnant
4842848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
484376a01ea3SEric Fiselier    pointer_safety() : __v_() {}
484476a01ea3SEric Fiselier
484576a01ea3SEric Fiselier    _LIBCPP_INLINE_VISIBILITY
484654d333a6SHoward Hinnant    pointer_safety(__lx __v) : __v_(__v) {}
4847848a5374SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
48483e519524SHoward Hinnant    operator int() const {return __v_;}
48493e519524SHoward Hinnant};
4850528600c4SEric Fiselier#endif
4851528600c4SEric Fiselier
4852528600c4SEric Fiselier#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
4853c8e84ff2SLouis Dionne    defined(_LIBCPP_BUILDING_LIBRARY)
4854528600c4SEric Fiselier_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
4855528600c4SEric Fiselier#else
4856528600c4SEric Fiselier// This function is only offered in C++03 under ABI v1.
4857528600c4SEric Fiselier# if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) || !defined(_LIBCPP_CXX03_LANG)
4858528600c4SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
4859528600c4SEric Fiselierpointer_safety get_pointer_safety() _NOEXCEPT {
4860528600c4SEric Fiselier  return pointer_safety::relaxed;
4861528600c4SEric Fiselier}
4862528600c4SEric Fiselier# endif
4863528600c4SEric Fiselier#endif
4864528600c4SEric Fiselier
48653e519524SHoward Hinnant
4866f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
4867f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
4868f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
4869f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
48703e519524SHoward Hinnant
48713e519524SHoward Hinnanttemplate <class _Tp>
48723e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
48733e519524SHoward Hinnant_Tp*
48743e519524SHoward Hinnantundeclare_reachable(_Tp* __p)
48753e519524SHoward Hinnant{
48763e519524SHoward Hinnant    return static_cast<_Tp*>(__undeclare_reachable(__p));
48773e519524SHoward Hinnant}
48783e519524SHoward Hinnant
4879f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
48803e519524SHoward Hinnant
4881e3fbe143SMarshall Clow// --- Helper for container swap --
4882e3fbe143SMarshall Clowtemplate <typename _Alloc>
4883e3fbe143SMarshall Clow_LIBCPP_INLINE_VISIBILITY
4884e3fbe143SMarshall Clowvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
4885e3fbe143SMarshall Clow#if _LIBCPP_STD_VER >= 14
4886e3fbe143SMarshall Clow    _NOEXCEPT
4887e3fbe143SMarshall Clow#else
4888e3fbe143SMarshall Clow    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
4889e3fbe143SMarshall Clow#endif
4890e3fbe143SMarshall Clow{
4891e3fbe143SMarshall Clow    using _VSTD::swap;
4892e3fbe143SMarshall Clow    swap(__a1, __a2);
4893e3fbe143SMarshall Clow}
4894e3fbe143SMarshall Clow
4895e3fbe143SMarshall Clowtemplate <typename _Alloc>
489689dd1dd2SEric Fiselierinline _LIBCPP_INLINE_VISIBILITY
4897e3fbe143SMarshall Clowvoid __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}
4898e3fbe143SMarshall Clow
48996e965df6SArthur O'Dwyertemplate <typename _Alloc>
49006e965df6SArthur O'Dwyerinline _LIBCPP_INLINE_VISIBILITY
49016e965df6SArthur O'Dwyervoid __swap_allocator(_Alloc & __a1, _Alloc & __a2)
49026e965df6SArthur O'Dwyer#if _LIBCPP_STD_VER >= 14
49036e965df6SArthur O'Dwyer    _NOEXCEPT
49046e965df6SArthur O'Dwyer#else
49056e965df6SArthur O'Dwyer    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
49066e965df6SArthur O'Dwyer#endif
49076e965df6SArthur O'Dwyer{
49086e965df6SArthur O'Dwyer    _VSTD::__swap_allocator(__a1, __a2,
49096e965df6SArthur O'Dwyer      integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
49106e965df6SArthur O'Dwyer}
49116e965df6SArthur O'Dwyer
49121378a5aeSMarshall Clowtemplate <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
49131378a5aeSMarshall Clowstruct __noexcept_move_assign_container : public integral_constant<bool,
49141378a5aeSMarshall Clow    _Traits::propagate_on_container_move_assignment::value
49151378a5aeSMarshall Clow#if _LIBCPP_STD_VER > 14
49161378a5aeSMarshall Clow        || _Traits::is_always_equal::value
49171378a5aeSMarshall Clow#else
49181378a5aeSMarshall Clow        && is_nothrow_move_assignable<_Alloc>::value
49191378a5aeSMarshall Clow#endif
49201378a5aeSMarshall Clow    > {};
4921e3fbe143SMarshall Clow
4922dc3eb83dSMarshall Clow
4923dc3eb83dSMarshall Clowtemplate <class _Tp, class _Alloc>
4924dc3eb83dSMarshall Clowstruct __temp_value {
4925dc3eb83dSMarshall Clow    typedef allocator_traits<_Alloc> _Traits;
4926dc3eb83dSMarshall Clow
4927d108bf85SEric Fiselier    typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
4928dc3eb83dSMarshall Clow    _Alloc &__a;
4929dc3eb83dSMarshall Clow
4930dc3eb83dSMarshall Clow    _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
4931dc3eb83dSMarshall Clow    _Tp &   get() { return *__addr(); }
4932dc3eb83dSMarshall Clow
4933dc3eb83dSMarshall Clow    template<class... _Args>
4934f11c00d7SPeter Collingbourne    _LIBCPP_NO_CFI
4935f11c00d7SPeter Collingbourne    __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
4936f11c00d7SPeter Collingbourne      _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
4937f11c00d7SPeter Collingbourne                         _VSTD::forward<_Args>(__args)...);
4938f11c00d7SPeter Collingbourne    }
4939dc3eb83dSMarshall Clow
4940dc3eb83dSMarshall Clow    ~__temp_value() { _Traits::destroy(__a, __addr()); }
4941dc3eb83dSMarshall Clow    };
4942dc3eb83dSMarshall Clow
494376b26852SMarshall Clowtemplate<typename _Alloc, typename = void, typename = void>
49440e22bf8cSMarshall Clowstruct __is_allocator : false_type {};
49450e22bf8cSMarshall Clow
49460e22bf8cSMarshall Clowtemplate<typename _Alloc>
49470e22bf8cSMarshall Clowstruct __is_allocator<_Alloc,
494876b26852SMarshall Clow       typename __void_t<typename _Alloc::value_type>::type,
494976b26852SMarshall Clow       typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type
495076b26852SMarshall Clow     >
49510e22bf8cSMarshall Clow   : true_type {};
49520e22bf8cSMarshall Clow
4953d63dd874SEric Fiselier// __builtin_new_allocator -- A non-templated helper for allocating and
4954d63dd874SEric Fiselier// deallocating memory using __builtin_operator_new and
4955d63dd874SEric Fiselier// __builtin_operator_delete. It should be used in preference to
4956d63dd874SEric Fiselier// `std::allocator<T>` to avoid additional instantiations.
4957d63dd874SEric Fiselierstruct __builtin_new_allocator {
4958d63dd874SEric Fiselier  struct __builtin_new_deleter {
4959d63dd874SEric Fiselier    typedef void* pointer_type;
4960d63dd874SEric Fiselier
4961d63dd874SEric Fiselier    _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
4962d63dd874SEric Fiselier        : __size_(__size), __align_(__align) {}
4963d63dd874SEric Fiselier
4964d63dd874SEric Fiselier    void operator()(void* p) const _NOEXCEPT {
4965d586f92cSArthur O'Dwyer        _VSTD::__libcpp_deallocate(p, __size_, __align_);
4966d63dd874SEric Fiselier    }
4967d63dd874SEric Fiselier
4968d63dd874SEric Fiselier   private:
4969d63dd874SEric Fiselier    size_t __size_;
4970d63dd874SEric Fiselier    size_t __align_;
4971d63dd874SEric Fiselier  };
4972d63dd874SEric Fiselier
4973d63dd874SEric Fiselier  typedef unique_ptr<void, __builtin_new_deleter> __holder_t;
4974d63dd874SEric Fiselier
4975d63dd874SEric Fiselier  static __holder_t __allocate_bytes(size_t __s, size_t __align) {
4976d586f92cSArthur O'Dwyer      return __holder_t(_VSTD::__libcpp_allocate(__s, __align),
4977d63dd874SEric Fiselier                     __builtin_new_deleter(__s, __align));
4978d63dd874SEric Fiselier  }
4979d63dd874SEric Fiselier
4980d63dd874SEric Fiselier  static void __deallocate_bytes(void* __p, size_t __s,
4981d63dd874SEric Fiselier                                 size_t __align) _NOEXCEPT {
4982d586f92cSArthur O'Dwyer      _VSTD::__libcpp_deallocate(__p, __s, __align);
4983d63dd874SEric Fiselier  }
4984d63dd874SEric Fiselier
4985d63dd874SEric Fiselier  template <class _Tp>
4986d63dd874SEric Fiselier  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
4987d63dd874SEric Fiselier  static __holder_t __allocate_type(size_t __n) {
4988d63dd874SEric Fiselier      return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
4989d63dd874SEric Fiselier  }
4990d63dd874SEric Fiselier
4991d63dd874SEric Fiselier  template <class _Tp>
4992d63dd874SEric Fiselier  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
4993d63dd874SEric Fiselier  static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
4994d63dd874SEric Fiselier      __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
4995d63dd874SEric Fiselier  }
4996d63dd874SEric Fiselier};
4997d63dd874SEric Fiselier
4998d63dd874SEric Fiselier
49993e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
50003e519524SHoward Hinnant
5001a016efb1SEric Fiselier_LIBCPP_POP_MACROS
5002a016efb1SEric Fiselier
50030a06eb91SLouis Dionne#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
500495689243SLouis Dionne#   include <__pstl_memory>
50050a06eb91SLouis Dionne#endif
50060a06eb91SLouis Dionne
50073e519524SHoward Hinnant#endif  // _LIBCPP_MEMORY
5008