xref: /freebsd/contrib/llvm-project/libcxx/include/memory (revision 9ec406dc40df40f5e40672437517d1f3fe78149b)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===-------------------------- memory ------------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_MEMORY
110b57cec5SDimitry Andric#define _LIBCPP_MEMORY
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    memory synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andricstruct allocator_arg_t { };
200b57cec5SDimitry Andricinline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
210b57cec5SDimitry Andric
220b57cec5SDimitry Andrictemplate <class T, class Alloc> struct uses_allocator;
230b57cec5SDimitry Andric
240b57cec5SDimitry Andrictemplate <class Ptr>
250b57cec5SDimitry Andricstruct pointer_traits
260b57cec5SDimitry Andric{
270b57cec5SDimitry Andric    typedef Ptr pointer;
280b57cec5SDimitry Andric    typedef <details> element_type;
290b57cec5SDimitry Andric    typedef <details> difference_type;
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric    template <class U> using rebind = <details>;
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric    static pointer pointer_to(<details>);
340b57cec5SDimitry Andric};
350b57cec5SDimitry Andric
360b57cec5SDimitry Andrictemplate <class T>
370b57cec5SDimitry Andricstruct pointer_traits<T*>
380b57cec5SDimitry Andric{
390b57cec5SDimitry Andric    typedef T* pointer;
400b57cec5SDimitry Andric    typedef T element_type;
410b57cec5SDimitry Andric    typedef ptrdiff_t difference_type;
420b57cec5SDimitry Andric
430b57cec5SDimitry Andric    template <class U> using rebind = U*;
440b57cec5SDimitry Andric
450b57cec5SDimitry Andric    static pointer pointer_to(<details>) noexcept; // constexpr in C++20
460b57cec5SDimitry Andric};
470b57cec5SDimitry Andric
480b57cec5SDimitry Andrictemplate <class T> constexpr T* to_address(T* p) noexcept; // C++20
490b57cec5SDimitry Andrictemplate <class Ptr> auto to_address(const Ptr& p) noexcept; // C++20
500b57cec5SDimitry Andric
510b57cec5SDimitry Andrictemplate <class Alloc>
520b57cec5SDimitry Andricstruct allocator_traits
530b57cec5SDimitry Andric{
540b57cec5SDimitry Andric    typedef Alloc                        allocator_type;
550b57cec5SDimitry Andric    typedef typename allocator_type::value_type
560b57cec5SDimitry Andric                                         value_type;
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric    typedef Alloc::pointer | value_type* pointer;
590b57cec5SDimitry Andric    typedef Alloc::const_pointer
600b57cec5SDimitry Andric          | pointer_traits<pointer>::rebind<const value_type>
610b57cec5SDimitry Andric                                         const_pointer;
620b57cec5SDimitry Andric    typedef Alloc::void_pointer
630b57cec5SDimitry Andric          | pointer_traits<pointer>::rebind<void>
640b57cec5SDimitry Andric                                         void_pointer;
650b57cec5SDimitry Andric    typedef Alloc::const_void_pointer
660b57cec5SDimitry Andric          | pointer_traits<pointer>::rebind<const void>
670b57cec5SDimitry Andric                                         const_void_pointer;
680b57cec5SDimitry Andric    typedef Alloc::difference_type
690b57cec5SDimitry Andric          | pointer_traits<pointer>::difference_type
700b57cec5SDimitry Andric                                         difference_type;
710b57cec5SDimitry Andric    typedef Alloc::size_type
720b57cec5SDimitry Andric          | make_unsigned<difference_type>::type
730b57cec5SDimitry Andric                                         size_type;
740b57cec5SDimitry Andric    typedef Alloc::propagate_on_container_copy_assignment
750b57cec5SDimitry Andric          | false_type                   propagate_on_container_copy_assignment;
760b57cec5SDimitry Andric    typedef Alloc::propagate_on_container_move_assignment
770b57cec5SDimitry Andric          | false_type                   propagate_on_container_move_assignment;
780b57cec5SDimitry Andric    typedef Alloc::propagate_on_container_swap
790b57cec5SDimitry Andric          | false_type                   propagate_on_container_swap;
800b57cec5SDimitry Andric    typedef Alloc::is_always_equal
810b57cec5SDimitry Andric          | is_empty                     is_always_equal;
820b57cec5SDimitry Andric
830b57cec5SDimitry Andric    template <class T> using rebind_alloc  = Alloc::rebind<U>::other | Alloc<T, Args...>;
840b57cec5SDimitry Andric    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
850b57cec5SDimitry Andric
860b57cec5SDimitry Andric    static pointer allocate(allocator_type& a, size_type n);                          // [[nodiscard]] in C++20
870b57cec5SDimitry Andric    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // [[nodiscard]] in C++20
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept;
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric    template <class T, class... Args>
920b57cec5SDimitry Andric        static void construct(allocator_type& a, T* p, Args&&... args);
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric    template <class T>
950b57cec5SDimitry Andric        static void destroy(allocator_type& a, T* p);
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric    static size_type max_size(const allocator_type& a); // noexcept in C++14
980b57cec5SDimitry Andric
990b57cec5SDimitry Andric    static allocator_type
1000b57cec5SDimitry Andric        select_on_container_copy_construction(const allocator_type& a);
1010b57cec5SDimitry Andric};
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andrictemplate <>
1040b57cec5SDimitry Andricclass allocator<void>
1050b57cec5SDimitry Andric{
1060b57cec5SDimitry Andricpublic:
1070b57cec5SDimitry Andric    typedef void*                                 pointer;
1080b57cec5SDimitry Andric    typedef const void*                           const_pointer;
1090b57cec5SDimitry Andric    typedef void                                  value_type;
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric    template <class _Up> struct rebind {typedef allocator<_Up> other;};
1120b57cec5SDimitry Andric};
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andrictemplate <class T>
1150b57cec5SDimitry Andricclass allocator
1160b57cec5SDimitry Andric{
1170b57cec5SDimitry Andricpublic:
1180b57cec5SDimitry Andric    typedef size_t                                size_type;
1190b57cec5SDimitry Andric    typedef ptrdiff_t                             difference_type;
1200b57cec5SDimitry Andric    typedef T*                                    pointer;
1210b57cec5SDimitry Andric    typedef const T*                              const_pointer;
1220b57cec5SDimitry Andric    typedef typename add_lvalue_reference<T>::type       reference;
1230b57cec5SDimitry Andric    typedef typename add_lvalue_reference<const T>::type const_reference;
1240b57cec5SDimitry Andric    typedef T                                     value_type;
1250b57cec5SDimitry Andric
1260b57cec5SDimitry Andric    template <class U> struct rebind {typedef allocator<U> other;};
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andric    constexpr allocator() noexcept;                      // constexpr in C++20
1290b57cec5SDimitry Andric    constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
1300b57cec5SDimitry Andric    template <class U>
1310b57cec5SDimitry Andric      constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
1320b57cec5SDimitry Andric    ~allocator();
1330b57cec5SDimitry Andric    pointer address(reference x) const noexcept;
1340b57cec5SDimitry Andric    const_pointer address(const_reference x) const noexcept;
1350b57cec5SDimitry Andric    pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
1360b57cec5SDimitry Andric    void deallocate(pointer p, size_type n) noexcept;
1370b57cec5SDimitry Andric    size_type max_size() const noexcept;
1380b57cec5SDimitry Andric    template<class U, class... Args>
1390b57cec5SDimitry Andric        void construct(U* p, Args&&... args);
1400b57cec5SDimitry Andric    template <class U>
1410b57cec5SDimitry Andric        void destroy(U* p);
1420b57cec5SDimitry Andric};
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andrictemplate <class T, class U>
1450b57cec5SDimitry Andricbool operator==(const allocator<T>&, const allocator<U>&) noexcept;
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andrictemplate <class T, class U>
1480b57cec5SDimitry Andricbool operator!=(const allocator<T>&, const allocator<U>&) noexcept;
1490b57cec5SDimitry Andric
1500b57cec5SDimitry Andrictemplate <class OutputIterator, class T>
1510b57cec5SDimitry Andricclass raw_storage_iterator
1520b57cec5SDimitry Andric    : public iterator<output_iterator_tag,
1530b57cec5SDimitry Andric                      T,                               // purposefully not C++03
1540b57cec5SDimitry Andric                      ptrdiff_t,                       // purposefully not C++03
1550b57cec5SDimitry Andric                      T*,                              // purposefully not C++03
1560b57cec5SDimitry Andric                      raw_storage_iterator&>           // purposefully not C++03
1570b57cec5SDimitry Andric{
1580b57cec5SDimitry Andricpublic:
1590b57cec5SDimitry Andric    explicit raw_storage_iterator(OutputIterator x);
1600b57cec5SDimitry Andric    raw_storage_iterator& operator*();
1610b57cec5SDimitry Andric    raw_storage_iterator& operator=(const T& element);
1620b57cec5SDimitry Andric    raw_storage_iterator& operator++();
1630b57cec5SDimitry Andric    raw_storage_iterator  operator++(int);
1640b57cec5SDimitry Andric};
1650b57cec5SDimitry Andric
1660b57cec5SDimitry Andrictemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
1670b57cec5SDimitry Andrictemplate <class T> void               return_temporary_buffer(T* p) noexcept;
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andrictemplate <class T> T* addressof(T& r) noexcept;
1700b57cec5SDimitry Andrictemplate <class T> T* addressof(const T&& r) noexcept = delete;
1710b57cec5SDimitry Andric
1720b57cec5SDimitry Andrictemplate <class InputIterator, class ForwardIterator>
1730b57cec5SDimitry AndricForwardIterator
1740b57cec5SDimitry Andricuninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andrictemplate <class InputIterator, class Size, class ForwardIterator>
1770b57cec5SDimitry AndricForwardIterator
1780b57cec5SDimitry Andricuninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
1790b57cec5SDimitry Andric
1800b57cec5SDimitry Andrictemplate <class ForwardIterator, class T>
1810b57cec5SDimitry Andricvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
1820b57cec5SDimitry Andric
1830b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size, class T>
1840b57cec5SDimitry AndricForwardIterator
1850b57cec5SDimitry Andricuninitialized_fill_n(ForwardIterator first, Size n, const T& x);
1860b57cec5SDimitry Andric
1870b57cec5SDimitry Andrictemplate <class T>
1880b57cec5SDimitry Andricvoid destroy_at(T* location);
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andrictemplate <class ForwardIterator>
1910b57cec5SDimitry Andric void destroy(ForwardIterator first, ForwardIterator last);
1920b57cec5SDimitry Andric
1930b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size>
1940b57cec5SDimitry Andric ForwardIterator destroy_n(ForwardIterator first, Size n);
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andrictemplate <class InputIterator, class ForwardIterator>
1970b57cec5SDimitry Andric ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
1980b57cec5SDimitry Andric
1990b57cec5SDimitry Andrictemplate <class InputIterator, class Size, class ForwardIterator>
2000b57cec5SDimitry Andric pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andrictemplate <class ForwardIterator>
2030b57cec5SDimitry Andric void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
2040b57cec5SDimitry Andric
2050b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size>
2060b57cec5SDimitry Andric ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andrictemplate <class ForwardIterator>
2090b57cec5SDimitry Andric void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
2100b57cec5SDimitry Andric
2110b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size>
2120b57cec5SDimitry Andric ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andrictemplate <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andrictemplate<class X>
2170b57cec5SDimitry Andricclass auto_ptr                                  // deprecated in C++11, removed in C++17
2180b57cec5SDimitry Andric{
2190b57cec5SDimitry Andricpublic:
2200b57cec5SDimitry Andric    typedef X element_type;
2210b57cec5SDimitry Andric
2220b57cec5SDimitry Andric    explicit auto_ptr(X* p =0) throw();
2230b57cec5SDimitry Andric    auto_ptr(auto_ptr&) throw();
2240b57cec5SDimitry Andric    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
2250b57cec5SDimitry Andric    auto_ptr& operator=(auto_ptr&) throw();
2260b57cec5SDimitry Andric    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
2270b57cec5SDimitry Andric    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
2280b57cec5SDimitry Andric    ~auto_ptr() throw();
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric    typename add_lvalue_reference<X>::type operator*() const throw();
2310b57cec5SDimitry Andric    X* operator->() const throw();
2320b57cec5SDimitry Andric    X* get() const throw();
2330b57cec5SDimitry Andric    X* release() throw();
2340b57cec5SDimitry Andric    void reset(X* p =0) throw();
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric    auto_ptr(auto_ptr_ref<X>) throw();
2370b57cec5SDimitry Andric    template<class Y> operator auto_ptr_ref<Y>() throw();
2380b57cec5SDimitry Andric    template<class Y> operator auto_ptr<Y>() throw();
2390b57cec5SDimitry Andric};
2400b57cec5SDimitry Andric
2410b57cec5SDimitry Andrictemplate <class T>
2420b57cec5SDimitry Andricstruct default_delete
2430b57cec5SDimitry Andric{
2440b57cec5SDimitry Andric    constexpr default_delete() noexcept = default;
2450b57cec5SDimitry Andric    template <class U> default_delete(const default_delete<U>&) noexcept;
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric    void operator()(T*) const noexcept;
2480b57cec5SDimitry Andric};
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andrictemplate <class T>
2510b57cec5SDimitry Andricstruct default_delete<T[]>
2520b57cec5SDimitry Andric{
2530b57cec5SDimitry Andric    constexpr default_delete() noexcept = default;
2540b57cec5SDimitry Andric    void operator()(T*) const noexcept;
2550b57cec5SDimitry Andric    template <class U> void operator()(U*) const = delete;
2560b57cec5SDimitry Andric};
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andrictemplate <class T, class D = default_delete<T>>
2590b57cec5SDimitry Andricclass unique_ptr
2600b57cec5SDimitry Andric{
2610b57cec5SDimitry Andricpublic:
2620b57cec5SDimitry Andric    typedef see below pointer;
2630b57cec5SDimitry Andric    typedef T element_type;
2640b57cec5SDimitry Andric    typedef D deleter_type;
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andric    // constructors
2670b57cec5SDimitry Andric    constexpr unique_ptr() noexcept;
2680b57cec5SDimitry Andric    explicit unique_ptr(pointer p) noexcept;
2690b57cec5SDimitry Andric    unique_ptr(pointer p, see below d1) noexcept;
2700b57cec5SDimitry Andric    unique_ptr(pointer p, see below d2) noexcept;
2710b57cec5SDimitry Andric    unique_ptr(unique_ptr&& u) noexcept;
2720b57cec5SDimitry Andric    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
2730b57cec5SDimitry Andric    template <class U, class E>
2740b57cec5SDimitry Andric        unique_ptr(unique_ptr<U, E>&& u) noexcept;
2750b57cec5SDimitry Andric    template <class U>
2760b57cec5SDimitry Andric        unique_ptr(auto_ptr<U>&& u) noexcept;       // removed in C++17
2770b57cec5SDimitry Andric
2780b57cec5SDimitry Andric    // destructor
2790b57cec5SDimitry Andric    ~unique_ptr();
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andric    // assignment
2820b57cec5SDimitry Andric    unique_ptr& operator=(unique_ptr&& u) noexcept;
2830b57cec5SDimitry Andric    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
2840b57cec5SDimitry Andric    unique_ptr& operator=(nullptr_t) noexcept;
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric    // observers
2870b57cec5SDimitry Andric    typename add_lvalue_reference<T>::type operator*() const;
2880b57cec5SDimitry Andric    pointer operator->() const noexcept;
2890b57cec5SDimitry Andric    pointer get() const noexcept;
2900b57cec5SDimitry Andric    deleter_type& get_deleter() noexcept;
2910b57cec5SDimitry Andric    const deleter_type& get_deleter() const noexcept;
2920b57cec5SDimitry Andric    explicit operator bool() const noexcept;
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andric    // modifiers
2950b57cec5SDimitry Andric    pointer release() noexcept;
2960b57cec5SDimitry Andric    void reset(pointer p = pointer()) noexcept;
2970b57cec5SDimitry Andric    void swap(unique_ptr& u) noexcept;
2980b57cec5SDimitry Andric};
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andrictemplate <class T, class D>
3010b57cec5SDimitry Andricclass unique_ptr<T[], D>
3020b57cec5SDimitry Andric{
3030b57cec5SDimitry Andricpublic:
3040b57cec5SDimitry Andric    typedef implementation-defined pointer;
3050b57cec5SDimitry Andric    typedef T element_type;
3060b57cec5SDimitry Andric    typedef D deleter_type;
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andric    // constructors
3090b57cec5SDimitry Andric    constexpr unique_ptr() noexcept;
3100b57cec5SDimitry Andric    explicit unique_ptr(pointer p) noexcept;
3110b57cec5SDimitry Andric    unique_ptr(pointer p, see below d) noexcept;
3120b57cec5SDimitry Andric    unique_ptr(pointer p, see below d) noexcept;
3130b57cec5SDimitry Andric    unique_ptr(unique_ptr&& u) noexcept;
3140b57cec5SDimitry Andric    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric    // destructor
3170b57cec5SDimitry Andric    ~unique_ptr();
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric    // assignment
3200b57cec5SDimitry Andric    unique_ptr& operator=(unique_ptr&& u) noexcept;
3210b57cec5SDimitry Andric    unique_ptr& operator=(nullptr_t) noexcept;
3220b57cec5SDimitry Andric
3230b57cec5SDimitry Andric    // observers
3240b57cec5SDimitry Andric    T& operator[](size_t i) const;
3250b57cec5SDimitry Andric    pointer get() const noexcept;
3260b57cec5SDimitry Andric    deleter_type& get_deleter() noexcept;
3270b57cec5SDimitry Andric    const deleter_type& get_deleter() const noexcept;
3280b57cec5SDimitry Andric    explicit operator bool() const noexcept;
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric    // modifiers
3310b57cec5SDimitry Andric    pointer release() noexcept;
3320b57cec5SDimitry Andric    void reset(pointer p = pointer()) noexcept;
3330b57cec5SDimitry Andric    void reset(nullptr_t) noexcept;
3340b57cec5SDimitry Andric    template <class U> void reset(U) = delete;
3350b57cec5SDimitry Andric    void swap(unique_ptr& u) noexcept;
3360b57cec5SDimitry Andric};
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andrictemplate <class T, class D>
3390b57cec5SDimitry Andric    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
3400b57cec5SDimitry Andric
3410b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3420b57cec5SDimitry Andric    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3430b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3440b57cec5SDimitry Andric    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3450b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3460b57cec5SDimitry Andric    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3470b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3480b57cec5SDimitry Andric    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3490b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3500b57cec5SDimitry Andric    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3510b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3520b57cec5SDimitry Andric    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3530b57cec5SDimitry Andric
3540b57cec5SDimitry Andrictemplate <class T, class D>
3550b57cec5SDimitry Andric    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3560b57cec5SDimitry Andrictemplate <class T, class D>
3570b57cec5SDimitry Andric    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3580b57cec5SDimitry Andrictemplate <class T, class D>
3590b57cec5SDimitry Andric    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3600b57cec5SDimitry Andrictemplate <class T, class D>
3610b57cec5SDimitry Andric    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andrictemplate <class T, class D>
3640b57cec5SDimitry Andric    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
3650b57cec5SDimitry Andrictemplate <class T, class D>
3660b57cec5SDimitry Andric    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
3670b57cec5SDimitry Andrictemplate <class T, class D>
3680b57cec5SDimitry Andric    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
3690b57cec5SDimitry Andrictemplate <class T, class D>
3700b57cec5SDimitry Andric    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
3710b57cec5SDimitry Andrictemplate <class T, class D>
3720b57cec5SDimitry Andric    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
3730b57cec5SDimitry Andrictemplate <class T, class D>
3740b57cec5SDimitry Andric    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
3750b57cec5SDimitry Andrictemplate <class T, class D>
3760b57cec5SDimitry Andric    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
3770b57cec5SDimitry Andrictemplate <class T, class D>
3780b57cec5SDimitry Andric    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
3790b57cec5SDimitry Andric
3800b57cec5SDimitry Andricclass bad_weak_ptr
3810b57cec5SDimitry Andric    : public std::exception
3820b57cec5SDimitry Andric{
3830b57cec5SDimitry Andric    bad_weak_ptr() noexcept;
3840b57cec5SDimitry Andric};
3850b57cec5SDimitry Andric
3860b57cec5SDimitry Andrictemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
3870b57cec5SDimitry Andrictemplate<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
3880b57cec5SDimitry Andrictemplate<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andrictemplate<class E, class T, class Y, class D>
3910b57cec5SDimitry Andric    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andrictemplate<class T>
3940b57cec5SDimitry Andricclass shared_ptr
3950b57cec5SDimitry Andric{
3960b57cec5SDimitry Andricpublic:
3970b57cec5SDimitry Andric    typedef T element_type;
3980b57cec5SDimitry Andric    typedef weak_ptr<T> weak_type; // C++17
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric    // constructors:
4010b57cec5SDimitry Andric    constexpr shared_ptr() noexcept;
4020b57cec5SDimitry Andric    template<class Y> explicit shared_ptr(Y* p);
4030b57cec5SDimitry Andric    template<class Y, class D> shared_ptr(Y* p, D d);
4040b57cec5SDimitry Andric    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
4050b57cec5SDimitry Andric    template <class D> shared_ptr(nullptr_t p, D d);
4060b57cec5SDimitry Andric    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
4070b57cec5SDimitry Andric    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
4080b57cec5SDimitry Andric    shared_ptr(const shared_ptr& r) noexcept;
4090b57cec5SDimitry Andric    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
4100b57cec5SDimitry Andric    shared_ptr(shared_ptr&& r) noexcept;
4110b57cec5SDimitry Andric    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
4120b57cec5SDimitry Andric    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
4130b57cec5SDimitry Andric    template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
4140b57cec5SDimitry Andric    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
4150b57cec5SDimitry Andric    shared_ptr(nullptr_t) : shared_ptr() { }
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric    // destructor:
4180b57cec5SDimitry Andric    ~shared_ptr();
4190b57cec5SDimitry Andric
4200b57cec5SDimitry Andric    // assignment:
4210b57cec5SDimitry Andric    shared_ptr& operator=(const shared_ptr& r) noexcept;
4220b57cec5SDimitry Andric    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
4230b57cec5SDimitry Andric    shared_ptr& operator=(shared_ptr&& r) noexcept;
4240b57cec5SDimitry Andric    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
4250b57cec5SDimitry Andric    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
4260b57cec5SDimitry Andric    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andric    // modifiers:
4290b57cec5SDimitry Andric    void swap(shared_ptr& r) noexcept;
4300b57cec5SDimitry Andric    void reset() noexcept;
4310b57cec5SDimitry Andric    template<class Y> void reset(Y* p);
4320b57cec5SDimitry Andric    template<class Y, class D> void reset(Y* p, D d);
4330b57cec5SDimitry Andric    template<class Y, class D, class A> void reset(Y* p, D d, A a);
4340b57cec5SDimitry Andric
4350b57cec5SDimitry Andric    // observers:
4360b57cec5SDimitry Andric    T* get() const noexcept;
4370b57cec5SDimitry Andric    T& operator*() const noexcept;
4380b57cec5SDimitry Andric    T* operator->() const noexcept;
4390b57cec5SDimitry Andric    long use_count() const noexcept;
4400b57cec5SDimitry Andric    bool unique() const noexcept;
4410b57cec5SDimitry Andric    explicit operator bool() const noexcept;
4420b57cec5SDimitry Andric    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
4430b57cec5SDimitry Andric    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
4440b57cec5SDimitry Andric};
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric// shared_ptr comparisons:
4470b57cec5SDimitry Andrictemplate<class T, class U>
4480b57cec5SDimitry Andric    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4490b57cec5SDimitry Andrictemplate<class T, class U>
4500b57cec5SDimitry Andric    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4510b57cec5SDimitry Andrictemplate<class T, class U>
4520b57cec5SDimitry Andric    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4530b57cec5SDimitry Andrictemplate<class T, class U>
4540b57cec5SDimitry Andric    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4550b57cec5SDimitry Andrictemplate<class T, class U>
4560b57cec5SDimitry Andric    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4570b57cec5SDimitry Andrictemplate<class T, class U>
4580b57cec5SDimitry Andric    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4590b57cec5SDimitry Andric
4600b57cec5SDimitry Andrictemplate <class T>
4610b57cec5SDimitry Andric    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
4620b57cec5SDimitry Andrictemplate <class T>
4630b57cec5SDimitry Andric    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
4640b57cec5SDimitry Andrictemplate <class T>
4650b57cec5SDimitry Andric    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
4660b57cec5SDimitry Andrictemplate <class T>
4670b57cec5SDimitry Andric    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
4680b57cec5SDimitry Andrictemplate <class T>
4690b57cec5SDimitry Andric    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
4700b57cec5SDimitry Andrictemplate <class T>
4710b57cec5SDimitry Andricbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
4720b57cec5SDimitry Andrictemplate <class T>
4730b57cec5SDimitry Andric    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
4740b57cec5SDimitry Andrictemplate <class T>
4750b57cec5SDimitry Andric    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
4760b57cec5SDimitry Andrictemplate <class T>
4770b57cec5SDimitry Andric    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
4780b57cec5SDimitry Andrictemplate <class T>
4790b57cec5SDimitry Andric    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
4800b57cec5SDimitry Andrictemplate <class T>
4810b57cec5SDimitry Andric    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
4820b57cec5SDimitry Andrictemplate <class T>
4830b57cec5SDimitry Andric    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andric// shared_ptr specialized algorithms:
4860b57cec5SDimitry Andrictemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andric// shared_ptr casts:
4890b57cec5SDimitry Andrictemplate<class T, class U>
4900b57cec5SDimitry Andric    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
4910b57cec5SDimitry Andrictemplate<class T, class U>
4920b57cec5SDimitry Andric    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
4930b57cec5SDimitry Andrictemplate<class T, class U>
4940b57cec5SDimitry Andric    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
4950b57cec5SDimitry Andric
4960b57cec5SDimitry Andric// shared_ptr I/O:
4970b57cec5SDimitry Andrictemplate<class E, class T, class Y>
4980b57cec5SDimitry Andric    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andric// shared_ptr get_deleter:
5010b57cec5SDimitry Andrictemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
5020b57cec5SDimitry Andric
5030b57cec5SDimitry Andrictemplate<class T, class... Args>
5040b57cec5SDimitry Andric    shared_ptr<T> make_shared(Args&&... args);
5050b57cec5SDimitry Andrictemplate<class T, class A, class... Args>
5060b57cec5SDimitry Andric    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andrictemplate<class T>
5090b57cec5SDimitry Andricclass weak_ptr
5100b57cec5SDimitry Andric{
5110b57cec5SDimitry Andricpublic:
5120b57cec5SDimitry Andric    typedef T element_type;
5130b57cec5SDimitry Andric
5140b57cec5SDimitry Andric    // constructors
5150b57cec5SDimitry Andric    constexpr weak_ptr() noexcept;
5160b57cec5SDimitry Andric    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
5170b57cec5SDimitry Andric    weak_ptr(weak_ptr const& r) noexcept;
5180b57cec5SDimitry Andric    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
5190b57cec5SDimitry Andric    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
5200b57cec5SDimitry Andric    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
5210b57cec5SDimitry Andric
5220b57cec5SDimitry Andric    // destructor
5230b57cec5SDimitry Andric    ~weak_ptr();
5240b57cec5SDimitry Andric
5250b57cec5SDimitry Andric    // assignment
5260b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr const& r) noexcept;
5270b57cec5SDimitry Andric    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
5280b57cec5SDimitry Andric    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
5290b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
5300b57cec5SDimitry Andric    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andric    // modifiers
5330b57cec5SDimitry Andric    void swap(weak_ptr& r) noexcept;
5340b57cec5SDimitry Andric    void reset() noexcept;
5350b57cec5SDimitry Andric
5360b57cec5SDimitry Andric    // observers
5370b57cec5SDimitry Andric    long use_count() const noexcept;
5380b57cec5SDimitry Andric    bool expired() const noexcept;
5390b57cec5SDimitry Andric    shared_ptr<T> lock() const noexcept;
5400b57cec5SDimitry Andric    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
5410b57cec5SDimitry Andric    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
5420b57cec5SDimitry Andric};
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andric// weak_ptr specialized algorithms:
5450b57cec5SDimitry Andrictemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric// class owner_less:
5480b57cec5SDimitry Andrictemplate<class T> struct owner_less;
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andrictemplate<class T>
5510b57cec5SDimitry Andricstruct owner_less<shared_ptr<T> >
5520b57cec5SDimitry Andric    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
5530b57cec5SDimitry Andric{
5540b57cec5SDimitry Andric    typedef bool result_type;
5550b57cec5SDimitry Andric    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
5560b57cec5SDimitry Andric    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
5570b57cec5SDimitry Andric    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
5580b57cec5SDimitry Andric};
5590b57cec5SDimitry Andric
5600b57cec5SDimitry Andrictemplate<class T>
5610b57cec5SDimitry Andricstruct owner_less<weak_ptr<T> >
5620b57cec5SDimitry Andric    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
5630b57cec5SDimitry Andric{
5640b57cec5SDimitry Andric    typedef bool result_type;
5650b57cec5SDimitry Andric    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
5660b57cec5SDimitry Andric    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
5670b57cec5SDimitry Andric    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
5680b57cec5SDimitry Andric};
5690b57cec5SDimitry Andric
5700b57cec5SDimitry Andrictemplate <>  // Added in C++14
5710b57cec5SDimitry Andricstruct owner_less<void>
5720b57cec5SDimitry Andric{
5730b57cec5SDimitry Andric    template <class _Tp, class _Up>
5740b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
5750b57cec5SDimitry Andric    template <class _Tp, class _Up>
5760b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
5770b57cec5SDimitry Andric    template <class _Tp, class _Up>
5780b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
5790b57cec5SDimitry Andric    template <class _Tp, class _Up>
5800b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric    typedef void is_transparent;
5830b57cec5SDimitry Andric};
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andrictemplate<class T>
5860b57cec5SDimitry Andricclass enable_shared_from_this
5870b57cec5SDimitry Andric{
5880b57cec5SDimitry Andricprotected:
5890b57cec5SDimitry Andric    constexpr enable_shared_from_this() noexcept;
5900b57cec5SDimitry Andric    enable_shared_from_this(enable_shared_from_this const&) noexcept;
5910b57cec5SDimitry Andric    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
5920b57cec5SDimitry Andric    ~enable_shared_from_this();
5930b57cec5SDimitry Andricpublic:
5940b57cec5SDimitry Andric    shared_ptr<T> shared_from_this();
5950b57cec5SDimitry Andric    shared_ptr<T const> shared_from_this() const;
5960b57cec5SDimitry Andric};
5970b57cec5SDimitry Andric
5980b57cec5SDimitry Andrictemplate<class T>
5990b57cec5SDimitry Andric    bool atomic_is_lock_free(const shared_ptr<T>* p);
6000b57cec5SDimitry Andrictemplate<class T>
6010b57cec5SDimitry Andric    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
6020b57cec5SDimitry Andrictemplate<class T>
6030b57cec5SDimitry Andric    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
6040b57cec5SDimitry Andrictemplate<class T>
6050b57cec5SDimitry Andric    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
6060b57cec5SDimitry Andrictemplate<class T>
6070b57cec5SDimitry Andric    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
6080b57cec5SDimitry Andrictemplate<class T>
6090b57cec5SDimitry Andric    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
6100b57cec5SDimitry Andrictemplate<class T>
6110b57cec5SDimitry Andric    shared_ptr<T>
6120b57cec5SDimitry Andric    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
6130b57cec5SDimitry Andrictemplate<class T>
6140b57cec5SDimitry Andric    bool
6150b57cec5SDimitry Andric    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
6160b57cec5SDimitry Andrictemplate<class T>
6170b57cec5SDimitry Andric    bool
6180b57cec5SDimitry Andric    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
6190b57cec5SDimitry Andrictemplate<class T>
6200b57cec5SDimitry Andric    bool
6210b57cec5SDimitry Andric    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
6220b57cec5SDimitry Andric                                          shared_ptr<T> w, memory_order success,
6230b57cec5SDimitry Andric                                          memory_order failure);
6240b57cec5SDimitry Andrictemplate<class T>
6250b57cec5SDimitry Andric    bool
6260b57cec5SDimitry Andric    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
6270b57cec5SDimitry Andric                                            shared_ptr<T> w, memory_order success,
6280b57cec5SDimitry Andric                                            memory_order failure);
6290b57cec5SDimitry Andric// Hash support
6300b57cec5SDimitry Andrictemplate <class T> struct hash;
6310b57cec5SDimitry Andrictemplate <class T, class D> struct hash<unique_ptr<T, D> >;
6320b57cec5SDimitry Andrictemplate <class T> struct hash<shared_ptr<T> >;
6330b57cec5SDimitry Andric
6340b57cec5SDimitry Andrictemplate <class T, class Alloc>
6350b57cec5SDimitry Andric  inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
6360b57cec5SDimitry Andric
6370b57cec5SDimitry Andric// Pointer safety
6380b57cec5SDimitry Andricenum class pointer_safety { relaxed, preferred, strict };
6390b57cec5SDimitry Andricvoid declare_reachable(void *p);
6400b57cec5SDimitry Andrictemplate <class T> T *undeclare_reachable(T *p);
6410b57cec5SDimitry Andricvoid declare_no_pointers(char *p, size_t n);
6420b57cec5SDimitry Andricvoid undeclare_no_pointers(char *p, size_t n);
6430b57cec5SDimitry Andricpointer_safety get_pointer_safety() noexcept;
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andricvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space);
6460b57cec5SDimitry Andric
6470b57cec5SDimitry Andric}  // std
6480b57cec5SDimitry Andric
6490b57cec5SDimitry Andric*/
6500b57cec5SDimitry Andric
6510b57cec5SDimitry Andric#include <__config>
6520b57cec5SDimitry Andric#include <type_traits>
6530b57cec5SDimitry Andric#include <typeinfo>
6540b57cec5SDimitry Andric#include <cstddef>
6550b57cec5SDimitry Andric#include <cstdint>
6560b57cec5SDimitry Andric#include <new>
6570b57cec5SDimitry Andric#include <utility>
6580b57cec5SDimitry Andric#include <limits>
6590b57cec5SDimitry Andric#include <iterator>
6600b57cec5SDimitry Andric#include <__functional_base>
6610b57cec5SDimitry Andric#include <iosfwd>
6620b57cec5SDimitry Andric#include <tuple>
6630b57cec5SDimitry Andric#include <stdexcept>
6640b57cec5SDimitry Andric#include <cstring>
6650b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
6660b57cec5SDimitry Andric#  include <atomic>
6670b57cec5SDimitry Andric#endif
6680b57cec5SDimitry Andric#include <version>
6690b57cec5SDimitry Andric
6700b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6710b57cec5SDimitry Andric#pragma GCC system_header
6720b57cec5SDimitry Andric#endif
6730b57cec5SDimitry Andric
6740b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
6750b57cec5SDimitry Andric#include <__undef_macros>
6760b57cec5SDimitry Andric
6770b57cec5SDimitry Andric
6780b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
6790b57cec5SDimitry Andric
6800b57cec5SDimitry Andrictemplate <class _ValueType>
6810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
6820b57cec5SDimitry Andric_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
6830b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS) && \
6840b57cec5SDimitry Andric    defined(__ATOMIC_RELAXED) &&        \
6850b57cec5SDimitry Andric    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
6860b57cec5SDimitry Andric    return __atomic_load_n(__value, __ATOMIC_RELAXED);
6870b57cec5SDimitry Andric#else
6880b57cec5SDimitry Andric    return *__value;
6890b57cec5SDimitry Andric#endif
6900b57cec5SDimitry Andric}
6910b57cec5SDimitry Andric
6920b57cec5SDimitry Andrictemplate <class _ValueType>
6930b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
6940b57cec5SDimitry Andric_ValueType __libcpp_acquire_load(_ValueType const* __value) {
6950b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS) && \
6960b57cec5SDimitry Andric    defined(__ATOMIC_ACQUIRE) &&        \
6970b57cec5SDimitry Andric    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
6980b57cec5SDimitry Andric    return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
6990b57cec5SDimitry Andric#else
7000b57cec5SDimitry Andric    return *__value;
7010b57cec5SDimitry Andric#endif
7020b57cec5SDimitry Andric}
7030b57cec5SDimitry Andric
7040b57cec5SDimitry Andric// addressof moved to <type_traits>
7050b57cec5SDimitry Andric
7060b57cec5SDimitry Andrictemplate <class _Tp> class allocator;
7070b57cec5SDimitry Andric
7080b57cec5SDimitry Andrictemplate <>
7090b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<void>
7100b57cec5SDimitry Andric{
7110b57cec5SDimitry Andricpublic:
7120b57cec5SDimitry Andric    typedef void*             pointer;
7130b57cec5SDimitry Andric    typedef const void*       const_pointer;
7140b57cec5SDimitry Andric    typedef void              value_type;
7150b57cec5SDimitry Andric
7160b57cec5SDimitry Andric    template <class _Up> struct rebind {typedef allocator<_Up> other;};
7170b57cec5SDimitry Andric};
7180b57cec5SDimitry Andric
7190b57cec5SDimitry Andrictemplate <>
7200b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<const void>
7210b57cec5SDimitry Andric{
7220b57cec5SDimitry Andricpublic:
7230b57cec5SDimitry Andric    typedef const void*       pointer;
7240b57cec5SDimitry Andric    typedef const void*       const_pointer;
7250b57cec5SDimitry Andric    typedef const void        value_type;
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andric    template <class _Up> struct rebind {typedef allocator<_Up> other;};
7280b57cec5SDimitry Andric};
7290b57cec5SDimitry Andric
7300b57cec5SDimitry Andric// pointer_traits
7310b57cec5SDimitry Andric
7320b57cec5SDimitry Andrictemplate <class _Tp, class = void>
7330b57cec5SDimitry Andricstruct __has_element_type : false_type {};
7340b57cec5SDimitry Andric
7350b57cec5SDimitry Andrictemplate <class _Tp>
7360b57cec5SDimitry Andricstruct __has_element_type<_Tp,
7370b57cec5SDimitry Andric              typename __void_t<typename _Tp::element_type>::type> : true_type {};
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andrictemplate <class _Ptr, bool = __has_element_type<_Ptr>::value>
7400b57cec5SDimitry Andricstruct __pointer_traits_element_type;
7410b57cec5SDimitry Andric
7420b57cec5SDimitry Andrictemplate <class _Ptr>
7430b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Ptr, true>
7440b57cec5SDimitry Andric{
7450b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::element_type type;
7460b57cec5SDimitry Andric};
7470b57cec5SDimitry Andric
7480b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
7490b57cec5SDimitry Andric
7500b57cec5SDimitry Andrictemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>
7510b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, true>
7520b57cec5SDimitry Andric{
7530b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::element_type type;
7540b57cec5SDimitry Andric};
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andrictemplate <template <class, class...> class _Sp, class _Tp, class ..._Args>
7570b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _Args...>, false>
7580b57cec5SDimitry Andric{
7590b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE _Tp type;
7600b57cec5SDimitry Andric};
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_VARIADICS
7630b57cec5SDimitry Andric
7640b57cec5SDimitry Andrictemplate <template <class> class _Sp, class _Tp>
7650b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp>, true>
7660b57cec5SDimitry Andric{
7670b57cec5SDimitry Andric    typedef typename _Sp<_Tp>::element_type type;
7680b57cec5SDimitry Andric};
7690b57cec5SDimitry Andric
7700b57cec5SDimitry Andrictemplate <template <class> class _Sp, class _Tp>
7710b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp>, false>
7720b57cec5SDimitry Andric{
7730b57cec5SDimitry Andric    typedef _Tp type;
7740b57cec5SDimitry Andric};
7750b57cec5SDimitry Andric
7760b57cec5SDimitry Andrictemplate <template <class, class> class _Sp, class _Tp, class _A0>
7770b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _A0>, true>
7780b57cec5SDimitry Andric{
7790b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0>::element_type type;
7800b57cec5SDimitry Andric};
7810b57cec5SDimitry Andric
7820b57cec5SDimitry Andrictemplate <template <class, class> class _Sp, class _Tp, class _A0>
7830b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _A0>, false>
7840b57cec5SDimitry Andric{
7850b57cec5SDimitry Andric    typedef _Tp type;
7860b57cec5SDimitry Andric};
7870b57cec5SDimitry Andric
7880b57cec5SDimitry Andrictemplate <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>
7890b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, true>
7900b57cec5SDimitry Andric{
7910b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0, _A1>::element_type type;
7920b57cec5SDimitry Andric};
7930b57cec5SDimitry Andric
7940b57cec5SDimitry Andrictemplate <template <class, class, class> class _Sp, class _Tp, class _A0, class _A1>
7950b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1>, false>
7960b57cec5SDimitry Andric{
7970b57cec5SDimitry Andric    typedef _Tp type;
7980b57cec5SDimitry Andric};
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andrictemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
8010b57cec5SDimitry Andric                                                           class _A1, class _A2>
8020b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, true>
8030b57cec5SDimitry Andric{
8040b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0, _A1, _A2>::element_type type;
8050b57cec5SDimitry Andric};
8060b57cec5SDimitry Andric
8070b57cec5SDimitry Andrictemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
8080b57cec5SDimitry Andric                                                           class _A1, class _A2>
8090b57cec5SDimitry Andricstruct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, false>
8100b57cec5SDimitry Andric{
8110b57cec5SDimitry Andric    typedef _Tp type;
8120b57cec5SDimitry Andric};
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
8150b57cec5SDimitry Andric
8160b57cec5SDimitry Andrictemplate <class _Tp, class = void>
8170b57cec5SDimitry Andricstruct __has_difference_type : false_type {};
8180b57cec5SDimitry Andric
8190b57cec5SDimitry Andrictemplate <class _Tp>
8200b57cec5SDimitry Andricstruct __has_difference_type<_Tp,
8210b57cec5SDimitry Andric            typename __void_t<typename _Tp::difference_type>::type> : true_type {};
8220b57cec5SDimitry Andric
8230b57cec5SDimitry Andrictemplate <class _Ptr, bool = __has_difference_type<_Ptr>::value>
8240b57cec5SDimitry Andricstruct __pointer_traits_difference_type
8250b57cec5SDimitry Andric{
8260b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE ptrdiff_t type;
8270b57cec5SDimitry Andric};
8280b57cec5SDimitry Andric
8290b57cec5SDimitry Andrictemplate <class _Ptr>
8300b57cec5SDimitry Andricstruct __pointer_traits_difference_type<_Ptr, true>
8310b57cec5SDimitry Andric{
8320b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Ptr::difference_type type;
8330b57cec5SDimitry Andric};
8340b57cec5SDimitry Andric
8350b57cec5SDimitry Andrictemplate <class _Tp, class _Up>
8360b57cec5SDimitry Andricstruct __has_rebind
8370b57cec5SDimitry Andric{
8380b57cec5SDimitry Andricprivate:
8390b57cec5SDimitry Andric    struct __two {char __lx; char __lxx;};
8400b57cec5SDimitry Andric    template <class _Xp> static __two __test(...);
8410b57cec5SDimitry Andric    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
8420b57cec5SDimitry Andricpublic:
8430b57cec5SDimitry Andric    static const bool value = sizeof(__test<_Tp>(0)) == 1;
8440b57cec5SDimitry Andric};
8450b57cec5SDimitry Andric
8460b57cec5SDimitry Andrictemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
8470b57cec5SDimitry Andricstruct __pointer_traits_rebind
8480b57cec5SDimitry Andric{
8490b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8500b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up> type;
8510b57cec5SDimitry Andric#else
8520b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
8530b57cec5SDimitry Andric#endif
8540b57cec5SDimitry Andric};
8550b57cec5SDimitry Andric
8560b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
8570b57cec5SDimitry Andric
8580b57cec5SDimitry Andrictemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
8590b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, true>
8600b57cec5SDimitry Andric{
8610b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8620b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up> type;
8630b57cec5SDimitry Andric#else
8640b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Sp<_Tp, _Args...>::template rebind<_Up>::other type;
8650b57cec5SDimitry Andric#endif
8660b57cec5SDimitry Andric};
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andrictemplate <template <class, class...> class _Sp, class _Tp, class ..._Args, class _Up>
8690b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _Args...>, _Up, false>
8700b57cec5SDimitry Andric{
8710b57cec5SDimitry Andric    typedef _Sp<_Up, _Args...> type;
8720b57cec5SDimitry Andric};
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_VARIADICS
8750b57cec5SDimitry Andric
8760b57cec5SDimitry Andrictemplate <template <class> class _Sp, class _Tp, class _Up>
8770b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp>, _Up, true>
8780b57cec5SDimitry Andric{
8790b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8800b57cec5SDimitry Andric    typedef typename _Sp<_Tp>::template rebind<_Up> type;
8810b57cec5SDimitry Andric#else
8820b57cec5SDimitry Andric    typedef typename _Sp<_Tp>::template rebind<_Up>::other type;
8830b57cec5SDimitry Andric#endif
8840b57cec5SDimitry Andric};
8850b57cec5SDimitry Andric
8860b57cec5SDimitry Andrictemplate <template <class> class _Sp, class _Tp, class _Up>
8870b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp>, _Up, false>
8880b57cec5SDimitry Andric{
8890b57cec5SDimitry Andric    typedef _Sp<_Up> type;
8900b57cec5SDimitry Andric};
8910b57cec5SDimitry Andric
8920b57cec5SDimitry Andrictemplate <template <class, class> class _Sp, class _Tp, class _A0, class _Up>
8930b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, true>
8940b57cec5SDimitry Andric{
8950b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
8960b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0>::template rebind<_Up> type;
8970b57cec5SDimitry Andric#else
8980b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0>::template rebind<_Up>::other type;
8990b57cec5SDimitry Andric#endif
9000b57cec5SDimitry Andric};
9010b57cec5SDimitry Andric
9020b57cec5SDimitry Andrictemplate <template <class, class> class _Sp, class _Tp, class _A0, class _Up>
9030b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _A0>, _Up, false>
9040b57cec5SDimitry Andric{
9050b57cec5SDimitry Andric    typedef _Sp<_Up, _A0> type;
9060b57cec5SDimitry Andric};
9070b57cec5SDimitry Andric
9080b57cec5SDimitry Andrictemplate <template <class, class, class> class _Sp, class _Tp, class _A0,
9090b57cec5SDimitry Andric                                         class _A1, class _Up>
9100b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, true>
9110b57cec5SDimitry Andric{
9120b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9130b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up> type;
9140b57cec5SDimitry Andric#else
9150b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0, _A1>::template rebind<_Up>::other type;
9160b57cec5SDimitry Andric#endif
9170b57cec5SDimitry Andric};
9180b57cec5SDimitry Andric
9190b57cec5SDimitry Andrictemplate <template <class, class, class> class _Sp, class _Tp, class _A0,
9200b57cec5SDimitry Andric                                         class _A1, class _Up>
9210b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1>, _Up, false>
9220b57cec5SDimitry Andric{
9230b57cec5SDimitry Andric    typedef _Sp<_Up, _A0, _A1> type;
9240b57cec5SDimitry Andric};
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andrictemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
9270b57cec5SDimitry Andric                                                class _A1, class _A2, class _Up>
9280b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, true>
9290b57cec5SDimitry Andric{
9300b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9310b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up> type;
9320b57cec5SDimitry Andric#else
9330b57cec5SDimitry Andric    typedef typename _Sp<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
9340b57cec5SDimitry Andric#endif
9350b57cec5SDimitry Andric};
9360b57cec5SDimitry Andric
9370b57cec5SDimitry Andrictemplate <template <class, class, class, class> class _Sp, class _Tp, class _A0,
9380b57cec5SDimitry Andric                                                class _A1, class _A2, class _Up>
9390b57cec5SDimitry Andricstruct __pointer_traits_rebind<_Sp<_Tp, _A0, _A1, _A2>, _Up, false>
9400b57cec5SDimitry Andric{
9410b57cec5SDimitry Andric    typedef _Sp<_Up, _A0, _A1, _A2> type;
9420b57cec5SDimitry Andric};
9430b57cec5SDimitry Andric
9440b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
9450b57cec5SDimitry Andric
9460b57cec5SDimitry Andrictemplate <class _Ptr>
9470b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS pointer_traits
9480b57cec5SDimitry Andric{
9490b57cec5SDimitry Andric    typedef _Ptr                                                     pointer;
9500b57cec5SDimitry Andric    typedef typename __pointer_traits_element_type<pointer>::type    element_type;
9510b57cec5SDimitry Andric    typedef typename __pointer_traits_difference_type<pointer>::type difference_type;
9520b57cec5SDimitry Andric
9530b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9540b57cec5SDimitry Andric    template <class _Up> using rebind = typename __pointer_traits_rebind<pointer, _Up>::type;
9550b57cec5SDimitry Andric#else
9560b57cec5SDimitry Andric    template <class _Up> struct rebind
9570b57cec5SDimitry Andric        {typedef typename __pointer_traits_rebind<pointer, _Up>::type other;};
9580b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andricprivate:
9610b57cec5SDimitry Andric    struct __nat {};
9620b57cec5SDimitry Andricpublic:
9630b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
9640b57cec5SDimitry Andric    static pointer pointer_to(typename conditional<is_void<element_type>::value,
9650b57cec5SDimitry Andric                                           __nat, element_type>::type& __r)
9660b57cec5SDimitry Andric        {return pointer::pointer_to(__r);}
9670b57cec5SDimitry Andric};
9680b57cec5SDimitry Andric
9690b57cec5SDimitry Andrictemplate <class _Tp>
9700b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS pointer_traits<_Tp*>
9710b57cec5SDimitry Andric{
9720b57cec5SDimitry Andric    typedef _Tp*      pointer;
9730b57cec5SDimitry Andric    typedef _Tp       element_type;
9740b57cec5SDimitry Andric    typedef ptrdiff_t difference_type;
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9770b57cec5SDimitry Andric    template <class _Up> using rebind = _Up*;
9780b57cec5SDimitry Andric#else
9790b57cec5SDimitry Andric    template <class _Up> struct rebind {typedef _Up* other;};
9800b57cec5SDimitry Andric#endif
9810b57cec5SDimitry Andric
9820b57cec5SDimitry Andricprivate:
9830b57cec5SDimitry Andric    struct __nat {};
9840b57cec5SDimitry Andricpublic:
9850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
9860b57cec5SDimitry Andric    static pointer pointer_to(typename conditional<is_void<element_type>::value,
9870b57cec5SDimitry Andric                                      __nat, element_type>::type& __r) _NOEXCEPT
9880b57cec5SDimitry Andric        {return _VSTD::addressof(__r);}
9890b57cec5SDimitry Andric};
9900b57cec5SDimitry Andric
9910b57cec5SDimitry Andrictemplate <class _From, class _To>
9920b57cec5SDimitry Andricstruct __rebind_pointer {
9930b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9940b57cec5SDimitry Andric    typedef typename pointer_traits<_From>::template rebind<_To>        type;
9950b57cec5SDimitry Andric#else
9960b57cec5SDimitry Andric    typedef typename pointer_traits<_From>::template rebind<_To>::other type;
9970b57cec5SDimitry Andric#endif
9980b57cec5SDimitry Andric};
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andric// allocator_traits
10010b57cec5SDimitry Andric
10020b57cec5SDimitry Andrictemplate <class _Tp, class = void>
10030b57cec5SDimitry Andricstruct __has_pointer_type : false_type {};
10040b57cec5SDimitry Andric
10050b57cec5SDimitry Andrictemplate <class _Tp>
10060b57cec5SDimitry Andricstruct __has_pointer_type<_Tp,
10070b57cec5SDimitry Andric          typename __void_t<typename _Tp::pointer>::type> : true_type {};
10080b57cec5SDimitry Andric
10090b57cec5SDimitry Andricnamespace __pointer_type_imp
10100b57cec5SDimitry Andric{
10110b57cec5SDimitry Andric
10120b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, bool = __has_pointer_type<_Dp>::value>
10130b57cec5SDimitry Andricstruct __pointer_type
10140b57cec5SDimitry Andric{
10150b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Dp::pointer type;
10160b57cec5SDimitry Andric};
10170b57cec5SDimitry Andric
10180b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
10190b57cec5SDimitry Andricstruct __pointer_type<_Tp, _Dp, false>
10200b57cec5SDimitry Andric{
10210b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE _Tp* type;
10220b57cec5SDimitry Andric};
10230b57cec5SDimitry Andric
10240b57cec5SDimitry Andric}  // __pointer_type_imp
10250b57cec5SDimitry Andric
10260b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
10270b57cec5SDimitry Andricstruct __pointer_type
10280b57cec5SDimitry Andric{
10290b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
10300b57cec5SDimitry Andric};
10310b57cec5SDimitry Andric
10320b57cec5SDimitry Andrictemplate <class _Tp, class = void>
10330b57cec5SDimitry Andricstruct __has_const_pointer : false_type {};
10340b57cec5SDimitry Andric
10350b57cec5SDimitry Andrictemplate <class _Tp>
10360b57cec5SDimitry Andricstruct __has_const_pointer<_Tp,
10370b57cec5SDimitry Andric            typename __void_t<typename _Tp::const_pointer>::type> : true_type {};
10380b57cec5SDimitry Andric
10390b57cec5SDimitry Andrictemplate <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>
10400b57cec5SDimitry Andricstruct __const_pointer
10410b57cec5SDimitry Andric{
10420b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::const_pointer type;
10430b57cec5SDimitry Andric};
10440b57cec5SDimitry Andric
10450b57cec5SDimitry Andrictemplate <class _Tp, class _Ptr, class _Alloc>
10460b57cec5SDimitry Andricstruct __const_pointer<_Tp, _Ptr, _Alloc, false>
10470b57cec5SDimitry Andric{
10480b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10490b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const _Tp> type;
10500b57cec5SDimitry Andric#else
10510b57cec5SDimitry Andric    typedef typename pointer_traits<_Ptr>::template rebind<const _Tp>::other type;
10520b57cec5SDimitry Andric#endif
10530b57cec5SDimitry Andric};
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andrictemplate <class _Tp, class = void>
10560b57cec5SDimitry Andricstruct __has_void_pointer : false_type {};
10570b57cec5SDimitry Andric
10580b57cec5SDimitry Andrictemplate <class _Tp>
10590b57cec5SDimitry Andricstruct __has_void_pointer<_Tp,
10600b57cec5SDimitry Andric               typename __void_t<typename _Tp::void_pointer>::type> : true_type {};
10610b57cec5SDimitry Andric
10620b57cec5SDimitry Andrictemplate <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>
10630b57cec5SDimitry Andricstruct __void_pointer
10640b57cec5SDimitry Andric{
10650b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::void_pointer type;
10660b57cec5SDimitry Andric};
10670b57cec5SDimitry Andric
10680b57cec5SDimitry Andrictemplate <class _Ptr, class _Alloc>
10690b57cec5SDimitry Andricstruct __void_pointer<_Ptr, _Alloc, false>
10700b57cec5SDimitry Andric{
10710b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10720b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<void> type;
10730b57cec5SDimitry Andric#else
10740b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<void>::other type;
10750b57cec5SDimitry Andric#endif
10760b57cec5SDimitry Andric};
10770b57cec5SDimitry Andric
10780b57cec5SDimitry Andrictemplate <class _Tp, class = void>
10790b57cec5SDimitry Andricstruct __has_const_void_pointer : false_type {};
10800b57cec5SDimitry Andric
10810b57cec5SDimitry Andrictemplate <class _Tp>
10820b57cec5SDimitry Andricstruct __has_const_void_pointer<_Tp,
10830b57cec5SDimitry Andric            typename __void_t<typename _Tp::const_void_pointer>::type> : true_type {};
10840b57cec5SDimitry Andric
10850b57cec5SDimitry Andrictemplate <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>
10860b57cec5SDimitry Andricstruct __const_void_pointer
10870b57cec5SDimitry Andric{
10880b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::const_void_pointer type;
10890b57cec5SDimitry Andric};
10900b57cec5SDimitry Andric
10910b57cec5SDimitry Andrictemplate <class _Ptr, class _Alloc>
10920b57cec5SDimitry Andricstruct __const_void_pointer<_Ptr, _Alloc, false>
10930b57cec5SDimitry Andric{
10940b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
10950b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const void> type;
10960b57cec5SDimitry Andric#else
10970b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::template rebind<const void>::other type;
10980b57cec5SDimitry Andric#endif
10990b57cec5SDimitry Andric};
11000b57cec5SDimitry Andric
1101480093f4SDimitry Andric
1102480093f4SDimitry Andrictemplate <bool _UsePointerTraits> struct __to_address_helper;
1103480093f4SDimitry Andric
1104480093f4SDimitry Andrictemplate <> struct __to_address_helper<true> {
1105480093f4SDimitry Andric    template <class _Pointer>
1106480093f4SDimitry Andric    using __return_type = decltype(pointer_traits<_Pointer>::to_address(std::declval<const _Pointer&>()));
1107480093f4SDimitry Andric
1108480093f4SDimitry Andric    template <class _Pointer>
1109480093f4SDimitry Andric    _LIBCPP_CONSTEXPR
1110480093f4SDimitry Andric    static __return_type<_Pointer>
1111480093f4SDimitry Andric    __do_it(const _Pointer &__p) _NOEXCEPT { return pointer_traits<_Pointer>::to_address(__p); }
1112480093f4SDimitry Andric};
1113480093f4SDimitry Andric
1114480093f4SDimitry Andrictemplate <class _Pointer, bool _Dummy = true>
1115480093f4SDimitry Andricusing __choose_to_address = __to_address_helper<_IsValidExpansion<__to_address_helper<_Dummy>::template __return_type, _Pointer>::value>;
1116480093f4SDimitry Andric
1117480093f4SDimitry Andric
11180b57cec5SDimitry Andrictemplate <class _Tp>
11190b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
11200b57cec5SDimitry Andric_Tp*
1121480093f4SDimitry Andric__to_address(_Tp* __p) _NOEXCEPT
11220b57cec5SDimitry Andric{
1123480093f4SDimitry Andric    static_assert(!is_function<_Tp>::value, "_Tp is a function type");
11240b57cec5SDimitry Andric    return __p;
11250b57cec5SDimitry Andric}
11260b57cec5SDimitry Andric
11270b57cec5SDimitry Andrictemplate <class _Pointer>
1128480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1129480093f4SDimitry Andrictypename __choose_to_address<_Pointer>::template __return_type<_Pointer>
1130480093f4SDimitry Andric__to_address(const _Pointer& __p) _NOEXCEPT {
1131480093f4SDimitry Andric  return __choose_to_address<_Pointer>::__do_it(__p);
11320b57cec5SDimitry Andric}
11330b57cec5SDimitry Andric
1134480093f4SDimitry Andrictemplate <> struct __to_address_helper<false> {
1135480093f4SDimitry Andric    template <class _Pointer>
1136480093f4SDimitry Andric    using __return_type = typename pointer_traits<_Pointer>::element_type*;
11370b57cec5SDimitry Andric
1138480093f4SDimitry Andric    template <class _Pointer>
1139480093f4SDimitry Andric    _LIBCPP_CONSTEXPR
1140480093f4SDimitry Andric    static __return_type<_Pointer>
1141480093f4SDimitry Andric    __do_it(const _Pointer &__p) _NOEXCEPT { return std::__to_address(__p.operator->()); }
1142480093f4SDimitry Andric};
1143480093f4SDimitry Andric
1144480093f4SDimitry Andric
1145480093f4SDimitry Andric#if _LIBCPP_STD_VER > 17
11460b57cec5SDimitry Andrictemplate <class _Tp>
11470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY constexpr
11480b57cec5SDimitry Andric_Tp*
11490b57cec5SDimitry Andricto_address(_Tp* __p) _NOEXCEPT
11500b57cec5SDimitry Andric{
11510b57cec5SDimitry Andric    static_assert(!is_function_v<_Tp>, "_Tp is a function type");
11520b57cec5SDimitry Andric    return __p;
11530b57cec5SDimitry Andric}
11540b57cec5SDimitry Andric
11550b57cec5SDimitry Andrictemplate <class _Pointer>
11560b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11570b57cec5SDimitry Andricauto
11580b57cec5SDimitry Andricto_address(const _Pointer& __p) _NOEXCEPT
11590b57cec5SDimitry Andric{
1160480093f4SDimitry Andric    return _VSTD::__to_address(__p);
11610b57cec5SDimitry Andric}
11620b57cec5SDimitry Andric#endif
11630b57cec5SDimitry Andric
11640b57cec5SDimitry Andrictemplate <class _Tp, class = void>
11650b57cec5SDimitry Andricstruct __has_size_type : false_type {};
11660b57cec5SDimitry Andric
11670b57cec5SDimitry Andrictemplate <class _Tp>
11680b57cec5SDimitry Andricstruct __has_size_type<_Tp,
11690b57cec5SDimitry Andric               typename __void_t<typename _Tp::size_type>::type> : true_type {};
11700b57cec5SDimitry Andric
11710b57cec5SDimitry Andrictemplate <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
11720b57cec5SDimitry Andricstruct __size_type
11730b57cec5SDimitry Andric{
11740b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename make_unsigned<_DiffType>::type type;
11750b57cec5SDimitry Andric};
11760b57cec5SDimitry Andric
11770b57cec5SDimitry Andrictemplate <class _Alloc, class _DiffType>
11780b57cec5SDimitry Andricstruct __size_type<_Alloc, _DiffType, true>
11790b57cec5SDimitry Andric{
11800b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::size_type type;
11810b57cec5SDimitry Andric};
11820b57cec5SDimitry Andric
11830b57cec5SDimitry Andrictemplate <class _Tp, class = void>
11840b57cec5SDimitry Andricstruct __has_propagate_on_container_copy_assignment : false_type {};
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andrictemplate <class _Tp>
11870b57cec5SDimitry Andricstruct __has_propagate_on_container_copy_assignment<_Tp,
11880b57cec5SDimitry Andric    typename __void_t<typename _Tp::propagate_on_container_copy_assignment>::type>
11890b57cec5SDimitry Andric        : true_type {};
11900b57cec5SDimitry Andric
11910b57cec5SDimitry Andrictemplate <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
11920b57cec5SDimitry Andricstruct __propagate_on_container_copy_assignment
11930b57cec5SDimitry Andric{
11940b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE false_type type;
11950b57cec5SDimitry Andric};
11960b57cec5SDimitry Andric
11970b57cec5SDimitry Andrictemplate <class _Alloc>
11980b57cec5SDimitry Andricstruct __propagate_on_container_copy_assignment<_Alloc, true>
11990b57cec5SDimitry Andric{
12000b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_copy_assignment type;
12010b57cec5SDimitry Andric};
12020b57cec5SDimitry Andric
12030b57cec5SDimitry Andrictemplate <class _Tp, class = void>
12040b57cec5SDimitry Andricstruct __has_propagate_on_container_move_assignment : false_type {};
12050b57cec5SDimitry Andric
12060b57cec5SDimitry Andrictemplate <class _Tp>
12070b57cec5SDimitry Andricstruct __has_propagate_on_container_move_assignment<_Tp,
12080b57cec5SDimitry Andric           typename __void_t<typename _Tp::propagate_on_container_move_assignment>::type>
12090b57cec5SDimitry Andric               : true_type {};
12100b57cec5SDimitry Andric
12110b57cec5SDimitry Andrictemplate <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
12120b57cec5SDimitry Andricstruct __propagate_on_container_move_assignment
12130b57cec5SDimitry Andric{
12140b57cec5SDimitry Andric    typedef false_type type;
12150b57cec5SDimitry Andric};
12160b57cec5SDimitry Andric
12170b57cec5SDimitry Andrictemplate <class _Alloc>
12180b57cec5SDimitry Andricstruct __propagate_on_container_move_assignment<_Alloc, true>
12190b57cec5SDimitry Andric{
12200b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_move_assignment type;
12210b57cec5SDimitry Andric};
12220b57cec5SDimitry Andric
12230b57cec5SDimitry Andrictemplate <class _Tp, class = void>
12240b57cec5SDimitry Andricstruct __has_propagate_on_container_swap : false_type {};
12250b57cec5SDimitry Andric
12260b57cec5SDimitry Andrictemplate <class _Tp>
12270b57cec5SDimitry Andricstruct __has_propagate_on_container_swap<_Tp,
12280b57cec5SDimitry Andric           typename __void_t<typename _Tp::propagate_on_container_swap>::type>
12290b57cec5SDimitry Andric               : true_type {};
12300b57cec5SDimitry Andric
12310b57cec5SDimitry Andrictemplate <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
12320b57cec5SDimitry Andricstruct __propagate_on_container_swap
12330b57cec5SDimitry Andric{
12340b57cec5SDimitry Andric    typedef false_type type;
12350b57cec5SDimitry Andric};
12360b57cec5SDimitry Andric
12370b57cec5SDimitry Andrictemplate <class _Alloc>
12380b57cec5SDimitry Andricstruct __propagate_on_container_swap<_Alloc, true>
12390b57cec5SDimitry Andric{
12400b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::propagate_on_container_swap type;
12410b57cec5SDimitry Andric};
12420b57cec5SDimitry Andric
12430b57cec5SDimitry Andrictemplate <class _Tp, class = void>
12440b57cec5SDimitry Andricstruct __has_is_always_equal : false_type {};
12450b57cec5SDimitry Andric
12460b57cec5SDimitry Andrictemplate <class _Tp>
12470b57cec5SDimitry Andricstruct __has_is_always_equal<_Tp,
12480b57cec5SDimitry Andric           typename __void_t<typename _Tp::is_always_equal>::type>
12490b57cec5SDimitry Andric               : true_type {};
12500b57cec5SDimitry Andric
12510b57cec5SDimitry Andrictemplate <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
12520b57cec5SDimitry Andricstruct __is_always_equal
12530b57cec5SDimitry Andric{
12540b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _VSTD::is_empty<_Alloc>::type type;
12550b57cec5SDimitry Andric};
12560b57cec5SDimitry Andric
12570b57cec5SDimitry Andrictemplate <class _Alloc>
12580b57cec5SDimitry Andricstruct __is_always_equal<_Alloc, true>
12590b57cec5SDimitry Andric{
12600b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::is_always_equal type;
12610b57cec5SDimitry Andric};
12620b57cec5SDimitry Andric
12630b57cec5SDimitry Andrictemplate <class _Tp, class _Up, bool = __has_rebind<_Tp, _Up>::value>
12640b57cec5SDimitry Andricstruct __has_rebind_other
12650b57cec5SDimitry Andric{
12660b57cec5SDimitry Andricprivate:
12670b57cec5SDimitry Andric    struct __two {char __lx; char __lxx;};
12680b57cec5SDimitry Andric    template <class _Xp> static __two __test(...);
12690b57cec5SDimitry Andric    template <class _Xp> static char __test(typename _Xp::template rebind<_Up>::other* = 0);
12700b57cec5SDimitry Andricpublic:
12710b57cec5SDimitry Andric    static const bool value = sizeof(__test<_Tp>(0)) == 1;
12720b57cec5SDimitry Andric};
12730b57cec5SDimitry Andric
12740b57cec5SDimitry Andrictemplate <class _Tp, class _Up>
12750b57cec5SDimitry Andricstruct __has_rebind_other<_Tp, _Up, false>
12760b57cec5SDimitry Andric{
12770b57cec5SDimitry Andric    static const bool value = false;
12780b57cec5SDimitry Andric};
12790b57cec5SDimitry Andric
12800b57cec5SDimitry Andrictemplate <class _Tp, class _Up, bool = __has_rebind_other<_Tp, _Up>::value>
12810b57cec5SDimitry Andricstruct __allocator_traits_rebind
12820b57cec5SDimitry Andric{
12830b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Tp::template rebind<_Up>::other type;
12840b57cec5SDimitry Andric};
12850b57cec5SDimitry Andric
12860b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
12870b57cec5SDimitry Andric
12880b57cec5SDimitry Andrictemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
12890b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>
12900b57cec5SDimitry Andric{
12910b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc<_Tp, _Args...>::template rebind<_Up>::other type;
12920b57cec5SDimitry Andric};
12930b57cec5SDimitry Andric
12940b57cec5SDimitry Andrictemplate <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
12950b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
12960b57cec5SDimitry Andric{
12970b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE _Alloc<_Up, _Args...> type;
12980b57cec5SDimitry Andric};
12990b57cec5SDimitry Andric
13000b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_VARIADICS
13010b57cec5SDimitry Andric
13020b57cec5SDimitry Andrictemplate <template <class> class _Alloc, class _Tp, class _Up>
13030b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp>, _Up, true>
13040b57cec5SDimitry Andric{
13050b57cec5SDimitry Andric    typedef typename _Alloc<_Tp>::template rebind<_Up>::other type;
13060b57cec5SDimitry Andric};
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andrictemplate <template <class> class _Alloc, class _Tp, class _Up>
13090b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp>, _Up, false>
13100b57cec5SDimitry Andric{
13110b57cec5SDimitry Andric    typedef _Alloc<_Up> type;
13120b57cec5SDimitry Andric};
13130b57cec5SDimitry Andric
13140b57cec5SDimitry Andrictemplate <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
13150b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, true>
13160b57cec5SDimitry Andric{
13170b57cec5SDimitry Andric    typedef typename _Alloc<_Tp, _A0>::template rebind<_Up>::other type;
13180b57cec5SDimitry Andric};
13190b57cec5SDimitry Andric
13200b57cec5SDimitry Andrictemplate <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
13210b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, false>
13220b57cec5SDimitry Andric{
13230b57cec5SDimitry Andric    typedef _Alloc<_Up, _A0> type;
13240b57cec5SDimitry Andric};
13250b57cec5SDimitry Andric
13260b57cec5SDimitry Andrictemplate <template <class, class, class> class _Alloc, class _Tp, class _A0,
13270b57cec5SDimitry Andric                                         class _A1, class _Up>
13280b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, true>
13290b57cec5SDimitry Andric{
13300b57cec5SDimitry Andric    typedef typename _Alloc<_Tp, _A0, _A1>::template rebind<_Up>::other type;
13310b57cec5SDimitry Andric};
13320b57cec5SDimitry Andric
13330b57cec5SDimitry Andrictemplate <template <class, class, class> class _Alloc, class _Tp, class _A0,
13340b57cec5SDimitry Andric                                         class _A1, class _Up>
13350b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, false>
13360b57cec5SDimitry Andric{
13370b57cec5SDimitry Andric    typedef _Alloc<_Up, _A0, _A1> type;
13380b57cec5SDimitry Andric};
13390b57cec5SDimitry Andric
13400b57cec5SDimitry Andrictemplate <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
13410b57cec5SDimitry Andric                                                class _A1, class _A2, class _Up>
13420b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, true>
13430b57cec5SDimitry Andric{
13440b57cec5SDimitry Andric    typedef typename _Alloc<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
13450b57cec5SDimitry Andric};
13460b57cec5SDimitry Andric
13470b57cec5SDimitry Andrictemplate <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
13480b57cec5SDimitry Andric                                                class _A1, class _A2, class _Up>
13490b57cec5SDimitry Andricstruct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false>
13500b57cec5SDimitry Andric{
13510b57cec5SDimitry Andric    typedef _Alloc<_Up, _A0, _A1, _A2> type;
13520b57cec5SDimitry Andric};
13530b57cec5SDimitry Andric
13540b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
13550b57cec5SDimitry Andric
13560b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
13570b57cec5SDimitry Andric
13580b57cec5SDimitry Andrictemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13590b57cec5SDimitry Andricauto
13600b57cec5SDimitry Andric__has_allocate_hint_test(_Alloc&& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
13610b57cec5SDimitry Andric    -> decltype((void)__a.allocate(__sz, __p), true_type());
13620b57cec5SDimitry Andric
13630b57cec5SDimitry Andrictemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13640b57cec5SDimitry Andricauto
13650b57cec5SDimitry Andric__has_allocate_hint_test(const _Alloc& __a, _SizeType&& __sz, _ConstVoidPtr&& __p)
13660b57cec5SDimitry Andric    -> false_type;
13670b57cec5SDimitry Andric
13680b57cec5SDimitry Andrictemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13690b57cec5SDimitry Andricstruct __has_allocate_hint
13700b57cec5SDimitry Andric    : integral_constant<bool,
13710b57cec5SDimitry Andric        is_same<
13720b57cec5SDimitry Andric            decltype(_VSTD::__has_allocate_hint_test(declval<_Alloc>(),
13730b57cec5SDimitry Andric                                          declval<_SizeType>(),
13740b57cec5SDimitry Andric                                          declval<_ConstVoidPtr>())),
13750b57cec5SDimitry Andric            true_type>::value>
13760b57cec5SDimitry Andric{
13770b57cec5SDimitry Andric};
13780b57cec5SDimitry Andric
13790b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
13800b57cec5SDimitry Andric
13810b57cec5SDimitry Andrictemplate <class _Alloc, class _SizeType, class _ConstVoidPtr>
13820b57cec5SDimitry Andricstruct __has_allocate_hint
13830b57cec5SDimitry Andric    : true_type
13840b57cec5SDimitry Andric{
13850b57cec5SDimitry Andric};
13860b57cec5SDimitry Andric
13870b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
13880b57cec5SDimitry Andric
13890b57cec5SDimitry Andric#if !defined(_LIBCPP_CXX03_LANG)
13900b57cec5SDimitry Andric
13910b57cec5SDimitry Andrictemplate <class _Alloc, class _Tp, class ..._Args>
13920b57cec5SDimitry Andricdecltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Tp*>(),
13930b57cec5SDimitry Andric                                           _VSTD::declval<_Args>()...),
13940b57cec5SDimitry Andric                                           true_type())
13950b57cec5SDimitry Andric__has_construct_test(_Alloc&& __a, _Tp* __p, _Args&& ...__args);
13960b57cec5SDimitry Andric
13970b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer, class ..._Args>
13980b57cec5SDimitry Andricfalse_type
13990b57cec5SDimitry Andric__has_construct_test(const _Alloc& __a, _Pointer&& __p, _Args&& ...__args);
14000b57cec5SDimitry Andric
14010b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer, class ..._Args>
14020b57cec5SDimitry Andricstruct __has_construct
14030b57cec5SDimitry Andric    : integral_constant<bool,
14040b57cec5SDimitry Andric        is_same<
14050b57cec5SDimitry Andric            decltype(_VSTD::__has_construct_test(declval<_Alloc>(),
14060b57cec5SDimitry Andric                                          declval<_Pointer>(),
14070b57cec5SDimitry Andric                                          declval<_Args>()...)),
14080b57cec5SDimitry Andric            true_type>::value>
14090b57cec5SDimitry Andric{
14100b57cec5SDimitry Andric};
14110b57cec5SDimitry Andric
14120b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer>
14130b57cec5SDimitry Andricauto
14140b57cec5SDimitry Andric__has_destroy_test(_Alloc&& __a, _Pointer&& __p)
14150b57cec5SDimitry Andric    -> decltype(__a.destroy(__p), true_type());
14160b57cec5SDimitry Andric
14170b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer>
14180b57cec5SDimitry Andricauto
14190b57cec5SDimitry Andric__has_destroy_test(const _Alloc& __a, _Pointer&& __p)
14200b57cec5SDimitry Andric    -> false_type;
14210b57cec5SDimitry Andric
14220b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer>
14230b57cec5SDimitry Andricstruct __has_destroy
14240b57cec5SDimitry Andric    : integral_constant<bool,
14250b57cec5SDimitry Andric        is_same<
14260b57cec5SDimitry Andric            decltype(_VSTD::__has_destroy_test(declval<_Alloc>(),
14270b57cec5SDimitry Andric                                        declval<_Pointer>())),
14280b57cec5SDimitry Andric            true_type>::value>
14290b57cec5SDimitry Andric{
14300b57cec5SDimitry Andric};
14310b57cec5SDimitry Andric
14320b57cec5SDimitry Andrictemplate <class _Alloc>
14330b57cec5SDimitry Andricauto
14340b57cec5SDimitry Andric__has_max_size_test(_Alloc&& __a)
14350b57cec5SDimitry Andric    -> decltype(__a.max_size(), true_type());
14360b57cec5SDimitry Andric
14370b57cec5SDimitry Andrictemplate <class _Alloc>
14380b57cec5SDimitry Andricauto
14390b57cec5SDimitry Andric__has_max_size_test(const volatile _Alloc& __a)
14400b57cec5SDimitry Andric    -> false_type;
14410b57cec5SDimitry Andric
14420b57cec5SDimitry Andrictemplate <class _Alloc>
14430b57cec5SDimitry Andricstruct __has_max_size
14440b57cec5SDimitry Andric    : integral_constant<bool,
14450b57cec5SDimitry Andric        is_same<
14460b57cec5SDimitry Andric            decltype(_VSTD::__has_max_size_test(declval<_Alloc&>())),
14470b57cec5SDimitry Andric            true_type>::value>
14480b57cec5SDimitry Andric{
14490b57cec5SDimitry Andric};
14500b57cec5SDimitry Andric
14510b57cec5SDimitry Andrictemplate <class _Alloc>
14520b57cec5SDimitry Andricauto
14530b57cec5SDimitry Andric__has_select_on_container_copy_construction_test(_Alloc&& __a)
14540b57cec5SDimitry Andric    -> decltype(__a.select_on_container_copy_construction(), true_type());
14550b57cec5SDimitry Andric
14560b57cec5SDimitry Andrictemplate <class _Alloc>
14570b57cec5SDimitry Andricauto
14580b57cec5SDimitry Andric__has_select_on_container_copy_construction_test(const volatile _Alloc& __a)
14590b57cec5SDimitry Andric    -> false_type;
14600b57cec5SDimitry Andric
14610b57cec5SDimitry Andrictemplate <class _Alloc>
14620b57cec5SDimitry Andricstruct __has_select_on_container_copy_construction
14630b57cec5SDimitry Andric    : integral_constant<bool,
14640b57cec5SDimitry Andric        is_same<
14650b57cec5SDimitry Andric            decltype(_VSTD::__has_select_on_container_copy_construction_test(declval<_Alloc&>())),
14660b57cec5SDimitry Andric            true_type>::value>
14670b57cec5SDimitry Andric{
14680b57cec5SDimitry Andric};
14690b57cec5SDimitry Andric
14700b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
14710b57cec5SDimitry Andric
14720b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer, class _Tp, class = void>
14730b57cec5SDimitry Andricstruct __has_construct : std::false_type {};
14740b57cec5SDimitry Andric
14750b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer, class _Tp>
14760b57cec5SDimitry Andricstruct __has_construct<_Alloc, _Pointer, _Tp, typename __void_t<
14770b57cec5SDimitry Andric    decltype(_VSTD::declval<_Alloc>().construct(_VSTD::declval<_Pointer>(), _VSTD::declval<_Tp>()))
14780b57cec5SDimitry Andric>::type> : std::true_type {};
14790b57cec5SDimitry Andric
14800b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer, class = void>
14810b57cec5SDimitry Andricstruct __has_destroy : false_type {};
14820b57cec5SDimitry Andric
14830b57cec5SDimitry Andrictemplate <class _Alloc, class _Pointer>
14840b57cec5SDimitry Andricstruct __has_destroy<_Alloc, _Pointer, typename __void_t<
14850b57cec5SDimitry Andric    decltype(_VSTD::declval<_Alloc>().destroy(_VSTD::declval<_Pointer>()))
14860b57cec5SDimitry Andric>::type> : std::true_type {};
14870b57cec5SDimitry Andric
14880b57cec5SDimitry Andrictemplate <class _Alloc>
14890b57cec5SDimitry Andricstruct __has_max_size
14900b57cec5SDimitry Andric    : true_type
14910b57cec5SDimitry Andric{
14920b57cec5SDimitry Andric};
14930b57cec5SDimitry Andric
14940b57cec5SDimitry Andrictemplate <class _Alloc>
14950b57cec5SDimitry Andricstruct __has_select_on_container_copy_construction
14960b57cec5SDimitry Andric    : false_type
14970b57cec5SDimitry Andric{
14980b57cec5SDimitry Andric};
14990b57cec5SDimitry Andric
15000b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
15010b57cec5SDimitry Andric
15020b57cec5SDimitry Andrictemplate <class _Alloc, class _Ptr, bool = __has_difference_type<_Alloc>::value>
15030b57cec5SDimitry Andricstruct __alloc_traits_difference_type
15040b57cec5SDimitry Andric{
15050b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename pointer_traits<_Ptr>::difference_type type;
15060b57cec5SDimitry Andric};
15070b57cec5SDimitry Andric
15080b57cec5SDimitry Andrictemplate <class _Alloc, class _Ptr>
15090b57cec5SDimitry Andricstruct __alloc_traits_difference_type<_Alloc, _Ptr, true>
15100b57cec5SDimitry Andric{
15110b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Alloc::difference_type type;
15120b57cec5SDimitry Andric};
15130b57cec5SDimitry Andric
15140b57cec5SDimitry Andrictemplate <class _Tp>
15150b57cec5SDimitry Andricstruct __is_default_allocator : false_type {};
15160b57cec5SDimitry Andric
15170b57cec5SDimitry Andrictemplate <class _Tp>
15180b57cec5SDimitry Andricstruct __is_default_allocator<_VSTD::allocator<_Tp> > : true_type {};
15190b57cec5SDimitry Andric
1520e40139ffSDimitry Andric
1521e40139ffSDimitry Andric
1522e40139ffSDimitry Andrictemplate <class _Alloc,
1523e40139ffSDimitry Andric    bool = __has_construct<_Alloc, typename _Alloc::value_type*,  typename _Alloc::value_type&&>::value && !__is_default_allocator<_Alloc>::value
1524e40139ffSDimitry Andric    >
1525e40139ffSDimitry Andricstruct __is_cpp17_move_insertable;
1526e40139ffSDimitry Andrictemplate <class _Alloc>
1527e40139ffSDimitry Andricstruct __is_cpp17_move_insertable<_Alloc, true> : std::true_type {};
1528e40139ffSDimitry Andrictemplate <class _Alloc>
1529e40139ffSDimitry Andricstruct __is_cpp17_move_insertable<_Alloc, false> : std::is_move_constructible<typename _Alloc::value_type> {};
1530e40139ffSDimitry Andric
1531e40139ffSDimitry Andrictemplate <class _Alloc,
1532e40139ffSDimitry Andric    bool = __has_construct<_Alloc, typename _Alloc::value_type*, const typename _Alloc::value_type&>::value && !__is_default_allocator<_Alloc>::value
1533e40139ffSDimitry Andric    >
1534e40139ffSDimitry Andricstruct __is_cpp17_copy_insertable;
1535e40139ffSDimitry Andrictemplate <class _Alloc>
1536e40139ffSDimitry Andricstruct __is_cpp17_copy_insertable<_Alloc, true> : __is_cpp17_move_insertable<_Alloc> {};
1537e40139ffSDimitry Andrictemplate <class _Alloc>
1538e40139ffSDimitry Andricstruct __is_cpp17_copy_insertable<_Alloc, false> : integral_constant<bool,
1539e40139ffSDimitry Andric    std::is_copy_constructible<typename _Alloc::value_type>::value &&
1540e40139ffSDimitry Andric    __is_cpp17_move_insertable<_Alloc>::value>
1541e40139ffSDimitry Andric  {};
1542e40139ffSDimitry Andric
1543e40139ffSDimitry Andric
1544e40139ffSDimitry Andric
15450b57cec5SDimitry Andrictemplate <class _Alloc>
15460b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS allocator_traits
15470b57cec5SDimitry Andric{
15480b57cec5SDimitry Andric    typedef _Alloc                              allocator_type;
15490b57cec5SDimitry Andric    typedef typename allocator_type::value_type value_type;
15500b57cec5SDimitry Andric
15510b57cec5SDimitry Andric    typedef typename __pointer_type<value_type, allocator_type>::type pointer;
15520b57cec5SDimitry Andric    typedef typename __const_pointer<value_type, pointer, allocator_type>::type const_pointer;
15530b57cec5SDimitry Andric    typedef typename __void_pointer<pointer, allocator_type>::type void_pointer;
15540b57cec5SDimitry Andric    typedef typename __const_void_pointer<pointer, allocator_type>::type const_void_pointer;
15550b57cec5SDimitry Andric
15560b57cec5SDimitry Andric    typedef typename __alloc_traits_difference_type<allocator_type, pointer>::type difference_type;
15570b57cec5SDimitry Andric    typedef typename __size_type<allocator_type, difference_type>::type size_type;
15580b57cec5SDimitry Andric
15590b57cec5SDimitry Andric    typedef typename __propagate_on_container_copy_assignment<allocator_type>::type
15600b57cec5SDimitry Andric                     propagate_on_container_copy_assignment;
15610b57cec5SDimitry Andric    typedef typename __propagate_on_container_move_assignment<allocator_type>::type
15620b57cec5SDimitry Andric                     propagate_on_container_move_assignment;
15630b57cec5SDimitry Andric    typedef typename __propagate_on_container_swap<allocator_type>::type
15640b57cec5SDimitry Andric                     propagate_on_container_swap;
15650b57cec5SDimitry Andric    typedef typename __is_always_equal<allocator_type>::type
15660b57cec5SDimitry Andric                     is_always_equal;
15670b57cec5SDimitry Andric
15680b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
15690b57cec5SDimitry Andric    template <class _Tp> using rebind_alloc =
15700b57cec5SDimitry Andric                  typename __allocator_traits_rebind<allocator_type, _Tp>::type;
15710b57cec5SDimitry Andric    template <class _Tp> using rebind_traits = allocator_traits<rebind_alloc<_Tp> >;
15720b57cec5SDimitry Andric#else  // _LIBCPP_CXX03_LANG
15730b57cec5SDimitry Andric    template <class _Tp> struct rebind_alloc
15740b57cec5SDimitry Andric        {typedef typename __allocator_traits_rebind<allocator_type, _Tp>::type other;};
15750b57cec5SDimitry Andric    template <class _Tp> struct rebind_traits
15760b57cec5SDimitry Andric        {typedef allocator_traits<typename rebind_alloc<_Tp>::other> other;};
15770b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
15780b57cec5SDimitry Andric
15790b57cec5SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
15800b57cec5SDimitry Andric    static pointer allocate(allocator_type& __a, size_type __n)
15810b57cec5SDimitry Andric        {return __a.allocate(__n);}
15820b57cec5SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
15830b57cec5SDimitry Andric    static pointer allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
15840b57cec5SDimitry Andric        {return __allocate(__a, __n, __hint,
15850b57cec5SDimitry Andric            __has_allocate_hint<allocator_type, size_type, const_void_pointer>());}
15860b57cec5SDimitry Andric
15870b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15880b57cec5SDimitry Andric    static void deallocate(allocator_type& __a, pointer __p, size_type __n) _NOEXCEPT
15890b57cec5SDimitry Andric        {__a.deallocate(__p, __n);}
15900b57cec5SDimitry Andric
15910b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
15920b57cec5SDimitry Andric    template <class _Tp, class... _Args>
15930b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
15940b57cec5SDimitry Andric        static void construct(allocator_type& __a, _Tp* __p, _Args&&... __args)
15950b57cec5SDimitry Andric            {__construct(__has_construct<allocator_type, _Tp*, _Args...>(),
15960b57cec5SDimitry Andric                         __a, __p, _VSTD::forward<_Args>(__args)...);}
15970b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_VARIADICS
15980b57cec5SDimitry Andric    template <class _Tp>
15990b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16000b57cec5SDimitry Andric        static void construct(allocator_type&, _Tp* __p)
16010b57cec5SDimitry Andric            {
16020b57cec5SDimitry Andric                ::new ((void*)__p) _Tp();
16030b57cec5SDimitry Andric            }
16040b57cec5SDimitry Andric    template <class _Tp, class _A0>
16050b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16060b57cec5SDimitry Andric        static void construct(allocator_type& __a, _Tp* __p, const _A0& __a0)
16070b57cec5SDimitry Andric            {
16080b57cec5SDimitry Andric                __construct(__has_construct<allocator_type, _Tp*, const _A0&>(),
16090b57cec5SDimitry Andric                            __a, __p, __a0);
16100b57cec5SDimitry Andric            }
16110b57cec5SDimitry Andric    template <class _Tp, class _A0, class _A1>
16120b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16130b57cec5SDimitry Andric        static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
16140b57cec5SDimitry Andric                              const _A1& __a1)
16150b57cec5SDimitry Andric            {
16160b57cec5SDimitry Andric                ::new ((void*)__p) _Tp(__a0, __a1);
16170b57cec5SDimitry Andric            }
16180b57cec5SDimitry Andric    template <class _Tp, class _A0, class _A1, class _A2>
16190b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16200b57cec5SDimitry Andric        static void construct(allocator_type&, _Tp* __p, const _A0& __a0,
16210b57cec5SDimitry Andric                              const _A1& __a1, const _A2& __a2)
16220b57cec5SDimitry Andric            {
16230b57cec5SDimitry Andric                ::new ((void*)__p) _Tp(__a0, __a1, __a2);
16240b57cec5SDimitry Andric            }
16250b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
16260b57cec5SDimitry Andric
16270b57cec5SDimitry Andric    template <class _Tp>
16280b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16290b57cec5SDimitry Andric        static void destroy(allocator_type& __a, _Tp* __p)
16300b57cec5SDimitry Andric            {__destroy(__has_destroy<allocator_type, _Tp*>(), __a, __p);}
16310b57cec5SDimitry Andric
16320b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16330b57cec5SDimitry Andric    static size_type max_size(const allocator_type& __a) _NOEXCEPT
16340b57cec5SDimitry Andric        {return __max_size(__has_max_size<const allocator_type>(), __a);}
16350b57cec5SDimitry Andric
16360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16370b57cec5SDimitry Andric    static allocator_type
16380b57cec5SDimitry Andric        select_on_container_copy_construction(const allocator_type& __a)
16390b57cec5SDimitry Andric            {return __select_on_container_copy_construction(
16400b57cec5SDimitry Andric                __has_select_on_container_copy_construction<const allocator_type>(),
16410b57cec5SDimitry Andric                __a);}
16420b57cec5SDimitry Andric
16430b57cec5SDimitry Andric    template <class _Ptr>
16440b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16450b57cec5SDimitry Andric        static
16460b57cec5SDimitry Andric        void
1647e40139ffSDimitry Andric        __construct_forward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2)
16480b57cec5SDimitry Andric        {
1649e40139ffSDimitry Andric            static_assert(__is_cpp17_move_insertable<allocator_type>::value,
1650e40139ffSDimitry Andric              "The specified type does not meet the requirements of Cpp17MoveInsertible");
16510b57cec5SDimitry Andric            for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
1652480093f4SDimitry Andric              construct(__a, _VSTD::__to_address(__begin2),
1653e40139ffSDimitry Andric#ifdef _LIBCPP_NO_EXCEPTIONS
1654e40139ffSDimitry Andric                        _VSTD::move(*__begin1)
1655e40139ffSDimitry Andric#else
1656e40139ffSDimitry Andric                        _VSTD::move_if_noexcept(*__begin1)
1657e40139ffSDimitry Andric#endif
1658e40139ffSDimitry Andric                        );
16590b57cec5SDimitry Andric        }
16600b57cec5SDimitry Andric
16610b57cec5SDimitry Andric    template <class _Tp>
16620b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16630b57cec5SDimitry Andric        static
16640b57cec5SDimitry Andric        typename enable_if
16650b57cec5SDimitry Andric        <
16660b57cec5SDimitry Andric            (__is_default_allocator<allocator_type>::value
16670b57cec5SDimitry Andric                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
16680b57cec5SDimitry Andric             is_trivially_move_constructible<_Tp>::value,
16690b57cec5SDimitry Andric            void
16700b57cec5SDimitry Andric        >::type
1671e40139ffSDimitry Andric        __construct_forward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2)
16720b57cec5SDimitry Andric        {
16730b57cec5SDimitry Andric            ptrdiff_t _Np = __end1 - __begin1;
16740b57cec5SDimitry Andric            if (_Np > 0)
16750b57cec5SDimitry Andric            {
16760b57cec5SDimitry Andric                _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
16770b57cec5SDimitry Andric                __begin2 += _Np;
16780b57cec5SDimitry Andric            }
16790b57cec5SDimitry Andric        }
16800b57cec5SDimitry Andric
16810b57cec5SDimitry Andric    template <class _Iter, class _Ptr>
16820b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16830b57cec5SDimitry Andric        static
16840b57cec5SDimitry Andric        void
16850b57cec5SDimitry Andric        __construct_range_forward(allocator_type& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2)
16860b57cec5SDimitry Andric        {
16870b57cec5SDimitry Andric            for (; __begin1 != __end1; ++__begin1, (void) ++__begin2)
1688480093f4SDimitry Andric                construct(__a, _VSTD::__to_address(__begin2), *__begin1);
16890b57cec5SDimitry Andric        }
16900b57cec5SDimitry Andric
16910b57cec5SDimitry Andric    template <class _SourceTp, class _DestTp,
16920b57cec5SDimitry Andric              class _RawSourceTp = typename remove_const<_SourceTp>::type,
16930b57cec5SDimitry Andric              class _RawDestTp = typename remove_const<_DestTp>::type>
16940b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
16950b57cec5SDimitry Andric        static
16960b57cec5SDimitry Andric        typename enable_if
16970b57cec5SDimitry Andric        <
16980b57cec5SDimitry Andric            is_trivially_move_constructible<_DestTp>::value &&
16990b57cec5SDimitry Andric            is_same<_RawSourceTp, _RawDestTp>::value &&
17000b57cec5SDimitry Andric            (__is_default_allocator<allocator_type>::value ||
17010b57cec5SDimitry Andric             !__has_construct<allocator_type, _DestTp*, _SourceTp&>::value),
17020b57cec5SDimitry Andric            void
17030b57cec5SDimitry Andric        >::type
17040b57cec5SDimitry Andric        __construct_range_forward(allocator_type&, _SourceTp* __begin1, _SourceTp* __end1, _DestTp*& __begin2)
17050b57cec5SDimitry Andric        {
17060b57cec5SDimitry Andric            ptrdiff_t _Np = __end1 - __begin1;
17070b57cec5SDimitry Andric            if (_Np > 0)
17080b57cec5SDimitry Andric            {
17090b57cec5SDimitry Andric                _VSTD::memcpy(const_cast<_RawDestTp*>(__begin2), __begin1, _Np * sizeof(_DestTp));
17100b57cec5SDimitry Andric                __begin2 += _Np;
17110b57cec5SDimitry Andric            }
17120b57cec5SDimitry Andric        }
17130b57cec5SDimitry Andric
17140b57cec5SDimitry Andric    template <class _Ptr>
17150b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17160b57cec5SDimitry Andric        static
17170b57cec5SDimitry Andric        void
1718e40139ffSDimitry Andric        __construct_backward_with_exception_guarantees(allocator_type& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2)
17190b57cec5SDimitry Andric        {
1720e40139ffSDimitry Andric            static_assert(__is_cpp17_move_insertable<allocator_type>::value,
1721e40139ffSDimitry Andric              "The specified type does not meet the requirements of Cpp17MoveInsertable");
17220b57cec5SDimitry Andric            while (__end1 != __begin1)
17230b57cec5SDimitry Andric            {
1724480093f4SDimitry Andric              construct(__a, _VSTD::__to_address(__end2 - 1),
1725e40139ffSDimitry Andric#ifdef _LIBCPP_NO_EXCEPTIONS
1726e40139ffSDimitry Andric                        _VSTD::move(*--__end1)
1727e40139ffSDimitry Andric#else
1728e40139ffSDimitry Andric                        _VSTD::move_if_noexcept(*--__end1)
1729e40139ffSDimitry Andric#endif
1730e40139ffSDimitry Andric                        );
17310b57cec5SDimitry Andric              --__end2;
17320b57cec5SDimitry Andric            }
17330b57cec5SDimitry Andric        }
17340b57cec5SDimitry Andric
17350b57cec5SDimitry Andric    template <class _Tp>
17360b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17370b57cec5SDimitry Andric        static
17380b57cec5SDimitry Andric        typename enable_if
17390b57cec5SDimitry Andric        <
17400b57cec5SDimitry Andric            (__is_default_allocator<allocator_type>::value
17410b57cec5SDimitry Andric                || !__has_construct<allocator_type, _Tp*, _Tp>::value) &&
17420b57cec5SDimitry Andric             is_trivially_move_constructible<_Tp>::value,
17430b57cec5SDimitry Andric            void
17440b57cec5SDimitry Andric        >::type
1745e40139ffSDimitry Andric        __construct_backward_with_exception_guarantees(allocator_type&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2)
17460b57cec5SDimitry Andric        {
17470b57cec5SDimitry Andric            ptrdiff_t _Np = __end1 - __begin1;
17480b57cec5SDimitry Andric            __end2 -= _Np;
17490b57cec5SDimitry Andric            if (_Np > 0)
17500b57cec5SDimitry Andric                _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
17510b57cec5SDimitry Andric        }
17520b57cec5SDimitry Andric
17530b57cec5SDimitry Andricprivate:
17540b57cec5SDimitry Andric
17550b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17560b57cec5SDimitry Andric    static pointer __allocate(allocator_type& __a, size_type __n,
17570b57cec5SDimitry Andric        const_void_pointer __hint, true_type)
17580b57cec5SDimitry Andric        {return __a.allocate(__n, __hint);}
17590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17600b57cec5SDimitry Andric    static pointer __allocate(allocator_type& __a, size_type __n,
17610b57cec5SDimitry Andric        const_void_pointer, false_type)
17620b57cec5SDimitry Andric        {return __a.allocate(__n);}
17630b57cec5SDimitry Andric
17640b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
17650b57cec5SDimitry Andric    template <class _Tp, class... _Args>
17660b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17670b57cec5SDimitry Andric        static void __construct(true_type, allocator_type& __a, _Tp* __p, _Args&&... __args)
17680b57cec5SDimitry Andric            {__a.construct(__p, _VSTD::forward<_Args>(__args)...);}
17690b57cec5SDimitry Andric    template <class _Tp, class... _Args>
17700b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17710b57cec5SDimitry Andric        static void __construct(false_type, allocator_type&, _Tp* __p, _Args&&... __args)
17720b57cec5SDimitry Andric            {
17730b57cec5SDimitry Andric                ::new ((void*)__p) _Tp(_VSTD::forward<_Args>(__args)...);
17740b57cec5SDimitry Andric            }
17750b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_VARIADICS
17760b57cec5SDimitry Andric    template <class _Tp, class _A0>
17770b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17780b57cec5SDimitry Andric        static void __construct(true_type, allocator_type& __a, _Tp* __p,
17790b57cec5SDimitry Andric                                const _A0& __a0)
17800b57cec5SDimitry Andric            {__a.construct(__p, __a0);}
17810b57cec5SDimitry Andric    template <class _Tp, class _A0>
17820b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17830b57cec5SDimitry Andric        static void __construct(false_type, allocator_type&, _Tp* __p,
17840b57cec5SDimitry Andric                                const _A0& __a0)
17850b57cec5SDimitry Andric            {
17860b57cec5SDimitry Andric                ::new ((void*)__p) _Tp(__a0);
17870b57cec5SDimitry Andric            }
17880b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
17890b57cec5SDimitry Andric
17900b57cec5SDimitry Andric    template <class _Tp>
17910b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17920b57cec5SDimitry Andric        static void __destroy(true_type, allocator_type& __a, _Tp* __p)
17930b57cec5SDimitry Andric            {__a.destroy(__p);}
17940b57cec5SDimitry Andric    template <class _Tp>
17950b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
17960b57cec5SDimitry Andric        static void __destroy(false_type, allocator_type&, _Tp* __p)
17970b57cec5SDimitry Andric            {
17980b57cec5SDimitry Andric                __p->~_Tp();
17990b57cec5SDimitry Andric            }
18000b57cec5SDimitry Andric
18010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18020b57cec5SDimitry Andric    static size_type __max_size(true_type, const allocator_type& __a) _NOEXCEPT
18030b57cec5SDimitry Andric            {return __a.max_size();}
18040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18050b57cec5SDimitry Andric    static size_type __max_size(false_type, const allocator_type&) _NOEXCEPT
18060b57cec5SDimitry Andric            {return numeric_limits<size_type>::max() / sizeof(value_type);}
18070b57cec5SDimitry Andric
18080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18090b57cec5SDimitry Andric    static allocator_type
18100b57cec5SDimitry Andric        __select_on_container_copy_construction(true_type, const allocator_type& __a)
18110b57cec5SDimitry Andric            {return __a.select_on_container_copy_construction();}
18120b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18130b57cec5SDimitry Andric    static allocator_type
18140b57cec5SDimitry Andric        __select_on_container_copy_construction(false_type, const allocator_type& __a)
18150b57cec5SDimitry Andric            {return __a;}
18160b57cec5SDimitry Andric};
18170b57cec5SDimitry Andric
18180b57cec5SDimitry Andrictemplate <class _Traits, class _Tp>
18190b57cec5SDimitry Andricstruct __rebind_alloc_helper
18200b57cec5SDimitry Andric{
18210b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
18220b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename _Traits::template rebind_alloc<_Tp>        type;
18230b57cec5SDimitry Andric#else
18240b57cec5SDimitry Andric    typedef typename _Traits::template rebind_alloc<_Tp>::other type;
18250b57cec5SDimitry Andric#endif
18260b57cec5SDimitry Andric};
18270b57cec5SDimitry Andric
18280b57cec5SDimitry Andric// allocator
18290b57cec5SDimitry Andric
18300b57cec5SDimitry Andrictemplate <class _Tp>
18310b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator
18320b57cec5SDimitry Andric{
18330b57cec5SDimitry Andricpublic:
18340b57cec5SDimitry Andric    typedef size_t            size_type;
18350b57cec5SDimitry Andric    typedef ptrdiff_t         difference_type;
18360b57cec5SDimitry Andric    typedef _Tp*              pointer;
18370b57cec5SDimitry Andric    typedef const _Tp*        const_pointer;
18380b57cec5SDimitry Andric    typedef _Tp&              reference;
18390b57cec5SDimitry Andric    typedef const _Tp&        const_reference;
18400b57cec5SDimitry Andric    typedef _Tp               value_type;
18410b57cec5SDimitry Andric
18420b57cec5SDimitry Andric    typedef true_type propagate_on_container_move_assignment;
18430b57cec5SDimitry Andric    typedef true_type is_always_equal;
18440b57cec5SDimitry Andric
18450b57cec5SDimitry Andric    template <class _Up> struct rebind {typedef allocator<_Up> other;};
18460b57cec5SDimitry Andric
18470b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
18480b57cec5SDimitry Andric    allocator() _NOEXCEPT {}
18490b57cec5SDimitry Andric
18500b57cec5SDimitry Andric    template <class _Up>
18510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
18520b57cec5SDimitry Andric    allocator(const allocator<_Up>&) _NOEXCEPT {}
18530b57cec5SDimitry Andric
18540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY pointer address(reference __x) const _NOEXCEPT
18550b57cec5SDimitry Andric        {return _VSTD::addressof(__x);}
18560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
18570b57cec5SDimitry Andric        {return _VSTD::addressof(__x);}
18580b57cec5SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
18590b57cec5SDimitry Andric    pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
18600b57cec5SDimitry Andric        {
18610b57cec5SDimitry Andric        if (__n > max_size())
18620b57cec5SDimitry Andric            __throw_length_error("allocator<T>::allocate(size_t n)"
18630b57cec5SDimitry Andric                                 " 'n' exceeds maximum supported size");
18640b57cec5SDimitry Andric        return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
18650b57cec5SDimitry Andric        }
18660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
18670b57cec5SDimitry Andric        {_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
18680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
18690b57cec5SDimitry Andric        {return size_type(~0) / sizeof(_Tp);}
18700b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
18710b57cec5SDimitry Andric    template <class _Up, class... _Args>
18720b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
18730b57cec5SDimitry Andric        void
18740b57cec5SDimitry Andric        construct(_Up* __p, _Args&&... __args)
18750b57cec5SDimitry Andric        {
18760b57cec5SDimitry Andric            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
18770b57cec5SDimitry Andric        }
18780b57cec5SDimitry Andric#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
18790b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
18800b57cec5SDimitry Andric        void
18810b57cec5SDimitry Andric        construct(pointer __p)
18820b57cec5SDimitry Andric        {
18830b57cec5SDimitry Andric            ::new((void*)__p) _Tp();
18840b57cec5SDimitry Andric        }
18850b57cec5SDimitry Andric# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
18860b57cec5SDimitry Andric
18870b57cec5SDimitry Andric    template <class _A0>
18880b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
18890b57cec5SDimitry Andric        void
18900b57cec5SDimitry Andric        construct(pointer __p, _A0& __a0)
18910b57cec5SDimitry Andric        {
18920b57cec5SDimitry Andric            ::new((void*)__p) _Tp(__a0);
18930b57cec5SDimitry Andric        }
18940b57cec5SDimitry Andric    template <class _A0>
18950b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
18960b57cec5SDimitry Andric        void
18970b57cec5SDimitry Andric        construct(pointer __p, const _A0& __a0)
18980b57cec5SDimitry Andric        {
18990b57cec5SDimitry Andric            ::new((void*)__p) _Tp(__a0);
19000b57cec5SDimitry Andric        }
19010b57cec5SDimitry Andric# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
19020b57cec5SDimitry Andric    template <class _A0, class _A1>
19030b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19040b57cec5SDimitry Andric        void
19050b57cec5SDimitry Andric        construct(pointer __p, _A0& __a0, _A1& __a1)
19060b57cec5SDimitry Andric        {
19070b57cec5SDimitry Andric            ::new((void*)__p) _Tp(__a0, __a1);
19080b57cec5SDimitry Andric        }
19090b57cec5SDimitry Andric    template <class _A0, class _A1>
19100b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19110b57cec5SDimitry Andric        void
19120b57cec5SDimitry Andric        construct(pointer __p, const _A0& __a0, _A1& __a1)
19130b57cec5SDimitry Andric        {
19140b57cec5SDimitry Andric            ::new((void*)__p) _Tp(__a0, __a1);
19150b57cec5SDimitry Andric        }
19160b57cec5SDimitry Andric    template <class _A0, class _A1>
19170b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19180b57cec5SDimitry Andric        void
19190b57cec5SDimitry Andric        construct(pointer __p, _A0& __a0, const _A1& __a1)
19200b57cec5SDimitry Andric        {
19210b57cec5SDimitry Andric            ::new((void*)__p) _Tp(__a0, __a1);
19220b57cec5SDimitry Andric        }
19230b57cec5SDimitry Andric    template <class _A0, class _A1>
19240b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19250b57cec5SDimitry Andric        void
19260b57cec5SDimitry Andric        construct(pointer __p, const _A0& __a0, const _A1& __a1)
19270b57cec5SDimitry Andric        {
19280b57cec5SDimitry Andric            ::new((void*)__p) _Tp(__a0, __a1);
19290b57cec5SDimitry Andric        }
19300b57cec5SDimitry Andric#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
19310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
19320b57cec5SDimitry Andric};
19330b57cec5SDimitry Andric
19340b57cec5SDimitry Andrictemplate <class _Tp>
19350b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
19360b57cec5SDimitry Andric{
19370b57cec5SDimitry Andricpublic:
19380b57cec5SDimitry Andric    typedef size_t            size_type;
19390b57cec5SDimitry Andric    typedef ptrdiff_t         difference_type;
19400b57cec5SDimitry Andric    typedef const _Tp*        pointer;
19410b57cec5SDimitry Andric    typedef const _Tp*        const_pointer;
19420b57cec5SDimitry Andric    typedef const _Tp&        reference;
19430b57cec5SDimitry Andric    typedef const _Tp&        const_reference;
19440b57cec5SDimitry Andric    typedef const _Tp         value_type;
19450b57cec5SDimitry Andric
19460b57cec5SDimitry Andric    typedef true_type propagate_on_container_move_assignment;
19470b57cec5SDimitry Andric    typedef true_type is_always_equal;
19480b57cec5SDimitry Andric
19490b57cec5SDimitry Andric    template <class _Up> struct rebind {typedef allocator<_Up> other;};
19500b57cec5SDimitry Andric
19510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
19520b57cec5SDimitry Andric    allocator() _NOEXCEPT {}
19530b57cec5SDimitry Andric
19540b57cec5SDimitry Andric    template <class _Up>
19550b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
19560b57cec5SDimitry Andric    allocator(const allocator<_Up>&) _NOEXCEPT {}
19570b57cec5SDimitry Andric
19580b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY const_pointer address(const_reference __x) const _NOEXCEPT
19590b57cec5SDimitry Andric        {return _VSTD::addressof(__x);}
19600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY pointer allocate(size_type __n, allocator<void>::const_pointer = 0)
19610b57cec5SDimitry Andric    {
19620b57cec5SDimitry Andric        if (__n > max_size())
19630b57cec5SDimitry Andric            __throw_length_error("allocator<const T>::allocate(size_t n)"
19640b57cec5SDimitry Andric                                 " 'n' exceeds maximum supported size");
19650b57cec5SDimitry Andric        return static_cast<pointer>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
19660b57cec5SDimitry Andric    }
19670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type __n) _NOEXCEPT
19680b57cec5SDimitry Andric        {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
19690b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
19700b57cec5SDimitry Andric        {return size_type(~0) / sizeof(_Tp);}
19710b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
19720b57cec5SDimitry Andric    template <class _Up, class... _Args>
19730b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19740b57cec5SDimitry Andric        void
19750b57cec5SDimitry Andric        construct(_Up* __p, _Args&&... __args)
19760b57cec5SDimitry Andric        {
19770b57cec5SDimitry Andric            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
19780b57cec5SDimitry Andric        }
19790b57cec5SDimitry Andric#else  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
19800b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19810b57cec5SDimitry Andric        void
19820b57cec5SDimitry Andric        construct(pointer __p)
19830b57cec5SDimitry Andric        {
19840b57cec5SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp();
19850b57cec5SDimitry Andric        }
19860b57cec5SDimitry Andric# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
19870b57cec5SDimitry Andric
19880b57cec5SDimitry Andric    template <class _A0>
19890b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19900b57cec5SDimitry Andric        void
19910b57cec5SDimitry Andric        construct(pointer __p, _A0& __a0)
19920b57cec5SDimitry Andric        {
19930b57cec5SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
19940b57cec5SDimitry Andric        }
19950b57cec5SDimitry Andric    template <class _A0>
19960b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19970b57cec5SDimitry Andric        void
19980b57cec5SDimitry Andric        construct(pointer __p, const _A0& __a0)
19990b57cec5SDimitry Andric        {
20000b57cec5SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
20010b57cec5SDimitry Andric        }
20020b57cec5SDimitry Andric# endif  // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
20030b57cec5SDimitry Andric    template <class _A0, class _A1>
20040b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
20050b57cec5SDimitry Andric        void
20060b57cec5SDimitry Andric        construct(pointer __p, _A0& __a0, _A1& __a1)
20070b57cec5SDimitry Andric        {
20080b57cec5SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
20090b57cec5SDimitry Andric        }
20100b57cec5SDimitry Andric    template <class _A0, class _A1>
20110b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
20120b57cec5SDimitry Andric        void
20130b57cec5SDimitry Andric        construct(pointer __p, const _A0& __a0, _A1& __a1)
20140b57cec5SDimitry Andric        {
20150b57cec5SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
20160b57cec5SDimitry Andric        }
20170b57cec5SDimitry Andric    template <class _A0, class _A1>
20180b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
20190b57cec5SDimitry Andric        void
20200b57cec5SDimitry Andric        construct(pointer __p, _A0& __a0, const _A1& __a1)
20210b57cec5SDimitry Andric        {
20220b57cec5SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
20230b57cec5SDimitry Andric        }
20240b57cec5SDimitry Andric    template <class _A0, class _A1>
20250b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
20260b57cec5SDimitry Andric        void
20270b57cec5SDimitry Andric        construct(pointer __p, const _A0& __a0, const _A1& __a1)
20280b57cec5SDimitry Andric        {
20290b57cec5SDimitry Andric            ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
20300b57cec5SDimitry Andric        }
20310b57cec5SDimitry Andric#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
20320b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
20330b57cec5SDimitry Andric};
20340b57cec5SDimitry Andric
20350b57cec5SDimitry Andrictemplate <class _Tp, class _Up>
20360b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20370b57cec5SDimitry Andricbool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
20380b57cec5SDimitry Andric
20390b57cec5SDimitry Andrictemplate <class _Tp, class _Up>
20400b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20410b57cec5SDimitry Andricbool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
20420b57cec5SDimitry Andric
20430b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Tp>
20440b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS raw_storage_iterator
20450b57cec5SDimitry Andric    : public iterator<output_iterator_tag,
20460b57cec5SDimitry Andric                      _Tp,                                         // purposefully not C++03
20470b57cec5SDimitry Andric                      ptrdiff_t,                                   // purposefully not C++03
20480b57cec5SDimitry Andric                      _Tp*,                                        // purposefully not C++03
20490b57cec5SDimitry Andric                      raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03
20500b57cec5SDimitry Andric{
20510b57cec5SDimitry Andricprivate:
20520b57cec5SDimitry Andric    _OutputIterator __x_;
20530b57cec5SDimitry Andricpublic:
20540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
20550b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
20560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
20570b57cec5SDimitry Andric        {::new(_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
20580b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
20590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
20600b57cec5SDimitry Andric        {::new(_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
20610b57cec5SDimitry Andric#endif
20620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
20630b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator  operator++(int)
20640b57cec5SDimitry Andric        {raw_storage_iterator __t(*this); ++__x_; return __t;}
20650b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
20660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
20670b57cec5SDimitry Andric#endif
20680b57cec5SDimitry Andric};
20690b57cec5SDimitry Andric
20700b57cec5SDimitry Andrictemplate <class _Tp>
20710b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
20720b57cec5SDimitry Andricpair<_Tp*, ptrdiff_t>
20730b57cec5SDimitry Andricget_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
20740b57cec5SDimitry Andric{
20750b57cec5SDimitry Andric    pair<_Tp*, ptrdiff_t> __r(0, 0);
20760b57cec5SDimitry Andric    const ptrdiff_t __m = (~ptrdiff_t(0) ^
20770b57cec5SDimitry Andric                           ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
20780b57cec5SDimitry Andric                           / sizeof(_Tp);
20790b57cec5SDimitry Andric    if (__n > __m)
20800b57cec5SDimitry Andric        __n = __m;
20810b57cec5SDimitry Andric    while (__n > 0)
20820b57cec5SDimitry Andric    {
20830b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
20840b57cec5SDimitry Andric    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
20850b57cec5SDimitry Andric        {
20860b57cec5SDimitry Andric            std::align_val_t __al =
20870b57cec5SDimitry Andric                std::align_val_t(std::alignment_of<_Tp>::value);
20880b57cec5SDimitry Andric            __r.first = static_cast<_Tp*>(::operator new(
20890b57cec5SDimitry Andric                __n * sizeof(_Tp), __al, nothrow));
20900b57cec5SDimitry Andric        } else {
20910b57cec5SDimitry Andric            __r.first = static_cast<_Tp*>(::operator new(
20920b57cec5SDimitry Andric                __n * sizeof(_Tp), nothrow));
20930b57cec5SDimitry Andric        }
20940b57cec5SDimitry Andric#else
20950b57cec5SDimitry Andric    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
20960b57cec5SDimitry Andric        {
20970b57cec5SDimitry Andric            // Since aligned operator new is unavailable, return an empty
20980b57cec5SDimitry Andric            // buffer rather than one with invalid alignment.
20990b57cec5SDimitry Andric            return __r;
21000b57cec5SDimitry Andric        }
21010b57cec5SDimitry Andric
21020b57cec5SDimitry Andric        __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
21030b57cec5SDimitry Andric#endif
21040b57cec5SDimitry Andric
21050b57cec5SDimitry Andric        if (__r.first)
21060b57cec5SDimitry Andric        {
21070b57cec5SDimitry Andric            __r.second = __n;
21080b57cec5SDimitry Andric            break;
21090b57cec5SDimitry Andric        }
21100b57cec5SDimitry Andric        __n /= 2;
21110b57cec5SDimitry Andric    }
21120b57cec5SDimitry Andric    return __r;
21130b57cec5SDimitry Andric}
21140b57cec5SDimitry Andric
21150b57cec5SDimitry Andrictemplate <class _Tp>
21160b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
21170b57cec5SDimitry Andricvoid return_temporary_buffer(_Tp* __p) _NOEXCEPT
21180b57cec5SDimitry Andric{
21190b57cec5SDimitry Andric  _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
21200b57cec5SDimitry Andric}
21210b57cec5SDimitry Andric
21220b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
21230b57cec5SDimitry Andrictemplate <class _Tp>
21240b57cec5SDimitry Andricstruct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
21250b57cec5SDimitry Andric{
21260b57cec5SDimitry Andric    _Tp* __ptr_;
21270b57cec5SDimitry Andric};
21280b57cec5SDimitry Andric
21290b57cec5SDimitry Andrictemplate<class _Tp>
21300b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
21310b57cec5SDimitry Andric{
21320b57cec5SDimitry Andricprivate:
21330b57cec5SDimitry Andric    _Tp* __ptr_;
21340b57cec5SDimitry Andricpublic:
21350b57cec5SDimitry Andric    typedef _Tp element_type;
21360b57cec5SDimitry Andric
2137*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {}
2138*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {}
2139*9ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT
21400b57cec5SDimitry Andric        : __ptr_(__p.release()) {}
2141*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT
21420b57cec5SDimitry Andric        {reset(__p.release()); return *this;}
2143*9ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT
21440b57cec5SDimitry Andric        {reset(__p.release()); return *this;}
2145*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT
21460b57cec5SDimitry Andric        {reset(__p.__ptr_); return *this;}
2147*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;}
21480b57cec5SDimitry Andric
2149*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT
21500b57cec5SDimitry Andric        {return *__ptr_;}
2151*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;}
2152*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;}
2153*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT
21540b57cec5SDimitry Andric    {
21550b57cec5SDimitry Andric        _Tp* __t = __ptr_;
21560b57cec5SDimitry Andric        __ptr_ = 0;
21570b57cec5SDimitry Andric        return __t;
21580b57cec5SDimitry Andric    }
2159*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT
21600b57cec5SDimitry Andric    {
21610b57cec5SDimitry Andric        if (__ptr_ != __p)
21620b57cec5SDimitry Andric            delete __ptr_;
21630b57cec5SDimitry Andric        __ptr_ = __p;
21640b57cec5SDimitry Andric    }
21650b57cec5SDimitry Andric
2166*9ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
2167*9ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT
21680b57cec5SDimitry Andric        {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
2169*9ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT
21700b57cec5SDimitry Andric        {return auto_ptr<_Up>(release());}
21710b57cec5SDimitry Andric};
21720b57cec5SDimitry Andric
21730b57cec5SDimitry Andrictemplate <>
21740b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
21750b57cec5SDimitry Andric{
21760b57cec5SDimitry Andricpublic:
21770b57cec5SDimitry Andric    typedef void element_type;
21780b57cec5SDimitry Andric};
21790b57cec5SDimitry Andric#endif
21800b57cec5SDimitry Andric
2181480093f4SDimitry Andric// Tag used to default initialize one or both of the pair's elements.
2182480093f4SDimitry Andricstruct __default_init_tag {};
2183480093f4SDimitry Andricstruct __value_init_tag {};
2184480093f4SDimitry Andric
21850b57cec5SDimitry Andrictemplate <class _Tp, int _Idx,
21860b57cec5SDimitry Andric          bool _CanBeEmptyBase =
21870b57cec5SDimitry Andric              is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
21880b57cec5SDimitry Andricstruct __compressed_pair_elem {
21890b57cec5SDimitry Andric  typedef _Tp _ParamT;
21900b57cec5SDimitry Andric  typedef _Tp& reference;
21910b57cec5SDimitry Andric  typedef const _Tp& const_reference;
21920b57cec5SDimitry Andric
2193480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2194480093f4SDimitry Andric  __compressed_pair_elem(__default_init_tag) {}
2195480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2196480093f4SDimitry Andric  __compressed_pair_elem(__value_init_tag) : __value_() {}
21970b57cec5SDimitry Andric
21980b57cec5SDimitry Andric  template <class _Up, class = typename enable_if<
21990b57cec5SDimitry Andric      !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
22000b57cec5SDimitry Andric  >::type>
22010b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2202480093f4SDimitry Andric  _LIBCPP_CONSTEXPR explicit
22030b57cec5SDimitry Andric  __compressed_pair_elem(_Up&& __u)
22040b57cec5SDimitry Andric      : __value_(_VSTD::forward<_Up>(__u))
22050b57cec5SDimitry Andric    {
22060b57cec5SDimitry Andric    }
22070b57cec5SDimitry Andric
2208480093f4SDimitry Andric
2209480093f4SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
22100b57cec5SDimitry Andric  template <class... _Args, size_t... _Indexes>
22110b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
22120b57cec5SDimitry Andric  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
22130b57cec5SDimitry Andric                         __tuple_indices<_Indexes...>)
22140b57cec5SDimitry Andric      : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
22150b57cec5SDimitry Andric#endif
22160b57cec5SDimitry Andric
2217480093f4SDimitry Andric
22180b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
22190b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22200b57cec5SDimitry Andric  const_reference __get() const _NOEXCEPT { return __value_; }
22210b57cec5SDimitry Andric
22220b57cec5SDimitry Andricprivate:
22230b57cec5SDimitry Andric  _Tp __value_;
22240b57cec5SDimitry Andric};
22250b57cec5SDimitry Andric
22260b57cec5SDimitry Andrictemplate <class _Tp, int _Idx>
22270b57cec5SDimitry Andricstruct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
22280b57cec5SDimitry Andric  typedef _Tp _ParamT;
22290b57cec5SDimitry Andric  typedef _Tp& reference;
22300b57cec5SDimitry Andric  typedef const _Tp& const_reference;
22310b57cec5SDimitry Andric  typedef _Tp __value_type;
22320b57cec5SDimitry Andric
2233480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
2234480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2235480093f4SDimitry Andric  __compressed_pair_elem(__default_init_tag) {}
2236480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2237480093f4SDimitry Andric  __compressed_pair_elem(__value_init_tag) : __value_type() {}
22380b57cec5SDimitry Andric
22390b57cec5SDimitry Andric  template <class _Up, class = typename enable_if<
22400b57cec5SDimitry Andric        !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
22410b57cec5SDimitry Andric  >::type>
22420b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2243480093f4SDimitry Andric  _LIBCPP_CONSTEXPR explicit
22440b57cec5SDimitry Andric  __compressed_pair_elem(_Up&& __u)
22450b57cec5SDimitry Andric      : __value_type(_VSTD::forward<_Up>(__u))
22460b57cec5SDimitry Andric  {}
22470b57cec5SDimitry Andric
2248480093f4SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
22490b57cec5SDimitry Andric  template <class... _Args, size_t... _Indexes>
22500b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
22510b57cec5SDimitry Andric  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
22520b57cec5SDimitry Andric                         __tuple_indices<_Indexes...>)
22530b57cec5SDimitry Andric      : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
22540b57cec5SDimitry Andric#endif
22550b57cec5SDimitry Andric
22560b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
22570b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
22580b57cec5SDimitry Andric  const_reference __get() const _NOEXCEPT { return *this; }
22590b57cec5SDimitry Andric};
22600b57cec5SDimitry Andric
22610b57cec5SDimitry Andrictemplate <class _T1, class _T2>
22620b57cec5SDimitry Andricclass __compressed_pair : private __compressed_pair_elem<_T1, 0>,
22630b57cec5SDimitry Andric                          private __compressed_pair_elem<_T2, 1> {
22640b57cec5SDimitry Andric  typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T1, 0> _Base1;
22650b57cec5SDimitry Andric  typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T2, 1> _Base2;
22660b57cec5SDimitry Andric
22670b57cec5SDimitry Andric  // NOTE: This static assert should never fire because __compressed_pair
22680b57cec5SDimitry Andric  // is *almost never* used in a scenario where it's possible for T1 == T2.
22690b57cec5SDimitry Andric  // (The exception is std::function where it is possible that the function
22700b57cec5SDimitry Andric  //  object and the allocator have the same type).
22710b57cec5SDimitry Andric  static_assert((!is_same<_T1, _T2>::value),
22720b57cec5SDimitry Andric    "__compressed_pair cannot be instantated when T1 and T2 are the same type; "
22730b57cec5SDimitry Andric    "The current implementation is NOT ABI-compatible with the previous "
22740b57cec5SDimitry Andric    "implementation for this configuration");
22750b57cec5SDimitry Andric
22760b57cec5SDimitry Andricpublic:
22770b57cec5SDimitry Andric    template <bool _Dummy = true,
22780b57cec5SDimitry Andric      class = typename enable_if<
22790b57cec5SDimitry Andric          __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
22800b57cec5SDimitry Andric          __dependent_type<is_default_constructible<_T2>, _Dummy>::value
22810b57cec5SDimitry Andric      >::type
22820b57cec5SDimitry Andric  >
22830b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2284480093f4SDimitry Andric  _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
22850b57cec5SDimitry Andric
22860b57cec5SDimitry Andric  template <class _U1, class _U2>
2287480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
22880b57cec5SDimitry Andric  __compressed_pair(_U1&& __t1, _U2&& __t2)
22890b57cec5SDimitry Andric      : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {}
22900b57cec5SDimitry Andric
2291480093f4SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
22920b57cec5SDimitry Andric  template <class... _Args1, class... _Args2>
22930b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
22940b57cec5SDimitry Andric  __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
22950b57cec5SDimitry Andric                    tuple<_Args2...> __second_args)
22960b57cec5SDimitry Andric      : _Base1(__pc, _VSTD::move(__first_args),
22970b57cec5SDimitry Andric               typename __make_tuple_indices<sizeof...(_Args1)>::type()),
22980b57cec5SDimitry Andric        _Base2(__pc, _VSTD::move(__second_args),
22990b57cec5SDimitry Andric               typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
23000b57cec5SDimitry Andric#endif
23010b57cec5SDimitry Andric
23020b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23030b57cec5SDimitry Andric  typename _Base1::reference first() _NOEXCEPT {
23040b57cec5SDimitry Andric    return static_cast<_Base1&>(*this).__get();
23050b57cec5SDimitry Andric  }
23060b57cec5SDimitry Andric
23070b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23080b57cec5SDimitry Andric  typename _Base1::const_reference first() const _NOEXCEPT {
23090b57cec5SDimitry Andric    return static_cast<_Base1 const&>(*this).__get();
23100b57cec5SDimitry Andric  }
23110b57cec5SDimitry Andric
23120b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23130b57cec5SDimitry Andric  typename _Base2::reference second() _NOEXCEPT {
23140b57cec5SDimitry Andric    return static_cast<_Base2&>(*this).__get();
23150b57cec5SDimitry Andric  }
23160b57cec5SDimitry Andric
23170b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23180b57cec5SDimitry Andric  typename _Base2::const_reference second() const _NOEXCEPT {
23190b57cec5SDimitry Andric    return static_cast<_Base2 const&>(*this).__get();
23200b57cec5SDimitry Andric  }
23210b57cec5SDimitry Andric
23220b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23230b57cec5SDimitry Andric  void swap(__compressed_pair& __x)
23240b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
23250b57cec5SDimitry Andric               __is_nothrow_swappable<_T2>::value)
23260b57cec5SDimitry Andric  {
23270b57cec5SDimitry Andric    using std::swap;
23280b57cec5SDimitry Andric    swap(first(), __x.first());
23290b57cec5SDimitry Andric    swap(second(), __x.second());
23300b57cec5SDimitry Andric  }
23310b57cec5SDimitry Andric};
23320b57cec5SDimitry Andric
23330b57cec5SDimitry Andrictemplate <class _T1, class _T2>
23340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23350b57cec5SDimitry Andricvoid swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
23360b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
23370b57cec5SDimitry Andric               __is_nothrow_swappable<_T2>::value) {
23380b57cec5SDimitry Andric  __x.swap(__y);
23390b57cec5SDimitry Andric}
23400b57cec5SDimitry Andric
23410b57cec5SDimitry Andric// default_delete
23420b57cec5SDimitry Andric
23430b57cec5SDimitry Andrictemplate <class _Tp>
23440b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS default_delete {
23450b57cec5SDimitry Andric    static_assert(!is_function<_Tp>::value,
23460b57cec5SDimitry Andric                  "default_delete cannot be instantiated for function types");
23470b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
23480b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
23490b57cec5SDimitry Andric#else
23500b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY default_delete() {}
23510b57cec5SDimitry Andric#endif
23520b57cec5SDimitry Andric  template <class _Up>
23530b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23540b57cec5SDimitry Andric  default_delete(const default_delete<_Up>&,
23550b57cec5SDimitry Andric                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
23560b57cec5SDimitry Andric                     0) _NOEXCEPT {}
23570b57cec5SDimitry Andric
23580b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
23590b57cec5SDimitry Andric    static_assert(sizeof(_Tp) > 0,
23600b57cec5SDimitry Andric                  "default_delete can not delete incomplete type");
23610b57cec5SDimitry Andric    static_assert(!is_void<_Tp>::value,
23620b57cec5SDimitry Andric                  "default_delete can not delete incomplete type");
23630b57cec5SDimitry Andric    delete __ptr;
23640b57cec5SDimitry Andric  }
23650b57cec5SDimitry Andric};
23660b57cec5SDimitry Andric
23670b57cec5SDimitry Andrictemplate <class _Tp>
23680b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
23690b57cec5SDimitry Andricprivate:
23700b57cec5SDimitry Andric  template <class _Up>
23710b57cec5SDimitry Andric  struct _EnableIfConvertible
23720b57cec5SDimitry Andric      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
23730b57cec5SDimitry Andric
23740b57cec5SDimitry Andricpublic:
23750b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
23760b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
23770b57cec5SDimitry Andric#else
23780b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY default_delete() {}
23790b57cec5SDimitry Andric#endif
23800b57cec5SDimitry Andric
23810b57cec5SDimitry Andric  template <class _Up>
23820b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23830b57cec5SDimitry Andric  default_delete(const default_delete<_Up[]>&,
23840b57cec5SDimitry Andric                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
23850b57cec5SDimitry Andric
23860b57cec5SDimitry Andric  template <class _Up>
23870b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
23880b57cec5SDimitry Andric  typename _EnableIfConvertible<_Up>::type
23890b57cec5SDimitry Andric  operator()(_Up* __ptr) const _NOEXCEPT {
23900b57cec5SDimitry Andric    static_assert(sizeof(_Tp) > 0,
23910b57cec5SDimitry Andric                  "default_delete can not delete incomplete type");
23920b57cec5SDimitry Andric    static_assert(!is_void<_Tp>::value,
23930b57cec5SDimitry Andric                  "default_delete can not delete void type");
23940b57cec5SDimitry Andric    delete[] __ptr;
23950b57cec5SDimitry Andric  }
23960b57cec5SDimitry Andric};
23970b57cec5SDimitry Andric
23980b57cec5SDimitry Andrictemplate <class _Deleter>
23990b57cec5SDimitry Andricstruct __unique_ptr_deleter_sfinae {
24000b57cec5SDimitry Andric  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
24010b57cec5SDimitry Andric  typedef const _Deleter& __lval_ref_type;
24020b57cec5SDimitry Andric  typedef _Deleter&& __good_rval_ref_type;
24030b57cec5SDimitry Andric  typedef true_type __enable_rval_overload;
24040b57cec5SDimitry Andric};
24050b57cec5SDimitry Andric
24060b57cec5SDimitry Andrictemplate <class _Deleter>
24070b57cec5SDimitry Andricstruct __unique_ptr_deleter_sfinae<_Deleter const&> {
24080b57cec5SDimitry Andric  typedef const _Deleter& __lval_ref_type;
24090b57cec5SDimitry Andric  typedef const _Deleter&& __bad_rval_ref_type;
24100b57cec5SDimitry Andric  typedef false_type __enable_rval_overload;
24110b57cec5SDimitry Andric};
24120b57cec5SDimitry Andric
24130b57cec5SDimitry Andrictemplate <class _Deleter>
24140b57cec5SDimitry Andricstruct __unique_ptr_deleter_sfinae<_Deleter&> {
24150b57cec5SDimitry Andric  typedef _Deleter& __lval_ref_type;
24160b57cec5SDimitry Andric  typedef _Deleter&& __bad_rval_ref_type;
24170b57cec5SDimitry Andric  typedef false_type __enable_rval_overload;
24180b57cec5SDimitry Andric};
24190b57cec5SDimitry Andric
24200b57cec5SDimitry Andrictemplate <class _Tp, class _Dp = default_delete<_Tp> >
24210b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS unique_ptr {
24220b57cec5SDimitry Andricpublic:
24230b57cec5SDimitry Andric  typedef _Tp element_type;
24240b57cec5SDimitry Andric  typedef _Dp deleter_type;
24250b57cec5SDimitry Andric  typedef _LIBCPP_NODEBUG_TYPE typename __pointer_type<_Tp, deleter_type>::type pointer;
24260b57cec5SDimitry Andric
24270b57cec5SDimitry Andric  static_assert(!is_rvalue_reference<deleter_type>::value,
24280b57cec5SDimitry Andric                "the specified deleter type cannot be an rvalue reference");
24290b57cec5SDimitry Andric
24300b57cec5SDimitry Andricprivate:
24310b57cec5SDimitry Andric  __compressed_pair<pointer, deleter_type> __ptr_;
24320b57cec5SDimitry Andric
24330b57cec5SDimitry Andric  struct __nat { int __for_bool_; };
24340b57cec5SDimitry Andric
24350b57cec5SDimitry Andric  typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
24360b57cec5SDimitry Andric
24370b57cec5SDimitry Andric  template <bool _Dummy>
24380b57cec5SDimitry Andric  using _LValRefType _LIBCPP_NODEBUG_TYPE =
24390b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
24400b57cec5SDimitry Andric
24410b57cec5SDimitry Andric  template <bool _Dummy>
24420b57cec5SDimitry Andric  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
24430b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
24440b57cec5SDimitry Andric
24450b57cec5SDimitry Andric  template <bool _Dummy>
24460b57cec5SDimitry Andric  using _BadRValRefType _LIBCPP_NODEBUG_TYPE  =
24470b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
24480b57cec5SDimitry Andric
24490b57cec5SDimitry Andric  template <bool _Dummy, class _Deleter = typename __dependent_type<
24500b57cec5SDimitry Andric                             __identity<deleter_type>, _Dummy>::type>
24510b57cec5SDimitry Andric  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
24520b57cec5SDimitry Andric      typename enable_if<is_default_constructible<_Deleter>::value &&
24530b57cec5SDimitry Andric                         !is_pointer<_Deleter>::value>::type;
24540b57cec5SDimitry Andric
24550b57cec5SDimitry Andric  template <class _ArgType>
24560b57cec5SDimitry Andric  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
24570b57cec5SDimitry Andric      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
24580b57cec5SDimitry Andric
24590b57cec5SDimitry Andric  template <class _UPtr, class _Up>
24600b57cec5SDimitry Andric  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
24610b57cec5SDimitry Andric      is_convertible<typename _UPtr::pointer, pointer>::value &&
24620b57cec5SDimitry Andric      !is_array<_Up>::value
24630b57cec5SDimitry Andric  >::type;
24640b57cec5SDimitry Andric
24650b57cec5SDimitry Andric  template <class _UDel>
24660b57cec5SDimitry Andric  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
24670b57cec5SDimitry Andric      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
24680b57cec5SDimitry Andric      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
24690b57cec5SDimitry Andric    >::type;
24700b57cec5SDimitry Andric
24710b57cec5SDimitry Andric  template <class _UDel>
24720b57cec5SDimitry Andric  using _EnableIfDeleterAssignable = typename enable_if<
24730b57cec5SDimitry Andric      is_assignable<_Dp&, _UDel&&>::value
24740b57cec5SDimitry Andric    >::type;
24750b57cec5SDimitry Andric
24760b57cec5SDimitry Andricpublic:
24770b57cec5SDimitry Andric  template <bool _Dummy = true,
24780b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
24790b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2480480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
24810b57cec5SDimitry Andric
24820b57cec5SDimitry Andric  template <bool _Dummy = true,
24830b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
24840b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2485480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
24860b57cec5SDimitry Andric
24870b57cec5SDimitry Andric  template <bool _Dummy = true,
24880b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
24890b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2490480093f4SDimitry Andric  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
24910b57cec5SDimitry Andric
24920b57cec5SDimitry Andric  template <bool _Dummy = true,
24930b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
24940b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
24950b57cec5SDimitry Andric  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
24960b57cec5SDimitry Andric      : __ptr_(__p, __d) {}
24970b57cec5SDimitry Andric
24980b57cec5SDimitry Andric  template <bool _Dummy = true,
24990b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
25000b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25010b57cec5SDimitry Andric  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
25020b57cec5SDimitry Andric      : __ptr_(__p, _VSTD::move(__d)) {
25030b57cec5SDimitry Andric    static_assert(!is_reference<deleter_type>::value,
25040b57cec5SDimitry Andric                  "rvalue deleter bound to reference");
25050b57cec5SDimitry Andric  }
25060b57cec5SDimitry Andric
25070b57cec5SDimitry Andric  template <bool _Dummy = true,
25080b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
25090b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25100b57cec5SDimitry Andric  unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
25110b57cec5SDimitry Andric
25120b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25130b57cec5SDimitry Andric  unique_ptr(unique_ptr&& __u) _NOEXCEPT
25140b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
25150b57cec5SDimitry Andric  }
25160b57cec5SDimitry Andric
25170b57cec5SDimitry Andric  template <class _Up, class _Ep,
25180b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
25190b57cec5SDimitry Andric      class = _EnableIfDeleterConvertible<_Ep>
25200b57cec5SDimitry Andric  >
25210b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25220b57cec5SDimitry Andric  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
25230b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
25240b57cec5SDimitry Andric
25250b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
25260b57cec5SDimitry Andric  template <class _Up>
25270b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25280b57cec5SDimitry Andric  unique_ptr(auto_ptr<_Up>&& __p,
25290b57cec5SDimitry Andric             typename enable_if<is_convertible<_Up*, _Tp*>::value &&
25300b57cec5SDimitry Andric                                    is_same<_Dp, default_delete<_Tp> >::value,
25310b57cec5SDimitry Andric                                __nat>::type = __nat()) _NOEXCEPT
2532480093f4SDimitry Andric      : __ptr_(__p.release(), __default_init_tag()) {}
25330b57cec5SDimitry Andric#endif
25340b57cec5SDimitry Andric
25350b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25360b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
25370b57cec5SDimitry Andric    reset(__u.release());
25380b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
25390b57cec5SDimitry Andric    return *this;
25400b57cec5SDimitry Andric  }
25410b57cec5SDimitry Andric
25420b57cec5SDimitry Andric  template <class _Up, class _Ep,
25430b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
25440b57cec5SDimitry Andric      class = _EnableIfDeleterAssignable<_Ep>
25450b57cec5SDimitry Andric  >
25460b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25470b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
25480b57cec5SDimitry Andric    reset(__u.release());
25490b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
25500b57cec5SDimitry Andric    return *this;
25510b57cec5SDimitry Andric  }
25520b57cec5SDimitry Andric
25530b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
25540b57cec5SDimitry Andric  template <class _Up>
25550b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25560b57cec5SDimitry Andric      typename enable_if<is_convertible<_Up*, _Tp*>::value &&
25570b57cec5SDimitry Andric                             is_same<_Dp, default_delete<_Tp> >::value,
25580b57cec5SDimitry Andric                         unique_ptr&>::type
25590b57cec5SDimitry Andric      operator=(auto_ptr<_Up> __p) {
25600b57cec5SDimitry Andric    reset(__p.release());
25610b57cec5SDimitry Andric    return *this;
25620b57cec5SDimitry Andric  }
25630b57cec5SDimitry Andric#endif
25640b57cec5SDimitry Andric
25650b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
25660b57cec5SDimitry Andric  unique_ptr(unique_ptr const&) = delete;
25670b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr const&) = delete;
25680b57cec5SDimitry Andric#endif
25690b57cec5SDimitry Andric
25700b57cec5SDimitry Andric
25710b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25720b57cec5SDimitry Andric  ~unique_ptr() { reset(); }
25730b57cec5SDimitry Andric
25740b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25750b57cec5SDimitry Andric  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
25760b57cec5SDimitry Andric    reset();
25770b57cec5SDimitry Andric    return *this;
25780b57cec5SDimitry Andric  }
25790b57cec5SDimitry Andric
25800b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25810b57cec5SDimitry Andric  typename add_lvalue_reference<_Tp>::type
25820b57cec5SDimitry Andric  operator*() const {
25830b57cec5SDimitry Andric    return *__ptr_.first();
25840b57cec5SDimitry Andric  }
25850b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25860b57cec5SDimitry Andric  pointer operator->() const _NOEXCEPT {
25870b57cec5SDimitry Andric    return __ptr_.first();
25880b57cec5SDimitry Andric  }
25890b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25900b57cec5SDimitry Andric  pointer get() const _NOEXCEPT {
25910b57cec5SDimitry Andric    return __ptr_.first();
25920b57cec5SDimitry Andric  }
25930b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25940b57cec5SDimitry Andric  deleter_type& get_deleter() _NOEXCEPT {
25950b57cec5SDimitry Andric    return __ptr_.second();
25960b57cec5SDimitry Andric  }
25970b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
25980b57cec5SDimitry Andric  const deleter_type& get_deleter() const _NOEXCEPT {
25990b57cec5SDimitry Andric    return __ptr_.second();
26000b57cec5SDimitry Andric  }
26010b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26020b57cec5SDimitry Andric  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
26030b57cec5SDimitry Andric    return __ptr_.first() != nullptr;
26040b57cec5SDimitry Andric  }
26050b57cec5SDimitry Andric
26060b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26070b57cec5SDimitry Andric  pointer release() _NOEXCEPT {
26080b57cec5SDimitry Andric    pointer __t = __ptr_.first();
26090b57cec5SDimitry Andric    __ptr_.first() = pointer();
26100b57cec5SDimitry Andric    return __t;
26110b57cec5SDimitry Andric  }
26120b57cec5SDimitry Andric
26130b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26140b57cec5SDimitry Andric  void reset(pointer __p = pointer()) _NOEXCEPT {
26150b57cec5SDimitry Andric    pointer __tmp = __ptr_.first();
26160b57cec5SDimitry Andric    __ptr_.first() = __p;
26170b57cec5SDimitry Andric    if (__tmp)
26180b57cec5SDimitry Andric      __ptr_.second()(__tmp);
26190b57cec5SDimitry Andric  }
26200b57cec5SDimitry Andric
26210b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
26220b57cec5SDimitry Andric  void swap(unique_ptr& __u) _NOEXCEPT {
26230b57cec5SDimitry Andric    __ptr_.swap(__u.__ptr_);
26240b57cec5SDimitry Andric  }
26250b57cec5SDimitry Andric};
26260b57cec5SDimitry Andric
26270b57cec5SDimitry Andric
26280b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
26290b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
26300b57cec5SDimitry Andricpublic:
26310b57cec5SDimitry Andric  typedef _Tp element_type;
26320b57cec5SDimitry Andric  typedef _Dp deleter_type;
26330b57cec5SDimitry Andric  typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
26340b57cec5SDimitry Andric
26350b57cec5SDimitry Andricprivate:
26360b57cec5SDimitry Andric  __compressed_pair<pointer, deleter_type> __ptr_;
26370b57cec5SDimitry Andric
26380b57cec5SDimitry Andric  template <class _From>
26390b57cec5SDimitry Andric  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
26400b57cec5SDimitry Andric
26410b57cec5SDimitry Andric  template <class _FromElem>
26420b57cec5SDimitry Andric  struct _CheckArrayPointerConversion<_FromElem*>
26430b57cec5SDimitry Andric      : integral_constant<bool,
26440b57cec5SDimitry Andric          is_same<_FromElem*, pointer>::value ||
26450b57cec5SDimitry Andric            (is_same<pointer, element_type*>::value &&
26460b57cec5SDimitry Andric             is_convertible<_FromElem(*)[], element_type(*)[]>::value)
26470b57cec5SDimitry Andric      >
26480b57cec5SDimitry Andric  {};
26490b57cec5SDimitry Andric
26500b57cec5SDimitry Andric  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
26510b57cec5SDimitry Andric
26520b57cec5SDimitry Andric  template <bool _Dummy>
26530b57cec5SDimitry Andric  using _LValRefType _LIBCPP_NODEBUG_TYPE =
26540b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
26550b57cec5SDimitry Andric
26560b57cec5SDimitry Andric  template <bool _Dummy>
26570b57cec5SDimitry Andric  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
26580b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
26590b57cec5SDimitry Andric
26600b57cec5SDimitry Andric  template <bool _Dummy>
26610b57cec5SDimitry Andric  using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
26620b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
26630b57cec5SDimitry Andric
26640b57cec5SDimitry Andric  template <bool _Dummy, class _Deleter = typename __dependent_type<
26650b57cec5SDimitry Andric                             __identity<deleter_type>, _Dummy>::type>
26660b57cec5SDimitry Andric  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE  =
26670b57cec5SDimitry Andric      typename enable_if<is_default_constructible<_Deleter>::value &&
26680b57cec5SDimitry Andric                         !is_pointer<_Deleter>::value>::type;
26690b57cec5SDimitry Andric
26700b57cec5SDimitry Andric  template <class _ArgType>
26710b57cec5SDimitry Andric  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
26720b57cec5SDimitry Andric      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
26730b57cec5SDimitry Andric
26740b57cec5SDimitry Andric  template <class _Pp>
26750b57cec5SDimitry Andric  using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
26760b57cec5SDimitry Andric      _CheckArrayPointerConversion<_Pp>::value
26770b57cec5SDimitry Andric  >::type;
26780b57cec5SDimitry Andric
26790b57cec5SDimitry Andric  template <class _UPtr, class _Up,
26800b57cec5SDimitry Andric        class _ElemT = typename _UPtr::element_type>
26810b57cec5SDimitry Andric  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
26820b57cec5SDimitry Andric      is_array<_Up>::value &&
26830b57cec5SDimitry Andric      is_same<pointer, element_type*>::value &&
26840b57cec5SDimitry Andric      is_same<typename _UPtr::pointer, _ElemT*>::value &&
26850b57cec5SDimitry Andric      is_convertible<_ElemT(*)[], element_type(*)[]>::value
26860b57cec5SDimitry Andric    >::type;
26870b57cec5SDimitry Andric
26880b57cec5SDimitry Andric  template <class _UDel>
26890b57cec5SDimitry Andric  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
26900b57cec5SDimitry Andric      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
26910b57cec5SDimitry Andric      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
26920b57cec5SDimitry Andric    >::type;
26930b57cec5SDimitry Andric
26940b57cec5SDimitry Andric  template <class _UDel>
26950b57cec5SDimitry Andric  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE  = typename enable_if<
26960b57cec5SDimitry Andric      is_assignable<_Dp&, _UDel&&>::value
26970b57cec5SDimitry Andric    >::type;
26980b57cec5SDimitry Andric
26990b57cec5SDimitry Andricpublic:
27000b57cec5SDimitry Andric  template <bool _Dummy = true,
27010b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
27020b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2703480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
27040b57cec5SDimitry Andric
27050b57cec5SDimitry Andric  template <bool _Dummy = true,
27060b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
27070b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
2708480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
27090b57cec5SDimitry Andric
27100b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
27110b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
27120b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
27130b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27140b57cec5SDimitry Andric  explicit unique_ptr(_Pp __p) _NOEXCEPT
2715480093f4SDimitry Andric      : __ptr_(__p, __default_init_tag()) {}
27160b57cec5SDimitry Andric
27170b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
27180b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
27190b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
27200b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27210b57cec5SDimitry Andric  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
27220b57cec5SDimitry Andric      : __ptr_(__p, __d) {}
27230b57cec5SDimitry Andric
27240b57cec5SDimitry Andric  template <bool _Dummy = true,
27250b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
27260b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27270b57cec5SDimitry Andric  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
27280b57cec5SDimitry Andric      : __ptr_(nullptr, __d) {}
27290b57cec5SDimitry Andric
27300b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
27310b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
27320b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
27330b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27340b57cec5SDimitry Andric  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
27350b57cec5SDimitry Andric      : __ptr_(__p, _VSTD::move(__d)) {
27360b57cec5SDimitry Andric    static_assert(!is_reference<deleter_type>::value,
27370b57cec5SDimitry Andric                  "rvalue deleter bound to reference");
27380b57cec5SDimitry Andric  }
27390b57cec5SDimitry Andric
27400b57cec5SDimitry Andric  template <bool _Dummy = true,
27410b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
27420b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27430b57cec5SDimitry Andric  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
27440b57cec5SDimitry Andric      : __ptr_(nullptr, _VSTD::move(__d)) {
27450b57cec5SDimitry Andric    static_assert(!is_reference<deleter_type>::value,
27460b57cec5SDimitry Andric                  "rvalue deleter bound to reference");
27470b57cec5SDimitry Andric  }
27480b57cec5SDimitry Andric
27490b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
27500b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
27510b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
27520b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27530b57cec5SDimitry Andric  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
27540b57cec5SDimitry Andric
27550b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27560b57cec5SDimitry Andric  unique_ptr(unique_ptr&& __u) _NOEXCEPT
27570b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
27580b57cec5SDimitry Andric  }
27590b57cec5SDimitry Andric
27600b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27610b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
27620b57cec5SDimitry Andric    reset(__u.release());
27630b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
27640b57cec5SDimitry Andric    return *this;
27650b57cec5SDimitry Andric  }
27660b57cec5SDimitry Andric
27670b57cec5SDimitry Andric  template <class _Up, class _Ep,
27680b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
27690b57cec5SDimitry Andric      class = _EnableIfDeleterConvertible<_Ep>
27700b57cec5SDimitry Andric  >
27710b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27720b57cec5SDimitry Andric  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
27730b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
27740b57cec5SDimitry Andric  }
27750b57cec5SDimitry Andric
27760b57cec5SDimitry Andric  template <class _Up, class _Ep,
27770b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
27780b57cec5SDimitry Andric      class = _EnableIfDeleterAssignable<_Ep>
27790b57cec5SDimitry Andric  >
27800b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27810b57cec5SDimitry Andric  unique_ptr&
27820b57cec5SDimitry Andric  operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
27830b57cec5SDimitry Andric    reset(__u.release());
27840b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
27850b57cec5SDimitry Andric    return *this;
27860b57cec5SDimitry Andric  }
27870b57cec5SDimitry Andric
27880b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
27890b57cec5SDimitry Andric  unique_ptr(unique_ptr const&) = delete;
27900b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr const&) = delete;
27910b57cec5SDimitry Andric#endif
27920b57cec5SDimitry Andric
27930b57cec5SDimitry Andricpublic:
27940b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27950b57cec5SDimitry Andric  ~unique_ptr() { reset(); }
27960b57cec5SDimitry Andric
27970b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
27980b57cec5SDimitry Andric  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
27990b57cec5SDimitry Andric    reset();
28000b57cec5SDimitry Andric    return *this;
28010b57cec5SDimitry Andric  }
28020b57cec5SDimitry Andric
28030b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28040b57cec5SDimitry Andric  typename add_lvalue_reference<_Tp>::type
28050b57cec5SDimitry Andric  operator[](size_t __i) const {
28060b57cec5SDimitry Andric    return __ptr_.first()[__i];
28070b57cec5SDimitry Andric  }
28080b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28090b57cec5SDimitry Andric  pointer get() const _NOEXCEPT {
28100b57cec5SDimitry Andric    return __ptr_.first();
28110b57cec5SDimitry Andric  }
28120b57cec5SDimitry Andric
28130b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28140b57cec5SDimitry Andric  deleter_type& get_deleter() _NOEXCEPT {
28150b57cec5SDimitry Andric    return __ptr_.second();
28160b57cec5SDimitry Andric  }
28170b57cec5SDimitry Andric
28180b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28190b57cec5SDimitry Andric  const deleter_type& get_deleter() const _NOEXCEPT {
28200b57cec5SDimitry Andric    return __ptr_.second();
28210b57cec5SDimitry Andric  }
28220b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28230b57cec5SDimitry Andric  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
28240b57cec5SDimitry Andric    return __ptr_.first() != nullptr;
28250b57cec5SDimitry Andric  }
28260b57cec5SDimitry Andric
28270b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28280b57cec5SDimitry Andric  pointer release() _NOEXCEPT {
28290b57cec5SDimitry Andric    pointer __t = __ptr_.first();
28300b57cec5SDimitry Andric    __ptr_.first() = pointer();
28310b57cec5SDimitry Andric    return __t;
28320b57cec5SDimitry Andric  }
28330b57cec5SDimitry Andric
28340b57cec5SDimitry Andric  template <class _Pp>
28350b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28360b57cec5SDimitry Andric  typename enable_if<
28370b57cec5SDimitry Andric      _CheckArrayPointerConversion<_Pp>::value
28380b57cec5SDimitry Andric  >::type
28390b57cec5SDimitry Andric  reset(_Pp __p) _NOEXCEPT {
28400b57cec5SDimitry Andric    pointer __tmp = __ptr_.first();
28410b57cec5SDimitry Andric    __ptr_.first() = __p;
28420b57cec5SDimitry Andric    if (__tmp)
28430b57cec5SDimitry Andric      __ptr_.second()(__tmp);
28440b57cec5SDimitry Andric  }
28450b57cec5SDimitry Andric
28460b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28470b57cec5SDimitry Andric  void reset(nullptr_t = nullptr) _NOEXCEPT {
28480b57cec5SDimitry Andric    pointer __tmp = __ptr_.first();
28490b57cec5SDimitry Andric    __ptr_.first() = nullptr;
28500b57cec5SDimitry Andric    if (__tmp)
28510b57cec5SDimitry Andric      __ptr_.second()(__tmp);
28520b57cec5SDimitry Andric  }
28530b57cec5SDimitry Andric
28540b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
28550b57cec5SDimitry Andric  void swap(unique_ptr& __u) _NOEXCEPT {
28560b57cec5SDimitry Andric    __ptr_.swap(__u.__ptr_);
28570b57cec5SDimitry Andric  }
28580b57cec5SDimitry Andric
28590b57cec5SDimitry Andric};
28600b57cec5SDimitry Andric
28610b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
28620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28630b57cec5SDimitry Andrictypename enable_if<
28640b57cec5SDimitry Andric    __is_swappable<_Dp>::value,
28650b57cec5SDimitry Andric    void
28660b57cec5SDimitry Andric>::type
28670b57cec5SDimitry Andricswap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
28680b57cec5SDimitry Andric
28690b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
28700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28710b57cec5SDimitry Andricbool
28720b57cec5SDimitry Andricoperator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
28730b57cec5SDimitry Andric
28740b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
28750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28760b57cec5SDimitry Andricbool
28770b57cec5SDimitry Andricoperator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
28780b57cec5SDimitry Andric
28790b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
28800b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28810b57cec5SDimitry Andricbool
28820b57cec5SDimitry Andricoperator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
28830b57cec5SDimitry Andric{
28840b57cec5SDimitry Andric    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
28850b57cec5SDimitry Andric    typedef typename unique_ptr<_T2, _D2>::pointer _P2;
28860b57cec5SDimitry Andric    typedef typename common_type<_P1, _P2>::type _Vp;
28870b57cec5SDimitry Andric    return less<_Vp>()(__x.get(), __y.get());
28880b57cec5SDimitry Andric}
28890b57cec5SDimitry Andric
28900b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
28910b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28920b57cec5SDimitry Andricbool
28930b57cec5SDimitry Andricoperator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
28940b57cec5SDimitry Andric
28950b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
28960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28970b57cec5SDimitry Andricbool
28980b57cec5SDimitry Andricoperator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
28990b57cec5SDimitry Andric
29000b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
29010b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29020b57cec5SDimitry Andricbool
29030b57cec5SDimitry Andricoperator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
29040b57cec5SDimitry Andric
29050b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29060b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29070b57cec5SDimitry Andricbool
29080b57cec5SDimitry Andricoperator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
29090b57cec5SDimitry Andric{
29100b57cec5SDimitry Andric    return !__x;
29110b57cec5SDimitry Andric}
29120b57cec5SDimitry Andric
29130b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29150b57cec5SDimitry Andricbool
29160b57cec5SDimitry Andricoperator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
29170b57cec5SDimitry Andric{
29180b57cec5SDimitry Andric    return !__x;
29190b57cec5SDimitry Andric}
29200b57cec5SDimitry Andric
29210b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29220b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29230b57cec5SDimitry Andricbool
29240b57cec5SDimitry Andricoperator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
29250b57cec5SDimitry Andric{
29260b57cec5SDimitry Andric    return static_cast<bool>(__x);
29270b57cec5SDimitry Andric}
29280b57cec5SDimitry Andric
29290b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29300b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29310b57cec5SDimitry Andricbool
29320b57cec5SDimitry Andricoperator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
29330b57cec5SDimitry Andric{
29340b57cec5SDimitry Andric    return static_cast<bool>(__x);
29350b57cec5SDimitry Andric}
29360b57cec5SDimitry Andric
29370b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29380b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29390b57cec5SDimitry Andricbool
29400b57cec5SDimitry Andricoperator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
29410b57cec5SDimitry Andric{
29420b57cec5SDimitry Andric    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
29430b57cec5SDimitry Andric    return less<_P1>()(__x.get(), nullptr);
29440b57cec5SDimitry Andric}
29450b57cec5SDimitry Andric
29460b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29480b57cec5SDimitry Andricbool
29490b57cec5SDimitry Andricoperator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
29500b57cec5SDimitry Andric{
29510b57cec5SDimitry Andric    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
29520b57cec5SDimitry Andric    return less<_P1>()(nullptr, __x.get());
29530b57cec5SDimitry Andric}
29540b57cec5SDimitry Andric
29550b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29560b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29570b57cec5SDimitry Andricbool
29580b57cec5SDimitry Andricoperator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
29590b57cec5SDimitry Andric{
29600b57cec5SDimitry Andric    return nullptr < __x;
29610b57cec5SDimitry Andric}
29620b57cec5SDimitry Andric
29630b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29640b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29650b57cec5SDimitry Andricbool
29660b57cec5SDimitry Andricoperator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
29670b57cec5SDimitry Andric{
29680b57cec5SDimitry Andric    return __x < nullptr;
29690b57cec5SDimitry Andric}
29700b57cec5SDimitry Andric
29710b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29720b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29730b57cec5SDimitry Andricbool
29740b57cec5SDimitry Andricoperator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
29750b57cec5SDimitry Andric{
29760b57cec5SDimitry Andric    return !(nullptr < __x);
29770b57cec5SDimitry Andric}
29780b57cec5SDimitry Andric
29790b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29800b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29810b57cec5SDimitry Andricbool
29820b57cec5SDimitry Andricoperator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
29830b57cec5SDimitry Andric{
29840b57cec5SDimitry Andric    return !(__x < nullptr);
29850b57cec5SDimitry Andric}
29860b57cec5SDimitry Andric
29870b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29880b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29890b57cec5SDimitry Andricbool
29900b57cec5SDimitry Andricoperator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
29910b57cec5SDimitry Andric{
29920b57cec5SDimitry Andric    return !(__x < nullptr);
29930b57cec5SDimitry Andric}
29940b57cec5SDimitry Andric
29950b57cec5SDimitry Andrictemplate <class _T1, class _D1>
29960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
29970b57cec5SDimitry Andricbool
29980b57cec5SDimitry Andricoperator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
29990b57cec5SDimitry Andric{
30000b57cec5SDimitry Andric    return !(nullptr < __x);
30010b57cec5SDimitry Andric}
30020b57cec5SDimitry Andric
30030b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
30040b57cec5SDimitry Andric
30050b57cec5SDimitry Andrictemplate<class _Tp>
30060b57cec5SDimitry Andricstruct __unique_if
30070b57cec5SDimitry Andric{
30080b57cec5SDimitry Andric    typedef unique_ptr<_Tp> __unique_single;
30090b57cec5SDimitry Andric};
30100b57cec5SDimitry Andric
30110b57cec5SDimitry Andrictemplate<class _Tp>
30120b57cec5SDimitry Andricstruct __unique_if<_Tp[]>
30130b57cec5SDimitry Andric{
30140b57cec5SDimitry Andric    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
30150b57cec5SDimitry Andric};
30160b57cec5SDimitry Andric
30170b57cec5SDimitry Andrictemplate<class _Tp, size_t _Np>
30180b57cec5SDimitry Andricstruct __unique_if<_Tp[_Np]>
30190b57cec5SDimitry Andric{
30200b57cec5SDimitry Andric    typedef void __unique_array_known_bound;
30210b57cec5SDimitry Andric};
30220b57cec5SDimitry Andric
30230b57cec5SDimitry Andrictemplate<class _Tp, class... _Args>
30240b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
30250b57cec5SDimitry Andrictypename __unique_if<_Tp>::__unique_single
30260b57cec5SDimitry Andricmake_unique(_Args&&... __args)
30270b57cec5SDimitry Andric{
30280b57cec5SDimitry Andric    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
30290b57cec5SDimitry Andric}
30300b57cec5SDimitry Andric
30310b57cec5SDimitry Andrictemplate<class _Tp>
30320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
30330b57cec5SDimitry Andrictypename __unique_if<_Tp>::__unique_array_unknown_bound
30340b57cec5SDimitry Andricmake_unique(size_t __n)
30350b57cec5SDimitry Andric{
30360b57cec5SDimitry Andric    typedef typename remove_extent<_Tp>::type _Up;
30370b57cec5SDimitry Andric    return unique_ptr<_Tp>(new _Up[__n]());
30380b57cec5SDimitry Andric}
30390b57cec5SDimitry Andric
30400b57cec5SDimitry Andrictemplate<class _Tp, class... _Args>
30410b57cec5SDimitry Andric    typename __unique_if<_Tp>::__unique_array_known_bound
30420b57cec5SDimitry Andric    make_unique(_Args&&...) = delete;
30430b57cec5SDimitry Andric
30440b57cec5SDimitry Andric#endif  // _LIBCPP_STD_VER > 11
30450b57cec5SDimitry Andric
30460b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
30470b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
30480b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
30490b57cec5SDimitry Andric#else
30500b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
30510b57cec5SDimitry Andric    unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
30520b57cec5SDimitry Andric#endif
30530b57cec5SDimitry Andric{
30540b57cec5SDimitry Andric    typedef unique_ptr<_Tp, _Dp> argument_type;
30550b57cec5SDimitry Andric    typedef size_t               result_type;
30560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
30570b57cec5SDimitry Andric    result_type operator()(const argument_type& __ptr) const
30580b57cec5SDimitry Andric    {
30590b57cec5SDimitry Andric        typedef typename argument_type::pointer pointer;
30600b57cec5SDimitry Andric        return hash<pointer>()(__ptr.get());
30610b57cec5SDimitry Andric    }
30620b57cec5SDimitry Andric};
30630b57cec5SDimitry Andric
30640b57cec5SDimitry Andricstruct __destruct_n
30650b57cec5SDimitry Andric{
30660b57cec5SDimitry Andricprivate:
30670b57cec5SDimitry Andric    size_t __size_;
30680b57cec5SDimitry Andric
30690b57cec5SDimitry Andric    template <class _Tp>
30700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
30710b57cec5SDimitry Andric        {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
30720b57cec5SDimitry Andric
30730b57cec5SDimitry Andric    template <class _Tp>
30740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
30750b57cec5SDimitry Andric        {}
30760b57cec5SDimitry Andric
30770b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
30780b57cec5SDimitry Andric        {++__size_;}
30790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
30800b57cec5SDimitry Andric        {}
30810b57cec5SDimitry Andric
30820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
30830b57cec5SDimitry Andric        {__size_ = __s;}
30840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
30850b57cec5SDimitry Andric        {}
30860b57cec5SDimitry Andricpublic:
30870b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
30880b57cec5SDimitry Andric        : __size_(__s) {}
30890b57cec5SDimitry Andric
30900b57cec5SDimitry Andric    template <class _Tp>
30910b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __incr(_Tp*) _NOEXCEPT
30920b57cec5SDimitry Andric        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
30930b57cec5SDimitry Andric
30940b57cec5SDimitry Andric    template <class _Tp>
30950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
30960b57cec5SDimitry Andric        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
30970b57cec5SDimitry Andric
30980b57cec5SDimitry Andric    template <class _Tp>
30990b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
31000b57cec5SDimitry Andric        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
31010b57cec5SDimitry Andric};
31020b57cec5SDimitry Andric
31030b57cec5SDimitry Andrictemplate <class _Alloc>
31040b57cec5SDimitry Andricclass __allocator_destructor
31050b57cec5SDimitry Andric{
31060b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits;
31070b57cec5SDimitry Andricpublic:
31080b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer;
31090b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type;
31100b57cec5SDimitry Andricprivate:
31110b57cec5SDimitry Andric    _Alloc& __alloc_;
31120b57cec5SDimitry Andric    size_type __s_;
31130b57cec5SDimitry Andricpublic:
31140b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
31150b57cec5SDimitry Andric             _NOEXCEPT
31160b57cec5SDimitry Andric        : __alloc_(__a), __s_(__s) {}
31170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31180b57cec5SDimitry Andric    void operator()(pointer __p) _NOEXCEPT
31190b57cec5SDimitry Andric        {__alloc_traits::deallocate(__alloc_, __p, __s_);}
31200b57cec5SDimitry Andric};
31210b57cec5SDimitry Andric
31220b57cec5SDimitry Andrictemplate <class _InputIterator, class _ForwardIterator>
31230b57cec5SDimitry Andric_ForwardIterator
31240b57cec5SDimitry Andricuninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
31250b57cec5SDimitry Andric{
31260b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
31270b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
31280b57cec5SDimitry Andric    _ForwardIterator __s = __r;
31290b57cec5SDimitry Andric    try
31300b57cec5SDimitry Andric    {
31310b57cec5SDimitry Andric#endif
31320b57cec5SDimitry Andric        for (; __f != __l; ++__f, (void) ++__r)
31330b57cec5SDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
31340b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
31350b57cec5SDimitry Andric    }
31360b57cec5SDimitry Andric    catch (...)
31370b57cec5SDimitry Andric    {
31380b57cec5SDimitry Andric        for (; __s != __r; ++__s)
31390b57cec5SDimitry Andric            __s->~value_type();
31400b57cec5SDimitry Andric        throw;
31410b57cec5SDimitry Andric    }
31420b57cec5SDimitry Andric#endif
31430b57cec5SDimitry Andric    return __r;
31440b57cec5SDimitry Andric}
31450b57cec5SDimitry Andric
31460b57cec5SDimitry Andrictemplate <class _InputIterator, class _Size, class _ForwardIterator>
31470b57cec5SDimitry Andric_ForwardIterator
31480b57cec5SDimitry Andricuninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
31490b57cec5SDimitry Andric{
31500b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
31510b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
31520b57cec5SDimitry Andric    _ForwardIterator __s = __r;
31530b57cec5SDimitry Andric    try
31540b57cec5SDimitry Andric    {
31550b57cec5SDimitry Andric#endif
31560b57cec5SDimitry Andric        for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
31570b57cec5SDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__r))) value_type(*__f);
31580b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
31590b57cec5SDimitry Andric    }
31600b57cec5SDimitry Andric    catch (...)
31610b57cec5SDimitry Andric    {
31620b57cec5SDimitry Andric        for (; __s != __r; ++__s)
31630b57cec5SDimitry Andric            __s->~value_type();
31640b57cec5SDimitry Andric        throw;
31650b57cec5SDimitry Andric    }
31660b57cec5SDimitry Andric#endif
31670b57cec5SDimitry Andric    return __r;
31680b57cec5SDimitry Andric}
31690b57cec5SDimitry Andric
31700b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp>
31710b57cec5SDimitry Andricvoid
31720b57cec5SDimitry Andricuninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
31730b57cec5SDimitry Andric{
31740b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
31750b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
31760b57cec5SDimitry Andric    _ForwardIterator __s = __f;
31770b57cec5SDimitry Andric    try
31780b57cec5SDimitry Andric    {
31790b57cec5SDimitry Andric#endif
31800b57cec5SDimitry Andric        for (; __f != __l; ++__f)
31810b57cec5SDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
31820b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
31830b57cec5SDimitry Andric    }
31840b57cec5SDimitry Andric    catch (...)
31850b57cec5SDimitry Andric    {
31860b57cec5SDimitry Andric        for (; __s != __f; ++__s)
31870b57cec5SDimitry Andric            __s->~value_type();
31880b57cec5SDimitry Andric        throw;
31890b57cec5SDimitry Andric    }
31900b57cec5SDimitry Andric#endif
31910b57cec5SDimitry Andric}
31920b57cec5SDimitry Andric
31930b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size, class _Tp>
31940b57cec5SDimitry Andric_ForwardIterator
31950b57cec5SDimitry Andricuninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
31960b57cec5SDimitry Andric{
31970b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
31980b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
31990b57cec5SDimitry Andric    _ForwardIterator __s = __f;
32000b57cec5SDimitry Andric    try
32010b57cec5SDimitry Andric    {
32020b57cec5SDimitry Andric#endif
32030b57cec5SDimitry Andric        for (; __n > 0; ++__f, (void) --__n)
32040b57cec5SDimitry Andric            ::new (static_cast<void*>(_VSTD::addressof(*__f))) value_type(__x);
32050b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
32060b57cec5SDimitry Andric    }
32070b57cec5SDimitry Andric    catch (...)
32080b57cec5SDimitry Andric    {
32090b57cec5SDimitry Andric        for (; __s != __f; ++__s)
32100b57cec5SDimitry Andric            __s->~value_type();
32110b57cec5SDimitry Andric        throw;
32120b57cec5SDimitry Andric    }
32130b57cec5SDimitry Andric#endif
32140b57cec5SDimitry Andric    return __f;
32150b57cec5SDimitry Andric}
32160b57cec5SDimitry Andric
32170b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
32180b57cec5SDimitry Andric
32190b57cec5SDimitry Andrictemplate <class _Tp>
32200b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32210b57cec5SDimitry Andricvoid destroy_at(_Tp* __loc) {
32220b57cec5SDimitry Andric    _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
32230b57cec5SDimitry Andric    __loc->~_Tp();
32240b57cec5SDimitry Andric}
32250b57cec5SDimitry Andric
32260b57cec5SDimitry Andrictemplate <class _ForwardIterator>
32270b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32280b57cec5SDimitry Andricvoid destroy(_ForwardIterator __first, _ForwardIterator __last) {
32290b57cec5SDimitry Andric    for (; __first != __last; ++__first)
32300b57cec5SDimitry Andric        _VSTD::destroy_at(_VSTD::addressof(*__first));
32310b57cec5SDimitry Andric}
32320b57cec5SDimitry Andric
32330b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size>
32340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32350b57cec5SDimitry Andric_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
32360b57cec5SDimitry Andric    for (; __n > 0; (void)++__first, --__n)
32370b57cec5SDimitry Andric        _VSTD::destroy_at(_VSTD::addressof(*__first));
32380b57cec5SDimitry Andric    return __first;
32390b57cec5SDimitry Andric}
32400b57cec5SDimitry Andric
32410b57cec5SDimitry Andrictemplate <class _ForwardIterator>
32420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32430b57cec5SDimitry Andricvoid uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
32440b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
32450b57cec5SDimitry Andric    auto __idx = __first;
32460b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
32470b57cec5SDimitry Andric    try {
32480b57cec5SDimitry Andric#endif
32490b57cec5SDimitry Andric    for (; __idx != __last; ++__idx)
32500b57cec5SDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt;
32510b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
32520b57cec5SDimitry Andric    } catch (...) {
32530b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
32540b57cec5SDimitry Andric        throw;
32550b57cec5SDimitry Andric    }
32560b57cec5SDimitry Andric#endif
32570b57cec5SDimitry Andric}
32580b57cec5SDimitry Andric
32590b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size>
32600b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32610b57cec5SDimitry Andric_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
32620b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
32630b57cec5SDimitry Andric    auto __idx = __first;
32640b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
32650b57cec5SDimitry Andric    try {
32660b57cec5SDimitry Andric#endif
32670b57cec5SDimitry Andric    for (; __n > 0; (void)++__idx, --__n)
32680b57cec5SDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt;
32690b57cec5SDimitry Andric    return __idx;
32700b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
32710b57cec5SDimitry Andric    } catch (...) {
32720b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
32730b57cec5SDimitry Andric        throw;
32740b57cec5SDimitry Andric    }
32750b57cec5SDimitry Andric#endif
32760b57cec5SDimitry Andric}
32770b57cec5SDimitry Andric
32780b57cec5SDimitry Andric
32790b57cec5SDimitry Andrictemplate <class _ForwardIterator>
32800b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32810b57cec5SDimitry Andricvoid uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
32820b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
32830b57cec5SDimitry Andric    auto __idx = __first;
32840b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
32850b57cec5SDimitry Andric    try {
32860b57cec5SDimitry Andric#endif
32870b57cec5SDimitry Andric    for (; __idx != __last; ++__idx)
32880b57cec5SDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt();
32890b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
32900b57cec5SDimitry Andric    } catch (...) {
32910b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
32920b57cec5SDimitry Andric        throw;
32930b57cec5SDimitry Andric    }
32940b57cec5SDimitry Andric#endif
32950b57cec5SDimitry Andric}
32960b57cec5SDimitry Andric
32970b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size>
32980b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32990b57cec5SDimitry Andric_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
33000b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
33010b57cec5SDimitry Andric    auto __idx = __first;
33020b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
33030b57cec5SDimitry Andric    try {
33040b57cec5SDimitry Andric#endif
33050b57cec5SDimitry Andric    for (; __n > 0; (void)++__idx, --__n)
33060b57cec5SDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt();
33070b57cec5SDimitry Andric    return __idx;
33080b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
33090b57cec5SDimitry Andric    } catch (...) {
33100b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
33110b57cec5SDimitry Andric        throw;
33120b57cec5SDimitry Andric    }
33130b57cec5SDimitry Andric#endif
33140b57cec5SDimitry Andric}
33150b57cec5SDimitry Andric
33160b57cec5SDimitry Andric
33170b57cec5SDimitry Andrictemplate <class _InputIt, class _ForwardIt>
33180b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
33190b57cec5SDimitry Andric_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
33200b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
33210b57cec5SDimitry Andric    auto __idx = __first_res;
33220b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
33230b57cec5SDimitry Andric    try {
33240b57cec5SDimitry Andric#endif
33250b57cec5SDimitry Andric    for (; __first != __last; (void)++__idx, ++__first)
33260b57cec5SDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first));
33270b57cec5SDimitry Andric    return __idx;
33280b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
33290b57cec5SDimitry Andric    } catch (...) {
33300b57cec5SDimitry Andric        _VSTD::destroy(__first_res, __idx);
33310b57cec5SDimitry Andric        throw;
33320b57cec5SDimitry Andric    }
33330b57cec5SDimitry Andric#endif
33340b57cec5SDimitry Andric}
33350b57cec5SDimitry Andric
33360b57cec5SDimitry Andrictemplate <class _InputIt, class _Size, class _ForwardIt>
33370b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
33380b57cec5SDimitry Andricpair<_InputIt, _ForwardIt>
33390b57cec5SDimitry Andricuninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
33400b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
33410b57cec5SDimitry Andric    auto __idx = __first_res;
33420b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
33430b57cec5SDimitry Andric    try {
33440b57cec5SDimitry Andric#endif
33450b57cec5SDimitry Andric    for (; __n > 0; ++__idx, (void)++__first, --__n)
33460b57cec5SDimitry Andric        ::new((void*)_VSTD::addressof(*__idx)) _Vt(std::move(*__first));
33470b57cec5SDimitry Andric    return {__first, __idx};
33480b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
33490b57cec5SDimitry Andric    } catch (...) {
33500b57cec5SDimitry Andric        _VSTD::destroy(__first_res, __idx);
33510b57cec5SDimitry Andric        throw;
33520b57cec5SDimitry Andric    }
33530b57cec5SDimitry Andric#endif
33540b57cec5SDimitry Andric}
33550b57cec5SDimitry Andric
33560b57cec5SDimitry Andric
33570b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
33580b57cec5SDimitry Andric
33590b57cec5SDimitry Andric// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
33600b57cec5SDimitry Andric// should be sufficient for thread safety.
33610b57cec5SDimitry Andric// See https://bugs.llvm.org/show_bug.cgi?id=22803
33620b57cec5SDimitry Andric#if defined(__clang__) && __has_builtin(__atomic_add_fetch)          \
33630b57cec5SDimitry Andric                       && defined(__ATOMIC_RELAXED)                  \
33640b57cec5SDimitry Andric                       && defined(__ATOMIC_ACQ_REL)
33650b57cec5SDimitry Andric#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
33660b57cec5SDimitry Andric#elif defined(_LIBCPP_COMPILER_GCC)
33670b57cec5SDimitry Andric#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
33680b57cec5SDimitry Andric#endif
33690b57cec5SDimitry Andric
33700b57cec5SDimitry Andrictemplate <class _Tp>
33710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _Tp
33720b57cec5SDimitry Andric__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
33730b57cec5SDimitry Andric{
33740b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
33750b57cec5SDimitry Andric    return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
33760b57cec5SDimitry Andric#else
33770b57cec5SDimitry Andric    return __t += 1;
33780b57cec5SDimitry Andric#endif
33790b57cec5SDimitry Andric}
33800b57cec5SDimitry Andric
33810b57cec5SDimitry Andrictemplate <class _Tp>
33820b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _Tp
33830b57cec5SDimitry Andric__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
33840b57cec5SDimitry Andric{
33850b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
33860b57cec5SDimitry Andric    return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
33870b57cec5SDimitry Andric#else
33880b57cec5SDimitry Andric    return __t -= 1;
33890b57cec5SDimitry Andric#endif
33900b57cec5SDimitry Andric}
33910b57cec5SDimitry Andric
33920b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI bad_weak_ptr
33930b57cec5SDimitry Andric    : public std::exception
33940b57cec5SDimitry Andric{
33950b57cec5SDimitry Andricpublic:
3396*9ec406dcSDimitry Andric    bad_weak_ptr() _NOEXCEPT = default;
3397*9ec406dcSDimitry Andric    bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
33980b57cec5SDimitry Andric    virtual ~bad_weak_ptr() _NOEXCEPT;
33990b57cec5SDimitry Andric    virtual const char* what() const  _NOEXCEPT;
34000b57cec5SDimitry Andric};
34010b57cec5SDimitry Andric
34020b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
34030b57cec5SDimitry Andricvoid __throw_bad_weak_ptr()
34040b57cec5SDimitry Andric{
34050b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
34060b57cec5SDimitry Andric    throw bad_weak_ptr();
34070b57cec5SDimitry Andric#else
34080b57cec5SDimitry Andric    _VSTD::abort();
34090b57cec5SDimitry Andric#endif
34100b57cec5SDimitry Andric}
34110b57cec5SDimitry Andric
34120b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
34130b57cec5SDimitry Andric
34140b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __shared_count
34150b57cec5SDimitry Andric{
34160b57cec5SDimitry Andric    __shared_count(const __shared_count&);
34170b57cec5SDimitry Andric    __shared_count& operator=(const __shared_count&);
34180b57cec5SDimitry Andric
34190b57cec5SDimitry Andricprotected:
34200b57cec5SDimitry Andric    long __shared_owners_;
34210b57cec5SDimitry Andric    virtual ~__shared_count();
34220b57cec5SDimitry Andricprivate:
34230b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT = 0;
34240b57cec5SDimitry Andric
34250b57cec5SDimitry Andricpublic:
34260b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34270b57cec5SDimitry Andric    explicit __shared_count(long __refs = 0) _NOEXCEPT
34280b57cec5SDimitry Andric        : __shared_owners_(__refs) {}
34290b57cec5SDimitry Andric
34300b57cec5SDimitry Andric#if defined(_LIBCPP_BUILDING_LIBRARY) && \
34310b57cec5SDimitry Andric    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
34320b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT;
34330b57cec5SDimitry Andric    bool __release_shared() _NOEXCEPT;
34340b57cec5SDimitry Andric#else
34350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34360b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT {
34370b57cec5SDimitry Andric      __libcpp_atomic_refcount_increment(__shared_owners_);
34380b57cec5SDimitry Andric    }
34390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34400b57cec5SDimitry Andric    bool __release_shared() _NOEXCEPT {
34410b57cec5SDimitry Andric      if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
34420b57cec5SDimitry Andric        __on_zero_shared();
34430b57cec5SDimitry Andric        return true;
34440b57cec5SDimitry Andric      }
34450b57cec5SDimitry Andric      return false;
34460b57cec5SDimitry Andric    }
34470b57cec5SDimitry Andric#endif
34480b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34490b57cec5SDimitry Andric    long use_count() const _NOEXCEPT {
34500b57cec5SDimitry Andric        return __libcpp_relaxed_load(&__shared_owners_) + 1;
34510b57cec5SDimitry Andric    }
34520b57cec5SDimitry Andric};
34530b57cec5SDimitry Andric
34540b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __shared_weak_count
34550b57cec5SDimitry Andric    : private __shared_count
34560b57cec5SDimitry Andric{
34570b57cec5SDimitry Andric    long __shared_weak_owners_;
34580b57cec5SDimitry Andric
34590b57cec5SDimitry Andricpublic:
34600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34610b57cec5SDimitry Andric    explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
34620b57cec5SDimitry Andric        : __shared_count(__refs),
34630b57cec5SDimitry Andric          __shared_weak_owners_(__refs) {}
34640b57cec5SDimitry Andricprotected:
34650b57cec5SDimitry Andric    virtual ~__shared_weak_count();
34660b57cec5SDimitry Andric
34670b57cec5SDimitry Andricpublic:
34680b57cec5SDimitry Andric#if defined(_LIBCPP_BUILDING_LIBRARY) && \
34690b57cec5SDimitry Andric    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
34700b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT;
34710b57cec5SDimitry Andric    void __add_weak() _NOEXCEPT;
34720b57cec5SDimitry Andric    void __release_shared() _NOEXCEPT;
34730b57cec5SDimitry Andric#else
34740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34750b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT {
34760b57cec5SDimitry Andric      __shared_count::__add_shared();
34770b57cec5SDimitry Andric    }
34780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34790b57cec5SDimitry Andric    void __add_weak() _NOEXCEPT {
34800b57cec5SDimitry Andric      __libcpp_atomic_refcount_increment(__shared_weak_owners_);
34810b57cec5SDimitry Andric    }
34820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34830b57cec5SDimitry Andric    void __release_shared() _NOEXCEPT {
34840b57cec5SDimitry Andric      if (__shared_count::__release_shared())
34850b57cec5SDimitry Andric        __release_weak();
34860b57cec5SDimitry Andric    }
34870b57cec5SDimitry Andric#endif
34880b57cec5SDimitry Andric    void __release_weak() _NOEXCEPT;
34890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34900b57cec5SDimitry Andric    long use_count() const _NOEXCEPT {return __shared_count::use_count();}
34910b57cec5SDimitry Andric    __shared_weak_count* lock() _NOEXCEPT;
34920b57cec5SDimitry Andric
34930b57cec5SDimitry Andric    // Define the function out only if we build static libc++ without RTTI.
34940b57cec5SDimitry Andric    // Otherwise we may break clients who need to compile their projects with
34950b57cec5SDimitry Andric    // -fno-rtti and yet link against a libc++.dylib compiled
34960b57cec5SDimitry Andric    // without -fno-rtti.
34970b57cec5SDimitry Andric#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
34980b57cec5SDimitry Andric    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
34990b57cec5SDimitry Andric#endif
35000b57cec5SDimitry Andricprivate:
35010b57cec5SDimitry Andric    virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
35020b57cec5SDimitry Andric};
35030b57cec5SDimitry Andric
35040b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
35050b57cec5SDimitry Andricclass __shared_ptr_pointer
35060b57cec5SDimitry Andric    : public __shared_weak_count
35070b57cec5SDimitry Andric{
35080b57cec5SDimitry Andric    __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
35090b57cec5SDimitry Andricpublic:
35100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
35110b57cec5SDimitry Andric    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
35120b57cec5SDimitry Andric        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
35130b57cec5SDimitry Andric
35140b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
35150b57cec5SDimitry Andric    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
35160b57cec5SDimitry Andric#endif
35170b57cec5SDimitry Andric
35180b57cec5SDimitry Andricprivate:
35190b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
35200b57cec5SDimitry Andric    virtual void __on_zero_shared_weak() _NOEXCEPT;
35210b57cec5SDimitry Andric};
35220b57cec5SDimitry Andric
35230b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
35240b57cec5SDimitry Andric
35250b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
35260b57cec5SDimitry Andricconst void*
35270b57cec5SDimitry Andric__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
35280b57cec5SDimitry Andric{
35290b57cec5SDimitry Andric    return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
35300b57cec5SDimitry Andric}
35310b57cec5SDimitry Andric
35320b57cec5SDimitry Andric#endif  // _LIBCPP_NO_RTTI
35330b57cec5SDimitry Andric
35340b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
35350b57cec5SDimitry Andricvoid
35360b57cec5SDimitry Andric__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
35370b57cec5SDimitry Andric{
35380b57cec5SDimitry Andric    __data_.first().second()(__data_.first().first());
35390b57cec5SDimitry Andric    __data_.first().second().~_Dp();
35400b57cec5SDimitry Andric}
35410b57cec5SDimitry Andric
35420b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
35430b57cec5SDimitry Andricvoid
35440b57cec5SDimitry Andric__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
35450b57cec5SDimitry Andric{
35460b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
35470b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
35480b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
35490b57cec5SDimitry Andric
35500b57cec5SDimitry Andric    _Al __a(__data_.second());
35510b57cec5SDimitry Andric    __data_.second().~_Alloc();
35520b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
35530b57cec5SDimitry Andric}
35540b57cec5SDimitry Andric
35550b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
35560b57cec5SDimitry Andricclass __shared_ptr_emplace
35570b57cec5SDimitry Andric    : public __shared_weak_count
35580b57cec5SDimitry Andric{
35590b57cec5SDimitry Andric    __compressed_pair<_Alloc, _Tp> __data_;
35600b57cec5SDimitry Andricpublic:
35610b57cec5SDimitry Andric
35620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
35630b57cec5SDimitry Andric    __shared_ptr_emplace(_Alloc __a)
3564480093f4SDimitry Andric        :  __data_(_VSTD::move(__a), __value_init_tag()) {}
35650b57cec5SDimitry Andric
3566480093f4SDimitry Andric
3567480093f4SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
35680b57cec5SDimitry Andric    template <class ..._Args>
35690b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
35700b57cec5SDimitry Andric        __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
35710b57cec5SDimitry Andric            :  __data_(piecewise_construct, _VSTD::forward_as_tuple(__a),
35720b57cec5SDimitry Andric                   _VSTD::forward_as_tuple(_VSTD::forward<_Args>(__args)...)) {}
35730b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_VARIADICS
35740b57cec5SDimitry Andric
35750b57cec5SDimitry Andric    template <class _A0>
35760b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
35770b57cec5SDimitry Andric        __shared_ptr_emplace(_Alloc __a, _A0& __a0)
35780b57cec5SDimitry Andric            :  __data_(__a, _Tp(__a0)) {}
35790b57cec5SDimitry Andric
35800b57cec5SDimitry Andric    template <class _A0, class _A1>
35810b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
35820b57cec5SDimitry Andric        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1)
35830b57cec5SDimitry Andric            :  __data_(__a, _Tp(__a0, __a1)) {}
35840b57cec5SDimitry Andric
35850b57cec5SDimitry Andric    template <class _A0, class _A1, class _A2>
35860b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
35870b57cec5SDimitry Andric        __shared_ptr_emplace(_Alloc __a, _A0& __a0, _A1& __a1, _A2& __a2)
35880b57cec5SDimitry Andric            :  __data_(__a, _Tp(__a0, __a1, __a2)) {}
35890b57cec5SDimitry Andric
35900b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_VARIADICS
35910b57cec5SDimitry Andric
35920b57cec5SDimitry Andricprivate:
35930b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
35940b57cec5SDimitry Andric    virtual void __on_zero_shared_weak() _NOEXCEPT;
35950b57cec5SDimitry Andricpublic:
35960b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
35970b57cec5SDimitry Andric    _Tp* get() _NOEXCEPT {return _VSTD::addressof(__data_.second());}
35980b57cec5SDimitry Andric};
35990b57cec5SDimitry Andric
36000b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
36010b57cec5SDimitry Andricvoid
36020b57cec5SDimitry Andric__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared() _NOEXCEPT
36030b57cec5SDimitry Andric{
36040b57cec5SDimitry Andric    __data_.second().~_Tp();
36050b57cec5SDimitry Andric}
36060b57cec5SDimitry Andric
36070b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
36080b57cec5SDimitry Andricvoid
36090b57cec5SDimitry Andric__shared_ptr_emplace<_Tp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
36100b57cec5SDimitry Andric{
36110b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type _Al;
36120b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
36130b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
36140b57cec5SDimitry Andric    _Al __a(__data_.first());
36150b57cec5SDimitry Andric    __data_.first().~_Alloc();
36160b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
36170b57cec5SDimitry Andric}
36180b57cec5SDimitry Andric
36190b57cec5SDimitry Andricstruct __shared_ptr_dummy_rebind_allocator_type;
36200b57cec5SDimitry Andrictemplate <>
36210b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
36220b57cec5SDimitry Andric{
36230b57cec5SDimitry Andricpublic:
36240b57cec5SDimitry Andric    template <class _Other>
36250b57cec5SDimitry Andric    struct rebind
36260b57cec5SDimitry Andric    {
36270b57cec5SDimitry Andric        typedef allocator<_Other> other;
36280b57cec5SDimitry Andric    };
36290b57cec5SDimitry Andric};
36300b57cec5SDimitry Andric
36310b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
36320b57cec5SDimitry Andric
36330b57cec5SDimitry Andrictemplate<class _Tp>
36340b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shared_ptr
36350b57cec5SDimitry Andric{
36360b57cec5SDimitry Andricpublic:
36370b57cec5SDimitry Andric    typedef _Tp element_type;
36380b57cec5SDimitry Andric
36390b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
36400b57cec5SDimitry Andric    typedef weak_ptr<_Tp> weak_type;
36410b57cec5SDimitry Andric#endif
36420b57cec5SDimitry Andricprivate:
36430b57cec5SDimitry Andric    element_type*      __ptr_;
36440b57cec5SDimitry Andric    __shared_weak_count* __cntrl_;
36450b57cec5SDimitry Andric
36460b57cec5SDimitry Andric    struct __nat {int __for_bool_;};
36470b57cec5SDimitry Andricpublic:
36480b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36490b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
36500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36510b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
36520b57cec5SDimitry Andric    template<class _Yp>
36530b57cec5SDimitry Andric        explicit shared_ptr(_Yp* __p,
36540b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
36550b57cec5SDimitry Andric    template<class _Yp, class _Dp>
36560b57cec5SDimitry Andric        shared_ptr(_Yp* __p, _Dp __d,
36570b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
36580b57cec5SDimitry Andric    template<class _Yp, class _Dp, class _Alloc>
36590b57cec5SDimitry Andric        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
36600b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
36610b57cec5SDimitry Andric    template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
36620b57cec5SDimitry Andric    template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
36630b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
36640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36650b57cec5SDimitry Andric    shared_ptr(const shared_ptr& __r) _NOEXCEPT;
36660b57cec5SDimitry Andric    template<class _Yp>
36670b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36680b57cec5SDimitry Andric        shared_ptr(const shared_ptr<_Yp>& __r,
36690b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat())
36700b57cec5SDimitry Andric                       _NOEXCEPT;
36710b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
36720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36730b57cec5SDimitry Andric    shared_ptr(shared_ptr&& __r) _NOEXCEPT;
36740b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r,
36750b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat())
36760b57cec5SDimitry Andric                       _NOEXCEPT;
36770b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
36780b57cec5SDimitry Andric    template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
36790b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
36800b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
36810b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
36820b57cec5SDimitry Andric    template<class _Yp>
36830b57cec5SDimitry Andric        shared_ptr(auto_ptr<_Yp>&& __r,
36840b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
36850b57cec5SDimitry Andric#else
36860b57cec5SDimitry Andric    template<class _Yp>
36870b57cec5SDimitry Andric        shared_ptr(auto_ptr<_Yp> __r,
36880b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
36890b57cec5SDimitry Andric#endif
36900b57cec5SDimitry Andric#endif
36910b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
36920b57cec5SDimitry Andric    template <class _Yp, class _Dp>
36930b57cec5SDimitry Andric        shared_ptr(unique_ptr<_Yp, _Dp>&&,
36940b57cec5SDimitry Andric                   typename enable_if
36950b57cec5SDimitry Andric                   <
36960b57cec5SDimitry Andric                       !is_lvalue_reference<_Dp>::value &&
36970b57cec5SDimitry Andric                       !is_array<_Yp>::value &&
36980b57cec5SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
36990b57cec5SDimitry Andric                       __nat
37000b57cec5SDimitry Andric                   >::type = __nat());
37010b57cec5SDimitry Andric    template <class _Yp, class _Dp>
37020b57cec5SDimitry Andric        shared_ptr(unique_ptr<_Yp, _Dp>&&,
37030b57cec5SDimitry Andric                   typename enable_if
37040b57cec5SDimitry Andric                   <
37050b57cec5SDimitry Andric                       is_lvalue_reference<_Dp>::value &&
37060b57cec5SDimitry Andric                       !is_array<_Yp>::value &&
37070b57cec5SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
37080b57cec5SDimitry Andric                       __nat
37090b57cec5SDimitry Andric                   >::type = __nat());
37100b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
37110b57cec5SDimitry Andric    template <class _Yp, class _Dp>
37120b57cec5SDimitry Andric        shared_ptr(unique_ptr<_Yp, _Dp>,
37130b57cec5SDimitry Andric                   typename enable_if
37140b57cec5SDimitry Andric                   <
37150b57cec5SDimitry Andric                       !is_lvalue_reference<_Dp>::value &&
37160b57cec5SDimitry Andric                       !is_array<_Yp>::value &&
37170b57cec5SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
37180b57cec5SDimitry Andric                       __nat
37190b57cec5SDimitry Andric                   >::type = __nat());
37200b57cec5SDimitry Andric    template <class _Yp, class _Dp>
37210b57cec5SDimitry Andric        shared_ptr(unique_ptr<_Yp, _Dp>,
37220b57cec5SDimitry Andric                   typename enable_if
37230b57cec5SDimitry Andric                   <
37240b57cec5SDimitry Andric                       is_lvalue_reference<_Dp>::value &&
37250b57cec5SDimitry Andric                       !is_array<_Yp>::value &&
37260b57cec5SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
37270b57cec5SDimitry Andric                       __nat
37280b57cec5SDimitry Andric                   >::type = __nat());
37290b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
37300b57cec5SDimitry Andric
37310b57cec5SDimitry Andric    ~shared_ptr();
37320b57cec5SDimitry Andric
37330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
37340b57cec5SDimitry Andric    shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
37350b57cec5SDimitry Andric    template<class _Yp>
37360b57cec5SDimitry Andric        typename enable_if
37370b57cec5SDimitry Andric        <
37380b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
37390b57cec5SDimitry Andric            shared_ptr&
37400b57cec5SDimitry Andric        >::type
37410b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
37420b57cec5SDimitry Andric        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
37430b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
37440b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
37450b57cec5SDimitry Andric    shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
37460b57cec5SDimitry Andric    template<class _Yp>
37470b57cec5SDimitry Andric        typename enable_if
37480b57cec5SDimitry Andric        <
37490b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
37500b57cec5SDimitry Andric            shared_ptr<_Tp>&
37510b57cec5SDimitry Andric        >::type
37520b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
37530b57cec5SDimitry Andric        operator=(shared_ptr<_Yp>&& __r);
37540b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
37550b57cec5SDimitry Andric    template<class _Yp>
37560b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
37570b57cec5SDimitry Andric        typename enable_if
37580b57cec5SDimitry Andric        <
37590b57cec5SDimitry Andric            !is_array<_Yp>::value &&
37600b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
37610b57cec5SDimitry Andric            shared_ptr
37620b57cec5SDimitry Andric        >::type&
37630b57cec5SDimitry Andric        operator=(auto_ptr<_Yp>&& __r);
37640b57cec5SDimitry Andric#endif
37650b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
37660b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
37670b57cec5SDimitry Andric    template<class _Yp>
37680b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
37690b57cec5SDimitry Andric        typename enable_if
37700b57cec5SDimitry Andric        <
37710b57cec5SDimitry Andric            !is_array<_Yp>::value &&
37720b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
37730b57cec5SDimitry Andric            shared_ptr&
37740b57cec5SDimitry Andric        >::type
37750b57cec5SDimitry Andric        operator=(auto_ptr<_Yp> __r);
37760b57cec5SDimitry Andric#endif
37770b57cec5SDimitry Andric#endif
37780b57cec5SDimitry Andric    template <class _Yp, class _Dp>
37790b57cec5SDimitry Andric        typename enable_if
37800b57cec5SDimitry Andric        <
37810b57cec5SDimitry Andric            !is_array<_Yp>::value &&
37820b57cec5SDimitry Andric            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
37830b57cec5SDimitry Andric            shared_ptr&
37840b57cec5SDimitry Andric        >::type
37850b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
37860b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
37870b57cec5SDimitry Andric        operator=(unique_ptr<_Yp, _Dp>&& __r);
37880b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
37890b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
37900b57cec5SDimitry Andric        operator=(unique_ptr<_Yp, _Dp> __r);
37910b57cec5SDimitry Andric#endif
37920b57cec5SDimitry Andric
37930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
37940b57cec5SDimitry Andric    void swap(shared_ptr& __r) _NOEXCEPT;
37950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
37960b57cec5SDimitry Andric    void reset() _NOEXCEPT;
37970b57cec5SDimitry Andric    template<class _Yp>
37980b57cec5SDimitry Andric        typename enable_if
37990b57cec5SDimitry Andric        <
38000b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
38010b57cec5SDimitry Andric            void
38020b57cec5SDimitry Andric        >::type
38030b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38040b57cec5SDimitry Andric        reset(_Yp* __p);
38050b57cec5SDimitry Andric    template<class _Yp, class _Dp>
38060b57cec5SDimitry Andric        typename enable_if
38070b57cec5SDimitry Andric        <
38080b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
38090b57cec5SDimitry Andric            void
38100b57cec5SDimitry Andric        >::type
38110b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38120b57cec5SDimitry Andric        reset(_Yp* __p, _Dp __d);
38130b57cec5SDimitry Andric    template<class _Yp, class _Dp, class _Alloc>
38140b57cec5SDimitry Andric        typename enable_if
38150b57cec5SDimitry Andric        <
38160b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
38170b57cec5SDimitry Andric            void
38180b57cec5SDimitry Andric        >::type
38190b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38200b57cec5SDimitry Andric        reset(_Yp* __p, _Dp __d, _Alloc __a);
38210b57cec5SDimitry Andric
38220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38230b57cec5SDimitry Andric    element_type* get() const _NOEXCEPT {return __ptr_;}
38240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38250b57cec5SDimitry Andric    typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
38260b57cec5SDimitry Andric        {return *__ptr_;}
38270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38280b57cec5SDimitry Andric    element_type* operator->() const _NOEXCEPT {return __ptr_;}
38290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38300b57cec5SDimitry Andric    long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
38310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38320b57cec5SDimitry Andric    bool unique() const _NOEXCEPT {return use_count() == 1;}
38330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38340b57cec5SDimitry Andric    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != 0;}
38350b57cec5SDimitry Andric    template <class _Up>
38360b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38370b57cec5SDimitry Andric        bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
38380b57cec5SDimitry Andric        {return __cntrl_ < __p.__cntrl_;}
38390b57cec5SDimitry Andric    template <class _Up>
38400b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38410b57cec5SDimitry Andric        bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
38420b57cec5SDimitry Andric        {return __cntrl_ < __p.__cntrl_;}
38430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38440b57cec5SDimitry Andric    bool
38450b57cec5SDimitry Andric    __owner_equivalent(const shared_ptr& __p) const
38460b57cec5SDimitry Andric        {return __cntrl_ == __p.__cntrl_;}
38470b57cec5SDimitry Andric
38480b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
38490b57cec5SDimitry Andric    template <class _Dp>
38500b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38510b57cec5SDimitry Andric        _Dp* __get_deleter() const _NOEXCEPT
38520b57cec5SDimitry Andric            {return static_cast<_Dp*>(__cntrl_
38530b57cec5SDimitry Andric                    ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
38540b57cec5SDimitry Andric                      : nullptr);}
38550b57cec5SDimitry Andric#endif  // _LIBCPP_NO_RTTI
38560b57cec5SDimitry Andric
3857e40139ffSDimitry Andric    template<class _Yp, class _CntrlBlk>
3858e40139ffSDimitry Andric    static shared_ptr<_Tp>
3859e40139ffSDimitry Andric    __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl)
3860e40139ffSDimitry Andric    {
3861e40139ffSDimitry Andric        shared_ptr<_Tp> __r;
3862e40139ffSDimitry Andric        __r.__ptr_ = __p;
3863e40139ffSDimitry Andric        __r.__cntrl_ = __cntrl;
3864e40139ffSDimitry Andric        __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
3865e40139ffSDimitry Andric        return __r;
3866e40139ffSDimitry Andric    }
38670b57cec5SDimitry Andric
38680b57cec5SDimitry Andric    template<class _Alloc, class ..._Args>
38690b57cec5SDimitry Andric        static
38700b57cec5SDimitry Andric        shared_ptr<_Tp>
38710b57cec5SDimitry Andric        allocate_shared(const _Alloc& __a, _Args&& ...__args);
38720b57cec5SDimitry Andric
38730b57cec5SDimitry Andricprivate:
38740b57cec5SDimitry Andric    template <class _Yp, bool = is_function<_Yp>::value>
38750b57cec5SDimitry Andric        struct __shared_ptr_default_allocator
38760b57cec5SDimitry Andric        {
38770b57cec5SDimitry Andric            typedef allocator<_Yp> type;
38780b57cec5SDimitry Andric        };
38790b57cec5SDimitry Andric
38800b57cec5SDimitry Andric    template <class _Yp>
38810b57cec5SDimitry Andric        struct __shared_ptr_default_allocator<_Yp, true>
38820b57cec5SDimitry Andric        {
38830b57cec5SDimitry Andric            typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
38840b57cec5SDimitry Andric        };
38850b57cec5SDimitry Andric
38860b57cec5SDimitry Andric    template <class _Yp, class _OrigPtr>
38870b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38880b57cec5SDimitry Andric        typename enable_if<is_convertible<_OrigPtr*,
38890b57cec5SDimitry Andric                                          const enable_shared_from_this<_Yp>*
38900b57cec5SDimitry Andric        >::value,
38910b57cec5SDimitry Andric            void>::type
38920b57cec5SDimitry Andric        __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
38930b57cec5SDimitry Andric                           _OrigPtr* __ptr) _NOEXCEPT
38940b57cec5SDimitry Andric        {
38950b57cec5SDimitry Andric            typedef typename remove_cv<_Yp>::type _RawYp;
38960b57cec5SDimitry Andric            if (__e && __e->__weak_this_.expired())
38970b57cec5SDimitry Andric            {
38980b57cec5SDimitry Andric                __e->__weak_this_ = shared_ptr<_RawYp>(*this,
38990b57cec5SDimitry Andric                    const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
39000b57cec5SDimitry Andric            }
39010b57cec5SDimitry Andric        }
39020b57cec5SDimitry Andric
39030b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
39040b57cec5SDimitry Andric
39050b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
39060b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
39070b57cec5SDimitry Andric};
39080b57cec5SDimitry Andric
39090b57cec5SDimitry Andric
39100b57cec5SDimitry Andrictemplate<class _Tp>
39110b57cec5SDimitry Andricinline
39120b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
39130b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr() _NOEXCEPT
39140b57cec5SDimitry Andric    : __ptr_(0),
39150b57cec5SDimitry Andric      __cntrl_(0)
39160b57cec5SDimitry Andric{
39170b57cec5SDimitry Andric}
39180b57cec5SDimitry Andric
39190b57cec5SDimitry Andrictemplate<class _Tp>
39200b57cec5SDimitry Andricinline
39210b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
39220b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
39230b57cec5SDimitry Andric    : __ptr_(0),
39240b57cec5SDimitry Andric      __cntrl_(0)
39250b57cec5SDimitry Andric{
39260b57cec5SDimitry Andric}
39270b57cec5SDimitry Andric
39280b57cec5SDimitry Andrictemplate<class _Tp>
39290b57cec5SDimitry Andrictemplate<class _Yp>
39300b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p,
39310b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
39320b57cec5SDimitry Andric    : __ptr_(__p)
39330b57cec5SDimitry Andric{
39340b57cec5SDimitry Andric    unique_ptr<_Yp> __hold(__p);
39350b57cec5SDimitry Andric    typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
39360b57cec5SDimitry Andric    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _AllocT > _CntrlBlk;
39370b57cec5SDimitry Andric    __cntrl_ = new _CntrlBlk(__p, default_delete<_Yp>(), _AllocT());
39380b57cec5SDimitry Andric    __hold.release();
39390b57cec5SDimitry Andric    __enable_weak_this(__p, __p);
39400b57cec5SDimitry Andric}
39410b57cec5SDimitry Andric
39420b57cec5SDimitry Andrictemplate<class _Tp>
39430b57cec5SDimitry Andrictemplate<class _Yp, class _Dp>
39440b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
39450b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
39460b57cec5SDimitry Andric    : __ptr_(__p)
39470b57cec5SDimitry Andric{
39480b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
39490b57cec5SDimitry Andric    try
39500b57cec5SDimitry Andric    {
39510b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
39520b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
39530b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
39540b57cec5SDimitry Andric        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
39550b57cec5SDimitry Andric        __enable_weak_this(__p, __p);
39560b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
39570b57cec5SDimitry Andric    }
39580b57cec5SDimitry Andric    catch (...)
39590b57cec5SDimitry Andric    {
39600b57cec5SDimitry Andric        __d(__p);
39610b57cec5SDimitry Andric        throw;
39620b57cec5SDimitry Andric    }
39630b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
39640b57cec5SDimitry Andric}
39650b57cec5SDimitry Andric
39660b57cec5SDimitry Andrictemplate<class _Tp>
39670b57cec5SDimitry Andrictemplate<class _Dp>
39680b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
39690b57cec5SDimitry Andric    : __ptr_(0)
39700b57cec5SDimitry Andric{
39710b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
39720b57cec5SDimitry Andric    try
39730b57cec5SDimitry Andric    {
39740b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
39750b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
39760b57cec5SDimitry Andric        typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
39770b57cec5SDimitry Andric        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
39780b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
39790b57cec5SDimitry Andric    }
39800b57cec5SDimitry Andric    catch (...)
39810b57cec5SDimitry Andric    {
39820b57cec5SDimitry Andric        __d(__p);
39830b57cec5SDimitry Andric        throw;
39840b57cec5SDimitry Andric    }
39850b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
39860b57cec5SDimitry Andric}
39870b57cec5SDimitry Andric
39880b57cec5SDimitry Andrictemplate<class _Tp>
39890b57cec5SDimitry Andrictemplate<class _Yp, class _Dp, class _Alloc>
39900b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
39910b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
39920b57cec5SDimitry Andric    : __ptr_(__p)
39930b57cec5SDimitry Andric{
39940b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
39950b57cec5SDimitry Andric    try
39960b57cec5SDimitry Andric    {
39970b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
39980b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
39990b57cec5SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
40000b57cec5SDimitry Andric        typedef __allocator_destructor<_A2> _D2;
40010b57cec5SDimitry Andric        _A2 __a2(__a);
40020b57cec5SDimitry Andric        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
40030b57cec5SDimitry Andric        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
40040b57cec5SDimitry Andric            _CntrlBlk(__p, __d, __a);
40050b57cec5SDimitry Andric        __cntrl_ = _VSTD::addressof(*__hold2.release());
40060b57cec5SDimitry Andric        __enable_weak_this(__p, __p);
40070b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
40080b57cec5SDimitry Andric    }
40090b57cec5SDimitry Andric    catch (...)
40100b57cec5SDimitry Andric    {
40110b57cec5SDimitry Andric        __d(__p);
40120b57cec5SDimitry Andric        throw;
40130b57cec5SDimitry Andric    }
40140b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
40150b57cec5SDimitry Andric}
40160b57cec5SDimitry Andric
40170b57cec5SDimitry Andrictemplate<class _Tp>
40180b57cec5SDimitry Andrictemplate<class _Dp, class _Alloc>
40190b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
40200b57cec5SDimitry Andric    : __ptr_(0)
40210b57cec5SDimitry Andric{
40220b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
40230b57cec5SDimitry Andric    try
40240b57cec5SDimitry Andric    {
40250b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
40260b57cec5SDimitry Andric        typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
40270b57cec5SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
40280b57cec5SDimitry Andric        typedef __allocator_destructor<_A2> _D2;
40290b57cec5SDimitry Andric        _A2 __a2(__a);
40300b57cec5SDimitry Andric        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
40310b57cec5SDimitry Andric        ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
40320b57cec5SDimitry Andric            _CntrlBlk(__p, __d, __a);
40330b57cec5SDimitry Andric        __cntrl_ = _VSTD::addressof(*__hold2.release());
40340b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
40350b57cec5SDimitry Andric    }
40360b57cec5SDimitry Andric    catch (...)
40370b57cec5SDimitry Andric    {
40380b57cec5SDimitry Andric        __d(__p);
40390b57cec5SDimitry Andric        throw;
40400b57cec5SDimitry Andric    }
40410b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
40420b57cec5SDimitry Andric}
40430b57cec5SDimitry Andric
40440b57cec5SDimitry Andrictemplate<class _Tp>
40450b57cec5SDimitry Andrictemplate<class _Yp>
40460b57cec5SDimitry Andricinline
40470b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
40480b57cec5SDimitry Andric    : __ptr_(__p),
40490b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
40500b57cec5SDimitry Andric{
40510b57cec5SDimitry Andric    if (__cntrl_)
40520b57cec5SDimitry Andric        __cntrl_->__add_shared();
40530b57cec5SDimitry Andric}
40540b57cec5SDimitry Andric
40550b57cec5SDimitry Andrictemplate<class _Tp>
40560b57cec5SDimitry Andricinline
40570b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
40580b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
40590b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
40600b57cec5SDimitry Andric{
40610b57cec5SDimitry Andric    if (__cntrl_)
40620b57cec5SDimitry Andric        __cntrl_->__add_shared();
40630b57cec5SDimitry Andric}
40640b57cec5SDimitry Andric
40650b57cec5SDimitry Andrictemplate<class _Tp>
40660b57cec5SDimitry Andrictemplate<class _Yp>
40670b57cec5SDimitry Andricinline
40680b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
40690b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
40700b57cec5SDimitry Andric         _NOEXCEPT
40710b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
40720b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
40730b57cec5SDimitry Andric{
40740b57cec5SDimitry Andric    if (__cntrl_)
40750b57cec5SDimitry Andric        __cntrl_->__add_shared();
40760b57cec5SDimitry Andric}
40770b57cec5SDimitry Andric
40780b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
40790b57cec5SDimitry Andric
40800b57cec5SDimitry Andrictemplate<class _Tp>
40810b57cec5SDimitry Andricinline
40820b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
40830b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
40840b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
40850b57cec5SDimitry Andric{
40860b57cec5SDimitry Andric    __r.__ptr_ = 0;
40870b57cec5SDimitry Andric    __r.__cntrl_ = 0;
40880b57cec5SDimitry Andric}
40890b57cec5SDimitry Andric
40900b57cec5SDimitry Andrictemplate<class _Tp>
40910b57cec5SDimitry Andrictemplate<class _Yp>
40920b57cec5SDimitry Andricinline
40930b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
40940b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
40950b57cec5SDimitry Andric         _NOEXCEPT
40960b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
40970b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
40980b57cec5SDimitry Andric{
40990b57cec5SDimitry Andric    __r.__ptr_ = 0;
41000b57cec5SDimitry Andric    __r.__cntrl_ = 0;
41010b57cec5SDimitry Andric}
41020b57cec5SDimitry Andric
41030b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
41040b57cec5SDimitry Andric
41050b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
41060b57cec5SDimitry Andrictemplate<class _Tp>
41070b57cec5SDimitry Andrictemplate<class _Yp>
41080b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
41090b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
41100b57cec5SDimitry Andric#else
41110b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp> __r,
41120b57cec5SDimitry Andric#endif
41130b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
41140b57cec5SDimitry Andric    : __ptr_(__r.get())
41150b57cec5SDimitry Andric{
41160b57cec5SDimitry Andric    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
41170b57cec5SDimitry Andric    __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
41180b57cec5SDimitry Andric    __enable_weak_this(__r.get(), __r.get());
41190b57cec5SDimitry Andric    __r.release();
41200b57cec5SDimitry Andric}
41210b57cec5SDimitry Andric#endif
41220b57cec5SDimitry Andric
41230b57cec5SDimitry Andrictemplate<class _Tp>
41240b57cec5SDimitry Andrictemplate <class _Yp, class _Dp>
41250b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
41260b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
41270b57cec5SDimitry Andric#else
41280b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
41290b57cec5SDimitry Andric#endif
41300b57cec5SDimitry Andric                            typename enable_if
41310b57cec5SDimitry Andric                            <
41320b57cec5SDimitry Andric                                !is_lvalue_reference<_Dp>::value &&
41330b57cec5SDimitry Andric                                !is_array<_Yp>::value &&
41340b57cec5SDimitry Andric                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
41350b57cec5SDimitry Andric                                __nat
41360b57cec5SDimitry Andric                            >::type)
41370b57cec5SDimitry Andric    : __ptr_(__r.get())
41380b57cec5SDimitry Andric{
41390b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
41400b57cec5SDimitry Andric    if (__ptr_ == nullptr)
41410b57cec5SDimitry Andric        __cntrl_ = nullptr;
41420b57cec5SDimitry Andric    else
41430b57cec5SDimitry Andric#endif
41440b57cec5SDimitry Andric    {
41450b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
41460b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
41470b57cec5SDimitry Andric        __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
41480b57cec5SDimitry Andric        __enable_weak_this(__r.get(), __r.get());
41490b57cec5SDimitry Andric    }
41500b57cec5SDimitry Andric    __r.release();
41510b57cec5SDimitry Andric}
41520b57cec5SDimitry Andric
41530b57cec5SDimitry Andrictemplate<class _Tp>
41540b57cec5SDimitry Andrictemplate <class _Yp, class _Dp>
41550b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
41560b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
41570b57cec5SDimitry Andric#else
41580b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp> __r,
41590b57cec5SDimitry Andric#endif
41600b57cec5SDimitry Andric                            typename enable_if
41610b57cec5SDimitry Andric                            <
41620b57cec5SDimitry Andric                                is_lvalue_reference<_Dp>::value &&
41630b57cec5SDimitry Andric                                !is_array<_Yp>::value &&
41640b57cec5SDimitry Andric                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
41650b57cec5SDimitry Andric                                __nat
41660b57cec5SDimitry Andric                            >::type)
41670b57cec5SDimitry Andric    : __ptr_(__r.get())
41680b57cec5SDimitry Andric{
41690b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
41700b57cec5SDimitry Andric    if (__ptr_ == nullptr)
41710b57cec5SDimitry Andric        __cntrl_ = nullptr;
41720b57cec5SDimitry Andric    else
41730b57cec5SDimitry Andric#endif
41740b57cec5SDimitry Andric    {
41750b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
41760b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*,
41770b57cec5SDimitry Andric                                     reference_wrapper<typename remove_reference<_Dp>::type>,
41780b57cec5SDimitry Andric                                     _AllocT > _CntrlBlk;
41790b57cec5SDimitry Andric        __cntrl_ = new _CntrlBlk(__r.get(), ref(__r.get_deleter()), _AllocT());
41800b57cec5SDimitry Andric        __enable_weak_this(__r.get(), __r.get());
41810b57cec5SDimitry Andric    }
41820b57cec5SDimitry Andric    __r.release();
41830b57cec5SDimitry Andric}
41840b57cec5SDimitry Andric
41850b57cec5SDimitry Andrictemplate<class _Tp>
41860b57cec5SDimitry Andrictemplate<class _Alloc, class ..._Args>
41870b57cec5SDimitry Andricshared_ptr<_Tp>
41880b57cec5SDimitry Andricshared_ptr<_Tp>::allocate_shared(const _Alloc& __a, _Args&& ...__args)
41890b57cec5SDimitry Andric{
41900b57cec5SDimitry Andric    static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared" );
41910b57cec5SDimitry Andric    typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
41920b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
41930b57cec5SDimitry Andric    typedef __allocator_destructor<_A2> _D2;
41940b57cec5SDimitry Andric    _A2 __a2(__a);
41950b57cec5SDimitry Andric    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
41960b57cec5SDimitry Andric    ::new(static_cast<void*>(_VSTD::addressof(*__hold2.get())))
41970b57cec5SDimitry Andric        _CntrlBlk(__a, _VSTD::forward<_Args>(__args)...);
41980b57cec5SDimitry Andric    shared_ptr<_Tp> __r;
41990b57cec5SDimitry Andric    __r.__ptr_ = __hold2.get()->get();
42000b57cec5SDimitry Andric    __r.__cntrl_ = _VSTD::addressof(*__hold2.release());
42010b57cec5SDimitry Andric    __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
42020b57cec5SDimitry Andric    return __r;
42030b57cec5SDimitry Andric}
42040b57cec5SDimitry Andric
42050b57cec5SDimitry Andrictemplate<class _Tp>
42060b57cec5SDimitry Andricshared_ptr<_Tp>::~shared_ptr()
42070b57cec5SDimitry Andric{
42080b57cec5SDimitry Andric    if (__cntrl_)
42090b57cec5SDimitry Andric        __cntrl_->__release_shared();
42100b57cec5SDimitry Andric}
42110b57cec5SDimitry Andric
42120b57cec5SDimitry Andrictemplate<class _Tp>
42130b57cec5SDimitry Andricinline
42140b57cec5SDimitry Andricshared_ptr<_Tp>&
42150b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
42160b57cec5SDimitry Andric{
42170b57cec5SDimitry Andric    shared_ptr(__r).swap(*this);
42180b57cec5SDimitry Andric    return *this;
42190b57cec5SDimitry Andric}
42200b57cec5SDimitry Andric
42210b57cec5SDimitry Andrictemplate<class _Tp>
42220b57cec5SDimitry Andrictemplate<class _Yp>
42230b57cec5SDimitry Andricinline
42240b57cec5SDimitry Andrictypename enable_if
42250b57cec5SDimitry Andric<
42260b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
42270b57cec5SDimitry Andric    shared_ptr<_Tp>&
42280b57cec5SDimitry Andric>::type
42290b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
42300b57cec5SDimitry Andric{
42310b57cec5SDimitry Andric    shared_ptr(__r).swap(*this);
42320b57cec5SDimitry Andric    return *this;
42330b57cec5SDimitry Andric}
42340b57cec5SDimitry Andric
42350b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
42360b57cec5SDimitry Andric
42370b57cec5SDimitry Andrictemplate<class _Tp>
42380b57cec5SDimitry Andricinline
42390b57cec5SDimitry Andricshared_ptr<_Tp>&
42400b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
42410b57cec5SDimitry Andric{
42420b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
42430b57cec5SDimitry Andric    return *this;
42440b57cec5SDimitry Andric}
42450b57cec5SDimitry Andric
42460b57cec5SDimitry Andrictemplate<class _Tp>
42470b57cec5SDimitry Andrictemplate<class _Yp>
42480b57cec5SDimitry Andricinline
42490b57cec5SDimitry Andrictypename enable_if
42500b57cec5SDimitry Andric<
42510b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
42520b57cec5SDimitry Andric    shared_ptr<_Tp>&
42530b57cec5SDimitry Andric>::type
42540b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
42550b57cec5SDimitry Andric{
42560b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
42570b57cec5SDimitry Andric    return *this;
42580b57cec5SDimitry Andric}
42590b57cec5SDimitry Andric
42600b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
42610b57cec5SDimitry Andrictemplate<class _Tp>
42620b57cec5SDimitry Andrictemplate<class _Yp>
42630b57cec5SDimitry Andricinline
42640b57cec5SDimitry Andrictypename enable_if
42650b57cec5SDimitry Andric<
42660b57cec5SDimitry Andric    !is_array<_Yp>::value &&
42670b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
42680b57cec5SDimitry Andric    shared_ptr<_Tp>
42690b57cec5SDimitry Andric>::type&
42700b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
42710b57cec5SDimitry Andric{
42720b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
42730b57cec5SDimitry Andric    return *this;
42740b57cec5SDimitry Andric}
42750b57cec5SDimitry Andric#endif
42760b57cec5SDimitry Andric
42770b57cec5SDimitry Andrictemplate<class _Tp>
42780b57cec5SDimitry Andrictemplate <class _Yp, class _Dp>
42790b57cec5SDimitry Andricinline
42800b57cec5SDimitry Andrictypename enable_if
42810b57cec5SDimitry Andric<
42820b57cec5SDimitry Andric    !is_array<_Yp>::value &&
42830b57cec5SDimitry Andric    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
42840b57cec5SDimitry Andric                   typename shared_ptr<_Tp>::element_type*>::value,
42850b57cec5SDimitry Andric    shared_ptr<_Tp>&
42860b57cec5SDimitry Andric>::type
42870b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
42880b57cec5SDimitry Andric{
42890b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
42900b57cec5SDimitry Andric    return *this;
42910b57cec5SDimitry Andric}
42920b57cec5SDimitry Andric
42930b57cec5SDimitry Andric#else  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
42940b57cec5SDimitry Andric
42950b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
42960b57cec5SDimitry Andrictemplate<class _Tp>
42970b57cec5SDimitry Andrictemplate<class _Yp>
42980b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
42990b57cec5SDimitry Andrictypename enable_if
43000b57cec5SDimitry Andric<
43010b57cec5SDimitry Andric    !is_array<_Yp>::value &&
43020b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
43030b57cec5SDimitry Andric    shared_ptr<_Tp>&
43040b57cec5SDimitry Andric>::type
43050b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(auto_ptr<_Yp> __r)
43060b57cec5SDimitry Andric{
43070b57cec5SDimitry Andric    shared_ptr(__r).swap(*this);
43080b57cec5SDimitry Andric    return *this;
43090b57cec5SDimitry Andric}
43100b57cec5SDimitry Andric#endif
43110b57cec5SDimitry Andric
43120b57cec5SDimitry Andrictemplate<class _Tp>
43130b57cec5SDimitry Andrictemplate <class _Yp, class _Dp>
43140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
43150b57cec5SDimitry Andrictypename enable_if
43160b57cec5SDimitry Andric<
43170b57cec5SDimitry Andric    !is_array<_Yp>::value &&
43180b57cec5SDimitry Andric    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
43190b57cec5SDimitry Andric                   typename shared_ptr<_Tp>::element_type*>::value,
43200b57cec5SDimitry Andric    shared_ptr<_Tp>&
43210b57cec5SDimitry Andric>::type
43220b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp> __r)
43230b57cec5SDimitry Andric{
43240b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
43250b57cec5SDimitry Andric    return *this;
43260b57cec5SDimitry Andric}
43270b57cec5SDimitry Andric
43280b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
43290b57cec5SDimitry Andric
43300b57cec5SDimitry Andrictemplate<class _Tp>
43310b57cec5SDimitry Andricinline
43320b57cec5SDimitry Andricvoid
43330b57cec5SDimitry Andricshared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
43340b57cec5SDimitry Andric{
43350b57cec5SDimitry Andric    _VSTD::swap(__ptr_, __r.__ptr_);
43360b57cec5SDimitry Andric    _VSTD::swap(__cntrl_, __r.__cntrl_);
43370b57cec5SDimitry Andric}
43380b57cec5SDimitry Andric
43390b57cec5SDimitry Andrictemplate<class _Tp>
43400b57cec5SDimitry Andricinline
43410b57cec5SDimitry Andricvoid
43420b57cec5SDimitry Andricshared_ptr<_Tp>::reset() _NOEXCEPT
43430b57cec5SDimitry Andric{
43440b57cec5SDimitry Andric    shared_ptr().swap(*this);
43450b57cec5SDimitry Andric}
43460b57cec5SDimitry Andric
43470b57cec5SDimitry Andrictemplate<class _Tp>
43480b57cec5SDimitry Andrictemplate<class _Yp>
43490b57cec5SDimitry Andricinline
43500b57cec5SDimitry Andrictypename enable_if
43510b57cec5SDimitry Andric<
43520b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
43530b57cec5SDimitry Andric    void
43540b57cec5SDimitry Andric>::type
43550b57cec5SDimitry Andricshared_ptr<_Tp>::reset(_Yp* __p)
43560b57cec5SDimitry Andric{
43570b57cec5SDimitry Andric    shared_ptr(__p).swap(*this);
43580b57cec5SDimitry Andric}
43590b57cec5SDimitry Andric
43600b57cec5SDimitry Andrictemplate<class _Tp>
43610b57cec5SDimitry Andrictemplate<class _Yp, class _Dp>
43620b57cec5SDimitry Andricinline
43630b57cec5SDimitry Andrictypename enable_if
43640b57cec5SDimitry Andric<
43650b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
43660b57cec5SDimitry Andric    void
43670b57cec5SDimitry Andric>::type
43680b57cec5SDimitry Andricshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
43690b57cec5SDimitry Andric{
43700b57cec5SDimitry Andric    shared_ptr(__p, __d).swap(*this);
43710b57cec5SDimitry Andric}
43720b57cec5SDimitry Andric
43730b57cec5SDimitry Andrictemplate<class _Tp>
43740b57cec5SDimitry Andrictemplate<class _Yp, class _Dp, class _Alloc>
43750b57cec5SDimitry Andricinline
43760b57cec5SDimitry Andrictypename enable_if
43770b57cec5SDimitry Andric<
43780b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
43790b57cec5SDimitry Andric    void
43800b57cec5SDimitry Andric>::type
43810b57cec5SDimitry Andricshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
43820b57cec5SDimitry Andric{
43830b57cec5SDimitry Andric    shared_ptr(__p, __d, __a).swap(*this);
43840b57cec5SDimitry Andric}
43850b57cec5SDimitry Andric
43860b57cec5SDimitry Andrictemplate<class _Tp, class ..._Args>
43870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
43880b57cec5SDimitry Andrictypename enable_if
43890b57cec5SDimitry Andric<
43900b57cec5SDimitry Andric    !is_array<_Tp>::value,
43910b57cec5SDimitry Andric    shared_ptr<_Tp>
43920b57cec5SDimitry Andric>::type
43930b57cec5SDimitry Andricmake_shared(_Args&& ...__args)
43940b57cec5SDimitry Andric{
4395e40139ffSDimitry Andric    static_assert(is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared");
4396e40139ffSDimitry Andric    typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
4397e40139ffSDimitry Andric    typedef allocator<_CntrlBlk> _A2;
4398e40139ffSDimitry Andric    typedef __allocator_destructor<_A2> _D2;
4399e40139ffSDimitry Andric
4400e40139ffSDimitry Andric    _A2 __a2;
4401e40139ffSDimitry Andric    unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
4402e40139ffSDimitry Andric    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
4403e40139ffSDimitry Andric
4404e40139ffSDimitry Andric    _Tp *__ptr = __hold2.get()->get();
4405e40139ffSDimitry Andric    return shared_ptr<_Tp>::__create_with_control_block(__ptr, __hold2.release());
44060b57cec5SDimitry Andric}
44070b57cec5SDimitry Andric
44080b57cec5SDimitry Andrictemplate<class _Tp, class _Alloc, class ..._Args>
44090b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44100b57cec5SDimitry Andrictypename enable_if
44110b57cec5SDimitry Andric<
44120b57cec5SDimitry Andric    !is_array<_Tp>::value,
44130b57cec5SDimitry Andric    shared_ptr<_Tp>
44140b57cec5SDimitry Andric>::type
44150b57cec5SDimitry Andricallocate_shared(const _Alloc& __a, _Args&& ...__args)
44160b57cec5SDimitry Andric{
44170b57cec5SDimitry Andric    return shared_ptr<_Tp>::allocate_shared(__a, _VSTD::forward<_Args>(__args)...);
44180b57cec5SDimitry Andric}
44190b57cec5SDimitry Andric
44200b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
44210b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44220b57cec5SDimitry Andricbool
44230b57cec5SDimitry Andricoperator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
44240b57cec5SDimitry Andric{
44250b57cec5SDimitry Andric    return __x.get() == __y.get();
44260b57cec5SDimitry Andric}
44270b57cec5SDimitry Andric
44280b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
44290b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44300b57cec5SDimitry Andricbool
44310b57cec5SDimitry Andricoperator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
44320b57cec5SDimitry Andric{
44330b57cec5SDimitry Andric    return !(__x == __y);
44340b57cec5SDimitry Andric}
44350b57cec5SDimitry Andric
44360b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
44370b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44380b57cec5SDimitry Andricbool
44390b57cec5SDimitry Andricoperator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
44400b57cec5SDimitry Andric{
44410b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 11
44420b57cec5SDimitry Andric    typedef typename common_type<_Tp*, _Up*>::type _Vp;
44430b57cec5SDimitry Andric    return less<_Vp>()(__x.get(), __y.get());
44440b57cec5SDimitry Andric#else
44450b57cec5SDimitry Andric    return less<>()(__x.get(), __y.get());
44460b57cec5SDimitry Andric#endif
44470b57cec5SDimitry Andric
44480b57cec5SDimitry Andric}
44490b57cec5SDimitry Andric
44500b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
44510b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44520b57cec5SDimitry Andricbool
44530b57cec5SDimitry Andricoperator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
44540b57cec5SDimitry Andric{
44550b57cec5SDimitry Andric    return __y < __x;
44560b57cec5SDimitry Andric}
44570b57cec5SDimitry Andric
44580b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
44590b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44600b57cec5SDimitry Andricbool
44610b57cec5SDimitry Andricoperator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
44620b57cec5SDimitry Andric{
44630b57cec5SDimitry Andric    return !(__y < __x);
44640b57cec5SDimitry Andric}
44650b57cec5SDimitry Andric
44660b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
44670b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44680b57cec5SDimitry Andricbool
44690b57cec5SDimitry Andricoperator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
44700b57cec5SDimitry Andric{
44710b57cec5SDimitry Andric    return !(__x < __y);
44720b57cec5SDimitry Andric}
44730b57cec5SDimitry Andric
44740b57cec5SDimitry Andrictemplate<class _Tp>
44750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44760b57cec5SDimitry Andricbool
44770b57cec5SDimitry Andricoperator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
44780b57cec5SDimitry Andric{
44790b57cec5SDimitry Andric    return !__x;
44800b57cec5SDimitry Andric}
44810b57cec5SDimitry Andric
44820b57cec5SDimitry Andrictemplate<class _Tp>
44830b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44840b57cec5SDimitry Andricbool
44850b57cec5SDimitry Andricoperator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
44860b57cec5SDimitry Andric{
44870b57cec5SDimitry Andric    return !__x;
44880b57cec5SDimitry Andric}
44890b57cec5SDimitry Andric
44900b57cec5SDimitry Andrictemplate<class _Tp>
44910b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
44920b57cec5SDimitry Andricbool
44930b57cec5SDimitry Andricoperator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
44940b57cec5SDimitry Andric{
44950b57cec5SDimitry Andric    return static_cast<bool>(__x);
44960b57cec5SDimitry Andric}
44970b57cec5SDimitry Andric
44980b57cec5SDimitry Andrictemplate<class _Tp>
44990b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45000b57cec5SDimitry Andricbool
45010b57cec5SDimitry Andricoperator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
45020b57cec5SDimitry Andric{
45030b57cec5SDimitry Andric    return static_cast<bool>(__x);
45040b57cec5SDimitry Andric}
45050b57cec5SDimitry Andric
45060b57cec5SDimitry Andrictemplate<class _Tp>
45070b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45080b57cec5SDimitry Andricbool
45090b57cec5SDimitry Andricoperator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
45100b57cec5SDimitry Andric{
45110b57cec5SDimitry Andric    return less<_Tp*>()(__x.get(), nullptr);
45120b57cec5SDimitry Andric}
45130b57cec5SDimitry Andric
45140b57cec5SDimitry Andrictemplate<class _Tp>
45150b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45160b57cec5SDimitry Andricbool
45170b57cec5SDimitry Andricoperator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
45180b57cec5SDimitry Andric{
45190b57cec5SDimitry Andric    return less<_Tp*>()(nullptr, __x.get());
45200b57cec5SDimitry Andric}
45210b57cec5SDimitry Andric
45220b57cec5SDimitry Andrictemplate<class _Tp>
45230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45240b57cec5SDimitry Andricbool
45250b57cec5SDimitry Andricoperator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
45260b57cec5SDimitry Andric{
45270b57cec5SDimitry Andric    return nullptr < __x;
45280b57cec5SDimitry Andric}
45290b57cec5SDimitry Andric
45300b57cec5SDimitry Andrictemplate<class _Tp>
45310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45320b57cec5SDimitry Andricbool
45330b57cec5SDimitry Andricoperator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
45340b57cec5SDimitry Andric{
45350b57cec5SDimitry Andric    return __x < nullptr;
45360b57cec5SDimitry Andric}
45370b57cec5SDimitry Andric
45380b57cec5SDimitry Andrictemplate<class _Tp>
45390b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45400b57cec5SDimitry Andricbool
45410b57cec5SDimitry Andricoperator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
45420b57cec5SDimitry Andric{
45430b57cec5SDimitry Andric    return !(nullptr < __x);
45440b57cec5SDimitry Andric}
45450b57cec5SDimitry Andric
45460b57cec5SDimitry Andrictemplate<class _Tp>
45470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45480b57cec5SDimitry Andricbool
45490b57cec5SDimitry Andricoperator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
45500b57cec5SDimitry Andric{
45510b57cec5SDimitry Andric    return !(__x < nullptr);
45520b57cec5SDimitry Andric}
45530b57cec5SDimitry Andric
45540b57cec5SDimitry Andrictemplate<class _Tp>
45550b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45560b57cec5SDimitry Andricbool
45570b57cec5SDimitry Andricoperator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
45580b57cec5SDimitry Andric{
45590b57cec5SDimitry Andric    return !(__x < nullptr);
45600b57cec5SDimitry Andric}
45610b57cec5SDimitry Andric
45620b57cec5SDimitry Andrictemplate<class _Tp>
45630b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45640b57cec5SDimitry Andricbool
45650b57cec5SDimitry Andricoperator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
45660b57cec5SDimitry Andric{
45670b57cec5SDimitry Andric    return !(nullptr < __x);
45680b57cec5SDimitry Andric}
45690b57cec5SDimitry Andric
45700b57cec5SDimitry Andrictemplate<class _Tp>
45710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45720b57cec5SDimitry Andricvoid
45730b57cec5SDimitry Andricswap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
45740b57cec5SDimitry Andric{
45750b57cec5SDimitry Andric    __x.swap(__y);
45760b57cec5SDimitry Andric}
45770b57cec5SDimitry Andric
45780b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
45790b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45800b57cec5SDimitry Andrictypename enable_if
45810b57cec5SDimitry Andric<
45820b57cec5SDimitry Andric    !is_array<_Tp>::value && !is_array<_Up>::value,
45830b57cec5SDimitry Andric    shared_ptr<_Tp>
45840b57cec5SDimitry Andric>::type
45850b57cec5SDimitry Andricstatic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
45860b57cec5SDimitry Andric{
45870b57cec5SDimitry Andric    return shared_ptr<_Tp>(__r, static_cast<_Tp*>(__r.get()));
45880b57cec5SDimitry Andric}
45890b57cec5SDimitry Andric
45900b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
45910b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
45920b57cec5SDimitry Andrictypename enable_if
45930b57cec5SDimitry Andric<
45940b57cec5SDimitry Andric    !is_array<_Tp>::value && !is_array<_Up>::value,
45950b57cec5SDimitry Andric    shared_ptr<_Tp>
45960b57cec5SDimitry Andric>::type
45970b57cec5SDimitry Andricdynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
45980b57cec5SDimitry Andric{
45990b57cec5SDimitry Andric    _Tp* __p = dynamic_cast<_Tp*>(__r.get());
46000b57cec5SDimitry Andric    return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
46010b57cec5SDimitry Andric}
46020b57cec5SDimitry Andric
46030b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
46040b57cec5SDimitry Andrictypename enable_if
46050b57cec5SDimitry Andric<
46060b57cec5SDimitry Andric    is_array<_Tp>::value == is_array<_Up>::value,
46070b57cec5SDimitry Andric    shared_ptr<_Tp>
46080b57cec5SDimitry Andric>::type
46090b57cec5SDimitry Andricconst_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
46100b57cec5SDimitry Andric{
46110b57cec5SDimitry Andric    typedef typename remove_extent<_Tp>::type _RTp;
46120b57cec5SDimitry Andric    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
46130b57cec5SDimitry Andric}
46140b57cec5SDimitry Andric
46150b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
46160b57cec5SDimitry Andric
46170b57cec5SDimitry Andrictemplate<class _Dp, class _Tp>
46180b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
46190b57cec5SDimitry Andric_Dp*
46200b57cec5SDimitry Andricget_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
46210b57cec5SDimitry Andric{
46220b57cec5SDimitry Andric    return __p.template __get_deleter<_Dp>();
46230b57cec5SDimitry Andric}
46240b57cec5SDimitry Andric
46250b57cec5SDimitry Andric#endif  // _LIBCPP_NO_RTTI
46260b57cec5SDimitry Andric
46270b57cec5SDimitry Andrictemplate<class _Tp>
46280b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS weak_ptr
46290b57cec5SDimitry Andric{
46300b57cec5SDimitry Andricpublic:
46310b57cec5SDimitry Andric    typedef _Tp element_type;
46320b57cec5SDimitry Andricprivate:
46330b57cec5SDimitry Andric    element_type*        __ptr_;
46340b57cec5SDimitry Andric    __shared_weak_count* __cntrl_;
46350b57cec5SDimitry Andric
46360b57cec5SDimitry Andricpublic:
46370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46380b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
46390b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
46400b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
46410b57cec5SDimitry Andric                        _NOEXCEPT;
46420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46430b57cec5SDimitry Andric    weak_ptr(weak_ptr const& __r) _NOEXCEPT;
46440b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
46450b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
46460b57cec5SDimitry Andric                         _NOEXCEPT;
46470b57cec5SDimitry Andric
46480b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
46490b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46500b57cec5SDimitry Andric    weak_ptr(weak_ptr&& __r) _NOEXCEPT;
46510b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
46520b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
46530b57cec5SDimitry Andric                         _NOEXCEPT;
46540b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
46550b57cec5SDimitry Andric    ~weak_ptr();
46560b57cec5SDimitry Andric
46570b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46580b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
46590b57cec5SDimitry Andric    template<class _Yp>
46600b57cec5SDimitry Andric        typename enable_if
46610b57cec5SDimitry Andric        <
46620b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
46630b57cec5SDimitry Andric            weak_ptr&
46640b57cec5SDimitry Andric        >::type
46650b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
46660b57cec5SDimitry Andric        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
46670b57cec5SDimitry Andric
46680b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
46690b57cec5SDimitry Andric
46700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46710b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
46720b57cec5SDimitry Andric    template<class _Yp>
46730b57cec5SDimitry Andric        typename enable_if
46740b57cec5SDimitry Andric        <
46750b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
46760b57cec5SDimitry Andric            weak_ptr&
46770b57cec5SDimitry Andric        >::type
46780b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
46790b57cec5SDimitry Andric        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
46800b57cec5SDimitry Andric
46810b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
46820b57cec5SDimitry Andric
46830b57cec5SDimitry Andric    template<class _Yp>
46840b57cec5SDimitry Andric        typename enable_if
46850b57cec5SDimitry Andric        <
46860b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
46870b57cec5SDimitry Andric            weak_ptr&
46880b57cec5SDimitry Andric        >::type
46890b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
46900b57cec5SDimitry Andric        operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
46910b57cec5SDimitry Andric
46920b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46930b57cec5SDimitry Andric    void swap(weak_ptr& __r) _NOEXCEPT;
46940b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46950b57cec5SDimitry Andric    void reset() _NOEXCEPT;
46960b57cec5SDimitry Andric
46970b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46980b57cec5SDimitry Andric    long use_count() const _NOEXCEPT
46990b57cec5SDimitry Andric        {return __cntrl_ ? __cntrl_->use_count() : 0;}
47000b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47010b57cec5SDimitry Andric    bool expired() const _NOEXCEPT
47020b57cec5SDimitry Andric        {return __cntrl_ == 0 || __cntrl_->use_count() == 0;}
47030b57cec5SDimitry Andric    shared_ptr<_Tp> lock() const _NOEXCEPT;
47040b57cec5SDimitry Andric    template<class _Up>
47050b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
47060b57cec5SDimitry Andric        bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
47070b57cec5SDimitry Andric        {return __cntrl_ < __r.__cntrl_;}
47080b57cec5SDimitry Andric    template<class _Up>
47090b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
47100b57cec5SDimitry Andric        bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
47110b57cec5SDimitry Andric        {return __cntrl_ < __r.__cntrl_;}
47120b57cec5SDimitry Andric
47130b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
47140b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
47150b57cec5SDimitry Andric};
47160b57cec5SDimitry Andric
47170b57cec5SDimitry Andrictemplate<class _Tp>
47180b57cec5SDimitry Andricinline
47190b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
47200b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr() _NOEXCEPT
47210b57cec5SDimitry Andric    : __ptr_(0),
47220b57cec5SDimitry Andric      __cntrl_(0)
47230b57cec5SDimitry Andric{
47240b57cec5SDimitry Andric}
47250b57cec5SDimitry Andric
47260b57cec5SDimitry Andrictemplate<class _Tp>
47270b57cec5SDimitry Andricinline
47280b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
47290b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
47300b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
47310b57cec5SDimitry Andric{
47320b57cec5SDimitry Andric    if (__cntrl_)
47330b57cec5SDimitry Andric        __cntrl_->__add_weak();
47340b57cec5SDimitry Andric}
47350b57cec5SDimitry Andric
47360b57cec5SDimitry Andrictemplate<class _Tp>
47370b57cec5SDimitry Andrictemplate<class _Yp>
47380b57cec5SDimitry Andricinline
47390b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
47400b57cec5SDimitry Andric                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
47410b57cec5SDimitry Andric                         _NOEXCEPT
47420b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
47430b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
47440b57cec5SDimitry Andric{
47450b57cec5SDimitry Andric    if (__cntrl_)
47460b57cec5SDimitry Andric        __cntrl_->__add_weak();
47470b57cec5SDimitry Andric}
47480b57cec5SDimitry Andric
47490b57cec5SDimitry Andrictemplate<class _Tp>
47500b57cec5SDimitry Andrictemplate<class _Yp>
47510b57cec5SDimitry Andricinline
47520b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
47530b57cec5SDimitry Andric                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
47540b57cec5SDimitry Andric         _NOEXCEPT
47550b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
47560b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
47570b57cec5SDimitry Andric{
47580b57cec5SDimitry Andric    if (__cntrl_)
47590b57cec5SDimitry Andric        __cntrl_->__add_weak();
47600b57cec5SDimitry Andric}
47610b57cec5SDimitry Andric
47620b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
47630b57cec5SDimitry Andric
47640b57cec5SDimitry Andrictemplate<class _Tp>
47650b57cec5SDimitry Andricinline
47660b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
47670b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
47680b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
47690b57cec5SDimitry Andric{
47700b57cec5SDimitry Andric    __r.__ptr_ = 0;
47710b57cec5SDimitry Andric    __r.__cntrl_ = 0;
47720b57cec5SDimitry Andric}
47730b57cec5SDimitry Andric
47740b57cec5SDimitry Andrictemplate<class _Tp>
47750b57cec5SDimitry Andrictemplate<class _Yp>
47760b57cec5SDimitry Andricinline
47770b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
47780b57cec5SDimitry Andric                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
47790b57cec5SDimitry Andric         _NOEXCEPT
47800b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
47810b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
47820b57cec5SDimitry Andric{
47830b57cec5SDimitry Andric    __r.__ptr_ = 0;
47840b57cec5SDimitry Andric    __r.__cntrl_ = 0;
47850b57cec5SDimitry Andric}
47860b57cec5SDimitry Andric
47870b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
47880b57cec5SDimitry Andric
47890b57cec5SDimitry Andrictemplate<class _Tp>
47900b57cec5SDimitry Andricweak_ptr<_Tp>::~weak_ptr()
47910b57cec5SDimitry Andric{
47920b57cec5SDimitry Andric    if (__cntrl_)
47930b57cec5SDimitry Andric        __cntrl_->__release_weak();
47940b57cec5SDimitry Andric}
47950b57cec5SDimitry Andric
47960b57cec5SDimitry Andrictemplate<class _Tp>
47970b57cec5SDimitry Andricinline
47980b57cec5SDimitry Andricweak_ptr<_Tp>&
47990b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
48000b57cec5SDimitry Andric{
48010b57cec5SDimitry Andric    weak_ptr(__r).swap(*this);
48020b57cec5SDimitry Andric    return *this;
48030b57cec5SDimitry Andric}
48040b57cec5SDimitry Andric
48050b57cec5SDimitry Andrictemplate<class _Tp>
48060b57cec5SDimitry Andrictemplate<class _Yp>
48070b57cec5SDimitry Andricinline
48080b57cec5SDimitry Andrictypename enable_if
48090b57cec5SDimitry Andric<
48100b57cec5SDimitry Andric    is_convertible<_Yp*, _Tp*>::value,
48110b57cec5SDimitry Andric    weak_ptr<_Tp>&
48120b57cec5SDimitry Andric>::type
48130b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
48140b57cec5SDimitry Andric{
48150b57cec5SDimitry Andric    weak_ptr(__r).swap(*this);
48160b57cec5SDimitry Andric    return *this;
48170b57cec5SDimitry Andric}
48180b57cec5SDimitry Andric
48190b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
48200b57cec5SDimitry Andric
48210b57cec5SDimitry Andrictemplate<class _Tp>
48220b57cec5SDimitry Andricinline
48230b57cec5SDimitry Andricweak_ptr<_Tp>&
48240b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
48250b57cec5SDimitry Andric{
48260b57cec5SDimitry Andric    weak_ptr(_VSTD::move(__r)).swap(*this);
48270b57cec5SDimitry Andric    return *this;
48280b57cec5SDimitry Andric}
48290b57cec5SDimitry Andric
48300b57cec5SDimitry Andrictemplate<class _Tp>
48310b57cec5SDimitry Andrictemplate<class _Yp>
48320b57cec5SDimitry Andricinline
48330b57cec5SDimitry Andrictypename enable_if
48340b57cec5SDimitry Andric<
48350b57cec5SDimitry Andric    is_convertible<_Yp*, _Tp*>::value,
48360b57cec5SDimitry Andric    weak_ptr<_Tp>&
48370b57cec5SDimitry Andric>::type
48380b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
48390b57cec5SDimitry Andric{
48400b57cec5SDimitry Andric    weak_ptr(_VSTD::move(__r)).swap(*this);
48410b57cec5SDimitry Andric    return *this;
48420b57cec5SDimitry Andric}
48430b57cec5SDimitry Andric
48440b57cec5SDimitry Andric#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
48450b57cec5SDimitry Andric
48460b57cec5SDimitry Andrictemplate<class _Tp>
48470b57cec5SDimitry Andrictemplate<class _Yp>
48480b57cec5SDimitry Andricinline
48490b57cec5SDimitry Andrictypename enable_if
48500b57cec5SDimitry Andric<
48510b57cec5SDimitry Andric    is_convertible<_Yp*, _Tp*>::value,
48520b57cec5SDimitry Andric    weak_ptr<_Tp>&
48530b57cec5SDimitry Andric>::type
48540b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
48550b57cec5SDimitry Andric{
48560b57cec5SDimitry Andric    weak_ptr(__r).swap(*this);
48570b57cec5SDimitry Andric    return *this;
48580b57cec5SDimitry Andric}
48590b57cec5SDimitry Andric
48600b57cec5SDimitry Andrictemplate<class _Tp>
48610b57cec5SDimitry Andricinline
48620b57cec5SDimitry Andricvoid
48630b57cec5SDimitry Andricweak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
48640b57cec5SDimitry Andric{
48650b57cec5SDimitry Andric    _VSTD::swap(__ptr_, __r.__ptr_);
48660b57cec5SDimitry Andric    _VSTD::swap(__cntrl_, __r.__cntrl_);
48670b57cec5SDimitry Andric}
48680b57cec5SDimitry Andric
48690b57cec5SDimitry Andrictemplate<class _Tp>
48700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
48710b57cec5SDimitry Andricvoid
48720b57cec5SDimitry Andricswap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
48730b57cec5SDimitry Andric{
48740b57cec5SDimitry Andric    __x.swap(__y);
48750b57cec5SDimitry Andric}
48760b57cec5SDimitry Andric
48770b57cec5SDimitry Andrictemplate<class _Tp>
48780b57cec5SDimitry Andricinline
48790b57cec5SDimitry Andricvoid
48800b57cec5SDimitry Andricweak_ptr<_Tp>::reset() _NOEXCEPT
48810b57cec5SDimitry Andric{
48820b57cec5SDimitry Andric    weak_ptr().swap(*this);
48830b57cec5SDimitry Andric}
48840b57cec5SDimitry Andric
48850b57cec5SDimitry Andrictemplate<class _Tp>
48860b57cec5SDimitry Andrictemplate<class _Yp>
48870b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
48880b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
48890b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
48900b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
48910b57cec5SDimitry Andric{
48920b57cec5SDimitry Andric    if (__cntrl_ == 0)
48930b57cec5SDimitry Andric        __throw_bad_weak_ptr();
48940b57cec5SDimitry Andric}
48950b57cec5SDimitry Andric
48960b57cec5SDimitry Andrictemplate<class _Tp>
48970b57cec5SDimitry Andricshared_ptr<_Tp>
48980b57cec5SDimitry Andricweak_ptr<_Tp>::lock() const _NOEXCEPT
48990b57cec5SDimitry Andric{
49000b57cec5SDimitry Andric    shared_ptr<_Tp> __r;
49010b57cec5SDimitry Andric    __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
49020b57cec5SDimitry Andric    if (__r.__cntrl_)
49030b57cec5SDimitry Andric        __r.__ptr_ = __ptr_;
49040b57cec5SDimitry Andric    return __r;
49050b57cec5SDimitry Andric}
49060b57cec5SDimitry Andric
49070b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
49080b57cec5SDimitry Andrictemplate <class _Tp = void> struct owner_less;
49090b57cec5SDimitry Andric#else
49100b57cec5SDimitry Andrictemplate <class _Tp> struct owner_less;
49110b57cec5SDimitry Andric#endif
49120b57cec5SDimitry Andric
49130b57cec5SDimitry Andrictemplate <class _Tp>
49140b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
49150b57cec5SDimitry Andric    : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
49160b57cec5SDimitry Andric{
49170b57cec5SDimitry Andric    typedef bool result_type;
49180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49190b57cec5SDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
49200b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49220b57cec5SDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
49230b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49250b57cec5SDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
49260b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49270b57cec5SDimitry Andric};
49280b57cec5SDimitry Andric
49290b57cec5SDimitry Andrictemplate <class _Tp>
49300b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
49310b57cec5SDimitry Andric    : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
49320b57cec5SDimitry Andric{
49330b57cec5SDimitry Andric    typedef bool result_type;
49340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49350b57cec5SDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
49360b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49380b57cec5SDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
49390b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49400b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49410b57cec5SDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
49420b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49430b57cec5SDimitry Andric};
49440b57cec5SDimitry Andric
49450b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
49460b57cec5SDimitry Andrictemplate <>
49470b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<void>
49480b57cec5SDimitry Andric{
49490b57cec5SDimitry Andric    template <class _Tp, class _Up>
49500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49510b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
49520b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49530b57cec5SDimitry Andric    template <class _Tp, class _Up>
49540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49550b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
49560b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49570b57cec5SDimitry Andric    template <class _Tp, class _Up>
49580b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49590b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
49600b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49610b57cec5SDimitry Andric    template <class _Tp, class _Up>
49620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49630b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
49640b57cec5SDimitry Andric        {return __x.owner_before(__y);}
49650b57cec5SDimitry Andric    typedef void is_transparent;
49660b57cec5SDimitry Andric};
49670b57cec5SDimitry Andric#endif
49680b57cec5SDimitry Andric
49690b57cec5SDimitry Andrictemplate<class _Tp>
49700b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS enable_shared_from_this
49710b57cec5SDimitry Andric{
49720b57cec5SDimitry Andric    mutable weak_ptr<_Tp> __weak_this_;
49730b57cec5SDimitry Andricprotected:
49740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
49750b57cec5SDimitry Andric    enable_shared_from_this() _NOEXCEPT {}
49760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49770b57cec5SDimitry Andric    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
49780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49790b57cec5SDimitry Andric    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
49800b57cec5SDimitry Andric        {return *this;}
49810b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49820b57cec5SDimitry Andric    ~enable_shared_from_this() {}
49830b57cec5SDimitry Andricpublic:
49840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49850b57cec5SDimitry Andric    shared_ptr<_Tp> shared_from_this()
49860b57cec5SDimitry Andric        {return shared_ptr<_Tp>(__weak_this_);}
49870b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49880b57cec5SDimitry Andric    shared_ptr<_Tp const> shared_from_this() const
49890b57cec5SDimitry Andric        {return shared_ptr<const _Tp>(__weak_this_);}
49900b57cec5SDimitry Andric
49910b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
49920b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49930b57cec5SDimitry Andric    weak_ptr<_Tp> weak_from_this() _NOEXCEPT
49940b57cec5SDimitry Andric       { return __weak_this_; }
49950b57cec5SDimitry Andric
49960b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49970b57cec5SDimitry Andric    weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
49980b57cec5SDimitry Andric        { return __weak_this_; }
49990b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
50000b57cec5SDimitry Andric
50010b57cec5SDimitry Andric    template <class _Up> friend class shared_ptr;
50020b57cec5SDimitry Andric};
50030b57cec5SDimitry Andric
50040b57cec5SDimitry Andrictemplate <class _Tp>
50050b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
50060b57cec5SDimitry Andric{
50070b57cec5SDimitry Andric    typedef shared_ptr<_Tp>      argument_type;
50080b57cec5SDimitry Andric    typedef size_t               result_type;
50090b57cec5SDimitry Andric
50100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50110b57cec5SDimitry Andric    result_type operator()(const argument_type& __ptr) const _NOEXCEPT
50120b57cec5SDimitry Andric    {
50130b57cec5SDimitry Andric        return hash<_Tp*>()(__ptr.get());
50140b57cec5SDimitry Andric    }
50150b57cec5SDimitry Andric};
50160b57cec5SDimitry Andric
50170b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Yp>
50180b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
50190b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
50200b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
50210b57cec5SDimitry Andric
50220b57cec5SDimitry Andric
50230b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
50240b57cec5SDimitry Andric
50250b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __sp_mut
50260b57cec5SDimitry Andric{
50270b57cec5SDimitry Andric    void* __lx;
50280b57cec5SDimitry Andricpublic:
50290b57cec5SDimitry Andric    void lock() _NOEXCEPT;
50300b57cec5SDimitry Andric    void unlock() _NOEXCEPT;
50310b57cec5SDimitry Andric
50320b57cec5SDimitry Andricprivate:
50330b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
50340b57cec5SDimitry Andric    __sp_mut(const __sp_mut&);
50350b57cec5SDimitry Andric    __sp_mut& operator=(const __sp_mut&);
50360b57cec5SDimitry Andric
50370b57cec5SDimitry Andric    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
50380b57cec5SDimitry Andric};
50390b57cec5SDimitry Andric
50400b57cec5SDimitry Andric_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
50410b57cec5SDimitry Andric__sp_mut& __get_sp_mut(const void*);
50420b57cec5SDimitry Andric
50430b57cec5SDimitry Andrictemplate <class _Tp>
50440b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
50450b57cec5SDimitry Andricbool
50460b57cec5SDimitry Andricatomic_is_lock_free(const shared_ptr<_Tp>*)
50470b57cec5SDimitry Andric{
50480b57cec5SDimitry Andric    return false;
50490b57cec5SDimitry Andric}
50500b57cec5SDimitry Andric
50510b57cec5SDimitry Andrictemplate <class _Tp>
50520b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
50530b57cec5SDimitry Andricshared_ptr<_Tp>
50540b57cec5SDimitry Andricatomic_load(const shared_ptr<_Tp>* __p)
50550b57cec5SDimitry Andric{
50560b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
50570b57cec5SDimitry Andric    __m.lock();
50580b57cec5SDimitry Andric    shared_ptr<_Tp> __q = *__p;
50590b57cec5SDimitry Andric    __m.unlock();
50600b57cec5SDimitry Andric    return __q;
50610b57cec5SDimitry Andric}
50620b57cec5SDimitry Andric
50630b57cec5SDimitry Andrictemplate <class _Tp>
50640b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
50650b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
50660b57cec5SDimitry Andricshared_ptr<_Tp>
50670b57cec5SDimitry Andricatomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
50680b57cec5SDimitry Andric{
50690b57cec5SDimitry Andric    return atomic_load(__p);
50700b57cec5SDimitry Andric}
50710b57cec5SDimitry Andric
50720b57cec5SDimitry Andrictemplate <class _Tp>
50730b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
50740b57cec5SDimitry Andricvoid
50750b57cec5SDimitry Andricatomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
50760b57cec5SDimitry Andric{
50770b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
50780b57cec5SDimitry Andric    __m.lock();
50790b57cec5SDimitry Andric    __p->swap(__r);
50800b57cec5SDimitry Andric    __m.unlock();
50810b57cec5SDimitry Andric}
50820b57cec5SDimitry Andric
50830b57cec5SDimitry Andrictemplate <class _Tp>
50840b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
50850b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
50860b57cec5SDimitry Andricvoid
50870b57cec5SDimitry Andricatomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
50880b57cec5SDimitry Andric{
50890b57cec5SDimitry Andric    atomic_store(__p, __r);
50900b57cec5SDimitry Andric}
50910b57cec5SDimitry Andric
50920b57cec5SDimitry Andrictemplate <class _Tp>
50930b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
50940b57cec5SDimitry Andricshared_ptr<_Tp>
50950b57cec5SDimitry Andricatomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
50960b57cec5SDimitry Andric{
50970b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
50980b57cec5SDimitry Andric    __m.lock();
50990b57cec5SDimitry Andric    __p->swap(__r);
51000b57cec5SDimitry Andric    __m.unlock();
51010b57cec5SDimitry Andric    return __r;
51020b57cec5SDimitry Andric}
51030b57cec5SDimitry Andric
51040b57cec5SDimitry Andrictemplate <class _Tp>
51050b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
51060b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
51070b57cec5SDimitry Andricshared_ptr<_Tp>
51080b57cec5SDimitry Andricatomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
51090b57cec5SDimitry Andric{
51100b57cec5SDimitry Andric    return atomic_exchange(__p, __r);
51110b57cec5SDimitry Andric}
51120b57cec5SDimitry Andric
51130b57cec5SDimitry Andrictemplate <class _Tp>
51140b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
51150b57cec5SDimitry Andricbool
51160b57cec5SDimitry Andricatomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
51170b57cec5SDimitry Andric{
51180b57cec5SDimitry Andric    shared_ptr<_Tp> __temp;
51190b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
51200b57cec5SDimitry Andric    __m.lock();
51210b57cec5SDimitry Andric    if (__p->__owner_equivalent(*__v))
51220b57cec5SDimitry Andric    {
51230b57cec5SDimitry Andric        _VSTD::swap(__temp, *__p);
51240b57cec5SDimitry Andric        *__p = __w;
51250b57cec5SDimitry Andric        __m.unlock();
51260b57cec5SDimitry Andric        return true;
51270b57cec5SDimitry Andric    }
51280b57cec5SDimitry Andric    _VSTD::swap(__temp, *__v);
51290b57cec5SDimitry Andric    *__v = *__p;
51300b57cec5SDimitry Andric    __m.unlock();
51310b57cec5SDimitry Andric    return false;
51320b57cec5SDimitry Andric}
51330b57cec5SDimitry Andric
51340b57cec5SDimitry Andrictemplate <class _Tp>
51350b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
51360b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
51370b57cec5SDimitry Andricbool
51380b57cec5SDimitry Andricatomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
51390b57cec5SDimitry Andric{
51400b57cec5SDimitry Andric    return atomic_compare_exchange_strong(__p, __v, __w);
51410b57cec5SDimitry Andric}
51420b57cec5SDimitry Andric
51430b57cec5SDimitry Andrictemplate <class _Tp>
51440b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
51450b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
51460b57cec5SDimitry Andricbool
51470b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
51480b57cec5SDimitry Andric                                        shared_ptr<_Tp> __w, memory_order, memory_order)
51490b57cec5SDimitry Andric{
51500b57cec5SDimitry Andric    return atomic_compare_exchange_strong(__p, __v, __w);
51510b57cec5SDimitry Andric}
51520b57cec5SDimitry Andric
51530b57cec5SDimitry Andrictemplate <class _Tp>
51540b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
51550b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
51560b57cec5SDimitry Andricbool
51570b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
51580b57cec5SDimitry Andric                                      shared_ptr<_Tp> __w, memory_order, memory_order)
51590b57cec5SDimitry Andric{
51600b57cec5SDimitry Andric    return atomic_compare_exchange_weak(__p, __v, __w);
51610b57cec5SDimitry Andric}
51620b57cec5SDimitry Andric
51630b57cec5SDimitry Andric#endif  // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
51640b57cec5SDimitry Andric
51650b57cec5SDimitry Andric//enum class
51660b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
51670b57cec5SDimitry Andric# ifndef _LIBCPP_CXX03_LANG
51680b57cec5SDimitry Andricenum class pointer_safety : unsigned char {
51690b57cec5SDimitry Andric  relaxed,
51700b57cec5SDimitry Andric  preferred,
51710b57cec5SDimitry Andric  strict
51720b57cec5SDimitry Andric};
51730b57cec5SDimitry Andric# endif
51740b57cec5SDimitry Andric#else
51750b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS pointer_safety
51760b57cec5SDimitry Andric{
51770b57cec5SDimitry Andric    enum __lx
51780b57cec5SDimitry Andric    {
51790b57cec5SDimitry Andric        relaxed,
51800b57cec5SDimitry Andric        preferred,
51810b57cec5SDimitry Andric        strict
51820b57cec5SDimitry Andric    };
51830b57cec5SDimitry Andric
51840b57cec5SDimitry Andric    __lx __v_;
51850b57cec5SDimitry Andric
51860b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51870b57cec5SDimitry Andric    pointer_safety() : __v_() {}
51880b57cec5SDimitry Andric
51890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51900b57cec5SDimitry Andric    pointer_safety(__lx __v) : __v_(__v) {}
51910b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51920b57cec5SDimitry Andric    operator int() const {return __v_;}
51930b57cec5SDimitry Andric};
51940b57cec5SDimitry Andric#endif
51950b57cec5SDimitry Andric
51960b57cec5SDimitry Andric#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
51970b57cec5SDimitry Andric    defined(_LIBCPP_BUILDING_LIBRARY)
51980b57cec5SDimitry Andric_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
51990b57cec5SDimitry Andric#else
52000b57cec5SDimitry Andric// This function is only offered in C++03 under ABI v1.
52010b57cec5SDimitry Andric# if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) || !defined(_LIBCPP_CXX03_LANG)
52020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
52030b57cec5SDimitry Andricpointer_safety get_pointer_safety() _NOEXCEPT {
52040b57cec5SDimitry Andric  return pointer_safety::relaxed;
52050b57cec5SDimitry Andric}
52060b57cec5SDimitry Andric# endif
52070b57cec5SDimitry Andric#endif
52080b57cec5SDimitry Andric
52090b57cec5SDimitry Andric
52100b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
52110b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
52120b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
52130b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
52140b57cec5SDimitry Andric
52150b57cec5SDimitry Andrictemplate <class _Tp>
52160b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
52170b57cec5SDimitry Andric_Tp*
52180b57cec5SDimitry Andricundeclare_reachable(_Tp* __p)
52190b57cec5SDimitry Andric{
52200b57cec5SDimitry Andric    return static_cast<_Tp*>(__undeclare_reachable(__p));
52210b57cec5SDimitry Andric}
52220b57cec5SDimitry Andric
52230b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
52240b57cec5SDimitry Andric
52250b57cec5SDimitry Andric// --- Helper for container swap --
52260b57cec5SDimitry Andrictemplate <typename _Alloc>
52270b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
52280b57cec5SDimitry Andricvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2)
52290b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
52300b57cec5SDimitry Andric    _NOEXCEPT
52310b57cec5SDimitry Andric#else
52320b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
52330b57cec5SDimitry Andric#endif
52340b57cec5SDimitry Andric{
52350b57cec5SDimitry Andric    __swap_allocator(__a1, __a2,
52360b57cec5SDimitry Andric      integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
52370b57cec5SDimitry Andric}
52380b57cec5SDimitry Andric
52390b57cec5SDimitry Andrictemplate <typename _Alloc>
52400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
52410b57cec5SDimitry Andricvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
52420b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
52430b57cec5SDimitry Andric    _NOEXCEPT
52440b57cec5SDimitry Andric#else
52450b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
52460b57cec5SDimitry Andric#endif
52470b57cec5SDimitry Andric{
52480b57cec5SDimitry Andric    using _VSTD::swap;
52490b57cec5SDimitry Andric    swap(__a1, __a2);
52500b57cec5SDimitry Andric}
52510b57cec5SDimitry Andric
52520b57cec5SDimitry Andrictemplate <typename _Alloc>
52530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
52540b57cec5SDimitry Andricvoid __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}
52550b57cec5SDimitry Andric
52560b57cec5SDimitry Andrictemplate <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
52570b57cec5SDimitry Andricstruct __noexcept_move_assign_container : public integral_constant<bool,
52580b57cec5SDimitry Andric    _Traits::propagate_on_container_move_assignment::value
52590b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
52600b57cec5SDimitry Andric        || _Traits::is_always_equal::value
52610b57cec5SDimitry Andric#else
52620b57cec5SDimitry Andric        && is_nothrow_move_assignable<_Alloc>::value
52630b57cec5SDimitry Andric#endif
52640b57cec5SDimitry Andric    > {};
52650b57cec5SDimitry Andric
52660b57cec5SDimitry Andric
52670b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_VARIADICS
52680b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
52690b57cec5SDimitry Andricstruct __temp_value {
52700b57cec5SDimitry Andric    typedef allocator_traits<_Alloc> _Traits;
52710b57cec5SDimitry Andric
52720b57cec5SDimitry Andric    typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
52730b57cec5SDimitry Andric    _Alloc &__a;
52740b57cec5SDimitry Andric
52750b57cec5SDimitry Andric    _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
52760b57cec5SDimitry Andric    _Tp &   get() { return *__addr(); }
52770b57cec5SDimitry Andric
52780b57cec5SDimitry Andric    template<class... _Args>
52790b57cec5SDimitry Andric    _LIBCPP_NO_CFI
52800b57cec5SDimitry Andric    __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
52810b57cec5SDimitry Andric      _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
52820b57cec5SDimitry Andric                         _VSTD::forward<_Args>(__args)...);
52830b57cec5SDimitry Andric    }
52840b57cec5SDimitry Andric
52850b57cec5SDimitry Andric    ~__temp_value() { _Traits::destroy(__a, __addr()); }
52860b57cec5SDimitry Andric    };
52870b57cec5SDimitry Andric#endif
52880b57cec5SDimitry Andric
52890b57cec5SDimitry Andrictemplate<typename _Alloc, typename = void, typename = void>
52900b57cec5SDimitry Andricstruct __is_allocator : false_type {};
52910b57cec5SDimitry Andric
52920b57cec5SDimitry Andrictemplate<typename _Alloc>
52930b57cec5SDimitry Andricstruct __is_allocator<_Alloc,
52940b57cec5SDimitry Andric       typename __void_t<typename _Alloc::value_type>::type,
52950b57cec5SDimitry Andric       typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type
52960b57cec5SDimitry Andric     >
52970b57cec5SDimitry Andric   : true_type {};
52980b57cec5SDimitry Andric
52990b57cec5SDimitry Andric// __builtin_new_allocator -- A non-templated helper for allocating and
53000b57cec5SDimitry Andric// deallocating memory using __builtin_operator_new and
53010b57cec5SDimitry Andric// __builtin_operator_delete. It should be used in preference to
53020b57cec5SDimitry Andric// `std::allocator<T>` to avoid additional instantiations.
53030b57cec5SDimitry Andricstruct __builtin_new_allocator {
53040b57cec5SDimitry Andric  struct __builtin_new_deleter {
53050b57cec5SDimitry Andric    typedef void* pointer_type;
53060b57cec5SDimitry Andric
53070b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
53080b57cec5SDimitry Andric        : __size_(__size), __align_(__align) {}
53090b57cec5SDimitry Andric
53100b57cec5SDimitry Andric    void operator()(void* p) const _NOEXCEPT {
53110b57cec5SDimitry Andric        std::__libcpp_deallocate(p, __size_, __align_);
53120b57cec5SDimitry Andric    }
53130b57cec5SDimitry Andric
53140b57cec5SDimitry Andric   private:
53150b57cec5SDimitry Andric    size_t __size_;
53160b57cec5SDimitry Andric    size_t __align_;
53170b57cec5SDimitry Andric  };
53180b57cec5SDimitry Andric
53190b57cec5SDimitry Andric  typedef unique_ptr<void, __builtin_new_deleter> __holder_t;
53200b57cec5SDimitry Andric
53210b57cec5SDimitry Andric  static __holder_t __allocate_bytes(size_t __s, size_t __align) {
53220b57cec5SDimitry Andric      return __holder_t(std::__libcpp_allocate(__s, __align),
53230b57cec5SDimitry Andric                     __builtin_new_deleter(__s, __align));
53240b57cec5SDimitry Andric  }
53250b57cec5SDimitry Andric
53260b57cec5SDimitry Andric  static void __deallocate_bytes(void* __p, size_t __s,
53270b57cec5SDimitry Andric                                 size_t __align) _NOEXCEPT {
53280b57cec5SDimitry Andric      std::__libcpp_deallocate(__p, __s, __align);
53290b57cec5SDimitry Andric  }
53300b57cec5SDimitry Andric
53310b57cec5SDimitry Andric  template <class _Tp>
53320b57cec5SDimitry Andric  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
53330b57cec5SDimitry Andric  static __holder_t __allocate_type(size_t __n) {
53340b57cec5SDimitry Andric      return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
53350b57cec5SDimitry Andric  }
53360b57cec5SDimitry Andric
53370b57cec5SDimitry Andric  template <class _Tp>
53380b57cec5SDimitry Andric  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
53390b57cec5SDimitry Andric  static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
53400b57cec5SDimitry Andric      __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
53410b57cec5SDimitry Andric  }
53420b57cec5SDimitry Andric};
53430b57cec5SDimitry Andric
53440b57cec5SDimitry Andric
53450b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
53460b57cec5SDimitry Andric
53470b57cec5SDimitry Andric_LIBCPP_POP_MACROS
53480b57cec5SDimitry Andric
5349e40139ffSDimitry Andric#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
5350e40139ffSDimitry Andric#   include <__pstl_memory>
5351e40139ffSDimitry Andric#endif
5352e40139ffSDimitry Andric
53530b57cec5SDimitry Andric#endif  // _LIBCPP_MEMORY
5354