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