xref: /freebsd/contrib/llvm-project/libcxx/include/memory (revision 23408297fbf3089f0388a8873b02fa75ab3f5bb9)
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
49e8d8bef9SDimitry Andrictemplate <class Ptr> constexpr 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
835ffd83dbSDimitry 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
86e8d8bef9SDimitry Andric    static pointer allocate(allocator_type& a, size_type n);                          // constexpr and [[nodiscard]] in C++20
87e8d8bef9SDimitry Andric    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20
880b57cec5SDimitry Andric
89e8d8bef9SDimitry Andric    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric    template <class T, class... Args>
92e8d8bef9SDimitry Andric    static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20
930b57cec5SDimitry Andric
940b57cec5SDimitry Andric    template <class T>
95e8d8bef9SDimitry Andric    static void destroy(allocator_type& a, T* p); // constexpr in C++20
960b57cec5SDimitry Andric
97e8d8bef9SDimitry Andric    static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20
98e8d8bef9SDimitry Andric    static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20
990b57cec5SDimitry Andric};
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andrictemplate <>
102*23408297SDimitry Andricclass allocator<void> // removed in C++20
1030b57cec5SDimitry Andric{
1040b57cec5SDimitry Andricpublic:
105*23408297SDimitry Andric    typedef void*                                 pointer;          // deprecated in C++17
106*23408297SDimitry Andric    typedef const void*                           const_pointer;    // deprecated in C++17
107*23408297SDimitry Andric    typedef void                                  value_type;       // deprecated in C++17
1080b57cec5SDimitry Andric
109*23408297SDimitry Andric    template <class _Up> struct rebind {typedef allocator<_Up> other;}; // deprecated in C++17
1100b57cec5SDimitry Andric};
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andrictemplate <class T>
1130b57cec5SDimitry Andricclass allocator
1140b57cec5SDimitry Andric{
1150b57cec5SDimitry Andricpublic:
116e8d8bef9SDimitry Andric    typedef size_t    size_type;
117e8d8bef9SDimitry Andric    typedef ptrdiff_t difference_type;
1185ffd83dbSDimitry Andric    typedef T*        pointer;                           // deprecated in C++17, removed in C++20
1195ffd83dbSDimitry Andric    typedef const T*  const_pointer;                     // deprecated in C++17, removed in C++20
1205ffd83dbSDimitry Andric    typedef typename add_lvalue_reference<T>::type
1215ffd83dbSDimitry Andric                      reference;                         // deprecated in C++17, removed in C++20
1225ffd83dbSDimitry Andric    typedef typename add_lvalue_reference<const T>::type
1235ffd83dbSDimitry Andric                      const_reference;                   // deprecated in C++17, removed in C++20
1245ffd83dbSDimitry Andric
1250b57cec5SDimitry Andric    typedef T         value_type;
1260b57cec5SDimitry Andric
1275ffd83dbSDimitry Andric    template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20
1285ffd83dbSDimitry Andric
1295ffd83dbSDimitry Andric    typedef true_type propagate_on_container_move_assignment;
1305ffd83dbSDimitry Andric    typedef true_type is_always_equal;
1310b57cec5SDimitry Andric
1320b57cec5SDimitry Andric    constexpr allocator() noexcept;                      // constexpr in C++20
1330b57cec5SDimitry Andric    constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
1340b57cec5SDimitry Andric    template <class U>
1350b57cec5SDimitry Andric      constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
136e8d8bef9SDimitry Andric    ~allocator();                                        // constexpr in C++20
1375ffd83dbSDimitry Andric    pointer address(reference x) const noexcept;             // deprecated in C++17, removed in C++20
1385ffd83dbSDimitry Andric    const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20
1395ffd83dbSDimitry Andric    T* allocate(size_t n, const void* hint);          // deprecated in C++17, removed in C++20
140e8d8bef9SDimitry Andric    T* allocate(size_t n);                              // constexpr in C++20
141e8d8bef9SDimitry Andric    void deallocate(T* p, size_t n) noexcept;           // constexpr in C++20
1425ffd83dbSDimitry Andric    size_type max_size() const noexcept;              // deprecated in C++17, removed in C++20
1430b57cec5SDimitry Andric    template<class U, class... Args>
1445ffd83dbSDimitry Andric        void construct(U* p, Args&&... args);         // deprecated in C++17, removed in C++20
1450b57cec5SDimitry Andric    template <class U>
1465ffd83dbSDimitry Andric        void destroy(U* p);                           // deprecated in C++17, removed in C++20
1470b57cec5SDimitry Andric};
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andrictemplate <class T, class U>
150e8d8bef9SDimitry Andricbool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andrictemplate <class T, class U>
153e8d8bef9SDimitry Andricbool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andrictemplate <class OutputIterator, class T>
1560b57cec5SDimitry Andricclass raw_storage_iterator
1570b57cec5SDimitry Andric    : public iterator<output_iterator_tag,
1580b57cec5SDimitry Andric                      T,                               // purposefully not C++03
1590b57cec5SDimitry Andric                      ptrdiff_t,                       // purposefully not C++03
1600b57cec5SDimitry Andric                      T*,                              // purposefully not C++03
1610b57cec5SDimitry Andric                      raw_storage_iterator&>           // purposefully not C++03
1620b57cec5SDimitry Andric{
1630b57cec5SDimitry Andricpublic:
1640b57cec5SDimitry Andric    explicit raw_storage_iterator(OutputIterator x);
1650b57cec5SDimitry Andric    raw_storage_iterator& operator*();
1660b57cec5SDimitry Andric    raw_storage_iterator& operator=(const T& element);
1670b57cec5SDimitry Andric    raw_storage_iterator& operator++();
1680b57cec5SDimitry Andric    raw_storage_iterator  operator++(int);
1690b57cec5SDimitry Andric};
1700b57cec5SDimitry Andric
1710b57cec5SDimitry Andrictemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
1720b57cec5SDimitry Andrictemplate <class T> void               return_temporary_buffer(T* p) noexcept;
1730b57cec5SDimitry Andric
1740b57cec5SDimitry Andrictemplate <class T> T* addressof(T& r) noexcept;
1750b57cec5SDimitry Andrictemplate <class T> T* addressof(const T&& r) noexcept = delete;
1760b57cec5SDimitry Andric
1770b57cec5SDimitry Andrictemplate <class InputIterator, class ForwardIterator>
1780b57cec5SDimitry AndricForwardIterator
1790b57cec5SDimitry Andricuninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andrictemplate <class InputIterator, class Size, class ForwardIterator>
1820b57cec5SDimitry AndricForwardIterator
1830b57cec5SDimitry Andricuninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andrictemplate <class ForwardIterator, class T>
1860b57cec5SDimitry Andricvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size, class T>
1890b57cec5SDimitry AndricForwardIterator
1900b57cec5SDimitry Andricuninitialized_fill_n(ForwardIterator first, Size n, const T& x);
1910b57cec5SDimitry Andric
192e8d8bef9SDimitry Andrictemplate <class T, class ...Args>
193e8d8bef9SDimitry Andricconstexpr T* construct_at(T* location, Args&& ...args); // since C++20
194e8d8bef9SDimitry Andric
1950b57cec5SDimitry Andrictemplate <class T>
196e8d8bef9SDimitry Andricvoid destroy_at(T* location); // constexpr in C++20
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andrictemplate <class ForwardIterator>
199e8d8bef9SDimitry Andricvoid destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20
2000b57cec5SDimitry Andric
2010b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size>
202e8d8bef9SDimitry AndricForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andrictemplate <class InputIterator, class ForwardIterator>
2050b57cec5SDimitry Andric ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
2060b57cec5SDimitry Andric
2070b57cec5SDimitry Andrictemplate <class InputIterator, class Size, class ForwardIterator>
2080b57cec5SDimitry Andric pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andrictemplate <class ForwardIterator>
2110b57cec5SDimitry Andric void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
2120b57cec5SDimitry Andric
2130b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size>
2140b57cec5SDimitry Andric ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
2150b57cec5SDimitry Andric
2160b57cec5SDimitry Andrictemplate <class ForwardIterator>
2170b57cec5SDimitry Andric void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
2180b57cec5SDimitry Andric
2190b57cec5SDimitry Andrictemplate <class ForwardIterator, class Size>
2200b57cec5SDimitry Andric ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
2210b57cec5SDimitry Andric
2220b57cec5SDimitry Andrictemplate <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andrictemplate<class X>
2250b57cec5SDimitry Andricclass auto_ptr                                  // deprecated in C++11, removed in C++17
2260b57cec5SDimitry Andric{
2270b57cec5SDimitry Andricpublic:
2280b57cec5SDimitry Andric    typedef X element_type;
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric    explicit auto_ptr(X* p =0) throw();
2310b57cec5SDimitry Andric    auto_ptr(auto_ptr&) throw();
2320b57cec5SDimitry Andric    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
2330b57cec5SDimitry Andric    auto_ptr& operator=(auto_ptr&) throw();
2340b57cec5SDimitry Andric    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
2350b57cec5SDimitry Andric    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
2360b57cec5SDimitry Andric    ~auto_ptr() throw();
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric    typename add_lvalue_reference<X>::type operator*() const throw();
2390b57cec5SDimitry Andric    X* operator->() const throw();
2400b57cec5SDimitry Andric    X* get() const throw();
2410b57cec5SDimitry Andric    X* release() throw();
2420b57cec5SDimitry Andric    void reset(X* p =0) throw();
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric    auto_ptr(auto_ptr_ref<X>) throw();
2450b57cec5SDimitry Andric    template<class Y> operator auto_ptr_ref<Y>() throw();
2460b57cec5SDimitry Andric    template<class Y> operator auto_ptr<Y>() throw();
2470b57cec5SDimitry Andric};
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andrictemplate <class T>
2500b57cec5SDimitry Andricstruct default_delete
2510b57cec5SDimitry Andric{
2520b57cec5SDimitry Andric    constexpr default_delete() noexcept = default;
2530b57cec5SDimitry Andric    template <class U> default_delete(const default_delete<U>&) noexcept;
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric    void operator()(T*) const noexcept;
2560b57cec5SDimitry Andric};
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andrictemplate <class T>
2590b57cec5SDimitry Andricstruct default_delete<T[]>
2600b57cec5SDimitry Andric{
2610b57cec5SDimitry Andric    constexpr default_delete() noexcept = default;
2620b57cec5SDimitry Andric    void operator()(T*) const noexcept;
2630b57cec5SDimitry Andric    template <class U> void operator()(U*) const = delete;
2640b57cec5SDimitry Andric};
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andrictemplate <class T, class D = default_delete<T>>
2670b57cec5SDimitry Andricclass unique_ptr
2680b57cec5SDimitry Andric{
2690b57cec5SDimitry Andricpublic:
2700b57cec5SDimitry Andric    typedef see below pointer;
2710b57cec5SDimitry Andric    typedef T element_type;
2720b57cec5SDimitry Andric    typedef D deleter_type;
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric    // constructors
2750b57cec5SDimitry Andric    constexpr unique_ptr() noexcept;
2760b57cec5SDimitry Andric    explicit unique_ptr(pointer p) noexcept;
2770b57cec5SDimitry Andric    unique_ptr(pointer p, see below d1) noexcept;
2780b57cec5SDimitry Andric    unique_ptr(pointer p, see below d2) noexcept;
2790b57cec5SDimitry Andric    unique_ptr(unique_ptr&& u) noexcept;
2800b57cec5SDimitry Andric    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
2810b57cec5SDimitry Andric    template <class U, class E>
2820b57cec5SDimitry Andric        unique_ptr(unique_ptr<U, E>&& u) noexcept;
2830b57cec5SDimitry Andric    template <class U>
2840b57cec5SDimitry Andric        unique_ptr(auto_ptr<U>&& u) noexcept;       // removed in C++17
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric    // destructor
2870b57cec5SDimitry Andric    ~unique_ptr();
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andric    // assignment
2900b57cec5SDimitry Andric    unique_ptr& operator=(unique_ptr&& u) noexcept;
2910b57cec5SDimitry Andric    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
2920b57cec5SDimitry Andric    unique_ptr& operator=(nullptr_t) noexcept;
2930b57cec5SDimitry Andric
2940b57cec5SDimitry Andric    // observers
2950b57cec5SDimitry Andric    typename add_lvalue_reference<T>::type operator*() const;
2960b57cec5SDimitry Andric    pointer operator->() const noexcept;
2970b57cec5SDimitry Andric    pointer get() const noexcept;
2980b57cec5SDimitry Andric    deleter_type& get_deleter() noexcept;
2990b57cec5SDimitry Andric    const deleter_type& get_deleter() const noexcept;
3000b57cec5SDimitry Andric    explicit operator bool() const noexcept;
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric    // modifiers
3030b57cec5SDimitry Andric    pointer release() noexcept;
3040b57cec5SDimitry Andric    void reset(pointer p = pointer()) noexcept;
3050b57cec5SDimitry Andric    void swap(unique_ptr& u) noexcept;
3060b57cec5SDimitry Andric};
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andrictemplate <class T, class D>
3090b57cec5SDimitry Andricclass unique_ptr<T[], D>
3100b57cec5SDimitry Andric{
3110b57cec5SDimitry Andricpublic:
3120b57cec5SDimitry Andric    typedef implementation-defined pointer;
3130b57cec5SDimitry Andric    typedef T element_type;
3140b57cec5SDimitry Andric    typedef D deleter_type;
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric    // constructors
3170b57cec5SDimitry Andric    constexpr unique_ptr() noexcept;
3180b57cec5SDimitry Andric    explicit unique_ptr(pointer p) noexcept;
3190b57cec5SDimitry Andric    unique_ptr(pointer p, see below d) noexcept;
3200b57cec5SDimitry Andric    unique_ptr(pointer p, see below d) noexcept;
3210b57cec5SDimitry Andric    unique_ptr(unique_ptr&& u) noexcept;
3220b57cec5SDimitry Andric    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andric    // destructor
3250b57cec5SDimitry Andric    ~unique_ptr();
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric    // assignment
3280b57cec5SDimitry Andric    unique_ptr& operator=(unique_ptr&& u) noexcept;
3290b57cec5SDimitry Andric    unique_ptr& operator=(nullptr_t) noexcept;
3300b57cec5SDimitry Andric
3310b57cec5SDimitry Andric    // observers
3320b57cec5SDimitry Andric    T& operator[](size_t i) const;
3330b57cec5SDimitry Andric    pointer get() const noexcept;
3340b57cec5SDimitry Andric    deleter_type& get_deleter() noexcept;
3350b57cec5SDimitry Andric    const deleter_type& get_deleter() const noexcept;
3360b57cec5SDimitry Andric    explicit operator bool() const noexcept;
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric    // modifiers
3390b57cec5SDimitry Andric    pointer release() noexcept;
3400b57cec5SDimitry Andric    void reset(pointer p = pointer()) noexcept;
3410b57cec5SDimitry Andric    void reset(nullptr_t) noexcept;
3420b57cec5SDimitry Andric  template <class U> void reset(U) = delete;
3430b57cec5SDimitry Andric    void swap(unique_ptr& u) noexcept;
3440b57cec5SDimitry Andric};
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andrictemplate <class T, class D>
3470b57cec5SDimitry Andric    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
3480b57cec5SDimitry Andric
3490b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3500b57cec5SDimitry Andric    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3510b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3520b57cec5SDimitry Andric    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3530b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3540b57cec5SDimitry Andric    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3550b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3560b57cec5SDimitry Andric    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3570b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3580b57cec5SDimitry Andric    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3590b57cec5SDimitry Andrictemplate <class T1, class D1, class T2, class D2>
3600b57cec5SDimitry Andric    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
3610b57cec5SDimitry Andric
3620b57cec5SDimitry Andrictemplate <class T, class D>
3630b57cec5SDimitry Andric    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3640b57cec5SDimitry Andrictemplate <class T, class D>
3650b57cec5SDimitry Andric    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3660b57cec5SDimitry Andrictemplate <class T, class D>
3670b57cec5SDimitry Andric    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
3680b57cec5SDimitry Andrictemplate <class T, class D>
3690b57cec5SDimitry Andric    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
3700b57cec5SDimitry Andric
3710b57cec5SDimitry Andrictemplate <class T, class D>
3720b57cec5SDimitry Andric    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
3730b57cec5SDimitry Andrictemplate <class T, class D>
3740b57cec5SDimitry Andric    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
3750b57cec5SDimitry Andrictemplate <class T, class D>
3760b57cec5SDimitry Andric    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
3770b57cec5SDimitry Andrictemplate <class T, class D>
3780b57cec5SDimitry Andric    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
3790b57cec5SDimitry Andrictemplate <class T, class D>
3800b57cec5SDimitry Andric    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
3810b57cec5SDimitry Andrictemplate <class T, class D>
3820b57cec5SDimitry Andric    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
3830b57cec5SDimitry Andrictemplate <class T, class D>
3840b57cec5SDimitry Andric    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
3850b57cec5SDimitry Andrictemplate <class T, class D>
3860b57cec5SDimitry Andric    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
3870b57cec5SDimitry Andric
3880b57cec5SDimitry Andricclass bad_weak_ptr
3890b57cec5SDimitry Andric    : public std::exception
3900b57cec5SDimitry Andric{
3910b57cec5SDimitry Andric    bad_weak_ptr() noexcept;
3920b57cec5SDimitry Andric};
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andrictemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
3950b57cec5SDimitry Andrictemplate<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
3960b57cec5SDimitry Andrictemplate<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andrictemplate<class E, class T, class Y, class D>
3990b57cec5SDimitry Andric    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andrictemplate<class T>
4020b57cec5SDimitry Andricclass shared_ptr
4030b57cec5SDimitry Andric{
4040b57cec5SDimitry Andricpublic:
4050b57cec5SDimitry Andric    typedef T element_type;
4060b57cec5SDimitry Andric    typedef weak_ptr<T> weak_type; // C++17
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andric    // constructors:
4090b57cec5SDimitry Andric    constexpr shared_ptr() noexcept;
4100b57cec5SDimitry Andric    template<class Y> explicit shared_ptr(Y* p);
4110b57cec5SDimitry Andric    template<class Y, class D> shared_ptr(Y* p, D d);
4120b57cec5SDimitry Andric    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
4130b57cec5SDimitry Andric    template <class D> shared_ptr(nullptr_t p, D d);
4140b57cec5SDimitry Andric    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
4150b57cec5SDimitry Andric    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
4160b57cec5SDimitry Andric    shared_ptr(const shared_ptr& r) noexcept;
4170b57cec5SDimitry Andric    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
4180b57cec5SDimitry Andric    shared_ptr(shared_ptr&& r) noexcept;
4190b57cec5SDimitry Andric    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
4200b57cec5SDimitry Andric    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
4210b57cec5SDimitry Andric    template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
4220b57cec5SDimitry Andric    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
4230b57cec5SDimitry Andric    shared_ptr(nullptr_t) : shared_ptr() { }
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andric    // destructor:
4260b57cec5SDimitry Andric    ~shared_ptr();
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andric    // assignment:
4290b57cec5SDimitry Andric    shared_ptr& operator=(const shared_ptr& r) noexcept;
4300b57cec5SDimitry Andric    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
4310b57cec5SDimitry Andric    shared_ptr& operator=(shared_ptr&& r) noexcept;
4320b57cec5SDimitry Andric    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
4330b57cec5SDimitry Andric    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
4340b57cec5SDimitry Andric    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
4350b57cec5SDimitry Andric
4360b57cec5SDimitry Andric    // modifiers:
4370b57cec5SDimitry Andric    void swap(shared_ptr& r) noexcept;
4380b57cec5SDimitry Andric    void reset() noexcept;
4390b57cec5SDimitry Andric    template<class Y> void reset(Y* p);
4400b57cec5SDimitry Andric    template<class Y, class D> void reset(Y* p, D d);
4410b57cec5SDimitry Andric    template<class Y, class D, class A> void reset(Y* p, D d, A a);
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andric    // observers:
4440b57cec5SDimitry Andric    T* get() const noexcept;
4450b57cec5SDimitry Andric    T& operator*() const noexcept;
4460b57cec5SDimitry Andric    T* operator->() const noexcept;
4470b57cec5SDimitry Andric    long use_count() const noexcept;
4480b57cec5SDimitry Andric    bool unique() const noexcept;
4490b57cec5SDimitry Andric    explicit operator bool() const noexcept;
4500b57cec5SDimitry Andric    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
4510b57cec5SDimitry Andric    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
4520b57cec5SDimitry Andric};
4530b57cec5SDimitry Andric
4545ffd83dbSDimitry Andrictemplate<class T>
4555ffd83dbSDimitry Andricshared_ptr(weak_ptr<T>) -> shared_ptr<T>;
4565ffd83dbSDimitry Andrictemplate<class T, class D>
4575ffd83dbSDimitry Andricshared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
4585ffd83dbSDimitry Andric
4590b57cec5SDimitry Andric// shared_ptr comparisons:
4600b57cec5SDimitry Andrictemplate<class T, class U>
4610b57cec5SDimitry Andric    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4620b57cec5SDimitry Andrictemplate<class T, class U>
4630b57cec5SDimitry Andric    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4640b57cec5SDimitry Andrictemplate<class T, class U>
4650b57cec5SDimitry Andric    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4660b57cec5SDimitry Andrictemplate<class T, class U>
4670b57cec5SDimitry Andric    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4680b57cec5SDimitry Andrictemplate<class T, class U>
4690b57cec5SDimitry Andric    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4700b57cec5SDimitry Andrictemplate<class T, class U>
4710b57cec5SDimitry Andric    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
4720b57cec5SDimitry Andric
4730b57cec5SDimitry Andrictemplate <class T>
4740b57cec5SDimitry Andric    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
4750b57cec5SDimitry Andrictemplate <class T>
4760b57cec5SDimitry Andric    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
4770b57cec5SDimitry Andrictemplate <class T>
4780b57cec5SDimitry Andric    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
4790b57cec5SDimitry Andrictemplate <class T>
4800b57cec5SDimitry Andric    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
4810b57cec5SDimitry Andrictemplate <class T>
4820b57cec5SDimitry Andric    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
4830b57cec5SDimitry Andrictemplate <class T>
4840b57cec5SDimitry Andricbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
4850b57cec5SDimitry Andrictemplate <class T>
4860b57cec5SDimitry Andric    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
4870b57cec5SDimitry Andrictemplate <class T>
4880b57cec5SDimitry Andric    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
4890b57cec5SDimitry Andrictemplate <class T>
4900b57cec5SDimitry Andric    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
4910b57cec5SDimitry Andrictemplate <class T>
4920b57cec5SDimitry Andric    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
4930b57cec5SDimitry Andrictemplate <class T>
4940b57cec5SDimitry Andric    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
4950b57cec5SDimitry Andrictemplate <class T>
4960b57cec5SDimitry Andric    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;
4970b57cec5SDimitry Andric
4980b57cec5SDimitry Andric// shared_ptr specialized algorithms:
4990b57cec5SDimitry Andrictemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
5000b57cec5SDimitry Andric
5010b57cec5SDimitry Andric// shared_ptr casts:
5020b57cec5SDimitry Andrictemplate<class T, class U>
5030b57cec5SDimitry Andric    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
5040b57cec5SDimitry Andrictemplate<class T, class U>
5050b57cec5SDimitry Andric    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
5060b57cec5SDimitry Andrictemplate<class T, class U>
5070b57cec5SDimitry Andric    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
5080b57cec5SDimitry Andric
5090b57cec5SDimitry Andric// shared_ptr I/O:
5100b57cec5SDimitry Andrictemplate<class E, class T, class Y>
5110b57cec5SDimitry Andric    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric// shared_ptr get_deleter:
5140b57cec5SDimitry Andrictemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
5150b57cec5SDimitry Andric
5160b57cec5SDimitry Andrictemplate<class T, class... Args>
5170b57cec5SDimitry Andric    shared_ptr<T> make_shared(Args&&... args);
5180b57cec5SDimitry Andrictemplate<class T, class A, class... Args>
5190b57cec5SDimitry Andric    shared_ptr<T> allocate_shared(const A& a, Args&&... args);
5200b57cec5SDimitry Andric
5210b57cec5SDimitry Andrictemplate<class T>
5220b57cec5SDimitry Andricclass weak_ptr
5230b57cec5SDimitry Andric{
5240b57cec5SDimitry Andricpublic:
5250b57cec5SDimitry Andric    typedef T element_type;
5260b57cec5SDimitry Andric
5270b57cec5SDimitry Andric    // constructors
5280b57cec5SDimitry Andric    constexpr weak_ptr() noexcept;
5290b57cec5SDimitry Andric    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
5300b57cec5SDimitry Andric    weak_ptr(weak_ptr const& r) noexcept;
5310b57cec5SDimitry Andric    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
5320b57cec5SDimitry Andric    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
5330b57cec5SDimitry Andric    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric    // destructor
5360b57cec5SDimitry Andric    ~weak_ptr();
5370b57cec5SDimitry Andric
5380b57cec5SDimitry Andric    // assignment
5390b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr const& r) noexcept;
5400b57cec5SDimitry Andric    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
5410b57cec5SDimitry Andric    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
5420b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
5430b57cec5SDimitry Andric    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andric    // modifiers
5460b57cec5SDimitry Andric    void swap(weak_ptr& r) noexcept;
5470b57cec5SDimitry Andric    void reset() noexcept;
5480b57cec5SDimitry Andric
5490b57cec5SDimitry Andric    // observers
5500b57cec5SDimitry Andric    long use_count() const noexcept;
5510b57cec5SDimitry Andric    bool expired() const noexcept;
5520b57cec5SDimitry Andric    shared_ptr<T> lock() const noexcept;
5530b57cec5SDimitry Andric    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
5540b57cec5SDimitry Andric    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
5550b57cec5SDimitry Andric};
5560b57cec5SDimitry Andric
5575ffd83dbSDimitry Andrictemplate<class T>
5585ffd83dbSDimitry Andricweak_ptr(shared_ptr<T>) -> weak_ptr<T>;
5595ffd83dbSDimitry Andric
5600b57cec5SDimitry Andric// weak_ptr specialized algorithms:
5610b57cec5SDimitry Andrictemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
5620b57cec5SDimitry Andric
5630b57cec5SDimitry Andric// class owner_less:
5640b57cec5SDimitry Andrictemplate<class T> struct owner_less;
5650b57cec5SDimitry Andric
5660b57cec5SDimitry Andrictemplate<class T>
5670b57cec5SDimitry Andricstruct owner_less<shared_ptr<T> >
5680b57cec5SDimitry Andric    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
5690b57cec5SDimitry Andric{
5700b57cec5SDimitry Andric    typedef bool result_type;
5710b57cec5SDimitry Andric    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
5720b57cec5SDimitry Andric    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
5730b57cec5SDimitry Andric    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
5740b57cec5SDimitry Andric};
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andrictemplate<class T>
5770b57cec5SDimitry Andricstruct owner_less<weak_ptr<T> >
5780b57cec5SDimitry Andric    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
5790b57cec5SDimitry Andric{
5800b57cec5SDimitry Andric    typedef bool result_type;
5810b57cec5SDimitry Andric    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
5820b57cec5SDimitry Andric    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
5830b57cec5SDimitry Andric    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
5840b57cec5SDimitry Andric};
5850b57cec5SDimitry Andric
5860b57cec5SDimitry Andrictemplate <>  // Added in C++14
5870b57cec5SDimitry Andricstruct owner_less<void>
5880b57cec5SDimitry Andric{
5890b57cec5SDimitry Andric    template <class _Tp, class _Up>
5900b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
5910b57cec5SDimitry Andric    template <class _Tp, class _Up>
5920b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
5930b57cec5SDimitry Andric    template <class _Tp, class _Up>
5940b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
5950b57cec5SDimitry Andric    template <class _Tp, class _Up>
5960b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
5970b57cec5SDimitry Andric
5980b57cec5SDimitry Andric    typedef void is_transparent;
5990b57cec5SDimitry Andric};
6000b57cec5SDimitry Andric
6010b57cec5SDimitry Andrictemplate<class T>
6020b57cec5SDimitry Andricclass enable_shared_from_this
6030b57cec5SDimitry Andric{
6040b57cec5SDimitry Andricprotected:
6050b57cec5SDimitry Andric    constexpr enable_shared_from_this() noexcept;
6060b57cec5SDimitry Andric    enable_shared_from_this(enable_shared_from_this const&) noexcept;
6070b57cec5SDimitry Andric    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
6080b57cec5SDimitry Andric    ~enable_shared_from_this();
6090b57cec5SDimitry Andricpublic:
6100b57cec5SDimitry Andric    shared_ptr<T> shared_from_this();
6110b57cec5SDimitry Andric    shared_ptr<T const> shared_from_this() const;
6120b57cec5SDimitry Andric};
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andrictemplate<class T>
6150b57cec5SDimitry Andric    bool atomic_is_lock_free(const shared_ptr<T>* p);
6160b57cec5SDimitry Andrictemplate<class T>
6170b57cec5SDimitry Andric    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
6180b57cec5SDimitry Andrictemplate<class T>
6190b57cec5SDimitry Andric    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
6200b57cec5SDimitry Andrictemplate<class T>
6210b57cec5SDimitry Andric    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
6220b57cec5SDimitry Andrictemplate<class T>
6230b57cec5SDimitry Andric    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
6240b57cec5SDimitry Andrictemplate<class T>
6250b57cec5SDimitry Andric    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
6260b57cec5SDimitry Andrictemplate<class T>
6270b57cec5SDimitry Andric    shared_ptr<T>
6280b57cec5SDimitry Andric    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
6290b57cec5SDimitry Andrictemplate<class T>
6300b57cec5SDimitry Andric    bool
6310b57cec5SDimitry Andric    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
6320b57cec5SDimitry Andrictemplate<class T>
6330b57cec5SDimitry Andric    bool
6340b57cec5SDimitry Andric    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
6350b57cec5SDimitry Andrictemplate<class T>
6360b57cec5SDimitry Andric    bool
6370b57cec5SDimitry Andric    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
6380b57cec5SDimitry Andric                                          shared_ptr<T> w, memory_order success,
6390b57cec5SDimitry Andric                                          memory_order failure);
6400b57cec5SDimitry Andrictemplate<class T>
6410b57cec5SDimitry Andric    bool
6420b57cec5SDimitry Andric    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
6430b57cec5SDimitry Andric                                            shared_ptr<T> w, memory_order success,
6440b57cec5SDimitry Andric                                            memory_order failure);
6450b57cec5SDimitry Andric// Hash support
6460b57cec5SDimitry Andrictemplate <class T> struct hash;
6470b57cec5SDimitry Andrictemplate <class T, class D> struct hash<unique_ptr<T, D> >;
6480b57cec5SDimitry Andrictemplate <class T> struct hash<shared_ptr<T> >;
6490b57cec5SDimitry Andric
6500b57cec5SDimitry Andrictemplate <class T, class Alloc>
6510b57cec5SDimitry Andric  inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
6520b57cec5SDimitry Andric
6530b57cec5SDimitry Andric// Pointer safety
6540b57cec5SDimitry Andricenum class pointer_safety { relaxed, preferred, strict };
6550b57cec5SDimitry Andricvoid declare_reachable(void *p);
6560b57cec5SDimitry Andrictemplate <class T> T *undeclare_reachable(T *p);
6570b57cec5SDimitry Andricvoid declare_no_pointers(char *p, size_t n);
6580b57cec5SDimitry Andricvoid undeclare_no_pointers(char *p, size_t n);
6590b57cec5SDimitry Andricpointer_safety get_pointer_safety() noexcept;
6600b57cec5SDimitry Andric
6610b57cec5SDimitry Andricvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space);
6620b57cec5SDimitry Andric
6630b57cec5SDimitry Andric}  // std
6640b57cec5SDimitry Andric
6650b57cec5SDimitry Andric*/
6660b57cec5SDimitry Andric
6670b57cec5SDimitry Andric#include <__config>
668e8d8bef9SDimitry Andric#include <__availability>
6690b57cec5SDimitry Andric#include <type_traits>
6700b57cec5SDimitry Andric#include <typeinfo>
6710b57cec5SDimitry Andric#include <cstddef>
6720b57cec5SDimitry Andric#include <cstdint>
6730b57cec5SDimitry Andric#include <new>
6740b57cec5SDimitry Andric#include <utility>
6750b57cec5SDimitry Andric#include <limits>
6760b57cec5SDimitry Andric#include <iterator>
6770b57cec5SDimitry Andric#include <__functional_base>
6780b57cec5SDimitry Andric#include <iosfwd>
6790b57cec5SDimitry Andric#include <tuple>
6800b57cec5SDimitry Andric#include <stdexcept>
6810b57cec5SDimitry Andric#include <cstring>
682e8d8bef9SDimitry Andric#include <__memory/allocator_traits.h>
683e8d8bef9SDimitry Andric#include <__memory/base.h>
684e8d8bef9SDimitry Andric#include <__memory/pointer_traits.h>
685e8d8bef9SDimitry Andric#include <__memory/utilities.h>
6860b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
6870b57cec5SDimitry Andric#  include <atomic>
6880b57cec5SDimitry Andric#endif
6890b57cec5SDimitry Andric#include <version>
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6920b57cec5SDimitry Andric#pragma GCC system_header
6930b57cec5SDimitry Andric#endif
6940b57cec5SDimitry Andric
6950b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
6960b57cec5SDimitry Andric#include <__undef_macros>
6970b57cec5SDimitry Andric
6980b57cec5SDimitry Andric
6990b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
7000b57cec5SDimitry Andric
7010b57cec5SDimitry Andrictemplate <class _ValueType>
7020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
7030b57cec5SDimitry Andric_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
7040b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS) && \
7050b57cec5SDimitry Andric    defined(__ATOMIC_RELAXED) &&        \
7060b57cec5SDimitry Andric    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
7070b57cec5SDimitry Andric    return __atomic_load_n(__value, __ATOMIC_RELAXED);
7080b57cec5SDimitry Andric#else
7090b57cec5SDimitry Andric    return *__value;
7100b57cec5SDimitry Andric#endif
7110b57cec5SDimitry Andric}
7120b57cec5SDimitry Andric
7130b57cec5SDimitry Andrictemplate <class _ValueType>
7140b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
7150b57cec5SDimitry Andric_ValueType __libcpp_acquire_load(_ValueType const* __value) {
7160b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_THREADS) && \
7170b57cec5SDimitry Andric    defined(__ATOMIC_ACQUIRE) &&        \
7180b57cec5SDimitry Andric    (__has_builtin(__atomic_load_n) || defined(_LIBCPP_COMPILER_GCC))
7190b57cec5SDimitry Andric    return __atomic_load_n(__value, __ATOMIC_ACQUIRE);
7200b57cec5SDimitry Andric#else
7210b57cec5SDimitry Andric    return *__value;
7220b57cec5SDimitry Andric#endif
7230b57cec5SDimitry Andric}
7240b57cec5SDimitry Andric
725480093f4SDimitry Andrictemplate <bool _UsePointerTraits> struct __to_address_helper;
726480093f4SDimitry Andric
727480093f4SDimitry Andrictemplate <> struct __to_address_helper<true> {
728480093f4SDimitry Andric    template <class _Pointer>
729e8d8bef9SDimitry Andric    using __return_type = decltype(pointer_traits<_Pointer>::to_address(_VSTD::declval<const _Pointer&>()));
730480093f4SDimitry Andric
731480093f4SDimitry Andric    template <class _Pointer>
732480093f4SDimitry Andric    _LIBCPP_CONSTEXPR
733480093f4SDimitry Andric    static __return_type<_Pointer>
734480093f4SDimitry Andric    __do_it(const _Pointer &__p) _NOEXCEPT { return pointer_traits<_Pointer>::to_address(__p); }
735480093f4SDimitry Andric};
736480093f4SDimitry Andric
737480093f4SDimitry Andrictemplate <class _Pointer, bool _Dummy = true>
738480093f4SDimitry Andricusing __choose_to_address = __to_address_helper<_IsValidExpansion<__to_address_helper<_Dummy>::template __return_type, _Pointer>::value>;
739480093f4SDimitry Andric
740480093f4SDimitry Andric
7410b57cec5SDimitry Andrictemplate <class _Tp>
7420b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
7430b57cec5SDimitry Andric_Tp*
744480093f4SDimitry Andric__to_address(_Tp* __p) _NOEXCEPT
7450b57cec5SDimitry Andric{
746480093f4SDimitry Andric    static_assert(!is_function<_Tp>::value, "_Tp is a function type");
7470b57cec5SDimitry Andric    return __p;
7480b57cec5SDimitry Andric}
7490b57cec5SDimitry Andric
7500b57cec5SDimitry Andrictemplate <class _Pointer>
751480093f4SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
752480093f4SDimitry Andrictypename __choose_to_address<_Pointer>::template __return_type<_Pointer>
753480093f4SDimitry Andric__to_address(const _Pointer& __p) _NOEXCEPT {
754480093f4SDimitry Andric  return __choose_to_address<_Pointer>::__do_it(__p);
7550b57cec5SDimitry Andric}
7560b57cec5SDimitry Andric
757480093f4SDimitry Andrictemplate <> struct __to_address_helper<false> {
758480093f4SDimitry Andric    template <class _Pointer>
759480093f4SDimitry Andric    using __return_type = typename pointer_traits<_Pointer>::element_type*;
7600b57cec5SDimitry Andric
761480093f4SDimitry Andric    template <class _Pointer>
762480093f4SDimitry Andric    _LIBCPP_CONSTEXPR
763480093f4SDimitry Andric    static __return_type<_Pointer>
764e8d8bef9SDimitry Andric    __do_it(const _Pointer &__p) _NOEXCEPT { return _VSTD::__to_address(__p.operator->()); }
765480093f4SDimitry Andric};
766480093f4SDimitry Andric
767480093f4SDimitry Andric
768480093f4SDimitry Andric#if _LIBCPP_STD_VER > 17
7690b57cec5SDimitry Andrictemplate <class _Tp>
7700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY constexpr
7710b57cec5SDimitry Andric_Tp*
7720b57cec5SDimitry Andricto_address(_Tp* __p) _NOEXCEPT
7730b57cec5SDimitry Andric{
7740b57cec5SDimitry Andric    static_assert(!is_function_v<_Tp>, "_Tp is a function type");
7750b57cec5SDimitry Andric    return __p;
7760b57cec5SDimitry Andric}
7770b57cec5SDimitry Andric
7780b57cec5SDimitry Andrictemplate <class _Pointer>
779e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY constexpr
7800b57cec5SDimitry Andricauto
7810b57cec5SDimitry Andricto_address(const _Pointer& __p) _NOEXCEPT
7820b57cec5SDimitry Andric{
783480093f4SDimitry Andric    return _VSTD::__to_address(__p);
7840b57cec5SDimitry Andric}
7850b57cec5SDimitry Andric#endif
7860b57cec5SDimitry Andric
787e8d8bef9SDimitry Andrictemplate <class _Tp> class allocator;
7880b57cec5SDimitry Andric
789*23408297SDimitry Andric#if _LIBCPP_STD_VER <= 17
790e8d8bef9SDimitry Andrictemplate <>
791*23408297SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<void>
7920b57cec5SDimitry Andric{
7930b57cec5SDimitry Andricpublic:
794*23408297SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef void*             pointer;
795*23408297SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       const_pointer;
796*23408297SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef void              value_type;
797e8d8bef9SDimitry Andric
798*23408297SDimitry Andric    template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
799e8d8bef9SDimitry Andric};
800e8d8bef9SDimitry Andric
801e8d8bef9SDimitry Andrictemplate <>
802*23408297SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<const void>
803e8d8bef9SDimitry Andric{
804e8d8bef9SDimitry Andricpublic:
805*23408297SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       pointer;
806*23408297SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void*       const_pointer;
807*23408297SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const void        value_type;
808e8d8bef9SDimitry Andric
809*23408297SDimitry Andric    template <class _Up> struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;};
810e8d8bef9SDimitry Andric};
811e8d8bef9SDimitry Andric#endif
812e8d8bef9SDimitry Andric
813e8d8bef9SDimitry Andric// allocator
814e8d8bef9SDimitry Andric
815e8d8bef9SDimitry Andrictemplate <class _Tp>
816e8d8bef9SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator
817e8d8bef9SDimitry Andric{
818e8d8bef9SDimitry Andricpublic:
819e8d8bef9SDimitry Andric    typedef size_t      size_type;
820e8d8bef9SDimitry Andric    typedef ptrdiff_t   difference_type;
821e8d8bef9SDimitry Andric    typedef _Tp         value_type;
822e8d8bef9SDimitry Andric    typedef true_type   propagate_on_container_move_assignment;
823e8d8bef9SDimitry Andric    typedef true_type   is_always_equal;
824e8d8bef9SDimitry Andric
825e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
826e8d8bef9SDimitry Andric    allocator() _NOEXCEPT { }
827e8d8bef9SDimitry Andric
828e8d8bef9SDimitry Andric    template <class _Up>
829e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
830e8d8bef9SDimitry Andric    allocator(const allocator<_Up>&) _NOEXCEPT { }
831e8d8bef9SDimitry Andric
832e8d8bef9SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
833e8d8bef9SDimitry Andric    _Tp* allocate(size_t __n) {
834e8d8bef9SDimitry Andric        if (__n > allocator_traits<allocator>::max_size(*this))
835e8d8bef9SDimitry Andric            __throw_length_error("allocator<T>::allocate(size_t n)"
836e8d8bef9SDimitry Andric                                 " 'n' exceeds maximum supported size");
837e8d8bef9SDimitry Andric        if (__libcpp_is_constant_evaluated()) {
838e8d8bef9SDimitry Andric            return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
839e8d8bef9SDimitry Andric        } else {
840e8d8bef9SDimitry Andric            return static_cast<_Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
841e8d8bef9SDimitry Andric        }
842e8d8bef9SDimitry Andric    }
843e8d8bef9SDimitry Andric
844e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
845e8d8bef9SDimitry Andric    void deallocate(_Tp* __p, size_t __n) _NOEXCEPT {
846e8d8bef9SDimitry Andric        if (__libcpp_is_constant_evaluated()) {
847e8d8bef9SDimitry Andric            ::operator delete(__p);
848e8d8bef9SDimitry Andric        } else {
849e8d8bef9SDimitry Andric            _VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
850e8d8bef9SDimitry Andric        }
851e8d8bef9SDimitry Andric    }
852e8d8bef9SDimitry Andric
853e8d8bef9SDimitry Andric    // C++20 Removed members
854e8d8bef9SDimitry Andric#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
855e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp*       pointer;
856e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
857e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef _Tp&       reference;
858e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
859e8d8bef9SDimitry Andric
860e8d8bef9SDimitry Andric    template <class _Up>
861e8d8bef9SDimitry Andric    struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
862e8d8bef9SDimitry Andric        typedef allocator<_Up> other;
863e8d8bef9SDimitry Andric    };
864e8d8bef9SDimitry Andric
865e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
866e8d8bef9SDimitry Andric    pointer address(reference __x) const _NOEXCEPT {
867e8d8bef9SDimitry Andric        return _VSTD::addressof(__x);
868e8d8bef9SDimitry Andric    }
869e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
870e8d8bef9SDimitry Andric    const_pointer address(const_reference __x) const _NOEXCEPT {
871e8d8bef9SDimitry Andric        return _VSTD::addressof(__x);
872e8d8bef9SDimitry Andric    }
873e8d8bef9SDimitry Andric
874e8d8bef9SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
875e8d8bef9SDimitry Andric    _Tp* allocate(size_t __n, const void*) {
876e8d8bef9SDimitry Andric        return allocate(__n);
877e8d8bef9SDimitry Andric    }
878e8d8bef9SDimitry Andric
879e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
880e8d8bef9SDimitry Andric        return size_type(~0) / sizeof(_Tp);
881e8d8bef9SDimitry Andric    }
882e8d8bef9SDimitry Andric
883e8d8bef9SDimitry Andric    template <class _Up, class... _Args>
884e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
885e8d8bef9SDimitry Andric    void construct(_Up* __p, _Args&&... __args) {
886e8d8bef9SDimitry Andric        ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
887e8d8bef9SDimitry Andric    }
888e8d8bef9SDimitry Andric
889e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
890e8d8bef9SDimitry Andric    void destroy(pointer __p) {
891e8d8bef9SDimitry Andric        __p->~_Tp();
892e8d8bef9SDimitry Andric    }
893e8d8bef9SDimitry Andric#endif
894e8d8bef9SDimitry Andric};
895e8d8bef9SDimitry Andric
896e8d8bef9SDimitry Andrictemplate <class _Tp>
897e8d8bef9SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<const _Tp>
898e8d8bef9SDimitry Andric{
899e8d8bef9SDimitry Andricpublic:
900e8d8bef9SDimitry Andric    typedef size_t      size_type;
901e8d8bef9SDimitry Andric    typedef ptrdiff_t   difference_type;
902e8d8bef9SDimitry Andric    typedef const _Tp   value_type;
903e8d8bef9SDimitry Andric    typedef true_type   propagate_on_container_move_assignment;
904e8d8bef9SDimitry Andric    typedef true_type   is_always_equal;
905e8d8bef9SDimitry Andric
906e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
907e8d8bef9SDimitry Andric    allocator() _NOEXCEPT { }
908e8d8bef9SDimitry Andric
909e8d8bef9SDimitry Andric    template <class _Up>
910e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
911e8d8bef9SDimitry Andric    allocator(const allocator<_Up>&) _NOEXCEPT { }
912e8d8bef9SDimitry Andric
913e8d8bef9SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
914e8d8bef9SDimitry Andric    const _Tp* allocate(size_t __n) {
915e8d8bef9SDimitry Andric        if (__n > allocator_traits<allocator>::max_size(*this))
916e8d8bef9SDimitry Andric            __throw_length_error("allocator<const T>::allocate(size_t n)"
917e8d8bef9SDimitry Andric                                 " 'n' exceeds maximum supported size");
918e8d8bef9SDimitry Andric        if (__libcpp_is_constant_evaluated()) {
919e8d8bef9SDimitry Andric            return static_cast<const _Tp*>(::operator new(__n * sizeof(_Tp)));
920e8d8bef9SDimitry Andric        } else {
921e8d8bef9SDimitry Andric            return static_cast<const _Tp*>(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)));
922e8d8bef9SDimitry Andric        }
923e8d8bef9SDimitry Andric    }
924e8d8bef9SDimitry Andric
925e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
926e8d8bef9SDimitry Andric    void deallocate(const _Tp* __p, size_t __n) {
927e8d8bef9SDimitry Andric        if (__libcpp_is_constant_evaluated()) {
928e8d8bef9SDimitry Andric            ::operator delete(const_cast<_Tp*>(__p));
929e8d8bef9SDimitry Andric        } else {
930e8d8bef9SDimitry Andric            _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
931e8d8bef9SDimitry Andric        }
932e8d8bef9SDimitry Andric    }
933e8d8bef9SDimitry Andric
934e8d8bef9SDimitry Andric    // C++20 Removed members
935e8d8bef9SDimitry Andric#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS)
936e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer;
937e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer;
938e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference;
939e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference;
940e8d8bef9SDimitry Andric
941e8d8bef9SDimitry Andric    template <class _Up>
942e8d8bef9SDimitry Andric    struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {
943e8d8bef9SDimitry Andric        typedef allocator<_Up> other;
944e8d8bef9SDimitry Andric    };
945e8d8bef9SDimitry Andric
946e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
947e8d8bef9SDimitry Andric    const_pointer address(const_reference __x) const _NOEXCEPT {
948e8d8bef9SDimitry Andric        return _VSTD::addressof(__x);
949e8d8bef9SDimitry Andric    }
950e8d8bef9SDimitry Andric
951e8d8bef9SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17
952e8d8bef9SDimitry Andric    const _Tp* allocate(size_t __n, const void*) {
953e8d8bef9SDimitry Andric        return allocate(__n);
954e8d8bef9SDimitry Andric    }
955e8d8bef9SDimitry Andric
956e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT {
957e8d8bef9SDimitry Andric        return size_type(~0) / sizeof(_Tp);
958e8d8bef9SDimitry Andric    }
959e8d8bef9SDimitry Andric
960e8d8bef9SDimitry Andric    template <class _Up, class... _Args>
961e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
962e8d8bef9SDimitry Andric    void construct(_Up* __p, _Args&&... __args) {
963e8d8bef9SDimitry Andric        ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
964e8d8bef9SDimitry Andric    }
965e8d8bef9SDimitry Andric
966e8d8bef9SDimitry Andric    _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
967e8d8bef9SDimitry Andric    void destroy(pointer __p) {
968e8d8bef9SDimitry Andric        __p->~_Tp();
969e8d8bef9SDimitry Andric    }
970e8d8bef9SDimitry Andric#endif
9710b57cec5SDimitry Andric};
9720b57cec5SDimitry Andric
9730b57cec5SDimitry Andrictemplate <class _Tp, class _Up>
974e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
975e8d8bef9SDimitry Andricbool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;}
9760b57cec5SDimitry Andric
977e8d8bef9SDimitry Andrictemplate <class _Tp, class _Up>
978e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
979e8d8bef9SDimitry Andricbool operator!=(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return false;}
9800b57cec5SDimitry Andric
9810b57cec5SDimitry Andrictemplate <class _Alloc, class _Ptr>
9820b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
983e8d8bef9SDimitry Andricvoid __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) {
984e8d8bef9SDimitry Andric    static_assert(__is_cpp17_move_insertable<_Alloc>::value,
985e8d8bef9SDimitry Andric        "The specified type does not meet the requirements of Cpp17MoveInsertable");
986e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _Traits;
987e8d8bef9SDimitry Andric    for (; __begin1 != __end1; ++__begin1, (void)++__begin2) {
988e8d8bef9SDimitry Andric        _Traits::construct(__a, _VSTD::__to_address(__begin2),
989e40139ffSDimitry Andric#ifdef _LIBCPP_NO_EXCEPTIONS
990e40139ffSDimitry Andric            _VSTD::move(*__begin1)
991e40139ffSDimitry Andric#else
992e40139ffSDimitry Andric            _VSTD::move_if_noexcept(*__begin1)
993e40139ffSDimitry Andric#endif
994e40139ffSDimitry Andric        );
9950b57cec5SDimitry Andric    }
996e8d8bef9SDimitry Andric}
9970b57cec5SDimitry Andric
998e8d8bef9SDimitry Andrictemplate <class _Alloc, class _Tp, typename enable_if<
999e8d8bef9SDimitry Andric    (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) &&
1000e8d8bef9SDimitry Andric    is_trivially_move_constructible<_Tp>::value
1001e8d8bef9SDimitry Andric>::type>
10020b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1003e8d8bef9SDimitry Andricvoid __construct_forward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) {
10040b57cec5SDimitry Andric    ptrdiff_t _Np = __end1 - __begin1;
1005e8d8bef9SDimitry Andric    if (_Np > 0) {
10060b57cec5SDimitry Andric        _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
10070b57cec5SDimitry Andric        __begin2 += _Np;
10080b57cec5SDimitry Andric    }
10090b57cec5SDimitry Andric}
10100b57cec5SDimitry Andric
1011e8d8bef9SDimitry Andrictemplate <class _Alloc, class _Iter, class _Ptr>
10120b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1013e8d8bef9SDimitry Andricvoid __construct_range_forward(_Alloc& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) {
1014e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _Traits;
1015e8d8bef9SDimitry Andric    for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) {
1016e8d8bef9SDimitry Andric        _Traits::construct(__a, _VSTD::__to_address(__begin2), *__begin1);
1017e8d8bef9SDimitry Andric    }
10180b57cec5SDimitry Andric}
10190b57cec5SDimitry Andric
1020e8d8bef9SDimitry Andrictemplate <class _Alloc, class _Source, class _Dest,
1021e8d8bef9SDimitry Andric          class _RawSource = typename remove_const<_Source>::type,
1022e8d8bef9SDimitry Andric          class _RawDest = typename remove_const<_Dest>::type,
1023e8d8bef9SDimitry Andric          class =
1024e8d8bef9SDimitry Andric    typename enable_if<
1025e8d8bef9SDimitry Andric        is_trivially_copy_constructible<_Dest>::value &&
1026e8d8bef9SDimitry Andric        is_same<_RawSource, _RawDest>::value &&
1027e8d8bef9SDimitry Andric        (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value)
1028e8d8bef9SDimitry Andric    >::type>
10290b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1030e8d8bef9SDimitry Andricvoid __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) {
10310b57cec5SDimitry Andric    ptrdiff_t _Np = __end1 - __begin1;
1032e8d8bef9SDimitry Andric    if (_Np > 0) {
1033e8d8bef9SDimitry Andric        _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest));
10340b57cec5SDimitry Andric        __begin2 += _Np;
10350b57cec5SDimitry Andric    }
10360b57cec5SDimitry Andric}
10370b57cec5SDimitry Andric
1038e8d8bef9SDimitry Andrictemplate <class _Alloc, class _Ptr>
10390b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1040e8d8bef9SDimitry Andricvoid __construct_backward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) {
1041e8d8bef9SDimitry Andric    static_assert(__is_cpp17_move_insertable<_Alloc>::value,
1042e40139ffSDimitry Andric        "The specified type does not meet the requirements of Cpp17MoveInsertable");
1043e8d8bef9SDimitry Andric    typedef allocator_traits<_Alloc> _Traits;
1044e8d8bef9SDimitry Andric    while (__end1 != __begin1) {
1045e8d8bef9SDimitry Andric        _Traits::construct(__a, _VSTD::__to_address(__end2 - 1),
1046e40139ffSDimitry Andric#ifdef _LIBCPP_NO_EXCEPTIONS
1047e40139ffSDimitry Andric            _VSTD::move(*--__end1)
1048e40139ffSDimitry Andric#else
1049e40139ffSDimitry Andric            _VSTD::move_if_noexcept(*--__end1)
1050e40139ffSDimitry Andric#endif
1051e40139ffSDimitry Andric        );
10520b57cec5SDimitry Andric        --__end2;
10530b57cec5SDimitry Andric    }
10540b57cec5SDimitry Andric}
10550b57cec5SDimitry Andric
1056e8d8bef9SDimitry Andrictemplate <class _Alloc, class _Tp, class = typename enable_if<
1057e8d8bef9SDimitry Andric    (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) &&
1058e8d8bef9SDimitry Andric    is_trivially_move_constructible<_Tp>::value
1059e8d8bef9SDimitry Andric>::type>
10600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1061e8d8bef9SDimitry Andricvoid __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) {
10620b57cec5SDimitry Andric    ptrdiff_t _Np = __end1 - __begin1;
10630b57cec5SDimitry Andric    __end2 -= _Np;
10640b57cec5SDimitry Andric    if (_Np > 0)
10650b57cec5SDimitry Andric        _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
10660b57cec5SDimitry Andric}
10670b57cec5SDimitry Andric
10680b57cec5SDimitry Andrictemplate <class _OutputIterator, class _Tp>
10690b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS raw_storage_iterator
10700b57cec5SDimitry Andric    : public iterator<output_iterator_tag,
10710b57cec5SDimitry Andric                      _Tp,                                         // purposefully not C++03
10720b57cec5SDimitry Andric                      ptrdiff_t,                                   // purposefully not C++03
10730b57cec5SDimitry Andric                      _Tp*,                                        // purposefully not C++03
10740b57cec5SDimitry Andric                      raw_storage_iterator<_OutputIterator, _Tp>&> // purposefully not C++03
10750b57cec5SDimitry Andric{
10760b57cec5SDimitry Andricprivate:
10770b57cec5SDimitry Andric    _OutputIterator __x_;
10780b57cec5SDimitry Andricpublic:
10790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit raw_storage_iterator(_OutputIterator __x) : __x_(__x) {}
10800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator*() {return *this;}
10810b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(const _Tp& __element)
1082e8d8bef9SDimitry Andric        {::new ((void*)_VSTD::addressof(*__x_)) _Tp(__element); return *this;}
10830b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
10840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator=(_Tp&& __element)
1085e8d8bef9SDimitry Andric        {::new ((void*)_VSTD::addressof(*__x_)) _Tp(_VSTD::move(__element)); return *this;}
10860b57cec5SDimitry Andric#endif
10870b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator& operator++() {++__x_; return *this;}
10880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY raw_storage_iterator  operator++(int)
10890b57cec5SDimitry Andric        {raw_storage_iterator __t(*this); ++__x_; return __t;}
10900b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
10910b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _OutputIterator base() const { return __x_; }
10920b57cec5SDimitry Andric#endif
10930b57cec5SDimitry Andric};
10940b57cec5SDimitry Andric
10950b57cec5SDimitry Andrictemplate <class _Tp>
10960b57cec5SDimitry Andric_LIBCPP_NODISCARD_EXT _LIBCPP_NO_CFI
10970b57cec5SDimitry Andricpair<_Tp*, ptrdiff_t>
10980b57cec5SDimitry Andricget_temporary_buffer(ptrdiff_t __n) _NOEXCEPT
10990b57cec5SDimitry Andric{
11000b57cec5SDimitry Andric    pair<_Tp*, ptrdiff_t> __r(0, 0);
11010b57cec5SDimitry Andric    const ptrdiff_t __m = (~ptrdiff_t(0) ^
11020b57cec5SDimitry Andric                           ptrdiff_t(ptrdiff_t(1) << (sizeof(ptrdiff_t) * __CHAR_BIT__ - 1)))
11030b57cec5SDimitry Andric                           / sizeof(_Tp);
11040b57cec5SDimitry Andric    if (__n > __m)
11050b57cec5SDimitry Andric        __n = __m;
11060b57cec5SDimitry Andric    while (__n > 0)
11070b57cec5SDimitry Andric    {
11080b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION)
11090b57cec5SDimitry Andric    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
11100b57cec5SDimitry Andric        {
1111e8d8bef9SDimitry Andric            align_val_t __al =
1112e8d8bef9SDimitry Andric                align_val_t(alignment_of<_Tp>::value);
11130b57cec5SDimitry Andric            __r.first = static_cast<_Tp*>(::operator new(
11140b57cec5SDimitry Andric                __n * sizeof(_Tp), __al, nothrow));
11150b57cec5SDimitry Andric        } else {
11160b57cec5SDimitry Andric            __r.first = static_cast<_Tp*>(::operator new(
11170b57cec5SDimitry Andric                __n * sizeof(_Tp), nothrow));
11180b57cec5SDimitry Andric        }
11190b57cec5SDimitry Andric#else
11200b57cec5SDimitry Andric    if (__is_overaligned_for_new(_LIBCPP_ALIGNOF(_Tp)))
11210b57cec5SDimitry Andric        {
11220b57cec5SDimitry Andric            // Since aligned operator new is unavailable, return an empty
11230b57cec5SDimitry Andric            // buffer rather than one with invalid alignment.
11240b57cec5SDimitry Andric            return __r;
11250b57cec5SDimitry Andric        }
11260b57cec5SDimitry Andric
11270b57cec5SDimitry Andric        __r.first = static_cast<_Tp*>(::operator new(__n * sizeof(_Tp), nothrow));
11280b57cec5SDimitry Andric#endif
11290b57cec5SDimitry Andric
11300b57cec5SDimitry Andric        if (__r.first)
11310b57cec5SDimitry Andric        {
11320b57cec5SDimitry Andric            __r.second = __n;
11330b57cec5SDimitry Andric            break;
11340b57cec5SDimitry Andric        }
11350b57cec5SDimitry Andric        __n /= 2;
11360b57cec5SDimitry Andric    }
11370b57cec5SDimitry Andric    return __r;
11380b57cec5SDimitry Andric}
11390b57cec5SDimitry Andric
11400b57cec5SDimitry Andrictemplate <class _Tp>
11410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
11420b57cec5SDimitry Andricvoid return_temporary_buffer(_Tp* __p) _NOEXCEPT
11430b57cec5SDimitry Andric{
11440b57cec5SDimitry Andric  _VSTD::__libcpp_deallocate_unsized((void*)__p, _LIBCPP_ALIGNOF(_Tp));
11450b57cec5SDimitry Andric}
11460b57cec5SDimitry Andric
11470b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
11480b57cec5SDimitry Andrictemplate <class _Tp>
11490b57cec5SDimitry Andricstruct _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr_ref
11500b57cec5SDimitry Andric{
11510b57cec5SDimitry Andric    _Tp* __ptr_;
11520b57cec5SDimitry Andric};
11530b57cec5SDimitry Andric
11540b57cec5SDimitry Andrictemplate<class _Tp>
11550b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr
11560b57cec5SDimitry Andric{
11570b57cec5SDimitry Andricprivate:
11580b57cec5SDimitry Andric    _Tp* __ptr_;
11590b57cec5SDimitry Andricpublic:
11600b57cec5SDimitry Andric    typedef _Tp element_type;
11610b57cec5SDimitry Andric
11629ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit auto_ptr(_Tp* __p = 0) _NOEXCEPT : __ptr_(__p) {}
11639ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr& __p) _NOEXCEPT : __ptr_(__p.release()) {}
11649ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr<_Up>& __p) _NOEXCEPT
11650b57cec5SDimitry Andric        : __ptr_(__p.release()) {}
11669ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr& __p) _NOEXCEPT
11670b57cec5SDimitry Andric        {reset(__p.release()); return *this;}
11689ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr<_Up>& __p) _NOEXCEPT
11690b57cec5SDimitry Andric        {reset(__p.release()); return *this;}
11709ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr& operator=(auto_ptr_ref<_Tp> __p) _NOEXCEPT
11710b57cec5SDimitry Andric        {reset(__p.__ptr_); return *this;}
11729ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY ~auto_ptr() _NOEXCEPT {delete __ptr_;}
11730b57cec5SDimitry Andric
11749ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp& operator*() const _NOEXCEPT
11750b57cec5SDimitry Andric        {return *__ptr_;}
11769ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* operator->() const _NOEXCEPT {return __ptr_;}
11779ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* get() const _NOEXCEPT {return __ptr_;}
11789ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY _Tp* release() _NOEXCEPT
11790b57cec5SDimitry Andric    {
11800b57cec5SDimitry Andric        _Tp* __t = __ptr_;
1181e8d8bef9SDimitry Andric        __ptr_ = nullptr;
11820b57cec5SDimitry Andric        return __t;
11830b57cec5SDimitry Andric    }
11849ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY void reset(_Tp* __p = 0) _NOEXCEPT
11850b57cec5SDimitry Andric    {
11860b57cec5SDimitry Andric        if (__ptr_ != __p)
11870b57cec5SDimitry Andric            delete __ptr_;
11880b57cec5SDimitry Andric        __ptr_ = __p;
11890b57cec5SDimitry Andric    }
11900b57cec5SDimitry Andric
11919ec406dcSDimitry Andric    _LIBCPP_INLINE_VISIBILITY auto_ptr(auto_ptr_ref<_Tp> __p) _NOEXCEPT : __ptr_(__p.__ptr_) {}
11929ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr_ref<_Up>() _NOEXCEPT
11930b57cec5SDimitry Andric        {auto_ptr_ref<_Up> __t; __t.__ptr_ = release(); return __t;}
11949ec406dcSDimitry Andric    template<class _Up> _LIBCPP_INLINE_VISIBILITY operator auto_ptr<_Up>() _NOEXCEPT
11950b57cec5SDimitry Andric        {return auto_ptr<_Up>(release());}
11960b57cec5SDimitry Andric};
11970b57cec5SDimitry Andric
11980b57cec5SDimitry Andrictemplate <>
11990b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX11 auto_ptr<void>
12000b57cec5SDimitry Andric{
12010b57cec5SDimitry Andricpublic:
12020b57cec5SDimitry Andric    typedef void element_type;
12030b57cec5SDimitry Andric};
12040b57cec5SDimitry Andric#endif
12050b57cec5SDimitry Andric
1206480093f4SDimitry Andric// Tag used to default initialize one or both of the pair's elements.
1207480093f4SDimitry Andricstruct __default_init_tag {};
1208480093f4SDimitry Andricstruct __value_init_tag {};
1209480093f4SDimitry Andric
12100b57cec5SDimitry Andrictemplate <class _Tp, int _Idx,
12110b57cec5SDimitry Andric          bool _CanBeEmptyBase =
12120b57cec5SDimitry Andric              is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>
12130b57cec5SDimitry Andricstruct __compressed_pair_elem {
12140b57cec5SDimitry Andric  typedef _Tp _ParamT;
12150b57cec5SDimitry Andric  typedef _Tp& reference;
12160b57cec5SDimitry Andric  typedef const _Tp& const_reference;
12170b57cec5SDimitry Andric
1218480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1219480093f4SDimitry Andric  __compressed_pair_elem(__default_init_tag) {}
1220480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1221480093f4SDimitry Andric  __compressed_pair_elem(__value_init_tag) : __value_() {}
12220b57cec5SDimitry Andric
12230b57cec5SDimitry Andric  template <class _Up, class = typename enable_if<
12240b57cec5SDimitry Andric      !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
12250b57cec5SDimitry Andric  >::type>
12260b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1227480093f4SDimitry Andric  _LIBCPP_CONSTEXPR explicit
12280b57cec5SDimitry Andric  __compressed_pair_elem(_Up&& __u)
12290b57cec5SDimitry Andric      : __value_(_VSTD::forward<_Up>(__u))
12300b57cec5SDimitry Andric    {
12310b57cec5SDimitry Andric    }
12320b57cec5SDimitry Andric
1233480093f4SDimitry Andric
1234480093f4SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
12350b57cec5SDimitry Andric  template <class... _Args, size_t... _Indexes>
12360b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12370b57cec5SDimitry Andric  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
12380b57cec5SDimitry Andric                         __tuple_indices<_Indexes...>)
12390b57cec5SDimitry Andric      : __value_(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
12400b57cec5SDimitry Andric#endif
12410b57cec5SDimitry Andric
1242480093f4SDimitry Andric
12430b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return __value_; }
12440b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12450b57cec5SDimitry Andric  const_reference __get() const _NOEXCEPT { return __value_; }
12460b57cec5SDimitry Andric
12470b57cec5SDimitry Andricprivate:
12480b57cec5SDimitry Andric  _Tp __value_;
12490b57cec5SDimitry Andric};
12500b57cec5SDimitry Andric
12510b57cec5SDimitry Andrictemplate <class _Tp, int _Idx>
12520b57cec5SDimitry Andricstruct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {
12530b57cec5SDimitry Andric  typedef _Tp _ParamT;
12540b57cec5SDimitry Andric  typedef _Tp& reference;
12550b57cec5SDimitry Andric  typedef const _Tp& const_reference;
12560b57cec5SDimitry Andric  typedef _Tp __value_type;
12570b57cec5SDimitry Andric
1258480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
1259480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1260480093f4SDimitry Andric  __compressed_pair_elem(__default_init_tag) {}
1261480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1262480093f4SDimitry Andric  __compressed_pair_elem(__value_init_tag) : __value_type() {}
12630b57cec5SDimitry Andric
12640b57cec5SDimitry Andric  template <class _Up, class = typename enable_if<
12650b57cec5SDimitry Andric        !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
12660b57cec5SDimitry Andric  >::type>
12670b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1268480093f4SDimitry Andric  _LIBCPP_CONSTEXPR explicit
12690b57cec5SDimitry Andric  __compressed_pair_elem(_Up&& __u)
12700b57cec5SDimitry Andric      : __value_type(_VSTD::forward<_Up>(__u))
12710b57cec5SDimitry Andric  {}
12720b57cec5SDimitry Andric
1273480093f4SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
12740b57cec5SDimitry Andric  template <class... _Args, size_t... _Indexes>
12750b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
12760b57cec5SDimitry Andric  __compressed_pair_elem(piecewise_construct_t, tuple<_Args...> __args,
12770b57cec5SDimitry Andric                         __tuple_indices<_Indexes...>)
12780b57cec5SDimitry Andric      : __value_type(_VSTD::forward<_Args>(_VSTD::get<_Indexes>(__args))...) {}
12790b57cec5SDimitry Andric#endif
12800b57cec5SDimitry Andric
12810b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY reference __get() _NOEXCEPT { return *this; }
12820b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
12830b57cec5SDimitry Andric  const_reference __get() const _NOEXCEPT { return *this; }
12840b57cec5SDimitry Andric};
12850b57cec5SDimitry Andric
12860b57cec5SDimitry Andrictemplate <class _T1, class _T2>
12870b57cec5SDimitry Andricclass __compressed_pair : private __compressed_pair_elem<_T1, 0>,
12880b57cec5SDimitry Andric                          private __compressed_pair_elem<_T2, 1> {
1289e8d8bef9SDimitry Andricpublic:
12900b57cec5SDimitry Andric  // NOTE: This static assert should never fire because __compressed_pair
12910b57cec5SDimitry Andric  // is *almost never* used in a scenario where it's possible for T1 == T2.
12920b57cec5SDimitry Andric  // (The exception is std::function where it is possible that the function
12930b57cec5SDimitry Andric  //  object and the allocator have the same type).
12940b57cec5SDimitry Andric  static_assert((!is_same<_T1, _T2>::value),
1295e8d8bef9SDimitry Andric    "__compressed_pair cannot be instantiated when T1 and T2 are the same type; "
12960b57cec5SDimitry Andric    "The current implementation is NOT ABI-compatible with the previous "
12970b57cec5SDimitry Andric    "implementation for this configuration");
12980b57cec5SDimitry Andric
1299e8d8bef9SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T1, 0> _Base1;
1300e8d8bef9SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE __compressed_pair_elem<_T2, 1> _Base2;
1301e8d8bef9SDimitry Andric
13020b57cec5SDimitry Andric    template <bool _Dummy = true,
13030b57cec5SDimitry Andric      class = typename enable_if<
13040b57cec5SDimitry Andric          __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&
13050b57cec5SDimitry Andric          __dependent_type<is_default_constructible<_T2>, _Dummy>::value
13060b57cec5SDimitry Andric      >::type
13070b57cec5SDimitry Andric  >
13080b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1309480093f4SDimitry Andric  _LIBCPP_CONSTEXPR __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}
13100b57cec5SDimitry Andric
13110b57cec5SDimitry Andric  template <class _U1, class _U2>
1312480093f4SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
13130b57cec5SDimitry Andric  __compressed_pair(_U1&& __t1, _U2&& __t2)
1314e8d8bef9SDimitry Andric      : _Base1(_VSTD::forward<_U1>(__t1)), _Base2(_VSTD::forward<_U2>(__t2)) {}
13150b57cec5SDimitry Andric
1316480093f4SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
13170b57cec5SDimitry Andric  template <class... _Args1, class... _Args2>
13180b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
13190b57cec5SDimitry Andric  __compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args,
13200b57cec5SDimitry Andric                    tuple<_Args2...> __second_args)
13210b57cec5SDimitry Andric      : _Base1(__pc, _VSTD::move(__first_args),
13220b57cec5SDimitry Andric               typename __make_tuple_indices<sizeof...(_Args1)>::type()),
13230b57cec5SDimitry Andric        _Base2(__pc, _VSTD::move(__second_args),
13240b57cec5SDimitry Andric               typename __make_tuple_indices<sizeof...(_Args2)>::type()) {}
13250b57cec5SDimitry Andric#endif
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13280b57cec5SDimitry Andric  typename _Base1::reference first() _NOEXCEPT {
13290b57cec5SDimitry Andric    return static_cast<_Base1&>(*this).__get();
13300b57cec5SDimitry Andric  }
13310b57cec5SDimitry Andric
13320b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13330b57cec5SDimitry Andric  typename _Base1::const_reference first() const _NOEXCEPT {
13340b57cec5SDimitry Andric    return static_cast<_Base1 const&>(*this).__get();
13350b57cec5SDimitry Andric  }
13360b57cec5SDimitry Andric
13370b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13380b57cec5SDimitry Andric  typename _Base2::reference second() _NOEXCEPT {
13390b57cec5SDimitry Andric    return static_cast<_Base2&>(*this).__get();
13400b57cec5SDimitry Andric  }
13410b57cec5SDimitry Andric
13420b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13430b57cec5SDimitry Andric  typename _Base2::const_reference second() const _NOEXCEPT {
13440b57cec5SDimitry Andric    return static_cast<_Base2 const&>(*this).__get();
13450b57cec5SDimitry Andric  }
13460b57cec5SDimitry Andric
1347e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1348e8d8bef9SDimitry Andric  static _Base1* __get_first_base(__compressed_pair* __pair) _NOEXCEPT {
1349e8d8bef9SDimitry Andric    return static_cast<_Base1*>(__pair);
1350e8d8bef9SDimitry Andric  }
1351e8d8bef9SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1352e8d8bef9SDimitry Andric  static _Base2* __get_second_base(__compressed_pair* __pair) _NOEXCEPT {
1353e8d8bef9SDimitry Andric    return static_cast<_Base2*>(__pair);
1354e8d8bef9SDimitry Andric  }
1355e8d8bef9SDimitry Andric
13560b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13570b57cec5SDimitry Andric  void swap(__compressed_pair& __x)
13580b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
13590b57cec5SDimitry Andric               __is_nothrow_swappable<_T2>::value)
13600b57cec5SDimitry Andric  {
1361e8d8bef9SDimitry Andric    using _VSTD::swap;
13620b57cec5SDimitry Andric    swap(first(), __x.first());
13630b57cec5SDimitry Andric    swap(second(), __x.second());
13640b57cec5SDimitry Andric  }
13650b57cec5SDimitry Andric};
13660b57cec5SDimitry Andric
13670b57cec5SDimitry Andrictemplate <class _T1, class _T2>
13680b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
13690b57cec5SDimitry Andricvoid swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y)
13700b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_T1>::value &&
13710b57cec5SDimitry Andric               __is_nothrow_swappable<_T2>::value) {
13720b57cec5SDimitry Andric  __x.swap(__y);
13730b57cec5SDimitry Andric}
13740b57cec5SDimitry Andric
13750b57cec5SDimitry Andric// default_delete
13760b57cec5SDimitry Andric
13770b57cec5SDimitry Andrictemplate <class _Tp>
13780b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS default_delete {
13790b57cec5SDimitry Andric    static_assert(!is_function<_Tp>::value,
13800b57cec5SDimitry Andric                  "default_delete cannot be instantiated for function types");
13810b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
13820b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
13830b57cec5SDimitry Andric#else
13840b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY default_delete() {}
13850b57cec5SDimitry Andric#endif
13860b57cec5SDimitry Andric  template <class _Up>
13870b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
13880b57cec5SDimitry Andric  default_delete(const default_delete<_Up>&,
13890b57cec5SDimitry Andric                 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
13900b57cec5SDimitry Andric                     0) _NOEXCEPT {}
13910b57cec5SDimitry Andric
13920b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
13930b57cec5SDimitry Andric    static_assert(sizeof(_Tp) > 0,
13940b57cec5SDimitry Andric                  "default_delete can not delete incomplete type");
13950b57cec5SDimitry Andric    static_assert(!is_void<_Tp>::value,
13960b57cec5SDimitry Andric                  "default_delete can not delete incomplete type");
13970b57cec5SDimitry Andric    delete __ptr;
13980b57cec5SDimitry Andric  }
13990b57cec5SDimitry Andric};
14000b57cec5SDimitry Andric
14010b57cec5SDimitry Andrictemplate <class _Tp>
14020b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS default_delete<_Tp[]> {
14030b57cec5SDimitry Andricprivate:
14040b57cec5SDimitry Andric  template <class _Up>
14050b57cec5SDimitry Andric  struct _EnableIfConvertible
14060b57cec5SDimitry Andric      : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
14070b57cec5SDimitry Andric
14080b57cec5SDimitry Andricpublic:
14090b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
14100b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY constexpr default_delete() _NOEXCEPT = default;
14110b57cec5SDimitry Andric#else
14120b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY default_delete() {}
14130b57cec5SDimitry Andric#endif
14140b57cec5SDimitry Andric
14150b57cec5SDimitry Andric  template <class _Up>
14160b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
14170b57cec5SDimitry Andric  default_delete(const default_delete<_Up[]>&,
14180b57cec5SDimitry Andric                 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPT {}
14190b57cec5SDimitry Andric
14200b57cec5SDimitry Andric  template <class _Up>
14210b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
14220b57cec5SDimitry Andric  typename _EnableIfConvertible<_Up>::type
14230b57cec5SDimitry Andric  operator()(_Up* __ptr) const _NOEXCEPT {
14240b57cec5SDimitry Andric    static_assert(sizeof(_Tp) > 0,
14250b57cec5SDimitry Andric                  "default_delete can not delete incomplete type");
14260b57cec5SDimitry Andric    static_assert(!is_void<_Tp>::value,
14270b57cec5SDimitry Andric                  "default_delete can not delete void type");
14280b57cec5SDimitry Andric    delete[] __ptr;
14290b57cec5SDimitry Andric  }
14300b57cec5SDimitry Andric};
14310b57cec5SDimitry Andric
14320b57cec5SDimitry Andrictemplate <class _Deleter>
14330b57cec5SDimitry Andricstruct __unique_ptr_deleter_sfinae {
14340b57cec5SDimitry Andric  static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
14350b57cec5SDimitry Andric  typedef const _Deleter& __lval_ref_type;
14360b57cec5SDimitry Andric  typedef _Deleter&& __good_rval_ref_type;
14370b57cec5SDimitry Andric  typedef true_type __enable_rval_overload;
14380b57cec5SDimitry Andric};
14390b57cec5SDimitry Andric
14400b57cec5SDimitry Andrictemplate <class _Deleter>
14410b57cec5SDimitry Andricstruct __unique_ptr_deleter_sfinae<_Deleter const&> {
14420b57cec5SDimitry Andric  typedef const _Deleter& __lval_ref_type;
14430b57cec5SDimitry Andric  typedef const _Deleter&& __bad_rval_ref_type;
14440b57cec5SDimitry Andric  typedef false_type __enable_rval_overload;
14450b57cec5SDimitry Andric};
14460b57cec5SDimitry Andric
14470b57cec5SDimitry Andrictemplate <class _Deleter>
14480b57cec5SDimitry Andricstruct __unique_ptr_deleter_sfinae<_Deleter&> {
14490b57cec5SDimitry Andric  typedef _Deleter& __lval_ref_type;
14500b57cec5SDimitry Andric  typedef _Deleter&& __bad_rval_ref_type;
14510b57cec5SDimitry Andric  typedef false_type __enable_rval_overload;
14520b57cec5SDimitry Andric};
14530b57cec5SDimitry Andric
1454e8d8bef9SDimitry Andric#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
1455e8d8bef9SDimitry Andric#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
1456e8d8bef9SDimitry Andric#else
1457e8d8bef9SDimitry Andric#  define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
1458e8d8bef9SDimitry Andric#endif
1459e8d8bef9SDimitry Andric
14600b57cec5SDimitry Andrictemplate <class _Tp, class _Dp = default_delete<_Tp> >
1461e8d8bef9SDimitry Andricclass _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
14620b57cec5SDimitry Andricpublic:
14630b57cec5SDimitry Andric  typedef _Tp element_type;
14640b57cec5SDimitry Andric  typedef _Dp deleter_type;
1465e8d8bef9SDimitry Andric  typedef _LIBCPP_NODEBUG_TYPE typename __pointer<_Tp, deleter_type>::type pointer;
14660b57cec5SDimitry Andric
14670b57cec5SDimitry Andric  static_assert(!is_rvalue_reference<deleter_type>::value,
14680b57cec5SDimitry Andric                "the specified deleter type cannot be an rvalue reference");
14690b57cec5SDimitry Andric
14700b57cec5SDimitry Andricprivate:
14710b57cec5SDimitry Andric  __compressed_pair<pointer, deleter_type> __ptr_;
14720b57cec5SDimitry Andric
14730b57cec5SDimitry Andric  struct __nat { int __for_bool_; };
14740b57cec5SDimitry Andric
14750b57cec5SDimitry Andric  typedef _LIBCPP_NODEBUG_TYPE __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
14760b57cec5SDimitry Andric
14770b57cec5SDimitry Andric  template <bool _Dummy>
14780b57cec5SDimitry Andric  using _LValRefType _LIBCPP_NODEBUG_TYPE =
14790b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
14800b57cec5SDimitry Andric
14810b57cec5SDimitry Andric  template <bool _Dummy>
14820b57cec5SDimitry Andric  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
14830b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
14840b57cec5SDimitry Andric
14850b57cec5SDimitry Andric  template <bool _Dummy>
14860b57cec5SDimitry Andric  using _BadRValRefType _LIBCPP_NODEBUG_TYPE  =
14870b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
14880b57cec5SDimitry Andric
14890b57cec5SDimitry Andric  template <bool _Dummy, class _Deleter = typename __dependent_type<
14900b57cec5SDimitry Andric                             __identity<deleter_type>, _Dummy>::type>
14910b57cec5SDimitry Andric  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE =
14920b57cec5SDimitry Andric      typename enable_if<is_default_constructible<_Deleter>::value &&
14930b57cec5SDimitry Andric                         !is_pointer<_Deleter>::value>::type;
14940b57cec5SDimitry Andric
14950b57cec5SDimitry Andric  template <class _ArgType>
14960b57cec5SDimitry Andric  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
14970b57cec5SDimitry Andric      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
14980b57cec5SDimitry Andric
14990b57cec5SDimitry Andric  template <class _UPtr, class _Up>
15000b57cec5SDimitry Andric  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
15010b57cec5SDimitry Andric      is_convertible<typename _UPtr::pointer, pointer>::value &&
15020b57cec5SDimitry Andric      !is_array<_Up>::value
15030b57cec5SDimitry Andric  >::type;
15040b57cec5SDimitry Andric
15050b57cec5SDimitry Andric  template <class _UDel>
15060b57cec5SDimitry Andric  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
15070b57cec5SDimitry Andric      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
15080b57cec5SDimitry Andric      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
15090b57cec5SDimitry Andric    >::type;
15100b57cec5SDimitry Andric
15110b57cec5SDimitry Andric  template <class _UDel>
15120b57cec5SDimitry Andric  using _EnableIfDeleterAssignable = typename enable_if<
15130b57cec5SDimitry Andric      is_assignable<_Dp&, _UDel&&>::value
15140b57cec5SDimitry Andric    >::type;
15150b57cec5SDimitry Andric
15160b57cec5SDimitry Andricpublic:
15170b57cec5SDimitry Andric  template <bool _Dummy = true,
15180b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
15190b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1520480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
15210b57cec5SDimitry Andric
15220b57cec5SDimitry Andric  template <bool _Dummy = true,
15230b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
15240b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1525480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
15260b57cec5SDimitry Andric
15270b57cec5SDimitry Andric  template <bool _Dummy = true,
15280b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
15290b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1530480093f4SDimitry Andric  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
15310b57cec5SDimitry Andric
15320b57cec5SDimitry Andric  template <bool _Dummy = true,
15330b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
15340b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15350b57cec5SDimitry Andric  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
15360b57cec5SDimitry Andric      : __ptr_(__p, __d) {}
15370b57cec5SDimitry Andric
15380b57cec5SDimitry Andric  template <bool _Dummy = true,
15390b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
15400b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15410b57cec5SDimitry Andric  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
15420b57cec5SDimitry Andric      : __ptr_(__p, _VSTD::move(__d)) {
15430b57cec5SDimitry Andric    static_assert(!is_reference<deleter_type>::value,
15440b57cec5SDimitry Andric                  "rvalue deleter bound to reference");
15450b57cec5SDimitry Andric  }
15460b57cec5SDimitry Andric
15470b57cec5SDimitry Andric  template <bool _Dummy = true,
15480b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
15490b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15500b57cec5SDimitry Andric  unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
15510b57cec5SDimitry Andric
15520b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15530b57cec5SDimitry Andric  unique_ptr(unique_ptr&& __u) _NOEXCEPT
15540b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
15550b57cec5SDimitry Andric  }
15560b57cec5SDimitry Andric
15570b57cec5SDimitry Andric  template <class _Up, class _Ep,
15580b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
15590b57cec5SDimitry Andric      class = _EnableIfDeleterConvertible<_Ep>
15600b57cec5SDimitry Andric  >
15610b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15620b57cec5SDimitry Andric  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
15630b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {}
15640b57cec5SDimitry Andric
15650b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
15660b57cec5SDimitry Andric  template <class _Up>
15670b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15680b57cec5SDimitry Andric  unique_ptr(auto_ptr<_Up>&& __p,
15690b57cec5SDimitry Andric             typename enable_if<is_convertible<_Up*, _Tp*>::value &&
15700b57cec5SDimitry Andric                                    is_same<_Dp, default_delete<_Tp> >::value,
15710b57cec5SDimitry Andric                                __nat>::type = __nat()) _NOEXCEPT
1572480093f4SDimitry Andric      : __ptr_(__p.release(), __default_init_tag()) {}
15730b57cec5SDimitry Andric#endif
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15760b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
15770b57cec5SDimitry Andric    reset(__u.release());
15780b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
15790b57cec5SDimitry Andric    return *this;
15800b57cec5SDimitry Andric  }
15810b57cec5SDimitry Andric
15820b57cec5SDimitry Andric  template <class _Up, class _Ep,
15830b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
15840b57cec5SDimitry Andric      class = _EnableIfDeleterAssignable<_Ep>
15850b57cec5SDimitry Andric  >
15860b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15870b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
15880b57cec5SDimitry Andric    reset(__u.release());
15890b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
15900b57cec5SDimitry Andric    return *this;
15910b57cec5SDimitry Andric  }
15920b57cec5SDimitry Andric
15930b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
15940b57cec5SDimitry Andric  template <class _Up>
15950b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
15960b57cec5SDimitry Andric      typename enable_if<is_convertible<_Up*, _Tp*>::value &&
15970b57cec5SDimitry Andric                             is_same<_Dp, default_delete<_Tp> >::value,
15980b57cec5SDimitry Andric                         unique_ptr&>::type
15990b57cec5SDimitry Andric      operator=(auto_ptr<_Up> __p) {
16000b57cec5SDimitry Andric    reset(__p.release());
16010b57cec5SDimitry Andric    return *this;
16020b57cec5SDimitry Andric  }
16030b57cec5SDimitry Andric#endif
16040b57cec5SDimitry Andric
16050b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
16060b57cec5SDimitry Andric  unique_ptr(unique_ptr const&) = delete;
16070b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr const&) = delete;
16080b57cec5SDimitry Andric#endif
16090b57cec5SDimitry Andric
16100b57cec5SDimitry Andric
16110b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16120b57cec5SDimitry Andric  ~unique_ptr() { reset(); }
16130b57cec5SDimitry Andric
16140b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16150b57cec5SDimitry Andric  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
16160b57cec5SDimitry Andric    reset();
16170b57cec5SDimitry Andric    return *this;
16180b57cec5SDimitry Andric  }
16190b57cec5SDimitry Andric
16200b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16210b57cec5SDimitry Andric  typename add_lvalue_reference<_Tp>::type
16220b57cec5SDimitry Andric  operator*() const {
16230b57cec5SDimitry Andric    return *__ptr_.first();
16240b57cec5SDimitry Andric  }
16250b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16260b57cec5SDimitry Andric  pointer operator->() const _NOEXCEPT {
16270b57cec5SDimitry Andric    return __ptr_.first();
16280b57cec5SDimitry Andric  }
16290b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16300b57cec5SDimitry Andric  pointer get() const _NOEXCEPT {
16310b57cec5SDimitry Andric    return __ptr_.first();
16320b57cec5SDimitry Andric  }
16330b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16340b57cec5SDimitry Andric  deleter_type& get_deleter() _NOEXCEPT {
16350b57cec5SDimitry Andric    return __ptr_.second();
16360b57cec5SDimitry Andric  }
16370b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16380b57cec5SDimitry Andric  const deleter_type& get_deleter() const _NOEXCEPT {
16390b57cec5SDimitry Andric    return __ptr_.second();
16400b57cec5SDimitry Andric  }
16410b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16420b57cec5SDimitry Andric  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
16430b57cec5SDimitry Andric    return __ptr_.first() != nullptr;
16440b57cec5SDimitry Andric  }
16450b57cec5SDimitry Andric
16460b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16470b57cec5SDimitry Andric  pointer release() _NOEXCEPT {
16480b57cec5SDimitry Andric    pointer __t = __ptr_.first();
16490b57cec5SDimitry Andric    __ptr_.first() = pointer();
16500b57cec5SDimitry Andric    return __t;
16510b57cec5SDimitry Andric  }
16520b57cec5SDimitry Andric
16530b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16540b57cec5SDimitry Andric  void reset(pointer __p = pointer()) _NOEXCEPT {
16550b57cec5SDimitry Andric    pointer __tmp = __ptr_.first();
16560b57cec5SDimitry Andric    __ptr_.first() = __p;
16570b57cec5SDimitry Andric    if (__tmp)
16580b57cec5SDimitry Andric      __ptr_.second()(__tmp);
16590b57cec5SDimitry Andric  }
16600b57cec5SDimitry Andric
16610b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
16620b57cec5SDimitry Andric  void swap(unique_ptr& __u) _NOEXCEPT {
16630b57cec5SDimitry Andric    __ptr_.swap(__u.__ptr_);
16640b57cec5SDimitry Andric  }
16650b57cec5SDimitry Andric};
16660b57cec5SDimitry Andric
16670b57cec5SDimitry Andric
16680b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
1669e8d8bef9SDimitry Andricclass _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr<_Tp[], _Dp> {
16700b57cec5SDimitry Andricpublic:
16710b57cec5SDimitry Andric  typedef _Tp element_type;
16720b57cec5SDimitry Andric  typedef _Dp deleter_type;
1673e8d8bef9SDimitry Andric  typedef typename __pointer<_Tp, deleter_type>::type pointer;
16740b57cec5SDimitry Andric
16750b57cec5SDimitry Andricprivate:
16760b57cec5SDimitry Andric  __compressed_pair<pointer, deleter_type> __ptr_;
16770b57cec5SDimitry Andric
16780b57cec5SDimitry Andric  template <class _From>
16790b57cec5SDimitry Andric  struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
16800b57cec5SDimitry Andric
16810b57cec5SDimitry Andric  template <class _FromElem>
16820b57cec5SDimitry Andric  struct _CheckArrayPointerConversion<_FromElem*>
16830b57cec5SDimitry Andric      : integral_constant<bool,
16840b57cec5SDimitry Andric          is_same<_FromElem*, pointer>::value ||
16850b57cec5SDimitry Andric            (is_same<pointer, element_type*>::value &&
16860b57cec5SDimitry Andric             is_convertible<_FromElem(*)[], element_type(*)[]>::value)
16870b57cec5SDimitry Andric      >
16880b57cec5SDimitry Andric  {};
16890b57cec5SDimitry Andric
16900b57cec5SDimitry Andric  typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
16910b57cec5SDimitry Andric
16920b57cec5SDimitry Andric  template <bool _Dummy>
16930b57cec5SDimitry Andric  using _LValRefType _LIBCPP_NODEBUG_TYPE =
16940b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
16950b57cec5SDimitry Andric
16960b57cec5SDimitry Andric  template <bool _Dummy>
16970b57cec5SDimitry Andric  using _GoodRValRefType _LIBCPP_NODEBUG_TYPE =
16980b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
16990b57cec5SDimitry Andric
17000b57cec5SDimitry Andric  template <bool _Dummy>
17010b57cec5SDimitry Andric  using _BadRValRefType _LIBCPP_NODEBUG_TYPE =
17020b57cec5SDimitry Andric      typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
17030b57cec5SDimitry Andric
17040b57cec5SDimitry Andric  template <bool _Dummy, class _Deleter = typename __dependent_type<
17050b57cec5SDimitry Andric                             __identity<deleter_type>, _Dummy>::type>
17060b57cec5SDimitry Andric  using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE  =
17070b57cec5SDimitry Andric      typename enable_if<is_default_constructible<_Deleter>::value &&
17080b57cec5SDimitry Andric                         !is_pointer<_Deleter>::value>::type;
17090b57cec5SDimitry Andric
17100b57cec5SDimitry Andric  template <class _ArgType>
17110b57cec5SDimitry Andric  using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE  =
17120b57cec5SDimitry Andric      typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
17130b57cec5SDimitry Andric
17140b57cec5SDimitry Andric  template <class _Pp>
17150b57cec5SDimitry Andric  using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
17160b57cec5SDimitry Andric      _CheckArrayPointerConversion<_Pp>::value
17170b57cec5SDimitry Andric  >::type;
17180b57cec5SDimitry Andric
17190b57cec5SDimitry Andric  template <class _UPtr, class _Up,
17200b57cec5SDimitry Andric        class _ElemT = typename _UPtr::element_type>
17210b57cec5SDimitry Andric  using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
17220b57cec5SDimitry Andric      is_array<_Up>::value &&
17230b57cec5SDimitry Andric      is_same<pointer, element_type*>::value &&
17240b57cec5SDimitry Andric      is_same<typename _UPtr::pointer, _ElemT*>::value &&
17250b57cec5SDimitry Andric      is_convertible<_ElemT(*)[], element_type(*)[]>::value
17260b57cec5SDimitry Andric    >::type;
17270b57cec5SDimitry Andric
17280b57cec5SDimitry Andric  template <class _UDel>
17290b57cec5SDimitry Andric  using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE  = typename enable_if<
17300b57cec5SDimitry Andric      (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
17310b57cec5SDimitry Andric      (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
17320b57cec5SDimitry Andric    >::type;
17330b57cec5SDimitry Andric
17340b57cec5SDimitry Andric  template <class _UDel>
17350b57cec5SDimitry Andric  using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE  = typename enable_if<
17360b57cec5SDimitry Andric      is_assignable<_Dp&, _UDel&&>::value
17370b57cec5SDimitry Andric    >::type;
17380b57cec5SDimitry Andric
17390b57cec5SDimitry Andricpublic:
17400b57cec5SDimitry Andric  template <bool _Dummy = true,
17410b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
17420b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1743480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
17440b57cec5SDimitry Andric
17450b57cec5SDimitry Andric  template <bool _Dummy = true,
17460b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy> >
17470b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1748480093f4SDimitry Andric  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
17490b57cec5SDimitry Andric
17500b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
17510b57cec5SDimitry Andric            class = _EnableIfDeleterDefaultConstructible<_Dummy>,
17520b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
17530b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17540b57cec5SDimitry Andric  explicit unique_ptr(_Pp __p) _NOEXCEPT
1755480093f4SDimitry Andric      : __ptr_(__p, __default_init_tag()) {}
17560b57cec5SDimitry Andric
17570b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
17580b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
17590b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
17600b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17610b57cec5SDimitry Andric  unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPT
17620b57cec5SDimitry Andric      : __ptr_(__p, __d) {}
17630b57cec5SDimitry Andric
17640b57cec5SDimitry Andric  template <bool _Dummy = true,
17650b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
17660b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17670b57cec5SDimitry Andric  unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPT
17680b57cec5SDimitry Andric      : __ptr_(nullptr, __d) {}
17690b57cec5SDimitry Andric
17700b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
17710b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
17720b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
17730b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17740b57cec5SDimitry Andric  unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
17750b57cec5SDimitry Andric      : __ptr_(__p, _VSTD::move(__d)) {
17760b57cec5SDimitry Andric    static_assert(!is_reference<deleter_type>::value,
17770b57cec5SDimitry Andric                  "rvalue deleter bound to reference");
17780b57cec5SDimitry Andric  }
17790b57cec5SDimitry Andric
17800b57cec5SDimitry Andric  template <bool _Dummy = true,
17810b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
17820b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17830b57cec5SDimitry Andric  unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
17840b57cec5SDimitry Andric      : __ptr_(nullptr, _VSTD::move(__d)) {
17850b57cec5SDimitry Andric    static_assert(!is_reference<deleter_type>::value,
17860b57cec5SDimitry Andric                  "rvalue deleter bound to reference");
17870b57cec5SDimitry Andric  }
17880b57cec5SDimitry Andric
17890b57cec5SDimitry Andric  template <class _Pp, bool _Dummy = true,
17900b57cec5SDimitry Andric            class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
17910b57cec5SDimitry Andric            class = _EnableIfPointerConvertible<_Pp> >
17920b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17930b57cec5SDimitry Andric  unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
17940b57cec5SDimitry Andric
17950b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
17960b57cec5SDimitry Andric  unique_ptr(unique_ptr&& __u) _NOEXCEPT
17970b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<deleter_type>(__u.get_deleter())) {
17980b57cec5SDimitry Andric  }
17990b57cec5SDimitry Andric
18000b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18010b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPT {
18020b57cec5SDimitry Andric    reset(__u.release());
18030b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<deleter_type>(__u.get_deleter());
18040b57cec5SDimitry Andric    return *this;
18050b57cec5SDimitry Andric  }
18060b57cec5SDimitry Andric
18070b57cec5SDimitry Andric  template <class _Up, class _Ep,
18080b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
18090b57cec5SDimitry Andric      class = _EnableIfDeleterConvertible<_Ep>
18100b57cec5SDimitry Andric  >
18110b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18120b57cec5SDimitry Andric  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
18130b57cec5SDimitry Andric      : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
18140b57cec5SDimitry Andric  }
18150b57cec5SDimitry Andric
18160b57cec5SDimitry Andric  template <class _Up, class _Ep,
18170b57cec5SDimitry Andric      class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
18180b57cec5SDimitry Andric      class = _EnableIfDeleterAssignable<_Ep>
18190b57cec5SDimitry Andric  >
18200b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18210b57cec5SDimitry Andric  unique_ptr&
18220b57cec5SDimitry Andric  operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT {
18230b57cec5SDimitry Andric    reset(__u.release());
18240b57cec5SDimitry Andric    __ptr_.second() = _VSTD::forward<_Ep>(__u.get_deleter());
18250b57cec5SDimitry Andric    return *this;
18260b57cec5SDimitry Andric  }
18270b57cec5SDimitry Andric
18280b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
18290b57cec5SDimitry Andric  unique_ptr(unique_ptr const&) = delete;
18300b57cec5SDimitry Andric  unique_ptr& operator=(unique_ptr const&) = delete;
18310b57cec5SDimitry Andric#endif
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andricpublic:
18340b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18350b57cec5SDimitry Andric  ~unique_ptr() { reset(); }
18360b57cec5SDimitry Andric
18370b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18380b57cec5SDimitry Andric  unique_ptr& operator=(nullptr_t) _NOEXCEPT {
18390b57cec5SDimitry Andric    reset();
18400b57cec5SDimitry Andric    return *this;
18410b57cec5SDimitry Andric  }
18420b57cec5SDimitry Andric
18430b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18440b57cec5SDimitry Andric  typename add_lvalue_reference<_Tp>::type
18450b57cec5SDimitry Andric  operator[](size_t __i) const {
18460b57cec5SDimitry Andric    return __ptr_.first()[__i];
18470b57cec5SDimitry Andric  }
18480b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18490b57cec5SDimitry Andric  pointer get() const _NOEXCEPT {
18500b57cec5SDimitry Andric    return __ptr_.first();
18510b57cec5SDimitry Andric  }
18520b57cec5SDimitry Andric
18530b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18540b57cec5SDimitry Andric  deleter_type& get_deleter() _NOEXCEPT {
18550b57cec5SDimitry Andric    return __ptr_.second();
18560b57cec5SDimitry Andric  }
18570b57cec5SDimitry Andric
18580b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18590b57cec5SDimitry Andric  const deleter_type& get_deleter() const _NOEXCEPT {
18600b57cec5SDimitry Andric    return __ptr_.second();
18610b57cec5SDimitry Andric  }
18620b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18630b57cec5SDimitry Andric  _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {
18640b57cec5SDimitry Andric    return __ptr_.first() != nullptr;
18650b57cec5SDimitry Andric  }
18660b57cec5SDimitry Andric
18670b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18680b57cec5SDimitry Andric  pointer release() _NOEXCEPT {
18690b57cec5SDimitry Andric    pointer __t = __ptr_.first();
18700b57cec5SDimitry Andric    __ptr_.first() = pointer();
18710b57cec5SDimitry Andric    return __t;
18720b57cec5SDimitry Andric  }
18730b57cec5SDimitry Andric
18740b57cec5SDimitry Andric  template <class _Pp>
18750b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18760b57cec5SDimitry Andric  typename enable_if<
18770b57cec5SDimitry Andric      _CheckArrayPointerConversion<_Pp>::value
18780b57cec5SDimitry Andric  >::type
18790b57cec5SDimitry Andric  reset(_Pp __p) _NOEXCEPT {
18800b57cec5SDimitry Andric    pointer __tmp = __ptr_.first();
18810b57cec5SDimitry Andric    __ptr_.first() = __p;
18820b57cec5SDimitry Andric    if (__tmp)
18830b57cec5SDimitry Andric      __ptr_.second()(__tmp);
18840b57cec5SDimitry Andric  }
18850b57cec5SDimitry Andric
18860b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18870b57cec5SDimitry Andric  void reset(nullptr_t = nullptr) _NOEXCEPT {
18880b57cec5SDimitry Andric    pointer __tmp = __ptr_.first();
18890b57cec5SDimitry Andric    __ptr_.first() = nullptr;
18900b57cec5SDimitry Andric    if (__tmp)
18910b57cec5SDimitry Andric      __ptr_.second()(__tmp);
18920b57cec5SDimitry Andric  }
18930b57cec5SDimitry Andric
18940b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
18950b57cec5SDimitry Andric  void swap(unique_ptr& __u) _NOEXCEPT {
18960b57cec5SDimitry Andric    __ptr_.swap(__u.__ptr_);
18970b57cec5SDimitry Andric  }
18980b57cec5SDimitry Andric
18990b57cec5SDimitry Andric};
19000b57cec5SDimitry Andric
19010b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
19020b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19030b57cec5SDimitry Andrictypename enable_if<
19040b57cec5SDimitry Andric    __is_swappable<_Dp>::value,
19050b57cec5SDimitry Andric    void
19060b57cec5SDimitry Andric>::type
19070b57cec5SDimitry Andricswap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPT {__x.swap(__y);}
19080b57cec5SDimitry Andric
19090b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
19100b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19110b57cec5SDimitry Andricbool
19120b57cec5SDimitry Andricoperator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
19130b57cec5SDimitry Andric
19140b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
19150b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19160b57cec5SDimitry Andricbool
19170b57cec5SDimitry Andricoperator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
19180b57cec5SDimitry Andric
19190b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
19200b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19210b57cec5SDimitry Andricbool
19220b57cec5SDimitry Andricoperator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
19230b57cec5SDimitry Andric{
19240b57cec5SDimitry Andric    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
19250b57cec5SDimitry Andric    typedef typename unique_ptr<_T2, _D2>::pointer _P2;
19260b57cec5SDimitry Andric    typedef typename common_type<_P1, _P2>::type _Vp;
19270b57cec5SDimitry Andric    return less<_Vp>()(__x.get(), __y.get());
19280b57cec5SDimitry Andric}
19290b57cec5SDimitry Andric
19300b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
19310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19320b57cec5SDimitry Andricbool
19330b57cec5SDimitry Andricoperator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
19340b57cec5SDimitry Andric
19350b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
19360b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19370b57cec5SDimitry Andricbool
19380b57cec5SDimitry Andricoperator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andrictemplate <class _T1, class _D1, class _T2, class _D2>
19410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19420b57cec5SDimitry Andricbool
19430b57cec5SDimitry Andricoperator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
19440b57cec5SDimitry Andric
19450b57cec5SDimitry Andrictemplate <class _T1, class _D1>
19460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19470b57cec5SDimitry Andricbool
19480b57cec5SDimitry Andricoperator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
19490b57cec5SDimitry Andric{
19500b57cec5SDimitry Andric    return !__x;
19510b57cec5SDimitry Andric}
19520b57cec5SDimitry Andric
19530b57cec5SDimitry Andrictemplate <class _T1, class _D1>
19540b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19550b57cec5SDimitry Andricbool
19560b57cec5SDimitry Andricoperator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
19570b57cec5SDimitry Andric{
19580b57cec5SDimitry Andric    return !__x;
19590b57cec5SDimitry Andric}
19600b57cec5SDimitry Andric
19610b57cec5SDimitry Andrictemplate <class _T1, class _D1>
19620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19630b57cec5SDimitry Andricbool
19640b57cec5SDimitry Andricoperator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
19650b57cec5SDimitry Andric{
19660b57cec5SDimitry Andric    return static_cast<bool>(__x);
19670b57cec5SDimitry Andric}
19680b57cec5SDimitry Andric
19690b57cec5SDimitry Andrictemplate <class _T1, class _D1>
19700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19710b57cec5SDimitry Andricbool
19720b57cec5SDimitry Andricoperator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
19730b57cec5SDimitry Andric{
19740b57cec5SDimitry Andric    return static_cast<bool>(__x);
19750b57cec5SDimitry Andric}
19760b57cec5SDimitry Andric
19770b57cec5SDimitry Andrictemplate <class _T1, class _D1>
19780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19790b57cec5SDimitry Andricbool
19800b57cec5SDimitry Andricoperator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
19810b57cec5SDimitry Andric{
19820b57cec5SDimitry Andric    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
19830b57cec5SDimitry Andric    return less<_P1>()(__x.get(), nullptr);
19840b57cec5SDimitry Andric}
19850b57cec5SDimitry Andric
19860b57cec5SDimitry Andrictemplate <class _T1, class _D1>
19870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19880b57cec5SDimitry Andricbool
19890b57cec5SDimitry Andricoperator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
19900b57cec5SDimitry Andric{
19910b57cec5SDimitry Andric    typedef typename unique_ptr<_T1, _D1>::pointer _P1;
19920b57cec5SDimitry Andric    return less<_P1>()(nullptr, __x.get());
19930b57cec5SDimitry Andric}
19940b57cec5SDimitry Andric
19950b57cec5SDimitry Andrictemplate <class _T1, class _D1>
19960b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
19970b57cec5SDimitry Andricbool
19980b57cec5SDimitry Andricoperator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
19990b57cec5SDimitry Andric{
20000b57cec5SDimitry Andric    return nullptr < __x;
20010b57cec5SDimitry Andric}
20020b57cec5SDimitry Andric
20030b57cec5SDimitry Andrictemplate <class _T1, class _D1>
20040b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20050b57cec5SDimitry Andricbool
20060b57cec5SDimitry Andricoperator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
20070b57cec5SDimitry Andric{
20080b57cec5SDimitry Andric    return __x < nullptr;
20090b57cec5SDimitry Andric}
20100b57cec5SDimitry Andric
20110b57cec5SDimitry Andrictemplate <class _T1, class _D1>
20120b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20130b57cec5SDimitry Andricbool
20140b57cec5SDimitry Andricoperator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
20150b57cec5SDimitry Andric{
20160b57cec5SDimitry Andric    return !(nullptr < __x);
20170b57cec5SDimitry Andric}
20180b57cec5SDimitry Andric
20190b57cec5SDimitry Andrictemplate <class _T1, class _D1>
20200b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20210b57cec5SDimitry Andricbool
20220b57cec5SDimitry Andricoperator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
20230b57cec5SDimitry Andric{
20240b57cec5SDimitry Andric    return !(__x < nullptr);
20250b57cec5SDimitry Andric}
20260b57cec5SDimitry Andric
20270b57cec5SDimitry Andrictemplate <class _T1, class _D1>
20280b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20290b57cec5SDimitry Andricbool
20300b57cec5SDimitry Andricoperator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
20310b57cec5SDimitry Andric{
20320b57cec5SDimitry Andric    return !(__x < nullptr);
20330b57cec5SDimitry Andric}
20340b57cec5SDimitry Andric
20350b57cec5SDimitry Andrictemplate <class _T1, class _D1>
20360b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20370b57cec5SDimitry Andricbool
20380b57cec5SDimitry Andricoperator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
20390b57cec5SDimitry Andric{
20400b57cec5SDimitry Andric    return !(nullptr < __x);
20410b57cec5SDimitry Andric}
20420b57cec5SDimitry Andric
20430b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
20440b57cec5SDimitry Andric
20450b57cec5SDimitry Andrictemplate<class _Tp>
20460b57cec5SDimitry Andricstruct __unique_if
20470b57cec5SDimitry Andric{
20480b57cec5SDimitry Andric    typedef unique_ptr<_Tp> __unique_single;
20490b57cec5SDimitry Andric};
20500b57cec5SDimitry Andric
20510b57cec5SDimitry Andrictemplate<class _Tp>
20520b57cec5SDimitry Andricstruct __unique_if<_Tp[]>
20530b57cec5SDimitry Andric{
20540b57cec5SDimitry Andric    typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
20550b57cec5SDimitry Andric};
20560b57cec5SDimitry Andric
20570b57cec5SDimitry Andrictemplate<class _Tp, size_t _Np>
20580b57cec5SDimitry Andricstruct __unique_if<_Tp[_Np]>
20590b57cec5SDimitry Andric{
20600b57cec5SDimitry Andric    typedef void __unique_array_known_bound;
20610b57cec5SDimitry Andric};
20620b57cec5SDimitry Andric
20630b57cec5SDimitry Andrictemplate<class _Tp, class... _Args>
20640b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20650b57cec5SDimitry Andrictypename __unique_if<_Tp>::__unique_single
20660b57cec5SDimitry Andricmake_unique(_Args&&... __args)
20670b57cec5SDimitry Andric{
20680b57cec5SDimitry Andric    return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
20690b57cec5SDimitry Andric}
20700b57cec5SDimitry Andric
20710b57cec5SDimitry Andrictemplate<class _Tp>
20720b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20730b57cec5SDimitry Andrictypename __unique_if<_Tp>::__unique_array_unknown_bound
20740b57cec5SDimitry Andricmake_unique(size_t __n)
20750b57cec5SDimitry Andric{
20760b57cec5SDimitry Andric    typedef typename remove_extent<_Tp>::type _Up;
20770b57cec5SDimitry Andric    return unique_ptr<_Tp>(new _Up[__n]());
20780b57cec5SDimitry Andric}
20790b57cec5SDimitry Andric
20800b57cec5SDimitry Andrictemplate<class _Tp, class... _Args>
20810b57cec5SDimitry Andric    typename __unique_if<_Tp>::__unique_array_known_bound
20820b57cec5SDimitry Andric    make_unique(_Args&&...) = delete;
20830b57cec5SDimitry Andric
20840b57cec5SDimitry Andric#endif  // _LIBCPP_STD_VER > 11
20850b57cec5SDimitry Andric
20860b57cec5SDimitry Andrictemplate <class _Tp, class _Dp>
20870b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
20880b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<unique_ptr<_Tp, _Dp> >
20890b57cec5SDimitry Andric#else
20900b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<__enable_hash_helper<
20910b57cec5SDimitry Andric    unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
20920b57cec5SDimitry Andric#endif
20930b57cec5SDimitry Andric{
20940b57cec5SDimitry Andric    typedef unique_ptr<_Tp, _Dp> argument_type;
20950b57cec5SDimitry Andric    typedef size_t               result_type;
20960b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
20970b57cec5SDimitry Andric    result_type operator()(const argument_type& __ptr) const
20980b57cec5SDimitry Andric    {
20990b57cec5SDimitry Andric        typedef typename argument_type::pointer pointer;
21000b57cec5SDimitry Andric        return hash<pointer>()(__ptr.get());
21010b57cec5SDimitry Andric    }
21020b57cec5SDimitry Andric};
21030b57cec5SDimitry Andric
21040b57cec5SDimitry Andricstruct __destruct_n
21050b57cec5SDimitry Andric{
21060b57cec5SDimitry Andricprivate:
21070b57cec5SDimitry Andric    size_t __size_;
21080b57cec5SDimitry Andric
21090b57cec5SDimitry Andric    template <class _Tp>
21100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
21110b57cec5SDimitry Andric        {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
21120b57cec5SDimitry Andric
21130b57cec5SDimitry Andric    template <class _Tp>
21140b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
21150b57cec5SDimitry Andric        {}
21160b57cec5SDimitry Andric
21170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
21180b57cec5SDimitry Andric        {++__size_;}
21190b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
21200b57cec5SDimitry Andric        {}
21210b57cec5SDimitry Andric
21220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
21230b57cec5SDimitry Andric        {__size_ = __s;}
21240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
21250b57cec5SDimitry Andric        {}
21260b57cec5SDimitry Andricpublic:
21270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
21280b57cec5SDimitry Andric        : __size_(__s) {}
21290b57cec5SDimitry Andric
21300b57cec5SDimitry Andric    template <class _Tp>
2131e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT
21320b57cec5SDimitry Andric        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
21330b57cec5SDimitry Andric
21340b57cec5SDimitry Andric    template <class _Tp>
21350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
21360b57cec5SDimitry Andric        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
21370b57cec5SDimitry Andric
21380b57cec5SDimitry Andric    template <class _Tp>
21390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
21400b57cec5SDimitry Andric        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
21410b57cec5SDimitry Andric};
21420b57cec5SDimitry Andric
21430b57cec5SDimitry Andrictemplate <class _Alloc>
21440b57cec5SDimitry Andricclass __allocator_destructor
21450b57cec5SDimitry Andric{
21460b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE allocator_traits<_Alloc> __alloc_traits;
21470b57cec5SDimitry Andricpublic:
21480b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::pointer pointer;
21490b57cec5SDimitry Andric    typedef _LIBCPP_NODEBUG_TYPE typename __alloc_traits::size_type size_type;
21500b57cec5SDimitry Andricprivate:
21510b57cec5SDimitry Andric    _Alloc& __alloc_;
21520b57cec5SDimitry Andric    size_type __s_;
21530b57cec5SDimitry Andricpublic:
21540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY __allocator_destructor(_Alloc& __a, size_type __s)
21550b57cec5SDimitry Andric             _NOEXCEPT
21560b57cec5SDimitry Andric        : __alloc_(__a), __s_(__s) {}
21570b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21580b57cec5SDimitry Andric    void operator()(pointer __p) _NOEXCEPT
21590b57cec5SDimitry Andric        {__alloc_traits::deallocate(__alloc_, __p, __s_);}
21600b57cec5SDimitry Andric};
21610b57cec5SDimitry Andric
21620b57cec5SDimitry Andrictemplate <class _InputIterator, class _ForwardIterator>
21630b57cec5SDimitry Andric_ForwardIterator
21640b57cec5SDimitry Andricuninitialized_copy(_InputIterator __f, _InputIterator __l, _ForwardIterator __r)
21650b57cec5SDimitry Andric{
21660b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
21670b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
21680b57cec5SDimitry Andric    _ForwardIterator __s = __r;
21690b57cec5SDimitry Andric    try
21700b57cec5SDimitry Andric    {
21710b57cec5SDimitry Andric#endif
21720b57cec5SDimitry Andric        for (; __f != __l; ++__f, (void) ++__r)
2173e8d8bef9SDimitry Andric            ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
21740b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
21750b57cec5SDimitry Andric    }
21760b57cec5SDimitry Andric    catch (...)
21770b57cec5SDimitry Andric    {
21780b57cec5SDimitry Andric        for (; __s != __r; ++__s)
21790b57cec5SDimitry Andric            __s->~value_type();
21800b57cec5SDimitry Andric        throw;
21810b57cec5SDimitry Andric    }
21820b57cec5SDimitry Andric#endif
21830b57cec5SDimitry Andric    return __r;
21840b57cec5SDimitry Andric}
21850b57cec5SDimitry Andric
21860b57cec5SDimitry Andrictemplate <class _InputIterator, class _Size, class _ForwardIterator>
21870b57cec5SDimitry Andric_ForwardIterator
21880b57cec5SDimitry Andricuninitialized_copy_n(_InputIterator __f, _Size __n, _ForwardIterator __r)
21890b57cec5SDimitry Andric{
21900b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
21910b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
21920b57cec5SDimitry Andric    _ForwardIterator __s = __r;
21930b57cec5SDimitry Andric    try
21940b57cec5SDimitry Andric    {
21950b57cec5SDimitry Andric#endif
21960b57cec5SDimitry Andric        for (; __n > 0; ++__f, (void) ++__r, (void) --__n)
2197e8d8bef9SDimitry Andric            ::new ((void*)_VSTD::addressof(*__r)) value_type(*__f);
21980b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
21990b57cec5SDimitry Andric    }
22000b57cec5SDimitry Andric    catch (...)
22010b57cec5SDimitry Andric    {
22020b57cec5SDimitry Andric        for (; __s != __r; ++__s)
22030b57cec5SDimitry Andric            __s->~value_type();
22040b57cec5SDimitry Andric        throw;
22050b57cec5SDimitry Andric    }
22060b57cec5SDimitry Andric#endif
22070b57cec5SDimitry Andric    return __r;
22080b57cec5SDimitry Andric}
22090b57cec5SDimitry Andric
22100b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Tp>
22110b57cec5SDimitry Andricvoid
22120b57cec5SDimitry Andricuninitialized_fill(_ForwardIterator __f, _ForwardIterator __l, const _Tp& __x)
22130b57cec5SDimitry Andric{
22140b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
22150b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22160b57cec5SDimitry Andric    _ForwardIterator __s = __f;
22170b57cec5SDimitry Andric    try
22180b57cec5SDimitry Andric    {
22190b57cec5SDimitry Andric#endif
22200b57cec5SDimitry Andric        for (; __f != __l; ++__f)
2221e8d8bef9SDimitry Andric            ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
22220b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22230b57cec5SDimitry Andric    }
22240b57cec5SDimitry Andric    catch (...)
22250b57cec5SDimitry Andric    {
22260b57cec5SDimitry Andric        for (; __s != __f; ++__s)
22270b57cec5SDimitry Andric            __s->~value_type();
22280b57cec5SDimitry Andric        throw;
22290b57cec5SDimitry Andric    }
22300b57cec5SDimitry Andric#endif
22310b57cec5SDimitry Andric}
22320b57cec5SDimitry Andric
22330b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size, class _Tp>
22340b57cec5SDimitry Andric_ForwardIterator
22350b57cec5SDimitry Andricuninitialized_fill_n(_ForwardIterator __f, _Size __n, const _Tp& __x)
22360b57cec5SDimitry Andric{
22370b57cec5SDimitry Andric    typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
22380b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22390b57cec5SDimitry Andric    _ForwardIterator __s = __f;
22400b57cec5SDimitry Andric    try
22410b57cec5SDimitry Andric    {
22420b57cec5SDimitry Andric#endif
22430b57cec5SDimitry Andric        for (; __n > 0; ++__f, (void) --__n)
2244e8d8bef9SDimitry Andric            ::new ((void*)_VSTD::addressof(*__f)) value_type(__x);
22450b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22460b57cec5SDimitry Andric    }
22470b57cec5SDimitry Andric    catch (...)
22480b57cec5SDimitry Andric    {
22490b57cec5SDimitry Andric        for (; __s != __f; ++__s)
22500b57cec5SDimitry Andric            __s->~value_type();
22510b57cec5SDimitry Andric        throw;
22520b57cec5SDimitry Andric    }
22530b57cec5SDimitry Andric#endif
22540b57cec5SDimitry Andric    return __f;
22550b57cec5SDimitry Andric}
22560b57cec5SDimitry Andric
22570b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
22580b57cec5SDimitry Andric
22590b57cec5SDimitry Andrictemplate <class _ForwardIterator>
2260e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
22610b57cec5SDimitry Andricvoid destroy(_ForwardIterator __first, _ForwardIterator __last) {
22620b57cec5SDimitry Andric    for (; __first != __last; ++__first)
22630b57cec5SDimitry Andric        _VSTD::destroy_at(_VSTD::addressof(*__first));
22640b57cec5SDimitry Andric}
22650b57cec5SDimitry Andric
22660b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size>
2267e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
22680b57cec5SDimitry Andric_ForwardIterator destroy_n(_ForwardIterator __first, _Size __n) {
22690b57cec5SDimitry Andric    for (; __n > 0; (void)++__first, --__n)
22700b57cec5SDimitry Andric        _VSTD::destroy_at(_VSTD::addressof(*__first));
22710b57cec5SDimitry Andric    return __first;
22720b57cec5SDimitry Andric}
22730b57cec5SDimitry Andric
22740b57cec5SDimitry Andrictemplate <class _ForwardIterator>
22750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
22760b57cec5SDimitry Andricvoid uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) {
22770b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
22780b57cec5SDimitry Andric    auto __idx = __first;
22790b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22800b57cec5SDimitry Andric    try {
22810b57cec5SDimitry Andric#endif
22820b57cec5SDimitry Andric    for (; __idx != __last; ++__idx)
22830b57cec5SDimitry Andric        ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
22840b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22850b57cec5SDimitry Andric    } catch (...) {
22860b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
22870b57cec5SDimitry Andric        throw;
22880b57cec5SDimitry Andric    }
22890b57cec5SDimitry Andric#endif
22900b57cec5SDimitry Andric}
22910b57cec5SDimitry Andric
22920b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size>
22930b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
22940b57cec5SDimitry Andric_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) {
22950b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
22960b57cec5SDimitry Andric    auto __idx = __first;
22970b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
22980b57cec5SDimitry Andric    try {
22990b57cec5SDimitry Andric#endif
23000b57cec5SDimitry Andric    for (; __n > 0; (void)++__idx, --__n)
23010b57cec5SDimitry Andric        ::new ((void*)_VSTD::addressof(*__idx)) _Vt;
23020b57cec5SDimitry Andric    return __idx;
23030b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23040b57cec5SDimitry Andric    } catch (...) {
23050b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
23060b57cec5SDimitry Andric        throw;
23070b57cec5SDimitry Andric    }
23080b57cec5SDimitry Andric#endif
23090b57cec5SDimitry Andric}
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andric
23120b57cec5SDimitry Andrictemplate <class _ForwardIterator>
23130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23140b57cec5SDimitry Andricvoid uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) {
23150b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
23160b57cec5SDimitry Andric    auto __idx = __first;
23170b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23180b57cec5SDimitry Andric    try {
23190b57cec5SDimitry Andric#endif
23200b57cec5SDimitry Andric    for (; __idx != __last; ++__idx)
23210b57cec5SDimitry Andric        ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
23220b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23230b57cec5SDimitry Andric    } catch (...) {
23240b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
23250b57cec5SDimitry Andric        throw;
23260b57cec5SDimitry Andric    }
23270b57cec5SDimitry Andric#endif
23280b57cec5SDimitry Andric}
23290b57cec5SDimitry Andric
23300b57cec5SDimitry Andrictemplate <class _ForwardIterator, class _Size>
23310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23320b57cec5SDimitry Andric_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) {
23330b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
23340b57cec5SDimitry Andric    auto __idx = __first;
23350b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23360b57cec5SDimitry Andric    try {
23370b57cec5SDimitry Andric#endif
23380b57cec5SDimitry Andric    for (; __n > 0; (void)++__idx, --__n)
23390b57cec5SDimitry Andric        ::new ((void*)_VSTD::addressof(*__idx)) _Vt();
23400b57cec5SDimitry Andric    return __idx;
23410b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23420b57cec5SDimitry Andric    } catch (...) {
23430b57cec5SDimitry Andric        _VSTD::destroy(__first, __idx);
23440b57cec5SDimitry Andric        throw;
23450b57cec5SDimitry Andric    }
23460b57cec5SDimitry Andric#endif
23470b57cec5SDimitry Andric}
23480b57cec5SDimitry Andric
23490b57cec5SDimitry Andric
23500b57cec5SDimitry Andrictemplate <class _InputIt, class _ForwardIt>
23510b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23520b57cec5SDimitry Andric_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt __first_res) {
23530b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
23540b57cec5SDimitry Andric    auto __idx = __first_res;
23550b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23560b57cec5SDimitry Andric    try {
23570b57cec5SDimitry Andric#endif
23580b57cec5SDimitry Andric    for (; __first != __last; (void)++__idx, ++__first)
2359e8d8bef9SDimitry Andric        ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
23600b57cec5SDimitry Andric    return __idx;
23610b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23620b57cec5SDimitry Andric    } catch (...) {
23630b57cec5SDimitry Andric        _VSTD::destroy(__first_res, __idx);
23640b57cec5SDimitry Andric        throw;
23650b57cec5SDimitry Andric    }
23660b57cec5SDimitry Andric#endif
23670b57cec5SDimitry Andric}
23680b57cec5SDimitry Andric
23690b57cec5SDimitry Andrictemplate <class _InputIt, class _Size, class _ForwardIt>
23700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23710b57cec5SDimitry Andricpair<_InputIt, _ForwardIt>
23720b57cec5SDimitry Andricuninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __first_res) {
23730b57cec5SDimitry Andric    using _Vt = typename iterator_traits<_ForwardIt>::value_type;
23740b57cec5SDimitry Andric    auto __idx = __first_res;
23750b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23760b57cec5SDimitry Andric    try {
23770b57cec5SDimitry Andric#endif
23780b57cec5SDimitry Andric    for (; __n > 0; ++__idx, (void)++__first, --__n)
2379e8d8bef9SDimitry Andric        ::new ((void*)_VSTD::addressof(*__idx)) _Vt(_VSTD::move(*__first));
23800b57cec5SDimitry Andric    return {__first, __idx};
23810b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
23820b57cec5SDimitry Andric    } catch (...) {
23830b57cec5SDimitry Andric        _VSTD::destroy(__first_res, __idx);
23840b57cec5SDimitry Andric        throw;
23850b57cec5SDimitry Andric    }
23860b57cec5SDimitry Andric#endif
23870b57cec5SDimitry Andric}
23880b57cec5SDimitry Andric
23890b57cec5SDimitry Andric
23900b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
23910b57cec5SDimitry Andric
23920b57cec5SDimitry Andric// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
23930b57cec5SDimitry Andric// should be sufficient for thread safety.
23940b57cec5SDimitry Andric// See https://bugs.llvm.org/show_bug.cgi?id=22803
23950b57cec5SDimitry Andric#if defined(__clang__) && __has_builtin(__atomic_add_fetch)          \
23960b57cec5SDimitry Andric                       && defined(__ATOMIC_RELAXED)                  \
23970b57cec5SDimitry Andric                       && defined(__ATOMIC_ACQ_REL)
23980b57cec5SDimitry Andric#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
23990b57cec5SDimitry Andric#elif defined(_LIBCPP_COMPILER_GCC)
24000b57cec5SDimitry Andric#   define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
24010b57cec5SDimitry Andric#endif
24020b57cec5SDimitry Andric
24030b57cec5SDimitry Andrictemplate <class _Tp>
24040b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _Tp
24050b57cec5SDimitry Andric__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
24060b57cec5SDimitry Andric{
24070b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
24080b57cec5SDimitry Andric    return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
24090b57cec5SDimitry Andric#else
24100b57cec5SDimitry Andric    return __t += 1;
24110b57cec5SDimitry Andric#endif
24120b57cec5SDimitry Andric}
24130b57cec5SDimitry Andric
24140b57cec5SDimitry Andrictemplate <class _Tp>
24150b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _Tp
24160b57cec5SDimitry Andric__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
24170b57cec5SDimitry Andric{
24180b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
24190b57cec5SDimitry Andric    return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
24200b57cec5SDimitry Andric#else
24210b57cec5SDimitry Andric    return __t -= 1;
24220b57cec5SDimitry Andric#endif
24230b57cec5SDimitry Andric}
24240b57cec5SDimitry Andric
24250b57cec5SDimitry Andricclass _LIBCPP_EXCEPTION_ABI bad_weak_ptr
24260b57cec5SDimitry Andric    : public std::exception
24270b57cec5SDimitry Andric{
24280b57cec5SDimitry Andricpublic:
24299ec406dcSDimitry Andric    bad_weak_ptr() _NOEXCEPT = default;
24309ec406dcSDimitry Andric    bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPT = default;
24310b57cec5SDimitry Andric    virtual ~bad_weak_ptr() _NOEXCEPT;
24320b57cec5SDimitry Andric    virtual const char* what() const  _NOEXCEPT;
24330b57cec5SDimitry Andric};
24340b57cec5SDimitry Andric
24350b57cec5SDimitry Andric_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY
24360b57cec5SDimitry Andricvoid __throw_bad_weak_ptr()
24370b57cec5SDimitry Andric{
24380b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
24390b57cec5SDimitry Andric    throw bad_weak_ptr();
24400b57cec5SDimitry Andric#else
24410b57cec5SDimitry Andric    _VSTD::abort();
24420b57cec5SDimitry Andric#endif
24430b57cec5SDimitry Andric}
24440b57cec5SDimitry Andric
24450b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS weak_ptr;
24460b57cec5SDimitry Andric
24470b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __shared_count
24480b57cec5SDimitry Andric{
24490b57cec5SDimitry Andric    __shared_count(const __shared_count&);
24500b57cec5SDimitry Andric    __shared_count& operator=(const __shared_count&);
24510b57cec5SDimitry Andric
24520b57cec5SDimitry Andricprotected:
24530b57cec5SDimitry Andric    long __shared_owners_;
24540b57cec5SDimitry Andric    virtual ~__shared_count();
24550b57cec5SDimitry Andricprivate:
24560b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT = 0;
24570b57cec5SDimitry Andric
24580b57cec5SDimitry Andricpublic:
24590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24600b57cec5SDimitry Andric    explicit __shared_count(long __refs = 0) _NOEXCEPT
24610b57cec5SDimitry Andric        : __shared_owners_(__refs) {}
24620b57cec5SDimitry Andric
24630b57cec5SDimitry Andric#if defined(_LIBCPP_BUILDING_LIBRARY) && \
24640b57cec5SDimitry Andric    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
24650b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT;
24660b57cec5SDimitry Andric    bool __release_shared() _NOEXCEPT;
24670b57cec5SDimitry Andric#else
24680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24690b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT {
24700b57cec5SDimitry Andric      __libcpp_atomic_refcount_increment(__shared_owners_);
24710b57cec5SDimitry Andric    }
24720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24730b57cec5SDimitry Andric    bool __release_shared() _NOEXCEPT {
24740b57cec5SDimitry Andric      if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
24750b57cec5SDimitry Andric        __on_zero_shared();
24760b57cec5SDimitry Andric        return true;
24770b57cec5SDimitry Andric      }
24780b57cec5SDimitry Andric      return false;
24790b57cec5SDimitry Andric    }
24800b57cec5SDimitry Andric#endif
24810b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24820b57cec5SDimitry Andric    long use_count() const _NOEXCEPT {
24830b57cec5SDimitry Andric        return __libcpp_relaxed_load(&__shared_owners_) + 1;
24840b57cec5SDimitry Andric    }
24850b57cec5SDimitry Andric};
24860b57cec5SDimitry Andric
24870b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __shared_weak_count
24880b57cec5SDimitry Andric    : private __shared_count
24890b57cec5SDimitry Andric{
24900b57cec5SDimitry Andric    long __shared_weak_owners_;
24910b57cec5SDimitry Andric
24920b57cec5SDimitry Andricpublic:
24930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
24940b57cec5SDimitry Andric    explicit __shared_weak_count(long __refs = 0) _NOEXCEPT
24950b57cec5SDimitry Andric        : __shared_count(__refs),
24960b57cec5SDimitry Andric          __shared_weak_owners_(__refs) {}
24970b57cec5SDimitry Andricprotected:
24980b57cec5SDimitry Andric    virtual ~__shared_weak_count();
24990b57cec5SDimitry Andric
25000b57cec5SDimitry Andricpublic:
25010b57cec5SDimitry Andric#if defined(_LIBCPP_BUILDING_LIBRARY) && \
25020b57cec5SDimitry Andric    defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
25030b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT;
25040b57cec5SDimitry Andric    void __add_weak() _NOEXCEPT;
25050b57cec5SDimitry Andric    void __release_shared() _NOEXCEPT;
25060b57cec5SDimitry Andric#else
25070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25080b57cec5SDimitry Andric    void __add_shared() _NOEXCEPT {
25090b57cec5SDimitry Andric      __shared_count::__add_shared();
25100b57cec5SDimitry Andric    }
25110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25120b57cec5SDimitry Andric    void __add_weak() _NOEXCEPT {
25130b57cec5SDimitry Andric      __libcpp_atomic_refcount_increment(__shared_weak_owners_);
25140b57cec5SDimitry Andric    }
25150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25160b57cec5SDimitry Andric    void __release_shared() _NOEXCEPT {
25170b57cec5SDimitry Andric      if (__shared_count::__release_shared())
25180b57cec5SDimitry Andric        __release_weak();
25190b57cec5SDimitry Andric    }
25200b57cec5SDimitry Andric#endif
25210b57cec5SDimitry Andric    void __release_weak() _NOEXCEPT;
25220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25230b57cec5SDimitry Andric    long use_count() const _NOEXCEPT {return __shared_count::use_count();}
25240b57cec5SDimitry Andric    __shared_weak_count* lock() _NOEXCEPT;
25250b57cec5SDimitry Andric
25260b57cec5SDimitry Andric    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
25270b57cec5SDimitry Andricprivate:
25280b57cec5SDimitry Andric    virtual void __on_zero_shared_weak() _NOEXCEPT = 0;
25290b57cec5SDimitry Andric};
25300b57cec5SDimitry Andric
25310b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
25320b57cec5SDimitry Andricclass __shared_ptr_pointer
25330b57cec5SDimitry Andric    : public __shared_weak_count
25340b57cec5SDimitry Andric{
25350b57cec5SDimitry Andric    __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
25360b57cec5SDimitry Andricpublic:
25370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25380b57cec5SDimitry Andric    __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
25390b57cec5SDimitry Andric        :  __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTD::move(__d)), _VSTD::move(__a)) {}
25400b57cec5SDimitry Andric
25410b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
25420b57cec5SDimitry Andric    virtual const void* __get_deleter(const type_info&) const _NOEXCEPT;
25430b57cec5SDimitry Andric#endif
25440b57cec5SDimitry Andric
25450b57cec5SDimitry Andricprivate:
25460b57cec5SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT;
25470b57cec5SDimitry Andric    virtual void __on_zero_shared_weak() _NOEXCEPT;
25480b57cec5SDimitry Andric};
25490b57cec5SDimitry Andric
25500b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
25510b57cec5SDimitry Andric
25520b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
25530b57cec5SDimitry Andricconst void*
25540b57cec5SDimitry Andric__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
25550b57cec5SDimitry Andric{
25560b57cec5SDimitry Andric    return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
25570b57cec5SDimitry Andric}
25580b57cec5SDimitry Andric
25590b57cec5SDimitry Andric#endif  // _LIBCPP_NO_RTTI
25600b57cec5SDimitry Andric
25610b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
25620b57cec5SDimitry Andricvoid
25630b57cec5SDimitry Andric__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPT
25640b57cec5SDimitry Andric{
25650b57cec5SDimitry Andric    __data_.first().second()(__data_.first().first());
25660b57cec5SDimitry Andric    __data_.first().second().~_Dp();
25670b57cec5SDimitry Andric}
25680b57cec5SDimitry Andric
25690b57cec5SDimitry Andrictemplate <class _Tp, class _Dp, class _Alloc>
25700b57cec5SDimitry Andricvoid
25710b57cec5SDimitry Andric__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPT
25720b57cec5SDimitry Andric{
25730b57cec5SDimitry Andric    typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
25740b57cec5SDimitry Andric    typedef allocator_traits<_Al> _ATraits;
25750b57cec5SDimitry Andric    typedef pointer_traits<typename _ATraits::pointer> _PTraits;
25760b57cec5SDimitry Andric
25770b57cec5SDimitry Andric    _Al __a(__data_.second());
25780b57cec5SDimitry Andric    __data_.second().~_Alloc();
25790b57cec5SDimitry Andric    __a.deallocate(_PTraits::pointer_to(*this), 1);
25800b57cec5SDimitry Andric}
25810b57cec5SDimitry Andric
25820b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
2583e8d8bef9SDimitry Andricstruct __shared_ptr_emplace
2584e8d8bef9SDimitry Andric    : __shared_weak_count
25850b57cec5SDimitry Andric{
25860b57cec5SDimitry Andric    template<class ..._Args>
2587e8d8bef9SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2588e8d8bef9SDimitry Andric    explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
2589e8d8bef9SDimitry Andric        : __storage_(_VSTD::move(__a))
2590e8d8bef9SDimitry Andric    {
2591e8d8bef9SDimitry Andric#if _LIBCPP_STD_VER > 17
2592e8d8bef9SDimitry Andric        using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
2593e8d8bef9SDimitry Andric        _TpAlloc __tmp(*__get_alloc());
2594e8d8bef9SDimitry Andric        allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...);
2595e8d8bef9SDimitry Andric#else
2596e8d8bef9SDimitry Andric        ::new ((void*)__get_elem()) _Tp(_VSTD::forward<_Args>(__args)...);
2597e8d8bef9SDimitry Andric#endif
2598e8d8bef9SDimitry Andric    }
25990b57cec5SDimitry Andric
2600e8d8bef9SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2601e8d8bef9SDimitry Andric    _Alloc* __get_alloc() _NOEXCEPT { return __storage_.__get_alloc(); }
26020b57cec5SDimitry Andric
2603e8d8bef9SDimitry Andric    _LIBCPP_HIDE_FROM_ABI
2604e8d8bef9SDimitry Andric    _Tp* __get_elem() _NOEXCEPT { return __storage_.__get_elem(); }
26050b57cec5SDimitry Andric
26060b57cec5SDimitry Andricprivate:
2607e8d8bef9SDimitry Andric    virtual void __on_zero_shared() _NOEXCEPT {
2608e8d8bef9SDimitry Andric#if _LIBCPP_STD_VER > 17
2609e8d8bef9SDimitry Andric        using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
2610e8d8bef9SDimitry Andric        _TpAlloc __tmp(*__get_alloc());
2611e8d8bef9SDimitry Andric        allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
2612e8d8bef9SDimitry Andric#else
2613e8d8bef9SDimitry Andric        __get_elem()->~_Tp();
2614e8d8bef9SDimitry Andric#endif
2615e8d8bef9SDimitry Andric    }
2616e8d8bef9SDimitry Andric
2617e8d8bef9SDimitry Andric    virtual void __on_zero_shared_weak() _NOEXCEPT {
2618e8d8bef9SDimitry Andric        using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
2619e8d8bef9SDimitry Andric        using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
2620e8d8bef9SDimitry Andric        _ControlBlockAlloc __tmp(*__get_alloc());
2621e8d8bef9SDimitry Andric        __storage_.~_Storage();
2622e8d8bef9SDimitry Andric        allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
2623e8d8bef9SDimitry Andric            pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
2624e8d8bef9SDimitry Andric    }
2625e8d8bef9SDimitry Andric
2626e8d8bef9SDimitry Andric    // This class implements the control block for non-array shared pointers created
2627e8d8bef9SDimitry Andric    // through `std::allocate_shared` and `std::make_shared`.
2628e8d8bef9SDimitry Andric    //
2629e8d8bef9SDimitry Andric    // In previous versions of the library, we used a compressed pair to store
2630e8d8bef9SDimitry Andric    // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
2631e8d8bef9SDimitry Andric    // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
2632e8d8bef9SDimitry Andric    // we now use a properly aligned char buffer while making sure that we maintain
2633e8d8bef9SDimitry Andric    // the same layout that we had when we used a compressed pair.
2634e8d8bef9SDimitry Andric    using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
2635e8d8bef9SDimitry Andric    struct _ALIGNAS_TYPE(_CompressedPair) _Storage {
2636e8d8bef9SDimitry Andric        char __blob_[sizeof(_CompressedPair)];
2637e8d8bef9SDimitry Andric
2638e8d8bef9SDimitry Andric        _LIBCPP_HIDE_FROM_ABI explicit _Storage(_Alloc&& __a) {
2639e8d8bef9SDimitry Andric            ::new ((void*)__get_alloc()) _Alloc(_VSTD::move(__a));
2640e8d8bef9SDimitry Andric        }
2641e8d8bef9SDimitry Andric        _LIBCPP_HIDE_FROM_ABI ~_Storage() {
2642e8d8bef9SDimitry Andric            __get_alloc()->~_Alloc();
2643e8d8bef9SDimitry Andric        }
2644e8d8bef9SDimitry Andric        _Alloc* __get_alloc() _NOEXCEPT {
2645e8d8bef9SDimitry Andric            _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
2646e8d8bef9SDimitry Andric            typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
2647e8d8bef9SDimitry Andric            _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
2648e8d8bef9SDimitry Andric            return __alloc;
2649e8d8bef9SDimitry Andric        }
2650d409305fSDimitry Andric        _LIBCPP_NO_CFI _Tp* __get_elem() _NOEXCEPT {
2651e8d8bef9SDimitry Andric            _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
2652e8d8bef9SDimitry Andric            typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
2653e8d8bef9SDimitry Andric            _Tp *__elem = reinterpret_cast<_Tp*>(__second);
2654e8d8bef9SDimitry Andric            return __elem;
2655e8d8bef9SDimitry Andric        }
26560b57cec5SDimitry Andric    };
26570b57cec5SDimitry Andric
2658e8d8bef9SDimitry Andric    static_assert(_LIBCPP_ALIGNOF(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair), "");
2659e8d8bef9SDimitry Andric    static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
2660e8d8bef9SDimitry Andric    _Storage __storage_;
2661e8d8bef9SDimitry Andric};
26620b57cec5SDimitry Andric
26630b57cec5SDimitry Andricstruct __shared_ptr_dummy_rebind_allocator_type;
26640b57cec5SDimitry Andrictemplate <>
26650b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS allocator<__shared_ptr_dummy_rebind_allocator_type>
26660b57cec5SDimitry Andric{
26670b57cec5SDimitry Andricpublic:
26680b57cec5SDimitry Andric    template <class _Other>
26690b57cec5SDimitry Andric    struct rebind
26700b57cec5SDimitry Andric    {
26710b57cec5SDimitry Andric        typedef allocator<_Other> other;
26720b57cec5SDimitry Andric    };
26730b57cec5SDimitry Andric};
26740b57cec5SDimitry Andric
26750b57cec5SDimitry Andrictemplate<class _Tp> class _LIBCPP_TEMPLATE_VIS enable_shared_from_this;
26760b57cec5SDimitry Andric
26775ffd83dbSDimitry Andrictemplate<class _Tp, class _Up>
26785ffd83dbSDimitry Andricstruct __compatible_with
26795ffd83dbSDimitry Andric#if _LIBCPP_STD_VER > 14
26805ffd83dbSDimitry Andric    : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
26815ffd83dbSDimitry Andric#else
26825ffd83dbSDimitry Andric    : is_convertible<_Tp*, _Up*> {};
26835ffd83dbSDimitry Andric#endif // _LIBCPP_STD_VER > 14
26845ffd83dbSDimitry Andric
2685e8d8bef9SDimitry Andric#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
2686e8d8bef9SDimitry Andric#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
2687e8d8bef9SDimitry Andric#else
2688e8d8bef9SDimitry Andric#  define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
2689e8d8bef9SDimitry Andric#endif
2690e8d8bef9SDimitry Andric
26910b57cec5SDimitry Andrictemplate<class _Tp>
2692e8d8bef9SDimitry Andricclass _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
26930b57cec5SDimitry Andric{
26940b57cec5SDimitry Andricpublic:
26950b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
26960b57cec5SDimitry Andric    typedef weak_ptr<_Tp> weak_type;
26975ffd83dbSDimitry Andric    typedef remove_extent_t<_Tp> element_type;
26985ffd83dbSDimitry Andric#else
26995ffd83dbSDimitry Andric    typedef _Tp element_type;
27000b57cec5SDimitry Andric#endif
27015ffd83dbSDimitry Andric
27020b57cec5SDimitry Andricprivate:
27030b57cec5SDimitry Andric    element_type*      __ptr_;
27040b57cec5SDimitry Andric    __shared_weak_count* __cntrl_;
27050b57cec5SDimitry Andric
27060b57cec5SDimitry Andric    struct __nat {int __for_bool_;};
27070b57cec5SDimitry Andricpublic:
27080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27090b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR shared_ptr() _NOEXCEPT;
27100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27110b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR shared_ptr(nullptr_t) _NOEXCEPT;
27120b57cec5SDimitry Andric    template<class _Yp>
27130b57cec5SDimitry Andric        explicit shared_ptr(_Yp* __p,
27145ffd83dbSDimitry Andric                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
27150b57cec5SDimitry Andric    template<class _Yp, class _Dp>
27160b57cec5SDimitry Andric        shared_ptr(_Yp* __p, _Dp __d,
27175ffd83dbSDimitry Andric                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
27180b57cec5SDimitry Andric    template<class _Yp, class _Dp, class _Alloc>
27190b57cec5SDimitry Andric        shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
27205ffd83dbSDimitry Andric                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat());
27210b57cec5SDimitry Andric    template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
27220b57cec5SDimitry Andric    template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
27230b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPT;
27240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27250b57cec5SDimitry Andric    shared_ptr(const shared_ptr& __r) _NOEXCEPT;
27260b57cec5SDimitry Andric    template<class _Yp>
27270b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
27280b57cec5SDimitry Andric        shared_ptr(const shared_ptr<_Yp>& __r,
27295ffd83dbSDimitry Andric                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
27300b57cec5SDimitry Andric                       _NOEXCEPT;
27310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27320b57cec5SDimitry Andric    shared_ptr(shared_ptr&& __r) _NOEXCEPT;
27330b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY  shared_ptr(shared_ptr<_Yp>&& __r,
27345ffd83dbSDimitry Andric                   typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
27350b57cec5SDimitry Andric                       _NOEXCEPT;
27360b57cec5SDimitry Andric    template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
27370b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
27380b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
27390b57cec5SDimitry Andric    template<class _Yp>
27400b57cec5SDimitry Andric        shared_ptr(auto_ptr<_Yp>&& __r,
27410b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
27420b57cec5SDimitry Andric#endif
27430b57cec5SDimitry Andric    template <class _Yp, class _Dp>
27440b57cec5SDimitry Andric        shared_ptr(unique_ptr<_Yp, _Dp>&&,
27450b57cec5SDimitry Andric                   typename enable_if
27460b57cec5SDimitry Andric                   <
27470b57cec5SDimitry Andric                       !is_lvalue_reference<_Dp>::value &&
27480b57cec5SDimitry Andric                       !is_array<_Yp>::value &&
27490b57cec5SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
27500b57cec5SDimitry Andric                       __nat
27510b57cec5SDimitry Andric                   >::type = __nat());
27520b57cec5SDimitry Andric    template <class _Yp, class _Dp>
27530b57cec5SDimitry Andric        shared_ptr(unique_ptr<_Yp, _Dp>&&,
27540b57cec5SDimitry Andric                   typename enable_if
27550b57cec5SDimitry Andric                   <
27560b57cec5SDimitry Andric                       is_lvalue_reference<_Dp>::value &&
27570b57cec5SDimitry Andric                       !is_array<_Yp>::value &&
27580b57cec5SDimitry Andric                       is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
27590b57cec5SDimitry Andric                       __nat
27600b57cec5SDimitry Andric                   >::type = __nat());
27610b57cec5SDimitry Andric
27620b57cec5SDimitry Andric    ~shared_ptr();
27630b57cec5SDimitry Andric
27640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27650b57cec5SDimitry Andric    shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPT;
27660b57cec5SDimitry Andric    template<class _Yp>
27670b57cec5SDimitry Andric        typename enable_if
27680b57cec5SDimitry Andric        <
27695ffd83dbSDimitry Andric            __compatible_with<_Yp, element_type>::value,
27700b57cec5SDimitry Andric            shared_ptr&
27710b57cec5SDimitry Andric        >::type
27720b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
27730b57cec5SDimitry Andric        operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT;
27740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
27750b57cec5SDimitry Andric    shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPT;
27760b57cec5SDimitry Andric    template<class _Yp>
27770b57cec5SDimitry Andric        typename enable_if
27780b57cec5SDimitry Andric        <
27795ffd83dbSDimitry Andric            __compatible_with<_Yp, element_type>::value,
27805ffd83dbSDimitry Andric            shared_ptr&
27810b57cec5SDimitry Andric        >::type
27820b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
27830b57cec5SDimitry Andric        operator=(shared_ptr<_Yp>&& __r);
27840b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
27850b57cec5SDimitry Andric    template<class _Yp>
27860b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
27870b57cec5SDimitry Andric        typename enable_if
27880b57cec5SDimitry Andric        <
27890b57cec5SDimitry Andric            !is_array<_Yp>::value &&
27900b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
27910b57cec5SDimitry Andric            shared_ptr
27920b57cec5SDimitry Andric        >::type&
27930b57cec5SDimitry Andric        operator=(auto_ptr<_Yp>&& __r);
27940b57cec5SDimitry Andric#endif
27950b57cec5SDimitry Andric    template <class _Yp, class _Dp>
27960b57cec5SDimitry Andric        typename enable_if
27970b57cec5SDimitry Andric        <
27980b57cec5SDimitry Andric            !is_array<_Yp>::value &&
27990b57cec5SDimitry Andric            is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
28000b57cec5SDimitry Andric            shared_ptr&
28010b57cec5SDimitry Andric        >::type
28020b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
28030b57cec5SDimitry Andric        operator=(unique_ptr<_Yp, _Dp>&& __r);
28040b57cec5SDimitry Andric
28050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28060b57cec5SDimitry Andric    void swap(shared_ptr& __r) _NOEXCEPT;
28070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28080b57cec5SDimitry Andric    void reset() _NOEXCEPT;
28090b57cec5SDimitry Andric    template<class _Yp>
28100b57cec5SDimitry Andric        typename enable_if
28110b57cec5SDimitry Andric        <
28125ffd83dbSDimitry Andric            __compatible_with<_Yp, element_type>::value,
28130b57cec5SDimitry Andric            void
28140b57cec5SDimitry Andric        >::type
28150b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
28160b57cec5SDimitry Andric        reset(_Yp* __p);
28170b57cec5SDimitry Andric    template<class _Yp, class _Dp>
28180b57cec5SDimitry Andric        typename enable_if
28190b57cec5SDimitry Andric        <
28205ffd83dbSDimitry Andric            __compatible_with<_Yp, element_type>::value,
28210b57cec5SDimitry Andric            void
28220b57cec5SDimitry Andric        >::type
28230b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
28240b57cec5SDimitry Andric        reset(_Yp* __p, _Dp __d);
28250b57cec5SDimitry Andric    template<class _Yp, class _Dp, class _Alloc>
28260b57cec5SDimitry Andric        typename enable_if
28270b57cec5SDimitry Andric        <
28285ffd83dbSDimitry Andric            __compatible_with<_Yp, element_type>::value,
28290b57cec5SDimitry Andric            void
28300b57cec5SDimitry Andric        >::type
28310b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
28320b57cec5SDimitry Andric        reset(_Yp* __p, _Dp __d, _Alloc __a);
28330b57cec5SDimitry Andric
28340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28350b57cec5SDimitry Andric    element_type* get() const _NOEXCEPT {return __ptr_;}
28360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28370b57cec5SDimitry Andric    typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPT
28380b57cec5SDimitry Andric        {return *__ptr_;}
28390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28405ffd83dbSDimitry Andric    element_type* operator->() const _NOEXCEPT
28415ffd83dbSDimitry Andric    {
28425ffd83dbSDimitry Andric        static_assert(!_VSTD::is_array<_Tp>::value,
28435ffd83dbSDimitry Andric                      "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
28445ffd83dbSDimitry Andric        return __ptr_;
28455ffd83dbSDimitry Andric    }
28460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28470b57cec5SDimitry Andric    long use_count() const _NOEXCEPT {return __cntrl_ ? __cntrl_->use_count() : 0;}
28480b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28490b57cec5SDimitry Andric    bool unique() const _NOEXCEPT {return use_count() == 1;}
28500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2851e8d8bef9SDimitry Andric    _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT {return get() != nullptr;}
28520b57cec5SDimitry Andric    template <class _Up>
28530b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
28540b57cec5SDimitry Andric        bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPT
28550b57cec5SDimitry Andric        {return __cntrl_ < __p.__cntrl_;}
28560b57cec5SDimitry Andric    template <class _Up>
28570b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
28580b57cec5SDimitry Andric        bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPT
28590b57cec5SDimitry Andric        {return __cntrl_ < __p.__cntrl_;}
28600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28610b57cec5SDimitry Andric    bool
28620b57cec5SDimitry Andric    __owner_equivalent(const shared_ptr& __p) const
28630b57cec5SDimitry Andric        {return __cntrl_ == __p.__cntrl_;}
28640b57cec5SDimitry Andric
28655ffd83dbSDimitry Andric#if _LIBCPP_STD_VER > 14
28665ffd83dbSDimitry Andric    typename add_lvalue_reference<element_type>::type
28675ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
28685ffd83dbSDimitry Andric    operator[](ptrdiff_t __i) const
28695ffd83dbSDimitry Andric    {
28705ffd83dbSDimitry Andric            static_assert(_VSTD::is_array<_Tp>::value,
28715ffd83dbSDimitry Andric                          "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
28725ffd83dbSDimitry Andric            return __ptr_[__i];
28735ffd83dbSDimitry Andric    }
28745ffd83dbSDimitry Andric#endif
28755ffd83dbSDimitry Andric
28760b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
28770b57cec5SDimitry Andric    template <class _Dp>
28780b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
28790b57cec5SDimitry Andric        _Dp* __get_deleter() const _NOEXCEPT
28800b57cec5SDimitry Andric            {return static_cast<_Dp*>(__cntrl_
28810b57cec5SDimitry Andric                    ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
28820b57cec5SDimitry Andric                      : nullptr);}
28830b57cec5SDimitry Andric#endif  // _LIBCPP_NO_RTTI
28840b57cec5SDimitry Andric
2885e40139ffSDimitry Andric    template<class _Yp, class _CntrlBlk>
2886e40139ffSDimitry Andric    static shared_ptr<_Tp>
28875ffd83dbSDimitry Andric    __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
2888e40139ffSDimitry Andric    {
2889e40139ffSDimitry Andric        shared_ptr<_Tp> __r;
2890e40139ffSDimitry Andric        __r.__ptr_ = __p;
2891e40139ffSDimitry Andric        __r.__cntrl_ = __cntrl;
2892e40139ffSDimitry Andric        __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
2893e40139ffSDimitry Andric        return __r;
2894e40139ffSDimitry Andric    }
28950b57cec5SDimitry Andric
28960b57cec5SDimitry Andricprivate:
28970b57cec5SDimitry Andric    template <class _Yp, bool = is_function<_Yp>::value>
28980b57cec5SDimitry Andric        struct __shared_ptr_default_allocator
28990b57cec5SDimitry Andric        {
29000b57cec5SDimitry Andric            typedef allocator<_Yp> type;
29010b57cec5SDimitry Andric        };
29020b57cec5SDimitry Andric
29030b57cec5SDimitry Andric    template <class _Yp>
29040b57cec5SDimitry Andric        struct __shared_ptr_default_allocator<_Yp, true>
29050b57cec5SDimitry Andric        {
29060b57cec5SDimitry Andric            typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
29070b57cec5SDimitry Andric        };
29080b57cec5SDimitry Andric
29090b57cec5SDimitry Andric    template <class _Yp, class _OrigPtr>
29100b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
29110b57cec5SDimitry Andric        typename enable_if<is_convertible<_OrigPtr*,
29120b57cec5SDimitry Andric                                          const enable_shared_from_this<_Yp>*
29130b57cec5SDimitry Andric        >::value,
29140b57cec5SDimitry Andric            void>::type
29150b57cec5SDimitry Andric        __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
29160b57cec5SDimitry Andric                           _OrigPtr* __ptr) _NOEXCEPT
29170b57cec5SDimitry Andric        {
29180b57cec5SDimitry Andric            typedef typename remove_cv<_Yp>::type _RawYp;
29190b57cec5SDimitry Andric            if (__e && __e->__weak_this_.expired())
29200b57cec5SDimitry Andric            {
29210b57cec5SDimitry Andric                __e->__weak_this_ = shared_ptr<_RawYp>(*this,
29220b57cec5SDimitry Andric                    const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
29230b57cec5SDimitry Andric            }
29240b57cec5SDimitry Andric        }
29250b57cec5SDimitry Andric
29260b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void __enable_weak_this(...) _NOEXCEPT {}
29270b57cec5SDimitry Andric
29285ffd83dbSDimitry Andric    template <class, class _Yp>
29295ffd83dbSDimitry Andric        struct __shared_ptr_default_delete
29305ffd83dbSDimitry Andric            : default_delete<_Yp> {};
29315ffd83dbSDimitry Andric
29325ffd83dbSDimitry Andric    template <class _Yp, class _Un, size_t _Sz>
29335ffd83dbSDimitry Andric        struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
29345ffd83dbSDimitry Andric            : default_delete<_Yp[]> {};
29355ffd83dbSDimitry Andric
29365ffd83dbSDimitry Andric    template <class _Yp, class _Un>
29375ffd83dbSDimitry Andric        struct __shared_ptr_default_delete<_Yp[], _Un>
29385ffd83dbSDimitry Andric            : default_delete<_Yp[]> {};
29395ffd83dbSDimitry Andric
29400b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
29410b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
29420b57cec5SDimitry Andric};
29430b57cec5SDimitry Andric
29445ffd83dbSDimitry Andric#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
29455ffd83dbSDimitry Andrictemplate<class _Tp>
29465ffd83dbSDimitry Andricshared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
29475ffd83dbSDimitry Andrictemplate<class _Tp, class _Dp>
29485ffd83dbSDimitry Andricshared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
29495ffd83dbSDimitry Andric#endif
29500b57cec5SDimitry Andric
29510b57cec5SDimitry Andrictemplate<class _Tp>
29520b57cec5SDimitry Andricinline
29530b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
29540b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr() _NOEXCEPT
2955e8d8bef9SDimitry Andric    : __ptr_(nullptr),
2956e8d8bef9SDimitry Andric      __cntrl_(nullptr)
29570b57cec5SDimitry Andric{
29580b57cec5SDimitry Andric}
29590b57cec5SDimitry Andric
29600b57cec5SDimitry Andrictemplate<class _Tp>
29610b57cec5SDimitry Andricinline
29620b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
29630b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPT
2964e8d8bef9SDimitry Andric    : __ptr_(nullptr),
2965e8d8bef9SDimitry Andric      __cntrl_(nullptr)
29660b57cec5SDimitry Andric{
29670b57cec5SDimitry Andric}
29680b57cec5SDimitry Andric
29690b57cec5SDimitry Andrictemplate<class _Tp>
29700b57cec5SDimitry Andrictemplate<class _Yp>
29710b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p,
29725ffd83dbSDimitry Andric                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
29730b57cec5SDimitry Andric    : __ptr_(__p)
29740b57cec5SDimitry Andric{
29750b57cec5SDimitry Andric    unique_ptr<_Yp> __hold(__p);
29760b57cec5SDimitry Andric    typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
29775ffd83dbSDimitry Andric    typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
29785ffd83dbSDimitry Andric    __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
29790b57cec5SDimitry Andric    __hold.release();
29800b57cec5SDimitry Andric    __enable_weak_this(__p, __p);
29810b57cec5SDimitry Andric}
29820b57cec5SDimitry Andric
29830b57cec5SDimitry Andrictemplate<class _Tp>
29840b57cec5SDimitry Andrictemplate<class _Yp, class _Dp>
29850b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
29865ffd83dbSDimitry Andric                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
29870b57cec5SDimitry Andric    : __ptr_(__p)
29880b57cec5SDimitry Andric{
29890b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
29900b57cec5SDimitry Andric    try
29910b57cec5SDimitry Andric    {
29920b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
29930b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
29940b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
29950b57cec5SDimitry Andric        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
29960b57cec5SDimitry Andric        __enable_weak_this(__p, __p);
29970b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
29980b57cec5SDimitry Andric    }
29990b57cec5SDimitry Andric    catch (...)
30000b57cec5SDimitry Andric    {
30010b57cec5SDimitry Andric        __d(__p);
30020b57cec5SDimitry Andric        throw;
30030b57cec5SDimitry Andric    }
30040b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
30050b57cec5SDimitry Andric}
30060b57cec5SDimitry Andric
30070b57cec5SDimitry Andrictemplate<class _Tp>
30080b57cec5SDimitry Andrictemplate<class _Dp>
30090b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
3010e8d8bef9SDimitry Andric    : __ptr_(nullptr)
30110b57cec5SDimitry Andric{
30120b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
30130b57cec5SDimitry Andric    try
30140b57cec5SDimitry Andric    {
30150b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
30160b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
30170b57cec5SDimitry Andric        typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
30180b57cec5SDimitry Andric        __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
30190b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
30200b57cec5SDimitry Andric    }
30210b57cec5SDimitry Andric    catch (...)
30220b57cec5SDimitry Andric    {
30230b57cec5SDimitry Andric        __d(__p);
30240b57cec5SDimitry Andric        throw;
30250b57cec5SDimitry Andric    }
30260b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
30270b57cec5SDimitry Andric}
30280b57cec5SDimitry Andric
30290b57cec5SDimitry Andrictemplate<class _Tp>
30300b57cec5SDimitry Andrictemplate<class _Yp, class _Dp, class _Alloc>
30310b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
30325ffd83dbSDimitry Andric                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
30330b57cec5SDimitry Andric    : __ptr_(__p)
30340b57cec5SDimitry Andric{
30350b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
30360b57cec5SDimitry Andric    try
30370b57cec5SDimitry Andric    {
30380b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
30390b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
30400b57cec5SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
30410b57cec5SDimitry Andric        typedef __allocator_destructor<_A2> _D2;
30420b57cec5SDimitry Andric        _A2 __a2(__a);
30430b57cec5SDimitry Andric        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
3044e8d8bef9SDimitry Andric        ::new ((void*)_VSTD::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);
30450b57cec5SDimitry Andric        __cntrl_ = _VSTD::addressof(*__hold2.release());
30460b57cec5SDimitry Andric        __enable_weak_this(__p, __p);
30470b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
30480b57cec5SDimitry Andric    }
30490b57cec5SDimitry Andric    catch (...)
30500b57cec5SDimitry Andric    {
30510b57cec5SDimitry Andric        __d(__p);
30520b57cec5SDimitry Andric        throw;
30530b57cec5SDimitry Andric    }
30540b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
30550b57cec5SDimitry Andric}
30560b57cec5SDimitry Andric
30570b57cec5SDimitry Andrictemplate<class _Tp>
30580b57cec5SDimitry Andrictemplate<class _Dp, class _Alloc>
30590b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
3060e8d8bef9SDimitry Andric    : __ptr_(nullptr)
30610b57cec5SDimitry Andric{
30620b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
30630b57cec5SDimitry Andric    try
30640b57cec5SDimitry Andric    {
30650b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
30660b57cec5SDimitry Andric        typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
30670b57cec5SDimitry Andric        typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
30680b57cec5SDimitry Andric        typedef __allocator_destructor<_A2> _D2;
30690b57cec5SDimitry Andric        _A2 __a2(__a);
30700b57cec5SDimitry Andric        unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
3071e8d8bef9SDimitry Andric        ::new ((void*)_VSTD::addressof(*__hold2.get())) _CntrlBlk(__p, __d, __a);
30720b57cec5SDimitry Andric        __cntrl_ = _VSTD::addressof(*__hold2.release());
30730b57cec5SDimitry Andric#ifndef _LIBCPP_NO_EXCEPTIONS
30740b57cec5SDimitry Andric    }
30750b57cec5SDimitry Andric    catch (...)
30760b57cec5SDimitry Andric    {
30770b57cec5SDimitry Andric        __d(__p);
30780b57cec5SDimitry Andric        throw;
30790b57cec5SDimitry Andric    }
30800b57cec5SDimitry Andric#endif  // _LIBCPP_NO_EXCEPTIONS
30810b57cec5SDimitry Andric}
30820b57cec5SDimitry Andric
30830b57cec5SDimitry Andrictemplate<class _Tp>
30840b57cec5SDimitry Andrictemplate<class _Yp>
30850b57cec5SDimitry Andricinline
30860b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPT
30870b57cec5SDimitry Andric    : __ptr_(__p),
30880b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
30890b57cec5SDimitry Andric{
30900b57cec5SDimitry Andric    if (__cntrl_)
30910b57cec5SDimitry Andric        __cntrl_->__add_shared();
30920b57cec5SDimitry Andric}
30930b57cec5SDimitry Andric
30940b57cec5SDimitry Andrictemplate<class _Tp>
30950b57cec5SDimitry Andricinline
30960b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPT
30970b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
30980b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
30990b57cec5SDimitry Andric{
31000b57cec5SDimitry Andric    if (__cntrl_)
31010b57cec5SDimitry Andric        __cntrl_->__add_shared();
31020b57cec5SDimitry Andric}
31030b57cec5SDimitry Andric
31040b57cec5SDimitry Andrictemplate<class _Tp>
31050b57cec5SDimitry Andrictemplate<class _Yp>
31060b57cec5SDimitry Andricinline
31070b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
31085ffd83dbSDimitry Andric                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
31090b57cec5SDimitry Andric         _NOEXCEPT
31100b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
31110b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
31120b57cec5SDimitry Andric{
31130b57cec5SDimitry Andric    if (__cntrl_)
31140b57cec5SDimitry Andric        __cntrl_->__add_shared();
31150b57cec5SDimitry Andric}
31160b57cec5SDimitry Andric
31170b57cec5SDimitry Andrictemplate<class _Tp>
31180b57cec5SDimitry Andricinline
31190b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPT
31200b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
31210b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
31220b57cec5SDimitry Andric{
3123e8d8bef9SDimitry Andric    __r.__ptr_ = nullptr;
3124e8d8bef9SDimitry Andric    __r.__cntrl_ = nullptr;
31250b57cec5SDimitry Andric}
31260b57cec5SDimitry Andric
31270b57cec5SDimitry Andrictemplate<class _Tp>
31280b57cec5SDimitry Andrictemplate<class _Yp>
31290b57cec5SDimitry Andricinline
31300b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
31315ffd83dbSDimitry Andric                            typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
31320b57cec5SDimitry Andric         _NOEXCEPT
31330b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
31340b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
31350b57cec5SDimitry Andric{
3136e8d8bef9SDimitry Andric    __r.__ptr_ = nullptr;
3137e8d8bef9SDimitry Andric    __r.__cntrl_ = nullptr;
31380b57cec5SDimitry Andric}
31390b57cec5SDimitry Andric
31400b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
31410b57cec5SDimitry Andrictemplate<class _Tp>
31420b57cec5SDimitry Andrictemplate<class _Yp>
31430b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
31440b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
31450b57cec5SDimitry Andric    : __ptr_(__r.get())
31460b57cec5SDimitry Andric{
31470b57cec5SDimitry Andric    typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
31480b57cec5SDimitry Andric    __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
31490b57cec5SDimitry Andric    __enable_weak_this(__r.get(), __r.get());
31500b57cec5SDimitry Andric    __r.release();
31510b57cec5SDimitry Andric}
31520b57cec5SDimitry Andric#endif
31530b57cec5SDimitry Andric
31540b57cec5SDimitry Andrictemplate<class _Tp>
31550b57cec5SDimitry Andrictemplate <class _Yp, class _Dp>
31560b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
31570b57cec5SDimitry Andric                            typename enable_if
31580b57cec5SDimitry Andric                            <
31590b57cec5SDimitry Andric                                !is_lvalue_reference<_Dp>::value &&
31600b57cec5SDimitry Andric                                !is_array<_Yp>::value &&
31610b57cec5SDimitry Andric                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
31620b57cec5SDimitry Andric                                __nat
31630b57cec5SDimitry Andric                            >::type)
31640b57cec5SDimitry Andric    : __ptr_(__r.get())
31650b57cec5SDimitry Andric{
31660b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
31670b57cec5SDimitry Andric    if (__ptr_ == nullptr)
31680b57cec5SDimitry Andric        __cntrl_ = nullptr;
31690b57cec5SDimitry Andric    else
31700b57cec5SDimitry Andric#endif
31710b57cec5SDimitry Andric    {
31720b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
31730b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
31740b57cec5SDimitry Andric        __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
31750b57cec5SDimitry Andric        __enable_weak_this(__r.get(), __r.get());
31760b57cec5SDimitry Andric    }
31770b57cec5SDimitry Andric    __r.release();
31780b57cec5SDimitry Andric}
31790b57cec5SDimitry Andric
31800b57cec5SDimitry Andrictemplate<class _Tp>
31810b57cec5SDimitry Andrictemplate <class _Yp, class _Dp>
31820b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
31830b57cec5SDimitry Andric                            typename enable_if
31840b57cec5SDimitry Andric                            <
31850b57cec5SDimitry Andric                                is_lvalue_reference<_Dp>::value &&
31860b57cec5SDimitry Andric                                !is_array<_Yp>::value &&
31870b57cec5SDimitry Andric                                is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
31880b57cec5SDimitry Andric                                __nat
31890b57cec5SDimitry Andric                            >::type)
31900b57cec5SDimitry Andric    : __ptr_(__r.get())
31910b57cec5SDimitry Andric{
31920b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 11
31930b57cec5SDimitry Andric    if (__ptr_ == nullptr)
31940b57cec5SDimitry Andric        __cntrl_ = nullptr;
31950b57cec5SDimitry Andric    else
31960b57cec5SDimitry Andric#endif
31970b57cec5SDimitry Andric    {
31980b57cec5SDimitry Andric        typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
31990b57cec5SDimitry Andric        typedef __shared_ptr_pointer<_Yp*,
32000b57cec5SDimitry Andric                                     reference_wrapper<typename remove_reference<_Dp>::type>,
32010b57cec5SDimitry Andric                                     _AllocT > _CntrlBlk;
32025ffd83dbSDimitry Andric        __cntrl_ = new _CntrlBlk(__r.get(), _VSTD::ref(__r.get_deleter()), _AllocT());
32030b57cec5SDimitry Andric        __enable_weak_this(__r.get(), __r.get());
32040b57cec5SDimitry Andric    }
32050b57cec5SDimitry Andric    __r.release();
32060b57cec5SDimitry Andric}
32070b57cec5SDimitry Andric
32080b57cec5SDimitry Andrictemplate<class _Tp>
32090b57cec5SDimitry Andricshared_ptr<_Tp>::~shared_ptr()
32100b57cec5SDimitry Andric{
32110b57cec5SDimitry Andric    if (__cntrl_)
32120b57cec5SDimitry Andric        __cntrl_->__release_shared();
32130b57cec5SDimitry Andric}
32140b57cec5SDimitry Andric
32150b57cec5SDimitry Andrictemplate<class _Tp>
32160b57cec5SDimitry Andricinline
32170b57cec5SDimitry Andricshared_ptr<_Tp>&
32180b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPT
32190b57cec5SDimitry Andric{
32200b57cec5SDimitry Andric    shared_ptr(__r).swap(*this);
32210b57cec5SDimitry Andric    return *this;
32220b57cec5SDimitry Andric}
32230b57cec5SDimitry Andric
32240b57cec5SDimitry Andrictemplate<class _Tp>
32250b57cec5SDimitry Andrictemplate<class _Yp>
32260b57cec5SDimitry Andricinline
32270b57cec5SDimitry Andrictypename enable_if
32280b57cec5SDimitry Andric<
32295ffd83dbSDimitry Andric    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
32300b57cec5SDimitry Andric    shared_ptr<_Tp>&
32310b57cec5SDimitry Andric>::type
32320b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT
32330b57cec5SDimitry Andric{
32340b57cec5SDimitry Andric    shared_ptr(__r).swap(*this);
32350b57cec5SDimitry Andric    return *this;
32360b57cec5SDimitry Andric}
32370b57cec5SDimitry Andric
32380b57cec5SDimitry Andrictemplate<class _Tp>
32390b57cec5SDimitry Andricinline
32400b57cec5SDimitry Andricshared_ptr<_Tp>&
32410b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPT
32420b57cec5SDimitry Andric{
32430b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
32440b57cec5SDimitry Andric    return *this;
32450b57cec5SDimitry Andric}
32460b57cec5SDimitry Andric
32470b57cec5SDimitry Andrictemplate<class _Tp>
32480b57cec5SDimitry Andrictemplate<class _Yp>
32490b57cec5SDimitry Andricinline
32500b57cec5SDimitry Andrictypename enable_if
32510b57cec5SDimitry Andric<
32525ffd83dbSDimitry Andric    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
32530b57cec5SDimitry Andric    shared_ptr<_Tp>&
32540b57cec5SDimitry Andric>::type
32550b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
32560b57cec5SDimitry Andric{
32570b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
32580b57cec5SDimitry Andric    return *this;
32590b57cec5SDimitry Andric}
32600b57cec5SDimitry Andric
32610b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
32620b57cec5SDimitry Andrictemplate<class _Tp>
32630b57cec5SDimitry Andrictemplate<class _Yp>
32640b57cec5SDimitry Andricinline
32650b57cec5SDimitry Andrictypename enable_if
32660b57cec5SDimitry Andric<
32670b57cec5SDimitry Andric    !is_array<_Yp>::value &&
32680b57cec5SDimitry Andric    is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
32690b57cec5SDimitry Andric    shared_ptr<_Tp>
32700b57cec5SDimitry Andric>::type&
32710b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
32720b57cec5SDimitry Andric{
32730b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
32740b57cec5SDimitry Andric    return *this;
32750b57cec5SDimitry Andric}
32760b57cec5SDimitry Andric#endif
32770b57cec5SDimitry Andric
32780b57cec5SDimitry Andrictemplate<class _Tp>
32790b57cec5SDimitry Andrictemplate <class _Yp, class _Dp>
32800b57cec5SDimitry Andricinline
32810b57cec5SDimitry Andrictypename enable_if
32820b57cec5SDimitry Andric<
32830b57cec5SDimitry Andric    !is_array<_Yp>::value &&
32840b57cec5SDimitry Andric    is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
32850b57cec5SDimitry Andric                   typename shared_ptr<_Tp>::element_type*>::value,
32860b57cec5SDimitry Andric    shared_ptr<_Tp>&
32870b57cec5SDimitry Andric>::type
32880b57cec5SDimitry Andricshared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
32890b57cec5SDimitry Andric{
32900b57cec5SDimitry Andric    shared_ptr(_VSTD::move(__r)).swap(*this);
32910b57cec5SDimitry Andric    return *this;
32920b57cec5SDimitry Andric}
32930b57cec5SDimitry Andric
32940b57cec5SDimitry Andrictemplate<class _Tp>
32950b57cec5SDimitry Andricinline
32960b57cec5SDimitry Andricvoid
32970b57cec5SDimitry Andricshared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPT
32980b57cec5SDimitry Andric{
32990b57cec5SDimitry Andric    _VSTD::swap(__ptr_, __r.__ptr_);
33000b57cec5SDimitry Andric    _VSTD::swap(__cntrl_, __r.__cntrl_);
33010b57cec5SDimitry Andric}
33020b57cec5SDimitry Andric
33030b57cec5SDimitry Andrictemplate<class _Tp>
33040b57cec5SDimitry Andricinline
33050b57cec5SDimitry Andricvoid
33060b57cec5SDimitry Andricshared_ptr<_Tp>::reset() _NOEXCEPT
33070b57cec5SDimitry Andric{
33080b57cec5SDimitry Andric    shared_ptr().swap(*this);
33090b57cec5SDimitry Andric}
33100b57cec5SDimitry Andric
33110b57cec5SDimitry Andrictemplate<class _Tp>
33120b57cec5SDimitry Andrictemplate<class _Yp>
33130b57cec5SDimitry Andricinline
33140b57cec5SDimitry Andrictypename enable_if
33150b57cec5SDimitry Andric<
33165ffd83dbSDimitry Andric    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
33170b57cec5SDimitry Andric    void
33180b57cec5SDimitry Andric>::type
33190b57cec5SDimitry Andricshared_ptr<_Tp>::reset(_Yp* __p)
33200b57cec5SDimitry Andric{
33210b57cec5SDimitry Andric    shared_ptr(__p).swap(*this);
33220b57cec5SDimitry Andric}
33230b57cec5SDimitry Andric
33240b57cec5SDimitry Andrictemplate<class _Tp>
33250b57cec5SDimitry Andrictemplate<class _Yp, class _Dp>
33260b57cec5SDimitry Andricinline
33270b57cec5SDimitry Andrictypename enable_if
33280b57cec5SDimitry Andric<
33295ffd83dbSDimitry Andric    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
33300b57cec5SDimitry Andric    void
33310b57cec5SDimitry Andric>::type
33320b57cec5SDimitry Andricshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
33330b57cec5SDimitry Andric{
33340b57cec5SDimitry Andric    shared_ptr(__p, __d).swap(*this);
33350b57cec5SDimitry Andric}
33360b57cec5SDimitry Andric
33370b57cec5SDimitry Andrictemplate<class _Tp>
33380b57cec5SDimitry Andrictemplate<class _Yp, class _Dp, class _Alloc>
33390b57cec5SDimitry Andricinline
33400b57cec5SDimitry Andrictypename enable_if
33410b57cec5SDimitry Andric<
33425ffd83dbSDimitry Andric    __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
33430b57cec5SDimitry Andric    void
33440b57cec5SDimitry Andric>::type
33450b57cec5SDimitry Andricshared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
33460b57cec5SDimitry Andric{
33470b57cec5SDimitry Andric    shared_ptr(__p, __d, __a).swap(*this);
33480b57cec5SDimitry Andric}
33490b57cec5SDimitry Andric
3350e8d8bef9SDimitry Andric//
3351e8d8bef9SDimitry Andric// std::allocate_shared and std::make_shared
3352e8d8bef9SDimitry Andric//
3353e8d8bef9SDimitry Andrictemplate<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
3354e8d8bef9SDimitry Andric_LIBCPP_HIDE_FROM_ABI
3355e8d8bef9SDimitry Andricshared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args)
33560b57cec5SDimitry Andric{
3357e8d8bef9SDimitry Andric    using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
3358e8d8bef9SDimitry Andric    using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
3359e8d8bef9SDimitry Andric    __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
3360e8d8bef9SDimitry Andric    ::new ((void*)_VSTD::addressof(*__guard.__get())) _ControlBlock(__a, _VSTD::forward<_Args>(__args)...);
3361e8d8bef9SDimitry Andric    auto __control_block = __guard.__release_ptr();
3362e8d8bef9SDimitry Andric    return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTD::addressof(*__control_block));
33630b57cec5SDimitry Andric}
33640b57cec5SDimitry Andric
3365e8d8bef9SDimitry Andrictemplate<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
3366e8d8bef9SDimitry Andric_LIBCPP_HIDE_FROM_ABI
3367e8d8bef9SDimitry Andricshared_ptr<_Tp> make_shared(_Args&& ...__args)
33680b57cec5SDimitry Andric{
3369e8d8bef9SDimitry Andric    return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
33700b57cec5SDimitry Andric}
33710b57cec5SDimitry Andric
33720b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
33730b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
33740b57cec5SDimitry Andricbool
33750b57cec5SDimitry Andricoperator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
33760b57cec5SDimitry Andric{
33770b57cec5SDimitry Andric    return __x.get() == __y.get();
33780b57cec5SDimitry Andric}
33790b57cec5SDimitry Andric
33800b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
33810b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
33820b57cec5SDimitry Andricbool
33830b57cec5SDimitry Andricoperator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
33840b57cec5SDimitry Andric{
33850b57cec5SDimitry Andric    return !(__x == __y);
33860b57cec5SDimitry Andric}
33870b57cec5SDimitry Andric
33880b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
33890b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
33900b57cec5SDimitry Andricbool
33910b57cec5SDimitry Andricoperator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
33920b57cec5SDimitry Andric{
33930b57cec5SDimitry Andric#if _LIBCPP_STD_VER <= 11
33940b57cec5SDimitry Andric    typedef typename common_type<_Tp*, _Up*>::type _Vp;
33950b57cec5SDimitry Andric    return less<_Vp>()(__x.get(), __y.get());
33960b57cec5SDimitry Andric#else
33970b57cec5SDimitry Andric    return less<>()(__x.get(), __y.get());
33980b57cec5SDimitry Andric#endif
33990b57cec5SDimitry Andric
34000b57cec5SDimitry Andric}
34010b57cec5SDimitry Andric
34020b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
34030b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34040b57cec5SDimitry Andricbool
34050b57cec5SDimitry Andricoperator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
34060b57cec5SDimitry Andric{
34070b57cec5SDimitry Andric    return __y < __x;
34080b57cec5SDimitry Andric}
34090b57cec5SDimitry Andric
34100b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
34110b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34120b57cec5SDimitry Andricbool
34130b57cec5SDimitry Andricoperator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
34140b57cec5SDimitry Andric{
34150b57cec5SDimitry Andric    return !(__y < __x);
34160b57cec5SDimitry Andric}
34170b57cec5SDimitry Andric
34180b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
34190b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34200b57cec5SDimitry Andricbool
34210b57cec5SDimitry Andricoperator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT
34220b57cec5SDimitry Andric{
34230b57cec5SDimitry Andric    return !(__x < __y);
34240b57cec5SDimitry Andric}
34250b57cec5SDimitry Andric
34260b57cec5SDimitry Andrictemplate<class _Tp>
34270b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34280b57cec5SDimitry Andricbool
34290b57cec5SDimitry Andricoperator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
34300b57cec5SDimitry Andric{
34310b57cec5SDimitry Andric    return !__x;
34320b57cec5SDimitry Andric}
34330b57cec5SDimitry Andric
34340b57cec5SDimitry Andrictemplate<class _Tp>
34350b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34360b57cec5SDimitry Andricbool
34370b57cec5SDimitry Andricoperator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
34380b57cec5SDimitry Andric{
34390b57cec5SDimitry Andric    return !__x;
34400b57cec5SDimitry Andric}
34410b57cec5SDimitry Andric
34420b57cec5SDimitry Andrictemplate<class _Tp>
34430b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34440b57cec5SDimitry Andricbool
34450b57cec5SDimitry Andricoperator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
34460b57cec5SDimitry Andric{
34470b57cec5SDimitry Andric    return static_cast<bool>(__x);
34480b57cec5SDimitry Andric}
34490b57cec5SDimitry Andric
34500b57cec5SDimitry Andrictemplate<class _Tp>
34510b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34520b57cec5SDimitry Andricbool
34530b57cec5SDimitry Andricoperator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
34540b57cec5SDimitry Andric{
34550b57cec5SDimitry Andric    return static_cast<bool>(__x);
34560b57cec5SDimitry Andric}
34570b57cec5SDimitry Andric
34580b57cec5SDimitry Andrictemplate<class _Tp>
34590b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34600b57cec5SDimitry Andricbool
34610b57cec5SDimitry Andricoperator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
34620b57cec5SDimitry Andric{
34630b57cec5SDimitry Andric    return less<_Tp*>()(__x.get(), nullptr);
34640b57cec5SDimitry Andric}
34650b57cec5SDimitry Andric
34660b57cec5SDimitry Andrictemplate<class _Tp>
34670b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34680b57cec5SDimitry Andricbool
34690b57cec5SDimitry Andricoperator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
34700b57cec5SDimitry Andric{
34710b57cec5SDimitry Andric    return less<_Tp*>()(nullptr, __x.get());
34720b57cec5SDimitry Andric}
34730b57cec5SDimitry Andric
34740b57cec5SDimitry Andrictemplate<class _Tp>
34750b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34760b57cec5SDimitry Andricbool
34770b57cec5SDimitry Andricoperator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
34780b57cec5SDimitry Andric{
34790b57cec5SDimitry Andric    return nullptr < __x;
34800b57cec5SDimitry Andric}
34810b57cec5SDimitry Andric
34820b57cec5SDimitry Andrictemplate<class _Tp>
34830b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34840b57cec5SDimitry Andricbool
34850b57cec5SDimitry Andricoperator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
34860b57cec5SDimitry Andric{
34870b57cec5SDimitry Andric    return __x < nullptr;
34880b57cec5SDimitry Andric}
34890b57cec5SDimitry Andric
34900b57cec5SDimitry Andrictemplate<class _Tp>
34910b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
34920b57cec5SDimitry Andricbool
34930b57cec5SDimitry Andricoperator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
34940b57cec5SDimitry Andric{
34950b57cec5SDimitry Andric    return !(nullptr < __x);
34960b57cec5SDimitry Andric}
34970b57cec5SDimitry Andric
34980b57cec5SDimitry Andrictemplate<class _Tp>
34990b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35000b57cec5SDimitry Andricbool
35010b57cec5SDimitry Andricoperator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
35020b57cec5SDimitry Andric{
35030b57cec5SDimitry Andric    return !(__x < nullptr);
35040b57cec5SDimitry Andric}
35050b57cec5SDimitry Andric
35060b57cec5SDimitry Andrictemplate<class _Tp>
35070b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35080b57cec5SDimitry Andricbool
35090b57cec5SDimitry Andricoperator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
35100b57cec5SDimitry Andric{
35110b57cec5SDimitry Andric    return !(__x < nullptr);
35120b57cec5SDimitry Andric}
35130b57cec5SDimitry Andric
35140b57cec5SDimitry Andrictemplate<class _Tp>
35150b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35160b57cec5SDimitry Andricbool
35170b57cec5SDimitry Andricoperator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT
35180b57cec5SDimitry Andric{
35190b57cec5SDimitry Andric    return !(nullptr < __x);
35200b57cec5SDimitry Andric}
35210b57cec5SDimitry Andric
35220b57cec5SDimitry Andrictemplate<class _Tp>
35230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35240b57cec5SDimitry Andricvoid
35250b57cec5SDimitry Andricswap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPT
35260b57cec5SDimitry Andric{
35270b57cec5SDimitry Andric    __x.swap(__y);
35280b57cec5SDimitry Andric}
35290b57cec5SDimitry Andric
35300b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
35310b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35320b57cec5SDimitry Andricshared_ptr<_Tp>
35330b57cec5SDimitry Andricstatic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
35340b57cec5SDimitry Andric{
35355ffd83dbSDimitry Andric    return shared_ptr<_Tp>(__r,
35365ffd83dbSDimitry Andric                           static_cast<
35375ffd83dbSDimitry Andric                               typename shared_ptr<_Tp>::element_type*>(__r.get()));
35380b57cec5SDimitry Andric}
35390b57cec5SDimitry Andric
35400b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
35410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35420b57cec5SDimitry Andricshared_ptr<_Tp>
35430b57cec5SDimitry Andricdynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
35440b57cec5SDimitry Andric{
35455ffd83dbSDimitry Andric    typedef typename shared_ptr<_Tp>::element_type _ET;
35465ffd83dbSDimitry Andric    _ET* __p = dynamic_cast<_ET*>(__r.get());
35470b57cec5SDimitry Andric    return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
35480b57cec5SDimitry Andric}
35490b57cec5SDimitry Andric
35500b57cec5SDimitry Andrictemplate<class _Tp, class _Up>
35510b57cec5SDimitry Andricshared_ptr<_Tp>
35520b57cec5SDimitry Andricconst_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
35530b57cec5SDimitry Andric{
35545ffd83dbSDimitry Andric    typedef typename shared_ptr<_Tp>::element_type _RTp;
35550b57cec5SDimitry Andric    return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
35560b57cec5SDimitry Andric}
35570b57cec5SDimitry Andric
35585ffd83dbSDimitry Andrictemplate<class _Tp, class _Up>
35595ffd83dbSDimitry Andricshared_ptr<_Tp>
35605ffd83dbSDimitry Andricreinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPT
35615ffd83dbSDimitry Andric{
35625ffd83dbSDimitry Andric    return shared_ptr<_Tp>(__r,
35635ffd83dbSDimitry Andric                           reinterpret_cast<
35645ffd83dbSDimitry Andric                               typename shared_ptr<_Tp>::element_type*>(__r.get()));
35655ffd83dbSDimitry Andric}
35665ffd83dbSDimitry Andric
35670b57cec5SDimitry Andric#ifndef _LIBCPP_NO_RTTI
35680b57cec5SDimitry Andric
35690b57cec5SDimitry Andrictemplate<class _Dp, class _Tp>
35700b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35710b57cec5SDimitry Andric_Dp*
35720b57cec5SDimitry Andricget_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPT
35730b57cec5SDimitry Andric{
35740b57cec5SDimitry Andric    return __p.template __get_deleter<_Dp>();
35750b57cec5SDimitry Andric}
35760b57cec5SDimitry Andric
35770b57cec5SDimitry Andric#endif  // _LIBCPP_NO_RTTI
35780b57cec5SDimitry Andric
35790b57cec5SDimitry Andrictemplate<class _Tp>
3580e8d8bef9SDimitry Andricclass _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS weak_ptr
35810b57cec5SDimitry Andric{
35820b57cec5SDimitry Andricpublic:
35830b57cec5SDimitry Andric    typedef _Tp element_type;
35840b57cec5SDimitry Andricprivate:
35850b57cec5SDimitry Andric    element_type*        __ptr_;
35860b57cec5SDimitry Andric    __shared_weak_count* __cntrl_;
35870b57cec5SDimitry Andric
35880b57cec5SDimitry Andricpublic:
35890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
35900b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR weak_ptr() _NOEXCEPT;
35910b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(shared_ptr<_Yp> const& __r,
35920b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
35930b57cec5SDimitry Andric                        _NOEXCEPT;
35940b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
35950b57cec5SDimitry Andric    weak_ptr(weak_ptr const& __r) _NOEXCEPT;
35960b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp> const& __r,
35970b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
35980b57cec5SDimitry Andric                         _NOEXCEPT;
35990b57cec5SDimitry Andric
36000b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36010b57cec5SDimitry Andric    weak_ptr(weak_ptr&& __r) _NOEXCEPT;
36020b57cec5SDimitry Andric    template<class _Yp> _LIBCPP_INLINE_VISIBILITY weak_ptr(weak_ptr<_Yp>&& __r,
36030b57cec5SDimitry Andric                   typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
36040b57cec5SDimitry Andric                         _NOEXCEPT;
36050b57cec5SDimitry Andric    ~weak_ptr();
36060b57cec5SDimitry Andric
36070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36080b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPT;
36090b57cec5SDimitry Andric    template<class _Yp>
36100b57cec5SDimitry Andric        typename enable_if
36110b57cec5SDimitry Andric        <
36120b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
36130b57cec5SDimitry Andric            weak_ptr&
36140b57cec5SDimitry Andric        >::type
36150b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36160b57cec5SDimitry Andric        operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT;
36170b57cec5SDimitry Andric
36180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36190b57cec5SDimitry Andric    weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPT;
36200b57cec5SDimitry Andric    template<class _Yp>
36210b57cec5SDimitry Andric        typename enable_if
36220b57cec5SDimitry Andric        <
36230b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
36240b57cec5SDimitry Andric            weak_ptr&
36250b57cec5SDimitry Andric        >::type
36260b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36270b57cec5SDimitry Andric        operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT;
36280b57cec5SDimitry Andric
36290b57cec5SDimitry Andric    template<class _Yp>
36300b57cec5SDimitry Andric        typename enable_if
36310b57cec5SDimitry Andric        <
36320b57cec5SDimitry Andric            is_convertible<_Yp*, element_type*>::value,
36330b57cec5SDimitry Andric            weak_ptr&
36340b57cec5SDimitry Andric        >::type
36350b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36360b57cec5SDimitry Andric        operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT;
36370b57cec5SDimitry Andric
36380b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36390b57cec5SDimitry Andric    void swap(weak_ptr& __r) _NOEXCEPT;
36400b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36410b57cec5SDimitry Andric    void reset() _NOEXCEPT;
36420b57cec5SDimitry Andric
36430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36440b57cec5SDimitry Andric    long use_count() const _NOEXCEPT
36450b57cec5SDimitry Andric        {return __cntrl_ ? __cntrl_->use_count() : 0;}
36460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36470b57cec5SDimitry Andric    bool expired() const _NOEXCEPT
3648e8d8bef9SDimitry Andric        {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
36490b57cec5SDimitry Andric    shared_ptr<_Tp> lock() const _NOEXCEPT;
36500b57cec5SDimitry Andric    template<class _Up>
36510b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36520b57cec5SDimitry Andric        bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPT
36530b57cec5SDimitry Andric        {return __cntrl_ < __r.__cntrl_;}
36540b57cec5SDimitry Andric    template<class _Up>
36550b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36560b57cec5SDimitry Andric        bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPT
36570b57cec5SDimitry Andric        {return __cntrl_ < __r.__cntrl_;}
36580b57cec5SDimitry Andric
36590b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS weak_ptr;
36600b57cec5SDimitry Andric    template <class _Up> friend class _LIBCPP_TEMPLATE_VIS shared_ptr;
36610b57cec5SDimitry Andric};
36620b57cec5SDimitry Andric
36635ffd83dbSDimitry Andric#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
36645ffd83dbSDimitry Andrictemplate<class _Tp>
36655ffd83dbSDimitry Andricweak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
36665ffd83dbSDimitry Andric#endif
36675ffd83dbSDimitry Andric
36680b57cec5SDimitry Andrictemplate<class _Tp>
36690b57cec5SDimitry Andricinline
36700b57cec5SDimitry Andric_LIBCPP_CONSTEXPR
36710b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr() _NOEXCEPT
3672e8d8bef9SDimitry Andric    : __ptr_(nullptr),
3673e8d8bef9SDimitry Andric      __cntrl_(nullptr)
36740b57cec5SDimitry Andric{
36750b57cec5SDimitry Andric}
36760b57cec5SDimitry Andric
36770b57cec5SDimitry Andrictemplate<class _Tp>
36780b57cec5SDimitry Andricinline
36790b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPT
36800b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
36810b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
36820b57cec5SDimitry Andric{
36830b57cec5SDimitry Andric    if (__cntrl_)
36840b57cec5SDimitry Andric        __cntrl_->__add_weak();
36850b57cec5SDimitry Andric}
36860b57cec5SDimitry Andric
36870b57cec5SDimitry Andrictemplate<class _Tp>
36880b57cec5SDimitry Andrictemplate<class _Yp>
36890b57cec5SDimitry Andricinline
36900b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
36910b57cec5SDimitry Andric                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
36920b57cec5SDimitry Andric                         _NOEXCEPT
36930b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
36940b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
36950b57cec5SDimitry Andric{
36960b57cec5SDimitry Andric    if (__cntrl_)
36970b57cec5SDimitry Andric        __cntrl_->__add_weak();
36980b57cec5SDimitry Andric}
36990b57cec5SDimitry Andric
37000b57cec5SDimitry Andrictemplate<class _Tp>
37010b57cec5SDimitry Andrictemplate<class _Yp>
37020b57cec5SDimitry Andricinline
37030b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
37040b57cec5SDimitry Andric                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
37050b57cec5SDimitry Andric         _NOEXCEPT
37060b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
37070b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
37080b57cec5SDimitry Andric{
37090b57cec5SDimitry Andric    if (__cntrl_)
37100b57cec5SDimitry Andric        __cntrl_->__add_weak();
37110b57cec5SDimitry Andric}
37120b57cec5SDimitry Andric
37130b57cec5SDimitry Andrictemplate<class _Tp>
37140b57cec5SDimitry Andricinline
37150b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPT
37160b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
37170b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
37180b57cec5SDimitry Andric{
3719e8d8bef9SDimitry Andric    __r.__ptr_ = nullptr;
3720e8d8bef9SDimitry Andric    __r.__cntrl_ = nullptr;
37210b57cec5SDimitry Andric}
37220b57cec5SDimitry Andric
37230b57cec5SDimitry Andrictemplate<class _Tp>
37240b57cec5SDimitry Andrictemplate<class _Yp>
37250b57cec5SDimitry Andricinline
37260b57cec5SDimitry Andricweak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
37270b57cec5SDimitry Andric                        typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
37280b57cec5SDimitry Andric         _NOEXCEPT
37290b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
37300b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_)
37310b57cec5SDimitry Andric{
3732e8d8bef9SDimitry Andric    __r.__ptr_ = nullptr;
3733e8d8bef9SDimitry Andric    __r.__cntrl_ = nullptr;
37340b57cec5SDimitry Andric}
37350b57cec5SDimitry Andric
37360b57cec5SDimitry Andrictemplate<class _Tp>
37370b57cec5SDimitry Andricweak_ptr<_Tp>::~weak_ptr()
37380b57cec5SDimitry Andric{
37390b57cec5SDimitry Andric    if (__cntrl_)
37400b57cec5SDimitry Andric        __cntrl_->__release_weak();
37410b57cec5SDimitry Andric}
37420b57cec5SDimitry Andric
37430b57cec5SDimitry Andrictemplate<class _Tp>
37440b57cec5SDimitry Andricinline
37450b57cec5SDimitry Andricweak_ptr<_Tp>&
37460b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPT
37470b57cec5SDimitry Andric{
37480b57cec5SDimitry Andric    weak_ptr(__r).swap(*this);
37490b57cec5SDimitry Andric    return *this;
37500b57cec5SDimitry Andric}
37510b57cec5SDimitry Andric
37520b57cec5SDimitry Andrictemplate<class _Tp>
37530b57cec5SDimitry Andrictemplate<class _Yp>
37540b57cec5SDimitry Andricinline
37550b57cec5SDimitry Andrictypename enable_if
37560b57cec5SDimitry Andric<
37570b57cec5SDimitry Andric    is_convertible<_Yp*, _Tp*>::value,
37580b57cec5SDimitry Andric    weak_ptr<_Tp>&
37590b57cec5SDimitry Andric>::type
37600b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPT
37610b57cec5SDimitry Andric{
37620b57cec5SDimitry Andric    weak_ptr(__r).swap(*this);
37630b57cec5SDimitry Andric    return *this;
37640b57cec5SDimitry Andric}
37650b57cec5SDimitry Andric
37660b57cec5SDimitry Andrictemplate<class _Tp>
37670b57cec5SDimitry Andricinline
37680b57cec5SDimitry Andricweak_ptr<_Tp>&
37690b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPT
37700b57cec5SDimitry Andric{
37710b57cec5SDimitry Andric    weak_ptr(_VSTD::move(__r)).swap(*this);
37720b57cec5SDimitry Andric    return *this;
37730b57cec5SDimitry Andric}
37740b57cec5SDimitry Andric
37750b57cec5SDimitry Andrictemplate<class _Tp>
37760b57cec5SDimitry Andrictemplate<class _Yp>
37770b57cec5SDimitry Andricinline
37780b57cec5SDimitry Andrictypename enable_if
37790b57cec5SDimitry Andric<
37800b57cec5SDimitry Andric    is_convertible<_Yp*, _Tp*>::value,
37810b57cec5SDimitry Andric    weak_ptr<_Tp>&
37820b57cec5SDimitry Andric>::type
37830b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPT
37840b57cec5SDimitry Andric{
37850b57cec5SDimitry Andric    weak_ptr(_VSTD::move(__r)).swap(*this);
37860b57cec5SDimitry Andric    return *this;
37870b57cec5SDimitry Andric}
37880b57cec5SDimitry Andric
37890b57cec5SDimitry Andrictemplate<class _Tp>
37900b57cec5SDimitry Andrictemplate<class _Yp>
37910b57cec5SDimitry Andricinline
37920b57cec5SDimitry Andrictypename enable_if
37930b57cec5SDimitry Andric<
37940b57cec5SDimitry Andric    is_convertible<_Yp*, _Tp*>::value,
37950b57cec5SDimitry Andric    weak_ptr<_Tp>&
37960b57cec5SDimitry Andric>::type
37970b57cec5SDimitry Andricweak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPT
37980b57cec5SDimitry Andric{
37990b57cec5SDimitry Andric    weak_ptr(__r).swap(*this);
38000b57cec5SDimitry Andric    return *this;
38010b57cec5SDimitry Andric}
38020b57cec5SDimitry Andric
38030b57cec5SDimitry Andrictemplate<class _Tp>
38040b57cec5SDimitry Andricinline
38050b57cec5SDimitry Andricvoid
38060b57cec5SDimitry Andricweak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPT
38070b57cec5SDimitry Andric{
38080b57cec5SDimitry Andric    _VSTD::swap(__ptr_, __r.__ptr_);
38090b57cec5SDimitry Andric    _VSTD::swap(__cntrl_, __r.__cntrl_);
38100b57cec5SDimitry Andric}
38110b57cec5SDimitry Andric
38120b57cec5SDimitry Andrictemplate<class _Tp>
38130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
38140b57cec5SDimitry Andricvoid
38150b57cec5SDimitry Andricswap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPT
38160b57cec5SDimitry Andric{
38170b57cec5SDimitry Andric    __x.swap(__y);
38180b57cec5SDimitry Andric}
38190b57cec5SDimitry Andric
38200b57cec5SDimitry Andrictemplate<class _Tp>
38210b57cec5SDimitry Andricinline
38220b57cec5SDimitry Andricvoid
38230b57cec5SDimitry Andricweak_ptr<_Tp>::reset() _NOEXCEPT
38240b57cec5SDimitry Andric{
38250b57cec5SDimitry Andric    weak_ptr().swap(*this);
38260b57cec5SDimitry Andric}
38270b57cec5SDimitry Andric
38280b57cec5SDimitry Andrictemplate<class _Tp>
38290b57cec5SDimitry Andrictemplate<class _Yp>
38300b57cec5SDimitry Andricshared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
38310b57cec5SDimitry Andric                            typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
38320b57cec5SDimitry Andric    : __ptr_(__r.__ptr_),
38330b57cec5SDimitry Andric      __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
38340b57cec5SDimitry Andric{
3835e8d8bef9SDimitry Andric    if (__cntrl_ == nullptr)
38360b57cec5SDimitry Andric        __throw_bad_weak_ptr();
38370b57cec5SDimitry Andric}
38380b57cec5SDimitry Andric
38390b57cec5SDimitry Andrictemplate<class _Tp>
38400b57cec5SDimitry Andricshared_ptr<_Tp>
38410b57cec5SDimitry Andricweak_ptr<_Tp>::lock() const _NOEXCEPT
38420b57cec5SDimitry Andric{
38430b57cec5SDimitry Andric    shared_ptr<_Tp> __r;
38440b57cec5SDimitry Andric    __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
38450b57cec5SDimitry Andric    if (__r.__cntrl_)
38460b57cec5SDimitry Andric        __r.__ptr_ = __ptr_;
38470b57cec5SDimitry Andric    return __r;
38480b57cec5SDimitry Andric}
38490b57cec5SDimitry Andric
38500b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
38510b57cec5SDimitry Andrictemplate <class _Tp = void> struct owner_less;
38520b57cec5SDimitry Andric#else
38530b57cec5SDimitry Andrictemplate <class _Tp> struct owner_less;
38540b57cec5SDimitry Andric#endif
38550b57cec5SDimitry Andric
38560b57cec5SDimitry Andrictemplate <class _Tp>
38570b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<shared_ptr<_Tp> >
38580b57cec5SDimitry Andric    : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
38590b57cec5SDimitry Andric{
38600b57cec5SDimitry Andric    typedef bool result_type;
38610b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38620b57cec5SDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
38630b57cec5SDimitry Andric        {return __x.owner_before(__y);}
38640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38650b57cec5SDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
38660b57cec5SDimitry Andric        {return __x.owner_before(__y);}
38670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38680b57cec5SDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
38690b57cec5SDimitry Andric        {return __x.owner_before(__y);}
38700b57cec5SDimitry Andric};
38710b57cec5SDimitry Andric
38720b57cec5SDimitry Andrictemplate <class _Tp>
38730b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<weak_ptr<_Tp> >
38740b57cec5SDimitry Andric    : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
38750b57cec5SDimitry Andric{
38760b57cec5SDimitry Andric    typedef bool result_type;
38770b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38780b57cec5SDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
38790b57cec5SDimitry Andric        {return __x.owner_before(__y);}
38800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38810b57cec5SDimitry Andric    bool operator()(shared_ptr<_Tp> const& __x,   weak_ptr<_Tp> const& __y) const _NOEXCEPT
38820b57cec5SDimitry Andric        {return __x.owner_before(__y);}
38830b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38840b57cec5SDimitry Andric    bool operator()(  weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPT
38850b57cec5SDimitry Andric        {return __x.owner_before(__y);}
38860b57cec5SDimitry Andric};
38870b57cec5SDimitry Andric
38880b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
38890b57cec5SDimitry Andrictemplate <>
38900b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS owner_less<void>
38910b57cec5SDimitry Andric{
38920b57cec5SDimitry Andric    template <class _Tp, class _Up>
38930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38940b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
38950b57cec5SDimitry Andric        {return __x.owner_before(__y);}
38960b57cec5SDimitry Andric    template <class _Tp, class _Up>
38970b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38980b57cec5SDimitry Andric    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
38990b57cec5SDimitry Andric        {return __x.owner_before(__y);}
39000b57cec5SDimitry Andric    template <class _Tp, class _Up>
39010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39020b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPT
39030b57cec5SDimitry Andric        {return __x.owner_before(__y);}
39040b57cec5SDimitry Andric    template <class _Tp, class _Up>
39050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39060b57cec5SDimitry Andric    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const _NOEXCEPT
39070b57cec5SDimitry Andric        {return __x.owner_before(__y);}
39080b57cec5SDimitry Andric    typedef void is_transparent;
39090b57cec5SDimitry Andric};
39100b57cec5SDimitry Andric#endif
39110b57cec5SDimitry Andric
39120b57cec5SDimitry Andrictemplate<class _Tp>
39130b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS enable_shared_from_this
39140b57cec5SDimitry Andric{
39150b57cec5SDimitry Andric    mutable weak_ptr<_Tp> __weak_this_;
39160b57cec5SDimitry Andricprotected:
39170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
39180b57cec5SDimitry Andric    enable_shared_from_this() _NOEXCEPT {}
39190b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39200b57cec5SDimitry Andric    enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPT {}
39210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39220b57cec5SDimitry Andric    enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPT
39230b57cec5SDimitry Andric        {return *this;}
39240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39250b57cec5SDimitry Andric    ~enable_shared_from_this() {}
39260b57cec5SDimitry Andricpublic:
39270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39280b57cec5SDimitry Andric    shared_ptr<_Tp> shared_from_this()
39290b57cec5SDimitry Andric        {return shared_ptr<_Tp>(__weak_this_);}
39300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39310b57cec5SDimitry Andric    shared_ptr<_Tp const> shared_from_this() const
39320b57cec5SDimitry Andric        {return shared_ptr<const _Tp>(__weak_this_);}
39330b57cec5SDimitry Andric
39340b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
39350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39360b57cec5SDimitry Andric    weak_ptr<_Tp> weak_from_this() _NOEXCEPT
39370b57cec5SDimitry Andric       { return __weak_this_; }
39380b57cec5SDimitry Andric
39390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39400b57cec5SDimitry Andric    weak_ptr<const _Tp> weak_from_this() const _NOEXCEPT
39410b57cec5SDimitry Andric        { return __weak_this_; }
39420b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14
39430b57cec5SDimitry Andric
39440b57cec5SDimitry Andric    template <class _Up> friend class shared_ptr;
39450b57cec5SDimitry Andric};
39460b57cec5SDimitry Andric
39470b57cec5SDimitry Andrictemplate <class _Tp>
39480b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS hash<shared_ptr<_Tp> >
39490b57cec5SDimitry Andric{
39500b57cec5SDimitry Andric    typedef shared_ptr<_Tp>      argument_type;
39510b57cec5SDimitry Andric    typedef size_t               result_type;
39520b57cec5SDimitry Andric
39530b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39540b57cec5SDimitry Andric    result_type operator()(const argument_type& __ptr) const _NOEXCEPT
39550b57cec5SDimitry Andric    {
39565ffd83dbSDimitry Andric        return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
39570b57cec5SDimitry Andric    }
39580b57cec5SDimitry Andric};
39590b57cec5SDimitry Andric
39600b57cec5SDimitry Andrictemplate<class _CharT, class _Traits, class _Yp>
39610b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
39620b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
39630b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
39640b57cec5SDimitry Andric
39650b57cec5SDimitry Andric
39660b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
39670b57cec5SDimitry Andric
39680b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __sp_mut
39690b57cec5SDimitry Andric{
39700b57cec5SDimitry Andric    void* __lx;
39710b57cec5SDimitry Andricpublic:
39720b57cec5SDimitry Andric    void lock() _NOEXCEPT;
39730b57cec5SDimitry Andric    void unlock() _NOEXCEPT;
39740b57cec5SDimitry Andric
39750b57cec5SDimitry Andricprivate:
39760b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR __sp_mut(void*) _NOEXCEPT;
39770b57cec5SDimitry Andric    __sp_mut(const __sp_mut&);
39780b57cec5SDimitry Andric    __sp_mut& operator=(const __sp_mut&);
39790b57cec5SDimitry Andric
39800b57cec5SDimitry Andric    friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
39810b57cec5SDimitry Andric};
39820b57cec5SDimitry Andric
39830b57cec5SDimitry Andric_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
39840b57cec5SDimitry Andric__sp_mut& __get_sp_mut(const void*);
39850b57cec5SDimitry Andric
39860b57cec5SDimitry Andrictemplate <class _Tp>
39870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
39880b57cec5SDimitry Andricbool
39890b57cec5SDimitry Andricatomic_is_lock_free(const shared_ptr<_Tp>*)
39900b57cec5SDimitry Andric{
39910b57cec5SDimitry Andric    return false;
39920b57cec5SDimitry Andric}
39930b57cec5SDimitry Andric
39940b57cec5SDimitry Andrictemplate <class _Tp>
39950b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
39960b57cec5SDimitry Andricshared_ptr<_Tp>
39970b57cec5SDimitry Andricatomic_load(const shared_ptr<_Tp>* __p)
39980b57cec5SDimitry Andric{
39990b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
40000b57cec5SDimitry Andric    __m.lock();
40010b57cec5SDimitry Andric    shared_ptr<_Tp> __q = *__p;
40020b57cec5SDimitry Andric    __m.unlock();
40030b57cec5SDimitry Andric    return __q;
40040b57cec5SDimitry Andric}
40050b57cec5SDimitry Andric
40060b57cec5SDimitry Andrictemplate <class _Tp>
40070b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
40080b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40090b57cec5SDimitry Andricshared_ptr<_Tp>
40100b57cec5SDimitry Andricatomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
40110b57cec5SDimitry Andric{
40120b57cec5SDimitry Andric    return atomic_load(__p);
40130b57cec5SDimitry Andric}
40140b57cec5SDimitry Andric
40150b57cec5SDimitry Andrictemplate <class _Tp>
40160b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40170b57cec5SDimitry Andricvoid
40180b57cec5SDimitry Andricatomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
40190b57cec5SDimitry Andric{
40200b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
40210b57cec5SDimitry Andric    __m.lock();
40220b57cec5SDimitry Andric    __p->swap(__r);
40230b57cec5SDimitry Andric    __m.unlock();
40240b57cec5SDimitry Andric}
40250b57cec5SDimitry Andric
40260b57cec5SDimitry Andrictemplate <class _Tp>
40270b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
40280b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40290b57cec5SDimitry Andricvoid
40300b57cec5SDimitry Andricatomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
40310b57cec5SDimitry Andric{
40320b57cec5SDimitry Andric    atomic_store(__p, __r);
40330b57cec5SDimitry Andric}
40340b57cec5SDimitry Andric
40350b57cec5SDimitry Andrictemplate <class _Tp>
40360b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40370b57cec5SDimitry Andricshared_ptr<_Tp>
40380b57cec5SDimitry Andricatomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
40390b57cec5SDimitry Andric{
40400b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
40410b57cec5SDimitry Andric    __m.lock();
40420b57cec5SDimitry Andric    __p->swap(__r);
40430b57cec5SDimitry Andric    __m.unlock();
40440b57cec5SDimitry Andric    return __r;
40450b57cec5SDimitry Andric}
40460b57cec5SDimitry Andric
40470b57cec5SDimitry Andrictemplate <class _Tp>
40480b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
40490b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40500b57cec5SDimitry Andricshared_ptr<_Tp>
40510b57cec5SDimitry Andricatomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
40520b57cec5SDimitry Andric{
40530b57cec5SDimitry Andric    return atomic_exchange(__p, __r);
40540b57cec5SDimitry Andric}
40550b57cec5SDimitry Andric
40560b57cec5SDimitry Andrictemplate <class _Tp>
40570b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40580b57cec5SDimitry Andricbool
40590b57cec5SDimitry Andricatomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
40600b57cec5SDimitry Andric{
40610b57cec5SDimitry Andric    shared_ptr<_Tp> __temp;
40620b57cec5SDimitry Andric    __sp_mut& __m = __get_sp_mut(__p);
40630b57cec5SDimitry Andric    __m.lock();
40640b57cec5SDimitry Andric    if (__p->__owner_equivalent(*__v))
40650b57cec5SDimitry Andric    {
40660b57cec5SDimitry Andric        _VSTD::swap(__temp, *__p);
40670b57cec5SDimitry Andric        *__p = __w;
40680b57cec5SDimitry Andric        __m.unlock();
40690b57cec5SDimitry Andric        return true;
40700b57cec5SDimitry Andric    }
40710b57cec5SDimitry Andric    _VSTD::swap(__temp, *__v);
40720b57cec5SDimitry Andric    *__v = *__p;
40730b57cec5SDimitry Andric    __m.unlock();
40740b57cec5SDimitry Andric    return false;
40750b57cec5SDimitry Andric}
40760b57cec5SDimitry Andric
40770b57cec5SDimitry Andrictemplate <class _Tp>
40780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
40790b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40800b57cec5SDimitry Andricbool
40810b57cec5SDimitry Andricatomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
40820b57cec5SDimitry Andric{
40830b57cec5SDimitry Andric    return atomic_compare_exchange_strong(__p, __v, __w);
40840b57cec5SDimitry Andric}
40850b57cec5SDimitry Andric
40860b57cec5SDimitry Andrictemplate <class _Tp>
40870b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
40880b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40890b57cec5SDimitry Andricbool
40900b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
40910b57cec5SDimitry Andric                                        shared_ptr<_Tp> __w, memory_order, memory_order)
40920b57cec5SDimitry Andric{
40930b57cec5SDimitry Andric    return atomic_compare_exchange_strong(__p, __v, __w);
40940b57cec5SDimitry Andric}
40950b57cec5SDimitry Andric
40960b57cec5SDimitry Andrictemplate <class _Tp>
40970b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
40980b57cec5SDimitry Andric_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
40990b57cec5SDimitry Andricbool
41000b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
41010b57cec5SDimitry Andric                                      shared_ptr<_Tp> __w, memory_order, memory_order)
41020b57cec5SDimitry Andric{
41030b57cec5SDimitry Andric    return atomic_compare_exchange_weak(__p, __v, __w);
41040b57cec5SDimitry Andric}
41050b57cec5SDimitry Andric
41060b57cec5SDimitry Andric#endif  // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
41070b57cec5SDimitry Andric
41080b57cec5SDimitry Andric//enum class
41090b57cec5SDimitry Andric#if defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
41100b57cec5SDimitry Andric# ifndef _LIBCPP_CXX03_LANG
41110b57cec5SDimitry Andricenum class pointer_safety : unsigned char {
41120b57cec5SDimitry Andric  relaxed,
41130b57cec5SDimitry Andric  preferred,
41140b57cec5SDimitry Andric  strict
41150b57cec5SDimitry Andric};
41160b57cec5SDimitry Andric# endif
41170b57cec5SDimitry Andric#else
41180b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS pointer_safety
41190b57cec5SDimitry Andric{
41200b57cec5SDimitry Andric    enum __lx
41210b57cec5SDimitry Andric    {
41220b57cec5SDimitry Andric        relaxed,
41230b57cec5SDimitry Andric        preferred,
41240b57cec5SDimitry Andric        strict
41250b57cec5SDimitry Andric    };
41260b57cec5SDimitry Andric
41270b57cec5SDimitry Andric    __lx __v_;
41280b57cec5SDimitry Andric
41290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41300b57cec5SDimitry Andric    pointer_safety() : __v_() {}
41310b57cec5SDimitry Andric
41320b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41330b57cec5SDimitry Andric    pointer_safety(__lx __v) : __v_(__v) {}
41340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41350b57cec5SDimitry Andric    operator int() const {return __v_;}
41360b57cec5SDimitry Andric};
41370b57cec5SDimitry Andric#endif
41380b57cec5SDimitry Andric
41390b57cec5SDimitry Andric#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
41400b57cec5SDimitry Andric    defined(_LIBCPP_BUILDING_LIBRARY)
41410b57cec5SDimitry Andric_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
41420b57cec5SDimitry Andric#else
41430b57cec5SDimitry Andric// This function is only offered in C++03 under ABI v1.
41440b57cec5SDimitry Andric# if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) || !defined(_LIBCPP_CXX03_LANG)
41450b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
41460b57cec5SDimitry Andricpointer_safety get_pointer_safety() _NOEXCEPT {
41470b57cec5SDimitry Andric  return pointer_safety::relaxed;
41480b57cec5SDimitry Andric}
41490b57cec5SDimitry Andric# endif
41500b57cec5SDimitry Andric#endif
41510b57cec5SDimitry Andric
41520b57cec5SDimitry Andric
41530b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
41540b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
41550b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n);
41560b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p);
41570b57cec5SDimitry Andric
41580b57cec5SDimitry Andrictemplate <class _Tp>
41590b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
41600b57cec5SDimitry Andric_Tp*
41610b57cec5SDimitry Andricundeclare_reachable(_Tp* __p)
41620b57cec5SDimitry Andric{
41630b57cec5SDimitry Andric    return static_cast<_Tp*>(__undeclare_reachable(__p));
41640b57cec5SDimitry Andric}
41650b57cec5SDimitry Andric
41660b57cec5SDimitry Andric_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
41670b57cec5SDimitry Andric
41680b57cec5SDimitry Andric// --- Helper for container swap --
41690b57cec5SDimitry Andrictemplate <typename _Alloc>
41700b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
41710b57cec5SDimitry Andricvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
41720b57cec5SDimitry Andric#if _LIBCPP_STD_VER >= 14
41730b57cec5SDimitry Andric    _NOEXCEPT
41740b57cec5SDimitry Andric#else
41750b57cec5SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
41760b57cec5SDimitry Andric#endif
41770b57cec5SDimitry Andric{
41780b57cec5SDimitry Andric    using _VSTD::swap;
41790b57cec5SDimitry Andric    swap(__a1, __a2);
41800b57cec5SDimitry Andric}
41810b57cec5SDimitry Andric
41820b57cec5SDimitry Andrictemplate <typename _Alloc>
41830b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
41840b57cec5SDimitry Andricvoid __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}
41850b57cec5SDimitry Andric
4186e8d8bef9SDimitry Andrictemplate <typename _Alloc>
4187e8d8bef9SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
4188e8d8bef9SDimitry Andricvoid __swap_allocator(_Alloc & __a1, _Alloc & __a2)
4189e8d8bef9SDimitry Andric#if _LIBCPP_STD_VER >= 14
4190e8d8bef9SDimitry Andric    _NOEXCEPT
4191e8d8bef9SDimitry Andric#else
4192e8d8bef9SDimitry Andric    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
4193e8d8bef9SDimitry Andric#endif
4194e8d8bef9SDimitry Andric{
4195e8d8bef9SDimitry Andric    _VSTD::__swap_allocator(__a1, __a2,
4196e8d8bef9SDimitry Andric      integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
4197e8d8bef9SDimitry Andric}
4198e8d8bef9SDimitry Andric
41990b57cec5SDimitry Andrictemplate <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
42000b57cec5SDimitry Andricstruct __noexcept_move_assign_container : public integral_constant<bool,
42010b57cec5SDimitry Andric    _Traits::propagate_on_container_move_assignment::value
42020b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14
42030b57cec5SDimitry Andric        || _Traits::is_always_equal::value
42040b57cec5SDimitry Andric#else
42050b57cec5SDimitry Andric        && is_nothrow_move_assignable<_Alloc>::value
42060b57cec5SDimitry Andric#endif
42070b57cec5SDimitry Andric    > {};
42080b57cec5SDimitry Andric
42090b57cec5SDimitry Andric
42100b57cec5SDimitry Andrictemplate <class _Tp, class _Alloc>
42110b57cec5SDimitry Andricstruct __temp_value {
42120b57cec5SDimitry Andric    typedef allocator_traits<_Alloc> _Traits;
42130b57cec5SDimitry Andric
42140b57cec5SDimitry Andric    typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
42150b57cec5SDimitry Andric    _Alloc &__a;
42160b57cec5SDimitry Andric
42170b57cec5SDimitry Andric    _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
42180b57cec5SDimitry Andric    _Tp &   get() { return *__addr(); }
42190b57cec5SDimitry Andric
42200b57cec5SDimitry Andric    template<class... _Args>
42210b57cec5SDimitry Andric    _LIBCPP_NO_CFI
42220b57cec5SDimitry Andric    __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
42230b57cec5SDimitry Andric      _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
42240b57cec5SDimitry Andric                         _VSTD::forward<_Args>(__args)...);
42250b57cec5SDimitry Andric    }
42260b57cec5SDimitry Andric
42270b57cec5SDimitry Andric    ~__temp_value() { _Traits::destroy(__a, __addr()); }
42280b57cec5SDimitry Andric    };
42290b57cec5SDimitry Andric
42300b57cec5SDimitry Andrictemplate<typename _Alloc, typename = void, typename = void>
42310b57cec5SDimitry Andricstruct __is_allocator : false_type {};
42320b57cec5SDimitry Andric
42330b57cec5SDimitry Andrictemplate<typename _Alloc>
42340b57cec5SDimitry Andricstruct __is_allocator<_Alloc,
42350b57cec5SDimitry Andric       typename __void_t<typename _Alloc::value_type>::type,
42360b57cec5SDimitry Andric       typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type
42370b57cec5SDimitry Andric     >
42380b57cec5SDimitry Andric   : true_type {};
42390b57cec5SDimitry Andric
42400b57cec5SDimitry Andric// __builtin_new_allocator -- A non-templated helper for allocating and
42410b57cec5SDimitry Andric// deallocating memory using __builtin_operator_new and
42420b57cec5SDimitry Andric// __builtin_operator_delete. It should be used in preference to
42430b57cec5SDimitry Andric// `std::allocator<T>` to avoid additional instantiations.
42440b57cec5SDimitry Andricstruct __builtin_new_allocator {
42450b57cec5SDimitry Andric  struct __builtin_new_deleter {
42460b57cec5SDimitry Andric    typedef void* pointer_type;
42470b57cec5SDimitry Andric
42480b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
42490b57cec5SDimitry Andric        : __size_(__size), __align_(__align) {}
42500b57cec5SDimitry Andric
42510b57cec5SDimitry Andric    void operator()(void* p) const _NOEXCEPT {
4252e8d8bef9SDimitry Andric        _VSTD::__libcpp_deallocate(p, __size_, __align_);
42530b57cec5SDimitry Andric    }
42540b57cec5SDimitry Andric
42550b57cec5SDimitry Andric   private:
42560b57cec5SDimitry Andric    size_t __size_;
42570b57cec5SDimitry Andric    size_t __align_;
42580b57cec5SDimitry Andric  };
42590b57cec5SDimitry Andric
42600b57cec5SDimitry Andric  typedef unique_ptr<void, __builtin_new_deleter> __holder_t;
42610b57cec5SDimitry Andric
42620b57cec5SDimitry Andric  static __holder_t __allocate_bytes(size_t __s, size_t __align) {
4263e8d8bef9SDimitry Andric      return __holder_t(_VSTD::__libcpp_allocate(__s, __align),
42640b57cec5SDimitry Andric                     __builtin_new_deleter(__s, __align));
42650b57cec5SDimitry Andric  }
42660b57cec5SDimitry Andric
42670b57cec5SDimitry Andric  static void __deallocate_bytes(void* __p, size_t __s,
42680b57cec5SDimitry Andric                                 size_t __align) _NOEXCEPT {
4269e8d8bef9SDimitry Andric      _VSTD::__libcpp_deallocate(__p, __s, __align);
42700b57cec5SDimitry Andric  }
42710b57cec5SDimitry Andric
42720b57cec5SDimitry Andric  template <class _Tp>
42730b57cec5SDimitry Andric  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
42740b57cec5SDimitry Andric  static __holder_t __allocate_type(size_t __n) {
42750b57cec5SDimitry Andric      return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
42760b57cec5SDimitry Andric  }
42770b57cec5SDimitry Andric
42780b57cec5SDimitry Andric  template <class _Tp>
42790b57cec5SDimitry Andric  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
42800b57cec5SDimitry Andric  static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
42810b57cec5SDimitry Andric      __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
42820b57cec5SDimitry Andric  }
42830b57cec5SDimitry Andric};
42840b57cec5SDimitry Andric
42850b57cec5SDimitry Andric
42860b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
42870b57cec5SDimitry Andric
42880b57cec5SDimitry Andric_LIBCPP_POP_MACROS
42890b57cec5SDimitry Andric
4290e40139ffSDimitry Andric#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
4291e40139ffSDimitry Andric#   include <__pstl_memory>
4292e40139ffSDimitry Andric#endif
4293e40139ffSDimitry Andric
42940b57cec5SDimitry Andric#endif  // _LIBCPP_MEMORY
4295