// -*- C++ -*-
//===-------------------------- memory ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP_MEMORY
#define _LIBCPP_MEMORY

/*
    memory synopsis

namespace std
{

struct allocator_arg_t { };
inline constexpr allocator_arg_t allocator_arg = allocator_arg_t();

template <class T, class Alloc> struct uses_allocator;

template <class Ptr>
struct pointer_traits
{
    typedef Ptr pointer;
    typedef <details> element_type;
    typedef <details> difference_type;

    template <class U> using rebind = <details>;

    static pointer pointer_to(<details>);
};

template <class T>
struct pointer_traits<T*>
{
    typedef T* pointer;
    typedef T element_type;
    typedef ptrdiff_t difference_type;

    template <class U> using rebind = U*;

    static pointer pointer_to(<details>) noexcept; // constexpr in C++20
};

template <class T> constexpr T* to_address(T* p) noexcept; // C++20
template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // C++20

template <class Alloc>
struct allocator_traits
{
    typedef Alloc                        allocator_type;
    typedef typename allocator_type::value_type
                                         value_type;

    typedef Alloc::pointer | value_type* pointer;
    typedef Alloc::const_pointer
          | pointer_traits<pointer>::rebind<const value_type>
                                         const_pointer;
    typedef Alloc::void_pointer
          | pointer_traits<pointer>::rebind<void>
                                         void_pointer;
    typedef Alloc::const_void_pointer
          | pointer_traits<pointer>::rebind<const void>
                                         const_void_pointer;
    typedef Alloc::difference_type
          | pointer_traits<pointer>::difference_type
                                         difference_type;
    typedef Alloc::size_type
          | make_unsigned<difference_type>::type
                                         size_type;
    typedef Alloc::propagate_on_container_copy_assignment
          | false_type                   propagate_on_container_copy_assignment;
    typedef Alloc::propagate_on_container_move_assignment
          | false_type                   propagate_on_container_move_assignment;
    typedef Alloc::propagate_on_container_swap
          | false_type                   propagate_on_container_swap;
    typedef Alloc::is_always_equal
          | is_empty                     is_always_equal;

    template <class T> using rebind_alloc  = Alloc::rebind<T>::other | Alloc<T, Args...>;
    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;

    static pointer allocate(allocator_type& a, size_type n);                          // constexpr and [[nodiscard]] in C++20
    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20

    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20

    template <class T, class... Args>
    static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20

    template <class T>
    static void destroy(allocator_type& a, T* p); // constexpr in C++20

    static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20
    static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20
};

template <>
class allocator<void> // deprecated in C++17, removed in C++20
{
public:
    typedef void*                                 pointer;
    typedef const void*                           const_pointer;
    typedef void                                  value_type;

    template <class _Up> struct rebind {typedef allocator<_Up> other;};
};

template <class T>
class allocator
{
public:
    typedef size_t    size_type;
    typedef ptrdiff_t difference_type;
    typedef T*        pointer;                           // deprecated in C++17, removed in C++20
    typedef const T*  const_pointer;                     // deprecated in C++17, removed in C++20
    typedef typename add_lvalue_reference<T>::type
                      reference;                         // deprecated in C++17, removed in C++20
    typedef typename add_lvalue_reference<const T>::type
                      const_reference;                   // deprecated in C++17, removed in C++20

    typedef T         value_type;

    template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20

    typedef true_type propagate_on_container_move_assignment;
    typedef true_type is_always_equal;

    constexpr allocator() noexcept;                      // constexpr in C++20
    constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
    template <class U>
      constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
    ~allocator();                                        // constexpr in C++20
    pointer address(reference x) const noexcept;             // deprecated in C++17, removed in C++20
    const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20
    T* allocate(size_t n, const void* hint);          // deprecated in C++17, removed in C++20
    T* allocate(size_t n);                              // constexpr in C++20
    void deallocate(T* p, size_t n) noexcept;           // constexpr in C++20
    size_type max_size() const noexcept;              // deprecated in C++17, removed in C++20
    template<class U, class... Args>
        void construct(U* p, Args&&... args);         // deprecated in C++17, removed in C++20
    template <class U>
        void destroy(U* p);                           // deprecated in C++17, removed in C++20
};

template <class T, class U>
bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20

template <class T, class U>
bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20

template <class OutputIterator, class T>
class raw_storage_iterator
    : public iterator<output_iterator_tag,
                      T,                               // purposefully not C++03
                      ptrdiff_t,                       // purposefully not C++03
                      T*,                              // purposefully not C++03
                      raw_storage_iterator&>           // purposefully not C++03
{
public:
    explicit raw_storage_iterator(OutputIterator x);
    raw_storage_iterator& operator*();
    raw_storage_iterator& operator=(const T& element);
    raw_storage_iterator& operator++();
    raw_storage_iterator  operator++(int);
};

template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
template <class T> void               return_temporary_buffer(T* p) noexcept;

template <class T> T* addressof(T& r) noexcept;
template <class T> T* addressof(const T&& r) noexcept = delete;

template <class InputIterator, class ForwardIterator>
ForwardIterator
uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);

template <class InputIterator, class Size, class ForwardIterator>
ForwardIterator
uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);

template <class ForwardIterator, class T>
void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);

template <class ForwardIterator, class Size, class T>
ForwardIterator
uninitialized_fill_n(ForwardIterator first, Size n, const T& x);

template <class T, class ...Args>
constexpr T* construct_at(T* location, Args&& ...args); // since C++20

template <class T>
void destroy_at(T* location); // constexpr in C++20

template <class ForwardIterator>
void destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20

template <class ForwardIterator, class Size>
ForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20

template <class InputIterator, class ForwardIterator>
 ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);

template <class InputIterator, class Size, class ForwardIterator>
 pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);

template <class ForwardIterator>
 void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class Size>
 ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);

template <class ForwardIterator>
 void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);

template <class ForwardIterator, class Size>
 ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);

template <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17

template<class X>
class auto_ptr                                  // deprecated in C++11, removed in C++17
{
public:
    typedef X element_type;

    explicit auto_ptr(X* p =0) throw();
    auto_ptr(auto_ptr&) throw();
    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
    auto_ptr& operator=(auto_ptr&) throw();
    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
    ~auto_ptr() throw();

    typename add_lvalue_reference<X>::type operator*() const throw();
    X* operator->() const throw();
    X* get() const throw();
    X* release() throw();
    void reset(X* p =0) throw();

    auto_ptr(auto_ptr_ref<X>) throw();
    template<class Y> operator auto_ptr_ref<Y>() throw();
    template<class Y> operator auto_ptr<Y>() throw();
};

template <class T>
struct default_delete
{
    constexpr default_delete() noexcept = default;
    template <class U> default_delete(const default_delete<U>&) noexcept;

    void operator()(T*) const noexcept;
};

template <class T>
struct default_delete<T[]>
{
    constexpr default_delete() noexcept = default;
    void operator()(T*) const noexcept;
    template <class U> void operator()(U*) const = delete;
};

template <class T, class D = default_delete<T>>
class unique_ptr
{
public:
    typedef see below pointer;
    typedef T element_type;
    typedef D deleter_type;

    // constructors
    constexpr unique_ptr() noexcept;
    explicit unique_ptr(pointer p) noexcept;
    unique_ptr(pointer p, see below d1) noexcept;
    unique_ptr(pointer p, see below d2) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
    template <class U, class E>
        unique_ptr(unique_ptr<U, E>&& u) noexcept;
    template <class U>
        unique_ptr(auto_ptr<U>&& u) noexcept;       // removed in C++17

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // observers
    typename add_lvalue_reference<T>::type operator*() const;
    pointer operator->() const noexcept;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // modifiers
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    void swap(unique_ptr& u) noexcept;
};

template <class T, class D>
class unique_ptr<T[], D>
{
public:
    typedef implementation-defined pointer;
    typedef T element_type;
    typedef D deleter_type;

    // constructors
    constexpr unique_ptr() noexcept;
    explicit unique_ptr(pointer p) noexcept;
    unique_ptr(pointer p, see below d) noexcept;
    unique_ptr(pointer p, see below d) noexcept;
    unique_ptr(unique_ptr&& u) noexcept;
    unique_ptr(nullptr_t) noexcept : unique_ptr() { }

    // destructor
    ~unique_ptr();

    // assignment
    unique_ptr& operator=(unique_ptr&& u) noexcept;
    unique_ptr& operator=(nullptr_t) noexcept;

    // observers
    T& operator[](size_t i) const;
    pointer get() const noexcept;
    deleter_type& get_deleter() noexcept;
    const deleter_type& get_deleter() const noexcept;
    explicit operator bool() const noexcept;

    // modifiers
    pointer release() noexcept;
    void reset(pointer p = pointer()) noexcept;
    void reset(nullptr_t) noexcept;
  template <class U> void reset(U) = delete;
    void swap(unique_ptr& u) noexcept;
};

template <class T, class D>
    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;

template <class T1, class D1, class T2, class D2>
    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
template <class T1, class D1, class T2, class D2>
    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

template <class T, class D>
    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
template <class T, class D>
    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
template <class T, class D>
    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;

template <class T, class D>
    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
template <class T, class D>
    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
template <class T, class D>
    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
template <class T, class D>
    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
template <class T, class D>
    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);

class bad_weak_ptr
    : public std::exception
{
    bad_weak_ptr() noexcept;
};

template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
template<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
template<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]

template<class E, class T, class Y, class D>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);

template<class T>
class shared_ptr
{
public:
    typedef T element_type;
    typedef weak_ptr<T> weak_type; // C++17

    // constructors:
    constexpr shared_ptr() noexcept;
    template<class Y> explicit shared_ptr(Y* p);
    template<class Y, class D> shared_ptr(Y* p, D d);
    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
    template <class D> shared_ptr(nullptr_t p, D d);
    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
    shared_ptr(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
    shared_ptr(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
    template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
    shared_ptr(nullptr_t) : shared_ptr() { }

    // destructor:
    ~shared_ptr();

    // assignment:
    shared_ptr& operator=(const shared_ptr& r) noexcept;
    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
    shared_ptr& operator=(shared_ptr&& r) noexcept;
    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);

    // modifiers:
    void swap(shared_ptr& r) noexcept;
    void reset() noexcept;
    template<class Y> void reset(Y* p);
    template<class Y, class D> void reset(Y* p, D d);
    template<class Y, class D, class A> void reset(Y* p, D d, A a);

    // observers:
    T* get() const noexcept;
    T& operator*() const noexcept;
    T* operator->() const noexcept;
    long use_count() const noexcept;
    bool unique() const noexcept;
    explicit operator bool() const noexcept;
    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
};

template<class T>
shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
template<class T, class D>
shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;

// shared_ptr comparisons:
template<class T, class U>
    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
template<class T, class U>
    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;

template <class T>
    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
template <class T>
    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
template <class T>
    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
template <class T>
    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
template <class T>
    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
template <class T>
bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
template <class T>
    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
template <class T>
    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
template <class T>
    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
template <class T>
    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
template <class T>
    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
template <class T>
    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;

// shared_ptr specialized algorithms:
template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;

// shared_ptr casts:
template<class T, class U>
    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
template<class T, class U>
    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;

// shared_ptr I/O:
template<class E, class T, class Y>
    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);

// shared_ptr get_deleter:
template<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;

template<class T, class... Args>
    shared_ptr<T> make_shared(Args&&... args);
template<class T, class A, class... Args>
    shared_ptr<T> allocate_shared(const A& a, Args&&... args);

template<class T>
class weak_ptr
{
public:
    typedef T element_type;

    // constructors
    constexpr weak_ptr() noexcept;
    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
    weak_ptr(weak_ptr const& r) noexcept;
    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14

    // destructor
    ~weak_ptr();

    // assignment
    weak_ptr& operator=(weak_ptr const& r) noexcept;
    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14

    // modifiers
    void swap(weak_ptr& r) noexcept;
    void reset() noexcept;

    // observers
    long use_count() const noexcept;
    bool expired() const noexcept;
    shared_ptr<T> lock() const noexcept;
    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
};

template<class T>
weak_ptr(shared_ptr<T>) -> weak_ptr<T>;

// weak_ptr specialized algorithms:
template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;

// class owner_less:
template<class T> struct owner_less;

template<class T>
struct owner_less<shared_ptr<T> >
    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
{
    typedef bool result_type;
    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
};

template<class T>
struct owner_less<weak_ptr<T> >
    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
{
    typedef bool result_type;
    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
};

template <>  // Added in C++14
struct owner_less<void>
{
    template <class _Tp, class _Up>
    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
    template <class _Tp, class _Up>
    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
    template <class _Tp, class _Up>
    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
    template <class _Tp, class _Up>
    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;

    typedef void is_transparent;
};

template<class T>
class enable_shared_from_this
{
protected:
    constexpr enable_shared_from_this() noexcept;
    enable_shared_from_this(enable_shared_from_this const&) noexcept;
    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
    ~enable_shared_from_this();
public:
    shared_ptr<T> shared_from_this();
    shared_ptr<T const> shared_from_this() const;
};

template<class T>
    bool atomic_is_lock_free(const shared_ptr<T>* p);
template<class T>
    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
template<class T>
    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
template<class T>
    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
template<class T>
    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
template<class T>
    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
template<class T>
    shared_ptr<T>
    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
template<class T>
    bool
    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
template<class T>
    bool
    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
template<class T>
    bool
    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
                                          shared_ptr<T> w, memory_order success,
                                          memory_order failure);
template<class T>
    bool
    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
                                            shared_ptr<T> w, memory_order success,
                                            memory_order failure);
// Hash support
template <class T> struct hash;
template <class T, class D> struct hash<unique_ptr<T, D> >;
template <class T> struct hash<shared_ptr<T> >;

template <class T, class Alloc>
  inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;

// Pointer safety
enum class pointer_safety { relaxed, preferred, strict };
void declare_reachable(void *p);
template <class T> T *undeclare_reachable(T *p);
void declare_no_pointers(char *p, size_t n);
void undeclare_no_pointers(char *p, size_t n);
pointer_safety get_pointer_safety() noexcept;

void* align(size_t alignment, size_t size, void*& ptr, size_t& space);

}  // std

*/

#include <__config>
#include <type_traits>
#include <typeinfo>
#include <compare>
#include <cstddef>
#include <cstdint>
#include <new>
#include <utility>
#include <iterator>
#include <__functional_base>
#include <iosfwd>
#include <tuple>
#include <stdexcept>
#include <cstring>
#include <__memory/addressof.h>
#include <__memory/allocator.h>
#include <__memory/allocator_traits.h>
#include <__memory/auto_ptr.h>
#include <__memory/compressed_pair.h>
#include <__memory/construct_at.h>
#include <__memory/pointer_safety.h>
#include <__memory/pointer_traits.h>
#include <__memory/raw_storage_iterator.h>
#include <__memory/shared_ptr.h>
#include <__memory/temporary_buffer.h>
#include <__memory/uninitialized_algorithms.h>
#include <__memory/unique_ptr.h>
#include <__memory/utilities.h>
#include <version>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>


_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Alloc, class _Ptr>
_LIBCPP_INLINE_VISIBILITY
void __construct_forward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __begin2) {
    static_assert(__is_cpp17_move_insertable<_Alloc>::value,
        "The specified type does not meet the requirements of Cpp17MoveInsertable");
    typedef allocator_traits<_Alloc> _Traits;
    for (; __begin1 != __end1; ++__begin1, (void)++__begin2) {
        _Traits::construct(__a, _VSTD::__to_address(__begin2),
#ifdef _LIBCPP_NO_EXCEPTIONS
            _VSTD::move(*__begin1)
#else
            _VSTD::move_if_noexcept(*__begin1)
#endif
        );
    }
}

template <class _Alloc, class _Tp, typename enable_if<
    (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) &&
    is_trivially_move_constructible<_Tp>::value
>::type>
_LIBCPP_INLINE_VISIBILITY
void __construct_forward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __begin2) {
    ptrdiff_t _Np = __end1 - __begin1;
    if (_Np > 0) {
        _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Tp));
        __begin2 += _Np;
    }
}

template <class _Alloc, class _Iter, class _Ptr>
_LIBCPP_INLINE_VISIBILITY
void __construct_range_forward(_Alloc& __a, _Iter __begin1, _Iter __end1, _Ptr& __begin2) {
    typedef allocator_traits<_Alloc> _Traits;
    for (; __begin1 != __end1; ++__begin1, (void) ++__begin2) {
        _Traits::construct(__a, _VSTD::__to_address(__begin2), *__begin1);
    }
}

template <class _Alloc, class _Source, class _Dest,
          class _RawSource = typename remove_const<_Source>::type,
          class _RawDest = typename remove_const<_Dest>::type,
          class =
    typename enable_if<
        is_trivially_copy_constructible<_Dest>::value &&
        is_same<_RawSource, _RawDest>::value &&
        (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value)
    >::type>
_LIBCPP_INLINE_VISIBILITY
void __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) {
    ptrdiff_t _Np = __end1 - __begin1;
    if (_Np > 0) {
        _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest));
        __begin2 += _Np;
    }
}

template <class _Alloc, class _Ptr>
_LIBCPP_INLINE_VISIBILITY
void __construct_backward_with_exception_guarantees(_Alloc& __a, _Ptr __begin1, _Ptr __end1, _Ptr& __end2) {
    static_assert(__is_cpp17_move_insertable<_Alloc>::value,
        "The specified type does not meet the requirements of Cpp17MoveInsertable");
    typedef allocator_traits<_Alloc> _Traits;
    while (__end1 != __begin1) {
        _Traits::construct(__a, _VSTD::__to_address(__end2 - 1),
#ifdef _LIBCPP_NO_EXCEPTIONS
            _VSTD::move(*--__end1)
#else
            _VSTD::move_if_noexcept(*--__end1)
#endif
        );
        --__end2;
    }
}

template <class _Alloc, class _Tp, class = typename enable_if<
    (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Tp*, _Tp>::value) &&
    is_trivially_move_constructible<_Tp>::value
>::type>
_LIBCPP_INLINE_VISIBILITY
void __construct_backward_with_exception_guarantees(_Alloc&, _Tp* __begin1, _Tp* __end1, _Tp*& __end2) {
    ptrdiff_t _Np = __end1 - __begin1;
    __end2 -= _Np;
    if (_Np > 0)
        _VSTD::memcpy(__end2, __begin1, _Np * sizeof(_Tp));
}

struct __destruct_n
{
private:
    size_t __size_;

    template <class _Tp>
    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
        {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}

    template <class _Tp>
    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
        {}

    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
        {++__size_;}
    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
        {}

    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
        {__size_ = __s;}
    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
        {}
public:
    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
        : __size_(__s) {}

    template <class _Tp>
    _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT
        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}

    template <class _Tp>
    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}

    template <class _Tp>
    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
};

_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);

// --- Helper for container swap --
template <typename _Alloc>
_LIBCPP_INLINE_VISIBILITY
void __swap_allocator(_Alloc & __a1, _Alloc & __a2, true_type)
#if _LIBCPP_STD_VER >= 14
    _NOEXCEPT
#else
    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
#endif
{
    using _VSTD::swap;
    swap(__a1, __a2);
}

template <typename _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
void __swap_allocator(_Alloc &, _Alloc &, false_type) _NOEXCEPT {}

template <typename _Alloc>
inline _LIBCPP_INLINE_VISIBILITY
void __swap_allocator(_Alloc & __a1, _Alloc & __a2)
#if _LIBCPP_STD_VER >= 14
    _NOEXCEPT
#else
    _NOEXCEPT_(__is_nothrow_swappable<_Alloc>::value)
#endif
{
    _VSTD::__swap_allocator(__a1, __a2,
      integral_constant<bool, _VSTD::allocator_traits<_Alloc>::propagate_on_container_swap::value>());
}

template <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
struct __noexcept_move_assign_container : public integral_constant<bool,
    _Traits::propagate_on_container_move_assignment::value
#if _LIBCPP_STD_VER > 14
        || _Traits::is_always_equal::value
#else
        && is_nothrow_move_assignable<_Alloc>::value
#endif
    > {};


template <class _Tp, class _Alloc>
struct __temp_value {
    typedef allocator_traits<_Alloc> _Traits;

    typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
    _Alloc &__a;

    _Tp *__addr() { return reinterpret_cast<_Tp *>(addressof(__v)); }
    _Tp &   get() { return *__addr(); }

    template<class... _Args>
    _LIBCPP_NO_CFI
    __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
      _Traits::construct(__a, reinterpret_cast<_Tp*>(addressof(__v)),
                         _VSTD::forward<_Args>(__args)...);
    }

    ~__temp_value() { _Traits::destroy(__a, __addr()); }
    };

template<typename _Alloc, typename = void, typename = void>
struct __is_allocator : false_type {};

template<typename _Alloc>
struct __is_allocator<_Alloc,
       typename __void_t<typename _Alloc::value_type>::type,
       typename __void_t<decltype(_VSTD::declval<_Alloc&>().allocate(size_t(0)))>::type
     >
   : true_type {};

// __builtin_new_allocator -- A non-templated helper for allocating and
// deallocating memory using __builtin_operator_new and
// __builtin_operator_delete. It should be used in preference to
// `std::allocator<T>` to avoid additional instantiations.
struct __builtin_new_allocator {
  struct __builtin_new_deleter {
    typedef void* pointer_type;

    _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
        : __size_(__size), __align_(__align) {}

    void operator()(void* p) const _NOEXCEPT {
        _VSTD::__libcpp_deallocate(p, __size_, __align_);
    }

   private:
    size_t __size_;
    size_t __align_;
  };

  typedef unique_ptr<void, __builtin_new_deleter> __holder_t;

  static __holder_t __allocate_bytes(size_t __s, size_t __align) {
      return __holder_t(_VSTD::__libcpp_allocate(__s, __align),
                     __builtin_new_deleter(__s, __align));
  }

  static void __deallocate_bytes(void* __p, size_t __s,
                                 size_t __align) _NOEXCEPT {
      _VSTD::__libcpp_deallocate(__p, __s, __align);
  }

  template <class _Tp>
  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
  static __holder_t __allocate_type(size_t __n) {
      return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
  }

  template <class _Tp>
  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
  static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
      __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
  }
};


_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
#   include <__pstl_memory>
#endif

#endif  // _LIBCPP_MEMORY
