xref: /freebsd-12.1/contrib/libc++/include/memory (revision b5893f02)
17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===-------------------------- memory ------------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open
77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_MEMORY
127a984708SDavid Chisnall#define _LIBCPP_MEMORY
137a984708SDavid Chisnall
147a984708SDavid Chisnall/*
157a984708SDavid Chisnall    memory synopsis
167a984708SDavid Chisnall
177a984708SDavid Chisnallnamespace std
187a984708SDavid Chisnall{
197a984708SDavid Chisnall
207a984708SDavid Chisnallstruct allocator_arg_t { };
2130785c0eSDimitry Andricinline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
227a984708SDavid Chisnall
237a984708SDavid Chisnalltemplate <class T, class Alloc> struct uses_allocator;
247a984708SDavid Chisnall
257a984708SDavid Chisnalltemplate <class Ptr>
267a984708SDavid Chisnallstruct pointer_traits
277a984708SDavid Chisnall{
287a984708SDavid Chisnall    typedef Ptr pointer;
297a984708SDavid Chisnall    typedef <details> element_type;
307a984708SDavid Chisnall    typedef <details> difference_type;
317a984708SDavid Chisnall
327a984708SDavid Chisnall    template <class U> using rebind = <details>;
337a984708SDavid Chisnall
347a984708SDavid Chisnall    static pointer pointer_to(<details>);
357a984708SDavid Chisnall};
367a984708SDavid Chisnall
377a984708SDavid Chisnalltemplate <class T>
387a984708SDavid Chisnallstruct pointer_traits<T*>
397a984708SDavid Chisnall{
407a984708SDavid Chisnall    typedef T* pointer;
417a984708SDavid Chisnall    typedef T element_type;
427a984708SDavid Chisnall    typedef ptrdiff_t difference_type;
437a984708SDavid Chisnall
447a984708SDavid Chisnall    template <class U> using rebind = U*;
457a984708SDavid Chisnall
46*b5893f02SDimitry Andric    static pointer pointer_to(<details>) noexcept; // constexpr in C++20
477a984708SDavid Chisnall};
487a984708SDavid Chisnall
49b2c7081bSDimitry Andrictemplate <class T> constexpr T* to_address(T* p) noexcept; // C++20
50b2c7081bSDimitry Andrictemplate <class Ptr> auto to_address(const Ptr& p) noexcept; // C++20
51b2c7081bSDimitry Andric
527a984708SDavid Chisnalltemplate <class Alloc>
537a984708SDavid Chisnallstruct allocator_traits
547a984708SDavid Chisnall{
557a984708SDavid Chisnall    typedef Alloc                        allocator_type;
567a984708SDavid Chisnall    typedef typename allocator_type::value_type
577a984708SDavid Chisnall                                         value_type;
587a984708SDavid Chisnall
597a984708SDavid Chisnall    typedef Alloc::pointer | value_type* pointer;
607a984708SDavid Chisnall    typedef Alloc::const_pointer
617a984708SDavid Chisnall          | pointer_traits<pointer>::rebind<const value_type>
627a984708SDavid Chisnall                                         const_pointer;
637a984708SDavid Chisnall    typedef Alloc::void_pointer
647a984708SDavid Chisnall          | pointer_traits<pointer>::rebind<void>
657a984708SDavid Chisnall                                         void_pointer;
667a984708SDavid Chisnall    typedef Alloc::const_void_pointer
677a984708SDavid Chisnall          | pointer_traits<pointer>::rebind<const void>
687a984708SDavid Chisnall                                         const_void_pointer;
697a984708SDavid Chisnall    typedef Alloc::difference_type
707a984708SDavid Chisnall          | pointer_traits<pointer>::difference_type
717a984708SDavid Chisnall                                         difference_type;
727a984708SDavid Chisnall    typedef Alloc::size_type
737a984708SDavid Chisnall          | make_unsigned<difference_type>::type
747a984708SDavid Chisnall                                         size_type;
757a984708SDavid Chisnall    typedef Alloc::propagate_on_container_copy_assignment
767a984708SDavid Chisnall          | false_type                   propagate_on_container_copy_assignment;
777a984708SDavid Chisnall    typedef Alloc::propagate_on_container_move_assignment
787a984708SDavid Chisnall          | false_type                   propagate_on_container_move_assignment;
797a984708SDavid Chisnall    typedef Alloc::propagate_on_container_swap
807a984708SDavid Chisnall          | false_type                   propagate_on_container_swap;
81854fa44bSDimitry Andric    typedef Alloc::is_always_equal
82854fa44bSDimitry Andric          | is_empty                     is_always_equal;
837a984708SDavid Chisnall
847a984708SDavid Chisnall    template <class T> using rebind_alloc  = Alloc::rebind<U>::other | Alloc<T, Args...>;
857a984708SDavid Chisnall    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
867a984708SDavid Chisnall
87b2c7081bSDimitry Andric    static pointer allocate(allocator_type& a, size_type n);                          // [[nodiscard]] in C++20
88b2c7081bSDimitry Andric    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // [[nodiscard]] in C++20
897a984708SDavid Chisnall
907a984708SDavid Chisnall    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept;
917a984708SDavid Chisnall
927a984708SDavid Chisnall    template <class T, class... Args>
937a984708SDavid Chisnall        static void construct(allocator_type& a, T* p, Args&&... args);
947a984708SDavid Chisnall
957a984708SDavid Chisnall    template <class T>
967a984708SDavid Chisnall        static void destroy(allocator_type& a, T* p);
977a984708SDavid Chisnall
984f7ab58eSDimitry Andric    static size_type max_size(const allocator_type& a); // noexcept in C++14
997a984708SDavid Chisnall
1007a984708SDavid Chisnall    static allocator_type
1017a984708SDavid Chisnall        select_on_container_copy_construction(const allocator_type& a);
1027a984708SDavid Chisnall};
1037a984708SDavid Chisnall
1047a984708SDavid Chisnalltemplate <>
1057a984708SDavid Chisnallclass allocator<void>
1067a984708SDavid Chisnall{
1077a984708SDavid Chisnallpublic:
1087a984708SDavid Chisnall    typedef void*                                 pointer;
1097a984708SDavid Chisnall    typedef const void*                           const_pointer;
1107a984708SDavid Chisnall    typedef void                                  value_type;
1117a984708SDavid Chisnall
1127a984708SDavid Chisnall    template <class _Up> struct rebind {typedef allocator<_Up> other;};
1137a984708SDavid Chisnall};
1147a984708SDavid Chisnall
1157a984708SDavid Chisnalltemplate <class T>
1167a984708SDavid Chisnallclass allocator
1177a984708SDavid Chisnall{
1187a984708SDavid Chisnallpublic:
1197a984708SDavid Chisnall    typedef size_t                                size_type;
1207a984708SDavid Chisnall    typedef ptrdiff_t                             difference_type;
1217a984708SDavid Chisnall    typedef T*                                    pointer;
1227a984708SDavid Chisnall    typedef const T*                              const_pointer;
1237a984708SDavid Chisnall    typedef typename add_lvalue_reference<T>::type       reference;
1247a984708SDavid Chisnall    typedef typename add_lvalue_reference<const T>::type const_reference;
1257a984708SDavid Chisnall    typedef T                                     value_type;
1267a984708SDavid Chisnall
1277a984708SDavid Chisnall    template <class U> struct rebind {typedef allocator<U> other;};
1287a984708SDavid Chisnall
1294ba319b5SDimitry Andric    constexpr allocator() noexcept;                      // constexpr in C++20
1304ba319b5SDimitry Andric    constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
1314ba319b5SDimitry Andric    template <class U>
1324ba319b5SDimitry Andric      constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
1337a984708SDavid Chisnall    ~allocator();
1347a984708SDavid Chisnall    pointer address(reference x) const noexcept;
1357a984708SDavid Chisnall    const_pointer address(const_reference x) const noexcept;
1367a984708SDavid Chisnall    pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
1377a984708SDavid Chisnall    void deallocate(pointer p, size_type n) noexcept;
1387a984708SDavid Chisnall    size_type max_size() const noexcept;
1397a984708SDavid Chisnall    template<class U, class... Args>
1407a984708SDavid Chisnall        void construct(U* p, Args&&... args);
1417a984708SDavid Chisnall    template <class U>
1427a984708SDavid Chisnall        void destroy(U* p);
1437a984708SDavid Chisnall};
1447a984708SDavid Chisnall
1457a984708SDavid Chisnalltemplate <class T, class U>
1467a984708SDavid Chisnallbool operator==(const allocator<T>&, const allocator<U>&) noexcept;
1477a984708SDavid Chisnall
1487a984708SDavid Chisnalltemplate <class T, class U>
1497a984708SDavid Chisnallbool operator!=(const allocator<T>&, const allocator<U>&) noexcept;
1507a984708SDavid Chisnall
1517a984708SDavid Chisnalltemplate <class OutputIterator, class T>
1527a984708SDavid Chisnallclass raw_storage_iterator
1537a984708SDavid Chisnall    : public iterator<output_iterator_tag,
1547a984708SDavid Chisnall                      T,                               // purposefully not C++03
1557a984708SDavid Chisnall                      ptrdiff_t,                       // purposefully not C++03
1567a984708SDavid Chisnall                      T*,                              // purposefully not C++03
1577a984708SDavid Chisnall                      raw_storage_iterator&>           // purposefully not C++03
1587a984708SDavid Chisnall{
1597a984708SDavid Chisnallpublic:
1607a984708SDavid Chisnall    explicit raw_storage_iterator(OutputIterator x);
1617a984708SDavid Chisnall    raw_storage_iterator& operator*();
1627a984708SDavid Chisnall    raw_storage_iterator& operator=(const T& element);
1637a984708SDavid Chisnall    raw_storage_iterator& operator++();
1647a984708SDavid Chisnall    raw_storage_iterator  operator++(int);
1657a984708SDavid Chisnall};
1667a984708SDavid Chisnall
1677a984708SDavid Chisnalltemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
1687a984708SDavid Chisnalltemplate <class T> void               return_temporary_buffer(T* p) noexcept;
1697a984708SDavid Chisnall
1707a984708SDavid Chisnalltemplate <class T> T* addressof(T& r) noexcept;
171aed8d94eSDimitry Andrictemplate <class T> T* addressof(const T&& r) noexcept = delete;
1727a984708SDavid Chisnall
1737a984708SDavid Chisnalltemplate <class InputIterator, class ForwardIterator>
1747a984708SDavid ChisnallForwardIterator
1757a984708SDavid Chisnalluninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
1767a984708SDavid Chisnall
1777a984708SDavid Chisnalltemplate <class InputIterator, class Size, class ForwardIterator>
1787a984708SDavid ChisnallForwardIterator
1797a984708SDavid Chisnalluninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
1807a984708SDavid Chisnall
1817a984708SDavid Chisnalltemplate <class ForwardIterator, class T>
1827a984708SDavid Chisnallvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
1837a984708SDavid Chisnall
1847a984708SDavid Chisnalltemplate <class ForwardIterator, class Size, class T>
1857a984708SDavid ChisnallForwardIterator
1867a984708SDavid Chisnalluninitialized_fill_n(ForwardIterator first, Size n, const T& x);
1877a984708SDavid Chisnall
188aed8d94eSDimitry Andrictemplate <class T>
189aed8d94eSDimitry Andricvoid destroy_at(T* location);
190aed8d94eSDimitry Andric
191aed8d94eSDimitry Andrictemplate <class ForwardIterator>
192aed8d94eSDimitry Andric void destroy(ForwardIterator first, ForwardIterator last);
193aed8d94eSDimitry Andric
194aed8d94eSDimitry Andrictemplate <class ForwardIterator, class Size>
195aed8d94eSDimitry Andric ForwardIterator destroy_n(ForwardIterator first, Size n);
196aed8d94eSDimitry Andric
197aed8d94eSDimitry Andrictemplate <class InputIterator, class ForwardIterator>
198aed8d94eSDimitry Andric ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
199aed8d94eSDimitry Andric
200aed8d94eSDimitry Andrictemplate <class InputIterator, class Size, class ForwardIterator>
201aed8d94eSDimitry Andric pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
202aed8d94eSDimitry Andric
203aed8d94eSDimitry Andrictemplate <class ForwardIterator>
204aed8d94eSDimitry Andric void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
205aed8d94eSDimitry Andric
206aed8d94eSDimitry Andrictemplate <class ForwardIterator, class Size>
207aed8d94eSDimitry Andric ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
208aed8d94eSDimitry Andric
209aed8d94eSDimitry Andrictemplate <class ForwardIterator>
210aed8d94eSDimitry Andric void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
211aed8d94eSDimitry Andric
212aed8d94eSDimitry Andrictemplate <class ForwardIterator, class Size>
213aed8d94eSDimitry Andric ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
214aed8d94eSDimitry Andric
215*b5893f02SDimitry Andrictemplate <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17
2167a984708SDavid Chisnall
2177a984708SDavid Chisnalltemplate<class X>
218*b5893f02SDimitry Andricclass auto_ptr                                  // deprecated in C++11, removed in C++17
2197a984708SDavid Chisnall{
2207a984708SDavid Chisnallpublic:
2217a984708SDavid Chisnall    typedef X element_type;
2227a984708SDavid Chisnall
2237a984708SDavid Chisnall    explicit auto_ptr(X* p =0) throw();
2247a984708SDavid Chisnall    auto_ptr(auto_ptr&) throw();
2257a984708SDavid Chisnall    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
2267a984708SDavid Chisnall    auto_ptr& operator=(auto_ptr&) throw();
2277a984708SDavid Chisnall    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
2287a984708SDavid Chisnall    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
2297a984708SDavid Chisnall    ~auto_ptr() throw();
2307a984708SDavid Chisnall
2317a984708SDavid Chisnall    typename add_lvalue_reference<X>::type operator*() const throw();
2327a984708SDavid Chisnall    X* operator->() const throw();
2337a984708SDavid Chisnall    X* get() const throw();
2347a984708SDavid Chisnall    X* release() throw();
2357a984708SDavid Chisnall    void reset(X* p =0) throw();
2367a984708SDavid Chisnall
2377a984708SDavid Chisnall    auto_ptr(auto_ptr_ref<X>) throw();
2387a984708SDavid Chisnall    template<class Y> operator auto_ptr_ref<Y>() throw();
2397a984708SDavid Chisnall    template<class Y> operator auto_ptr<Y>() throw();
2407a984708SDavid Chisnall};
2417a984708SDavid Chisnall
2427a984708SDavid Chisnalltemplate <class T>
2437a984708SDavid Chisnallstruct default_delete
2447a984708SDavid Chisnall{
2457a984708SDavid Chisnall    constexpr default_delete() noexcept = default;
2467a984708SDavid Chisnall    template <class U> default_delete(const default_delete<U>&) noexcept;
2477a984708SDavid Chisnall
2487a984708SDavid Chisnall    void operator()(T*) const noexcept;
2497a984708SDavid Chisnall};
2507a984708SDavid Chisnall
2517a984708SDavid Chisnalltemplate <class T>
2527a984708SDavid Chisnallstruct default_delete<T[]>
2537a984708SDavid Chisnall{
2547a984708SDavid Chisnall    constexpr default_delete() noexcept = default;
2557a984708SDavid Chisnall    void operator()(T*) const noexcept;
2567a984708SDavid Chisnall    template <class U> void operator()(U*) const = delete;
2577a984708SDavid Chisnall};
2587a984708SDavid Chisnall
2597a984708SDavid Chisnalltemplate <class T, class D = default_delete<T>>
2607a984708SDavid Chisnallclass unique_ptr
2617a984708SDavid Chisnall{
2627a984708SDavid Chisnallpublic:
2637a984708SDavid Chisnall    typedef see below pointer;
2647a984708SDavid Chisnall    typedef T element_type;
2657a984708SDavid Chisnall    typedef D deleter_type;
2667a984708SDavid Chisnall
2677a984708SDavid Chisnall    // constructors
2687a984708SDavid Chisnall    constexpr unique_ptr() noexcept;
2697a984708SDavid Chisnall    explicit unique_ptr(pointer p) noexcept;
2707a984708SDavid Chisnall    unique_ptr(pointer p, see below d1) noexcept;
2717a984708SDavid Chisnall    unique_ptr(pointer p, see below d2) noexcept;
2727a984708SDavid Chisnall    unique_ptr(unique_ptr&& u) noexcept;
2737a984708SDavid Chisnall    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
2747a984708SDavid Chisnall    template <class U, class E>
2757a984708SDavid Chisnall        unique_ptr(unique_ptr<U, E>&& u) noexcept;
2767a984708SDavid Chisnall    template <class U>
277540d2a8bSDimitry Andric        unique_ptr(auto_ptr<U>&& u) noexcept;       // removed in C++17
2787a984708SDavid Chisnall
2797a984708SDavid Chisnall    // destructor
2807a984708SDavid Chisnall    ~unique_ptr();
2817a984708SDavid Chisnall
2827a984708SDavid Chisnall    // assignment
2837a984708SDavid Chisnall    unique_ptr& operator=(unique_ptr&& u) noexcept;
2847a984708SDavid Chisnall    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
2857a984708SDavid Chisnall    unique_ptr& operator=(nullptr_t) noexcept;
2867a984708SDavid Chisnall
2877a984708SDavid Chisnall    // observers
2887a984708SDavid Chisnall    typename add_lvalue_reference<T>::type operator*() const;
2897a984708SDavid Chisnall    pointer operator->() const noexcept;
2907a984708SDavid Chisnall    pointer get() const noexcept;
2917a984708SDavid Chisnall    deleter_type& get_deleter() noexcept;
2927a984708SDavid Chisnall    const deleter_type& get_deleter() const noexcept;
2937a984708SDavid Chisnall    explicit operator bool() const noexcept;
2947a984708SDavid Chisnall
2957a984708SDavid Chisnall    // modifiers
2967a984708SDavid Chisnall    pointer release() noexcept;
2977a984708SDavid Chisnall    void reset(pointer p = pointer()) noexcept;
2987a984708SDavid Chisnall    void swap(unique_ptr& u) noexcept;
2997a984708SDavid Chisnall};
3007a984708SDavid Chisnall
3017a984708SDavid Chisnalltemplate <class T, class D>
3027a984708SDavid Chisnallclass unique_ptr<T[], D>
3037a984708SDavid Chisnall{
3047a984708SDavid Chisnallpublic:
3057a984708SDavid Chisnall    typedef implementation-defined pointer;
3067a984708SDavid Chisnall    typedef T element_type;
3077a984708SDavid Chisnall    typedef D deleter_type;
3087a984708SDavid Chisnall
3097a984708SDavid Chisnall    // constructors
3107a984708SDavid Chisnall    constexpr unique_ptr() noexcept;
3117a984708SDavid Chisnall    explicit unique_ptr(pointer p) noexcept;
3127a984708SDavid Chisnall    unique_ptr(pointer p, see below d) noexcept;
3137a984708SDavid Chisnall    unique_ptr(pointer p, see below d) noexcept;
3147a984708SDavid Chisnall    unique_ptr(unique_ptr&& u) noexcept;
3157a984708SDavid Chisnall    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
3167a984708SDavid Chisnall
3177a984708SDavid Chisnall    // destructor
3187a984708SDavid Chisnall    ~unique_ptr();
3197a984708SDavid Chisnall
3207a984708SDavid Chisnall    // assignment
3217a984708SDavid Chisnall    unique_ptr& operator=(unique_ptr&& u) noexcept;
3227a984708SDavid Chisnall    unique_ptr& operator=(nullptr_t) noexcept;
3237a984708SDavid Chisnall
3247a984708SDavid Chisnall    // observers
3257a984708SDavid Chisnall    T& operator[](size_t i) const;
3267a984708SDavid Chisnall    pointer get() const noexcept;
3277a984708SDavid Chisnall    deleter_type& get_deleter() noexcept;
3287a984708SDavid Chisnall    const deleter_type& get_deleter() const noexcept;
3297a984708SDavid Chisnall    explicit operator bool() const noexcept;
3307a984708SDavid Chisnall
3317a984708SDavid Chisnall    // modifiers
3327a984708SDavid Chisnall    pointer release() noexcept;
3337a984708SDavid Chisnall    void reset(pointer p = pointer()) noexcept;
3347a984708SDavid Chisnall    void reset(nullptr_t) noexcept;
3357a984708SDavid Chisnall    template <class U> void reset(U) = delete;
3367a984708SDavid Chisnall    void swap(unique_ptr& u) noexcept;
3377a984708SDavid Chisnall};
3387a984708SDavid Chisnall
3397a984708SDavid Chisnalltemplate <class T, class D>
3407a984708SDavid Chisnall    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
3417a984708SDavid Chisnall
3427a984708SDavid Chisnalltemplate <class T1, class D1, class T2, class D2>
3437a984708SDavid Chisnall    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3447a984708SDavid Chisnalltemplate <class T1, class D1, class T2, class D2>
3457a984708SDavid Chisnall    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3467a984708SDavid Chisnalltemplate <class T1, class D1, class T2, class D2>
3477a984708SDavid Chisnall    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3487a984708SDavid Chisnalltemplate <class T1, class D1, class T2, class D2>
3497a984708SDavid Chisnall    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3507a984708SDavid Chisnalltemplate <class T1, class D1, class T2, class D2>
3517a984708SDavid Chisnall    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3527a984708SDavid Chisnalltemplate <class T1, class D1, class T2, class D2>
3537a984708SDavid Chisnall    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3547a984708SDavid Chisnall
3557a984708SDavid Chisnalltemplate <class T, class D>
3567a984708SDavid Chisnall    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3577a984708SDavid Chisnalltemplate <class T, class D>
3587a984708SDavid Chisnall    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3597a984708SDavid Chisnalltemplate <class T, class D>
3607a984708SDavid Chisnall    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3617a984708SDavid Chisnalltemplate <class T, class D>
3627a984708SDavid Chisnall    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3637a984708SDavid Chisnall
3647a984708SDavid Chisnalltemplate <class T, class D>
3657a984708SDavid Chisnall    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
3667a984708SDavid Chisnalltemplate <class T, class D>
3677a984708SDavid Chisnall    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
3687a984708SDavid Chisnalltemplate <class T, class D>
3697a984708SDavid Chisnall    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
3707a984708SDavid Chisnalltemplate <class T, class D>
3717a984708SDavid Chisnall    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
3727a984708SDavid Chisnalltemplate <class T, class D>
3737a984708SDavid Chisnall    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
3747a984708SDavid Chisnalltemplate <class T, class D>
3757a984708SDavid Chisnall    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
3767a984708SDavid Chisnalltemplate <class T, class D>
3777a984708SDavid Chisnall    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
3787a984708SDavid Chisnalltemplate <class T, class D>
3797a984708SDavid Chisnall    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
3807a984708SDavid Chisnall
3817a984708SDavid Chisnallclass bad_weak_ptr
3827a984708SDavid Chisnall    : public std::exception
3837a984708SDavid Chisnall{
3847a984708SDavid Chisnall    bad_weak_ptr() noexcept;
3857a984708SDavid Chisnall};
3867a984708SDavid Chisnall
3874bab9fd9SDavid Chisnalltemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
3884bab9fd9SDavid Chisnalltemplate<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
3894bab9fd9SDavid Chisnalltemplate<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
3904bab9fd9SDavid Chisnall
391b2c7081bSDimitry Andrictemplate<class E, class T, class Y, class D>
392b2c7081bSDimitry Andric    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
393b2c7081bSDimitry Andric
3947a984708SDavid Chisnalltemplate<class T>
3957a984708SDavid Chisnallclass shared_ptr
3967a984708SDavid Chisnall{
3977a984708SDavid Chisnallpublic:
3987a984708SDavid Chisnall    typedef T element_type;
3997c82a1ecSDimitry Andric    typedef weak_ptr<T> weak_type; // C++17
4007a984708SDavid Chisnall
4017a984708SDavid Chisnall    // constructors:
4027a984708SDavid Chisnall    constexpr shared_ptr() noexcept;
4037a984708SDavid Chisnall    template<class Y> explicit shared_ptr(Y* p);
4047a984708SDavid Chisnall    template<class Y, class D> shared_ptr(Y* p, D d);
4057a984708SDavid Chisnall    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
4067a984708SDavid Chisnall    template <class D> shared_ptr(nullptr_t p, D d);
4077a984708SDavid Chisnall    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
4087a984708SDavid Chisnall    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
4097a984708SDavid Chisnall    shared_ptr(const shared_ptr& r) noexcept;
4107a984708SDavid Chisnall    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
4117a984708SDavid Chisnall    shared_ptr(shared_ptr&& r) noexcept;
4127a984708SDavid Chisnall    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
4137a984708SDavid Chisnall    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
414540d2a8bSDimitry Andric    template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
4157a984708SDavid Chisnall    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
4167a984708SDavid Chisnall    shared_ptr(nullptr_t) : shared_ptr() { }
4177a984708SDavid Chisnall
4187a984708SDavid Chisnall    // destructor:
4197a984708SDavid Chisnall    ~shared_ptr();
4207a984708SDavid Chisnall
4217a984708SDavid Chisnall    // assignment:
4227a984708SDavid Chisnall    shared_ptr& operator=(const shared_ptr& r) noexcept;
4237a984708SDavid Chisnall    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
4247a984708SDavid Chisnall    shared_ptr& operator=(shared_ptr&& r) noexcept;
4257a984708SDavid Chisnall    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
426540d2a8bSDimitry Andric    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
4277a984708SDavid Chisnall    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
4287a984708SDavid Chisnall
4297a984708SDavid Chisnall    // modifiers:
4307a984708SDavid Chisnall    void swap(shared_ptr& r) noexcept;
4317a984708SDavid Chisnall    void reset() noexcept;
4327a984708SDavid Chisnall    template<class Y> void reset(Y* p);
4337a984708SDavid Chisnall    template<class Y, class D> void reset(Y* p, D d);
4347a984708SDavid Chisnall    template<class Y, class D, class A> void reset(Y* p, D d, A a);
4357a984708SDavid Chisnall
4367a984708SDavid Chisnall    // observers:
4377a984708SDavid Chisnall    T* get() const noexcept;
4387a984708SDavid Chisnall    T& operator*() const noexcept;
4397a984708SDavid Chisnall    T* operator->() const noexcept;
4407a984708SDavid Chisnall    long use_count() const noexcept;
4417a984708SDavid Chisnall    bool unique() const noexcept;
4427a984708SDavid Chisnall    explicit operator bool() const noexcept;
443540d2a8bSDimitry Andric    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
444540d2a8bSDimitry Andric    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
4457a984708SDavid Chisnall};
4467a984708SDavid Chisnall
4477a984708SDavid Chisnall// shared_ptr comparisons:
4487a984708SDavid Chisnalltemplate<class T, class U>
4497a984708SDavid Chisnall    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4507a984708SDavid Chisnalltemplate<class T, class U>
4517a984708SDavid Chisnall    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4527a984708SDavid Chisnalltemplate<class T, class U>
4537a984708SDavid Chisnall    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4547a984708SDavid Chisnalltemplate<class T, class U>
4557a984708SDavid Chisnall    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4567a984708SDavid Chisnalltemplate<class T, class U>
4577a984708SDavid Chisnall    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4587a984708SDavid Chisnalltemplate<class T, class U>
4597a984708SDavid Chisnall    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4607a984708SDavid Chisnall
4617a984708SDavid Chisnalltemplate <class T>
4627a984708SDavid Chisnall    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
4637a984708SDavid Chisnalltemplate <class T>
4647a984708SDavid Chisnall    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
4657a984708SDavid Chisnalltemplate <class T>
4667a984708SDavid Chisnall    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
4677a984708SDavid Chisnalltemplate <class T>
4687a984708SDavid Chisnall    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
4697a984708SDavid Chisnalltemplate <class T>
4707a984708SDavid Chisnall    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
4717a984708SDavid Chisnalltemplate <class T>
4727a984708SDavid Chisnallbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
4737a984708SDavid Chisnalltemplate <class T>
4747a984708SDavid Chisnall    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
4757a984708SDavid Chisnalltemplate <class T>
4767a984708SDavid Chisnall    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
4777a984708SDavid Chisnalltemplate <class T>
4787a984708SDavid Chisnall    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
4797a984708SDavid Chisnalltemplate <class T>
4807a984708SDavid Chisnall    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
4817a984708SDavid Chisnalltemplate <class T>
4827a984708SDavid Chisnall    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
4837a984708SDavid Chisnalltemplate <class T>
4847a984708SDavid Chisnall    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;
4857a984708SDavid Chisnall
4867a984708SDavid Chisnall// shared_ptr specialized algorithms:
4877a984708SDavid Chisnalltemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
4887a984708SDavid Chisnall
4897a984708SDavid Chisnall// shared_ptr casts:
4907a984708SDavid Chisnalltemplate<class T, class U>
4917a984708SDavid Chisnall    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
4927a984708SDavid Chisnalltemplate<class T, class U>
4937a984708SDavid Chisnall    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
4947a984708SDavid Chisnalltemplate<class T, class U>
4957a984708SDavid Chisnall    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
4967a984708SDavid Chisnall
4977a984708SDavid Chisnall// shared_ptr I/O:
4987a984708SDavid Chisnalltemplate<class E, class T, class Y>
4997a984708SDavid Chisnall    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
5007a984708SDavid Chisnall
5017a984708SDavid Chisnall// shared_ptr get_deleter:
5027a984708SDavid Chisnalltemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
5037a984708SDavid Chisnall
5047a984708SDavid Chisnalltemplate<class T, class... Args>
5057a984708SDavid Chisnall    shared_ptr<T> make_shared(Args&&... args);
5067a984708SDavid Chisnalltemplate<class T, class A, class... Args>
5077a984708SDavid Chisnall    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
5087a984708SDavid Chisnall
5097a984708SDavid Chisnalltemplate<class T>
5107a984708SDavid Chisnallclass weak_ptr
5117a984708SDavid Chisnall{
5127a984708SDavid Chisnallpublic:
5137a984708SDavid Chisnall    typedef T element_type;
5147a984708SDavid Chisnall
5157a984708SDavid Chisnall    // constructors
5167a984708SDavid Chisnall    constexpr weak_ptr() noexcept;
5177a984708SDavid Chisnall    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
5187a984708SDavid Chisnall    weak_ptr(weak_ptr const& r) noexcept;
5197a984708SDavid Chisnall    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
520d72607e9SDimitry Andric    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
521d72607e9SDimitry Andric    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
5227a984708SDavid Chisnall
5237a984708SDavid Chisnall    // destructor
5247a984708SDavid Chisnall    ~weak_ptr();
5257a984708SDavid Chisnall
5267a984708SDavid Chisnall    // assignment
5277a984708SDavid Chisnall    weak_ptr& operator=(weak_ptr const& r) noexcept;
5287a984708SDavid Chisnall    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
5297a984708SDavid Chisnall    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
530d72607e9SDimitry Andric    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
531d72607e9SDimitry Andric    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
5327a984708SDavid Chisnall
5337a984708SDavid Chisnall    // modifiers
5347a984708SDavid Chisnall    void swap(weak_ptr& r) noexcept;
5357a984708SDavid Chisnall    void reset() noexcept;
5367a984708SDavid Chisnall
5377a984708SDavid Chisnall    // observers
5387a984708SDavid Chisnall    long use_count() const noexcept;
5397a984708SDavid Chisnall    bool expired() const noexcept;
5407a984708SDavid Chisnall    shared_ptr<T> lock() const noexcept;
541540d2a8bSDimitry Andric    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
542540d2a8bSDimitry Andric    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
5437a984708SDavid Chisnall};
5447a984708SDavid Chisnall
5457a984708SDavid Chisnall// weak_ptr specialized algorithms:
5467a984708SDavid Chisnalltemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
5477a984708SDavid Chisnall
5487a984708SDavid Chisnall// class owner_less:
5497a984708SDavid Chisnalltemplate<class T> struct owner_less;
5507a984708SDavid Chisnall
5517a984708SDavid Chisnalltemplate<class T>
5527a984708SDavid Chisnallstruct owner_less<shared_ptr<T>>
5537a984708SDavid Chisnall    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
5547a984708SDavid Chisnall{
5557a984708SDavid Chisnall    typedef bool result_type;
556540d2a8bSDimitry Andric    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
557540d2a8bSDimitry Andric    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
558540d2a8bSDimitry Andric    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
5597a984708SDavid Chisnall};
5607a984708SDavid Chisnall
5617a984708SDavid Chisnalltemplate<class T>
5627a984708SDavid Chisnallstruct owner_less<weak_ptr<T>>
5637a984708SDavid Chisnall    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
5647a984708SDavid Chisnall{
5657a984708SDavid Chisnall    typedef bool result_type;
566540d2a8bSDimitry Andric    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
567540d2a8bSDimitry Andric    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
568540d2a8bSDimitry Andric    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
569540d2a8bSDimitry Andric};
570540d2a8bSDimitry Andric
571540d2a8bSDimitry Andrictemplate <>  // Added in C++14
572540d2a8bSDimitry Andricstruct owner_less<void>
573540d2a8bSDimitry Andric{
574540d2a8bSDimitry Andric    template <class _Tp, class _Up>
575540d2a8bSDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
576540d2a8bSDimitry Andric    template <class _Tp, class _Up>
577540d2a8bSDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
578540d2a8bSDimitry Andric    template <class _Tp, class _Up>
579540d2a8bSDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
580540d2a8bSDimitry Andric    template <class _Tp, class _Up>
581540d2a8bSDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
582540d2a8bSDimitry Andric
583540d2a8bSDimitry Andric    typedef void is_transparent;
5847a984708SDavid Chisnall};
5857a984708SDavid Chisnall
5867a984708SDavid Chisnalltemplate<class T>
5877a984708SDavid Chisnallclass enable_shared_from_this
5887a984708SDavid Chisnall{
5897a984708SDavid Chisnallprotected:
5907a984708SDavid Chisnall    constexpr enable_shared_from_this() noexcept;
5917a984708SDavid Chisnall    enable_shared_from_this(enable_shared_from_this const&) noexcept;
5927a984708SDavid Chisnall    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
5937a984708SDavid Chisnall    ~enable_shared_from_this();
5947a984708SDavid Chisnallpublic:
5957a984708SDavid Chisnall    shared_ptr<T> shared_from_this();
5967a984708SDavid Chisnall    shared_ptr<T const> shared_from_this() const;
5977a984708SDavid Chisnall};
5987a984708SDavid Chisnall
5997a984708SDavid Chisnalltemplate<class T>
6007a984708SDavid Chisnall    bool atomic_is_lock_free(const shared_ptr<T>* p);
6017a984708SDavid Chisnalltemplate<class T>
6027a984708SDavid Chisnall    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
6037a984708SDavid Chisnalltemplate<class T>
6047a984708SDavid Chisnall    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
6057a984708SDavid Chisnalltemplate<class T>
6067a984708SDavid Chisnall    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
6077a984708SDavid Chisnalltemplate<class T>
6087a984708SDavid Chisnall    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
6097a984708SDavid Chisnalltemplate<class T>
6107a984708SDavid Chisnall    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
6117a984708SDavid Chisnalltemplate<class T>
6127a984708SDavid Chisnall    shared_ptr<T>
6137a984708SDavid Chisnall    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
6147a984708SDavid Chisnalltemplate<class T>
6157a984708SDavid Chisnall    bool
6167a984708SDavid Chisnall    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
6177a984708SDavid Chisnalltemplate<class T>
6187a984708SDavid Chisnall    bool
6197a984708SDavid Chisnall    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
6207a984708SDavid Chisnalltemplate<class T>
6217a984708SDavid Chisnall    bool
6227a984708SDavid Chisnall    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
6237a984708SDavid Chisnall                                          shared_ptr<T> w, memory_order success,
6247a984708SDavid Chisnall                                          memory_order failure);
6257a984708SDavid Chisnalltemplate<class T>
6267a984708SDavid Chisnall    bool
6277a984708SDavid Chisnall    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
6287a984708SDavid Chisnall                                            shared_ptr<T> w, memory_order success,
6297a984708SDavid Chisnall                                            memory_order failure);
6307a984708SDavid Chisnall// Hash support
6317a984708SDavid Chisnalltemplate <class T> struct hash;
6327a984708SDavid Chisnalltemplate <class T, class D> struct hash<unique_ptr<T, D> >;
6337a984708SDavid Chisnalltemplate <class T> struct hash<shared_ptr<T> >;
6347a984708SDavid Chisnall
63530785c0eSDimitry Andrictemplate <class T, class Alloc>
63630785c0eSDimitry Andric  inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
63730785c0eSDimitry Andric
6387a984708SDavid Chisnall// Pointer safety
6397a984708SDavid Chisnallenum class pointer_safety { relaxed, preferred, strict };
6407a984708SDavid Chisnallvoid declare_reachable(void *p);
6417a984708SDavid Chisnalltemplate <class T> T *undeclare_reachable(T *p);
6427a984708SDavid Chisnallvoid declare_no_pointers(char *p, size_t n);
6437a984708SDavid Chisnallvoid undeclare_no_pointers(char *p, size_t n);
6447a984708SDavid Chisnallpointer_safety get_pointer_safety() noexcept;
6457a984708SDavid Chisnall
6467a984708SDavid Chisnallvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space);
6477a984708SDavid Chisnall
6487a984708SDavid Chisnall}  // std
6497a984708SDavid Chisnall
6507a984708SDavid Chisnall*/
6517a984708SDavid Chisnall
6527a984708SDavid Chisnall#include <__config>
6537a984708SDavid Chisnall#include <type_traits>
6547a984708SDavid Chisnall#include <typeinfo>
6557a984708SDavid Chisnall#include <cstddef>
6567a984708SDavid Chisnall#include <cstdint>
6577a984708SDavid Chisnall#include <new>
6587a984708SDavid Chisnall#include <utility>
6597a984708SDavid Chisnall#include <limits>
6607a984708SDavid Chisnall#include <iterator>
6617a984708SDavid Chisnall#include <__functional_base>
6627a984708SDavid Chisnall#include <iosfwd>
66394e3ee44SDavid Chisnall#include <tuple>
6647c82a1ecSDimitry Andric#include <stdexcept>
66594e3ee44SDavid Chisnall#include <cstring>
666540d2a8bSDimitry Andric#include <cassert>
6679729cf09SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
668936e9439SDimitry Andric#  include <atomic>
669936e9439SDimitry Andric#endif
670*b5893f02SDimitry Andric#include <version>
671936e9439SDimitry Andric
6727a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6737a984708SDavid Chisnall#pragma GCC system_header
6747a984708SDavid Chisnall#endif
6757a984708SDavid Chisnall
676f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS
677f9448bf3SDimitry Andric#include <__undef_macros>
678f9448bf3SDimitry Andric
679f9448bf3SDimitry Andric
6807a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
6817a984708SDavid Chisnall
682854fa44bSDimitry Andrictemplate <class _ValueType>
6834ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
684854fa44bSDimitry Andric_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
685854fa44bSDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS) && \
686854fa44bSDimitry Andric    defined(__ATOMIC_RELAXED) &&        \
687854fa44bSDimitry Andric    (__has_builtin(__atomic_load_n) || _GNUC_VER >= 407)
688854fa44bSDimitry Andric    return __atomic_load_n(__value, __ATOMIC_RELAXED);
689854fa44bSDimitry Andric#else
690854fa44bSDimitry Andric    return *__value;
691854fa44bSDimitry Andric#endif
692854fa44bSDimitry Andric}
693854fa44bSDimitry Andric
694aed8d94eSDimitry Andrictemplate <class _ValueType>
6954ba319b5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
696aed8d94eSDimitry Andric_ValueType __libcpp_acquire_load(_ValueType const* __value) {
697aed8d94eSDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS) && \
698aed8d94eSDimitry Andric    defined(__ATOMIC_ACQUIRE) &&        \
699aed8d94eSDimitry Andric    (__has_builtin(__atomic_load_n) || _GNUC_VER >= 407)
700aed8d94eSDimitry Andric    return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
701aed8d94eSDimitry Andric#else
702aed8d94eSDimitry Andric    return *__value;
703aed8d94eSDimitry Andric#endif
704aed8d94eSDimitry Andric}
705aed8d94eSDimitry Andric
706aed8d94eSDimitry Andric// addressof moved to <type_traits>
7077a984708SDavid Chisnall
7087a984708SDavid Chisnalltemplate <class _Tp> class allocator;
7097a984708SDavid Chisnall
7107a984708SDavid Chisnalltemplate <>
711aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<void>
7127a984708SDavid Chisnall{
7137a984708SDavid Chisnallpublic:
7147a984708SDavid Chisnall    typedef void*             pointer;
7157a984708SDavid Chisnall    typedef const void*       const_pointer;
7167a984708SDavid Chisnall    typedef void              value_type;
7177a984708SDavid Chisnall
7187a984708SDavid Chisnall    template <class _Up> struct rebind {typedef allocator<_Up> other;};
7197a984708SDavid Chisnall};
7207a984708SDavid Chisnall
72194e3ee44SDavid Chisnalltemplate <>
722aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<const void>
72394e3ee44SDavid Chisnall{
72494e3ee44SDavid Chisnallpublic:
72594e3ee44SDavid Chisnall    typedef const void*       pointer;
72694e3ee44SDavid Chisnall    typedef const void*       const_pointer;
72794e3ee44SDavid Chisnall    typedef const void        value_type;
72894e3ee44SDavid Chisnall
72994e3ee44SDavid Chisnall    template <class _Up> struct rebind {typedef allocator<_Up> other;};
73094e3ee44SDavid Chisnall};
73194e3ee44SDavid Chisnall
7327a984708SDavid Chisnall// pointer_traits
7337a984708SDavid Chisnall
73424d58133SDimitry Andrictemplate <class _Tp, class = void>
73524d58133SDimitry Andricstruct __has_element_type : false_type {};
73624d58133SDimitry Andric
7377a984708SDavid Chisnalltemplate <class _Tp>
73824d58133SDimitry Andricstruct __has_element_type<_Tp,
73924d58133SDimitry Andric              typename __void_t<typename _Tp::element_type>::type> : true_type {};
7407a984708SDavid Chisnall
7417a984708SDavid Chisnalltemplate <class _Ptr, bool = __has_element_type<_Ptr>::value>
7427a984708SDavid Chisnallstruct __pointer_traits_element_type;
7437a984708SDavid Chisnall
7447a984708SDavid Chisnalltemplate <class _Ptr>
7457a984708SDavid Chisnallstruct __pointer_traits_element_type<_Ptr, true>
7467a984708SDavid Chisnall{
7477a984708SDavid Chisnall    typedef typename _Ptr::element_type type;
7487a984708SDavid Chisnall};
7497a984708SDavid Chisnall
7507a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
7517a984708SDavid Chisnall
7527a984708SDavid Chisnalltemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>
7537a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>
7547a984708SDavid Chisnall{
7557a984708SDavid Chisnall    typedef typename _Sp<_Tp, _Args...>::element_type type;
7567a984708SDavid Chisnall};
7577a984708SDavid Chisnall
7587a984708SDavid Chisnalltemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>
7597a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>
7607a984708SDavid Chisnall{
7617a984708SDavid Chisnall    typedef _Tp type;
7627a984708SDavid Chisnall};
7637a984708SDavid Chisnall
7647a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
7657a984708SDavid Chisnall
7667a984708SDavid Chisnalltemplate <template <class> class _Sp, class _Tp>
7677a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp>, true>
7687a984708SDavid Chisnall{
7697a984708SDavid Chisnall    typedef typename _Sp<_Tp>::element_type type;
7707a984708SDavid Chisnall};
7717a984708SDavid Chisnall
7727a984708SDavid Chisnalltemplate <template <class> class _Sp, class _Tp>
7737a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp>, false>
7747a984708SDavid Chisnall{
7757a984708SDavid Chisnall    typedef _Tp type;
7767a984708SDavid Chisnall};
7777a984708SDavid Chisnall
7787a984708SDavid Chisnalltemplate <template <class, class> class _Sp, class _Tp, class _A0>
7797a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _A0>, true>
7807a984708SDavid Chisnall{
7817a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0>::element_type type;
7827a984708SDavid Chisnall};
7837a984708SDavid Chisnall
7847a984708SDavid Chisnalltemplate <template <class, class> class _Sp, class _Tp, class _A0>
7857a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _A0>, false>
7867a984708SDavid Chisnall{
7877a984708SDavid Chisnall    typedef _Tp type;
7887a984708SDavid Chisnall};
7897a984708SDavid Chisnall
7907a984708SDavid Chisnalltemplate <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>
7917a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, true>
7927a984708SDavid Chisnall{
7937a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0, _A1>::element_type type;
7947a984708SDavid Chisnall};
7957a984708SDavid Chisnall
7967a984708SDavid Chisnalltemplate <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>
7977a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, false>
7987a984708SDavid Chisnall{
7997a984708SDavid Chisnall    typedef _Tp type;
8007a984708SDavid Chisnall};
8017a984708SDavid Chisnall
8027a984708SDavid Chisnalltemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
8037a984708SDavid Chisnall                                                           class _A1, class _A2>
8047a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, true>
8057a984708SDavid Chisnall{
8067a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0, _A1, _A2>::element_type type;
8077a984708SDavid Chisnall};
8087a984708SDavid Chisnall
8097a984708SDavid Chisnalltemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
8107a984708SDavid Chisnall                                                           class _A1, class _A2>
8117a984708SDavid Chisnallstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, false>
8127a984708SDavid Chisnall{
8137a984708SDavid Chisnall    typedef _Tp type;
8147a984708SDavid Chisnall};
8157a984708SDavid Chisnall
8167a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
8177a984708SDavid Chisnall
81824d58133SDimitry Andrictemplate <class _Tp, class = void>
81924d58133SDimitry Andricstruct __has_difference_type : false_type {};
82024d58133SDimitry Andric
8217a984708SDavid Chisnalltemplate <class _Tp>
82224d58133SDimitry Andricstruct __has_difference_type<_Tp,
82324d58133SDimitry Andric            typename __void_t<typename _Tp::difference_type>::type> : true_type {};
8247a984708SDavid Chisnall
8257a984708SDavid Chisnalltemplate <class _Ptr, bool = __has_difference_type<_Ptr>::value>
8267a984708SDavid Chisnallstruct __pointer_traits_difference_type
8277a984708SDavid Chisnall{
8287a984708SDavid Chisnall    typedef ptrdiff_t type;
8297a984708SDavid Chisnall};
8307a984708SDavid Chisnall
8317a984708SDavid Chisnalltemplate <class _Ptr>
8327a984708SDavid Chisnallstruct __pointer_traits_difference_type<_Ptr, true>
8337a984708SDavid Chisnall{
8347a984708SDavid Chisnall    typedef typename _Ptr::difference_type type;
8357a984708SDavid Chisnall};
8367a984708SDavid Chisnall
8377a984708SDavid Chisnalltemplate <class _Tp, class _Up>
8387a984708SDavid Chisnallstruct __has_rebind
8397a984708SDavid Chisnall{
8407a984708SDavid Chisnallprivate:
8411e0896acSDavid Chisnall    struct __two {char __lx; char __lxx;};
8427a984708SDavid Chisnall    template <class _Xp> static __two __test(...);
8437a984708SDavid Chisnall    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
8447a984708SDavid Chisnallpublic:
8457a984708SDavid Chisnall    static const bool value = sizeof(__test<_Tp>(0)) == 1;
8467a984708SDavid Chisnall};
8477a984708SDavid Chisnall
8487a984708SDavid Chisnalltemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
8497a984708SDavid Chisnallstruct __pointer_traits_rebind
8507a984708SDavid Chisnall{
851aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8527a984708SDavid Chisnall    typedef typename _Tp::template rebind<_Up> type;
8537a984708SDavid Chisnall#else
8547a984708SDavid Chisnall    typedef typename _Tp::template rebind<_Up>::other type;
8557a984708SDavid Chisnall#endif
8567a984708SDavid Chisnall};
8577a984708SDavid Chisnall
8587a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
8597a984708SDavid Chisnall
8607a984708SDavid Chisnalltemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
8617a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>
8627a984708SDavid Chisnall{
863aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8647a984708SDavid Chisnall    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
8657a984708SDavid Chisnall#else
8667a984708SDavid Chisnall    typedef typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
8677a984708SDavid Chisnall#endif
8687a984708SDavid Chisnall};
8697a984708SDavid Chisnall
8707a984708SDavid Chisnalltemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
8717a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>
8727a984708SDavid Chisnall{
8737a984708SDavid Chisnall    typedef _Sp<_Up, _Args...> type;
8747a984708SDavid Chisnall};
8757a984708SDavid Chisnall
8767a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
8777a984708SDavid Chisnall
8787a984708SDavid Chisnalltemplate <template <class> class _Sp, class _Tp, class _Up>
8797a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp>, _Up, true>
8807a984708SDavid Chisnall{
881aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8827a984708SDavid Chisnall    typedef typename _Sp<_Tp>::template rebind<_Up> type;
8837a984708SDavid Chisnall#else
8847a984708SDavid Chisnall    typedef typename _Sp<_Tp>::template rebind<_Up>::other type;
8857a984708SDavid Chisnall#endif
8867a984708SDavid Chisnall};
8877a984708SDavid Chisnall
8887a984708SDavid Chisnalltemplate <template <class> class _Sp, class _Tp, class _Up>
8897a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp>, _Up, false>
8907a984708SDavid Chisnall{
8917a984708SDavid Chisnall    typedef _Sp<_Up> type;
8927a984708SDavid Chisnall};
8937a984708SDavid Chisnall
8947a984708SDavid Chisnalltemplate <template <class, class> class _Sp, class _Tp, class _A0, class _Up>
8957a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, true>
8967a984708SDavid Chisnall{
897aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8987a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0>::template rebind<_Up> type;
8997a984708SDavid Chisnall#else
9007a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0>::template rebind<_Up>::other type;
9017a984708SDavid Chisnall#endif
9027a984708SDavid Chisnall};
9037a984708SDavid Chisnall
9047a984708SDavid Chisnalltemplate <template <class, class> class _Sp, class _Tp, class _A0, class _Up>
9057a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, false>
9067a984708SDavid Chisnall{
9077a984708SDavid Chisnall    typedef _Sp<_Up, _A0> type;
9087a984708SDavid Chisnall};
9097a984708SDavid Chisnall
9107a984708SDavid Chisnalltemplate <template <class, class, class> class _Sp, class _Tp, class _A0,
9117a984708SDavid Chisnall                                         class _A1, class _Up>
9127a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, true>
9137a984708SDavid Chisnall{
914aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9157a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up> type;
9167a984708SDavid Chisnall#else
9177a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up>::other type;
9187a984708SDavid Chisnall#endif
9197a984708SDavid Chisnall};
9207a984708SDavid Chisnall
9217a984708SDavid Chisnalltemplate <template <class, class, class> class _Sp, class _Tp, class _A0,
9227a984708SDavid Chisnall                                         class _A1, class _Up>
9237a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, false>
9247a984708SDavid Chisnall{
9257a984708SDavid Chisnall    typedef _Sp<_Up, _A0, _A1> type;
9267a984708SDavid Chisnall};
9277a984708SDavid Chisnall
9287a984708SDavid Chisnalltemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
9297a984708SDavid Chisnall                                                class _A1, class _A2, class _Up>
9307a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, true>
9317a984708SDavid Chisnall{
932aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9337a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up> type;
9347a984708SDavid Chisnall#else
9357a984708SDavid Chisnall    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
9367a984708SDavid Chisnall#endif
9377a984708SDavid Chisnall};
9387a984708SDavid Chisnall
9397a984708SDavid Chisnalltemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
9407a984708SDavid Chisnall                                                class _A1, class _A2, class _Up>
9417a984708SDavid Chisnallstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, false>
9427a984708SDavid Chisnall{
9437a984708SDavid Chisnall    typedef _Sp<_Up, _A0, _A1, _A2> type;
9447a984708SDavid Chisnall};
9457a984708SDavid Chisnall
9467a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
9477a984708SDavid Chisnall
9487a984708SDavid Chisnalltemplate <class _Ptr>
949aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS pointer_traits
9507a984708SDavid Chisnall{
9517a984708SDavid Chisnall    typedef _Ptr                                                     pointer;
9527a984708SDavid Chisnall    typedef typename __pointer_traits_element_type<pointer>::type    element_type;
9537a984708SDavid Chisnall    typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
9547a984708SDavid Chisnall
955aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9567a984708SDavid Chisnall    template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
9577a984708SDavid Chisnall#else
9587a984708SDavid Chisnall    template <class _Up> struct rebind
9597a984708SDavid Chisnall        {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};
960aed8d94eSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
9617a984708SDavid Chisnall
9627a984708SDavid Chisnallprivate:
9637a984708SDavid Chisnall    struct __nat {};
9647a984708SDavid Chisnallpublic:
9657a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9667a984708SDavid Chisnall    static pointer pointer_to(typename conditional<is_void<element_type>::value,
9677a984708SDavid Chisnall                                           __nat, element_type>::type& __r)
9687a984708SDavid Chisnall        {return pointer::pointer_to(__r);}
9697a984708SDavid Chisnall};
9707a984708SDavid Chisnall
9717a984708SDavid Chisnalltemplate <class _Tp>
972aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
9737a984708SDavid Chisnall{
9747a984708SDavid Chisnall    typedef _Tp*      pointer;
9757a984708SDavid Chisnall    typedef _Tp       element_type;
9767a984708SDavid Chisnall    typedef ptrdiff_t difference_type;
9777a984708SDavid Chisnall
978aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9797a984708SDavid Chisnall    template <class _Up> using rebind = _Up*;
9807a984708SDavid Chisnall#else
9817a984708SDavid Chisnall    template <class _Up> struct rebind {typedef _Up* other;};
9827a984708SDavid Chisnall#endif
9837a984708SDavid Chisnall
9847a984708SDavid Chisnallprivate:
9857a984708SDavid Chisnall    struct __nat {};
9867a984708SDavid Chisnallpublic:
987*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9887a984708SDavid Chisnall    static pointer pointer_to(typename conditional<is_void<element_type>::value,
9897a984708SDavid Chisnall                                      __nat, element_type>::type& __r) _NOEXCEPT
9907a984708SDavid Chisnall        {return _VSTD::addressof(__r);}
9917a984708SDavid Chisnall};
9927a984708SDavid Chisnall
9939729cf09SDimitry Andrictemplate <class _From, class _To>
9949729cf09SDimitry Andricstruct __rebind_pointer {
995aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9969729cf09SDimitry Andric    typedef typename pointer_traits<_From>::template rebind<_To>        type;
9979729cf09SDimitry Andric#else
9989729cf09SDimitry Andric    typedef typename pointer_traits<_From>::template rebind<_To>::other type;
9999729cf09SDimitry Andric#endif
10009729cf09SDimitry Andric};
10019729cf09SDimitry Andric
10027a984708SDavid Chisnall// allocator_traits
10037a984708SDavid Chisnall
100424d58133SDimitry Andrictemplate <class _Tp, class = void>
100524d58133SDimitry Andricstruct __has_pointer_type : false_type {};
10067a984708SDavid Chisnall
10077a984708SDavid Chisnalltemplate <class _Tp>
100824d58133SDimitry Andricstruct __has_pointer_type<_Tp,
100924d58133SDimitry Andric          typename __void_t<typename _Tp::pointer>::type> : true_type {};
10107a984708SDavid Chisnall
10117a984708SDavid Chisnallnamespace __pointer_type_imp
10127a984708SDavid Chisnall{
10137a984708SDavid Chisnall
10147a984708SDavid Chisnalltemplate <class _Tp, class _Dp, bool = __has_pointer_type<_Dp>::value>
10157a984708SDavid Chisnallstruct __pointer_type
10167a984708SDavid Chisnall{
10177a984708SDavid Chisnall    typedef typename _Dp::pointer type;
10187a984708SDavid Chisnall};
10197a984708SDavid Chisnall
10207a984708SDavid Chisnalltemplate <class _Tp, class _Dp>
10217a984708SDavid Chisnallstruct __pointer_type<_Tp, _Dp, false>
10227a984708SDavid Chisnall{
10237a984708SDavid Chisnall    typedef _Tp* type;
10247a984708SDavid Chisnall};
10257a984708SDavid Chisnall
10267a984708SDavid Chisnall}  // __pointer_type_imp
10277a984708SDavid Chisnall
10287a984708SDavid Chisnalltemplate <class _Tp, class _Dp>
10297a984708SDavid Chisnallstruct __pointer_type
10307a984708SDavid Chisnall{
10317a984708SDavid Chisnall    typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
10327a984708SDavid Chisnall};
10337a984708SDavid Chisnall
103424d58133SDimitry Andrictemplate <class _Tp, class = void>
103524d58133SDimitry Andricstruct __has_const_pointer : false_type {};
103624d58133SDimitry Andric
10377a984708SDavid Chisnalltemplate <class _Tp>
103824d58133SDimitry Andricstruct __has_const_pointer<_Tp,
103924d58133SDimitry Andric            typename __void_t<typename _Tp::const_pointer>::type> : true_type {};
10407a984708SDavid Chisnall
10417a984708SDavid Chisnalltemplate <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>
10427a984708SDavid Chisnallstruct __const_pointer
10437a984708SDavid Chisnall{
10447a984708SDavid Chisnall    typedef typename _Alloc::const_pointer type;
10457a984708SDavid Chisnall};
10467a984708SDavid Chisnall
10477a984708SDavid Chisnalltemplate <class _Tp, class _Ptr, class _Alloc>
10487a984708SDavid Chisnallstruct __const_pointer<_Tp, _Ptr, _Alloc, false>
10497a984708SDavid Chisnall{
1050aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10517a984708SDavid Chisnall    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp> type;
10527a984708SDavid Chisnall#else
10537a984708SDavid Chisnall    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp>::other type;
10547a984708SDavid Chisnall#endif
10557a984708SDavid Chisnall};
10567a984708SDavid Chisnall
105724d58133SDimitry Andrictemplate <class _Tp, class = void>
105824d58133SDimitry Andricstruct __has_void_pointer : false_type {};
105924d58133SDimitry Andric
10607a984708SDavid Chisnalltemplate <class _Tp>
106124d58133SDimitry Andricstruct __has_void_pointer<_Tp,
106224d58133SDimitry Andric               typename __void_t<typename _Tp::void_pointer>::type> : true_type {};
10637a984708SDavid Chisnall
10647a984708SDavid Chisnalltemplate <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>
10657a984708SDavid Chisnallstruct __void_pointer
10667a984708SDavid Chisnall{
10677a984708SDavid Chisnall    typedef typename _Alloc::void_pointer type;
10687a984708SDavid Chisnall};
10697a984708SDavid Chisnall
10707a984708SDavid Chisnalltemplate <class _Ptr, class _Alloc>
10717a984708SDavid Chisnallstruct __void_pointer<_Ptr, _Alloc, false>
10727a984708SDavid Chisnall{
1073aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10747a984708SDavid Chisnall    typedef typename pointer_traits<_Ptr>::template rebind<void> type;
10757a984708SDavid Chisnall#else
10767a984708SDavid Chisnall    typedef typename pointer_traits<_Ptr>::template rebind<void>::other type;
10777a984708SDavid Chisnall#endif
10787a984708SDavid Chisnall};
10797a984708SDavid Chisnall
108024d58133SDimitry Andrictemplate <class _Tp, class = void>
108124d58133SDimitry Andricstruct __has_const_void_pointer : false_type {};
108224d58133SDimitry Andric
10837a984708SDavid Chisnalltemplate <class _Tp>
108424d58133SDimitry Andricstruct __has_const_void_pointer<_Tp,
108524d58133SDimitry Andric            typename __void_t<typename _Tp::const_void_pointer>::type> : true_type {};
10867a984708SDavid Chisnall
10877a984708SDavid Chisnalltemplate <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>
10887a984708SDavid Chisnallstruct __const_void_pointer
10897a984708SDavid Chisnall{
10907a984708SDavid Chisnall    typedef typename _Alloc::const_void_pointer type;
10917a984708SDavid Chisnall};
10927a984708SDavid Chisnall
10937a984708SDavid Chisnalltemplate <class _Ptr, class _Alloc>
10947a984708SDavid Chisnallstruct __const_void_pointer<_Ptr, _Alloc, false>
10957a984708SDavid Chisnall{
1096aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10977a984708SDavid Chisnall    typedef typename pointer_traits<_Ptr>::template rebind<const void> type;
10987a984708SDavid Chisnall#else
10997a984708SDavid Chisnall    typedef typename pointer_traits<_Ptr>::template rebind<const void>::other type;
11007a984708SDavid Chisnall#endif
11017a984708SDavid Chisnall};
11027a984708SDavid Chisnall
110394e3ee44SDavid Chisnalltemplate <class _Tp>
1104b2c7081bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
110594e3ee44SDavid Chisnall_Tp*
110694e3ee44SDavid Chisnall__to_raw_pointer(_Tp* __p) _NOEXCEPT
11077a984708SDavid Chisnall{
11087a984708SDavid Chisnall    return __p;
11097a984708SDavid Chisnall}
11107a984708SDavid Chisnall
1111b2c7081bSDimitry Andric#if _LIBCPP_STD_VER <= 17
11127a984708SDavid Chisnalltemplate <class _Pointer>
11137a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
11147a984708SDavid Chisnalltypename pointer_traits<_Pointer>::element_type*
11157a984708SDavid Chisnall__to_raw_pointer(_Pointer __p) _NOEXCEPT
11167a984708SDavid Chisnall{
11177a984708SDavid Chisnall    return _VSTD::__to_raw_pointer(__p.operator->());
11187a984708SDavid Chisnall}
1119b2c7081bSDimitry Andric#else
1120b2c7081bSDimitry Andrictemplate <class _Pointer>
1121b2c7081bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1122b2c7081bSDimitry Andricauto
1123b2c7081bSDimitry Andric__to_raw_pointer(const _Pointer& __p) _NOEXCEPT
1124b2c7081bSDimitry Andric-> decltype(pointer_traits<_Pointer>::to_address(__p))
1125b2c7081bSDimitry Andric{
1126b2c7081bSDimitry Andric    return pointer_traits<_Pointer>::to_address(__p);
1127b2c7081bSDimitry Andric}
1128b2c7081bSDimitry Andric
1129b2c7081bSDimitry Andrictemplate <class _Pointer, class... _None>
1130b2c7081bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1131b2c7081bSDimitry Andricauto
1132b2c7081bSDimitry Andric__to_raw_pointer(const _Pointer& __p, _None...) _NOEXCEPT
1133b2c7081bSDimitry Andric{
1134b2c7081bSDimitry Andric    return _VSTD::__to_raw_pointer(__p.operator->());
1135b2c7081bSDimitry Andric}
1136b2c7081bSDimitry Andric
1137b2c7081bSDimitry Andrictemplate <class _Tp>
1138b2c7081bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY constexpr
1139b2c7081bSDimitry Andric_Tp*
1140b2c7081bSDimitry Andricto_address(_Tp* __p) _NOEXCEPT
1141b2c7081bSDimitry Andric{
1142b2c7081bSDimitry Andric    static_assert(!is_function_v<_Tp>, "_Tp is a function type");
1143b2c7081bSDimitry Andric    return __p;
1144b2c7081bSDimitry Andric}
1145b2c7081bSDimitry Andric
1146b2c7081bSDimitry Andrictemplate <class _Pointer>
1147b2c7081bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
1148b2c7081bSDimitry Andricauto
1149b2c7081bSDimitry Andricto_address(const _Pointer& __p) _NOEXCEPT
1150b2c7081bSDimitry Andric{
1151b2c7081bSDimitry Andric    return _VSTD::__to_raw_pointer(__p);
1152b2c7081bSDimitry Andric}
1153b2c7081bSDimitry Andric#endif
11547a984708SDavid Chisnall
115524d58133SDimitry Andrictemplate <class _Tp, class = void>
115624d58133SDimitry Andricstruct __has_size_type : false_type {};
115724d58133SDimitry Andric
11587a984708SDavid Chisnalltemplate <class _Tp>
115924d58133SDimitry Andricstruct __has_size_type<_Tp,
116024d58133SDimitry Andric               typename __void_t<typename _Tp::size_type>::type> : true_type {};
11617a984708SDavid Chisnall
11627a984708SDavid Chisnalltemplate <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
11637a984708SDavid Chisnallstruct __size_type
11647a984708SDavid Chisnall{
11657a984708SDavid Chisnall    typedef typename make_unsigned<_DiffType>::type type;
11667a984708SDavid Chisnall};
11677a984708SDavid Chisnall
11687a984708SDavid Chisnalltemplate <class _Alloc, class _DiffType>
11697a984708SDavid Chisnallstruct __size_type<_Alloc, _DiffType, true>
11707a984708SDavid Chisnall{
11717a984708SDavid Chisnall    typedef typename _Alloc::size_type type;
11727a984708SDavid Chisnall};
11737a984708SDavid Chisnall
117424d58133SDimitry Andrictemplate <class _Tp, class = void>
117524d58133SDimitry Andricstruct __has_propagate_on_container_copy_assignment : false_type {};
117624d58133SDimitry Andric
11777a984708SDavid Chisnalltemplate <class _Tp>
117824d58133SDimitry Andricstruct __has_propagate_on_container_copy_assignment<_Tp,
117924d58133SDimitry Andric    typename __void_t<typename _Tp::propagate_on_container_copy_assignment>::type>
118024d58133SDimitry Andric        : true_type {};
11817a984708SDavid Chisnall
11827a984708SDavid Chisnalltemplate <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
11837a984708SDavid Chisnallstruct __propagate_on_container_copy_assignment
11847a984708SDavid Chisnall{
11857a984708SDavid Chisnall    typedef false_type type;
11867a984708SDavid Chisnall};
11877a984708SDavid Chisnall
11887a984708SDavid Chisnalltemplate <class _Alloc>
11897a984708SDavid Chisnallstruct __propagate_on_container_copy_assignment<_Alloc, true>
11907a984708SDavid Chisnall{
11917a984708SDavid Chisnall    typedef typename _Alloc::propagate_on_container_copy_assignment type;
11927a984708SDavid Chisnall};
11937a984708SDavid Chisnall
119424d58133SDimitry Andrictemplate <class _Tp, class = void>
119524d58133SDimitry Andricstruct __has_propagate_on_container_move_assignment : false_type {};
119624d58133SDimitry Andric
11977a984708SDavid Chisnalltemplate <class _Tp>
119824d58133SDimitry Andricstruct __has_propagate_on_container_move_assignment<_Tp,
119924d58133SDimitry Andric           typename __void_t<typename _Tp::propagate_on_container_move_assignment>::type>
120024d58133SDimitry Andric               : true_type {};
12017a984708SDavid Chisnall
12027a984708SDavid Chisnalltemplate <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
12037a984708SDavid Chisnallstruct __propagate_on_container_move_assignment
12047a984708SDavid Chisnall{
12057a984708SDavid Chisnall    typedef false_type type;
12067a984708SDavid Chisnall};
12077a984708SDavid Chisnall
12087a984708SDavid Chisnalltemplate <class _Alloc>
12097a984708SDavid Chisnallstruct __propagate_on_container_move_assignment<_Alloc, true>
12107a984708SDavid Chisnall{
12117a984708SDavid Chisnall    typedef typename _Alloc::propagate_on_container_move_assignment type;
12127a984708SDavid Chisnall};
12137a984708SDavid Chisnall
121424d58133SDimitry Andrictemplate <class _Tp, class = void>
121524d58133SDimitry Andricstruct __has_propagate_on_container_swap : false_type {};
121624d58133SDimitry Andric
12177a984708SDavid Chisnalltemplate <class _Tp>
121824d58133SDimitry Andricstruct __has_propagate_on_container_swap<_Tp,
121924d58133SDimitry Andric           typename __void_t<typename _Tp::propagate_on_container_swap>::type>
122024d58133SDimitry Andric               : true_type {};
12217a984708SDavid Chisnall
12227a984708SDavid Chisnalltemplate <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
12237a984708SDavid Chisnallstruct __propagate_on_container_swap
12247a984708SDavid Chisnall{
12257a984708SDavid Chisnall    typedef false_type type;
12267a984708SDavid Chisnall};
12277a984708SDavid Chisnall
12287a984708SDavid Chisnalltemplate <class _Alloc>
12297a984708SDavid Chisnallstruct __propagate_on_container_swap<_Alloc, true>
12307a984708SDavid Chisnall{
12317a984708SDavid Chisnall    typedef typename _Alloc::propagate_on_container_swap type;
12327a984708SDavid Chisnall};
12337a984708SDavid Chisnall
123424d58133SDimitry Andrictemplate <class _Tp, class = void>
123524d58133SDimitry Andricstruct __has_is_always_equal : false_type {};
123624d58133SDimitry Andric
1237854fa44bSDimitry Andrictemplate <class _Tp>
123824d58133SDimitry Andricstruct __has_is_always_equal<_Tp,
123924d58133SDimitry Andric           typename __void_t<typename _Tp::is_always_equal>::type>
124024d58133SDimitry Andric               : true_type {};
1241854fa44bSDimitry Andric
1242854fa44bSDimitry Andrictemplate <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
1243854fa44bSDimitry Andricstruct __is_always_equal
1244854fa44bSDimitry Andric{
1245854fa44bSDimitry Andric    typedef typename _VSTD::is_empty<_Alloc>::type type;
1246854fa44bSDimitry Andric};
1247854fa44bSDimitry Andric
1248854fa44bSDimitry Andrictemplate <class _Alloc>
1249854fa44bSDimitry Andricstruct __is_always_equal<_Alloc, true>
1250854fa44bSDimitry Andric{
1251854fa44bSDimitry Andric    typedef typename _Alloc::is_always_equal type;
1252854fa44bSDimitry Andric};
1253854fa44bSDimitry Andric
12547a984708SDavid Chisnalltemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
12557a984708SDavid Chisnallstruct __has_rebind_other
12567a984708SDavid Chisnall{
12577a984708SDavid Chisnallprivate:
12581e0896acSDavid Chisnall    struct __two {char __lx; char __lxx;};
12597a984708SDavid Chisnall    template <class _Xp> static __two __test(...);
12607a984708SDavid Chisnall    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>::other* = 0);
12617a984708SDavid Chisnallpublic:
12627a984708SDavid Chisnall    static const bool value = sizeof(__test<_Tp>(0)) == 1;
12637a984708SDavid Chisnall};
12647a984708SDavid Chisnall
12657a984708SDavid Chisnalltemplate <class _Tp, class _Up>
12667a984708SDavid Chisnallstruct __has_rebind_other<_Tp, _Up, false>
12677a984708SDavid Chisnall{
12687a984708SDavid Chisnall    static const bool value = false;
12697a984708SDavid Chisnall};
12707a984708SDavid Chisnall
12717a984708SDavid Chisnalltemplate <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>
12727a984708SDavid Chisnallstruct __allocator_traits_rebind
12737a984708SDavid Chisnall{
12747a984708SDavid Chisnall    typedef typename _Tp::template rebind<_Up>::other type;
12757a984708SDavid Chisnall};
12767a984708SDavid Chisnall
12777a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
12787a984708SDavid Chisnall
12797a984708SDavid Chisnalltemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
12807a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>
12817a984708SDavid Chisnall{
12827a984708SDavid Chisnall    typedef typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;
12837a984708SDavid Chisnall};
12847a984708SDavid Chisnall
12857a984708SDavid Chisnalltemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
12867a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
12877a984708SDavid Chisnall{
12887a984708SDavid Chisnall    typedef _Alloc<_Up, _Args...> type;
12897a984708SDavid Chisnall};
12907a984708SDavid Chisnall
12917a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
12927a984708SDavid Chisnall
12937a984708SDavid Chisnalltemplate <template <class> class _Alloc, class _Tp, class _Up>
12947a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp>, _Up, true>
12957a984708SDavid Chisnall{
12967a984708SDavid Chisnall    typedef typename _Alloc<_Tp>::template rebind<_Up>::other type;
12977a984708SDavid Chisnall};
12987a984708SDavid Chisnall
12997a984708SDavid Chisnalltemplate <template <class> class _Alloc, class _Tp, class _Up>
13007a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp>, _Up, false>
13017a984708SDavid Chisnall{
13027a984708SDavid Chisnall    typedef _Alloc<_Up> type;
13037a984708SDavid Chisnall};
13047a984708SDavid Chisnall
13057a984708SDavid Chisnalltemplate <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
13067a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, true>
13077a984708SDavid Chisnall{
13087a984708SDavid Chisnall    typedef typename _Alloc<_Tp, _A0>::template rebind<_Up>::other type;
13097a984708SDavid Chisnall};
13107a984708SDavid Chisnall
13117a984708SDavid Chisnalltemplate <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
13127a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, false>
13137a984708SDavid Chisnall{
13147a984708SDavid Chisnall    typedef _Alloc<_Up, _A0> type;
13157a984708SDavid Chisnall};
13167a984708SDavid Chisnall
13177a984708SDavid Chisnalltemplate <template <class, class, class> class _Alloc, class _Tp, class _A0,
13187a984708SDavid Chisnall                                         class _A1, class _Up>
13197a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, true>
13207a984708SDavid Chisnall{
13217a984708SDavid Chisnall    typedef typename _Alloc<_Tp, _A0, _A1>::template rebind<_Up>::other type;
13227a984708SDavid Chisnall};
13237a984708SDavid Chisnall
13247a984708SDavid Chisnalltemplate <template <class, class, class> class _Alloc, class _Tp, class _A0,
13257a984708SDavid Chisnall                                         class _A1, class _Up>
13267a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, false>
13277a984708SDavid Chisnall{
13287a984708SDavid Chisnall    typedef _Alloc<_Up, _A0, _A1> type;
13297a984708SDavid Chisnall};
13307a984708SDavid Chisnall
13317a984708SDavid Chisnalltemplate <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
13327a984708SDavid Chisnall                                                class _A1, class _A2, class _Up>
13337a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, true>
13347a984708SDavid Chisnall{
13357a984708SDavid Chisnall    typedef typename _Alloc<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
13367a984708SDavid Chisnall};
13377a984708SDavid Chisnall
13387a984708SDavid Chisnalltemplate <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
13397a984708SDavid Chisnall                                                class _A1, class _A2, class _Up>
13407a984708SDavid Chisnallstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false>
13417a984708SDavid Chisnall{
13427a984708SDavid Chisnall    typedef _Alloc<_Up, _A0, _A1, _A2> type;
13437a984708SDavid Chisnall};
13447a984708SDavid Chisnall
13457a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
13467a984708SDavid Chisnall
1347aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
13487a984708SDavid Chisnall
13497a984708SDavid Chisnalltemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13507a984708SDavid Chisnallauto
13517a984708SDavid Chisnall__has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
1352b2c7081bSDimitry Andric    -> decltype((void)__a.allocate(__sz, __p), true_type());
13537a984708SDavid Chisnall
13547a984708SDavid Chisnalltemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13557a984708SDavid Chisnallauto
13567a984708SDavid Chisnall__has_allocate_hint_test(const _Alloc& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
13577a984708SDavid Chisnall    -> false_type;
13587a984708SDavid Chisnall
13597a984708SDavid Chisnalltemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13607a984708SDavid Chisnallstruct __has_allocate_hint
13617a984708SDavid Chisnall    : integral_constant<bool,
13627a984708SDavid Chisnall        is_same<
1363b2c7081bSDimitry Andric            decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(),
13647a984708SDavid Chisnall                                          declval<_SizeType>(),
13657a984708SDavid Chisnall                                          declval<_ConstVoidPtr>())),
13667a984708SDavid Chisnall            true_type>::value>
13677a984708SDavid Chisnall{
13687a984708SDavid Chisnall};
13697a984708SDavid Chisnall
1370aed8d94eSDimitry Andric#else  // _LIBCPP_CXX03_LANG
13717a984708SDavid Chisnall
13727a984708SDavid Chisnalltemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13737a984708SDavid Chisnallstruct __has_allocate_hint
13747a984708SDavid Chisnall    : true_type
13757a984708SDavid Chisnall{
13767a984708SDavid Chisnall};
13777a984708SDavid Chisnall
1378aed8d94eSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
13797a984708SDavid Chisnall
1380aed8d94eSDimitry Andric#if !defined(_LIBCPP_CXX03_LANG)
13817a984708SDavid Chisnall
13827a984708SDavid Chisnalltemplate <class _Alloc, class _Tp, class ..._Args>
13837a984708SDavid Chisnalldecltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(),
13847a984708SDavid Chisnall                                           _VSTD::declval<_Args>()...),
13857a984708SDavid Chisnall                                           true_type())
13867a984708SDavid Chisnall__has_construct_test(_Alloc&& __a, _Tp* __p, _Args&& ...__args);
13877a984708SDavid Chisnall
13887a984708SDavid Chisnalltemplate <class _Alloc, class _Pointer, class ..._Args>
13897a984708SDavid Chisnallfalse_type
13907a984708SDavid Chisnall__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args);
13917a984708SDavid Chisnall
13927a984708SDavid Chisnalltemplate <class _Alloc, class _Pointer, class ..._Args>
13937a984708SDavid Chisnallstruct __has_construct
13947a984708SDavid Chisnall    : integral_constant<bool,
13957a984708SDavid Chisnall        is_same<
1396b2c7081bSDimitry Andric            decltype(_VSTD::__has_construct_test(declval<_Alloc>(),
13977a984708SDavid Chisnall                                          declval<_Pointer>(),
13987a984708SDavid Chisnall                                          declval<_Args>()...)),
13997a984708SDavid Chisnall            true_type>::value>
14007a984708SDavid Chisnall{
14017a984708SDavid Chisnall};
14027a984708SDavid Chisnall
14037a984708SDavid Chisnalltemplate <class _Alloc, class _Pointer>
14047a984708SDavid Chisnallauto
14057a984708SDavid Chisnall__has_destroy_test(_Alloc&& __a, _Pointer&& __p)
14067a984708SDavid Chisnall    -> decltype(__a.destroy(__p), true_type());
14077a984708SDavid Chisnall
14087a984708SDavid Chisnalltemplate <class _Alloc, class _Pointer>
14097a984708SDavid Chisnallauto
14107a984708SDavid Chisnall__has_destroy_test(const _Alloc& __a, _Pointer&& __p)
14117a984708SDavid Chisnall    -> false_type;
14127a984708SDavid Chisnall
14137a984708SDavid Chisnalltemplate <class _Alloc, class _Pointer>
14147a984708SDavid Chisnallstruct __has_destroy
14157a984708SDavid Chisnall    : integral_constant<bool,
14167a984708SDavid Chisnall        is_same<
1417b2c7081bSDimitry Andric            decltype(_VSTD::__has_destroy_test(declval<_Alloc>(),
14187a984708SDavid Chisnall                                        declval<_Pointer>())),
14197a984708SDavid Chisnall            true_type>::value>
14207a984708SDavid Chisnall{
14217a984708SDavid Chisnall};
14227a984708SDavid Chisnall
14237a984708SDavid Chisnalltemplate <class _Alloc>
14247a984708SDavid Chisnallauto
14257a984708SDavid Chisnall__has_max_size_test(_Alloc&& __a)
14267a984708SDavid Chisnall    -> decltype(__a.max_size(), true_type());
14277a984708SDavid Chisnall
14287a984708SDavid Chisnalltemplate <class _Alloc>
14297a984708SDavid Chisnallauto
14307a984708SDavid Chisnall__has_max_size_test(const volatile _Alloc& __a)
14317a984708SDavid Chisnall    -> false_type;
14327a984708SDavid Chisnall
14337a984708SDavid Chisnalltemplate <class _Alloc>
14347a984708SDavid Chisnallstruct __has_max_size
14357a984708SDavid Chisnall    : integral_constant<bool,
14367a984708SDavid Chisnall        is_same<
1437b2c7081bSDimitry Andric            decltype(_VSTD::__has_max_size_test(declval<_Alloc&>())),
14387a984708SDavid Chisnall            true_type>::value>
14397a984708SDavid Chisnall{
14407a984708SDavid Chisnall};
14417a984708SDavid Chisnall
14427a984708SDavid Chisnalltemplate <class _Alloc>
14437a984708SDavid Chisnallauto
14447a984708SDavid Chisnall__has_select_on_container_copy_construction_test(_Alloc&& __a)
14457a984708SDavid Chisnall    -> decltype(__a.select_on_container_copy_construction(), true_type());
14467a984708SDavid Chisnall
14477a984708SDavid Chisnalltemplate <class _Alloc>
14487a984708SDavid Chisnallauto
14497a984708SDavid Chisnall__has_select_on_container_copy_construction_test(const volatile _Alloc& __a)
14507a984708SDavid Chisnall    -> false_type;
14517a984708SDavid Chisnall
14527a984708SDavid Chisnalltemplate <class _Alloc>
14537a984708SDavid Chisnallstruct __has_select_on_container_copy_construction
14547a984708SDavid Chisnall    : integral_constant<bool,
14557a984708SDavid Chisnall        is_same<
1456b2c7081bSDimitry Andric            decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>())),
14577a984708SDavid Chisnall            true_type>::value>
14587a984708SDavid Chisnall{
14597a984708SDavid Chisnall};
14607a984708SDavid Chisnall
1461aed8d94eSDimitry Andric#else  // _LIBCPP_CXX03_LANG
14627a984708SDavid Chisnall
1463*b5893f02SDimitry Andrictemplate <class _Alloc, class _Pointer, class _Tp, class = void>
1464*b5893f02SDimitry Andricstruct __has_construct : std::false_type {};
14657a984708SDavid Chisnall
1466*b5893f02SDimitry Andrictemplate <class _Alloc, class _Pointer, class _Tp>
1467*b5893f02SDimitry Andricstruct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t<
1468*b5893f02SDimitry Andric    decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>()))
1469*b5893f02SDimitry Andric>::type> : std::true_type {};
14707a984708SDavid Chisnall
1471*b5893f02SDimitry Andrictemplate <class _Alloc, class _Pointer, class = void>
1472*b5893f02SDimitry Andricstruct __has_destroy : false_type {};
14737a984708SDavid Chisnall
14747a984708SDavid Chisnalltemplate <class _Alloc, class _Pointer>
1475*b5893f02SDimitry Andricstruct __has_destroy<_Alloc, _Pointer, typename __void_t<
1476*b5893f02SDimitry Andric    decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()))
1477*b5893f02SDimitry Andric>::type> : std::true_type {};
14787a984708SDavid Chisnall
14797a984708SDavid Chisnalltemplate <class _Alloc>
14807a984708SDavid Chisnallstruct __has_max_size
14817a984708SDavid Chisnall    : true_type
14827a984708SDavid Chisnall{
14837a984708SDavid Chisnall};
14847a984708SDavid Chisnall
14857a984708SDavid Chisnalltemplate <class _Alloc>
14867a984708SDavid Chisnallstruct __has_select_on_container_copy_construction
14877a984708SDavid Chisnall    : false_type
14887a984708SDavid Chisnall{
14897a984708SDavid Chisnall};
14907a984708SDavid Chisnall
1491aed8d94eSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
14927a984708SDavid Chisnall
14937a984708SDavid Chisnalltemplate <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value>
14947a984708SDavid Chisnallstruct __alloc_traits_difference_type
14957a984708SDavid Chisnall{
14967a984708SDavid Chisnall    typedef typename pointer_traits<_Ptr>::difference_type type;
14977a984708SDavid Chisnall};
14987a984708SDavid Chisnall
14997a984708SDavid Chisnalltemplate <class _Alloc, class _Ptr>
15007a984708SDavid Chisnallstruct __alloc_traits_difference_type<_Alloc, _Ptr, true>
15017a984708SDavid Chisnall{
15027a984708SDavid Chisnall    typedef typename _Alloc::difference_type type;
15037a984708SDavid Chisnall};
15047a984708SDavid Chisnall
1505*b5893f02SDimitry Andrictemplate <class _Tp>
1506*b5893f02SDimitry Andricstruct __is_default_allocator : false_type {};
1507*b5893f02SDimitry Andric
1508*b5893f02SDimitry Andrictemplate <class _Tp>
1509*b5893f02SDimitry Andricstruct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {};
1510*b5893f02SDimitry Andric
15117a984708SDavid Chisnalltemplate <class _Alloc>
1512aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS allocator_traits
15137a984708SDavid Chisnall{
15147a984708SDavid Chisnall    typedef _Alloc                              allocator_type;
15157a984708SDavid Chisnall    typedef typename allocator_type::value_type value_type;
15167a984708SDavid Chisnall
15177a984708SDavid Chisnall    typedef typename __pointer_type<value_type, allocator_type>::type pointer;
15187a984708SDavid Chisnall    typedef typename __const_pointer<value_type, pointer, allocator_type>::type const_pointer;
15197a984708SDavid Chisnall    typedef typename __void_pointer<pointer, allocator_type>::type void_pointer;
15207a984708SDavid Chisnall    typedef typename __const_void_pointer<pointer, allocator_type>::type const_void_pointer;
15217a984708SDavid Chisnall
15227a984708SDavid Chisnall    typedef typename __alloc_traits_difference_type<allocator_type, pointer>::type difference_type;
15237a984708SDavid Chisnall    typedef typename __size_type<allocator_type, difference_type>::type size_type;
15247a984708SDavid Chisnall
15257a984708SDavid Chisnall    typedef typename __propagate_on_container_copy_assignment<allocator_type>::type
15267a984708SDavid Chisnall                     propagate_on_container_copy_assignment;
15277a984708SDavid Chisnall    typedef typename __propagate_on_container_move_assignment<allocator_type>::type
15287a984708SDavid Chisnall                     propagate_on_container_move_assignment;
15297a984708SDavid Chisnall    typedef typename __propagate_on_container_swap<allocator_type>::type
15307a984708SDavid Chisnall                     propagate_on_container_swap;
1531854fa44bSDimitry Andric    typedef typename __is_always_equal<allocator_type>::type
1532854fa44bSDimitry Andric                     is_always_equal;
15337a984708SDavid Chisnall
1534aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
15357a984708SDavid Chisnall    template <class _Tp> using rebind_alloc =
15367a984708SDavid Chisnall                  typename __allocator_traits_rebind<allocator_type, _Tp>::type;
15377a984708SDavid Chisnall    template <class _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
1538aed8d94eSDimitry Andric#else  // _LIBCPP_CXX03_LANG
15397a984708SDavid Chisnall    template <class _Tp> struct rebind_alloc
15407a984708SDavid Chisnall        {typedef typename __allocator_traits_rebind<allocator_type, _Tp>::type other;};
15417a984708SDavid Chisnall    template <class _Tp> struct rebind_traits
15427a984708SDavid Chisnall        {typedef allocator_traits<typename rebind_alloc<_Tp>::other> other;};
1543aed8d94eSDimitry Andric#endif  // _LIBCPP_CXX03_LANG
15447a984708SDavid Chisnall
1545b2c7081bSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
15467a984708SDavid Chisnall    static pointer allocate(allocator_type& __a, size_type __n)
15477a984708SDavid Chisnall        {return __a.allocate(__n);}
1548b2c7081bSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
15497a984708SDavid Chisnall    static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
1550f9448bf3SDimitry Andric        {return __allocate(__a, __n, __hint,
15517a984708SDavid Chisnall            __has_allocate_hint<allocator_type, size_type, const_void_pointer>());}
15527a984708SDavid Chisnall
15537a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
15547a984708SDavid Chisnall    static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT
15557a984708SDavid Chisnall        {__a.deallocate(__p, __n);}
15567a984708SDavid Chisnall
15577a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
15587a984708SDavid Chisnall    template <class _Tp, class... _Args>
15597a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
15607a984708SDavid Chisnall        static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)
1561d72607e9SDimitry Andric            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
15627a984708SDavid Chisnall                         __a, __p, _VSTD::forward<_Args>(__args)...);}
15637a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
15647a984708SDavid Chisnall    template <class _Tp>
15657a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
1566540d2a8bSDimitry Andric        static void construct(allocator_type&, _Tp* __p)
15677a984708SDavid Chisnall            {
15687a984708SDavid Chisnall                ::new ((void*)__p) _Tp();
15697a984708SDavid Chisnall            }
15707a984708SDavid Chisnall    template <class _Tp, class _A0>
15717a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
1572*b5893f02SDimitry Andric        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)
15737a984708SDavid Chisnall            {
1574*b5893f02SDimitry Andric                __construct(__has_construct<allocator_type, _Tp*, const _A0&>(),
1575*b5893f02SDimitry Andric                            __a, __p, __a0);
15767a984708SDavid Chisnall            }
15777a984708SDavid Chisnall    template <class _Tp, class _A0, class _A1>
15787a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
1579540d2a8bSDimitry Andric        static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
15807a984708SDavid Chisnall                              const _A1& __a1)
15817a984708SDavid Chisnall            {
15827a984708SDavid Chisnall                ::new ((void*)__p) _Tp(__a0, __a1);
15837a984708SDavid Chisnall            }
15847a984708SDavid Chisnall    template <class _Tp, class _A0, class _A1, class _A2>
15857a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
1586540d2a8bSDimitry Andric        static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
15877a984708SDavid Chisnall                              const _A1& __a1, const _A2& __a2)
15887a984708SDavid Chisnall            {
15897a984708SDavid Chisnall                ::new ((void*)__p) _Tp(__a0, __a1, __a2);
15907a984708SDavid Chisnall            }
15917a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
15927a984708SDavid Chisnall
15937a984708SDavid Chisnall    template <class _Tp>
15947a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
15957a984708SDavid Chisnall        static void destroy(allocator_type& __a, _Tp* __p)
15967a984708SDavid Chisnall            {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}
15977a984708SDavid Chisnall
15987a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
15994f7ab58eSDimitry Andric    static size_type max_size(const allocator_type& __a) _NOEXCEPT
16007a984708SDavid Chisnall        {return __max_size(__has_max_size<const allocator_type>(), __a);}
16017a984708SDavid Chisnall
16027a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
16037a984708SDavid Chisnall    static allocator_type
16047a984708SDavid Chisnall        select_on_container_copy_construction(const allocator_type& __a)
1605f9448bf3SDimitry Andric            {return __select_on_container_copy_construction(
16067a984708SDavid Chisnall                __has_select_on_container_copy_construction<const allocator_type>(),
16077a984708SDavid Chisnall                __a);}
16087a984708SDavid Chisnall
160994e3ee44SDavid Chisnall    template <class _Ptr>
161094e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
161194e3ee44SDavid Chisnall        static
161294e3ee44SDavid Chisnall        void
161394e3ee44SDavid Chisnall        __construct_forward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)
161494e3ee44SDavid Chisnall        {
1615*b5893f02SDimitry Andric            for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
161694e3ee44SDavid Chisnall                construct(__a, _VSTD::__to_raw_pointer(__begin2), _VSTD::move_if_noexcept(*__begin1));
161794e3ee44SDavid Chisnall        }
161894e3ee44SDavid Chisnall
161994e3ee44SDavid Chisnall    template <class _Tp>
162094e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
162194e3ee44SDavid Chisnall        static
162294e3ee44SDavid Chisnall        typename enable_if
162394e3ee44SDavid Chisnall        <
1624*b5893f02SDimitry Andric            (__is_default_allocator<allocator_type>::value
162594e3ee44SDavid Chisnall                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
162694e3ee44SDavid Chisnall             is_trivially_move_constructible<_Tp>::value,
162794e3ee44SDavid Chisnall            void
162894e3ee44SDavid Chisnall        >::type
1629aed8d94eSDimitry Andric        __construct_forward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
163094e3ee44SDavid Chisnall        {
163194e3ee44SDavid Chisnall            ptrdiff_t _Np = __end1 - __begin1;
1632854fa44bSDimitry Andric            if (_Np > 0)
1633854fa44bSDimitry Andric            {
163494e3ee44SDavid Chisnall                _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
163594e3ee44SDavid Chisnall                __begin2 += _Np;
163694e3ee44SDavid Chisnall            }
1637854fa44bSDimitry Andric        }
1638854fa44bSDimitry Andric
1639854fa44bSDimitry Andric    template <class _Iter, class _Ptr>
1640854fa44bSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1641854fa44bSDimitry Andric        static
1642854fa44bSDimitry Andric        void
1643854fa44bSDimitry Andric        __construct_range_forward(allocator_type& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2)
1644854fa44bSDimitry Andric        {
1645854fa44bSDimitry Andric            for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
1646854fa44bSDimitry Andric                construct(__a, _VSTD::__to_raw_pointer(__begin2), *__begin1);
1647854fa44bSDimitry Andric        }
1648854fa44bSDimitry Andric
1649*b5893f02SDimitry Andric    template <class _SourceTp, class _DestTp,
1650*b5893f02SDimitry Andric              class _RawSourceTp = typename remove_const<_SourceTp>::type,
1651*b5893f02SDimitry Andric              class _RawDestTp = typename remove_const<_DestTp>::type>
1652854fa44bSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1653854fa44bSDimitry Andric        static
1654854fa44bSDimitry Andric        typename enable_if
1655854fa44bSDimitry Andric        <
1656*b5893f02SDimitry Andric            is_trivially_move_constructible<_DestTp>::value &&
1657*b5893f02SDimitry Andric            is_same<_RawSourceTp, _RawDestTp>::value &&
1658*b5893f02SDimitry Andric            (__is_default_allocator<allocator_type>::value ||
1659*b5893f02SDimitry Andric             !__has_construct<allocator_type, _DestTp*, _SourceTp&>::value),
1660854fa44bSDimitry Andric            void
1661854fa44bSDimitry Andric        >::type
1662*b5893f02SDimitry Andric        __construct_range_forward(allocator_type&, _SourceTp* __begin1, _SourceTp* __end1, _DestTp*& __begin2)
1663854fa44bSDimitry Andric        {
1664854fa44bSDimitry Andric            ptrdiff_t _Np = __end1 - __begin1;
1665854fa44bSDimitry Andric            if (_Np > 0)
1666854fa44bSDimitry Andric            {
1667*b5893f02SDimitry Andric                _VSTD::memcpy(const_cast<_RawDestTp*>(__begin2), __begin1, _Np * sizeof(_DestTp));
1668854fa44bSDimitry Andric                __begin2 += _Np;
1669854fa44bSDimitry Andric            }
1670854fa44bSDimitry Andric        }
167194e3ee44SDavid Chisnall
167294e3ee44SDavid Chisnall    template <class _Ptr>
167394e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
167494e3ee44SDavid Chisnall        static
167594e3ee44SDavid Chisnall        void
167694e3ee44SDavid Chisnall        __construct_backward(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2)
167794e3ee44SDavid Chisnall        {
167894e3ee44SDavid Chisnall            while (__end1 != __begin1)
1679cfdf2879SDavid Chisnall            {
1680cfdf2879SDavid Chisnall                construct(__a, _VSTD::__to_raw_pointer(__end2-1), _VSTD::move_if_noexcept(*--__end1));
1681cfdf2879SDavid Chisnall                --__end2;
1682cfdf2879SDavid Chisnall            }
168394e3ee44SDavid Chisnall        }
168494e3ee44SDavid Chisnall
168594e3ee44SDavid Chisnall    template <class _Tp>
168694e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
168794e3ee44SDavid Chisnall        static
168894e3ee44SDavid Chisnall        typename enable_if
168994e3ee44SDavid Chisnall        <
1690*b5893f02SDimitry Andric            (__is_default_allocator<allocator_type>::value
169194e3ee44SDavid Chisnall                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
169294e3ee44SDavid Chisnall             is_trivially_move_constructible<_Tp>::value,
169394e3ee44SDavid Chisnall            void
169494e3ee44SDavid Chisnall        >::type
1695aed8d94eSDimitry Andric        __construct_backward(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2)
169694e3ee44SDavid Chisnall        {
169794e3ee44SDavid Chisnall            ptrdiff_t _Np = __end1 - __begin1;
169894e3ee44SDavid Chisnall            __end2 -= _Np;
1699854fa44bSDimitry Andric            if (_Np > 0)
170094e3ee44SDavid Chisnall                _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
170194e3ee44SDavid Chisnall        }
170294e3ee44SDavid Chisnall
17037a984708SDavid Chisnallprivate:
17047a984708SDavid Chisnall
17057a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1706f9448bf3SDimitry Andric    static pointer __allocate(allocator_type& __a, size_type __n,
17077a984708SDavid Chisnall        const_void_pointer __hint, true_type)
17087a984708SDavid Chisnall        {return __a.allocate(__n, __hint);}
17097a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1710f9448bf3SDimitry Andric    static pointer __allocate(allocator_type& __a, size_type __n,
171194e3ee44SDavid Chisnall        const_void_pointer, false_type)
17127a984708SDavid Chisnall        {return __a.allocate(__n);}
17137a984708SDavid Chisnall
17147a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
17157a984708SDavid Chisnall    template <class _Tp, class... _Args>
17167a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
17177a984708SDavid Chisnall        static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args)
17187a984708SDavid Chisnall            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
17197a984708SDavid Chisnall    template <class _Tp, class... _Args>
17207a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
17217a984708SDavid Chisnall        static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)
17227a984708SDavid Chisnall            {
17237a984708SDavid Chisnall                ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
17247a984708SDavid Chisnall            }
1725*b5893f02SDimitry Andric#else  // _LIBCPP_HAS_NO_VARIADICS
1726*b5893f02SDimitry Andric    template <class _Tp, class _A0>
1727*b5893f02SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1728*b5893f02SDimitry Andric        static void __construct(true_type, allocator_type& __a, _Tp* __p,
1729*b5893f02SDimitry Andric                                const _A0& __a0)
1730*b5893f02SDimitry Andric            {__a.construct(__p, __a0);}
1731*b5893f02SDimitry Andric    template <class _Tp, class _A0>
1732*b5893f02SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
1733*b5893f02SDimitry Andric        static void __construct(false_type, allocator_type&, _Tp* __p,
1734*b5893f02SDimitry Andric                                const _A0& __a0)
1735*b5893f02SDimitry Andric            {
1736*b5893f02SDimitry Andric                ::new ((void*)__p) _Tp(__a0);
1737*b5893f02SDimitry Andric            }
17387a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
17397a984708SDavid Chisnall
17407a984708SDavid Chisnall    template <class _Tp>
17417a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
17427a984708SDavid Chisnall        static void __destroy(true_type, allocator_type& __a, _Tp* __p)
17437a984708SDavid Chisnall            {__a.destroy(__p);}
17447a984708SDavid Chisnall    template <class _Tp>
17457a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
17467a984708SDavid Chisnall        static void __destroy(false_type, allocator_type&, _Tp* __p)
17477a984708SDavid Chisnall            {
17487a984708SDavid Chisnall                __p->~_Tp();
17497a984708SDavid Chisnall            }
17507a984708SDavid Chisnall
17517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1752b2c7081bSDimitry Andric    static size_type __max_size(true_type, const allocator_type& __a) _NOEXCEPT
17537a984708SDavid Chisnall            {return __a.max_size();}
17547a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1755b2c7081bSDimitry Andric    static size_type __max_size(false_type, const allocator_type&) _NOEXCEPT
17569729cf09SDimitry Andric            {return numeric_limits<size_type>::max() / sizeof(value_type);}
17577a984708SDavid Chisnall
17587a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
17597a984708SDavid Chisnall    static allocator_type
1760f9448bf3SDimitry Andric        __select_on_container_copy_construction(true_type, const allocator_type& __a)
17617a984708SDavid Chisnall            {return __a.select_on_container_copy_construction();}
17627a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
17637a984708SDavid Chisnall    static allocator_type
1764f9448bf3SDimitry Andric        __select_on_container_copy_construction(false_type, const allocator_type& __a)
17657a984708SDavid Chisnall            {return __a;}
17667a984708SDavid Chisnall};
17677a984708SDavid Chisnall
1768854fa44bSDimitry Andrictemplate <class _Traits, class _Tp>
1769854fa44bSDimitry Andricstruct __rebind_alloc_helper
1770854fa44bSDimitry Andric{
1771aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1772854fa44bSDimitry Andric    typedef typename _Traits::template rebind_alloc<_Tp>        type;
1773854fa44bSDimitry Andric#else
1774854fa44bSDimitry Andric    typedef typename _Traits::template rebind_alloc<_Tp>::other type;
1775854fa44bSDimitry Andric#endif
1776854fa44bSDimitry Andric};
1777854fa44bSDimitry Andric
17787a984708SDavid Chisnall// allocator
17797a984708SDavid Chisnall
17807a984708SDavid Chisnalltemplate <class _Tp>
1781aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator
17827a984708SDavid Chisnall{
17837a984708SDavid Chisnallpublic:
17847a984708SDavid Chisnall    typedef size_t            size_type;
17857a984708SDavid Chisnall    typedef ptrdiff_t         difference_type;
17867a984708SDavid Chisnall    typedef _Tp*              pointer;
17877a984708SDavid Chisnall    typedef const _Tp*        const_pointer;
17887a984708SDavid Chisnall    typedef _Tp&              reference;
17897a984708SDavid Chisnall    typedef const _Tp&        const_reference;
17907a984708SDavid Chisnall    typedef _Tp               value_type;
17917a984708SDavid Chisnall
17927a984708SDavid Chisnall    typedef true_type propagate_on_container_move_assignment;
1793854fa44bSDimitry Andric    typedef true_type is_always_equal;
17947a984708SDavid Chisnall
17957a984708SDavid Chisnall    template <class _Up> struct rebind {typedef allocator<_Up> other;};
17967a984708SDavid Chisnall
17974ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
17984ba319b5SDimitry Andric    allocator() _NOEXCEPT {}
17994ba319b5SDimitry Andric
18004ba319b5SDimitry Andric    template <class _Up>
18014ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
18024ba319b5SDimitry Andric    allocator(const allocator<_Up>&) _NOEXCEPT {}
18034ba319b5SDimitry Andric
18047a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT
18057a984708SDavid Chisnall        {return _VSTD::addressof(__x);}
18067a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
18077a984708SDavid Chisnall        {return _VSTD::addressof(__x);}
1808b2c7081bSDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
1809b2c7081bSDimitry Andric    pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
18107c82a1ecSDimitry Andric        {
18117c82a1ecSDimitry Andric        if (__n > max_size())
1812aed8d94eSDimitry Andric            __throw_length_error("allocator<T>::allocate(size_t n)"
1813aed8d94eSDimitry Andric                                 " 'n' exceeds maximum supported size");
1814*b5893f02SDimitry Andric        return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
18157c82a1ecSDimitry Andric        }
1816*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
1817*b5893f02SDimitry Andric        {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
18187a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
18197a984708SDavid Chisnall        {return size_type(~0) / sizeof(_Tp);}
18207a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
18217a984708SDavid Chisnall    template <class _Up, class... _Args>
18227a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18237a984708SDavid Chisnall        void
18247a984708SDavid Chisnall        construct(_Up* __p, _Args&&... __args)
18257a984708SDavid Chisnall        {
18267a984708SDavid Chisnall            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
18277a984708SDavid Chisnall        }
18287a984708SDavid Chisnall#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
18297a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18307a984708SDavid Chisnall        void
18317a984708SDavid Chisnall        construct(pointer __p)
18327a984708SDavid Chisnall        {
18337a984708SDavid Chisnall            ::new((void*)__p) _Tp();
18347a984708SDavid Chisnall        }
18357a984708SDavid Chisnall# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
1836b03f91a8SDavid Chisnall
18377a984708SDavid Chisnall    template <class _A0>
18387a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18397a984708SDavid Chisnall        void
18407a984708SDavid Chisnall        construct(pointer __p, _A0& __a0)
18417a984708SDavid Chisnall        {
18427a984708SDavid Chisnall            ::new((void*)__p) _Tp(__a0);
18437a984708SDavid Chisnall        }
18447a984708SDavid Chisnall    template <class _A0>
18457a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18467a984708SDavid Chisnall        void
18477a984708SDavid Chisnall        construct(pointer __p, const _A0& __a0)
18487a984708SDavid Chisnall        {
18497a984708SDavid Chisnall            ::new((void*)__p) _Tp(__a0);
18507a984708SDavid Chisnall        }
18517a984708SDavid Chisnall# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
18527a984708SDavid Chisnall    template <class _A0, class _A1>
18537a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18547a984708SDavid Chisnall        void
18557a984708SDavid Chisnall        construct(pointer __p, _A0& __a0, _A1& __a1)
18567a984708SDavid Chisnall        {
18577a984708SDavid Chisnall            ::new((void*)__p) _Tp(__a0, __a1);
18587a984708SDavid Chisnall        }
18597a984708SDavid Chisnall    template <class _A0, class _A1>
18607a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18617a984708SDavid Chisnall        void
18627a984708SDavid Chisnall        construct(pointer __p, const _A0& __a0, _A1& __a1)
18637a984708SDavid Chisnall        {
18647a984708SDavid Chisnall            ::new((void*)__p) _Tp(__a0, __a1);
18657a984708SDavid Chisnall        }
18667a984708SDavid Chisnall    template <class _A0, class _A1>
18677a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18687a984708SDavid Chisnall        void
18697a984708SDavid Chisnall        construct(pointer __p, _A0& __a0, const _A1& __a1)
18707a984708SDavid Chisnall        {
18717a984708SDavid Chisnall            ::new((void*)__p) _Tp(__a0, __a1);
18727a984708SDavid Chisnall        }
18737a984708SDavid Chisnall    template <class _A0, class _A1>
18747a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
18757a984708SDavid Chisnall        void
18767a984708SDavid Chisnall        construct(pointer __p, const _A0& __a0, const _A1& __a1)
18777a984708SDavid Chisnall        {
18787a984708SDavid Chisnall            ::new((void*)__p) _Tp(__a0, __a1);
18797a984708SDavid Chisnall        }
18807a984708SDavid Chisnall#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
18817a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
18827a984708SDavid Chisnall};
18837a984708SDavid Chisnall
188494e3ee44SDavid Chisnalltemplate <class _Tp>
1885aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
188694e3ee44SDavid Chisnall{
188794e3ee44SDavid Chisnallpublic:
188894e3ee44SDavid Chisnall    typedef size_t            size_type;
188994e3ee44SDavid Chisnall    typedef ptrdiff_t         difference_type;
189094e3ee44SDavid Chisnall    typedef const _Tp*        pointer;
189194e3ee44SDavid Chisnall    typedef const _Tp*        const_pointer;
189294e3ee44SDavid Chisnall    typedef const _Tp&        reference;
189394e3ee44SDavid Chisnall    typedef const _Tp&        const_reference;
18944bab9fd9SDavid Chisnall    typedef const _Tp         value_type;
189594e3ee44SDavid Chisnall
189694e3ee44SDavid Chisnall    typedef true_type propagate_on_container_move_assignment;
1897854fa44bSDimitry Andric    typedef true_type is_always_equal;
189894e3ee44SDavid Chisnall
189994e3ee44SDavid Chisnall    template <class _Up> struct rebind {typedef allocator<_Up> other;};
190094e3ee44SDavid Chisnall
19014ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
19024ba319b5SDimitry Andric    allocator() _NOEXCEPT {}
19034ba319b5SDimitry Andric
19044ba319b5SDimitry Andric    template <class _Up>
19054ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
19064ba319b5SDimitry Andric    allocator(const allocator<_Up>&) _NOEXCEPT {}
19074ba319b5SDimitry Andric
190894e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
190994e3ee44SDavid Chisnall        {return _VSTD::addressof(__x);}
191094e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
19117c82a1ecSDimitry Andric    {
19127c82a1ecSDimitry Andric        if (__n > max_size())
1913aed8d94eSDimitry Andric            __throw_length_error("allocator<const T>::allocate(size_t n)"
1914aed8d94eSDimitry Andric                                 " 'n' exceeds maximum supported size");
1915*b5893f02SDimitry Andric        return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
19167c82a1ecSDimitry Andric    }
1917*b5893f02SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
1918*b5893f02SDimitry Andric        {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
191994e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
192094e3ee44SDavid Chisnall        {return size_type(~0) / sizeof(_Tp);}
192194e3ee44SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
192294e3ee44SDavid Chisnall    template <class _Up, class... _Args>
192394e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
192494e3ee44SDavid Chisnall        void
192594e3ee44SDavid Chisnall        construct(_Up* __p, _Args&&... __args)
192694e3ee44SDavid Chisnall        {
192794e3ee44SDavid Chisnall            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
192894e3ee44SDavid Chisnall        }
192994e3ee44SDavid Chisnall#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
193094e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
193194e3ee44SDavid Chisnall        void
193294e3ee44SDavid Chisnall        construct(pointer __p)
193394e3ee44SDavid Chisnall        {
193424d58133SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp();
193594e3ee44SDavid Chisnall        }
193694e3ee44SDavid Chisnall# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
1937b03f91a8SDavid Chisnall
193894e3ee44SDavid Chisnall    template <class _A0>
193994e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
194094e3ee44SDavid Chisnall        void
194194e3ee44SDavid Chisnall        construct(pointer __p, _A0& __a0)
194294e3ee44SDavid Chisnall        {
194324d58133SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
194494e3ee44SDavid Chisnall        }
194594e3ee44SDavid Chisnall    template <class _A0>
194694e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
194794e3ee44SDavid Chisnall        void
194894e3ee44SDavid Chisnall        construct(pointer __p, const _A0& __a0)
194994e3ee44SDavid Chisnall        {
195024d58133SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
195194e3ee44SDavid Chisnall        }
195294e3ee44SDavid Chisnall# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
195394e3ee44SDavid Chisnall    template <class _A0, class _A1>
195494e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
195594e3ee44SDavid Chisnall        void
195694e3ee44SDavid Chisnall        construct(pointer __p, _A0& __a0, _A1& __a1)
195794e3ee44SDavid Chisnall        {
195824d58133SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
195994e3ee44SDavid Chisnall        }
196094e3ee44SDavid Chisnall    template <class _A0, class _A1>
196194e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
196294e3ee44SDavid Chisnall        void
196394e3ee44SDavid Chisnall        construct(pointer __p, const _A0& __a0, _A1& __a1)
196494e3ee44SDavid Chisnall        {
196524d58133SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
196694e3ee44SDavid Chisnall        }
196794e3ee44SDavid Chisnall    template <class _A0, class _A1>
196894e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
196994e3ee44SDavid Chisnall        void
197094e3ee44SDavid Chisnall        construct(pointer __p, _A0& __a0, const _A1& __a1)
197194e3ee44SDavid Chisnall        {
197224d58133SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
197394e3ee44SDavid Chisnall        }
197494e3ee44SDavid Chisnall    template <class _A0, class _A1>
197594e3ee44SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
197694e3ee44SDavid Chisnall        void
197794e3ee44SDavid Chisnall        construct(pointer __p, const _A0& __a0, const _A1& __a1)
197894e3ee44SDavid Chisnall        {
197924d58133SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
198094e3ee44SDavid Chisnall        }
198194e3ee44SDavid Chisnall#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
198294e3ee44SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
198394e3ee44SDavid Chisnall};
198494e3ee44SDavid Chisnall
19857a984708SDavid Chisnalltemplate <class _Tp, class _Up>
19867a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
19877a984708SDavid Chisnallbool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
19887a984708SDavid Chisnall
19897a984708SDavid Chisnalltemplate <class _Tp, class _Up>
19907a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
19917a984708SDavid Chisnallbool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
19927a984708SDavid Chisnall
19937a984708SDavid Chisnalltemplate <class _OutputIterator, class _Tp>
1994aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS raw_storage_iterator
19957a984708SDavid Chisnall    : public iterator<output_iterator_tag,
19967a984708SDavid Chisnall                      _Tp,                                         // purposefully not C++03
19977a984708SDavid Chisnall                      ptrdiff_t,                                   // purposefully not C++03
19987a984708SDavid Chisnall                      _Tp*,                                        // purposefully not C++03
19997a984708SDavid Chisnall                      raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03
20007a984708SDavid Chisnall{
20017a984708SDavid Chisnallprivate:
20027a984708SDavid Chisnall    _OutputIterator __x_;
20037a984708SDavid Chisnallpublic:
20047a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
20057a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
20067a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
20074ba319b5SDimitry Andric        {::new(_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
20089729cf09SDimitry Andric#if _LIBCPP_STD_VER >= 14
20099729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
20104ba319b5SDimitry Andric        {::new(_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
20119729cf09SDimitry Andric#endif
20127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
20137a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator  operator++(int)
20147a984708SDavid Chisnall        {raw_storage_iterator __t(*this); ++__x_; return __t;}
2015854fa44bSDimitry Andric#if _LIBCPP_STD_VER >= 14
2016854fa44bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
2017854fa44bSDimitry Andric#endif
20187a984708SDavid Chisnall};
20197a984708SDavid Chisnall
20207a984708SDavid Chisnalltemplate <class _Tp>
2021*b5893f02SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
20227a984708SDavid Chisnallpair<_Tp*, ptrdiff_t>
20237a984708SDavid Chisnallget_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
20247a984708SDavid Chisnall{
20257a984708SDavid Chisnall    pair<_Tp*, ptrdiff_t> __r(0, 0);
20267a984708SDavid Chisnall    const ptrdiff_t __m = (~ptrdiff_t(0) ^
20277a984708SDavid Chisnall                           ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
20287a984708SDavid Chisnall                           / sizeof(_Tp);
20297a984708SDavid Chisnall    if (__n > __m)
20307a984708SDavid Chisnall        __n = __m;
20317a984708SDavid Chisnall    while (__n > 0)
20327a984708SDavid Chisnall    {
20334ba319b5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
2034*b5893f02SDimitry Andric    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
20354ba319b5SDimitry Andric        {
20364ba319b5SDimitry Andric            std::align_val_t __al =
20374ba319b5SDimitry Andric                std::align_val_t(std::alignment_of<_Tp>::value);
20384ba319b5SDimitry Andric            __r.first = static_cast<_Tp*>(::operator new(
20394ba319b5SDimitry Andric                __n * sizeof(_Tp), __al, nothrow));
20404ba319b5SDimitry Andric        } else {
20414ba319b5SDimitry Andric            __r.first = static_cast<_Tp*>(::operator new(
20424ba319b5SDimitry Andric                __n * sizeof(_Tp), nothrow));
20434ba319b5SDimitry Andric        }
20444ba319b5SDimitry Andric#else
2045*b5893f02SDimitry Andric    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
20464ba319b5SDimitry Andric        {
20474ba319b5SDimitry Andric            // Since aligned operator new is unavailable, return an empty
20484ba319b5SDimitry Andric            // buffer rather than one with invalid alignment.
20494ba319b5SDimitry Andric            return __r;
20504ba319b5SDimitry Andric        }
20514ba319b5SDimitry Andric
20527a984708SDavid Chisnall        __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
20534ba319b5SDimitry Andric#endif
20544ba319b5SDimitry Andric
20557a984708SDavid Chisnall        if (__r.first)
20567a984708SDavid Chisnall        {
20577a984708SDavid Chisnall            __r.second = __n;
20587a984708SDavid Chisnall            break;
20597a984708SDavid Chisnall        }
20607a984708SDavid Chisnall        __n /= 2;
20617a984708SDavid Chisnall    }
20627a984708SDavid Chisnall    return __r;
20637a984708SDavid Chisnall}
20647a984708SDavid Chisnall
20657a984708SDavid Chisnalltemplate <class _Tp>
20667a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
20674ba319b5SDimitry Andricvoid return_temporary_buffer(_Tp* __p) _NOEXCEPT
20684ba319b5SDimitry Andric{
2069*b5893f02SDimitry Andric  _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
20704ba319b5SDimitry Andric}
20717a984708SDavid Chisnall
2072540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
20737a984708SDavid Chisnalltemplate <class _Tp>
2074*b5893f02SDimitry Andricstruct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
20757a984708SDavid Chisnall{
20767a984708SDavid Chisnall    _Tp* __ptr_;
20777a984708SDavid Chisnall};
20787a984708SDavid Chisnall
20797a984708SDavid Chisnalltemplate<class _Tp>
2080*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
20817a984708SDavid Chisnall{
20827a984708SDavid Chisnallprivate:
20837a984708SDavid Chisnall    _Tp* __ptr_;
20847a984708SDavid Chisnallpublic:
20857a984708SDavid Chisnall    typedef _Tp element_type;
20867a984708SDavid Chisnall
20877a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) throw() : __ptr_(__p) {}
20887a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) throw() : __ptr_(__p.release()) {}
20897a984708SDavid Chisnall    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) throw()
20907a984708SDavid Chisnall        : __ptr_(__p.release()) {}
20917a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) throw()
20927a984708SDavid Chisnall        {reset(__p.release()); return *this;}
20937a984708SDavid Chisnall    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) throw()
20947a984708SDavid Chisnall        {reset(__p.release()); return *this;}
20957a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) throw()
20967a984708SDavid Chisnall        {reset(__p.__ptr_); return *this;}
20977a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() throw() {delete __ptr_;}
20987a984708SDavid Chisnall
20997a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const throw()
21007a984708SDavid Chisnall        {return *__ptr_;}
21017a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const throw() {return __ptr_;}
21027a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Tp* get() const throw() {return __ptr_;}
21037a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY _Tp* release() throw()
21047a984708SDavid Chisnall    {
21057a984708SDavid Chisnall        _Tp* __t = __ptr_;
21067a984708SDavid Chisnall        __ptr_ = 0;
21077a984708SDavid Chisnall        return __t;
21087a984708SDavid Chisnall    }
21097a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) throw()
21107a984708SDavid Chisnall    {
21117a984708SDavid Chisnall        if (__ptr_ != __p)
21127a984708SDavid Chisnall            delete __ptr_;
21137a984708SDavid Chisnall        __ptr_ = __p;
21147a984708SDavid Chisnall    }
21157a984708SDavid Chisnall
21167a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) throw() : __ptr_(__p.__ptr_) {}
21177a984708SDavid Chisnall    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() throw()
21187a984708SDavid Chisnall        {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
21197a984708SDavid Chisnall    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() throw()
21207a984708SDavid Chisnall        {return auto_ptr<_Up>(release());}
21217a984708SDavid Chisnall};
21227a984708SDavid Chisnall
21237a984708SDavid Chisnalltemplate <>
2124*b5893f02SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
21257a984708SDavid Chisnall{
21267a984708SDavid Chisnallpublic:
21277a984708SDavid Chisnall    typedef void element_type;
21287a984708SDavid Chisnall};
2129540d2a8bSDimitry Andric#endif
21307a984708SDavid Chisnall
2131540d2a8bSDimitry Andrictemplate <class _Tp, int _Idx,
2132540d2a8bSDimitry Andric          bool _CanBeEmptyBase =
2133540d2a8bSDimitry Andric              is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
2134540d2a8bSDimitry Andricstruct __compressed_pair_elem {
2135540d2a8bSDimitry Andric  typedef _Tp _ParamT;
2136540d2a8bSDimitry Andric  typedef _Tp& reference;
2137540d2a8bSDimitry Andric  typedef const _Tp& const_reference;
2138540d2a8bSDimitry Andric
2139540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2140b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() : __value_() {}
2141540d2a8bSDimitry Andric
2142540d2a8bSDimitry Andric  template <class _Up, class = typename enable_if<
2143540d2a8bSDimitry Andric      !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
2144540d2a8bSDimitry Andric  >::type>
2145b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2146540d2a8bSDimitry Andric  constexpr explicit
2147540d2a8bSDimitry Andric  __compressed_pair_elem(_Up&& __u)
2148*b5893f02SDimitry Andric      : __value_(_VSTD::forward<_Up>(__u))
2149*b5893f02SDimitry Andric    {
2150*b5893f02SDimitry Andric    }
2151540d2a8bSDimitry Andric
2152540d2a8bSDimitry Andric  template <class... _Args, size_t... _Indexes>
2153540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
2154540d2a8bSDimitry Andric  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
2155540d2a8bSDimitry Andric                         __tuple_indices<_Indexes...>)
2156540d2a8bSDimitry Andric      : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
2157540d2a8bSDimitry Andric#else
2158b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY __compressed_pair_elem() : __value_() {}
2159b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2160540d2a8bSDimitry Andric  __compressed_pair_elem(_ParamT __p) : __value_(std::forward<_ParamT>(__p)) {}
2161540d2a8bSDimitry Andric#endif
2162540d2a8bSDimitry Andric
2163b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
2164b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2165540d2a8bSDimitry Andric  const_reference __get() const _NOEXCEPT { return __value_; }
2166540d2a8bSDimitry Andric
2167540d2a8bSDimitry Andricprivate:
2168540d2a8bSDimitry Andric  _Tp __value_;
2169540d2a8bSDimitry Andric};
2170540d2a8bSDimitry Andric
2171540d2a8bSDimitry Andrictemplate <class _Tp, int _Idx>
2172540d2a8bSDimitry Andricstruct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
2173540d2a8bSDimitry Andric  typedef _Tp _ParamT;
2174540d2a8bSDimitry Andric  typedef _Tp& reference;
2175540d2a8bSDimitry Andric  typedef const _Tp& const_reference;
2176540d2a8bSDimitry Andric  typedef _Tp __value_type;
2177540d2a8bSDimitry Andric
2178540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2179b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() = default;
2180540d2a8bSDimitry Andric
2181540d2a8bSDimitry Andric  template <class _Up, class = typename enable_if<
2182540d2a8bSDimitry Andric        !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
2183540d2a8bSDimitry Andric  >::type>
2184b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2185540d2a8bSDimitry Andric  constexpr explicit
2186540d2a8bSDimitry Andric  __compressed_pair_elem(_Up&& __u)
2187*b5893f02SDimitry Andric      : __value_type(_VSTD::forward<_Up>(__u))
2188*b5893f02SDimitry Andric  {}
2189540d2a8bSDimitry Andric
2190540d2a8bSDimitry Andric  template <class... _Args, size_t... _Indexes>
2191540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
2192540d2a8bSDimitry Andric  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
2193540d2a8bSDimitry Andric                         __tuple_indices<_Indexes...>)
2194540d2a8bSDimitry Andric      : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
2195540d2a8bSDimitry Andric#else
2196b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY __compressed_pair_elem() : __value_type() {}
2197b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2198540d2a8bSDimitry Andric  __compressed_pair_elem(_ParamT __p)
2199540d2a8bSDimitry Andric      : __value_type(std::forward<_ParamT>(__p)) {}
2200540d2a8bSDimitry Andric#endif
2201540d2a8bSDimitry Andric
2202b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
2203b2c7081bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2204540d2a8bSDimitry Andric  const_reference __get() const _NOEXCEPT { return *this; }
2205540d2a8bSDimitry Andric};
2206540d2a8bSDimitry Andric
2207540d2a8bSDimitry Andric// Tag used to construct the second element of the compressed pair.
2208540d2a8bSDimitry Andricstruct __second_tag {};
2209540d2a8bSDimitry Andric
2210540d2a8bSDimitry Andrictemplate <class _T1, class _T2>
2211540d2a8bSDimitry Andricclass __compressed_pair : private __compressed_pair_elem<_T1, 0>,
2212540d2a8bSDimitry Andric                          private __compressed_pair_elem<_T2, 1> {
2213540d2a8bSDimitry Andric  typedef __compressed_pair_elem<_T1, 0> _Base1;
2214540d2a8bSDimitry Andric  typedef __compressed_pair_elem<_T2, 1> _Base2;
2215540d2a8bSDimitry Andric
2216540d2a8bSDimitry Andric  // NOTE: This static assert should never fire because __compressed_pair
2217540d2a8bSDimitry Andric  // is *almost never* used in a scenario where it's possible for T1 == T2.
2218540d2a8bSDimitry Andric  // (The exception is std::function where it is possible that the function
2219540d2a8bSDimitry Andric  //  object and the allocator have the same type).
2220540d2a8bSDimitry Andric  static_assert((!is_same<_T1, _T2>::value),
2221540d2a8bSDimitry Andric    "__compressed_pair cannot be instantated when T1 and T2 are the same type; "
2222540d2a8bSDimitry Andric    "The current implementation is NOT ABI-compatible with the previous "
2223540d2a8bSDimitry Andric    "implementation for this configuration");
2224540d2a8bSDimitry Andric
2225540d2a8bSDimitry Andricpublic:
2226540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2227540d2a8bSDimitry Andric  template <bool _Dummy = true,
2228540d2a8bSDimitry Andric      class = typename enable_if<
2229540d2a8bSDimitry Andric          __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
2230540d2a8bSDimitry Andric          __dependent_type<is_default_constructible<_T2>, _Dummy>::value
2231540d2a8bSDimitry Andric      >::type
223294e3ee44SDavid Chisnall  >
223394e3ee44SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2234540d2a8bSDimitry Andric  constexpr __compressed_pair() {}
223594e3ee44SDavid Chisnall
2236540d2a8bSDimitry Andric  template <class _Tp, typename enable_if<!is_same<typename decay<_Tp>::type,
2237540d2a8bSDimitry Andric                                                   __compressed_pair>::value,
2238540d2a8bSDimitry Andric                                          bool>::type = true>
2239540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr explicit
2240540d2a8bSDimitry Andric  __compressed_pair(_Tp&& __t)
2241540d2a8bSDimitry Andric      : _Base1(std::forward<_Tp>(__t)), _Base2() {}
224294e3ee44SDavid Chisnall
2243540d2a8bSDimitry Andric  template <class _Tp>
2244540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr
2245540d2a8bSDimitry Andric  __compressed_pair(__second_tag, _Tp&& __t)
2246540d2a8bSDimitry Andric      : _Base1(), _Base2(std::forward<_Tp>(__t)) {}
22477a984708SDavid Chisnall
2248540d2a8bSDimitry Andric  template <class _U1, class _U2>
2249540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr
2250540d2a8bSDimitry Andric  __compressed_pair(_U1&& __t1, _U2&& __t2)
2251540d2a8bSDimitry Andric      : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {}
225294e3ee44SDavid Chisnall
225394e3ee44SDavid Chisnall  template <class... _Args1, class... _Args2>
2254540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
225594e3ee44SDavid Chisnall  __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
225694e3ee44SDavid Chisnall                    tuple<_Args2...> __second_args)
2257540d2a8bSDimitry Andric      : _Base1(__pc, _VSTD::move(__first_args),
2258540d2a8bSDimitry Andric               typename __make_tuple_indices<sizeof...(_Args1)>::type()),
2259540d2a8bSDimitry Andric        _Base2(__pc, _VSTD::move(__second_args),
2260540d2a8bSDimitry Andric               typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
226194e3ee44SDavid Chisnall
2262540d2a8bSDimitry Andric#else
2263540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2264540d2a8bSDimitry Andric  __compressed_pair() {}
226594e3ee44SDavid Chisnall
2266540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY explicit
2267540d2a8bSDimitry Andric  __compressed_pair(_T1 __t1) : _Base1(_VSTD::forward<_T1>(__t1)) {}
22687a984708SDavid Chisnall
2269540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2270540d2a8bSDimitry Andric  __compressed_pair(__second_tag, _T2 __t2)
2271540d2a8bSDimitry Andric      : _Base1(), _Base2(_VSTD::forward<_T2>(__t2)) {}
22727a984708SDavid Chisnall
2273540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2274540d2a8bSDimitry Andric  __compressed_pair(_T1 __t1, _T2 __t2)
2275540d2a8bSDimitry Andric      : _Base1(_VSTD::forward<_T1>(__t1)), _Base2(_VSTD::forward<_T2>(__t2)) {}
2276540d2a8bSDimitry Andric#endif
2277540d2a8bSDimitry Andric
2278540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2279540d2a8bSDimitry Andric  typename _Base1::reference first() _NOEXCEPT {
2280540d2a8bSDimitry Andric    return static_cast<_Base1&>(*this).__get();
2281540d2a8bSDimitry Andric  }
2282540d2a8bSDimitry Andric
2283540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2284540d2a8bSDimitry Andric  typename _Base1::const_reference first() const _NOEXCEPT {
2285540d2a8bSDimitry Andric    return static_cast<_Base1 const&>(*this).__get();
2286540d2a8bSDimitry Andric  }
2287540d2a8bSDimitry Andric
2288540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2289540d2a8bSDimitry Andric  typename _Base2::reference second() _NOEXCEPT {
2290540d2a8bSDimitry Andric    return static_cast<_Base2&>(*this).__get();
2291540d2a8bSDimitry Andric  }
2292540d2a8bSDimitry Andric
2293540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2294540d2a8bSDimitry Andric  typename _Base2::const_reference second() const _NOEXCEPT {
2295540d2a8bSDimitry Andric    return static_cast<_Base2 const&>(*this).__get();
2296540d2a8bSDimitry Andric  }
2297540d2a8bSDimitry Andric
2298540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2299540d2a8bSDimitry Andric  void swap(__compressed_pair& __x)
23007a984708SDavid Chisnall    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
2301d72607e9SDimitry Andric               __is_nothrow_swappable<_T2>::value)
2302540d2a8bSDimitry Andric  {
2303540d2a8bSDimitry Andric    using std::swap;
2304540d2a8bSDimitry Andric    swap(first(), __x.first());
2305540d2a8bSDimitry Andric    swap(second(), __x.second());
2306540d2a8bSDimitry Andric  }
23077a984708SDavid Chisnall};
23087a984708SDavid Chisnall
23097a984708SDavid Chisnalltemplate <class _T1, class _T2>
23107a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
2311540d2a8bSDimitry Andricvoid swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
23127a984708SDavid Chisnall    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
2313540d2a8bSDimitry Andric               __is_nothrow_swappable<_T2>::value) {
2314540d2a8bSDimitry Andric  __x.swap(__y);
2315540d2a8bSDimitry Andric}
231694e3ee44SDavid Chisnall
231794e3ee44SDavid Chisnall// default_delete
231894e3ee44SDavid Chisnall
23197a984708SDavid Chisnalltemplate <class _Tp>
2320540d2a8bSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS default_delete {
2321302affcbSDimitry Andric    static_assert(!is_function<_Tp>::value,
2322302affcbSDimitry Andric                  "default_delete cannot be instantiated for function types");
2323aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2324540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() noexcept = default;
2325936e9439SDimitry Andric#else
2326540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY default_delete() {}
2327936e9439SDimitry Andric#endif
23287a984708SDavid Chisnall  template <class _Up>
2329540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2330540d2a8bSDimitry Andric  default_delete(const default_delete<_Up>&,
2331540d2a8bSDimitry Andric                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
2332540d2a8bSDimitry Andric                     0) _NOEXCEPT {}
2333540d2a8bSDimitry Andric
2334540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
2335540d2a8bSDimitry Andric    static_assert(sizeof(_Tp) > 0,
2336540d2a8bSDimitry Andric                  "default_delete can not delete incomplete type");
2337540d2a8bSDimitry Andric    static_assert(!is_void<_Tp>::value,
2338540d2a8bSDimitry Andric                  "default_delete can not delete incomplete type");
23397a984708SDavid Chisnall    delete __ptr;
23407a984708SDavid Chisnall  }
23417a984708SDavid Chisnall};
23427a984708SDavid Chisnall
23437a984708SDavid Chisnalltemplate <class _Tp>
2344540d2a8bSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
2345540d2a8bSDimitry Andricprivate:
2346540d2a8bSDimitry Andric  template <class _Up>
2347540d2a8bSDimitry Andric  struct _EnableIfConvertible
2348540d2a8bSDimitry Andric      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
2349540d2a8bSDimitry Andric
235094e3ee44SDavid Chisnallpublic:
2351aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2352540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() noexcept = default;
2353936e9439SDimitry Andric#else
2354540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY default_delete() {}
2355936e9439SDimitry Andric#endif
2356540d2a8bSDimitry Andric
235794e3ee44SDavid Chisnall  template <class _Up>
235894e3ee44SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2359540d2a8bSDimitry Andric  default_delete(const default_delete<_Up[]>&,
2360540d2a8bSDimitry Andric                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
2361540d2a8bSDimitry Andric
2362540d2a8bSDimitry Andric  template <class _Up>
2363540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2364540d2a8bSDimitry Andric  typename _EnableIfConvertible<_Up>::type
2365540d2a8bSDimitry Andric  operator()(_Up* __ptr) const _NOEXCEPT {
2366540d2a8bSDimitry Andric    static_assert(sizeof(_Tp) > 0,
2367540d2a8bSDimitry Andric                  "default_delete can not delete incomplete type");
2368540d2a8bSDimitry Andric    static_assert(!is_void<_Tp>::value,
2369540d2a8bSDimitry Andric                  "default_delete can not delete void type");
23707a984708SDavid Chisnall    delete[] __ptr;
23717a984708SDavid Chisnall  }
23727a984708SDavid Chisnall};
23737a984708SDavid Chisnall
2374540d2a8bSDimitry Andric
2375540d2a8bSDimitry Andric
2376540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2377540d2a8bSDimitry Andrictemplate <class _Deleter>
2378540d2a8bSDimitry Andricstruct __unique_ptr_deleter_sfinae {
2379540d2a8bSDimitry Andric  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
2380540d2a8bSDimitry Andric  typedef const _Deleter& __lval_ref_type;
2381540d2a8bSDimitry Andric  typedef _Deleter&& __good_rval_ref_type;
2382540d2a8bSDimitry Andric  typedef true_type __enable_rval_overload;
2383540d2a8bSDimitry Andric};
2384540d2a8bSDimitry Andric
2385540d2a8bSDimitry Andrictemplate <class _Deleter>
2386540d2a8bSDimitry Andricstruct __unique_ptr_deleter_sfinae<_Deleter const&> {
2387540d2a8bSDimitry Andric  typedef const _Deleter& __lval_ref_type;
2388540d2a8bSDimitry Andric  typedef const _Deleter&& __bad_rval_ref_type;
2389540d2a8bSDimitry Andric  typedef false_type __enable_rval_overload;
2390540d2a8bSDimitry Andric};
2391540d2a8bSDimitry Andric
2392540d2a8bSDimitry Andrictemplate <class _Deleter>
2393540d2a8bSDimitry Andricstruct __unique_ptr_deleter_sfinae<_Deleter&> {
2394540d2a8bSDimitry Andric  typedef _Deleter& __lval_ref_type;
2395540d2a8bSDimitry Andric  typedef _Deleter&& __bad_rval_ref_type;
2396540d2a8bSDimitry Andric  typedef false_type __enable_rval_overload;
2397540d2a8bSDimitry Andric};
2398540d2a8bSDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG)
2399540d2a8bSDimitry Andric
24007a984708SDavid Chisnalltemplate <class _Tp, class _Dp = default_delete<_Tp> >
2401540d2a8bSDimitry Andricclass _LIBCPP_TEMPLATE_VIS unique_ptr {
24027a984708SDavid Chisnallpublic:
24037a984708SDavid Chisnall  typedef _Tp element_type;
24047a984708SDavid Chisnall  typedef _Dp deleter_type;
24057a984708SDavid Chisnall  typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
2406540d2a8bSDimitry Andric
2407540d2a8bSDimitry Andric  static_assert(!is_rvalue_reference<deleter_type>::value,
2408540d2a8bSDimitry Andric                "the specified deleter type cannot be an rvalue reference");
2409540d2a8bSDimitry Andric
24107a984708SDavid Chisnallprivate:
24117a984708SDavid Chisnall  __compressed_pair<pointer, deleter_type> __ptr_;
24127a984708SDavid Chisnall
24137a984708SDavid Chisnall  struct __nat { int __for_bool_; };
24147a984708SDavid Chisnall
2415540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2416540d2a8bSDimitry Andric  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
24177a984708SDavid Chisnall
2418540d2a8bSDimitry Andric  template <bool _Dummy>
2419540d2a8bSDimitry Andric  using _LValRefType =
2420540d2a8bSDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
2421540d2a8bSDimitry Andric
2422540d2a8bSDimitry Andric  template <bool _Dummy>
2423540d2a8bSDimitry Andric  using _GoodRValRefType =
2424540d2a8bSDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
2425540d2a8bSDimitry Andric
2426540d2a8bSDimitry Andric  template <bool _Dummy>
2427540d2a8bSDimitry Andric  using _BadRValRefType =
2428540d2a8bSDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
2429540d2a8bSDimitry Andric
2430540d2a8bSDimitry Andric  template <bool _Dummy, class _Deleter = typename __dependent_type<
2431540d2a8bSDimitry Andric                             __identity<deleter_type>, _Dummy>::type>
2432540d2a8bSDimitry Andric  using _EnableIfDeleterDefaultConstructible =
2433540d2a8bSDimitry Andric      typename enable_if<is_default_constructible<_Deleter>::value &&
2434540d2a8bSDimitry Andric                         !is_pointer<_Deleter>::value>::type;
2435540d2a8bSDimitry Andric
2436540d2a8bSDimitry Andric  template <class _ArgType>
2437540d2a8bSDimitry Andric  using _EnableIfDeleterConstructible =
2438540d2a8bSDimitry Andric      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
2439540d2a8bSDimitry Andric
2440540d2a8bSDimitry Andric  template <class _UPtr, class _Up>
2441540d2a8bSDimitry Andric  using _EnableIfMoveConvertible = typename enable_if<
2442540d2a8bSDimitry Andric      is_convertible<typename _UPtr::pointer, pointer>::value &&
2443540d2a8bSDimitry Andric      !is_array<_Up>::value
2444540d2a8bSDimitry Andric  >::type;
2445540d2a8bSDimitry Andric
2446540d2a8bSDimitry Andric  template <class _UDel>
2447540d2a8bSDimitry Andric  using _EnableIfDeleterConvertible = typename enable_if<
2448540d2a8bSDimitry Andric      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
2449540d2a8bSDimitry Andric      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
2450540d2a8bSDimitry Andric    >::type;
2451540d2a8bSDimitry Andric
2452540d2a8bSDimitry Andric  template <class _UDel>
2453540d2a8bSDimitry Andric  using _EnableIfDeleterAssignable = typename enable_if<
2454540d2a8bSDimitry Andric      is_assignable<_Dp&, _UDel&&>::value
2455540d2a8bSDimitry Andric    >::type;
2456540d2a8bSDimitry Andric
2457540d2a8bSDimitry Andricpublic:
2458540d2a8bSDimitry Andric  template <bool _Dummy = true,
2459540d2a8bSDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>>
2460540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2461540d2a8bSDimitry Andric  constexpr unique_ptr() noexcept : __ptr_(pointer()) {}
2462540d2a8bSDimitry Andric
2463540d2a8bSDimitry Andric  template <bool _Dummy = true,
2464540d2a8bSDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>>
2465540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2466540d2a8bSDimitry Andric  constexpr unique_ptr(nullptr_t) noexcept : __ptr_(pointer()) {}
2467540d2a8bSDimitry Andric
2468540d2a8bSDimitry Andric  template <bool _Dummy = true,
2469540d2a8bSDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>>
2470540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2471540d2a8bSDimitry Andric  explicit unique_ptr(pointer __p) noexcept : __ptr_(__p) {}
2472540d2a8bSDimitry Andric
2473540d2a8bSDimitry Andric  template <bool _Dummy = true,
2474540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy>>>
2475540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2476540d2a8bSDimitry Andric  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) noexcept
24777a984708SDavid Chisnall      : __ptr_(__p, __d) {}
24787a984708SDavid Chisnall
2479540d2a8bSDimitry Andric  template <bool _Dummy = true,
2480540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy>>>
24817a984708SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2482540d2a8bSDimitry Andric  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) noexcept
2483540d2a8bSDimitry Andric      : __ptr_(__p, _VSTD::move(__d)) {
2484540d2a8bSDimitry Andric    static_assert(!is_reference<deleter_type>::value,
2485540d2a8bSDimitry Andric                  "rvalue deleter bound to reference");
2486540d2a8bSDimitry Andric  }
2487540d2a8bSDimitry Andric
2488540d2a8bSDimitry Andric  template <bool _Dummy = true,
2489540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy>>>
2490540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2491540d2a8bSDimitry Andric  unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
2492540d2a8bSDimitry Andric
2493540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2494540d2a8bSDimitry Andric  unique_ptr(unique_ptr&& __u) noexcept
2495540d2a8bSDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
2496540d2a8bSDimitry Andric  }
2497540d2a8bSDimitry Andric
2498540d2a8bSDimitry Andric  template <class _Up, class _Ep,
2499540d2a8bSDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
2500540d2a8bSDimitry Andric      class = _EnableIfDeleterConvertible<_Ep>
2501540d2a8bSDimitry Andric  >
2502540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2503540d2a8bSDimitry Andric  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
25047a984708SDavid Chisnall      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
25057a984708SDavid Chisnall
2506540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
25077a984708SDavid Chisnall  template <class _Up>
2508540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2509540d2a8bSDimitry Andric  unique_ptr(auto_ptr<_Up>&& __p,
2510540d2a8bSDimitry Andric             typename enable_if<is_convertible<_Up*, _Tp*>::value &&
25117a984708SDavid Chisnall                                    is_same<_Dp, default_delete<_Tp>>::value,
2512540d2a8bSDimitry Andric                                __nat>::type = __nat()) _NOEXCEPT
2513540d2a8bSDimitry Andric      : __ptr_(__p.release()) {}
2514540d2a8bSDimitry Andric#endif
25157a984708SDavid Chisnall
2516540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2517540d2a8bSDimitry Andric  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
25187a984708SDavid Chisnall    reset(__u.release());
25197a984708SDavid Chisnall    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
25207a984708SDavid Chisnall    return *this;
25217a984708SDavid Chisnall  }
25227a984708SDavid Chisnall
2523540d2a8bSDimitry Andric  template <class _Up, class _Ep,
2524540d2a8bSDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
2525540d2a8bSDimitry Andric      class = _EnableIfDeleterAssignable<_Ep>
2526540d2a8bSDimitry Andric  >
25277a984708SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2528540d2a8bSDimitry Andric  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
25297a984708SDavid Chisnall    reset(__u.release());
25307a984708SDavid Chisnall    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
25317a984708SDavid Chisnall    return *this;
25327a984708SDavid Chisnall  }
25337a984708SDavid Chisnall
2534540d2a8bSDimitry Andric#else  // _LIBCPP_CXX03_LANG
2535540d2a8bSDimitry Andricprivate:
2536540d2a8bSDimitry Andric  unique_ptr(unique_ptr&);
2537540d2a8bSDimitry Andric  template <class _Up, class _Ep> unique_ptr(unique_ptr<_Up, _Ep>&);
2538540d2a8bSDimitry Andric
2539540d2a8bSDimitry Andric  unique_ptr& operator=(unique_ptr&);
2540540d2a8bSDimitry Andric  template <class _Up, class _Ep> unique_ptr& operator=(unique_ptr<_Up, _Ep>&);
2541540d2a8bSDimitry Andric
2542540d2a8bSDimitry Andricpublic:
2543540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2544540d2a8bSDimitry Andric  unique_ptr() : __ptr_(pointer())
25457a984708SDavid Chisnall  {
2546540d2a8bSDimitry Andric    static_assert(!is_pointer<deleter_type>::value,
2547540d2a8bSDimitry Andric                  "unique_ptr constructed with null function pointer deleter");
2548540d2a8bSDimitry Andric    static_assert(is_default_constructible<deleter_type>::value,
2549540d2a8bSDimitry Andric                  "unique_ptr::deleter_type is not default constructible");
2550540d2a8bSDimitry Andric  }
2551540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2552540d2a8bSDimitry Andric  unique_ptr(nullptr_t) : __ptr_(pointer())
2553540d2a8bSDimitry Andric  {
2554540d2a8bSDimitry Andric    static_assert(!is_pointer<deleter_type>::value,
2555540d2a8bSDimitry Andric                  "unique_ptr constructed with null function pointer deleter");
2556540d2a8bSDimitry Andric  }
2557540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2558540d2a8bSDimitry Andric  explicit unique_ptr(pointer __p)
2559540d2a8bSDimitry Andric      : __ptr_(_VSTD::move(__p)) {
2560540d2a8bSDimitry Andric    static_assert(!is_pointer<deleter_type>::value,
2561540d2a8bSDimitry Andric                  "unique_ptr constructed with null function pointer deleter");
2562540d2a8bSDimitry Andric  }
2563540d2a8bSDimitry Andric
2564540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2565540d2a8bSDimitry Andric  operator __rv<unique_ptr>() {
25667a984708SDavid Chisnall    return __rv<unique_ptr>(*this);
25677a984708SDavid Chisnall  }
25687a984708SDavid Chisnall
2569540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2570540d2a8bSDimitry Andric  unique_ptr(__rv<unique_ptr> __u)
2571540d2a8bSDimitry Andric      : __ptr_(__u->release(),
2572540d2a8bSDimitry Andric               _VSTD::forward<deleter_type>(__u->get_deleter())) {}
25737a984708SDavid Chisnall
25747a984708SDavid Chisnall  template <class _Up, class _Ep>
25759729cf09SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25769729cf09SDimitry Andric  typename enable_if<
25779729cf09SDimitry Andric      !is_array<_Up>::value &&
2578540d2a8bSDimitry Andric          is_convertible<typename unique_ptr<_Up, _Ep>::pointer,
2579540d2a8bSDimitry Andric                         pointer>::value &&
25809729cf09SDimitry Andric          is_assignable<deleter_type&, _Ep&>::value,
2581540d2a8bSDimitry Andric      unique_ptr&>::type
2582540d2a8bSDimitry Andric  operator=(unique_ptr<_Up, _Ep> __u) {
25837a984708SDavid Chisnall    reset(__u.release());
25849729cf09SDimitry Andric    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
25857a984708SDavid Chisnall    return *this;
25867a984708SDavid Chisnall  }
25877a984708SDavid Chisnall
2588540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2589540d2a8bSDimitry Andric  unique_ptr(pointer __p, deleter_type __d)
25907a984708SDavid Chisnall      : __ptr_(_VSTD::move(__p), _VSTD::move(__d)) {}
2591540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG
25927a984708SDavid Chisnall
2593540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
25947a984708SDavid Chisnall  template <class _Up>
25957a984708SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2596540d2a8bSDimitry Andric      typename enable_if<is_convertible<_Up*, _Tp*>::value &&
25977a984708SDavid Chisnall                             is_same<_Dp, default_delete<_Tp> >::value,
2598540d2a8bSDimitry Andric                         unique_ptr&>::type
2599540d2a8bSDimitry Andric      operator=(auto_ptr<_Up> __p) {
2600540d2a8bSDimitry Andric    reset(__p.release());
2601540d2a8bSDimitry Andric    return *this;
2602540d2a8bSDimitry Andric  }
2603540d2a8bSDimitry Andric#endif
26047a984708SDavid Chisnall
2605540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2606540d2a8bSDimitry Andric  ~unique_ptr() { reset(); }
26077a984708SDavid Chisnall
2608540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2609540d2a8bSDimitry Andric  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
26107a984708SDavid Chisnall    reset();
26117a984708SDavid Chisnall    return *this;
26127a984708SDavid Chisnall  }
26137a984708SDavid Chisnall
261494e3ee44SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2615540d2a8bSDimitry Andric  typename add_lvalue_reference<_Tp>::type
2616540d2a8bSDimitry Andric  operator*() const {
2617540d2a8bSDimitry Andric    return *__ptr_.first();
2618540d2a8bSDimitry Andric  }
2619540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2620540d2a8bSDimitry Andric  pointer operator->() const _NOEXCEPT {
2621540d2a8bSDimitry Andric    return __ptr_.first();
2622540d2a8bSDimitry Andric  }
2623540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2624540d2a8bSDimitry Andric  pointer get() const _NOEXCEPT {
2625540d2a8bSDimitry Andric    return __ptr_.first();
2626540d2a8bSDimitry Andric  }
2627540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2628540d2a8bSDimitry Andric  deleter_type& get_deleter() _NOEXCEPT {
2629540d2a8bSDimitry Andric    return __ptr_.second();
2630540d2a8bSDimitry Andric  }
2631540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2632540d2a8bSDimitry Andric  const deleter_type& get_deleter() const _NOEXCEPT {
2633540d2a8bSDimitry Andric    return __ptr_.second();
2634540d2a8bSDimitry Andric  }
2635540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2636540d2a8bSDimitry Andric  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
2637540d2a8bSDimitry Andric    return __ptr_.first() != nullptr;
2638540d2a8bSDimitry Andric  }
26397a984708SDavid Chisnall
2640540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2641540d2a8bSDimitry Andric  pointer release() _NOEXCEPT {
26427a984708SDavid Chisnall    pointer __t = __ptr_.first();
26437a984708SDavid Chisnall    __ptr_.first() = pointer();
26447a984708SDavid Chisnall    return __t;
26457a984708SDavid Chisnall  }
26467a984708SDavid Chisnall
2647540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2648540d2a8bSDimitry Andric  void reset(pointer __p = pointer()) _NOEXCEPT {
26497a984708SDavid Chisnall    pointer __tmp = __ptr_.first();
26507a984708SDavid Chisnall    __ptr_.first() = __p;
26517a984708SDavid Chisnall    if (__tmp)
26527a984708SDavid Chisnall      __ptr_.second()(__tmp);
26537a984708SDavid Chisnall  }
26547a984708SDavid Chisnall
2655540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2656540d2a8bSDimitry Andric  void swap(unique_ptr& __u) _NOEXCEPT {
2657540d2a8bSDimitry Andric    __ptr_.swap(__u.__ptr_);
2658540d2a8bSDimitry Andric  }
26597a984708SDavid Chisnall};
26607a984708SDavid Chisnall
2661540d2a8bSDimitry Andric
26627a984708SDavid Chisnalltemplate <class _Tp, class _Dp>
2663540d2a8bSDimitry Andricclass _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
26647a984708SDavid Chisnallpublic:
26657a984708SDavid Chisnall  typedef _Tp element_type;
26667a984708SDavid Chisnall  typedef _Dp deleter_type;
26677a984708SDavid Chisnall  typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
2668540d2a8bSDimitry Andric
26697a984708SDavid Chisnallprivate:
26707a984708SDavid Chisnall  __compressed_pair<pointer, deleter_type> __ptr_;
26717a984708SDavid Chisnall
2672540d2a8bSDimitry Andric  template <class _From>
2673540d2a8bSDimitry Andric  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
26747a984708SDavid Chisnall
2675540d2a8bSDimitry Andric  template <class _FromElem>
2676540d2a8bSDimitry Andric  struct _CheckArrayPointerConversion<_FromElem*>
2677540d2a8bSDimitry Andric      : integral_constant<bool,
2678540d2a8bSDimitry Andric          is_same<_FromElem*, pointer>::value ||
2679540d2a8bSDimitry Andric            (is_same<pointer, element_type*>::value &&
2680540d2a8bSDimitry Andric             is_convertible<_FromElem(*)[], element_type(*)[]>::value)
2681540d2a8bSDimitry Andric      >
2682540d2a8bSDimitry Andric  {};
26837a984708SDavid Chisnall
2684540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2685540d2a8bSDimitry Andric  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
2686540d2a8bSDimitry Andric
2687540d2a8bSDimitry Andric  template <bool _Dummy>
2688540d2a8bSDimitry Andric  using _LValRefType =
2689540d2a8bSDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
2690540d2a8bSDimitry Andric
2691540d2a8bSDimitry Andric  template <bool _Dummy>
2692540d2a8bSDimitry Andric  using _GoodRValRefType =
2693540d2a8bSDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
2694540d2a8bSDimitry Andric
2695540d2a8bSDimitry Andric  template <bool _Dummy>
2696540d2a8bSDimitry Andric  using _BadRValRefType =
2697540d2a8bSDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
2698540d2a8bSDimitry Andric
2699540d2a8bSDimitry Andric  template <bool _Dummy, class _Deleter = typename __dependent_type<
2700540d2a8bSDimitry Andric                             __identity<deleter_type>, _Dummy>::type>
2701540d2a8bSDimitry Andric  using _EnableIfDeleterDefaultConstructible =
2702540d2a8bSDimitry Andric      typename enable_if<is_default_constructible<_Deleter>::value &&
2703540d2a8bSDimitry Andric                         !is_pointer<_Deleter>::value>::type;
2704540d2a8bSDimitry Andric
2705540d2a8bSDimitry Andric  template <class _ArgType>
2706540d2a8bSDimitry Andric  using _EnableIfDeleterConstructible =
2707540d2a8bSDimitry Andric      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
2708540d2a8bSDimitry Andric
2709540d2a8bSDimitry Andric  template <class _Pp>
2710540d2a8bSDimitry Andric  using _EnableIfPointerConvertible = typename enable_if<
2711540d2a8bSDimitry Andric      _CheckArrayPointerConversion<_Pp>::value
2712540d2a8bSDimitry Andric  >::type;
2713540d2a8bSDimitry Andric
2714540d2a8bSDimitry Andric  template <class _UPtr, class _Up,
2715540d2a8bSDimitry Andric        class _ElemT = typename _UPtr::element_type>
2716540d2a8bSDimitry Andric  using _EnableIfMoveConvertible = typename enable_if<
2717540d2a8bSDimitry Andric      is_array<_Up>::value &&
2718540d2a8bSDimitry Andric      is_same<pointer, element_type*>::value &&
2719540d2a8bSDimitry Andric      is_same<typename _UPtr::pointer, _ElemT*>::value &&
2720540d2a8bSDimitry Andric      is_convertible<_ElemT(*)[], element_type(*)[]>::value
2721540d2a8bSDimitry Andric    >::type;
2722540d2a8bSDimitry Andric
2723540d2a8bSDimitry Andric  template <class _UDel>
2724540d2a8bSDimitry Andric  using _EnableIfDeleterConvertible = typename enable_if<
2725540d2a8bSDimitry Andric      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
2726540d2a8bSDimitry Andric      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
2727540d2a8bSDimitry Andric    >::type;
2728540d2a8bSDimitry Andric
2729540d2a8bSDimitry Andric  template <class _UDel>
2730540d2a8bSDimitry Andric  using _EnableIfDeleterAssignable = typename enable_if<
2731540d2a8bSDimitry Andric      is_assignable<_Dp&, _UDel&&>::value
2732540d2a8bSDimitry Andric    >::type;
2733540d2a8bSDimitry Andric
27347a984708SDavid Chisnallpublic:
2735540d2a8bSDimitry Andric  template <bool _Dummy = true,
2736540d2a8bSDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>>
2737540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2738540d2a8bSDimitry Andric  constexpr unique_ptr() noexcept : __ptr_(pointer()) {}
27397a984708SDavid Chisnall
2740540d2a8bSDimitry Andric  template <bool _Dummy = true,
2741540d2a8bSDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>>
2742540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2743540d2a8bSDimitry Andric  constexpr unique_ptr(nullptr_t) noexcept : __ptr_(pointer()) {}
2744540d2a8bSDimitry Andric
2745540d2a8bSDimitry Andric  template <class _Pp, bool _Dummy = true,
2746540d2a8bSDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
2747540d2a8bSDimitry Andric            class = _EnableIfPointerConvertible<_Pp>>
2748540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2749540d2a8bSDimitry Andric  explicit unique_ptr(_Pp __p) noexcept
2750540d2a8bSDimitry Andric      : __ptr_(__p) {}
2751540d2a8bSDimitry Andric
2752540d2a8bSDimitry Andric  template <class _Pp, bool _Dummy = true,
2753540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy>>,
2754540d2a8bSDimitry Andric            class = _EnableIfPointerConvertible<_Pp>>
2755540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2756540d2a8bSDimitry Andric  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) noexcept
27577a984708SDavid Chisnall      : __ptr_(__p, __d) {}
27587a984708SDavid Chisnall
2759540d2a8bSDimitry Andric  template <bool _Dummy = true,
2760540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy>>>
2761540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2762540d2a8bSDimitry Andric  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) noexcept
2763540d2a8bSDimitry Andric      : __ptr_(nullptr, __d) {}
27647a984708SDavid Chisnall
2765540d2a8bSDimitry Andric  template <class _Pp, bool _Dummy = true,
2766540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy>>,
2767540d2a8bSDimitry Andric            class = _EnableIfPointerConvertible<_Pp>>
2768540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2769540d2a8bSDimitry Andric  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) noexcept
2770540d2a8bSDimitry Andric      : __ptr_(__p, _VSTD::move(__d)) {
2771540d2a8bSDimitry Andric    static_assert(!is_reference<deleter_type>::value,
2772540d2a8bSDimitry Andric                  "rvalue deleter bound to reference");
27737a984708SDavid Chisnall  }
27747a984708SDavid Chisnall
2775540d2a8bSDimitry Andric  template <bool _Dummy = true,
2776540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy>>>
2777540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2778540d2a8bSDimitry Andric  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) noexcept
2779540d2a8bSDimitry Andric      : __ptr_(nullptr, _VSTD::move(__d)) {
2780540d2a8bSDimitry Andric    static_assert(!is_reference<deleter_type>::value,
2781540d2a8bSDimitry Andric                  "rvalue deleter bound to reference");
27827a984708SDavid Chisnall  }
27837a984708SDavid Chisnall
2784540d2a8bSDimitry Andric  template <class _Pp, bool _Dummy = true,
2785540d2a8bSDimitry Andric            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy>>,
2786540d2a8bSDimitry Andric            class = _EnableIfPointerConvertible<_Pp>>
2787540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2788540d2a8bSDimitry Andric  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
27897a984708SDavid Chisnall
2790540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2791540d2a8bSDimitry Andric  unique_ptr(unique_ptr&& __u) noexcept
2792540d2a8bSDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
2793540d2a8bSDimitry Andric  }
2794540d2a8bSDimitry Andric
2795540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2796540d2a8bSDimitry Andric  unique_ptr& operator=(unique_ptr&& __u) noexcept {
27977a984708SDavid Chisnall    reset(__u.release());
27987a984708SDavid Chisnall    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
27997a984708SDavid Chisnall    return *this;
28007a984708SDavid Chisnall  }
280194e3ee44SDavid Chisnall
2802540d2a8bSDimitry Andric  template <class _Up, class _Ep,
2803540d2a8bSDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
2804540d2a8bSDimitry Andric      class = _EnableIfDeleterConvertible<_Ep>
2805540d2a8bSDimitry Andric  >
280694e3ee44SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2807540d2a8bSDimitry Andric  unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
2808540d2a8bSDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
2809540d2a8bSDimitry Andric  }
281094e3ee44SDavid Chisnall
2811540d2a8bSDimitry Andric  template <class _Up, class _Ep,
2812540d2a8bSDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
2813540d2a8bSDimitry Andric      class = _EnableIfDeleterAssignable<_Ep>
2814540d2a8bSDimitry Andric  >
281594e3ee44SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
281694e3ee44SDavid Chisnall  unique_ptr&
2817540d2a8bSDimitry Andric  operator=(unique_ptr<_Up, _Ep>&& __u) noexcept {
281894e3ee44SDavid Chisnall    reset(__u.release());
281994e3ee44SDavid Chisnall    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
282094e3ee44SDavid Chisnall    return *this;
282194e3ee44SDavid Chisnall  }
28227a984708SDavid Chisnall
2823540d2a8bSDimitry Andric#else // _LIBCPP_CXX03_LANG
2824540d2a8bSDimitry Andricprivate:
2825540d2a8bSDimitry Andric  template <class _Up> explicit unique_ptr(_Up);
2826540d2a8bSDimitry Andric
2827540d2a8bSDimitry Andric  unique_ptr(unique_ptr&);
2828540d2a8bSDimitry Andric  template <class _Up> unique_ptr(unique_ptr<_Up>&);
2829540d2a8bSDimitry Andric
2830540d2a8bSDimitry Andric  unique_ptr& operator=(unique_ptr&);
2831540d2a8bSDimitry Andric  template <class _Up> unique_ptr& operator=(unique_ptr<_Up>&);
2832540d2a8bSDimitry Andric
2833540d2a8bSDimitry Andric  template <class _Up>
2834540d2a8bSDimitry Andric  unique_ptr(_Up __u,
2835540d2a8bSDimitry Andric             typename conditional<
2836540d2a8bSDimitry Andric                 is_reference<deleter_type>::value, deleter_type,
2837540d2a8bSDimitry Andric                 typename add_lvalue_reference<const deleter_type>::type>::type,
2838540d2a8bSDimitry Andric             typename enable_if<is_convertible<_Up, pointer>::value,
2839540d2a8bSDimitry Andric                                __nat>::type = __nat());
2840540d2a8bSDimitry Andricpublic:
2841540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2842540d2a8bSDimitry Andric  unique_ptr() : __ptr_(pointer()) {
2843540d2a8bSDimitry Andric    static_assert(!is_pointer<deleter_type>::value,
2844540d2a8bSDimitry Andric                  "unique_ptr constructed with null function pointer deleter");
2845540d2a8bSDimitry Andric  }
2846540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2847540d2a8bSDimitry Andric  unique_ptr(nullptr_t) : __ptr_(pointer()) {
28487a984708SDavid Chisnall    static_assert(!is_pointer<deleter_type>::value,
28497a984708SDavid Chisnall                  "unique_ptr constructed with null function pointer deleter");
28507a984708SDavid Chisnall  }
28517a984708SDavid Chisnall
2852540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2853540d2a8bSDimitry Andric  explicit unique_ptr(pointer __p) : __ptr_(__p) {
2854540d2a8bSDimitry Andric    static_assert(!is_pointer<deleter_type>::value,
2855540d2a8bSDimitry Andric                  "unique_ptr constructed with null function pointer deleter");
2856540d2a8bSDimitry Andric  }
2857540d2a8bSDimitry Andric
2858540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2859540d2a8bSDimitry Andric  unique_ptr(pointer __p, deleter_type __d)
28607a984708SDavid Chisnall      : __ptr_(__p, _VSTD::forward<deleter_type>(__d)) {}
28617a984708SDavid Chisnall
2862540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2863540d2a8bSDimitry Andric  unique_ptr(nullptr_t, deleter_type __d)
28647a984708SDavid Chisnall      : __ptr_(pointer(), _VSTD::forward<deleter_type>(__d)) {}
28657a984708SDavid Chisnall
2866540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2867540d2a8bSDimitry Andric  operator __rv<unique_ptr>() {
28687a984708SDavid Chisnall    return __rv<unique_ptr>(*this);
28697a984708SDavid Chisnall  }
28707a984708SDavid Chisnall
2871540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2872540d2a8bSDimitry Andric  unique_ptr(__rv<unique_ptr> __u)
2873540d2a8bSDimitry Andric      : __ptr_(__u->release(),
2874540d2a8bSDimitry Andric               _VSTD::forward<deleter_type>(__u->get_deleter())) {}
28757a984708SDavid Chisnall
2876540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2877540d2a8bSDimitry Andric  unique_ptr& operator=(__rv<unique_ptr> __u) {
28787a984708SDavid Chisnall    reset(__u->release());
28797a984708SDavid Chisnall    __ptr_.second() = _VSTD::forward<deleter_type>(__u->get_deleter());
28807a984708SDavid Chisnall    return *this;
28817a984708SDavid Chisnall  }
28827a984708SDavid Chisnall
2883540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG
28847a984708SDavid Chisnall
2885540d2a8bSDimitry Andricpublic:
2886540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2887540d2a8bSDimitry Andric  ~unique_ptr() { reset(); }
2888540d2a8bSDimitry Andric
2889540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2890540d2a8bSDimitry Andric  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
28917a984708SDavid Chisnall    reset();
28927a984708SDavid Chisnall    return *this;
28937a984708SDavid Chisnall  }
28947a984708SDavid Chisnall
289594e3ee44SDavid Chisnall  _LIBCPP_INLINE_VISIBILITY
2896540d2a8bSDimitry Andric  typename add_lvalue_reference<_Tp>::type
2897540d2a8bSDimitry Andric  operator[](size_t __i) const {
2898540d2a8bSDimitry Andric    return __ptr_.first()[__i];
2899540d2a8bSDimitry Andric  }
2900540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2901540d2a8bSDimitry Andric  pointer get() const _NOEXCEPT {
2902540d2a8bSDimitry Andric    return __ptr_.first();
2903540d2a8bSDimitry Andric  }
29047a984708SDavid Chisnall
2905540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2906540d2a8bSDimitry Andric  deleter_type& get_deleter() _NOEXCEPT {
2907540d2a8bSDimitry Andric    return __ptr_.second();
2908540d2a8bSDimitry Andric  }
2909540d2a8bSDimitry Andric
2910540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2911540d2a8bSDimitry Andric  const deleter_type& get_deleter() const _NOEXCEPT {
2912540d2a8bSDimitry Andric    return __ptr_.second();
2913540d2a8bSDimitry Andric  }
2914540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2915540d2a8bSDimitry Andric  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
2916540d2a8bSDimitry Andric    return __ptr_.first() != nullptr;
2917540d2a8bSDimitry Andric  }
2918540d2a8bSDimitry Andric
2919540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2920540d2a8bSDimitry Andric  pointer release() _NOEXCEPT {
29217a984708SDavid Chisnall    pointer __t = __ptr_.first();
29227a984708SDavid Chisnall    __ptr_.first() = pointer();
29237a984708SDavid Chisnall    return __t;
29247a984708SDavid Chisnall  }
29257a984708SDavid Chisnall
2926d72607e9SDimitry Andric  template <class _Pp>
2927d72607e9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2928540d2a8bSDimitry Andric  typename enable_if<
2929540d2a8bSDimitry Andric      _CheckArrayPointerConversion<_Pp>::value
2930540d2a8bSDimitry Andric  >::type
2931540d2a8bSDimitry Andric  reset(_Pp __p) _NOEXCEPT {
29327a984708SDavid Chisnall    pointer __tmp = __ptr_.first();
29337a984708SDavid Chisnall    __ptr_.first() = __p;
29347a984708SDavid Chisnall    if (__tmp)
29357a984708SDavid Chisnall      __ptr_.second()(__tmp);
29367a984708SDavid Chisnall  }
2937540d2a8bSDimitry Andric
2938540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2939540d2a8bSDimitry Andric  void reset(nullptr_t = nullptr) _NOEXCEPT {
29407a984708SDavid Chisnall    pointer __tmp = __ptr_.first();
29417a984708SDavid Chisnall    __ptr_.first() = nullptr;
29427a984708SDavid Chisnall    if (__tmp)
29437a984708SDavid Chisnall      __ptr_.second()(__tmp);
29447a984708SDavid Chisnall  }
29457a984708SDavid Chisnall
2946540d2a8bSDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2947540d2a8bSDimitry Andric  void swap(unique_ptr& __u) _NOEXCEPT {
2948540d2a8bSDimitry Andric    __ptr_.swap(__u.__ptr_);
2949540d2a8bSDimitry Andric  }
29507a984708SDavid Chisnall
29517a984708SDavid Chisnall};
29527a984708SDavid Chisnall
29537a984708SDavid Chisnalltemplate <class _Tp, class _Dp>
29547a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
29557c82a1ecSDimitry Andrictypename enable_if<
29567c82a1ecSDimitry Andric    __is_swappable<_Dp>::value,
29577a984708SDavid Chisnall    void
29587c82a1ecSDimitry Andric>::type
29597a984708SDavid Chisnallswap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
29607a984708SDavid Chisnall
29617a984708SDavid Chisnalltemplate <class _T1, class _D1, class _T2, class _D2>
29627a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
29637a984708SDavid Chisnallbool
29647a984708SDavid Chisnalloperator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
29657a984708SDavid Chisnall
29667a984708SDavid Chisnalltemplate <class _T1, class _D1, class _T2, class _D2>
29677a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
29687a984708SDavid Chisnallbool
29697a984708SDavid Chisnalloperator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
29707a984708SDavid Chisnall
29717a984708SDavid Chisnalltemplate <class _T1, class _D1, class _T2, class _D2>
29727a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
29737a984708SDavid Chisnallbool
297494e3ee44SDavid Chisnalloperator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
297594e3ee44SDavid Chisnall{
297694e3ee44SDavid Chisnall    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
297794e3ee44SDavid Chisnall    typedef typename unique_ptr<_T2, _D2>::pointer _P2;
2978854fa44bSDimitry Andric    typedef typename common_type<_P1, _P2>::type _Vp;
2979854fa44bSDimitry Andric    return less<_Vp>()(__x.get(), __y.get());
298094e3ee44SDavid Chisnall}
29817a984708SDavid Chisnall
29827a984708SDavid Chisnalltemplate <class _T1, class _D1, class _T2, class _D2>
29837a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
29847a984708SDavid Chisnallbool
29857a984708SDavid Chisnalloperator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
29867a984708SDavid Chisnall
29877a984708SDavid Chisnalltemplate <class _T1, class _D1, class _T2, class _D2>
29887a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
29897a984708SDavid Chisnallbool
29907a984708SDavid Chisnalloperator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
29917a984708SDavid Chisnall
29927a984708SDavid Chisnalltemplate <class _T1, class _D1, class _T2, class _D2>
29937a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
29947a984708SDavid Chisnallbool
29957a984708SDavid Chisnalloperator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
29967a984708SDavid Chisnall
299794e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
299894e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
299994e3ee44SDavid Chisnallbool
3000936e9439SDimitry Andricoperator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
300194e3ee44SDavid Chisnall{
300294e3ee44SDavid Chisnall    return !__x;
300394e3ee44SDavid Chisnall}
300494e3ee44SDavid Chisnall
300594e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
300694e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
300794e3ee44SDavid Chisnallbool
3008936e9439SDimitry Andricoperator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
300994e3ee44SDavid Chisnall{
301094e3ee44SDavid Chisnall    return !__x;
301194e3ee44SDavid Chisnall}
301294e3ee44SDavid Chisnall
301394e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
301494e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
301594e3ee44SDavid Chisnallbool
3016936e9439SDimitry Andricoperator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
301794e3ee44SDavid Chisnall{
301894e3ee44SDavid Chisnall    return static_cast<bool>(__x);
301994e3ee44SDavid Chisnall}
302094e3ee44SDavid Chisnall
302194e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
302294e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
302394e3ee44SDavid Chisnallbool
3024936e9439SDimitry Andricoperator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
302594e3ee44SDavid Chisnall{
302694e3ee44SDavid Chisnall    return static_cast<bool>(__x);
302794e3ee44SDavid Chisnall}
302894e3ee44SDavid Chisnall
302994e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
303094e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
303194e3ee44SDavid Chisnallbool
303294e3ee44SDavid Chisnalloperator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
303394e3ee44SDavid Chisnall{
303494e3ee44SDavid Chisnall    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
303594e3ee44SDavid Chisnall    return less<_P1>()(__x.get(), nullptr);
303694e3ee44SDavid Chisnall}
303794e3ee44SDavid Chisnall
303894e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
303994e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
304094e3ee44SDavid Chisnallbool
304194e3ee44SDavid Chisnalloperator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
304294e3ee44SDavid Chisnall{
304394e3ee44SDavid Chisnall    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
304494e3ee44SDavid Chisnall    return less<_P1>()(nullptr, __x.get());
304594e3ee44SDavid Chisnall}
304694e3ee44SDavid Chisnall
304794e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
304894e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
304994e3ee44SDavid Chisnallbool
305094e3ee44SDavid Chisnalloperator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
305194e3ee44SDavid Chisnall{
305294e3ee44SDavid Chisnall    return nullptr < __x;
305394e3ee44SDavid Chisnall}
305494e3ee44SDavid Chisnall
305594e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
305694e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
305794e3ee44SDavid Chisnallbool
305894e3ee44SDavid Chisnalloperator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
305994e3ee44SDavid Chisnall{
306094e3ee44SDavid Chisnall    return __x < nullptr;
306194e3ee44SDavid Chisnall}
306294e3ee44SDavid Chisnall
306394e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
306494e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
306594e3ee44SDavid Chisnallbool
306694e3ee44SDavid Chisnalloperator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
306794e3ee44SDavid Chisnall{
306894e3ee44SDavid Chisnall    return !(nullptr < __x);
306994e3ee44SDavid Chisnall}
307094e3ee44SDavid Chisnall
307194e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
307294e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
307394e3ee44SDavid Chisnallbool
307494e3ee44SDavid Chisnalloperator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
307594e3ee44SDavid Chisnall{
307694e3ee44SDavid Chisnall    return !(__x < nullptr);
307794e3ee44SDavid Chisnall}
307894e3ee44SDavid Chisnall
307994e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
308094e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
308194e3ee44SDavid Chisnallbool
308294e3ee44SDavid Chisnalloperator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
308394e3ee44SDavid Chisnall{
308494e3ee44SDavid Chisnall    return !(__x < nullptr);
308594e3ee44SDavid Chisnall}
308694e3ee44SDavid Chisnall
308794e3ee44SDavid Chisnalltemplate <class _T1, class _D1>
308894e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
308994e3ee44SDavid Chisnallbool
309094e3ee44SDavid Chisnalloperator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
309194e3ee44SDavid Chisnall{
309294e3ee44SDavid Chisnall    return !(nullptr < __x);
309394e3ee44SDavid Chisnall}
309494e3ee44SDavid Chisnall
3095b03f91a8SDavid Chisnall#ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3096b03f91a8SDavid Chisnall
3097b03f91a8SDavid Chisnalltemplate <class _Tp, class _Dp>
3098b03f91a8SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
3099b03f91a8SDavid Chisnallunique_ptr<_Tp, _Dp>
3100b03f91a8SDavid Chisnallmove(unique_ptr<_Tp, _Dp>& __t)
3101b03f91a8SDavid Chisnall{
3102b03f91a8SDavid Chisnall    return unique_ptr<_Tp, _Dp>(__rv<unique_ptr<_Tp, _Dp> >(__t));
3103b03f91a8SDavid Chisnall}
3104b03f91a8SDavid Chisnall
3105b03f91a8SDavid Chisnall#endif
3106b03f91a8SDavid Chisnall
31074bab9fd9SDavid Chisnall#if _LIBCPP_STD_VER > 11
31084bab9fd9SDavid Chisnall
31094bab9fd9SDavid Chisnalltemplate<class _Tp>
31104bab9fd9SDavid Chisnallstruct __unique_if
31114bab9fd9SDavid Chisnall{
31124bab9fd9SDavid Chisnall    typedef unique_ptr<_Tp> __unique_single;
31134bab9fd9SDavid Chisnall};
31144bab9fd9SDavid Chisnall
31154bab9fd9SDavid Chisnalltemplate<class _Tp>
31164bab9fd9SDavid Chisnallstruct __unique_if<_Tp[]>
31174bab9fd9SDavid Chisnall{
31184bab9fd9SDavid Chisnall    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
31194bab9fd9SDavid Chisnall};
31204bab9fd9SDavid Chisnall
31214bab9fd9SDavid Chisnalltemplate<class _Tp, size_t _Np>
31224bab9fd9SDavid Chisnallstruct __unique_if<_Tp[_Np]>
31234bab9fd9SDavid Chisnall{
31244bab9fd9SDavid Chisnall    typedef void __unique_array_known_bound;
31254bab9fd9SDavid Chisnall};
31264bab9fd9SDavid Chisnall
31274bab9fd9SDavid Chisnalltemplate<class _Tp, class... _Args>
31284bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
31294bab9fd9SDavid Chisnalltypename __unique_if<_Tp>::__unique_single
31304bab9fd9SDavid Chisnallmake_unique(_Args&&... __args)
31314bab9fd9SDavid Chisnall{
31324bab9fd9SDavid Chisnall    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
31334bab9fd9SDavid Chisnall}
31344bab9fd9SDavid Chisnall
31354bab9fd9SDavid Chisnalltemplate<class _Tp>
31364bab9fd9SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
31374bab9fd9SDavid Chisnalltypename __unique_if<_Tp>::__unique_array_unknown_bound
31384bab9fd9SDavid Chisnallmake_unique(size_t __n)
31394bab9fd9SDavid Chisnall{
31404bab9fd9SDavid Chisnall    typedef typename remove_extent<_Tp>::type _Up;
31414bab9fd9SDavid Chisnall    return unique_ptr<_Tp>(new _Up[__n]());
31424bab9fd9SDavid Chisnall}
31434bab9fd9SDavid Chisnall
31444bab9fd9SDavid Chisnalltemplate<class _Tp, class... _Args>
31454bab9fd9SDavid Chisnall    typename __unique_if<_Tp>::__unique_array_known_bound
31464bab9fd9SDavid Chisnall    make_unique(_Args&&...) = delete;
31474bab9fd9SDavid Chisnall
31484bab9fd9SDavid Chisnall#endif  // _LIBCPP_STD_VER > 11
31494bab9fd9SDavid Chisnall
31507a984708SDavid Chisnalltemplate <class _Tp, class _Dp>
3151540d2a8bSDimitry Andric#ifdef _LIBCPP_CXX03_LANG
3152aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
3153540d2a8bSDimitry Andric#else
3154540d2a8bSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
3155540d2a8bSDimitry Andric    unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer>>
3156540d2a8bSDimitry Andric#endif
31577a984708SDavid Chisnall{
31587a984708SDavid Chisnall    typedef unique_ptr<_Tp, _Dp> argument_type;
31597a984708SDavid Chisnall    typedef size_t               result_type;
31607a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3161540d2a8bSDimitry Andric    result_type operator()(const argument_type& __ptr) const
31627a984708SDavid Chisnall    {
31637a984708SDavid Chisnall        typedef typename argument_type::pointer pointer;
31647a984708SDavid Chisnall        return hash<pointer>()(__ptr.get());
31657a984708SDavid Chisnall    }
31667a984708SDavid Chisnall};
31677a984708SDavid Chisnall
31687a984708SDavid Chisnallstruct __destruct_n
31697a984708SDavid Chisnall{
31707a984708SDavid Chisnallprivate:
3171f9448bf3SDimitry Andric    size_t __size_;
31727a984708SDavid Chisnall
31737a984708SDavid Chisnall    template <class _Tp>
31747a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
3175f9448bf3SDimitry Andric        {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
31767a984708SDavid Chisnall
31777a984708SDavid Chisnall    template <class _Tp>
31787a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
31797a984708SDavid Chisnall        {}
31807a984708SDavid Chisnall
31817a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
3182f9448bf3SDimitry Andric        {++__size_;}
31837a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
31847a984708SDavid Chisnall        {}
31857a984708SDavid Chisnall
31867a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
3187f9448bf3SDimitry Andric        {__size_ = __s;}
31887a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
31897a984708SDavid Chisnall        {}
31907a984708SDavid Chisnallpublic:
31917a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
3192f9448bf3SDimitry Andric        : __size_(__s) {}
31937a984708SDavid Chisnall
31947a984708SDavid Chisnall    template <class _Tp>
31957a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __incr(_Tp*) _NOEXCEPT
31967a984708SDavid Chisnall        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
31977a984708SDavid Chisnall
31987a984708SDavid Chisnall    template <class _Tp>
31997a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
32007a984708SDavid Chisnall        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
32017a984708SDavid Chisnall
32027a984708SDavid Chisnall    template <class _Tp>
32037a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
32047a984708SDavid Chisnall        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
32057a984708SDavid Chisnall};
32067a984708SDavid Chisnall
32077a984708SDavid Chisnalltemplate <class _Alloc>
32087a984708SDavid Chisnallclass __allocator_destructor
32097a984708SDavid Chisnall{
32107a984708SDavid Chisnall    typedef allocator_traits<_Alloc> __alloc_traits;
32117a984708SDavid Chisnallpublic:
32127a984708SDavid Chisnall    typedef typename __alloc_traits::pointer pointer;
32137a984708SDavid Chisnall    typedef typename __alloc_traits::size_type size_type;
32147a984708SDavid Chisnallprivate:
32157a984708SDavid Chisnall    _Alloc& __alloc_;
32167a984708SDavid Chisnall    size_type __s_;
32177a984708SDavid Chisnallpublic:
32187a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
32197a984708SDavid Chisnall             _NOEXCEPT
32207a984708SDavid Chisnall        : __alloc_(__a), __s_(__s) {}
32217a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
32227a984708SDavid Chisnall    void operator()(pointer __p) _NOEXCEPT
32237a984708SDavid Chisnall        {__alloc_traits::deallocate(__alloc_, __p, __s_);}
32247a984708SDavid Chisnall};
32257a984708SDavid Chisnall
32267a984708SDavid Chisnalltemplate <class _InputIterator, class _ForwardIterator>
32277a984708SDavid Chisnall_ForwardIterator
32287a984708SDavid Chisnalluninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
32297a984708SDavid Chisnall{
32307a984708SDavid Chisnall    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
323194e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
323294e3ee44SDavid Chisnall    _ForwardIterator __s = __r;
323394e3ee44SDavid Chisnall    try
323494e3ee44SDavid Chisnall    {
323594e3ee44SDavid Chisnall#endif
3236854fa44bSDimitry Andric        for (; __f != __l; ++__f, (void) ++__r)
3237854fa44bSDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
323894e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
323994e3ee44SDavid Chisnall    }
324094e3ee44SDavid Chisnall    catch (...)
324194e3ee44SDavid Chisnall    {
324294e3ee44SDavid Chisnall        for (; __s != __r; ++__s)
324394e3ee44SDavid Chisnall            __s->~value_type();
324494e3ee44SDavid Chisnall        throw;
324594e3ee44SDavid Chisnall    }
324694e3ee44SDavid Chisnall#endif
32477a984708SDavid Chisnall    return __r;
32487a984708SDavid Chisnall}
32497a984708SDavid Chisnall
32507a984708SDavid Chisnalltemplate <class _InputIterator, class _Size, class _ForwardIterator>
32517a984708SDavid Chisnall_ForwardIterator
32527a984708SDavid Chisnalluninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
32537a984708SDavid Chisnall{
32547a984708SDavid Chisnall    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
325594e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
325694e3ee44SDavid Chisnall    _ForwardIterator __s = __r;
325794e3ee44SDavid Chisnall    try
325894e3ee44SDavid Chisnall    {
325994e3ee44SDavid Chisnall#endif
3260854fa44bSDimitry Andric        for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
3261854fa44bSDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
326294e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
326394e3ee44SDavid Chisnall    }
326494e3ee44SDavid Chisnall    catch (...)
326594e3ee44SDavid Chisnall    {
326694e3ee44SDavid Chisnall        for (; __s != __r; ++__s)
326794e3ee44SDavid Chisnall            __s->~value_type();
326894e3ee44SDavid Chisnall        throw;
326994e3ee44SDavid Chisnall    }
327094e3ee44SDavid Chisnall#endif
32717a984708SDavid Chisnall    return __r;
32727a984708SDavid Chisnall}
32737a984708SDavid Chisnall
32747a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Tp>
32757a984708SDavid Chisnallvoid
32767a984708SDavid Chisnalluninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
32777a984708SDavid Chisnall{
32787a984708SDavid Chisnall    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
327994e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
328094e3ee44SDavid Chisnall    _ForwardIterator __s = __f;
328194e3ee44SDavid Chisnall    try
328294e3ee44SDavid Chisnall    {
328394e3ee44SDavid Chisnall#endif
328494e3ee44SDavid Chisnall        for (; __f != __l; ++__f)
3285854fa44bSDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
328694e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
328794e3ee44SDavid Chisnall    }
328894e3ee44SDavid Chisnall    catch (...)
328994e3ee44SDavid Chisnall    {
329094e3ee44SDavid Chisnall        for (; __s != __f; ++__s)
329194e3ee44SDavid Chisnall            __s->~value_type();
329294e3ee44SDavid Chisnall        throw;
329394e3ee44SDavid Chisnall    }
329494e3ee44SDavid Chisnall#endif
32957a984708SDavid Chisnall}
32967a984708SDavid Chisnall
32977a984708SDavid Chisnalltemplate <class _ForwardIterator, class _Size, class _Tp>
32987a984708SDavid Chisnall_ForwardIterator
32997a984708SDavid Chisnalluninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
33007a984708SDavid Chisnall{
33017a984708SDavid Chisnall    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
330294e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
330394e3ee44SDavid Chisnall    _ForwardIterator __s = __f;
330494e3ee44SDavid Chisnall    try
330594e3ee44SDavid Chisnall    {
330694e3ee44SDavid Chisnall#endif
3307854fa44bSDimitry Andric        for (; __n > 0; ++__f, (void) --__n)
3308854fa44bSDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
330994e3ee44SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
331094e3ee44SDavid Chisnall    }
331194e3ee44SDavid Chisnall    catch (...)
331294e3ee44SDavid Chisnall    {
331394e3ee44SDavid Chisnall        for (; __s != __f; ++__s)
331494e3ee44SDavid Chisnall            __s->~value_type();
331594e3ee44SDavid Chisnall        throw;
331694e3ee44SDavid Chisnall    }
331794e3ee44SDavid Chisnall#endif
33187a984708SDavid Chisnall    return __f;
33197a984708SDavid Chisnall}
33207a984708SDavid Chisnall
3321aed8d94eSDimitry Andric#if _LIBCPP_STD_VER > 14
3322aed8d94eSDimitry Andric
3323aed8d94eSDimitry Andrictemplate <class _Tp>
3324aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3325aed8d94eSDimitry Andricvoid destroy_at(_Tp* __loc) {
3326aed8d94eSDimitry Andric    _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
3327aed8d94eSDimitry Andric    __loc->~_Tp();
3328aed8d94eSDimitry Andric}
3329aed8d94eSDimitry Andric
3330aed8d94eSDimitry Andrictemplate <class _ForwardIterator>
3331aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3332aed8d94eSDimitry Andricvoid destroy(_ForwardIterator __first, _ForwardIterator __last) {
3333aed8d94eSDimitry Andric    for (; __first != __last; ++__first)
3334aed8d94eSDimitry Andric        _VSTD::destroy_at(_VSTD::addressof(*__first));
3335aed8d94eSDimitry Andric}
3336aed8d94eSDimitry Andric
3337aed8d94eSDimitry Andrictemplate <class _ForwardIterator, class _Size>
3338aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3339aed8d94eSDimitry Andric_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
3340aed8d94eSDimitry Andric    for (; __n > 0; (void)++__first, --__n)
3341aed8d94eSDimitry Andric        _VSTD::destroy_at(_VSTD::addressof(*__first));
3342aed8d94eSDimitry Andric    return __first;
3343aed8d94eSDimitry Andric}
3344aed8d94eSDimitry Andric
3345aed8d94eSDimitry Andrictemplate <class _ForwardIterator>
3346aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3347aed8d94eSDimitry Andricvoid uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
3348aed8d94eSDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3349aed8d94eSDimitry Andric    auto __idx = __first;
3350aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3351aed8d94eSDimitry Andric    try {
3352aed8d94eSDimitry Andric#endif
3353aed8d94eSDimitry Andric    for (; __idx != __last; ++__idx)
3354aed8d94eSDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt;
3355aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3356aed8d94eSDimitry Andric    } catch (...) {
3357aed8d94eSDimitry Andric        _VSTD::destroy(__first, __idx);
3358aed8d94eSDimitry Andric        throw;
3359aed8d94eSDimitry Andric    }
3360aed8d94eSDimitry Andric#endif
3361aed8d94eSDimitry Andric}
3362aed8d94eSDimitry Andric
3363aed8d94eSDimitry Andrictemplate <class _ForwardIterator, class _Size>
3364aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3365aed8d94eSDimitry Andric_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
3366aed8d94eSDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3367aed8d94eSDimitry Andric    auto __idx = __first;
3368aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3369aed8d94eSDimitry Andric    try {
3370aed8d94eSDimitry Andric#endif
3371aed8d94eSDimitry Andric    for (; __n > 0; (void)++__idx, --__n)
3372aed8d94eSDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt;
3373aed8d94eSDimitry Andric    return __idx;
3374aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3375aed8d94eSDimitry Andric    } catch (...) {
3376aed8d94eSDimitry Andric        _VSTD::destroy(__first, __idx);
3377aed8d94eSDimitry Andric        throw;
3378aed8d94eSDimitry Andric    }
3379aed8d94eSDimitry Andric#endif
3380aed8d94eSDimitry Andric}
3381aed8d94eSDimitry Andric
3382aed8d94eSDimitry Andric
3383aed8d94eSDimitry Andrictemplate <class _ForwardIterator>
3384aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3385aed8d94eSDimitry Andricvoid uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
3386aed8d94eSDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3387aed8d94eSDimitry Andric    auto __idx = __first;
3388aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3389aed8d94eSDimitry Andric    try {
3390aed8d94eSDimitry Andric#endif
3391aed8d94eSDimitry Andric    for (; __idx != __last; ++__idx)
3392aed8d94eSDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt();
3393aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3394aed8d94eSDimitry Andric    } catch (...) {
3395aed8d94eSDimitry Andric        _VSTD::destroy(__first, __idx);
3396aed8d94eSDimitry Andric        throw;
3397aed8d94eSDimitry Andric    }
3398aed8d94eSDimitry Andric#endif
3399aed8d94eSDimitry Andric}
3400aed8d94eSDimitry Andric
3401aed8d94eSDimitry Andrictemplate <class _ForwardIterator, class _Size>
3402aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3403aed8d94eSDimitry Andric_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
3404aed8d94eSDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
3405aed8d94eSDimitry Andric    auto __idx = __first;
3406aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3407aed8d94eSDimitry Andric    try {
3408aed8d94eSDimitry Andric#endif
3409aed8d94eSDimitry Andric    for (; __n > 0; (void)++__idx, --__n)
3410aed8d94eSDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt();
3411aed8d94eSDimitry Andric    return __idx;
3412aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3413aed8d94eSDimitry Andric    } catch (...) {
3414aed8d94eSDimitry Andric        _VSTD::destroy(__first, __idx);
3415aed8d94eSDimitry Andric        throw;
3416aed8d94eSDimitry Andric    }
3417aed8d94eSDimitry Andric#endif
3418aed8d94eSDimitry Andric}
3419aed8d94eSDimitry Andric
3420aed8d94eSDimitry Andric
3421aed8d94eSDimitry Andrictemplate <class _InputIt, class _ForwardIt>
3422aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3423aed8d94eSDimitry Andric_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
3424aed8d94eSDimitry Andric    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
3425aed8d94eSDimitry Andric    auto __idx = __first_res;
3426aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3427aed8d94eSDimitry Andric    try {
3428aed8d94eSDimitry Andric#endif
3429aed8d94eSDimitry Andric    for (; __first != __last; (void)++__idx, ++__first)
3430aed8d94eSDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first));
3431aed8d94eSDimitry Andric    return __idx;
3432aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3433aed8d94eSDimitry Andric    } catch (...) {
3434aed8d94eSDimitry Andric        _VSTD::destroy(__first_res, __idx);
3435aed8d94eSDimitry Andric        throw;
3436aed8d94eSDimitry Andric    }
3437aed8d94eSDimitry Andric#endif
3438aed8d94eSDimitry Andric}
3439aed8d94eSDimitry Andric
3440aed8d94eSDimitry Andrictemplate <class _InputIt, class _Size, class _ForwardIt>
3441aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
3442aed8d94eSDimitry Andricpair<_InputIt, _ForwardIt>
3443aed8d94eSDimitry Andricuninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
3444aed8d94eSDimitry Andric    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
3445aed8d94eSDimitry Andric    auto __idx = __first_res;
3446aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3447aed8d94eSDimitry Andric    try {
3448aed8d94eSDimitry Andric#endif
3449aed8d94eSDimitry Andric    for (; __n > 0; ++__idx, (void)++__first, --__n)
3450aed8d94eSDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first));
3451aed8d94eSDimitry Andric    return {__first, __idx};
3452aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3453aed8d94eSDimitry Andric    } catch (...) {
3454aed8d94eSDimitry Andric        _VSTD::destroy(__first_res, __idx);
3455aed8d94eSDimitry Andric        throw;
3456aed8d94eSDimitry Andric    }
3457aed8d94eSDimitry Andric#endif
3458aed8d94eSDimitry Andric}
3459aed8d94eSDimitry Andric
3460aed8d94eSDimitry Andric
3461aed8d94eSDimitry Andric#endif // _LIBCPP_STD_VER > 14
3462aed8d94eSDimitry Andric
3463540d2a8bSDimitry Andric// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
3464540d2a8bSDimitry Andric// should be sufficient for thread safety.
3465540d2a8bSDimitry Andric// See https://bugs.llvm.org/show_bug.cgi?id=22803
3466540d2a8bSDimitry Andric#if defined(__clang__) && __has_builtin(__atomic_add_fetch)          \
3467540d2a8bSDimitry Andric                       && defined(__ATOMIC_RELAXED)                  \
3468540d2a8bSDimitry Andric                       && defined(__ATOMIC_ACQ_REL)
3469540d2a8bSDimitry Andric#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
3470540d2a8bSDimitry Andric#elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407
3471540d2a8bSDimitry Andric#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
3472540d2a8bSDimitry Andric#endif
3473540d2a8bSDimitry Andric
3474540d2a8bSDimitry Andrictemplate <class _Tp>
3475540d2a8bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _Tp
3476540d2a8bSDimitry Andric__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
3477540d2a8bSDimitry Andric{
3478540d2a8bSDimitry Andric#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
3479540d2a8bSDimitry Andric    return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
3480540d2a8bSDimitry Andric#else
3481540d2a8bSDimitry Andric    return __t += 1;
3482540d2a8bSDimitry Andric#endif
3483540d2a8bSDimitry Andric}
3484540d2a8bSDimitry Andric
3485540d2a8bSDimitry Andrictemplate <class _Tp>
3486540d2a8bSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _Tp
3487540d2a8bSDimitry Andric__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
3488540d2a8bSDimitry Andric{
3489540d2a8bSDimitry Andric#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
3490540d2a8bSDimitry Andric    return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
3491540d2a8bSDimitry Andric#else
3492540d2a8bSDimitry Andric    return __t -= 1;
3493540d2a8bSDimitry Andric#endif
3494540d2a8bSDimitry Andric}
3495540d2a8bSDimitry Andric
34967a984708SDavid Chisnallclass _LIBCPP_EXCEPTION_ABI bad_weak_ptr
34977a984708SDavid Chisnall    : public std::exception
34987a984708SDavid Chisnall{
34997a984708SDavid Chisnallpublic:
35007a984708SDavid Chisnall    virtual ~bad_weak_ptr() _NOEXCEPT;
35017a984708SDavid Chisnall    virtual const char* what() const  _NOEXCEPT;
35027a984708SDavid Chisnall};
35037a984708SDavid Chisnall
35044ba319b5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
3505aed8d94eSDimitry Andricvoid __throw_bad_weak_ptr()
3506aed8d94eSDimitry Andric{
3507aed8d94eSDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
3508aed8d94eSDimitry Andric    throw bad_weak_ptr();
3509aed8d94eSDimitry Andric#else
3510aed8d94eSDimitry Andric    _VSTD::abort();
3511aed8d94eSDimitry Andric#endif
3512aed8d94eSDimitry Andric}
3513aed8d94eSDimitry Andric
3514aed8d94eSDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
35157a984708SDavid Chisnall
35164f7ab58eSDimitry Andricclass _LIBCPP_TYPE_VIS __shared_count
35177a984708SDavid Chisnall{
35187a984708SDavid Chisnall    __shared_count(const __shared_count&);
35197a984708SDavid Chisnall    __shared_count& operator=(const __shared_count&);
35207a984708SDavid Chisnall
35217a984708SDavid Chisnallprotected:
35227a984708SDavid Chisnall    long __shared_owners_;
35237a984708SDavid Chisnall    virtual ~__shared_count();
35247a984708SDavid Chisnallprivate:
35257a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT = 0;
35267a984708SDavid Chisnall
35277a984708SDavid Chisnallpublic:
35287a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
35297a984708SDavid Chisnall    explicit __shared_count(long __refs = 0) _NOEXCEPT
35307a984708SDavid Chisnall        : __shared_owners_(__refs) {}
35317a984708SDavid Chisnall
35324ba319b5SDimitry Andric#if defined(_LIBCPP_BUILDING_LIBRARY) && \
3533540d2a8bSDimitry Andric    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
35347a984708SDavid Chisnall    void __add_shared() _NOEXCEPT;
35357a984708SDavid Chisnall    bool __release_shared() _NOEXCEPT;
3536540d2a8bSDimitry Andric#else
3537540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3538540d2a8bSDimitry Andric    void __add_shared() _NOEXCEPT {
3539540d2a8bSDimitry Andric      __libcpp_atomic_refcount_increment(__shared_owners_);
3540540d2a8bSDimitry Andric    }
3541540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3542540d2a8bSDimitry Andric    bool __release_shared() _NOEXCEPT {
3543540d2a8bSDimitry Andric      if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
3544540d2a8bSDimitry Andric        __on_zero_shared();
3545540d2a8bSDimitry Andric        return true;
3546540d2a8bSDimitry Andric      }
3547540d2a8bSDimitry Andric      return false;
3548540d2a8bSDimitry Andric    }
3549540d2a8bSDimitry Andric#endif
35507a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
3551854fa44bSDimitry Andric    long use_count() const _NOEXCEPT {
3552854fa44bSDimitry Andric        return __libcpp_relaxed_load(&__shared_owners_) + 1;
3553854fa44bSDimitry Andric    }
35547a984708SDavid Chisnall};
35557a984708SDavid Chisnall
35564f7ab58eSDimitry Andricclass _LIBCPP_TYPE_VIS __shared_weak_count
35577a984708SDavid Chisnall    : private __shared_count
35587a984708SDavid Chisnall{
35597a984708SDavid Chisnall    long __shared_weak_owners_;
35607a984708SDavid Chisnall
35617a984708SDavid Chisnallpublic:
35627a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
35637a984708SDavid Chisnall    explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
35647a984708SDavid Chisnall        : __shared_count(__refs),
35657a984708SDavid Chisnall          __shared_weak_owners_(__refs) {}
35667a984708SDavid Chisnallprotected:
35677a984708SDavid Chisnall    virtual ~__shared_weak_count();
35687a984708SDavid Chisnall
35697a984708SDavid Chisnallpublic:
35704ba319b5SDimitry Andric#if defined(_LIBCPP_BUILDING_LIBRARY) && \
3571540d2a8bSDimitry Andric    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
35727a984708SDavid Chisnall    void __add_shared() _NOEXCEPT;
35737a984708SDavid Chisnall    void __add_weak() _NOEXCEPT;
35747a984708SDavid Chisnall    void __release_shared() _NOEXCEPT;
3575540d2a8bSDimitry Andric#else
3576540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3577540d2a8bSDimitry Andric    void __add_shared() _NOEXCEPT {
3578540d2a8bSDimitry Andric      __shared_count::__add_shared();
3579540d2a8bSDimitry Andric    }
3580540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3581540d2a8bSDimitry Andric    void __add_weak() _NOEXCEPT {
3582540d2a8bSDimitry Andric      __libcpp_atomic_refcount_increment(__shared_weak_owners_);
3583540d2a8bSDimitry Andric    }
3584540d2a8bSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3585540d2a8bSDimitry Andric    void __release_shared() _NOEXCEPT {
3586540d2a8bSDimitry Andric      if (__shared_count::__release_shared())
3587540d2a8bSDimitry Andric        __release_weak();
3588540d2a8bSDimitry Andric    }
3589540d2a8bSDimitry Andric#endif
35907a984708SDavid Chisnall    void __release_weak() _NOEXCEPT;
35917a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
35927a984708SDavid Chisnall    long use_count() const _NOEXCEPT {return __shared_count::use_count();}
35937a984708SDavid Chisnall    __shared_weak_count* lock() _NOEXCEPT;
35947a984708SDavid Chisnall
35951bf9f7c1SDimitry Andric    // Define the function out only if we build static libc++ without RTTI.
35961bf9f7c1SDimitry Andric    // Otherwise we may break clients who need to compile their projects with
35971bf9f7c1SDimitry Andric    // -fno-rtti and yet link against a libc++.dylib compiled
35981bf9f7c1SDimitry Andric    // without -fno-rtti.
35991bf9f7c1SDimitry Andric#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
36007a984708SDavid Chisnall    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
36011bf9f7c1SDimitry Andric#endif
36027a984708SDavid Chisnallprivate:
36037a984708SDavid Chisnall    virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
36047a984708SDavid Chisnall};
36057a984708SDavid Chisnall
36067a984708SDavid Chisnalltemplate <class _Tp, class _Dp, class _Alloc>
36077a984708SDavid Chisnallclass __shared_ptr_pointer
36087a984708SDavid Chisnall    : public __shared_weak_count
36097a984708SDavid Chisnall{
36107a984708SDavid Chisnall    __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
36117a984708SDavid Chisnallpublic:
36127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
36137a984708SDavid Chisnall    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
36147a984708SDavid Chisnall        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
36157a984708SDavid Chisnall
36167a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
36177a984708SDavid Chisnall    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
36187a984708SDavid Chisnall#endif
36197a984708SDavid Chisnall
36207a984708SDavid Chisnallprivate:
36217a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
36227a984708SDavid Chisnall    virtual void __on_zero_shared_weak() _NOEXCEPT;
36237a984708SDavid Chisnall};
36247a984708SDavid Chisnall
36257a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
36267a984708SDavid Chisnall
36277a984708SDavid Chisnalltemplate <class _Tp, class _Dp, class _Alloc>
36287a984708SDavid Chisnallconst void*
36297a984708SDavid Chisnall__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
36307a984708SDavid Chisnall{
36310f5676f4SDimitry Andric    return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
36327a984708SDavid Chisnall}
36337a984708SDavid Chisnall
36347a984708SDavid Chisnall#endif  // _LIBCPP_NO_RTTI
36357a984708SDavid Chisnall
36367a984708SDavid Chisnalltemplate <class _Tp, class _Dp, class _Alloc>
36377a984708SDavid Chisnallvoid
36387a984708SDavid Chisnall__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
36397a984708SDavid Chisnall{
36407a984708SDavid Chisnall    __data_.first().second()(__data_.first().first());
36417a984708SDavid Chisnall    __data_.first().second().~_Dp();
36427a984708SDavid Chisnall}
36437a984708SDavid Chisnall
36447a984708SDavid Chisnalltemplate <class _Tp, class _Dp, class _Alloc>
36457a984708SDavid Chisnallvoid
36467a984708SDavid Chisnall__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
36477a984708SDavid Chisnall{
3648854fa44bSDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
3649854fa44bSDimitry Andric    typedef allocator_traits<_Al> _ATraits;
3650d72607e9SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
3651d72607e9SDimitry Andric
3652854fa44bSDimitry Andric    _Al __a(__data_.second());
36537a984708SDavid Chisnall    __data_.second().~_Alloc();
3654d72607e9SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
36557a984708SDavid Chisnall}
36567a984708SDavid Chisnall
36577a984708SDavid Chisnalltemplate <class _Tp, class _Alloc>
36587a984708SDavid Chisnallclass __shared_ptr_emplace
36597a984708SDavid Chisnall    : public __shared_weak_count
36607a984708SDavid Chisnall{
36617a984708SDavid Chisnall    __compressed_pair<_Alloc, _Tp> __data_;
36627a984708SDavid Chisnallpublic:
36637a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
36647a984708SDavid Chisnall
36657a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
36667a984708SDavid Chisnall    __shared_ptr_emplace(_Alloc __a)
36677a984708SDavid Chisnall        :  __data_(_VSTD::move(__a)) {}
36687a984708SDavid Chisnall
36697a984708SDavid Chisnall    template <class ..._Args>
36707a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
36717a984708SDavid Chisnall        __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
367294e3ee44SDavid Chisnall            :  __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
367394e3ee44SDavid Chisnall                   _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)) {}
36747a984708SDavid Chisnall
36757a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
36767a984708SDavid Chisnall
36777a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
36787a984708SDavid Chisnall    __shared_ptr_emplace(_Alloc __a)
36797a984708SDavid Chisnall        :  __data_(__a) {}
36807a984708SDavid Chisnall
36817a984708SDavid Chisnall    template <class _A0>
36827a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
36837a984708SDavid Chisnall        __shared_ptr_emplace(_Alloc __a, _A0& __a0)
36847a984708SDavid Chisnall            :  __data_(__a, _Tp(__a0)) {}
36857a984708SDavid Chisnall
36867a984708SDavid Chisnall    template <class _A0, class _A1>
36877a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
36887a984708SDavid Chisnall        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1)
36897a984708SDavid Chisnall            :  __data_(__a, _Tp(__a0, __a1)) {}
36907a984708SDavid Chisnall
36917a984708SDavid Chisnall    template <class _A0, class _A1, class _A2>
36927a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
36937a984708SDavid Chisnall        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1, _A2& __a2)
36947a984708SDavid Chisnall            :  __data_(__a, _Tp(__a0, __a1, __a2)) {}
36957a984708SDavid Chisnall
36967a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
36977a984708SDavid Chisnall
36987a984708SDavid Chisnallprivate:
36997a984708SDavid Chisnall    virtual void __on_zero_shared() _NOEXCEPT;
37007a984708SDavid Chisnall    virtual void __on_zero_shared_weak() _NOEXCEPT;
37017a984708SDavid Chisnallpublic:
37027a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
37034ba319b5SDimitry Andric    _Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());}
37047a984708SDavid Chisnall};
37057a984708SDavid Chisnall
37067a984708SDavid Chisnalltemplate <class _Tp, class _Alloc>
37077a984708SDavid Chisnallvoid
37087a984708SDavid Chisnall__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared() _NOEXCEPT
37097a984708SDavid Chisnall{
37107a984708SDavid Chisnall    __data_.second().~_Tp();
37117a984708SDavid Chisnall}
37127a984708SDavid Chisnall
37137a984708SDavid Chisnalltemplate <class _Tp, class _Alloc>
37147a984708SDavid Chisnallvoid
37157a984708SDavid Chisnall__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
37167a984708SDavid Chisnall{
3717854fa44bSDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type _Al;
3718854fa44bSDimitry Andric    typedef allocator_traits<_Al> _ATraits;
3719d72607e9SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
3720854fa44bSDimitry Andric    _Al __a(__data_.first());
37217a984708SDavid Chisnall    __data_.first().~_Alloc();
3722d72607e9SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
37237a984708SDavid Chisnall}
37247a984708SDavid Chisnall
3725302affcbSDimitry Andricstruct __shared_ptr_dummy_rebind_allocator_type;
3726302affcbSDimitry Andrictemplate <>
3727302affcbSDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
3728302affcbSDimitry Andric{
3729302affcbSDimitry Andricpublic:
3730302affcbSDimitry Andric    template <class _Other>
3731302affcbSDimitry Andric    struct rebind
3732302affcbSDimitry Andric    {
3733302affcbSDimitry Andric        typedef allocator<_Other> other;
3734302affcbSDimitry Andric    };
3735302affcbSDimitry Andric};
3736302affcbSDimitry Andric
3737aed8d94eSDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
37387a984708SDavid Chisnall
37397a984708SDavid Chisnalltemplate<class _Tp>
3740aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_ptr
37417a984708SDavid Chisnall{
37427a984708SDavid Chisnallpublic:
37437a984708SDavid Chisnall    typedef _Tp element_type;
37447a848d17SDimitry Andric
37457c82a1ecSDimitry Andric#if _LIBCPP_STD_VER > 14
37467c82a1ecSDimitry Andric    typedef weak_ptr<_Tp> weak_type;
37477c82a1ecSDimitry Andric#endif
37487a984708SDavid Chisnallprivate:
37497a984708SDavid Chisnall    element_type*      __ptr_;
37507a984708SDavid Chisnall    __shared_weak_count* __cntrl_;
37517a984708SDavid Chisnall
37527a984708SDavid Chisnall    struct __nat {int __for_bool_;};
37537a984708SDavid Chisnallpublic:
37549729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3755936e9439SDimitry Andric    _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
37569729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3757936e9439SDimitry Andric    _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
3758d72607e9SDimitry Andric    template<class _Yp>
3759d72607e9SDimitry Andric        explicit shared_ptr(_Yp* __p,
3760d72607e9SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
3761d72607e9SDimitry Andric    template<class _Yp, class _Dp>
3762d72607e9SDimitry Andric        shared_ptr(_Yp* __p, _Dp __d,
3763d72607e9SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
3764d72607e9SDimitry Andric    template<class _Yp, class _Dp, class _Alloc>
3765d72607e9SDimitry Andric        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
3766d72607e9SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
37677a984708SDavid Chisnall    template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
37687a984708SDavid Chisnall    template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
37699729cf09SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
37709729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
37717a984708SDavid Chisnall    shared_ptr(const shared_ptr& __r) _NOEXCEPT;
37727a984708SDavid Chisnall    template<class _Yp>
37739729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
37747a984708SDavid Chisnall        shared_ptr(const shared_ptr<_Yp>& __r,
37757a848d17SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat())
37767a984708SDavid Chisnall                       _NOEXCEPT;
37777a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
37789729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
37797a984708SDavid Chisnall    shared_ptr(shared_ptr&& __r) _NOEXCEPT;
37809729cf09SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r,
37817a848d17SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat())
37827a984708SDavid Chisnall                       _NOEXCEPT;
37837a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
37847a984708SDavid Chisnall    template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
37857a848d17SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
3786540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
37877a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3788d72607e9SDimitry Andric    template<class _Yp>
3789d72607e9SDimitry Andric        shared_ptr(auto_ptr<_Yp>&& __r,
3790d72607e9SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
37917a984708SDavid Chisnall#else
3792d72607e9SDimitry Andric    template<class _Yp>
3793d72607e9SDimitry Andric        shared_ptr(auto_ptr<_Yp> __r,
3794d72607e9SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
37957a984708SDavid Chisnall#endif
3796540d2a8bSDimitry Andric#endif
37977a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
3798d72607e9SDimitry Andric    template <class _Yp, class _Dp>
379994e3ee44SDavid Chisnall        shared_ptr(unique_ptr<_Yp, _Dp>&&,
3800d72607e9SDimitry Andric                   typename enable_if
380194e3ee44SDavid Chisnall                   <
3802d72607e9SDimitry Andric                       !is_lvalue_reference<_Dp>::value &&
380394e3ee44SDavid Chisnall                       !is_array<_Yp>::value &&
3804d72607e9SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
3805d72607e9SDimitry Andric                       __nat
3806d72607e9SDimitry Andric                   >::type = __nat());
3807d72607e9SDimitry Andric    template <class _Yp, class _Dp>
380894e3ee44SDavid Chisnall        shared_ptr(unique_ptr<_Yp, _Dp>&&,
3809d72607e9SDimitry Andric                   typename enable_if
3810d72607e9SDimitry Andric                   <
3811d72607e9SDimitry Andric                       is_lvalue_reference<_Dp>::value &&
3812d72607e9SDimitry Andric                       !is_array<_Yp>::value &&
3813d72607e9SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
3814d72607e9SDimitry Andric                       __nat
3815d72607e9SDimitry Andric                   >::type = __nat());
38167a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3817d72607e9SDimitry Andric    template <class _Yp, class _Dp>
381894e3ee44SDavid Chisnall        shared_ptr(unique_ptr<_Yp, _Dp>,
3819d72607e9SDimitry Andric                   typename enable_if
3820d72607e9SDimitry Andric                   <
3821d72607e9SDimitry Andric                       !is_lvalue_reference<_Dp>::value &&
3822d72607e9SDimitry Andric                       !is_array<_Yp>::value &&
3823d72607e9SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
3824d72607e9SDimitry Andric                       __nat
3825d72607e9SDimitry Andric                   >::type = __nat());
3826d72607e9SDimitry Andric    template <class _Yp, class _Dp>
3827d72607e9SDimitry Andric        shared_ptr(unique_ptr<_Yp, _Dp>,
3828d72607e9SDimitry Andric                   typename enable_if
3829d72607e9SDimitry Andric                   <
3830d72607e9SDimitry Andric                       is_lvalue_reference<_Dp>::value &&
3831d72607e9SDimitry Andric                       !is_array<_Yp>::value &&
3832d72607e9SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
3833d72607e9SDimitry Andric                       __nat
3834d72607e9SDimitry Andric                   >::type = __nat());
38357a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
38367a984708SDavid Chisnall
38377a984708SDavid Chisnall    ~shared_ptr();
38387a984708SDavid Chisnall
38399729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38407a984708SDavid Chisnall    shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
384194e3ee44SDavid Chisnall    template<class _Yp>
384294e3ee44SDavid Chisnall        typename enable_if
384394e3ee44SDavid Chisnall        <
384494e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
384594e3ee44SDavid Chisnall            shared_ptr&
384694e3ee44SDavid Chisnall        >::type
38479729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
384894e3ee44SDavid Chisnall        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
38497a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
38509729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38517a984708SDavid Chisnall    shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
385294e3ee44SDavid Chisnall    template<class _Yp>
385394e3ee44SDavid Chisnall        typename enable_if
385494e3ee44SDavid Chisnall        <
385594e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
385694e3ee44SDavid Chisnall            shared_ptr<_Tp>&
385794e3ee44SDavid Chisnall        >::type
38589729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
385994e3ee44SDavid Chisnall        operator=(shared_ptr<_Yp>&& __r);
3860540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
386194e3ee44SDavid Chisnall    template<class _Yp>
38627c82a1ecSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
386394e3ee44SDavid Chisnall        typename enable_if
386494e3ee44SDavid Chisnall        <
386594e3ee44SDavid Chisnall            !is_array<_Yp>::value &&
386694e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
38674f7ab58eSDimitry Andric            shared_ptr
38684f7ab58eSDimitry Andric        >::type&
386994e3ee44SDavid Chisnall        operator=(auto_ptr<_Yp>&& __r);
3870540d2a8bSDimitry Andric#endif
38717a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
3872540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
387394e3ee44SDavid Chisnall    template<class _Yp>
38747c82a1ecSDimitry Andric        _LIBCPP_INLINE_VISIBILITY
387594e3ee44SDavid Chisnall        typename enable_if
387694e3ee44SDavid Chisnall        <
387794e3ee44SDavid Chisnall            !is_array<_Yp>::value &&
387894e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
387994e3ee44SDavid Chisnall            shared_ptr&
388094e3ee44SDavid Chisnall        >::type
388194e3ee44SDavid Chisnall        operator=(auto_ptr<_Yp> __r);
38827a984708SDavid Chisnall#endif
3883540d2a8bSDimitry Andric#endif
388494e3ee44SDavid Chisnall    template <class _Yp, class _Dp>
388594e3ee44SDavid Chisnall        typename enable_if
388694e3ee44SDavid Chisnall        <
388794e3ee44SDavid Chisnall            !is_array<_Yp>::value &&
388894e3ee44SDavid Chisnall            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
388994e3ee44SDavid Chisnall            shared_ptr&
389094e3ee44SDavid Chisnall        >::type
38917a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
38929729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
389394e3ee44SDavid Chisnall        operator=(unique_ptr<_Yp, _Dp>&& __r);
38947a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
38959729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
389694e3ee44SDavid Chisnall        operator=(unique_ptr<_Yp, _Dp> __r);
38977a984708SDavid Chisnall#endif
38987a984708SDavid Chisnall
38999729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39007a984708SDavid Chisnall    void swap(shared_ptr& __r) _NOEXCEPT;
39019729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39027a984708SDavid Chisnall    void reset() _NOEXCEPT;
390394e3ee44SDavid Chisnall    template<class _Yp>
390494e3ee44SDavid Chisnall        typename enable_if
390594e3ee44SDavid Chisnall        <
390694e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
390794e3ee44SDavid Chisnall            void
390894e3ee44SDavid Chisnall        >::type
39099729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
391094e3ee44SDavid Chisnall        reset(_Yp* __p);
391194e3ee44SDavid Chisnall    template<class _Yp, class _Dp>
391294e3ee44SDavid Chisnall        typename enable_if
391394e3ee44SDavid Chisnall        <
391494e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
391594e3ee44SDavid Chisnall            void
391694e3ee44SDavid Chisnall        >::type
39179729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
391894e3ee44SDavid Chisnall        reset(_Yp* __p, _Dp __d);
391994e3ee44SDavid Chisnall    template<class _Yp, class _Dp, class _Alloc>
392094e3ee44SDavid Chisnall        typename enable_if
392194e3ee44SDavid Chisnall        <
392294e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
392394e3ee44SDavid Chisnall            void
392494e3ee44SDavid Chisnall        >::type
39259729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
392694e3ee44SDavid Chisnall        reset(_Yp* __p, _Dp __d, _Alloc __a);
39277a984708SDavid Chisnall
39287a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
39297a984708SDavid Chisnall    element_type* get() const _NOEXCEPT {return __ptr_;}
39307a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
39317a984708SDavid Chisnall    typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
39327a984708SDavid Chisnall        {return *__ptr_;}
39337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
39347a984708SDavid Chisnall    element_type* operator->() const _NOEXCEPT {return __ptr_;}
39357a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
39367a984708SDavid Chisnall    long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
39377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
39387a984708SDavid Chisnall    bool unique() const _NOEXCEPT {return use_count() == 1;}
39397a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
394094e3ee44SDavid Chisnall    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != 0;}
394194e3ee44SDavid Chisnall    template <class _Up>
39427a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
3943540d2a8bSDimitry Andric        bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
39447a984708SDavid Chisnall        {return __cntrl_ < __p.__cntrl_;}
394594e3ee44SDavid Chisnall    template <class _Up>
39467a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
3947540d2a8bSDimitry Andric        bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
39487a984708SDavid Chisnall        {return __cntrl_ < __p.__cntrl_;}
3949936e9439SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3950936e9439SDimitry Andric    bool
3951936e9439SDimitry Andric    __owner_equivalent(const shared_ptr& __p) const
3952936e9439SDimitry Andric        {return __cntrl_ == __p.__cntrl_;}
39537a984708SDavid Chisnall
39547a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
39557a984708SDavid Chisnall    template <class _Dp>
39567a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
39577a984708SDavid Chisnall        _Dp* __get_deleter() const _NOEXCEPT
395824d58133SDimitry Andric            {return static_cast<_Dp*>(__cntrl_
395924d58133SDimitry Andric                    ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
396024d58133SDimitry Andric                      : nullptr);}
39617a984708SDavid Chisnall#endif  // _LIBCPP_NO_RTTI
39627a984708SDavid Chisnall
39637a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
39647a984708SDavid Chisnall
39657a984708SDavid Chisnall    template<class ..._Args>
39667a984708SDavid Chisnall        static
39677a984708SDavid Chisnall        shared_ptr<_Tp>
39687a984708SDavid Chisnall        make_shared(_Args&& ...__args);
39697a984708SDavid Chisnall
39707a984708SDavid Chisnall    template<class _Alloc, class ..._Args>
39717a984708SDavid Chisnall        static
39727a984708SDavid Chisnall        shared_ptr<_Tp>
39737a984708SDavid Chisnall        allocate_shared(const _Alloc& __a, _Args&& ...__args);
39747a984708SDavid Chisnall
39757a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
39767a984708SDavid Chisnall
39777a984708SDavid Chisnall    static shared_ptr<_Tp> make_shared();
39787a984708SDavid Chisnall
39797a984708SDavid Chisnall    template<class _A0>
39807a984708SDavid Chisnall        static shared_ptr<_Tp> make_shared(_A0&);
39817a984708SDavid Chisnall
39827a984708SDavid Chisnall    template<class _A0, class _A1>
39837a984708SDavid Chisnall        static shared_ptr<_Tp> make_shared(_A0&, _A1&);
39847a984708SDavid Chisnall
39857a984708SDavid Chisnall    template<class _A0, class _A1, class _A2>
39867a984708SDavid Chisnall        static shared_ptr<_Tp> make_shared(_A0&, _A1&, _A2&);
39877a984708SDavid Chisnall
39887a984708SDavid Chisnall    template<class _Alloc>
39897a984708SDavid Chisnall        static shared_ptr<_Tp>
39907a984708SDavid Chisnall        allocate_shared(const _Alloc& __a);
39917a984708SDavid Chisnall
39927a984708SDavid Chisnall    template<class _Alloc, class _A0>
39937a984708SDavid Chisnall        static shared_ptr<_Tp>
39947a984708SDavid Chisnall        allocate_shared(const _Alloc& __a, _A0& __a0);
39957a984708SDavid Chisnall
39967a984708SDavid Chisnall    template<class _Alloc, class _A0, class _A1>
39977a984708SDavid Chisnall        static shared_ptr<_Tp>
39987a984708SDavid Chisnall        allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1);
39997a984708SDavid Chisnall
40007a984708SDavid Chisnall    template<class _Alloc, class _A0, class _A1, class _A2>
40017a984708SDavid Chisnall        static shared_ptr<_Tp>
40027a984708SDavid Chisnall        allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2);
40037a984708SDavid Chisnall
40047a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
40057a984708SDavid Chisnall
40067a984708SDavid Chisnallprivate:
4007302affcbSDimitry Andric    template <class _Yp, bool = is_function<_Yp>::value>
4008302affcbSDimitry Andric        struct __shared_ptr_default_allocator
4009302affcbSDimitry Andric        {
4010302affcbSDimitry Andric            typedef allocator<_Yp> type;
4011302affcbSDimitry Andric        };
4012302affcbSDimitry Andric
4013302affcbSDimitry Andric    template <class _Yp>
4014302affcbSDimitry Andric        struct __shared_ptr_default_allocator<_Yp, true>
4015302affcbSDimitry Andric        {
4016302affcbSDimitry Andric            typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
4017302affcbSDimitry Andric        };
40187a984708SDavid Chisnall
40197c82a1ecSDimitry Andric    template <class _Yp, class _OrigPtr>
40207a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
40215517e702SDimitry Andric        typename enable_if<is_convertible<_OrigPtr*,
40225517e702SDimitry Andric                                          const enable_shared_from_this<_Yp>*
40235517e702SDimitry Andric        >::value,
40245517e702SDimitry Andric            void>::type
40257c82a1ecSDimitry Andric        __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
40267c82a1ecSDimitry Andric                           _OrigPtr* __ptr) _NOEXCEPT
40277a984708SDavid Chisnall        {
40287c82a1ecSDimitry Andric            typedef typename remove_cv<_Yp>::type _RawYp;
40297c82a1ecSDimitry Andric            if (__e && __e->__weak_this_.expired())
4030854fa44bSDimitry Andric            {
40317c82a1ecSDimitry Andric                __e->__weak_this_ = shared_ptr<_RawYp>(*this,
40327c82a1ecSDimitry Andric                    const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
4033854fa44bSDimitry Andric            }
40347a984708SDavid Chisnall        }
40357a984708SDavid Chisnall
4036302affcbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
40377a984708SDavid Chisnall
4038aed8d94eSDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
4039aed8d94eSDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
40407a984708SDavid Chisnall};
40417a984708SDavid Chisnall
40425517e702SDimitry Andric
40437a984708SDavid Chisnalltemplate<class _Tp>
40449729cf09SDimitry Andricinline
4045936e9439SDimitry Andric_LIBCPP_CONSTEXPR
40467a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr() _NOEXCEPT
40477a984708SDavid Chisnall    : __ptr_(0),
40487a984708SDavid Chisnall      __cntrl_(0)
40497a984708SDavid Chisnall{
40507a984708SDavid Chisnall}
40517a984708SDavid Chisnall
40527a984708SDavid Chisnalltemplate<class _Tp>
40539729cf09SDimitry Andricinline
4054936e9439SDimitry Andric_LIBCPP_CONSTEXPR
40557a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
40567a984708SDavid Chisnall    : __ptr_(0),
40577a984708SDavid Chisnall      __cntrl_(0)
40587a984708SDavid Chisnall{
40597a984708SDavid Chisnall}
40607a984708SDavid Chisnall
40617a984708SDavid Chisnalltemplate<class _Tp>
4062d72607e9SDimitry Andrictemplate<class _Yp>
4063d72607e9SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p,
4064d72607e9SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
40657a984708SDavid Chisnall    : __ptr_(__p)
40667a984708SDavid Chisnall{
40677a984708SDavid Chisnall    unique_ptr<_Yp> __hold(__p);
4068302affcbSDimitry Andric    typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
4069302affcbSDimitry Andric    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk;
4070302affcbSDimitry Andric    __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), _AllocT());
40717a984708SDavid Chisnall    __hold.release();
40727c82a1ecSDimitry Andric    __enable_weak_this(__p, __p);
40737a984708SDavid Chisnall}
40747a984708SDavid Chisnall
40757a984708SDavid Chisnalltemplate<class _Tp>
4076d72607e9SDimitry Andrictemplate<class _Yp, class _Dp>
4077d72607e9SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
4078d72607e9SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
40797a984708SDavid Chisnall    : __ptr_(__p)
40807a984708SDavid Chisnall{
40817a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
40827a984708SDavid Chisnall    try
40837a984708SDavid Chisnall    {
40847a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
4085302affcbSDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
4086302affcbSDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
4087302affcbSDimitry Andric        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
40887c82a1ecSDimitry Andric        __enable_weak_this(__p, __p);
40897a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
40907a984708SDavid Chisnall    }
40917a984708SDavid Chisnall    catch (...)
40927a984708SDavid Chisnall    {
40937a984708SDavid Chisnall        __d(__p);
40947a984708SDavid Chisnall        throw;
40957a984708SDavid Chisnall    }
40967a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
40977a984708SDavid Chisnall}
40987a984708SDavid Chisnall
40997a984708SDavid Chisnalltemplate<class _Tp>
41007a984708SDavid Chisnalltemplate<class _Dp>
41017a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
41027a984708SDavid Chisnall    : __ptr_(0)
41037a984708SDavid Chisnall{
41047a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
41057a984708SDavid Chisnall    try
41067a984708SDavid Chisnall    {
41077a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
4108302affcbSDimitry Andric        typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
4109302affcbSDimitry Andric        typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
4110302affcbSDimitry Andric        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
41117a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
41127a984708SDavid Chisnall    }
41137a984708SDavid Chisnall    catch (...)
41147a984708SDavid Chisnall    {
41157a984708SDavid Chisnall        __d(__p);
41167a984708SDavid Chisnall        throw;
41177a984708SDavid Chisnall    }
41187a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
41197a984708SDavid Chisnall}
41207a984708SDavid Chisnall
41217a984708SDavid Chisnalltemplate<class _Tp>
4122d72607e9SDimitry Andrictemplate<class _Yp, class _Dp, class _Alloc>
4123d72607e9SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
4124d72607e9SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
41257a984708SDavid Chisnall    : __ptr_(__p)
41267a984708SDavid Chisnall{
41277a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
41287a984708SDavid Chisnall    try
41297a984708SDavid Chisnall    {
41307a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
41317a984708SDavid Chisnall        typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
4132d72607e9SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
41337a984708SDavid Chisnall        typedef __allocator_destructor<_A2> _D2;
41347a984708SDavid Chisnall        _A2 __a2(__a);
41357a984708SDavid Chisnall        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
4136d72607e9SDimitry Andric        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
4137d72607e9SDimitry Andric            _CntrlBlk(__p, __d, __a);
4138d72607e9SDimitry Andric        __cntrl_ = _VSTD::addressof(*__hold2.release());
41397c82a1ecSDimitry Andric        __enable_weak_this(__p, __p);
41407a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
41417a984708SDavid Chisnall    }
41427a984708SDavid Chisnall    catch (...)
41437a984708SDavid Chisnall    {
41447a984708SDavid Chisnall        __d(__p);
41457a984708SDavid Chisnall        throw;
41467a984708SDavid Chisnall    }
41477a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
41487a984708SDavid Chisnall}
41497a984708SDavid Chisnall
41507a984708SDavid Chisnalltemplate<class _Tp>
41517a984708SDavid Chisnalltemplate<class _Dp, class _Alloc>
41527a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
41537a984708SDavid Chisnall    : __ptr_(0)
41547a984708SDavid Chisnall{
41557a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
41567a984708SDavid Chisnall    try
41577a984708SDavid Chisnall    {
41587a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
41597a984708SDavid Chisnall        typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
4160d72607e9SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
41617a984708SDavid Chisnall        typedef __allocator_destructor<_A2> _D2;
41627a984708SDavid Chisnall        _A2 __a2(__a);
41637a984708SDavid Chisnall        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
4164d72607e9SDimitry Andric        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
4165d72607e9SDimitry Andric            _CntrlBlk(__p, __d, __a);
4166d72607e9SDimitry Andric        __cntrl_ = _VSTD::addressof(*__hold2.release());
41677a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS
41687a984708SDavid Chisnall    }
41697a984708SDavid Chisnall    catch (...)
41707a984708SDavid Chisnall    {
41717a984708SDavid Chisnall        __d(__p);
41727a984708SDavid Chisnall        throw;
41737a984708SDavid Chisnall    }
41747a984708SDavid Chisnall#endif  // _LIBCPP_NO_EXCEPTIONS
41757a984708SDavid Chisnall}
41767a984708SDavid Chisnall
41777a984708SDavid Chisnalltemplate<class _Tp>
41787a984708SDavid Chisnalltemplate<class _Yp>
41799729cf09SDimitry Andricinline
41807a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
41817a984708SDavid Chisnall    : __ptr_(__p),
41827a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
41837a984708SDavid Chisnall{
41847a984708SDavid Chisnall    if (__cntrl_)
41857a984708SDavid Chisnall        __cntrl_->__add_shared();
41867a984708SDavid Chisnall}
41877a984708SDavid Chisnall
41887a984708SDavid Chisnalltemplate<class _Tp>
41899729cf09SDimitry Andricinline
41907a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
41917a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
41927a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
41937a984708SDavid Chisnall{
41947a984708SDavid Chisnall    if (__cntrl_)
41957a984708SDavid Chisnall        __cntrl_->__add_shared();
41967a984708SDavid Chisnall}
41977a984708SDavid Chisnall
41987a984708SDavid Chisnalltemplate<class _Tp>
41997a984708SDavid Chisnalltemplate<class _Yp>
42009729cf09SDimitry Andricinline
42017a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
42027a848d17SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
42037a984708SDavid Chisnall         _NOEXCEPT
42047a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
42057a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
42067a984708SDavid Chisnall{
42077a984708SDavid Chisnall    if (__cntrl_)
42087a984708SDavid Chisnall        __cntrl_->__add_shared();
42097a984708SDavid Chisnall}
42107a984708SDavid Chisnall
42117a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
42127a984708SDavid Chisnall
42137a984708SDavid Chisnalltemplate<class _Tp>
42149729cf09SDimitry Andricinline
42157a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
42167a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
42177a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
42187a984708SDavid Chisnall{
42197a984708SDavid Chisnall    __r.__ptr_ = 0;
42207a984708SDavid Chisnall    __r.__cntrl_ = 0;
42217a984708SDavid Chisnall}
42227a984708SDavid Chisnall
42237a984708SDavid Chisnalltemplate<class _Tp>
42247a984708SDavid Chisnalltemplate<class _Yp>
42259729cf09SDimitry Andricinline
42267a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
42277a848d17SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
42287a984708SDavid Chisnall         _NOEXCEPT
42297a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
42307a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
42317a984708SDavid Chisnall{
42327a984708SDavid Chisnall    __r.__ptr_ = 0;
42337a984708SDavid Chisnall    __r.__cntrl_ = 0;
42347a984708SDavid Chisnall}
42357a984708SDavid Chisnall
42367a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
42377a984708SDavid Chisnall
4238540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
42397a984708SDavid Chisnalltemplate<class _Tp>
4240d72607e9SDimitry Andrictemplate<class _Yp>
42417a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
4242d72607e9SDimitry Andricshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
42437a984708SDavid Chisnall#else
4244d72607e9SDimitry Andricshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r,
42457a984708SDavid Chisnall#endif
4246d72607e9SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
42477a984708SDavid Chisnall    : __ptr_(__r.get())
42487a984708SDavid Chisnall{
42497a984708SDavid Chisnall    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
42507a984708SDavid Chisnall    __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
42517c82a1ecSDimitry Andric    __enable_weak_this(__r.get(), __r.get());
42527a984708SDavid Chisnall    __r.release();
42537a984708SDavid Chisnall}
4254540d2a8bSDimitry Andric#endif
42557a984708SDavid Chisnall
42567a984708SDavid Chisnalltemplate<class _Tp>
4257d72607e9SDimitry Andrictemplate <class _Yp, class _Dp>
42587a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
42597a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
42607a984708SDavid Chisnall#else
42617a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
42627a984708SDavid Chisnall#endif
4263d72607e9SDimitry Andric                            typename enable_if
4264d72607e9SDimitry Andric                            <
4265d72607e9SDimitry Andric                                !is_lvalue_reference<_Dp>::value &&
4266d72607e9SDimitry Andric                                !is_array<_Yp>::value &&
4267d72607e9SDimitry Andric                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
4268d72607e9SDimitry Andric                                __nat
4269d72607e9SDimitry Andric                            >::type)
42707a984708SDavid Chisnall    : __ptr_(__r.get())
42717a984708SDavid Chisnall{
4272854fa44bSDimitry Andric#if _LIBCPP_STD_VER > 11
4273854fa44bSDimitry Andric    if (__ptr_ == nullptr)
4274854fa44bSDimitry Andric        __cntrl_ = nullptr;
4275854fa44bSDimitry Andric    else
4276854fa44bSDimitry Andric#endif
4277854fa44bSDimitry Andric    {
4278302affcbSDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
4279302affcbSDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
4280302affcbSDimitry Andric        __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
42817c82a1ecSDimitry Andric        __enable_weak_this(__r.get(), __r.get());
4282854fa44bSDimitry Andric    }
42837a984708SDavid Chisnall    __r.release();
42847a984708SDavid Chisnall}
42857a984708SDavid Chisnall
42867a984708SDavid Chisnalltemplate<class _Tp>
4287d72607e9SDimitry Andrictemplate <class _Yp, class _Dp>
42887a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
42897a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
42907a984708SDavid Chisnall#else
42917a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
42927a984708SDavid Chisnall#endif
4293d72607e9SDimitry Andric                            typename enable_if
4294d72607e9SDimitry Andric                            <
4295d72607e9SDimitry Andric                                is_lvalue_reference<_Dp>::value &&
4296d72607e9SDimitry Andric                                !is_array<_Yp>::value &&
4297d72607e9SDimitry Andric                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
4298d72607e9SDimitry Andric                                __nat
4299d72607e9SDimitry Andric                            >::type)
43007a984708SDavid Chisnall    : __ptr_(__r.get())
43017a984708SDavid Chisnall{
4302854fa44bSDimitry Andric#if _LIBCPP_STD_VER > 11
4303854fa44bSDimitry Andric    if (__ptr_ == nullptr)
4304854fa44bSDimitry Andric        __cntrl_ = nullptr;
4305854fa44bSDimitry Andric    else
4306854fa44bSDimitry Andric#endif
4307854fa44bSDimitry Andric    {
4308302affcbSDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
43097a984708SDavid Chisnall        typedef __shared_ptr_pointer<_Yp*,
43107a984708SDavid Chisnall                                     reference_wrapper<typename remove_reference<_Dp>::type>,
4311302affcbSDimitry Andric                                     _AllocT > _CntrlBlk;
4312302affcbSDimitry Andric        __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), _AllocT());
43137c82a1ecSDimitry Andric        __enable_weak_this(__r.get(), __r.get());
4314854fa44bSDimitry Andric    }
43157a984708SDavid Chisnall    __r.release();
43167a984708SDavid Chisnall}
43177a984708SDavid Chisnall
43187a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
43197a984708SDavid Chisnall
43207a984708SDavid Chisnalltemplate<class _Tp>
43217a984708SDavid Chisnalltemplate<class ..._Args>
43227a984708SDavid Chisnallshared_ptr<_Tp>
43237a984708SDavid Chisnallshared_ptr<_Tp>::make_shared(_Args&& ...__args)
43247a984708SDavid Chisnall{
4325b2c7081bSDimitry Andric    static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared" );
43267a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
43277a984708SDavid Chisnall    typedef allocator<_CntrlBlk> _A2;
43287a984708SDavid Chisnall    typedef __allocator_destructor<_A2> _D2;
43297a984708SDavid Chisnall    _A2 __a2;
43307a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
43317a984708SDavid Chisnall    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
43327a984708SDavid Chisnall    shared_ptr<_Tp> __r;
43337a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
43347a984708SDavid Chisnall    __r.__cntrl_ = __hold2.release();
43357c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
43367a984708SDavid Chisnall    return __r;
43377a984708SDavid Chisnall}
43387a984708SDavid Chisnall
43397a984708SDavid Chisnalltemplate<class _Tp>
43407a984708SDavid Chisnalltemplate<class _Alloc, class ..._Args>
43417a984708SDavid Chisnallshared_ptr<_Tp>
43427a984708SDavid Chisnallshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args)
43437a984708SDavid Chisnall{
4344b2c7081bSDimitry Andric    static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared" );
43457a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
4346d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
43477a984708SDavid Chisnall    typedef __allocator_destructor<_A2> _D2;
43487a984708SDavid Chisnall    _A2 __a2(__a);
43497a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
4350d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
4351d72607e9SDimitry Andric        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
43527a984708SDavid Chisnall    shared_ptr<_Tp> __r;
43537a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
4354d72607e9SDimitry Andric    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
43557c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
43567a984708SDavid Chisnall    return __r;
43577a984708SDavid Chisnall}
43587a984708SDavid Chisnall
43597a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
43607a984708SDavid Chisnall
43617a984708SDavid Chisnalltemplate<class _Tp>
43627a984708SDavid Chisnallshared_ptr<_Tp>
43637a984708SDavid Chisnallshared_ptr<_Tp>::make_shared()
43647a984708SDavid Chisnall{
4365b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp>::value), "Can't construct object in make_shared" );
43667a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
43677a984708SDavid Chisnall    typedef allocator<_CntrlBlk> _Alloc2;
43687a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
43697a984708SDavid Chisnall    _Alloc2 __alloc2;
43707a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
43717a984708SDavid Chisnall    ::new(__hold2.get()) _CntrlBlk(__alloc2);
43727a984708SDavid Chisnall    shared_ptr<_Tp> __r;
43737a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
43747a984708SDavid Chisnall    __r.__cntrl_ = __hold2.release();
43757c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
43767a984708SDavid Chisnall    return __r;
43777a984708SDavid Chisnall}
43787a984708SDavid Chisnall
43797a984708SDavid Chisnalltemplate<class _Tp>
43807a984708SDavid Chisnalltemplate<class _A0>
43817a984708SDavid Chisnallshared_ptr<_Tp>
43827a984708SDavid Chisnallshared_ptr<_Tp>::make_shared(_A0& __a0)
43837a984708SDavid Chisnall{
4384b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp, _A0>::value), "Can't construct object in make_shared" );
43857a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
43867a984708SDavid Chisnall    typedef allocator<_CntrlBlk> _Alloc2;
43877a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
43887a984708SDavid Chisnall    _Alloc2 __alloc2;
43897a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
43907a984708SDavid Chisnall    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0);
43917a984708SDavid Chisnall    shared_ptr<_Tp> __r;
43927a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
43937a984708SDavid Chisnall    __r.__cntrl_ = __hold2.release();
43947c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
43957a984708SDavid Chisnall    return __r;
43967a984708SDavid Chisnall}
43977a984708SDavid Chisnall
43987a984708SDavid Chisnalltemplate<class _Tp>
43997a984708SDavid Chisnalltemplate<class _A0, class _A1>
44007a984708SDavid Chisnallshared_ptr<_Tp>
44017a984708SDavid Chisnallshared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1)
44027a984708SDavid Chisnall{
4403b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp, _A0, _A1>::value), "Can't construct object in make_shared" );
44047a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
44057a984708SDavid Chisnall    typedef allocator<_CntrlBlk> _Alloc2;
44067a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
44077a984708SDavid Chisnall    _Alloc2 __alloc2;
44087a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
44097a984708SDavid Chisnall    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1);
44107a984708SDavid Chisnall    shared_ptr<_Tp> __r;
44117a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
44127a984708SDavid Chisnall    __r.__cntrl_ = __hold2.release();
44137c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
44147a984708SDavid Chisnall    return __r;
44157a984708SDavid Chisnall}
44167a984708SDavid Chisnall
44177a984708SDavid Chisnalltemplate<class _Tp>
44187a984708SDavid Chisnalltemplate<class _A0, class _A1, class _A2>
44197a984708SDavid Chisnallshared_ptr<_Tp>
44207a984708SDavid Chisnallshared_ptr<_Tp>::make_shared(_A0& __a0, _A1& __a1, _A2& __a2)
44217a984708SDavid Chisnall{
4422b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't construct object in make_shared" );
44237a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
44247a984708SDavid Chisnall    typedef allocator<_CntrlBlk> _Alloc2;
44257a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
44267a984708SDavid Chisnall    _Alloc2 __alloc2;
44277a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
44287a984708SDavid Chisnall    ::new(__hold2.get()) _CntrlBlk(__alloc2, __a0, __a1, __a2);
44297a984708SDavid Chisnall    shared_ptr<_Tp> __r;
44307a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
44317a984708SDavid Chisnall    __r.__cntrl_ = __hold2.release();
44327c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
44337a984708SDavid Chisnall    return __r;
44347a984708SDavid Chisnall}
44357a984708SDavid Chisnall
44367a984708SDavid Chisnalltemplate<class _Tp>
44377a984708SDavid Chisnalltemplate<class _Alloc>
44387a984708SDavid Chisnallshared_ptr<_Tp>
44397a984708SDavid Chisnallshared_ptr<_Tp>::allocate_shared(const _Alloc& __a)
44407a984708SDavid Chisnall{
4441b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp>::value), "Can't construct object in allocate_shared" );
44427a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
4443d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
44447a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
44457a984708SDavid Chisnall    _Alloc2 __alloc2(__a);
44467a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
4447d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
4448d72607e9SDimitry Andric        _CntrlBlk(__a);
44497a984708SDavid Chisnall    shared_ptr<_Tp> __r;
44507a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
4451d72607e9SDimitry Andric    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
44527c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
44537a984708SDavid Chisnall    return __r;
44547a984708SDavid Chisnall}
44557a984708SDavid Chisnall
44567a984708SDavid Chisnalltemplate<class _Tp>
44577a984708SDavid Chisnalltemplate<class _Alloc, class _A0>
44587a984708SDavid Chisnallshared_ptr<_Tp>
44597a984708SDavid Chisnallshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0)
44607a984708SDavid Chisnall{
4461b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp, _A0>::value), "Can't construct object in allocate_shared" );
44627a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
4463d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
44647a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
44657a984708SDavid Chisnall    _Alloc2 __alloc2(__a);
44667a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
4467d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
4468d72607e9SDimitry Andric        _CntrlBlk(__a, __a0);
44697a984708SDavid Chisnall    shared_ptr<_Tp> __r;
44707a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
4471d72607e9SDimitry Andric    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
44727c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
44737a984708SDavid Chisnall    return __r;
44747a984708SDavid Chisnall}
44757a984708SDavid Chisnall
44767a984708SDavid Chisnalltemplate<class _Tp>
44777a984708SDavid Chisnalltemplate<class _Alloc, class _A0, class _A1>
44787a984708SDavid Chisnallshared_ptr<_Tp>
44797a984708SDavid Chisnallshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)
44807a984708SDavid Chisnall{
4481b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp, _A0, _A1>::value), "Can't construct object in allocate_shared" );
44827a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
4483d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
44847a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
44857a984708SDavid Chisnall    _Alloc2 __alloc2(__a);
44867a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
4487d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
4488d72607e9SDimitry Andric        _CntrlBlk(__a, __a0, __a1);
44897a984708SDavid Chisnall    shared_ptr<_Tp> __r;
44907a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
4491d72607e9SDimitry Andric    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
44927c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
44937a984708SDavid Chisnall    return __r;
44947a984708SDavid Chisnall}
44957a984708SDavid Chisnall
44967a984708SDavid Chisnalltemplate<class _Tp>
44977a984708SDavid Chisnalltemplate<class _Alloc, class _A0, class _A1, class _A2>
44987a984708SDavid Chisnallshared_ptr<_Tp>
44997a984708SDavid Chisnallshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)
45007a984708SDavid Chisnall{
4501b2c7081bSDimitry Andric    static_assert((is_constructible<_Tp, _A0, _A1, _A2>::value), "Can't construct object in allocate_shared" );
45027a984708SDavid Chisnall    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
4503d72607e9SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _Alloc2;
45047a984708SDavid Chisnall    typedef __allocator_destructor<_Alloc2> _D2;
45057a984708SDavid Chisnall    _Alloc2 __alloc2(__a);
45067a984708SDavid Chisnall    unique_ptr<_CntrlBlk, _D2> __hold2(__alloc2.allocate(1), _D2(__alloc2, 1));
4507d72607e9SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
4508d72607e9SDimitry Andric        _CntrlBlk(__a, __a0, __a1, __a2);
45097a984708SDavid Chisnall    shared_ptr<_Tp> __r;
45107a984708SDavid Chisnall    __r.__ptr_ = __hold2.get()->get();
4511d72607e9SDimitry Andric    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
45127c82a1ecSDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
45137a984708SDavid Chisnall    return __r;
45147a984708SDavid Chisnall}
45157a984708SDavid Chisnall
45167a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
45177a984708SDavid Chisnall
45187a984708SDavid Chisnalltemplate<class _Tp>
45197a984708SDavid Chisnallshared_ptr<_Tp>::~shared_ptr()
45207a984708SDavid Chisnall{
45217a984708SDavid Chisnall    if (__cntrl_)
45227a984708SDavid Chisnall        __cntrl_->__release_shared();
45237a984708SDavid Chisnall}
45247a984708SDavid Chisnall
45257a984708SDavid Chisnalltemplate<class _Tp>
45269729cf09SDimitry Andricinline
45277a984708SDavid Chisnallshared_ptr<_Tp>&
45287a984708SDavid Chisnallshared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
45297a984708SDavid Chisnall{
45307a984708SDavid Chisnall    shared_ptr(__r).swap(*this);
45317a984708SDavid Chisnall    return *this;
45327a984708SDavid Chisnall}
45337a984708SDavid Chisnall
45347a984708SDavid Chisnalltemplate<class _Tp>
45357a984708SDavid Chisnalltemplate<class _Yp>
45369729cf09SDimitry Andricinline
453794e3ee44SDavid Chisnalltypename enable_if
453894e3ee44SDavid Chisnall<
45397a848d17SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
45407a984708SDavid Chisnall    shared_ptr<_Tp>&
454194e3ee44SDavid Chisnall>::type
45427a984708SDavid Chisnallshared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
45437a984708SDavid Chisnall{
45447a984708SDavid Chisnall    shared_ptr(__r).swap(*this);
45457a984708SDavid Chisnall    return *this;
45467a984708SDavid Chisnall}
45477a984708SDavid Chisnall
45487a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
45497a984708SDavid Chisnall
45507a984708SDavid Chisnalltemplate<class _Tp>
45519729cf09SDimitry Andricinline
45527a984708SDavid Chisnallshared_ptr<_Tp>&
45537a984708SDavid Chisnallshared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
45547a984708SDavid Chisnall{
45557a984708SDavid Chisnall    shared_ptr(_VSTD::move(__r)).swap(*this);
45567a984708SDavid Chisnall    return *this;
45577a984708SDavid Chisnall}
45587a984708SDavid Chisnall
45597a984708SDavid Chisnalltemplate<class _Tp>
45607a984708SDavid Chisnalltemplate<class _Yp>
45619729cf09SDimitry Andricinline
456294e3ee44SDavid Chisnalltypename enable_if
456394e3ee44SDavid Chisnall<
45647a848d17SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
45657a984708SDavid Chisnall    shared_ptr<_Tp>&
456694e3ee44SDavid Chisnall>::type
45677a984708SDavid Chisnallshared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
45687a984708SDavid Chisnall{
45697a984708SDavid Chisnall    shared_ptr(_VSTD::move(__r)).swap(*this);
45707a984708SDavid Chisnall    return *this;
45717a984708SDavid Chisnall}
45727a984708SDavid Chisnall
4573540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
45747a984708SDavid Chisnalltemplate<class _Tp>
45757a984708SDavid Chisnalltemplate<class _Yp>
45769729cf09SDimitry Andricinline
457794e3ee44SDavid Chisnalltypename enable_if
457894e3ee44SDavid Chisnall<
457994e3ee44SDavid Chisnall    !is_array<_Yp>::value &&
45807a848d17SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
45814f7ab58eSDimitry Andric    shared_ptr<_Tp>
45824f7ab58eSDimitry Andric>::type&
45837a984708SDavid Chisnallshared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
45847a984708SDavid Chisnall{
45857a984708SDavid Chisnall    shared_ptr(_VSTD::move(__r)).swap(*this);
45867a984708SDavid Chisnall    return *this;
45877a984708SDavid Chisnall}
4588540d2a8bSDimitry Andric#endif
45897a984708SDavid Chisnall
45907a984708SDavid Chisnalltemplate<class _Tp>
45917a984708SDavid Chisnalltemplate <class _Yp, class _Dp>
45929729cf09SDimitry Andricinline
459394e3ee44SDavid Chisnalltypename enable_if
459494e3ee44SDavid Chisnall<
459594e3ee44SDavid Chisnall    !is_array<_Yp>::value &&
45967a848d17SDimitry Andric    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
45977a848d17SDimitry Andric                   typename shared_ptr<_Tp>::element_type*>::value,
45987a984708SDavid Chisnall    shared_ptr<_Tp>&
459994e3ee44SDavid Chisnall>::type
46007a984708SDavid Chisnallshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
46017a984708SDavid Chisnall{
46027a984708SDavid Chisnall    shared_ptr(_VSTD::move(__r)).swap(*this);
46037a984708SDavid Chisnall    return *this;
46047a984708SDavid Chisnall}
46057a984708SDavid Chisnall
46067a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
46077a984708SDavid Chisnall
4608540d2a8bSDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
46097a984708SDavid Chisnalltemplate<class _Tp>
46107a984708SDavid Chisnalltemplate<class _Yp>
46117a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
461294e3ee44SDavid Chisnalltypename enable_if
461394e3ee44SDavid Chisnall<
461494e3ee44SDavid Chisnall    !is_array<_Yp>::value &&
46157a848d17SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
46167a984708SDavid Chisnall    shared_ptr<_Tp>&
461794e3ee44SDavid Chisnall>::type
46187a984708SDavid Chisnallshared_ptr<_Tp>::operator=(auto_ptr<_Yp> __r)
46197a984708SDavid Chisnall{
46207a984708SDavid Chisnall    shared_ptr(__r).swap(*this);
46217a984708SDavid Chisnall    return *this;
46227a984708SDavid Chisnall}
4623540d2a8bSDimitry Andric#endif
46247a984708SDavid Chisnall
46257a984708SDavid Chisnalltemplate<class _Tp>
46267a984708SDavid Chisnalltemplate <class _Yp, class _Dp>
46277a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
462894e3ee44SDavid Chisnalltypename enable_if
462994e3ee44SDavid Chisnall<
463094e3ee44SDavid Chisnall    !is_array<_Yp>::value &&
46317a848d17SDimitry Andric    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
46327a848d17SDimitry Andric                   typename shared_ptr<_Tp>::element_type*>::value,
46337a984708SDavid Chisnall    shared_ptr<_Tp>&
463494e3ee44SDavid Chisnall>::type
46357a984708SDavid Chisnallshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp> __r)
46367a984708SDavid Chisnall{
46377a984708SDavid Chisnall    shared_ptr(_VSTD::move(__r)).swap(*this);
46387a984708SDavid Chisnall    return *this;
46397a984708SDavid Chisnall}
46407a984708SDavid Chisnall
46417a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
46427a984708SDavid Chisnall
46437a984708SDavid Chisnalltemplate<class _Tp>
46449729cf09SDimitry Andricinline
46457a984708SDavid Chisnallvoid
46467a984708SDavid Chisnallshared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
46477a984708SDavid Chisnall{
46487a984708SDavid Chisnall    _VSTD::swap(__ptr_, __r.__ptr_);
46497a984708SDavid Chisnall    _VSTD::swap(__cntrl_, __r.__cntrl_);
46507a984708SDavid Chisnall}
46517a984708SDavid Chisnall
46527a984708SDavid Chisnalltemplate<class _Tp>
46539729cf09SDimitry Andricinline
46547a984708SDavid Chisnallvoid
46557a984708SDavid Chisnallshared_ptr<_Tp>::reset() _NOEXCEPT
46567a984708SDavid Chisnall{
46577a984708SDavid Chisnall    shared_ptr().swap(*this);
46587a984708SDavid Chisnall}
46597a984708SDavid Chisnall
46607a984708SDavid Chisnalltemplate<class _Tp>
46617a984708SDavid Chisnalltemplate<class _Yp>
46629729cf09SDimitry Andricinline
466394e3ee44SDavid Chisnalltypename enable_if
466494e3ee44SDavid Chisnall<
46657a848d17SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
46667a984708SDavid Chisnall    void
466794e3ee44SDavid Chisnall>::type
46687a984708SDavid Chisnallshared_ptr<_Tp>::reset(_Yp* __p)
46697a984708SDavid Chisnall{
46707a984708SDavid Chisnall    shared_ptr(__p).swap(*this);
46717a984708SDavid Chisnall}
46727a984708SDavid Chisnall
46737a984708SDavid Chisnalltemplate<class _Tp>
46747a984708SDavid Chisnalltemplate<class _Yp, class _Dp>
46759729cf09SDimitry Andricinline
467694e3ee44SDavid Chisnalltypename enable_if
467794e3ee44SDavid Chisnall<
46787a848d17SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
46797a984708SDavid Chisnall    void
468094e3ee44SDavid Chisnall>::type
46817a984708SDavid Chisnallshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
46827a984708SDavid Chisnall{
46837a984708SDavid Chisnall    shared_ptr(__p, __d).swap(*this);
46847a984708SDavid Chisnall}
46857a984708SDavid Chisnall
46867a984708SDavid Chisnalltemplate<class _Tp>
46877a984708SDavid Chisnalltemplate<class _Yp, class _Dp, class _Alloc>
46889729cf09SDimitry Andricinline
468994e3ee44SDavid Chisnalltypename enable_if
469094e3ee44SDavid Chisnall<
46917a848d17SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
46927a984708SDavid Chisnall    void
469394e3ee44SDavid Chisnall>::type
46947a984708SDavid Chisnallshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
46957a984708SDavid Chisnall{
46967a984708SDavid Chisnall    shared_ptr(__p, __d, __a).swap(*this);
46977a984708SDavid Chisnall}
46987a984708SDavid Chisnall
46997a984708SDavid Chisnall#ifndef _LIBCPP_HAS_NO_VARIADICS
47007a984708SDavid Chisnall
47017a984708SDavid Chisnalltemplate<class _Tp, class ..._Args>
47027a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
470394e3ee44SDavid Chisnalltypename enable_if
470494e3ee44SDavid Chisnall<
470594e3ee44SDavid Chisnall    !is_array<_Tp>::value,
47067a984708SDavid Chisnall    shared_ptr<_Tp>
470794e3ee44SDavid Chisnall>::type
47087a984708SDavid Chisnallmake_shared(_Args&& ...__args)
47097a984708SDavid Chisnall{
47107a984708SDavid Chisnall    return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
47117a984708SDavid Chisnall}
47127a984708SDavid Chisnall
47137a984708SDavid Chisnalltemplate<class _Tp, class _Alloc, class ..._Args>
47147a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
471594e3ee44SDavid Chisnalltypename enable_if
471694e3ee44SDavid Chisnall<
471794e3ee44SDavid Chisnall    !is_array<_Tp>::value,
47187a984708SDavid Chisnall    shared_ptr<_Tp>
471994e3ee44SDavid Chisnall>::type
47207a984708SDavid Chisnallallocate_shared(const _Alloc& __a, _Args&& ...__args)
47217a984708SDavid Chisnall{
47227a984708SDavid Chisnall    return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...);
47237a984708SDavid Chisnall}
47247a984708SDavid Chisnall
47257a984708SDavid Chisnall#else  // _LIBCPP_HAS_NO_VARIADICS
47267a984708SDavid Chisnall
47277a984708SDavid Chisnalltemplate<class _Tp>
47287a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47297a984708SDavid Chisnallshared_ptr<_Tp>
47307a984708SDavid Chisnallmake_shared()
47317a984708SDavid Chisnall{
47327a984708SDavid Chisnall    return shared_ptr<_Tp>::make_shared();
47337a984708SDavid Chisnall}
47347a984708SDavid Chisnall
47357a984708SDavid Chisnalltemplate<class _Tp, class _A0>
47367a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47377a984708SDavid Chisnallshared_ptr<_Tp>
47387a984708SDavid Chisnallmake_shared(_A0& __a0)
47397a984708SDavid Chisnall{
47407a984708SDavid Chisnall    return shared_ptr<_Tp>::make_shared(__a0);
47417a984708SDavid Chisnall}
47427a984708SDavid Chisnall
47437a984708SDavid Chisnalltemplate<class _Tp, class _A0, class _A1>
47447a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47457a984708SDavid Chisnallshared_ptr<_Tp>
47467a984708SDavid Chisnallmake_shared(_A0& __a0, _A1& __a1)
47477a984708SDavid Chisnall{
47487a984708SDavid Chisnall    return shared_ptr<_Tp>::make_shared(__a0, __a1);
47497a984708SDavid Chisnall}
47507a984708SDavid Chisnall
47517a984708SDavid Chisnalltemplate<class _Tp, class _A0, class _A1, class _A2>
47527a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47537a984708SDavid Chisnallshared_ptr<_Tp>
47547a984708SDavid Chisnallmake_shared(_A0& __a0, _A1& __a1, _A2& __a2)
47557a984708SDavid Chisnall{
47567a984708SDavid Chisnall    return shared_ptr<_Tp>::make_shared(__a0, __a1, __a2);
47577a984708SDavid Chisnall}
47587a984708SDavid Chisnall
47597a984708SDavid Chisnalltemplate<class _Tp, class _Alloc>
47607a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47617a984708SDavid Chisnallshared_ptr<_Tp>
47627a984708SDavid Chisnallallocate_shared(const _Alloc& __a)
47637a984708SDavid Chisnall{
47647a984708SDavid Chisnall    return shared_ptr<_Tp>::allocate_shared(__a);
47657a984708SDavid Chisnall}
47667a984708SDavid Chisnall
47677a984708SDavid Chisnalltemplate<class _Tp, class _Alloc, class _A0>
47687a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47697a984708SDavid Chisnallshared_ptr<_Tp>
47707a984708SDavid Chisnallallocate_shared(const _Alloc& __a, _A0& __a0)
47717a984708SDavid Chisnall{
47727a984708SDavid Chisnall    return shared_ptr<_Tp>::allocate_shared(__a, __a0);
47737a984708SDavid Chisnall}
47747a984708SDavid Chisnall
47757a984708SDavid Chisnalltemplate<class _Tp, class _Alloc, class _A0, class _A1>
47767a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47777a984708SDavid Chisnallshared_ptr<_Tp>
47787a984708SDavid Chisnallallocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1)
47797a984708SDavid Chisnall{
47807a984708SDavid Chisnall    return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1);
47817a984708SDavid Chisnall}
47827a984708SDavid Chisnall
47837a984708SDavid Chisnalltemplate<class _Tp, class _Alloc, class _A0, class _A1, class _A2>
47847a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47857a984708SDavid Chisnallshared_ptr<_Tp>
47867a984708SDavid Chisnallallocate_shared(const _Alloc& __a, _A0& __a0, _A1& __a1, _A2& __a2)
47877a984708SDavid Chisnall{
47887a984708SDavid Chisnall    return shared_ptr<_Tp>::allocate_shared(__a, __a0, __a1, __a2);
47897a984708SDavid Chisnall}
47907a984708SDavid Chisnall
47917a984708SDavid Chisnall#endif  // _LIBCPP_HAS_NO_VARIADICS
47927a984708SDavid Chisnall
47937a984708SDavid Chisnalltemplate<class _Tp, class _Up>
47947a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
47957a984708SDavid Chisnallbool
47967a984708SDavid Chisnalloperator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
47977a984708SDavid Chisnall{
47987a984708SDavid Chisnall    return __x.get() == __y.get();
47997a984708SDavid Chisnall}
48007a984708SDavid Chisnall
48017a984708SDavid Chisnalltemplate<class _Tp, class _Up>
48027a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
48037a984708SDavid Chisnallbool
48047a984708SDavid Chisnalloperator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
48057a984708SDavid Chisnall{
48067a984708SDavid Chisnall    return !(__x == __y);
48077a984708SDavid Chisnall}
48087a984708SDavid Chisnall
48097a984708SDavid Chisnalltemplate<class _Tp, class _Up>
48107a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
48117a984708SDavid Chisnallbool
48127a984708SDavid Chisnalloperator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
48137a984708SDavid Chisnall{
48144ba319b5SDimitry Andric#if _LIBCPP_STD_VER <= 11
4815854fa44bSDimitry Andric    typedef typename common_type<_Tp*, _Up*>::type _Vp;
4816854fa44bSDimitry Andric    return less<_Vp>()(__x.get(), __y.get());
48174ba319b5SDimitry Andric#else
48184ba319b5SDimitry Andric    return less<>()(__x.get(), __y.get());
48194ba319b5SDimitry Andric#endif
48204ba319b5SDimitry Andric
482194e3ee44SDavid Chisnall}
482294e3ee44SDavid Chisnall
482394e3ee44SDavid Chisnalltemplate<class _Tp, class _Up>
482494e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
482594e3ee44SDavid Chisnallbool
482694e3ee44SDavid Chisnalloperator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
482794e3ee44SDavid Chisnall{
482894e3ee44SDavid Chisnall    return __y < __x;
482994e3ee44SDavid Chisnall}
483094e3ee44SDavid Chisnall
483194e3ee44SDavid Chisnalltemplate<class _Tp, class _Up>
483294e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
483394e3ee44SDavid Chisnallbool
483494e3ee44SDavid Chisnalloperator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
483594e3ee44SDavid Chisnall{
483694e3ee44SDavid Chisnall    return !(__y < __x);
483794e3ee44SDavid Chisnall}
483894e3ee44SDavid Chisnall
483994e3ee44SDavid Chisnalltemplate<class _Tp, class _Up>
484094e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
484194e3ee44SDavid Chisnallbool
484294e3ee44SDavid Chisnalloperator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
484394e3ee44SDavid Chisnall{
484494e3ee44SDavid Chisnall    return !(__x < __y);
484594e3ee44SDavid Chisnall}
484694e3ee44SDavid Chisnall
484794e3ee44SDavid Chisnalltemplate<class _Tp>
484894e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
484994e3ee44SDavid Chisnallbool
485094e3ee44SDavid Chisnalloperator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
485194e3ee44SDavid Chisnall{
485294e3ee44SDavid Chisnall    return !__x;
485394e3ee44SDavid Chisnall}
485494e3ee44SDavid Chisnall
485594e3ee44SDavid Chisnalltemplate<class _Tp>
485694e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
485794e3ee44SDavid Chisnallbool
485894e3ee44SDavid Chisnalloperator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
485994e3ee44SDavid Chisnall{
486094e3ee44SDavid Chisnall    return !__x;
486194e3ee44SDavid Chisnall}
486294e3ee44SDavid Chisnall
486394e3ee44SDavid Chisnalltemplate<class _Tp>
486494e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
486594e3ee44SDavid Chisnallbool
486694e3ee44SDavid Chisnalloperator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
486794e3ee44SDavid Chisnall{
486894e3ee44SDavid Chisnall    return static_cast<bool>(__x);
486994e3ee44SDavid Chisnall}
487094e3ee44SDavid Chisnall
487194e3ee44SDavid Chisnalltemplate<class _Tp>
487294e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
487394e3ee44SDavid Chisnallbool
487494e3ee44SDavid Chisnalloperator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
487594e3ee44SDavid Chisnall{
487694e3ee44SDavid Chisnall    return static_cast<bool>(__x);
487794e3ee44SDavid Chisnall}
487894e3ee44SDavid Chisnall
487994e3ee44SDavid Chisnalltemplate<class _Tp>
488094e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
488194e3ee44SDavid Chisnallbool
488294e3ee44SDavid Chisnalloperator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
488394e3ee44SDavid Chisnall{
488494e3ee44SDavid Chisnall    return less<_Tp*>()(__x.get(), nullptr);
488594e3ee44SDavid Chisnall}
488694e3ee44SDavid Chisnall
488794e3ee44SDavid Chisnalltemplate<class _Tp>
488894e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
488994e3ee44SDavid Chisnallbool
489094e3ee44SDavid Chisnalloperator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
489194e3ee44SDavid Chisnall{
489294e3ee44SDavid Chisnall    return less<_Tp*>()(nullptr, __x.get());
489394e3ee44SDavid Chisnall}
489494e3ee44SDavid Chisnall
489594e3ee44SDavid Chisnalltemplate<class _Tp>
489694e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
489794e3ee44SDavid Chisnallbool
489894e3ee44SDavid Chisnalloperator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
489994e3ee44SDavid Chisnall{
490094e3ee44SDavid Chisnall    return nullptr < __x;
490194e3ee44SDavid Chisnall}
490294e3ee44SDavid Chisnall
490394e3ee44SDavid Chisnalltemplate<class _Tp>
490494e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
490594e3ee44SDavid Chisnallbool
490694e3ee44SDavid Chisnalloperator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
490794e3ee44SDavid Chisnall{
490894e3ee44SDavid Chisnall    return __x < nullptr;
490994e3ee44SDavid Chisnall}
491094e3ee44SDavid Chisnall
491194e3ee44SDavid Chisnalltemplate<class _Tp>
491294e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
491394e3ee44SDavid Chisnallbool
491494e3ee44SDavid Chisnalloperator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
491594e3ee44SDavid Chisnall{
491694e3ee44SDavid Chisnall    return !(nullptr < __x);
491794e3ee44SDavid Chisnall}
491894e3ee44SDavid Chisnall
491994e3ee44SDavid Chisnalltemplate<class _Tp>
492094e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
492194e3ee44SDavid Chisnallbool
492294e3ee44SDavid Chisnalloperator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
492394e3ee44SDavid Chisnall{
492494e3ee44SDavid Chisnall    return !(__x < nullptr);
492594e3ee44SDavid Chisnall}
492694e3ee44SDavid Chisnall
492794e3ee44SDavid Chisnalltemplate<class _Tp>
492894e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
492994e3ee44SDavid Chisnallbool
493094e3ee44SDavid Chisnalloperator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
493194e3ee44SDavid Chisnall{
493294e3ee44SDavid Chisnall    return !(__x < nullptr);
493394e3ee44SDavid Chisnall}
493494e3ee44SDavid Chisnall
493594e3ee44SDavid Chisnalltemplate<class _Tp>
493694e3ee44SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
493794e3ee44SDavid Chisnallbool
493894e3ee44SDavid Chisnalloperator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
493994e3ee44SDavid Chisnall{
494094e3ee44SDavid Chisnall    return !(nullptr < __x);
49417a984708SDavid Chisnall}
49427a984708SDavid Chisnall
49437a984708SDavid Chisnalltemplate<class _Tp>
49447a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
49457a984708SDavid Chisnallvoid
49467a984708SDavid Chisnallswap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
49477a984708SDavid Chisnall{
49487a984708SDavid Chisnall    __x.swap(__y);
49497a984708SDavid Chisnall}
49507a984708SDavid Chisnall
49517a984708SDavid Chisnalltemplate<class _Tp, class _Up>
49527a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
495394e3ee44SDavid Chisnalltypename enable_if
495494e3ee44SDavid Chisnall<
495594e3ee44SDavid Chisnall    !is_array<_Tp>::value && !is_array<_Up>::value,
49567a984708SDavid Chisnall    shared_ptr<_Tp>
495794e3ee44SDavid Chisnall>::type
49587a984708SDavid Chisnallstatic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
49597a984708SDavid Chisnall{
49607a984708SDavid Chisnall    return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
49617a984708SDavid Chisnall}
49627a984708SDavid Chisnall
49637a984708SDavid Chisnalltemplate<class _Tp, class _Up>
49647a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
496594e3ee44SDavid Chisnalltypename enable_if
496694e3ee44SDavid Chisnall<
496794e3ee44SDavid Chisnall    !is_array<_Tp>::value && !is_array<_Up>::value,
49687a984708SDavid Chisnall    shared_ptr<_Tp>
496994e3ee44SDavid Chisnall>::type
49707a984708SDavid Chisnalldynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
49717a984708SDavid Chisnall{
49727a984708SDavid Chisnall    _Tp* __p = dynamic_cast<_Tp*>(__r.get());
49737a984708SDavid Chisnall    return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
49747a984708SDavid Chisnall}
49757a984708SDavid Chisnall
49767a984708SDavid Chisnalltemplate<class _Tp, class _Up>
497794e3ee44SDavid Chisnalltypename enable_if
497894e3ee44SDavid Chisnall<
497994e3ee44SDavid Chisnall    is_array<_Tp>::value == is_array<_Up>::value,
49807a984708SDavid Chisnall    shared_ptr<_Tp>
498194e3ee44SDavid Chisnall>::type
49827a984708SDavid Chisnallconst_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
49837a984708SDavid Chisnall{
498494e3ee44SDavid Chisnall    typedef typename remove_extent<_Tp>::type _RTp;
498594e3ee44SDavid Chisnall    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
49867a984708SDavid Chisnall}
49877a984708SDavid Chisnall
49887a984708SDavid Chisnall#ifndef _LIBCPP_NO_RTTI
49897a984708SDavid Chisnall
49907a984708SDavid Chisnalltemplate<class _Dp, class _Tp>
49917a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
49927a984708SDavid Chisnall_Dp*
49937a984708SDavid Chisnallget_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
49947a984708SDavid Chisnall{
49957a984708SDavid Chisnall    return __p.template __get_deleter<_Dp>();
49967a984708SDavid Chisnall}
49977a984708SDavid Chisnall
49987a984708SDavid Chisnall#endif  // _LIBCPP_NO_RTTI
49997a984708SDavid Chisnall
50007a984708SDavid Chisnalltemplate<class _Tp>
5001aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS weak_ptr
50027a984708SDavid Chisnall{
50037a984708SDavid Chisnallpublic:
50047a984708SDavid Chisnall    typedef _Tp element_type;
50057a984708SDavid Chisnallprivate:
50067a984708SDavid Chisnall    element_type*        __ptr_;
50077a984708SDavid Chisnall    __shared_weak_count* __cntrl_;
50087a984708SDavid Chisnall
50097a984708SDavid Chisnallpublic:
50109729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5011936e9439SDimitry Andric    _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
50129729cf09SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
50137a984708SDavid Chisnall                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
50147a984708SDavid Chisnall                        _NOEXCEPT;
50159729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50167a984708SDavid Chisnall    weak_ptr(weak_ptr const& __r) _NOEXCEPT;
50179729cf09SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
50187a984708SDavid Chisnall                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
50197a984708SDavid Chisnall                         _NOEXCEPT;
50207a984708SDavid Chisnall
502194e3ee44SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
50229729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
502394e3ee44SDavid Chisnall    weak_ptr(weak_ptr&& __r) _NOEXCEPT;
50249729cf09SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
502594e3ee44SDavid Chisnall                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
502694e3ee44SDavid Chisnall                         _NOEXCEPT;
502794e3ee44SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
50287a984708SDavid Chisnall    ~weak_ptr();
50297a984708SDavid Chisnall
50309729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50317a984708SDavid Chisnall    weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
503294e3ee44SDavid Chisnall    template<class _Yp>
503394e3ee44SDavid Chisnall        typename enable_if
503494e3ee44SDavid Chisnall        <
503594e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
503694e3ee44SDavid Chisnall            weak_ptr&
503794e3ee44SDavid Chisnall        >::type
50389729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
503994e3ee44SDavid Chisnall        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
504094e3ee44SDavid Chisnall
504194e3ee44SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
504294e3ee44SDavid Chisnall
50439729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
504494e3ee44SDavid Chisnall    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
504594e3ee44SDavid Chisnall    template<class _Yp>
504694e3ee44SDavid Chisnall        typename enable_if
504794e3ee44SDavid Chisnall        <
504894e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
504994e3ee44SDavid Chisnall            weak_ptr&
505094e3ee44SDavid Chisnall        >::type
50519729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
505294e3ee44SDavid Chisnall        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
505394e3ee44SDavid Chisnall
505494e3ee44SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
505594e3ee44SDavid Chisnall
505694e3ee44SDavid Chisnall    template<class _Yp>
505794e3ee44SDavid Chisnall        typename enable_if
505894e3ee44SDavid Chisnall        <
505994e3ee44SDavid Chisnall            is_convertible<_Yp*, element_type*>::value,
506094e3ee44SDavid Chisnall            weak_ptr&
506194e3ee44SDavid Chisnall        >::type
50629729cf09SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
506394e3ee44SDavid Chisnall        operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
50647a984708SDavid Chisnall
50659729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50667a984708SDavid Chisnall    void swap(weak_ptr& __r) _NOEXCEPT;
50679729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50687a984708SDavid Chisnall    void reset() _NOEXCEPT;
50697a984708SDavid Chisnall
50707a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
50717a984708SDavid Chisnall    long use_count() const _NOEXCEPT
50727a984708SDavid Chisnall        {return __cntrl_ ? __cntrl_->use_count() : 0;}
50737a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
50747a984708SDavid Chisnall    bool expired() const _NOEXCEPT
50757a984708SDavid Chisnall        {return __cntrl_ == 0 || __cntrl_->use_count() == 0;}
50767a984708SDavid Chisnall    shared_ptr<_Tp> lock() const _NOEXCEPT;
50777a984708SDavid Chisnall    template<class _Up>
50787a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
5079540d2a8bSDimitry Andric        bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
50807a984708SDavid Chisnall        {return __cntrl_ < __r.__cntrl_;}
50817a984708SDavid Chisnall    template<class _Up>
50827a984708SDavid Chisnall        _LIBCPP_INLINE_VISIBILITY
5083540d2a8bSDimitry Andric        bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
50847a984708SDavid Chisnall        {return __cntrl_ < __r.__cntrl_;}
50857a984708SDavid Chisnall
5086aed8d94eSDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
5087aed8d94eSDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
50887a984708SDavid Chisnall};
50897a984708SDavid Chisnall
50907a984708SDavid Chisnalltemplate<class _Tp>
50919729cf09SDimitry Andricinline
5092936e9439SDimitry Andric_LIBCPP_CONSTEXPR
50937a984708SDavid Chisnallweak_ptr<_Tp>::weak_ptr() _NOEXCEPT
50947a984708SDavid Chisnall    : __ptr_(0),
50957a984708SDavid Chisnall      __cntrl_(0)
50967a984708SDavid Chisnall{
50977a984708SDavid Chisnall}
50987a984708SDavid Chisnall
50997a984708SDavid Chisnalltemplate<class _Tp>
51009729cf09SDimitry Andricinline
51017a984708SDavid Chisnallweak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
51027a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
51037a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
51047a984708SDavid Chisnall{
51057a984708SDavid Chisnall    if (__cntrl_)
51067a984708SDavid Chisnall        __cntrl_->__add_weak();
51077a984708SDavid Chisnall}
51087a984708SDavid Chisnall
51097a984708SDavid Chisnalltemplate<class _Tp>
51107a984708SDavid Chisnalltemplate<class _Yp>
51119729cf09SDimitry Andricinline
51127a984708SDavid Chisnallweak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
51137a984708SDavid Chisnall                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
51147a984708SDavid Chisnall                         _NOEXCEPT
51157a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
51167a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
51177a984708SDavid Chisnall{
51187a984708SDavid Chisnall    if (__cntrl_)
51197a984708SDavid Chisnall        __cntrl_->__add_weak();
51207a984708SDavid Chisnall}
51217a984708SDavid Chisnall
51227a984708SDavid Chisnalltemplate<class _Tp>
51237a984708SDavid Chisnalltemplate<class _Yp>
51249729cf09SDimitry Andricinline
51257a984708SDavid Chisnallweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
51267a984708SDavid Chisnall                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
51277a984708SDavid Chisnall         _NOEXCEPT
51287a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
51297a984708SDavid Chisnall      __cntrl_(__r.__cntrl_)
51307a984708SDavid Chisnall{
51317a984708SDavid Chisnall    if (__cntrl_)
51327a984708SDavid Chisnall        __cntrl_->__add_weak();
51337a984708SDavid Chisnall}
51347a984708SDavid Chisnall
513594e3ee44SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
513694e3ee44SDavid Chisnall
513794e3ee44SDavid Chisnalltemplate<class _Tp>
51389729cf09SDimitry Andricinline
513994e3ee44SDavid Chisnallweak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
514094e3ee44SDavid Chisnall    : __ptr_(__r.__ptr_),
514194e3ee44SDavid Chisnall      __cntrl_(__r.__cntrl_)
514294e3ee44SDavid Chisnall{
514394e3ee44SDavid Chisnall    __r.__ptr_ = 0;
514494e3ee44SDavid Chisnall    __r.__cntrl_ = 0;
514594e3ee44SDavid Chisnall}
514694e3ee44SDavid Chisnall
514794e3ee44SDavid Chisnalltemplate<class _Tp>
514894e3ee44SDavid Chisnalltemplate<class _Yp>
51499729cf09SDimitry Andricinline
515094e3ee44SDavid Chisnallweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
515194e3ee44SDavid Chisnall                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
515294e3ee44SDavid Chisnall         _NOEXCEPT
515394e3ee44SDavid Chisnall    : __ptr_(__r.__ptr_),
515494e3ee44SDavid Chisnall      __cntrl_(__r.__cntrl_)
515594e3ee44SDavid Chisnall{
515694e3ee44SDavid Chisnall    __r.__ptr_ = 0;
515794e3ee44SDavid Chisnall    __r.__cntrl_ = 0;
515894e3ee44SDavid Chisnall}
515994e3ee44SDavid Chisnall
516094e3ee44SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
516194e3ee44SDavid Chisnall
51627a984708SDavid Chisnalltemplate<class _Tp>
51637a984708SDavid Chisnallweak_ptr<_Tp>::~weak_ptr()
51647a984708SDavid Chisnall{
51657a984708SDavid Chisnall    if (__cntrl_)
51667a984708SDavid Chisnall        __cntrl_->__release_weak();
51677a984708SDavid Chisnall}
51687a984708SDavid Chisnall
51697a984708SDavid Chisnalltemplate<class _Tp>
51709729cf09SDimitry Andricinline
51717a984708SDavid Chisnallweak_ptr<_Tp>&
51727a984708SDavid Chisnallweak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
51737a984708SDavid Chisnall{
51747a984708SDavid Chisnall    weak_ptr(__r).swap(*this);
51757a984708SDavid Chisnall    return *this;
51767a984708SDavid Chisnall}
51777a984708SDavid Chisnall
51787a984708SDavid Chisnalltemplate<class _Tp>
51797a984708SDavid Chisnalltemplate<class _Yp>
51809729cf09SDimitry Andricinline
518194e3ee44SDavid Chisnalltypename enable_if
518294e3ee44SDavid Chisnall<
518394e3ee44SDavid Chisnall    is_convertible<_Yp*, _Tp*>::value,
51847a984708SDavid Chisnall    weak_ptr<_Tp>&
518594e3ee44SDavid Chisnall>::type
51867a984708SDavid Chisnallweak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
51877a984708SDavid Chisnall{
51887a984708SDavid Chisnall    weak_ptr(__r).swap(*this);
51897a984708SDavid Chisnall    return *this;
51907a984708SDavid Chisnall}
51917a984708SDavid Chisnall
519294e3ee44SDavid Chisnall#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
519394e3ee44SDavid Chisnall
519494e3ee44SDavid Chisnalltemplate<class _Tp>
51959729cf09SDimitry Andricinline
519694e3ee44SDavid Chisnallweak_ptr<_Tp>&
519794e3ee44SDavid Chisnallweak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
519894e3ee44SDavid Chisnall{
519994e3ee44SDavid Chisnall    weak_ptr(_VSTD::move(__r)).swap(*this);
520094e3ee44SDavid Chisnall    return *this;
520194e3ee44SDavid Chisnall}
520294e3ee44SDavid Chisnall
52037a984708SDavid Chisnalltemplate<class _Tp>
52047a984708SDavid Chisnalltemplate<class _Yp>
52059729cf09SDimitry Andricinline
520694e3ee44SDavid Chisnalltypename enable_if
520794e3ee44SDavid Chisnall<
520894e3ee44SDavid Chisnall    is_convertible<_Yp*, _Tp*>::value,
52097a984708SDavid Chisnall    weak_ptr<_Tp>&
521094e3ee44SDavid Chisnall>::type
521194e3ee44SDavid Chisnallweak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
521294e3ee44SDavid Chisnall{
521394e3ee44SDavid Chisnall    weak_ptr(_VSTD::move(__r)).swap(*this);
521494e3ee44SDavid Chisnall    return *this;
521594e3ee44SDavid Chisnall}
521694e3ee44SDavid Chisnall
521794e3ee44SDavid Chisnall#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
521894e3ee44SDavid Chisnall
521994e3ee44SDavid Chisnalltemplate<class _Tp>
522094e3ee44SDavid Chisnalltemplate<class _Yp>
52219729cf09SDimitry Andricinline
522294e3ee44SDavid Chisnalltypename enable_if
522394e3ee44SDavid Chisnall<
522494e3ee44SDavid Chisnall    is_convertible<_Yp*, _Tp*>::value,
522594e3ee44SDavid Chisnall    weak_ptr<_Tp>&
522694e3ee44SDavid Chisnall>::type
52277a984708SDavid Chisnallweak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
52287a984708SDavid Chisnall{
52297a984708SDavid Chisnall    weak_ptr(__r).swap(*this);
52307a984708SDavid Chisnall    return *this;
52317a984708SDavid Chisnall}
52327a984708SDavid Chisnall
52337a984708SDavid Chisnalltemplate<class _Tp>
52349729cf09SDimitry Andricinline
52357a984708SDavid Chisnallvoid
52367a984708SDavid Chisnallweak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
52377a984708SDavid Chisnall{
52387a984708SDavid Chisnall    _VSTD::swap(__ptr_, __r.__ptr_);
52397a984708SDavid Chisnall    _VSTD::swap(__cntrl_, __r.__cntrl_);
52407a984708SDavid Chisnall}
52417a984708SDavid Chisnall
52427a984708SDavid Chisnalltemplate<class _Tp>
52437a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
52447a984708SDavid Chisnallvoid
52457a984708SDavid Chisnallswap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
52467a984708SDavid Chisnall{
52477a984708SDavid Chisnall    __x.swap(__y);
52487a984708SDavid Chisnall}
52497a984708SDavid Chisnall
52507a984708SDavid Chisnalltemplate<class _Tp>
52519729cf09SDimitry Andricinline
52527a984708SDavid Chisnallvoid
52537a984708SDavid Chisnallweak_ptr<_Tp>::reset() _NOEXCEPT
52547a984708SDavid Chisnall{
52557a984708SDavid Chisnall    weak_ptr().swap(*this);
52567a984708SDavid Chisnall}
52577a984708SDavid Chisnall
52587a984708SDavid Chisnalltemplate<class _Tp>
52597a984708SDavid Chisnalltemplate<class _Yp>
52607a984708SDavid Chisnallshared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
52617a848d17SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
52627a984708SDavid Chisnall    : __ptr_(__r.__ptr_),
52637a984708SDavid Chisnall      __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
52647a984708SDavid Chisnall{
52657a984708SDavid Chisnall    if (__cntrl_ == 0)
5266aed8d94eSDimitry Andric        __throw_bad_weak_ptr();
52677a984708SDavid Chisnall}
52687a984708SDavid Chisnall
52697a984708SDavid Chisnalltemplate<class _Tp>
52707a984708SDavid Chisnallshared_ptr<_Tp>
52717a984708SDavid Chisnallweak_ptr<_Tp>::lock() const _NOEXCEPT
52727a984708SDavid Chisnall{
52737a984708SDavid Chisnall    shared_ptr<_Tp> __r;
52747a984708SDavid Chisnall    __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
52757a984708SDavid Chisnall    if (__r.__cntrl_)
52767a984708SDavid Chisnall        __r.__ptr_ = __ptr_;
52777a984708SDavid Chisnall    return __r;
52787a984708SDavid Chisnall}
52797a984708SDavid Chisnall
52809729cf09SDimitry Andric#if _LIBCPP_STD_VER > 14
52819729cf09SDimitry Andrictemplate <class _Tp = void> struct owner_less;
52829729cf09SDimitry Andric#else
52837a984708SDavid Chisnalltemplate <class _Tp> struct owner_less;
52849729cf09SDimitry Andric#endif
52857a984708SDavid Chisnall
52867a984708SDavid Chisnalltemplate <class _Tp>
5287aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
52887a984708SDavid Chisnall    : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
52897a984708SDavid Chisnall{
52907a984708SDavid Chisnall    typedef bool result_type;
52917a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5292540d2a8bSDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
52937a984708SDavid Chisnall        {return __x.owner_before(__y);}
52947a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5295540d2a8bSDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
52967a984708SDavid Chisnall        {return __x.owner_before(__y);}
52977a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5298540d2a8bSDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
52997a984708SDavid Chisnall        {return __x.owner_before(__y);}
53007a984708SDavid Chisnall};
53017a984708SDavid Chisnall
53027a984708SDavid Chisnalltemplate <class _Tp>
5303aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
53047a984708SDavid Chisnall    : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
53057a984708SDavid Chisnall{
53067a984708SDavid Chisnall    typedef bool result_type;
53077a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5308540d2a8bSDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
53097a984708SDavid Chisnall        {return __x.owner_before(__y);}
53107a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5311540d2a8bSDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
53127a984708SDavid Chisnall        {return __x.owner_before(__y);}
53137a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5314540d2a8bSDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
53157a984708SDavid Chisnall        {return __x.owner_before(__y);}
53167a984708SDavid Chisnall};
53177a984708SDavid Chisnall
53189729cf09SDimitry Andric#if _LIBCPP_STD_VER > 14
53199729cf09SDimitry Andrictemplate <>
5320aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<void>
53219729cf09SDimitry Andric{
53229729cf09SDimitry Andric    template <class _Tp, class _Up>
53239729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5324540d2a8bSDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
53259729cf09SDimitry Andric        {return __x.owner_before(__y);}
53269729cf09SDimitry Andric    template <class _Tp, class _Up>
53279729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5328540d2a8bSDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
53299729cf09SDimitry Andric        {return __x.owner_before(__y);}
53309729cf09SDimitry Andric    template <class _Tp, class _Up>
53319729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5332540d2a8bSDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
53339729cf09SDimitry Andric        {return __x.owner_before(__y);}
53349729cf09SDimitry Andric    template <class _Tp, class _Up>
53359729cf09SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5336540d2a8bSDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
53379729cf09SDimitry Andric        {return __x.owner_before(__y);}
53389729cf09SDimitry Andric    typedef void is_transparent;
53399729cf09SDimitry Andric};
53409729cf09SDimitry Andric#endif
53419729cf09SDimitry Andric
53427a984708SDavid Chisnalltemplate<class _Tp>
5343aed8d94eSDimitry Andricclass _LIBCPP_TEMPLATE_VIS enable_shared_from_this
53447a984708SDavid Chisnall{
53457a984708SDavid Chisnall    mutable weak_ptr<_Tp> __weak_this_;
53467a984708SDavid Chisnallprotected:
5347936e9439SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
53487a984708SDavid Chisnall    enable_shared_from_this() _NOEXCEPT {}
53497a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
53507a984708SDavid Chisnall    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
53517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
53527a984708SDavid Chisnall    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
53537a984708SDavid Chisnall        {return *this;}
53547a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
53557a984708SDavid Chisnall    ~enable_shared_from_this() {}
53567a984708SDavid Chisnallpublic:
53577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
53587a984708SDavid Chisnall    shared_ptr<_Tp> shared_from_this()
53597a984708SDavid Chisnall        {return shared_ptr<_Tp>(__weak_this_);}
53607a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
53617a984708SDavid Chisnall    shared_ptr<_Tp const> shared_from_this() const
53627a984708SDavid Chisnall        {return shared_ptr<const _Tp>(__weak_this_);}
53637a984708SDavid Chisnall
53647c82a1ecSDimitry Andric#if _LIBCPP_STD_VER > 14
53657c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
53667c82a1ecSDimitry Andric    weak_ptr<_Tp> weak_from_this() _NOEXCEPT
53677c82a1ecSDimitry Andric       { return __weak_this_; }
53687c82a1ecSDimitry Andric
53697c82a1ecSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
53707c82a1ecSDimitry Andric    weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
53717c82a1ecSDimitry Andric        { return __weak_this_; }
53727c82a1ecSDimitry Andric#endif // _LIBCPP_STD_VER > 14
53737c82a1ecSDimitry Andric
53747a984708SDavid Chisnall    template <class _Up> friend class shared_ptr;
53757a984708SDavid Chisnall};
53767a984708SDavid Chisnall
53777a984708SDavid Chisnalltemplate <class _Tp>
5378aed8d94eSDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
53797a984708SDavid Chisnall{
53807a984708SDavid Chisnall    typedef shared_ptr<_Tp>      argument_type;
53817a984708SDavid Chisnall    typedef size_t               result_type;
5382540d2a8bSDimitry Andric
53837a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
53847a984708SDavid Chisnall    result_type operator()(const argument_type& __ptr) const _NOEXCEPT
53857a984708SDavid Chisnall    {
53867a984708SDavid Chisnall        return hash<_Tp*>()(__ptr.get());
53877a984708SDavid Chisnall    }
53887a984708SDavid Chisnall};
53897a984708SDavid Chisnall
539094e3ee44SDavid Chisnalltemplate<class _CharT, class _Traits, class _Yp>
53917a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
53927a984708SDavid Chisnallbasic_ostream<_CharT, _Traits>&
539394e3ee44SDavid Chisnalloperator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
53947a984708SDavid Chisnall
53957c82a1ecSDimitry Andric
53967c82a1ecSDimitry Andric#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
5397936e9439SDimitry Andric
53984f7ab58eSDimitry Andricclass _LIBCPP_TYPE_VIS __sp_mut
5399936e9439SDimitry Andric{
54001e0896acSDavid Chisnall    void* __lx;
5401936e9439SDimitry Andricpublic:
5402936e9439SDimitry Andric    void lock() _NOEXCEPT;
5403936e9439SDimitry Andric    void unlock() _NOEXCEPT;
5404936e9439SDimitry Andric
5405936e9439SDimitry Andricprivate:
5406936e9439SDimitry Andric    _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
5407936e9439SDimitry Andric    __sp_mut(const __sp_mut&);
5408936e9439SDimitry Andric    __sp_mut& operator=(const __sp_mut&);
5409936e9439SDimitry Andric
54101bf9f7c1SDimitry Andric    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
5411936e9439SDimitry Andric};
5412936e9439SDimitry Andric
54130f5676f4SDimitry Andric_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
54140f5676f4SDimitry Andric__sp_mut& __get_sp_mut(const void*);
5415936e9439SDimitry Andric
5416936e9439SDimitry Andrictemplate <class _Tp>
5417936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
5418936e9439SDimitry Andricbool
5419936e9439SDimitry Andricatomic_is_lock_free(const shared_ptr<_Tp>*)
5420936e9439SDimitry Andric{
5421936e9439SDimitry Andric    return false;
5422936e9439SDimitry Andric}
5423936e9439SDimitry Andric
5424936e9439SDimitry Andrictemplate <class _Tp>
54250f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5426936e9439SDimitry Andricshared_ptr<_Tp>
5427936e9439SDimitry Andricatomic_load(const shared_ptr<_Tp>* __p)
5428936e9439SDimitry Andric{
5429936e9439SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
5430936e9439SDimitry Andric    __m.lock();
5431936e9439SDimitry Andric    shared_ptr<_Tp> __q = *__p;
5432936e9439SDimitry Andric    __m.unlock();
5433936e9439SDimitry Andric    return __q;
5434936e9439SDimitry Andric}
5435936e9439SDimitry Andric
5436936e9439SDimitry Andrictemplate <class _Tp>
5437936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
54380f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5439936e9439SDimitry Andricshared_ptr<_Tp>
5440936e9439SDimitry Andricatomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
5441936e9439SDimitry Andric{
5442936e9439SDimitry Andric    return atomic_load(__p);
5443936e9439SDimitry Andric}
5444936e9439SDimitry Andric
5445936e9439SDimitry Andrictemplate <class _Tp>
54460f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5447936e9439SDimitry Andricvoid
5448936e9439SDimitry Andricatomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
5449936e9439SDimitry Andric{
5450936e9439SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
5451936e9439SDimitry Andric    __m.lock();
5452936e9439SDimitry Andric    __p->swap(__r);
5453936e9439SDimitry Andric    __m.unlock();
5454936e9439SDimitry Andric}
5455936e9439SDimitry Andric
5456936e9439SDimitry Andrictemplate <class _Tp>
5457936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
54580f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5459936e9439SDimitry Andricvoid
5460936e9439SDimitry Andricatomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
5461936e9439SDimitry Andric{
5462936e9439SDimitry Andric    atomic_store(__p, __r);
5463936e9439SDimitry Andric}
5464936e9439SDimitry Andric
5465936e9439SDimitry Andrictemplate <class _Tp>
54660f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5467936e9439SDimitry Andricshared_ptr<_Tp>
5468936e9439SDimitry Andricatomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
5469936e9439SDimitry Andric{
5470936e9439SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
5471936e9439SDimitry Andric    __m.lock();
5472936e9439SDimitry Andric    __p->swap(__r);
5473936e9439SDimitry Andric    __m.unlock();
5474936e9439SDimitry Andric    return __r;
5475936e9439SDimitry Andric}
5476936e9439SDimitry Andric
5477936e9439SDimitry Andrictemplate <class _Tp>
5478936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
54790f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5480936e9439SDimitry Andricshared_ptr<_Tp>
5481936e9439SDimitry Andricatomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
5482936e9439SDimitry Andric{
5483936e9439SDimitry Andric    return atomic_exchange(__p, __r);
5484936e9439SDimitry Andric}
5485936e9439SDimitry Andric
5486936e9439SDimitry Andrictemplate <class _Tp>
54870f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5488936e9439SDimitry Andricbool
5489936e9439SDimitry Andricatomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
5490936e9439SDimitry Andric{
54917c82a1ecSDimitry Andric    shared_ptr<_Tp> __temp;
5492936e9439SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
5493936e9439SDimitry Andric    __m.lock();
5494936e9439SDimitry Andric    if (__p->__owner_equivalent(*__v))
5495936e9439SDimitry Andric    {
54967c82a1ecSDimitry Andric        _VSTD::swap(__temp, *__p);
5497936e9439SDimitry Andric        *__p = __w;
5498936e9439SDimitry Andric        __m.unlock();
5499936e9439SDimitry Andric        return true;
5500936e9439SDimitry Andric    }
55017c82a1ecSDimitry Andric    _VSTD::swap(__temp, *__v);
5502936e9439SDimitry Andric    *__v = *__p;
5503936e9439SDimitry Andric    __m.unlock();
5504936e9439SDimitry Andric    return false;
5505936e9439SDimitry Andric}
5506936e9439SDimitry Andric
5507936e9439SDimitry Andrictemplate <class _Tp>
5508936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
55090f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5510936e9439SDimitry Andricbool
5511936e9439SDimitry Andricatomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
5512936e9439SDimitry Andric{
5513936e9439SDimitry Andric    return atomic_compare_exchange_strong(__p, __v, __w);
5514936e9439SDimitry Andric}
5515936e9439SDimitry Andric
5516936e9439SDimitry Andrictemplate <class _Tp>
5517936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
55180f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5519936e9439SDimitry Andricbool
5520936e9439SDimitry Andricatomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
5521936e9439SDimitry Andric                                        shared_ptr<_Tp> __w, memory_order, memory_order)
5522936e9439SDimitry Andric{
5523936e9439SDimitry Andric    return atomic_compare_exchange_strong(__p, __v, __w);
5524936e9439SDimitry Andric}
5525936e9439SDimitry Andric
5526936e9439SDimitry Andrictemplate <class _Tp>
5527936e9439SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
55280f5676f4SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
5529936e9439SDimitry Andricbool
5530936e9439SDimitry Andricatomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
5531936e9439SDimitry Andric                                      shared_ptr<_Tp> __w, memory_order, memory_order)
5532936e9439SDimitry Andric{
5533936e9439SDimitry Andric    return atomic_compare_exchange_weak(__p, __v, __w);
5534936e9439SDimitry Andric}
5535936e9439SDimitry Andric
55367c82a1ecSDimitry Andric#endif  // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
5537936e9439SDimitry Andric
55387a984708SDavid Chisnall//enum class
5539aed8d94eSDimitry Andric#if defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
5540aed8d94eSDimitry Andric# ifndef _LIBCPP_CXX03_LANG
5541aed8d94eSDimitry Andricenum class pointer_safety : unsigned char {
5542aed8d94eSDimitry Andric  relaxed,
5543aed8d94eSDimitry Andric  preferred,
5544aed8d94eSDimitry Andric  strict
5545aed8d94eSDimitry Andric};
5546aed8d94eSDimitry Andric# endif
5547aed8d94eSDimitry Andric#else
55481bf9f7c1SDimitry Andricstruct _LIBCPP_TYPE_VIS pointer_safety
55497a984708SDavid Chisnall{
55501e0896acSDavid Chisnall    enum __lx
55517a984708SDavid Chisnall    {
55527a984708SDavid Chisnall        relaxed,
55537a984708SDavid Chisnall        preferred,
55547a984708SDavid Chisnall        strict
55557a984708SDavid Chisnall    };
55567a984708SDavid Chisnall
55571e0896acSDavid Chisnall    __lx __v_;
55587a984708SDavid Chisnall
55597a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
5560aed8d94eSDimitry Andric    pointer_safety() : __v_() {}
5561aed8d94eSDimitry Andric
5562aed8d94eSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55631e0896acSDavid Chisnall    pointer_safety(__lx __v) : __v_(__v) {}
55647a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
55657a984708SDavid Chisnall    operator int() const {return __v_;}
55667a984708SDavid Chisnall};
5567aed8d94eSDimitry Andric#endif
5568aed8d94eSDimitry Andric
5569aed8d94eSDimitry Andric#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
55704ba319b5SDimitry Andric    defined(_LIBCPP_BUILDING_LIBRARY)
5571aed8d94eSDimitry Andric_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
5572aed8d94eSDimitry Andric#else
5573aed8d94eSDimitry Andric// This function is only offered in C++03 under ABI v1.
5574aed8d94eSDimitry Andric# if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) || !defined(_LIBCPP_CXX03_LANG)
5575aed8d94eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
5576aed8d94eSDimitry Andricpointer_safety get_pointer_safety() _NOEXCEPT {
5577aed8d94eSDimitry Andric  return pointer_safety::relaxed;
5578aed8d94eSDimitry Andric}
5579aed8d94eSDimitry Andric# endif
5580aed8d94eSDimitry Andric#endif
5581aed8d94eSDimitry Andric
55827a984708SDavid Chisnall
55834f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
55844f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
55854f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
55864f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
55877a984708SDavid Chisnall
55887a984708SDavid Chisnalltemplate <class _Tp>
55897a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
55907a984708SDavid Chisnall_Tp*
55917a984708SDavid Chisnallundeclare_reachable(_Tp* __p)
55927a984708SDavid Chisnall{
55937a984708SDavid Chisnall    return static_cast<_Tp*>(__undeclare_reachable(__p));
55947a984708SDavid Chisnall}
55957a984708SDavid Chisnall
55964f7ab58eSDimitry Andric_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
55977a984708SDavid Chisnall
5598854fa44bSDimitry Andric// --- Helper for container swap --
5599854fa44bSDimitry Andrictemplate <typename _Alloc>
56007c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
5601854fa44bSDimitry Andricvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2)
5602854fa44bSDimitry Andric#if _LIBCPP_STD_VER >= 14
5603854fa44bSDimitry Andric    _NOEXCEPT
5604854fa44bSDimitry Andric#else
5605854fa44bSDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
5606854fa44bSDimitry Andric#endif
5607854fa44bSDimitry Andric{
5608854fa44bSDimitry Andric    __swap_allocator(__a1, __a2,
5609854fa44bSDimitry Andric      integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
5610854fa44bSDimitry Andric}
5611854fa44bSDimitry Andric
5612854fa44bSDimitry Andrictemplate <typename _Alloc>
5613854fa44bSDimitry Andric_LIBCPP_INLINE_VISIBILITY
5614854fa44bSDimitry Andricvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
5615854fa44bSDimitry Andric#if _LIBCPP_STD_VER >= 14
5616854fa44bSDimitry Andric    _NOEXCEPT
5617854fa44bSDimitry Andric#else
5618854fa44bSDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
5619854fa44bSDimitry Andric#endif
5620854fa44bSDimitry Andric{
5621854fa44bSDimitry Andric    using _VSTD::swap;
5622854fa44bSDimitry Andric    swap(__a1, __a2);
5623854fa44bSDimitry Andric}
5624854fa44bSDimitry Andric
5625854fa44bSDimitry Andrictemplate <typename _Alloc>
56267c82a1ecSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
5627854fa44bSDimitry Andricvoid __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}
5628854fa44bSDimitry Andric
56299729cf09SDimitry Andrictemplate <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
56309729cf09SDimitry Andricstruct __noexcept_move_assign_container : public integral_constant<bool,
56319729cf09SDimitry Andric    _Traits::propagate_on_container_move_assignment::value
56329729cf09SDimitry Andric#if _LIBCPP_STD_VER > 14
56339729cf09SDimitry Andric        || _Traits::is_always_equal::value
56349729cf09SDimitry Andric#else
56359729cf09SDimitry Andric        && is_nothrow_move_assignable<_Alloc>::value
56369729cf09SDimitry Andric#endif
56379729cf09SDimitry Andric    > {};
5638854fa44bSDimitry Andric
56397c82a1ecSDimitry Andric
56407c82a1ecSDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
56417c82a1ecSDimitry Andrictemplate <class _Tp, class _Alloc>
56427c82a1ecSDimitry Andricstruct __temp_value {
56437c82a1ecSDimitry Andric    typedef allocator_traits<_Alloc> _Traits;
56447c82a1ecSDimitry Andric
5645*b5893f02SDimitry Andric    typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
56467c82a1ecSDimitry Andric    _Alloc &__a;
56477c82a1ecSDimitry Andric
56487c82a1ecSDimitry Andric    _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
56497c82a1ecSDimitry Andric    _Tp &   get() { return *__addr(); }
56507c82a1ecSDimitry Andric
56517c82a1ecSDimitry Andric    template<class... _Args>
5652*b5893f02SDimitry Andric    _LIBCPP_NO_CFI
5653*b5893f02SDimitry Andric    __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
5654*b5893f02SDimitry Andric      _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
5655*b5893f02SDimitry Andric                         _VSTD::forward<_Args>(__args)...);
5656*b5893f02SDimitry Andric    }
56577c82a1ecSDimitry Andric
56587c82a1ecSDimitry Andric    ~__temp_value() { _Traits::destroy(__a, __addr()); }
56597c82a1ecSDimitry Andric    };
56607c82a1ecSDimitry Andric#endif
56617c82a1ecSDimitry Andric
56624ba319b5SDimitry Andrictemplate<typename _Alloc, typename = void, typename = void>
56634ba319b5SDimitry Andricstruct __is_allocator : false_type {};
56644ba319b5SDimitry Andric
56654ba319b5SDimitry Andrictemplate<typename _Alloc>
56664ba319b5SDimitry Andricstruct __is_allocator<_Alloc,
56674ba319b5SDimitry Andric       typename __void_t<typename _Alloc::value_type>::type,
56684ba319b5SDimitry Andric       typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type
56694ba319b5SDimitry Andric     >
56704ba319b5SDimitry Andric   : true_type {};
56714ba319b5SDimitry Andric
56727a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
56737a984708SDavid Chisnall
5674f9448bf3SDimitry Andric_LIBCPP_POP_MACROS
5675f9448bf3SDimitry Andric
56767a984708SDavid Chisnall#endif  // _LIBCPP_MEMORY
5677