xref: /llvm-project-15.0.7/libcxx/include/memory (revision c74059c5)
13e519524SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
33e519524SHoward Hinnant//
457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
73e519524SHoward Hinnant//
83e519524SHoward Hinnant//===----------------------------------------------------------------------===//
93e519524SHoward Hinnant
103e519524SHoward Hinnant#ifndef _LIBCPP_MEMORY
113e519524SHoward Hinnant#define _LIBCPP_MEMORY
123e519524SHoward Hinnant
133e519524SHoward Hinnant/*
143e519524SHoward Hinnant    memory synopsis
153e519524SHoward Hinnant
163e519524SHoward Hinnantnamespace std
173e519524SHoward Hinnant{
183e519524SHoward Hinnant
193e519524SHoward Hinnantstruct allocator_arg_t { };
2040a01d53SMarshall Clowinline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
213e519524SHoward Hinnant
223e519524SHoward Hinnanttemplate <class T, class Alloc> struct uses_allocator;
233e519524SHoward Hinnant
243e519524SHoward Hinnanttemplate <class Ptr>
253e519524SHoward Hinnantstruct pointer_traits
263e519524SHoward Hinnant{
273e519524SHoward Hinnant    typedef Ptr pointer;
283e519524SHoward Hinnant    typedef <details> element_type;
293e519524SHoward Hinnant    typedef <details> difference_type;
303e519524SHoward Hinnant
313e519524SHoward Hinnant    template <class U> using rebind = <details>;
323e519524SHoward Hinnant
333e519524SHoward Hinnant    static pointer pointer_to(<details>);
343e519524SHoward Hinnant};
353e519524SHoward Hinnant
363739fe79SHoward Hinnanttemplate <class T>
373739fe79SHoward Hinnantstruct pointer_traits<T*>
383739fe79SHoward Hinnant{
393739fe79SHoward Hinnant    typedef T* pointer;
403739fe79SHoward Hinnant    typedef T element_type;
413739fe79SHoward Hinnant    typedef ptrdiff_t difference_type;
423739fe79SHoward Hinnant
433739fe79SHoward Hinnant    template <class U> using rebind = U*;
443739fe79SHoward Hinnant
4572720269SLouis Dionne    static pointer pointer_to(<details>) noexcept; // constexpr in C++20
463739fe79SHoward Hinnant};
473739fe79SHoward Hinnant
4832952747SEric Fiseliertemplate <class T> constexpr T* to_address(T* p) noexcept; // C++20
49f6326736SMarek Kurdejtemplate <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // C++20
5032952747SEric Fiselier
513e519524SHoward Hinnanttemplate <class Alloc>
523e519524SHoward Hinnantstruct allocator_traits
533e519524SHoward Hinnant{
543e519524SHoward Hinnant    typedef Alloc                        allocator_type;
553e519524SHoward Hinnant    typedef typename allocator_type::value_type
563e519524SHoward Hinnant                                         value_type;
573e519524SHoward Hinnant
583e519524SHoward Hinnant    typedef Alloc::pointer | value_type* pointer;
593e519524SHoward Hinnant    typedef Alloc::const_pointer
603e519524SHoward Hinnant          | pointer_traits<pointer>::rebind<const value_type>
613e519524SHoward Hinnant                                         const_pointer;
623e519524SHoward Hinnant    typedef Alloc::void_pointer
633e519524SHoward Hinnant          | pointer_traits<pointer>::rebind<void>
643e519524SHoward Hinnant                                         void_pointer;
653e519524SHoward Hinnant    typedef Alloc::const_void_pointer
663e519524SHoward Hinnant          | pointer_traits<pointer>::rebind<const void>
673e519524SHoward Hinnant                                         const_void_pointer;
683e519524SHoward Hinnant    typedef Alloc::difference_type
69a4a1ef1fSHoward Hinnant          | pointer_traits<pointer>::difference_type
70a4a1ef1fSHoward Hinnant                                         difference_type;
71a4a1ef1fSHoward Hinnant    typedef Alloc::size_type
72a4a1ef1fSHoward Hinnant          | make_unsigned<difference_type>::type
73a4a1ef1fSHoward Hinnant                                         size_type;
743e519524SHoward Hinnant    typedef Alloc::propagate_on_container_copy_assignment
753e519524SHoward Hinnant          | false_type                   propagate_on_container_copy_assignment;
763e519524SHoward Hinnant    typedef Alloc::propagate_on_container_move_assignment
773e519524SHoward Hinnant          | false_type                   propagate_on_container_move_assignment;
783e519524SHoward Hinnant    typedef Alloc::propagate_on_container_swap
793e519524SHoward Hinnant          | false_type                   propagate_on_container_swap;
8031a47313SMarshall Clow    typedef Alloc::is_always_equal
8131a47313SMarshall Clow          | is_empty                     is_always_equal;
823e519524SHoward Hinnant
835b1e5b43SMichael Park    template <class T> using rebind_alloc  = Alloc::rebind<T>::other | Alloc<T, Args...>;
843e519524SHoward Hinnant    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
853e519524SHoward Hinnant
860724f8bfSLouis Dionne    static pointer allocate(allocator_type& a, size_type n);                          // constexpr and [[nodiscard]] in C++20
870724f8bfSLouis Dionne    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20
883e519524SHoward Hinnant
890724f8bfSLouis Dionne    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20
903e519524SHoward Hinnant
913e519524SHoward Hinnant    template <class T, class... Args>
920724f8bfSLouis Dionne    static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20
933e519524SHoward Hinnant
943e519524SHoward Hinnant    template <class T>
950724f8bfSLouis Dionne    static void destroy(allocator_type& a, T* p); // constexpr in C++20
963e519524SHoward Hinnant
970724f8bfSLouis Dionne    static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20
980724f8bfSLouis Dionne    static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20
993e519524SHoward Hinnant};
1003e519524SHoward Hinnant
101a96443edSNikolas Klausertemplate<class Pointer>
102a96443edSNikolas Klauserstruct allocation_result {
103a96443edSNikolas Klauser    Pointer ptr;
104a96443edSNikolas Klauser    size_t count;
105a96443edSNikolas Klauser}; // since C++23
106a96443edSNikolas Klauser
107a96443edSNikolas Klausertemplate<class Allocator>
108a96443edSNikolas Klauser[[nodiscard]] constexpr allocation_result<typename allocator_traits<Allocator>::pointer>
109a96443edSNikolas Klauser    allocate_at_least(Allocator& a, size_t n); // since C++23
110a96443edSNikolas Klauser
1113e519524SHoward Hinnanttemplate <>
11287784cc6SLouis Dionneclass allocator<void> // removed in C++20
1133e519524SHoward Hinnant{
1143e519524SHoward Hinnantpublic:
1153e519524SHoward Hinnant    typedef void*                                 pointer;
1163e519524SHoward Hinnant    typedef const void*                           const_pointer;
1173e519524SHoward Hinnant    typedef void                                  value_type;
1183e519524SHoward Hinnant
1193e519524SHoward Hinnant    template <class _Up> struct rebind {typedef allocator<_Up> other;};
1203e519524SHoward Hinnant};
1213e519524SHoward Hinnant
1223e519524SHoward Hinnanttemplate <class T>
1233e519524SHoward Hinnantclass allocator
1243e519524SHoward Hinnant{
1253e519524SHoward Hinnantpublic:
126316d336dSLouis Dionne    typedef size_t    size_type;
127316d336dSLouis Dionne    typedef ptrdiff_t difference_type;
1285b1e5b43SMichael Park    typedef T*        pointer;                           // deprecated in C++17, removed in C++20
1295b1e5b43SMichael Park    typedef const T*  const_pointer;                     // deprecated in C++17, removed in C++20
1305b1e5b43SMichael Park    typedef typename add_lvalue_reference<T>::type
1315b1e5b43SMichael Park                      reference;                         // deprecated in C++17, removed in C++20
1325b1e5b43SMichael Park    typedef typename add_lvalue_reference<const T>::type
1335b1e5b43SMichael Park                      const_reference;                   // deprecated in C++17, removed in C++20
1345b1e5b43SMichael Park
1353e519524SHoward Hinnant    typedef T         value_type;
1363e519524SHoward Hinnant
1375b1e5b43SMichael Park    template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20
1385b1e5b43SMichael Park
1395b1e5b43SMichael Park    typedef true_type propagate_on_container_move_assignment;
1405b1e5b43SMichael Park    typedef true_type is_always_equal;
1413e519524SHoward Hinnant
142e0742c4aSMarshall Clow    constexpr allocator() noexcept;                      // constexpr in C++20
143e0742c4aSMarshall Clow    constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
144e0742c4aSMarshall Clow    template <class U>
145e0742c4aSMarshall Clow      constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
1460724f8bfSLouis Dionne    ~allocator();                                        // constexpr in C++20
1475b1e5b43SMichael Park    pointer address(reference x) const noexcept;             // deprecated in C++17, removed in C++20
1485b1e5b43SMichael Park    const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20
1495b1e5b43SMichael Park    T* allocate(size_t n, const void* hint);          // deprecated in C++17, removed in C++20
1500724f8bfSLouis Dionne    T* allocate(size_t n);                              // constexpr in C++20
1510724f8bfSLouis Dionne    void deallocate(T* p, size_t n) noexcept;           // constexpr in C++20
1525b1e5b43SMichael Park    size_type max_size() const noexcept;              // deprecated in C++17, removed in C++20
1533739fe79SHoward Hinnant    template<class U, class... Args>
1545b1e5b43SMichael Park        void construct(U* p, Args&&... args);         // deprecated in C++17, removed in C++20
1553739fe79SHoward Hinnant    template <class U>
1565b1e5b43SMichael Park        void destroy(U* p);                           // deprecated in C++17, removed in C++20
1573e519524SHoward Hinnant};
1583e519524SHoward Hinnant
1593e519524SHoward Hinnanttemplate <class T, class U>
1600724f8bfSLouis Dionnebool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
1613e519524SHoward Hinnant
1623e519524SHoward Hinnanttemplate <class T, class U>
1630724f8bfSLouis Dionnebool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
1643e519524SHoward Hinnant
1653e519524SHoward Hinnanttemplate <class OutputIterator, class T>
16641bdf64dSLouis Dionneclass raw_storage_iterator // deprecated in C++17, removed in C++20
1671055cb91SLouis Dionne    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
1683e519524SHoward Hinnant{
1693e519524SHoward Hinnantpublic:
17041bdf64dSLouis Dionne    typedef output_iterator_tag iterator_category;
17141bdf64dSLouis Dionne    typedef void                value_type;
17241bdf64dSLouis Dionne    typedef void                difference_type; // until C++20
17341bdf64dSLouis Dionne    typedef ptrdiff_t           difference_type; // since C++20
17441bdf64dSLouis Dionne    typedef void                pointer;
17541bdf64dSLouis Dionne    typedef void                reference;
17641bdf64dSLouis Dionne
1773e519524SHoward Hinnant    explicit raw_storage_iterator(OutputIterator x);
1783e519524SHoward Hinnant    raw_storage_iterator& operator*();
1793e519524SHoward Hinnant    raw_storage_iterator& operator=(const T& element);
1803e519524SHoward Hinnant    raw_storage_iterator& operator++();
1813e519524SHoward Hinnant    raw_storage_iterator  operator++(int);
1823e519524SHoward Hinnant};
1833e519524SHoward Hinnant
1843739fe79SHoward Hinnanttemplate <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
1853739fe79SHoward Hinnanttemplate <class T> void               return_temporary_buffer(T* p) noexcept;
1863739fe79SHoward Hinnant
1873739fe79SHoward Hinnanttemplate <class T> T* addressof(T& r) noexcept;
1881c7fe126SMarshall Clowtemplate <class T> T* addressof(const T&& r) noexcept = delete;
1893e519524SHoward Hinnant
1903e519524SHoward Hinnanttemplate <class InputIterator, class ForwardIterator>
1913e519524SHoward HinnantForwardIterator
1923e519524SHoward Hinnantuninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
1933e519524SHoward Hinnant
1948d23b742SKonstantin Varlamovnamespace ranges {
1958d23b742SKonstantin Varlamov
1968d23b742SKonstantin Varlamovtemplate<class InputIterator, class OutputIterator>
1978d23b742SKonstantin Varlamovusing uninitialized_copy_result = in_out_result<InputIterator, OutputIterator>; // since C++20
1988d23b742SKonstantin Varlamov
1998d23b742SKonstantin Varlamovtemplate<input_iterator InputIterator, sentinel-for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel2>
2008d23b742SKonstantin Varlamov  requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>>
2018d23b742SKonstantin Varlamovuninitialized_copy_result<InputIterator, OutputIterator>
2028d23b742SKonstantin Varlamovuninitialized_copy(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20
2038d23b742SKonstantin Varlamov
2048d23b742SKonstantin Varlamovtemplate<input_range InputRange, nothrow-forward-range OutputRange>
2058d23b742SKonstantin Varlamov  requires constructible_from<range_value_t<OutputRange>, range_reference_t<InputRange>>
2068d23b742SKonstantin Varlamovuninitialized_copy_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>>
2078d23b742SKonstantin Varlamovuninitialized_copy(InputRange&& in_range, OutputRange&& out_range); // since C++20
2088d23b742SKonstantin Varlamov
2098d23b742SKonstantin Varlamov}
2108d23b742SKonstantin Varlamov
2113739fe79SHoward Hinnanttemplate <class InputIterator, class Size, class ForwardIterator>
2123739fe79SHoward HinnantForwardIterator
2133739fe79SHoward Hinnantuninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
2143739fe79SHoward Hinnant
2158d23b742SKonstantin Varlamovnamespace ranges {
2168d23b742SKonstantin Varlamov
2178d23b742SKonstantin Varlamovtemplate<class InputIterator, class OutputIterator>
2188d23b742SKonstantin Varlamovusing uninitialized_copy_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20
2198d23b742SKonstantin Varlamov
2208d23b742SKonstantin Varlamovtemplate<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel>
2218d23b742SKonstantin Varlamov  requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>>
2228d23b742SKonstantin Varlamovuninitialized_copy_n_result<InputIterator, OutputIterator>
2238d23b742SKonstantin Varlamovuninitialized_copy_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20
2248d23b742SKonstantin Varlamov
2258d23b742SKonstantin Varlamov}
2268d23b742SKonstantin Varlamov
2273e519524SHoward Hinnanttemplate <class ForwardIterator, class T>
2283e519524SHoward Hinnantvoid uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
2293e519524SHoward Hinnant
2308d23b742SKonstantin Varlamovnamespace ranges {
2318d23b742SKonstantin Varlamov
232754ea6fdSKonstantin Varlamovtemplate <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel, class T>
233754ea6fdSKonstantin Varlamov  requires constructible_from<iter_value_t<ForwardIterator>, const T&>
2348d23b742SKonstantin VarlamovForwardIterator uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20
235754ea6fdSKonstantin Varlamov
236754ea6fdSKonstantin Varlamovtemplate <nothrow-forward-range ForwardRange, class T>
237754ea6fdSKonstantin Varlamov  requires constructible_from<range_value_t<ForwardRange>, const T&>
2388d23b742SKonstantin Varlamovborrowed_iterator_t<ForwardRange> uninitialized_fill(ForwardRange&& range, const T& x); // since C++20
2398d23b742SKonstantin Varlamov
2408d23b742SKonstantin Varlamov}
241754ea6fdSKonstantin Varlamov
2423e519524SHoward Hinnanttemplate <class ForwardIterator, class Size, class T>
24348d05bd2SHoward HinnantForwardIterator
24448d05bd2SHoward Hinnantuninitialized_fill_n(ForwardIterator first, Size n, const T& x);
2453e519524SHoward Hinnant
2468d23b742SKonstantin Varlamovnamespace ranges {
2478d23b742SKonstantin Varlamov
248754ea6fdSKonstantin Varlamovtemplate <nothrow-forward-iterator ForwardIterator, class T>
249754ea6fdSKonstantin Varlamov  requires constructible_from<iter_value_t<ForwardIterator>, const T&>
2508d23b742SKonstantin VarlamovForwardIterator uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
2518d23b742SKonstantin Varlamov
2528d23b742SKonstantin Varlamov}
253754ea6fdSKonstantin Varlamov
2540724f8bfSLouis Dionnetemplate <class T, class ...Args>
2550724f8bfSLouis Dionneconstexpr T* construct_at(T* location, Args&& ...args); // since C++20
2560724f8bfSLouis Dionne
257b9bc3c10SKonstantin Varlamovnamespace ranges {
258b9bc3c10SKonstantin Varlamov  template<class T, class... Args>
259b9bc3c10SKonstantin Varlamov    constexpr T* construct_at(T* location, Args&&... args); // since C++20
260b9bc3c10SKonstantin Varlamov}
261b9bc3c10SKonstantin Varlamov
262e4d9c316SEric Fiseliertemplate <class T>
2630724f8bfSLouis Dionnevoid destroy_at(T* location); // constexpr in C++20
264e4d9c316SEric Fiselier
265b9bc3c10SKonstantin Varlamovnamespace ranges {
266b9bc3c10SKonstantin Varlamov  template<destructible T>
267b9bc3c10SKonstantin Varlamov    constexpr void destroy_at(T* location) noexcept; // since C++20
268b9bc3c10SKonstantin Varlamov}
269b9bc3c10SKonstantin Varlamov
270e4d9c316SEric Fiseliertemplate <class ForwardIterator>
2710724f8bfSLouis Dionnevoid destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20
272e4d9c316SEric Fiselier
273b9bc3c10SKonstantin Varlamovnamespace ranges {
274b9bc3c10SKonstantin Varlamov  template<nothrow-input-iterator InputIterator, nothrow-sentinel-for<InputIterator> Sentinel>
275b9bc3c10SKonstantin Varlamov    requires destructible<iter_value_t<InputIterator>>
276b9bc3c10SKonstantin Varlamov    constexpr InputIterator destroy(InputIterator first, Sentinel last) noexcept; // since C++20
277b9bc3c10SKonstantin Varlamov  template<nothrow-input-range InputRange>
278b9bc3c10SKonstantin Varlamov    requires destructible<range_value_t<InputRange>>
279b9bc3c10SKonstantin Varlamov    constexpr borrowed_iterator_t<InputRange> destroy(InputRange&& range) noexcept; // since C++20
280b9bc3c10SKonstantin Varlamov}
281b9bc3c10SKonstantin Varlamov
282e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size>
2830724f8bfSLouis DionneForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20
284e4d9c316SEric Fiselier
285b9bc3c10SKonstantin Varlamovnamespace ranges {
286b9bc3c10SKonstantin Varlamov  template<nothrow-input-iterator InputIterator>
287b9bc3c10SKonstantin Varlamov    requires destructible<iter_value_t<InputIterator>>
288b9bc3c10SKonstantin Varlamov    constexpr InputIterator destroy_n(InputIterator first, iter_difference_t<InputIterator> n) noexcept; // since C++20
289b9bc3c10SKonstantin Varlamov}
290b9bc3c10SKonstantin Varlamov
291e4d9c316SEric Fiseliertemplate <class InputIterator, class ForwardIterator>
292e4d9c316SEric Fiselier ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
293e4d9c316SEric Fiselier
2948d23b742SKonstantin Varlamovnamespace ranges {
2958d23b742SKonstantin Varlamov
2968d23b742SKonstantin Varlamovtemplate<class InputIterator, class OutputIterator>
2978d23b742SKonstantin Varlamovusing uninitialized_move_result = in_out_result<InputIterator, OutputIterator>; // since C++20
2988d23b742SKonstantin Varlamov
2998d23b742SKonstantin Varlamovtemplate <input_iterator InputIterator, sentinel_for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<O> Sentinel2>
3008d23b742SKonstantin Varlamov  requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>>
3018d23b742SKonstantin Varlamovuninitialized_move_result<InputIterator, OutputIterator>
3028d23b742SKonstantin Varlamovuninitialized_move(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20
3038d23b742SKonstantin Varlamov
3048d23b742SKonstantin Varlamovtemplate<input_range InputRange, nothrow-forward-range OutputRange>
3058d23b742SKonstantin Varlamov  requires constructible_from<range_value_t<OutputRange>, range_rvalue_reference_t<InputRange>>
3068d23b742SKonstantin Varlamovuninitialized_move_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>>
3078d23b742SKonstantin Varlamovuninitialized_move(InputRange&& in_range, OutputRange&& out_range); // since C++20
3088d23b742SKonstantin Varlamov
3098d23b742SKonstantin Varlamov}
3108d23b742SKonstantin Varlamov
311e4d9c316SEric Fiseliertemplate <class InputIterator, class Size, class ForwardIterator>
312e4d9c316SEric Fiselier pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
313e4d9c316SEric Fiselier
3148d23b742SKonstantin Varlamovnamespace ranges {
3158d23b742SKonstantin Varlamov
3168d23b742SKonstantin Varlamovtemplate<class InputIterator, class OutputIterator>
3178d23b742SKonstantin Varlamovusing uninitialized_move_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20
3188d23b742SKonstantin Varlamov
3198d23b742SKonstantin Varlamovtemplate<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel>
3208d23b742SKonstantin Varlamov  requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>>
3218d23b742SKonstantin Varlamovuninitialized_move_n_result<InputIterator, OutputIterator>
3228d23b742SKonstantin Varlamovuninitialized_move_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20
3238d23b742SKonstantin Varlamov
3248d23b742SKonstantin Varlamov}
3258d23b742SKonstantin Varlamov
326e4d9c316SEric Fiseliertemplate <class ForwardIterator>
327e4d9c316SEric Fiselier void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
328e4d9c316SEric Fiselier
3298d23b742SKonstantin Varlamovnamespace ranges {
3308d23b742SKonstantin Varlamov
331754ea6fdSKonstantin Varlamovtemplate <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel>
332754ea6fdSKonstantin Varlamov  requires default_initializable<iter_value_t<ForwardIterator>>
3338d23b742SKonstantin Varlamov ForwardIterator uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20
334754ea6fdSKonstantin Varlamov
335754ea6fdSKonstantin Varlamovtemplate <nothrow-forward-range ForwardRange>
336754ea6fdSKonstantin Varlamov  requires default_initializable<range_value_t<ForwardRange>>
3378d23b742SKonstantin Varlamov borrowed_iterator_t<ForwardRange> uninitialized_value_construct(ForwardRange&& r); // since C++20
3388d23b742SKonstantin Varlamov
3398d23b742SKonstantin Varlamov}
340754ea6fdSKonstantin Varlamov
341e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size>
342e4d9c316SEric Fiselier ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
343e4d9c316SEric Fiselier
3448d23b742SKonstantin Varlamovnamespace ranges {
3458d23b742SKonstantin Varlamov
346754ea6fdSKonstantin Varlamovtemplate <nothrow-forward-iterator ForwardIterator>
347754ea6fdSKonstantin Varlamov  requires default_initializable<iter_value_t<ForwardIterator>>
3488d23b742SKonstantin Varlamov ForwardIterator uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
3498d23b742SKonstantin Varlamov
3508d23b742SKonstantin Varlamov}
351754ea6fdSKonstantin Varlamov
352e4d9c316SEric Fiseliertemplate <class ForwardIterator>
353e4d9c316SEric Fiselier void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
354e4d9c316SEric Fiselier
3558d23b742SKonstantin Varlamovnamespace ranges {
3568d23b742SKonstantin Varlamov
3573f630cffSKonstantin Varlamovtemplate <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel>
3583f630cffSKonstantin Varlamov  requires default_initializable<iter_value_t<ForwardIterator>>
3598d23b742SKonstantin Varlamov ForwardIterator uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20
3603f630cffSKonstantin Varlamov
3613f630cffSKonstantin Varlamovtemplate <nothrow-forward-range ForwardRange>
3623f630cffSKonstantin Varlamov  requires default_initializable<range_value_t<ForwardRange>>
3638d23b742SKonstantin Varlamov borrowed_iterator_t<ForwardRange> uninitialized_default_construct(ForwardRange&& r); // since C++20
3648d23b742SKonstantin Varlamov
3658d23b742SKonstantin Varlamov}
3663f630cffSKonstantin Varlamov
367e4d9c316SEric Fiseliertemplate <class ForwardIterator, class Size>
368e4d9c316SEric Fiselier ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
369e4d9c316SEric Fiselier
3708d23b742SKonstantin Varlamovnamespace ranges {
3718d23b742SKonstantin Varlamov
3723f630cffSKonstantin Varlamovtemplate <nothrow-forward-iterator ForwardIterator>
3733f630cffSKonstantin Varlamov  requires default_initializable<iter_value_t<ForwardIterator>>
3748d23b742SKonstantin Varlamov ForwardIterator uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
3758d23b742SKonstantin Varlamov
3768d23b742SKonstantin Varlamov}
3773f630cffSKonstantin Varlamov
378ea5cd3b4SLouis Dionnetemplate <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17
3793e519524SHoward Hinnant
3803e519524SHoward Hinnanttemplate<class X>
381ea5cd3b4SLouis Dionneclass auto_ptr                                  // deprecated in C++11, removed in C++17
3823e519524SHoward Hinnant{
3833e519524SHoward Hinnantpublic:
3843e519524SHoward Hinnant    typedef X element_type;
3853e519524SHoward Hinnant
3863e519524SHoward Hinnant    explicit auto_ptr(X* p =0) throw();
3873e519524SHoward Hinnant    auto_ptr(auto_ptr&) throw();
3883e519524SHoward Hinnant    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
3893e519524SHoward Hinnant    auto_ptr& operator=(auto_ptr&) throw();
3903e519524SHoward Hinnant    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
3913e519524SHoward Hinnant    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
3923e519524SHoward Hinnant    ~auto_ptr() throw();
3933e519524SHoward Hinnant
3943e519524SHoward Hinnant    typename add_lvalue_reference<X>::type operator*() const throw();
3953e519524SHoward Hinnant    X* operator->() const throw();
3963e519524SHoward Hinnant    X* get() const throw();
3973e519524SHoward Hinnant    X* release() throw();
3983e519524SHoward Hinnant    void reset(X* p =0) throw();
3993e519524SHoward Hinnant
4003e519524SHoward Hinnant    auto_ptr(auto_ptr_ref<X>) throw();
4013e519524SHoward Hinnant    template<class Y> operator auto_ptr_ref<Y>() throw();
4023e519524SHoward Hinnant    template<class Y> operator auto_ptr<Y>() throw();
4033e519524SHoward Hinnant};
4043e519524SHoward Hinnant
40520cc2a42SHoward Hinnanttemplate <class T>
40620cc2a42SHoward Hinnantstruct default_delete
40720cc2a42SHoward Hinnant{
4083739fe79SHoward Hinnant    constexpr default_delete() noexcept = default;
4093739fe79SHoward Hinnant    template <class U> default_delete(const default_delete<U>&) noexcept;
41020cc2a42SHoward Hinnant
4113739fe79SHoward Hinnant    void operator()(T*) const noexcept;
41220cc2a42SHoward Hinnant};
41320cc2a42SHoward Hinnant
41420cc2a42SHoward Hinnanttemplate <class T>
41520cc2a42SHoward Hinnantstruct default_delete<T[]>
41620cc2a42SHoward Hinnant{
4173739fe79SHoward Hinnant    constexpr default_delete() noexcept = default;
4183739fe79SHoward Hinnant    void operator()(T*) const noexcept;
41920cc2a42SHoward Hinnant    template <class U> void operator()(U*) const = delete;
42020cc2a42SHoward Hinnant};
42120cc2a42SHoward Hinnant
42220cc2a42SHoward Hinnanttemplate <class T, class D = default_delete<T>>
42320cc2a42SHoward Hinnantclass unique_ptr
42420cc2a42SHoward Hinnant{
42520cc2a42SHoward Hinnantpublic:
42620cc2a42SHoward Hinnant    typedef see below pointer;
42720cc2a42SHoward Hinnant    typedef T element_type;
42820cc2a42SHoward Hinnant    typedef D deleter_type;
42920cc2a42SHoward Hinnant
43020cc2a42SHoward Hinnant    // constructors
4313739fe79SHoward Hinnant    constexpr unique_ptr() noexcept;
4323739fe79SHoward Hinnant    explicit unique_ptr(pointer p) noexcept;
4333739fe79SHoward Hinnant    unique_ptr(pointer p, see below d1) noexcept;
4343739fe79SHoward Hinnant    unique_ptr(pointer p, see below d2) noexcept;
4353739fe79SHoward Hinnant    unique_ptr(unique_ptr&& u) noexcept;
4363739fe79SHoward Hinnant    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
43720cc2a42SHoward Hinnant    template <class U, class E>
4383739fe79SHoward Hinnant        unique_ptr(unique_ptr<U, E>&& u) noexcept;
43920cc2a42SHoward Hinnant    template <class U>
440e67179bcSMarshall Clow        unique_ptr(auto_ptr<U>&& u) noexcept;       // removed in C++17
44120cc2a42SHoward Hinnant
44220cc2a42SHoward Hinnant    // destructor
44320cc2a42SHoward Hinnant    ~unique_ptr();
44420cc2a42SHoward Hinnant
44520cc2a42SHoward Hinnant    // assignment
4463739fe79SHoward Hinnant    unique_ptr& operator=(unique_ptr&& u) noexcept;
4473739fe79SHoward Hinnant    template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;
4483739fe79SHoward Hinnant    unique_ptr& operator=(nullptr_t) noexcept;
44920cc2a42SHoward Hinnant
45020cc2a42SHoward Hinnant    // observers
45120cc2a42SHoward Hinnant    typename add_lvalue_reference<T>::type operator*() const;
4523739fe79SHoward Hinnant    pointer operator->() const noexcept;
4533739fe79SHoward Hinnant    pointer get() const noexcept;
4543739fe79SHoward Hinnant    deleter_type& get_deleter() noexcept;
4553739fe79SHoward Hinnant    const deleter_type& get_deleter() const noexcept;
4563739fe79SHoward Hinnant    explicit operator bool() const noexcept;
45720cc2a42SHoward Hinnant
45820cc2a42SHoward Hinnant    // modifiers
4593739fe79SHoward Hinnant    pointer release() noexcept;
4603739fe79SHoward Hinnant    void reset(pointer p = pointer()) noexcept;
4613739fe79SHoward Hinnant    void swap(unique_ptr& u) noexcept;
46220cc2a42SHoward Hinnant};
46320cc2a42SHoward Hinnant
46420cc2a42SHoward Hinnanttemplate <class T, class D>
46520cc2a42SHoward Hinnantclass unique_ptr<T[], D>
46620cc2a42SHoward Hinnant{
46720cc2a42SHoward Hinnantpublic:
46820cc2a42SHoward Hinnant    typedef implementation-defined pointer;
46920cc2a42SHoward Hinnant    typedef T element_type;
47020cc2a42SHoward Hinnant    typedef D deleter_type;
47120cc2a42SHoward Hinnant
47220cc2a42SHoward Hinnant    // constructors
4733739fe79SHoward Hinnant    constexpr unique_ptr() noexcept;
4743739fe79SHoward Hinnant    explicit unique_ptr(pointer p) noexcept;
4753739fe79SHoward Hinnant    unique_ptr(pointer p, see below d) noexcept;
4763739fe79SHoward Hinnant    unique_ptr(pointer p, see below d) noexcept;
4773739fe79SHoward Hinnant    unique_ptr(unique_ptr&& u) noexcept;
4783739fe79SHoward Hinnant    unique_ptr(nullptr_t) noexcept : unique_ptr() { }
47920cc2a42SHoward Hinnant
48020cc2a42SHoward Hinnant    // destructor
481b3371f6fSHoward Hinnant    ~unique_ptr();
48220cc2a42SHoward Hinnant
48320cc2a42SHoward Hinnant    // assignment
4843739fe79SHoward Hinnant    unique_ptr& operator=(unique_ptr&& u) noexcept;
4853739fe79SHoward Hinnant    unique_ptr& operator=(nullptr_t) noexcept;
48620cc2a42SHoward Hinnant
48720cc2a42SHoward Hinnant    // observers
48820cc2a42SHoward Hinnant    T& operator[](size_t i) const;
4893739fe79SHoward Hinnant    pointer get() const noexcept;
4903739fe79SHoward Hinnant    deleter_type& get_deleter() noexcept;
4913739fe79SHoward Hinnant    const deleter_type& get_deleter() const noexcept;
4923739fe79SHoward Hinnant    explicit operator bool() const noexcept;
49320cc2a42SHoward Hinnant
49420cc2a42SHoward Hinnant    // modifiers
4953739fe79SHoward Hinnant    pointer release() noexcept;
4963739fe79SHoward Hinnant    void reset(pointer p = pointer()) noexcept;
4973739fe79SHoward Hinnant    void reset(nullptr_t) noexcept;
49820cc2a42SHoward Hinnant  template <class U> void reset(U) = delete;
4993739fe79SHoward Hinnant    void swap(unique_ptr& u) noexcept;
50020cc2a42SHoward Hinnant};
50120cc2a42SHoward Hinnant
50220cc2a42SHoward Hinnanttemplate <class T, class D>
5033739fe79SHoward Hinnant    void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;
50420cc2a42SHoward Hinnant
50520cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
50620cc2a42SHoward Hinnant    bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
50720cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
50820cc2a42SHoward Hinnant    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
50920cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
51020cc2a42SHoward Hinnant    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
51120cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
51220cc2a42SHoward Hinnant    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
51320cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
51420cc2a42SHoward Hinnant    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
51520cc2a42SHoward Hinnanttemplate <class T1, class D1, class T2, class D2>
51620cc2a42SHoward Hinnant    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
51720cc2a42SHoward Hinnant
5183739fe79SHoward Hinnanttemplate <class T, class D>
5193739fe79SHoward Hinnant    bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
5203739fe79SHoward Hinnanttemplate <class T, class D>
5213739fe79SHoward Hinnant    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
5223739fe79SHoward Hinnanttemplate <class T, class D>
5233739fe79SHoward Hinnant    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
5243739fe79SHoward Hinnanttemplate <class T, class D>
5253739fe79SHoward Hinnant    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
5263739fe79SHoward Hinnant
5273739fe79SHoward Hinnanttemplate <class T, class D>
5283739fe79SHoward Hinnant    bool operator<(const unique_ptr<T, D>& x, nullptr_t);
5293739fe79SHoward Hinnanttemplate <class T, class D>
5303739fe79SHoward Hinnant    bool operator<(nullptr_t, const unique_ptr<T, D>& y);
5313739fe79SHoward Hinnanttemplate <class T, class D>
5323739fe79SHoward Hinnant    bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
5333739fe79SHoward Hinnanttemplate <class T, class D>
5343739fe79SHoward Hinnant    bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
5353739fe79SHoward Hinnanttemplate <class T, class D>
5363739fe79SHoward Hinnant    bool operator>(const unique_ptr<T, D>& x, nullptr_t);
5373739fe79SHoward Hinnanttemplate <class T, class D>
5383739fe79SHoward Hinnant    bool operator>(nullptr_t, const unique_ptr<T, D>& y);
5393739fe79SHoward Hinnanttemplate <class T, class D>
5403739fe79SHoward Hinnant    bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
5413739fe79SHoward Hinnanttemplate <class T, class D>
5423739fe79SHoward Hinnant    bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
5433739fe79SHoward Hinnant
54420cc2a42SHoward Hinnantclass bad_weak_ptr
54520cc2a42SHoward Hinnant    : public std::exception
54620cc2a42SHoward Hinnant{
5473739fe79SHoward Hinnant    bad_weak_ptr() noexcept;
54820cc2a42SHoward Hinnant};
54920cc2a42SHoward Hinnant
55028d8ba5fSMarshall Clowtemplate<class T, class... Args> unique_ptr<T> make_unique(Args&&... args);     // C++14
55128d8ba5fSMarshall Clowtemplate<class T>                unique_ptr<T> make_unique(size_t n);           // C++14
55228d8ba5fSMarshall Clowtemplate<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
55328d8ba5fSMarshall Clow
55448f36539SMarshall Clowtemplate<class E, class T, class Y, class D>
55548f36539SMarshall Clow    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
55648f36539SMarshall Clow
55720cc2a42SHoward Hinnanttemplate<class T>
55820cc2a42SHoward Hinnantclass shared_ptr
55920cc2a42SHoward Hinnant{
56020cc2a42SHoward Hinnantpublic:
561065ac300SKonstantin Varlamov    typedef T element_type; // until C++17
562065ac300SKonstantin Varlamov    typedef remove_extent_t<T> element_type; // since C++17
56368436a9bSEric Fiselier    typedef weak_ptr<T> weak_type; // C++17
56420cc2a42SHoward Hinnant
56520cc2a42SHoward Hinnant    // constructors:
5663739fe79SHoward Hinnant    constexpr shared_ptr() noexcept;
56720cc2a42SHoward Hinnant    template<class Y> explicit shared_ptr(Y* p);
56820cc2a42SHoward Hinnant    template<class Y, class D> shared_ptr(Y* p, D d);
56920cc2a42SHoward Hinnant    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
57020cc2a42SHoward Hinnant    template <class D> shared_ptr(nullptr_t p, D d);
57120cc2a42SHoward Hinnant    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
5723739fe79SHoward Hinnant    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
5733739fe79SHoward Hinnant    shared_ptr(const shared_ptr& r) noexcept;
5743739fe79SHoward Hinnant    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
5753739fe79SHoward Hinnant    shared_ptr(shared_ptr&& r) noexcept;
5763739fe79SHoward Hinnant    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
57720cc2a42SHoward Hinnant    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
578e67179bcSMarshall Clow    template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
57920cc2a42SHoward Hinnant    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
58020cc2a42SHoward Hinnant    shared_ptr(nullptr_t) : shared_ptr() { }
58120cc2a42SHoward Hinnant
58220cc2a42SHoward Hinnant    // destructor:
58320cc2a42SHoward Hinnant    ~shared_ptr();
58420cc2a42SHoward Hinnant
58520cc2a42SHoward Hinnant    // assignment:
5863739fe79SHoward Hinnant    shared_ptr& operator=(const shared_ptr& r) noexcept;
5873739fe79SHoward Hinnant    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
5883739fe79SHoward Hinnant    shared_ptr& operator=(shared_ptr&& r) noexcept;
58920cc2a42SHoward Hinnant    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
590e67179bcSMarshall Clow    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
59120cc2a42SHoward Hinnant    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
59220cc2a42SHoward Hinnant
59320cc2a42SHoward Hinnant    // modifiers:
5943739fe79SHoward Hinnant    void swap(shared_ptr& r) noexcept;
5953739fe79SHoward Hinnant    void reset() noexcept;
59620cc2a42SHoward Hinnant    template<class Y> void reset(Y* p);
59720cc2a42SHoward Hinnant    template<class Y, class D> void reset(Y* p, D d);
59820cc2a42SHoward Hinnant    template<class Y, class D, class A> void reset(Y* p, D d, A a);
59920cc2a42SHoward Hinnant
6003739fe79SHoward Hinnant    // observers:
6013739fe79SHoward Hinnant    T* get() const noexcept;
6023739fe79SHoward Hinnant    T& operator*() const noexcept;
6033739fe79SHoward Hinnant    T* operator->() const noexcept;
6043739fe79SHoward Hinnant    long use_count() const noexcept;
6053739fe79SHoward Hinnant    bool unique() const noexcept;
6063739fe79SHoward Hinnant    explicit operator bool() const noexcept;
60736bc7178SMarshall Clow    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
60836bc7178SMarshall Clow    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
60920cc2a42SHoward Hinnant};
61020cc2a42SHoward Hinnant
61183564056SLogan Smithtemplate<class T>
61283564056SLogan Smithshared_ptr(weak_ptr<T>) -> shared_ptr<T>;
61383564056SLogan Smithtemplate<class T, class D>
61483564056SLogan Smithshared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
61583564056SLogan Smith
61620cc2a42SHoward Hinnant// shared_ptr comparisons:
61720cc2a42SHoward Hinnanttemplate<class T, class U>
6183739fe79SHoward Hinnant    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
61920cc2a42SHoward Hinnanttemplate<class T, class U>
6203739fe79SHoward Hinnant    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
62120cc2a42SHoward Hinnanttemplate<class T, class U>
6223739fe79SHoward Hinnant    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
62320cc2a42SHoward Hinnanttemplate<class T, class U>
6243739fe79SHoward Hinnant    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
62520cc2a42SHoward Hinnanttemplate<class T, class U>
6263739fe79SHoward Hinnant    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
62720cc2a42SHoward Hinnanttemplate<class T, class U>
6283739fe79SHoward Hinnant    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
6293739fe79SHoward Hinnant
6303739fe79SHoward Hinnanttemplate <class T>
6313739fe79SHoward Hinnant    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
6323739fe79SHoward Hinnanttemplate <class T>
6333739fe79SHoward Hinnant    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;
6343739fe79SHoward Hinnanttemplate <class T>
6353739fe79SHoward Hinnant    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;
6363739fe79SHoward Hinnanttemplate <class T>
6373739fe79SHoward Hinnant    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;
6383739fe79SHoward Hinnanttemplate <class T>
6393739fe79SHoward Hinnant    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;
6403739fe79SHoward Hinnanttemplate <class T>
6413739fe79SHoward Hinnantbool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;
6423739fe79SHoward Hinnanttemplate <class T>
6433739fe79SHoward Hinnant    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;
6443739fe79SHoward Hinnanttemplate <class T>
6453739fe79SHoward Hinnant    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;
6463739fe79SHoward Hinnanttemplate <class T>
6473739fe79SHoward Hinnant    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;
6483739fe79SHoward Hinnanttemplate <class T>
6493739fe79SHoward Hinnant    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;
6503739fe79SHoward Hinnanttemplate <class T>
6513739fe79SHoward Hinnant    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;
6523739fe79SHoward Hinnanttemplate <class T>
6533739fe79SHoward Hinnant    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;
65420cc2a42SHoward Hinnant
65520cc2a42SHoward Hinnant// shared_ptr specialized algorithms:
6563739fe79SHoward Hinnanttemplate<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
65720cc2a42SHoward Hinnant
65820cc2a42SHoward Hinnant// shared_ptr casts:
65920cc2a42SHoward Hinnanttemplate<class T, class U>
6603739fe79SHoward Hinnant    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
66120cc2a42SHoward Hinnanttemplate<class T, class U>
6623739fe79SHoward Hinnant    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
66320cc2a42SHoward Hinnanttemplate<class T, class U>
6643739fe79SHoward Hinnant    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
66520cc2a42SHoward Hinnant
66620cc2a42SHoward Hinnant// shared_ptr I/O:
66720cc2a42SHoward Hinnanttemplate<class E, class T, class Y>
66820cc2a42SHoward Hinnant    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
66920cc2a42SHoward Hinnant
67020cc2a42SHoward Hinnant// shared_ptr get_deleter:
6713739fe79SHoward Hinnanttemplate<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
67220cc2a42SHoward Hinnant
67320cc2a42SHoward Hinnanttemplate<class T, class... Args>
674e27a122bSLouis Dionne    shared_ptr<T> make_shared(Args&&... args); // T is not an array
67520cc2a42SHoward Hinnanttemplate<class T, class A, class... Args>
676e27a122bSLouis Dionne    shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not an array
677e27a122bSLouis Dionne
678e27a122bSLouis Dionnetemplate<class T>
679e27a122bSLouis Dionne    shared_ptr<T> make_shared(size_t N); // T is U[] (since C++20)
680e27a122bSLouis Dionnetemplate<class T, class A>
681e27a122bSLouis Dionne    shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[] (since C++20)
682e27a122bSLouis Dionne
683e27a122bSLouis Dionnetemplate<class T>
684e27a122bSLouis Dionne    shared_ptr<T> make_shared(); // T is U[N] (since C++20)
685e27a122bSLouis Dionnetemplate<class T, class A>
686e27a122bSLouis Dionne    shared_ptr<T> allocate_shared(const A& a); // T is U[N] (since C++20)
687e27a122bSLouis Dionne
688e27a122bSLouis Dionnetemplate<class T>
689e27a122bSLouis Dionne    shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
690e27a122bSLouis Dionnetemplate<class T, class A>
691e27a122bSLouis Dionne    shared_ptr<T> allocate_shared(const A& a, size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
692e27a122bSLouis Dionne
693e27a122bSLouis Dionnetemplate<class T> shared_ptr<T>
694e27a122bSLouis Dionne    make_shared(const remove_extent_t<T>& u); // T is U[N] (since C++20)
695e27a122bSLouis Dionnetemplate<class T, class A>
696e27a122bSLouis Dionne    shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N] (since C++20)
69720cc2a42SHoward Hinnant
69820cc2a42SHoward Hinnanttemplate<class T>
69920cc2a42SHoward Hinnantclass weak_ptr
70020cc2a42SHoward Hinnant{
70120cc2a42SHoward Hinnantpublic:
702065ac300SKonstantin Varlamov    typedef T element_type; // until C++17
703065ac300SKonstantin Varlamov    typedef remove_extent_t<T> element_type; // since C++17
70420cc2a42SHoward Hinnant
70520cc2a42SHoward Hinnant    // constructors
7063739fe79SHoward Hinnant    constexpr weak_ptr() noexcept;
7073739fe79SHoward Hinnant    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
7083739fe79SHoward Hinnant    weak_ptr(weak_ptr const& r) noexcept;
7093739fe79SHoward Hinnant    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
7104703f763SMarshall Clow    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
7114703f763SMarshall Clow    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
71220cc2a42SHoward Hinnant
71320cc2a42SHoward Hinnant    // destructor
71420cc2a42SHoward Hinnant    ~weak_ptr();
71520cc2a42SHoward Hinnant
71620cc2a42SHoward Hinnant    // assignment
7173739fe79SHoward Hinnant    weak_ptr& operator=(weak_ptr const& r) noexcept;
7183739fe79SHoward Hinnant    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
7193739fe79SHoward Hinnant    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
7204703f763SMarshall Clow    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
7214703f763SMarshall Clow    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
72220cc2a42SHoward Hinnant
72320cc2a42SHoward Hinnant    // modifiers
7243739fe79SHoward Hinnant    void swap(weak_ptr& r) noexcept;
7253739fe79SHoward Hinnant    void reset() noexcept;
72620cc2a42SHoward Hinnant
72720cc2a42SHoward Hinnant    // observers
7283739fe79SHoward Hinnant    long use_count() const noexcept;
7293739fe79SHoward Hinnant    bool expired() const noexcept;
7303739fe79SHoward Hinnant    shared_ptr<T> lock() const noexcept;
73136bc7178SMarshall Clow    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
73236bc7178SMarshall Clow    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
73320cc2a42SHoward Hinnant};
73420cc2a42SHoward Hinnant
73583564056SLogan Smithtemplate<class T>
73683564056SLogan Smithweak_ptr(shared_ptr<T>) -> weak_ptr<T>;
73783564056SLogan Smith
73820cc2a42SHoward Hinnant// weak_ptr specialized algorithms:
7393739fe79SHoward Hinnanttemplate<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
74020cc2a42SHoward Hinnant
74120cc2a42SHoward Hinnant// class owner_less:
74220cc2a42SHoward Hinnanttemplate<class T> struct owner_less;
74320cc2a42SHoward Hinnant
74420cc2a42SHoward Hinnanttemplate<class T>
74520cc2a42SHoward Hinnantstruct owner_less<shared_ptr<T> >
74620cc2a42SHoward Hinnant    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
74720cc2a42SHoward Hinnant{
74820cc2a42SHoward Hinnant    typedef bool result_type;
74936bc7178SMarshall Clow    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
75036bc7178SMarshall Clow    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
75136bc7178SMarshall Clow    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
75220cc2a42SHoward Hinnant};
75320cc2a42SHoward Hinnant
75420cc2a42SHoward Hinnanttemplate<class T>
75520cc2a42SHoward Hinnantstruct owner_less<weak_ptr<T> >
75620cc2a42SHoward Hinnant    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
75720cc2a42SHoward Hinnant{
75820cc2a42SHoward Hinnant    typedef bool result_type;
75936bc7178SMarshall Clow    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
76036bc7178SMarshall Clow    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
76136bc7178SMarshall Clow    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
76236bc7178SMarshall Clow};
76336bc7178SMarshall Clow
76436bc7178SMarshall Clowtemplate <>  // Added in C++14
76536bc7178SMarshall Clowstruct owner_less<void>
76636bc7178SMarshall Clow{
76736bc7178SMarshall Clow    template <class _Tp, class _Up>
76836bc7178SMarshall Clow    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
76936bc7178SMarshall Clow    template <class _Tp, class _Up>
77036bc7178SMarshall Clow    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
77136bc7178SMarshall Clow    template <class _Tp, class _Up>
77236bc7178SMarshall Clow    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
77336bc7178SMarshall Clow    template <class _Tp, class _Up>
77436bc7178SMarshall Clow    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
77536bc7178SMarshall Clow
77636bc7178SMarshall Clow    typedef void is_transparent;
77720cc2a42SHoward Hinnant};
77820cc2a42SHoward Hinnant
77920cc2a42SHoward Hinnanttemplate<class T>
78020cc2a42SHoward Hinnantclass enable_shared_from_this
78120cc2a42SHoward Hinnant{
78220cc2a42SHoward Hinnantprotected:
7833739fe79SHoward Hinnant    constexpr enable_shared_from_this() noexcept;
7843739fe79SHoward Hinnant    enable_shared_from_this(enable_shared_from_this const&) noexcept;
7853739fe79SHoward Hinnant    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
78620cc2a42SHoward Hinnant    ~enable_shared_from_this();
78720cc2a42SHoward Hinnantpublic:
78820cc2a42SHoward Hinnant    shared_ptr<T> shared_from_this();
78920cc2a42SHoward Hinnant    shared_ptr<T const> shared_from_this() const;
79020cc2a42SHoward Hinnant};
79120cc2a42SHoward Hinnant
79220cc2a42SHoward Hinnanttemplate<class T>
79320cc2a42SHoward Hinnant    bool atomic_is_lock_free(const shared_ptr<T>* p);
79420cc2a42SHoward Hinnanttemplate<class T>
79520cc2a42SHoward Hinnant    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
79620cc2a42SHoward Hinnanttemplate<class T>
79720cc2a42SHoward Hinnant    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
79820cc2a42SHoward Hinnanttemplate<class T>
79920cc2a42SHoward Hinnant    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
80020cc2a42SHoward Hinnanttemplate<class T>
80120cc2a42SHoward Hinnant    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
80220cc2a42SHoward Hinnanttemplate<class T>
80320cc2a42SHoward Hinnant    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
80420cc2a42SHoward Hinnanttemplate<class T>
80520cc2a42SHoward Hinnant    shared_ptr<T>
80620cc2a42SHoward Hinnant    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
80720cc2a42SHoward Hinnanttemplate<class T>
80820cc2a42SHoward Hinnant    bool
80920cc2a42SHoward Hinnant    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
81020cc2a42SHoward Hinnanttemplate<class T>
81120cc2a42SHoward Hinnant    bool
81220cc2a42SHoward Hinnant    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
81320cc2a42SHoward Hinnanttemplate<class T>
81420cc2a42SHoward Hinnant    bool
81520cc2a42SHoward Hinnant    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
81620cc2a42SHoward Hinnant                                          shared_ptr<T> w, memory_order success,
81720cc2a42SHoward Hinnant                                          memory_order failure);
81820cc2a42SHoward Hinnanttemplate<class T>
81920cc2a42SHoward Hinnant    bool
82020cc2a42SHoward Hinnant    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
82120cc2a42SHoward Hinnant                                            shared_ptr<T> w, memory_order success,
82220cc2a42SHoward Hinnant                                            memory_order failure);
82320cc2a42SHoward Hinnant// Hash support
82420cc2a42SHoward Hinnanttemplate <class T> struct hash;
82520cc2a42SHoward Hinnanttemplate <class T, class D> struct hash<unique_ptr<T, D> >;
82620cc2a42SHoward Hinnanttemplate <class T> struct hash<shared_ptr<T> >;
82720cc2a42SHoward Hinnant
82840a01d53SMarshall Clowtemplate <class T, class Alloc>
82940a01d53SMarshall Clow  inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
83040a01d53SMarshall Clow
831c292b606SLouis Dionne// [ptr.align]
8323e519524SHoward Hinnantvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space);
8333e519524SHoward Hinnant
834c292b606SLouis Dionnetemplate<size_t N, class T>
835c292b606SLouis Dionne[[nodiscard]] constexpr T* assume_aligned(T* ptr); // since C++20
836c292b606SLouis Dionne
8373e519524SHoward Hinnant}  // std
8383e519524SHoward Hinnant
8393e519524SHoward Hinnant*/
8403e519524SHoward Hinnant
841*c74059c5SNikolas Klauser#include <__algorithm/copy.h>
842*c74059c5SNikolas Klauser#include <__algorithm/move.h>
843385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
8443e519524SHoward Hinnant#include <__config>
845f992cfbaSLouis Dionne#include <__memory/addressof.h>
846a96443edSNikolas Klauser#include <__memory/allocate_at_least.h>
847e98060faSLouis Dionne#include <__memory/allocation_guard.h>
8480b439e4cSLouis Dionne#include <__memory/allocator.h>
849050b064fSChristopher Di Bella#include <__memory/allocator_arg_t.h>
8507ad49aecSLouis Dionne#include <__memory/allocator_traits.h>
851c292b606SLouis Dionne#include <__memory/assume_aligned.h>
852681cde7dSNikolas Klauser#include <__memory/auto_ptr.h>
8539b0a3388SLouis Dionne#include <__memory/compressed_pair.h>
8542d9efcfeSKonstantin Varlamov#include <__memory/concepts.h>
855f992cfbaSLouis Dionne#include <__memory/construct_at.h>
8567ad49aecSLouis Dionne#include <__memory/pointer_traits.h>
857b9bc3c10SKonstantin Varlamov#include <__memory/ranges_construct_at.h>
8583f630cffSKonstantin Varlamov#include <__memory/ranges_uninitialized_algorithms.h>
859be54341cSLouis Dionne#include <__memory/raw_storage_iterator.h>
860916fecb4SLouis Dionne#include <__memory/shared_ptr.h>
8616a1ac88fSLouis Dionne#include <__memory/temporary_buffer.h>
8624f9b2469SLouis Dionne#include <__memory/uninitialized_algorithms.h>
86321d6636dSLouis Dionne#include <__memory/unique_ptr.h>
864050b064fSChristopher Di Bella#include <__memory/uses_allocator.h>
865bfbd73f8SArthur O'Dwyer#include <cstddef>
866bfbd73f8SArthur O'Dwyer#include <cstdint>
867bfbd73f8SArthur O'Dwyer#include <cstring>
868bfbd73f8SArthur O'Dwyer#include <iosfwd>
869bfbd73f8SArthur O'Dwyer#include <new>
870bfbd73f8SArthur O'Dwyer#include <stdexcept>
871bfbd73f8SArthur O'Dwyer#include <tuple>
872bfbd73f8SArthur O'Dwyer#include <type_traits>
873bfbd73f8SArthur O'Dwyer#include <typeinfo>
874f56972e2SMarshall Clow#include <version>
875d77851e8SHoward Hinnant
876de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
877de4a57cbSLouis Dionne#  include <iterator>
878de4a57cbSLouis Dionne#  include <utility>
879de4a57cbSLouis Dionne#endif
880de4a57cbSLouis Dionne
881db1978b6SNikolas Klauser// standard-mandated includes
882db1978b6SNikolas Klauser#include <compare>
883db1978b6SNikolas Klauser
884073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
8853e519524SHoward Hinnant#  pragma GCC system_header
886073458b1SHoward Hinnant#endif
8873e519524SHoward Hinnant
8883e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
8893e519524SHoward Hinnant
8903e519524SHoward Hinnantstruct __destruct_n
8913e519524SHoward Hinnant{
8923e519524SHoward Hinnantprivate:
8939ffacf3dSEric Fiselier    size_t __size_;
8943e519524SHoward Hinnant
8953e519524SHoward Hinnant    template <class _Tp>
8963739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __process(_Tp* __p, false_type) _NOEXCEPT
8979ffacf3dSEric Fiselier        {for (size_t __i = 0; __i < __size_; ++__i, ++__p) __p->~_Tp();}
8983e519524SHoward Hinnant
8993e519524SHoward Hinnant    template <class _Tp>
9003739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __process(_Tp*, true_type) _NOEXCEPT
9013e519524SHoward Hinnant        {}
9023e519524SHoward Hinnant
9033739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __incr(false_type) _NOEXCEPT
9049ffacf3dSEric Fiselier        {++__size_;}
9053739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __incr(true_type) _NOEXCEPT
9063e519524SHoward Hinnant        {}
9073e519524SHoward Hinnant
9083739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, false_type) _NOEXCEPT
9099ffacf3dSEric Fiselier        {__size_ = __s;}
9103739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __set(size_t, true_type) _NOEXCEPT
9113e519524SHoward Hinnant        {}
9123e519524SHoward Hinnantpublic:
9133739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY explicit __destruct_n(size_t __s) _NOEXCEPT
9149ffacf3dSEric Fiselier        : __size_(__s) {}
9153e519524SHoward Hinnant
9163e519524SHoward Hinnant    template <class _Tp>
917527a7fdfSBruce Mitchener    _LIBCPP_INLINE_VISIBILITY void __incr() _NOEXCEPT
918ca740483SHoward Hinnant        {__incr(integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
9193e519524SHoward Hinnant
9203e519524SHoward Hinnant    template <class _Tp>
9213739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void __set(size_t __s, _Tp*) _NOEXCEPT
922ca740483SHoward Hinnant        {__set(__s, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
9233e519524SHoward Hinnant
9243e519524SHoward Hinnant    template <class _Tp>
9253739fe79SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __p) _NOEXCEPT
926ca740483SHoward Hinnant        {__process(__p, integral_constant<bool, is_trivially_destructible<_Tp>::value>());}
9273e519524SHoward Hinnant};
9283e519524SHoward Hinnant
929f0544c20SHoward Hinnant_LIBCPP_FUNC_VIS void* align(size_t __align, size_t __sz, void*& __ptr, size_t& __space);
9303e519524SHoward Hinnant
9311378a5aeSMarshall Clowtemplate <typename _Alloc, typename _Traits=allocator_traits<_Alloc> >
9321378a5aeSMarshall Clowstruct __noexcept_move_assign_container : public integral_constant<bool,
9331378a5aeSMarshall Clow    _Traits::propagate_on_container_move_assignment::value
9341378a5aeSMarshall Clow#if _LIBCPP_STD_VER > 14
9351378a5aeSMarshall Clow        || _Traits::is_always_equal::value
9361378a5aeSMarshall Clow#else
9371378a5aeSMarshall Clow        && is_nothrow_move_assignable<_Alloc>::value
9381378a5aeSMarshall Clow#endif
9391378a5aeSMarshall Clow    > {};
940e3fbe143SMarshall Clow
941dc3eb83dSMarshall Clow
942dc3eb83dSMarshall Clowtemplate <class _Tp, class _Alloc>
943dc3eb83dSMarshall Clowstruct __temp_value {
944dc3eb83dSMarshall Clow    typedef allocator_traits<_Alloc> _Traits;
945dc3eb83dSMarshall Clow
946*c74059c5SNikolas Klauser#ifdef _LIBCPP_CXX03_LANG
947d108bf85SEric Fiselier    typename aligned_storage<sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)>::type __v;
948*c74059c5SNikolas Klauser#else
949*c74059c5SNikolas Klauser    union { _Tp __v; };
950*c74059c5SNikolas Klauser#endif
951dc3eb83dSMarshall Clow    _Alloc &__a;
952dc3eb83dSMarshall Clow
953*c74059c5SNikolas Klauser    _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp *__addr() {
954*c74059c5SNikolas Klauser#ifdef _LIBCPP_CXX03_LANG
955*c74059c5SNikolas Klauser        return reinterpret_cast<_Tp*>(std::addressof(__v));
956*c74059c5SNikolas Klauser#else
957*c74059c5SNikolas Klauser        return std::addressof(__v);
958*c74059c5SNikolas Klauser#endif
959*c74059c5SNikolas Klauser    }
960*c74059c5SNikolas Klauser
961*c74059c5SNikolas Klauser    _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &   get() { return *__addr(); }
962dc3eb83dSMarshall Clow
963dc3eb83dSMarshall Clow    template<class... _Args>
964f11c00d7SPeter Collingbourne    _LIBCPP_NO_CFI
965*c74059c5SNikolas Klauser    _LIBCPP_CONSTEXPR_AFTER_CXX17 __temp_value(_Alloc &__alloc, _Args&& ... __args) : __a(__alloc) {
966*c74059c5SNikolas Klauser      _Traits::construct(__a, __addr(), std::forward<_Args>(__args)...);
967f11c00d7SPeter Collingbourne    }
968dc3eb83dSMarshall Clow
969*c74059c5SNikolas Klauser    _LIBCPP_CONSTEXPR_AFTER_CXX17 ~__temp_value() { _Traits::destroy(__a, __addr()); }
970dc3eb83dSMarshall Clow};
971dc3eb83dSMarshall Clow
97276b26852SMarshall Clowtemplate<typename _Alloc, typename = void, typename = void>
9730e22bf8cSMarshall Clowstruct __is_allocator : false_type {};
9740e22bf8cSMarshall Clow
9750e22bf8cSMarshall Clowtemplate<typename _Alloc>
9760e22bf8cSMarshall Clowstruct __is_allocator<_Alloc,
97776b26852SMarshall Clow       typename __void_t<typename _Alloc::value_type>::type,
978ab3fcc50SArthur O'Dwyer       typename __void_t<decltype(declval<_Alloc&>().allocate(size_t(0)))>::type
97976b26852SMarshall Clow     >
9800e22bf8cSMarshall Clow   : true_type {};
9810e22bf8cSMarshall Clow
982d63dd874SEric Fiselier// __builtin_new_allocator -- A non-templated helper for allocating and
983d63dd874SEric Fiselier// deallocating memory using __builtin_operator_new and
984d63dd874SEric Fiselier// __builtin_operator_delete. It should be used in preference to
985d63dd874SEric Fiselier// `std::allocator<T>` to avoid additional instantiations.
986d63dd874SEric Fiselierstruct __builtin_new_allocator {
987d63dd874SEric Fiselier  struct __builtin_new_deleter {
988d63dd874SEric Fiselier    typedef void* pointer_type;
989d63dd874SEric Fiselier
990d63dd874SEric Fiselier    _LIBCPP_CONSTEXPR explicit __builtin_new_deleter(size_t __size, size_t __align)
991d63dd874SEric Fiselier        : __size_(__size), __align_(__align) {}
992d63dd874SEric Fiselier
993b48c5010SNikolas Klauser    void operator()(void* __p) const _NOEXCEPT {
994b48c5010SNikolas Klauser        _VSTD::__libcpp_deallocate(__p, __size_, __align_);
995d63dd874SEric Fiselier    }
996d63dd874SEric Fiselier
997d63dd874SEric Fiselier   private:
998d63dd874SEric Fiselier    size_t __size_;
999d63dd874SEric Fiselier    size_t __align_;
1000d63dd874SEric Fiselier  };
1001d63dd874SEric Fiselier
1002d63dd874SEric Fiselier  typedef unique_ptr<void, __builtin_new_deleter> __holder_t;
1003d63dd874SEric Fiselier
1004d63dd874SEric Fiselier  static __holder_t __allocate_bytes(size_t __s, size_t __align) {
1005d586f92cSArthur O'Dwyer      return __holder_t(_VSTD::__libcpp_allocate(__s, __align),
1006d63dd874SEric Fiselier                     __builtin_new_deleter(__s, __align));
1007d63dd874SEric Fiselier  }
1008d63dd874SEric Fiselier
1009d63dd874SEric Fiselier  static void __deallocate_bytes(void* __p, size_t __s,
1010d63dd874SEric Fiselier                                 size_t __align) _NOEXCEPT {
1011d586f92cSArthur O'Dwyer      _VSTD::__libcpp_deallocate(__p, __s, __align);
1012d63dd874SEric Fiselier  }
1013d63dd874SEric Fiselier
1014d63dd874SEric Fiselier  template <class _Tp>
1015d63dd874SEric Fiselier  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
1016d63dd874SEric Fiselier  static __holder_t __allocate_type(size_t __n) {
1017d63dd874SEric Fiselier      return __allocate_bytes(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
1018d63dd874SEric Fiselier  }
1019d63dd874SEric Fiselier
1020d63dd874SEric Fiselier  template <class _Tp>
1021d63dd874SEric Fiselier  _LIBCPP_NODEBUG _LIBCPP_ALWAYS_INLINE
1022d63dd874SEric Fiselier  static void __deallocate_type(void* __p, size_t __n) _NOEXCEPT {
1023d63dd874SEric Fiselier      __deallocate_bytes(__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));
1024d63dd874SEric Fiselier  }
1025d63dd874SEric Fiselier};
1026d63dd874SEric Fiselier
10273e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
10283e519524SHoward Hinnant
10290a06eb91SLouis Dionne#if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17
103095689243SLouis Dionne#   include <__pstl_memory>
10310a06eb91SLouis Dionne#endif
10320a06eb91SLouis Dionne
10333e519524SHoward Hinnant#endif // _LIBCPP_MEMORY
1034