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