master
   1// -*- C++ -*-
   2//===----------------------------------------------------------------------===//
   3//
   4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
   5// See https://llvm.org/LICENSE.txt for license information.
   6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
   7//
   8//===----------------------------------------------------------------------===//
   9
  10#ifndef _LIBCPP_MEMORY
  11#define _LIBCPP_MEMORY
  12
  13// clang-format off
  14
  15/*
  16    memory synopsis
  17
  18namespace std
  19{
  20
  21struct allocator_arg_t { };
  22inline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
  23
  24template <class T, class Alloc> struct uses_allocator;
  25
  26template <class Ptr>
  27struct pointer_traits
  28{
  29    typedef Ptr pointer;
  30    typedef <details> element_type;
  31    typedef <details> difference_type;
  32
  33    template <class U> using rebind = <details>;
  34
  35    static pointer pointer_to(<details>);
  36};
  37
  38template <class T>
  39struct pointer_traits<T*>
  40{
  41    typedef T* pointer;
  42    typedef T element_type;
  43    typedef ptrdiff_t difference_type;
  44
  45    template <class U> using rebind = U*;
  46
  47    static pointer pointer_to(<details>) noexcept; // constexpr in C++20
  48};
  49
  50template <class T> constexpr T* to_address(T* p) noexcept; // C++20
  51template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // C++20
  52
  53template <class Alloc>
  54struct allocator_traits
  55{
  56    typedef Alloc                        allocator_type;
  57    typedef typename allocator_type::value_type
  58                                         value_type;
  59
  60    typedef Alloc::pointer | value_type* pointer;
  61    typedef Alloc::const_pointer
  62          | pointer_traits<pointer>::rebind<const value_type>
  63                                         const_pointer;
  64    typedef Alloc::void_pointer
  65          | pointer_traits<pointer>::rebind<void>
  66                                         void_pointer;
  67    typedef Alloc::const_void_pointer
  68          | pointer_traits<pointer>::rebind<const void>
  69                                         const_void_pointer;
  70    typedef Alloc::difference_type
  71          | pointer_traits<pointer>::difference_type
  72                                         difference_type;
  73    typedef Alloc::size_type
  74          | make_unsigned<difference_type>::type
  75                                         size_type;
  76    typedef Alloc::propagate_on_container_copy_assignment
  77          | false_type                   propagate_on_container_copy_assignment;
  78    typedef Alloc::propagate_on_container_move_assignment
  79          | false_type                   propagate_on_container_move_assignment;
  80    typedef Alloc::propagate_on_container_swap
  81          | false_type                   propagate_on_container_swap;
  82    typedef Alloc::is_always_equal
  83          | is_empty                     is_always_equal;
  84
  85    template <class T> using rebind_alloc  = Alloc::rebind<T>::other | Alloc<T, Args...>;
  86    template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
  87
  88    static pointer allocate(allocator_type& a, size_type n);                          // constexpr and [[nodiscard]] in C++20
  89    static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20
  90
  91    [[nodiscard]] static constexpr allocation_result<pointer, size_type>
  92      allocate_at_least(Alloc& a, size_type n);                                 // Since C++23
  93
  94    static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20
  95
  96    template <class T, class... Args>
  97    static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20
  98
  99    template <class T>
 100    static void destroy(allocator_type& a, T* p); // constexpr in C++20
 101
 102    static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20
 103    static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20
 104};
 105
 106template<class Pointer, class SizeType = size_t>
 107struct allocation_result {
 108    Pointer ptr;
 109    SizeType count;
 110}; // Since C++23
 111
 112template <>
 113class allocator<void> // removed in C++20
 114{
 115public:
 116    typedef void*                                 pointer;
 117    typedef const void*                           const_pointer;
 118    typedef void                                  value_type;
 119
 120    template <class _Up> struct rebind {typedef allocator<_Up> other;};
 121};
 122
 123template <class T>
 124class allocator
 125{
 126public:
 127    typedef size_t    size_type;
 128    typedef ptrdiff_t difference_type;
 129    typedef T*        pointer;                           // deprecated in C++17, removed in C++20
 130    typedef const T*  const_pointer;                     // deprecated in C++17, removed in C++20
 131    typedef typename add_lvalue_reference<T>::type
 132                      reference;                         // deprecated in C++17, removed in C++20
 133    typedef typename add_lvalue_reference<const T>::type
 134                      const_reference;                   // deprecated in C++17, removed in C++20
 135
 136    typedef T         value_type;
 137
 138    template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20
 139
 140    typedef true_type propagate_on_container_move_assignment;
 141    typedef true_type is_always_equal;                   // Deprecated in C++23, removed in C++26
 142
 143    constexpr allocator() noexcept;                      // constexpr in C++20
 144    constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
 145    template <class U>
 146      constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
 147    ~allocator();                                        // constexpr in C++20
 148    pointer address(reference x) const noexcept;             // deprecated in C++17, removed in C++20
 149    const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20
 150    T* allocate(size_t n, const void* hint);          // deprecated in C++17, removed in C++20
 151    T* allocate(size_t n);                              // constexpr in C++20
 152    void deallocate(T* p, size_t n) noexcept;           // constexpr in C++20
 153    size_type max_size() const noexcept;              // deprecated in C++17, removed in C++20
 154    template<class U, class... Args>
 155        void construct(U* p, Args&&... args);         // deprecated in C++17, removed in C++20
 156    template <class U>
 157        void destroy(U* p);                           // deprecated in C++17, removed in C++20
 158};
 159
 160template <class T, class U>
 161bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
 162
 163template <class T, class U>
 164bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // removed in C++20
 165
 166template <class OutputIterator, class T>
 167class raw_storage_iterator // deprecated in C++17, removed in C++20
 168    : public iterator<output_iterator_tag, void, void, void, void> // until C++17
 169{
 170public:
 171    typedef output_iterator_tag iterator_category;
 172    typedef void                value_type;
 173    typedef void                difference_type; // until C++20
 174    typedef ptrdiff_t           difference_type; // since C++20
 175    typedef void                pointer;
 176    typedef void                reference;
 177
 178    explicit raw_storage_iterator(OutputIterator x);
 179    raw_storage_iterator& operator*();
 180    raw_storage_iterator& operator=(const T& element);
 181    raw_storage_iterator& operator++();
 182    raw_storage_iterator  operator++(int);
 183};
 184
 185template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept; // deprecated in C++17, removed in C++20
 186template <class T> void               return_temporary_buffer(T* p) noexcept;     // deprecated in C++17, removed in C++20
 187
 188template <class T> T* addressof(T& r) noexcept;
 189template <class T> T* addressof(const T&& r) noexcept = delete;
 190
 191template <class InputIterator, class ForwardIterator>
 192ForwardIterator
 193uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
 194
 195namespace ranges {
 196
 197template<class InputIterator, class OutputIterator>
 198using uninitialized_copy_result = in_out_result<InputIterator, OutputIterator>; // since C++20
 199
 200template<input_iterator InputIterator, sentinel-for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel2>
 201  requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>>
 202uninitialized_copy_result<InputIterator, OutputIterator>
 203uninitialized_copy(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20
 204
 205template<input_range InputRange, nothrow-forward-range OutputRange>
 206  requires constructible_from<range_value_t<OutputRange>, range_reference_t<InputRange>>
 207uninitialized_copy_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>>
 208uninitialized_copy(InputRange&& in_range, OutputRange&& out_range); // since C++20
 209
 210}
 211
 212template <class InputIterator, class Size, class ForwardIterator>
 213ForwardIterator
 214uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
 215
 216namespace ranges {
 217
 218template<class InputIterator, class OutputIterator>
 219using uninitialized_copy_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20
 220
 221template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel>
 222  requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>>
 223uninitialized_copy_n_result<InputIterator, OutputIterator>
 224uninitialized_copy_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20
 225
 226}
 227
 228template <class ForwardIterator, class T>
 229void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
 230
 231namespace ranges {
 232
 233template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel, class T>
 234  requires constructible_from<iter_value_t<ForwardIterator>, const T&>
 235ForwardIterator uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20
 236
 237template <nothrow-forward-range ForwardRange, class T>
 238  requires constructible_from<range_value_t<ForwardRange>, const T&>
 239borrowed_iterator_t<ForwardRange> uninitialized_fill(ForwardRange&& range, const T& x); // since C++20
 240
 241}
 242
 243template <class ForwardIterator, class Size, class T>
 244ForwardIterator
 245uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
 246
 247namespace ranges {
 248
 249template <nothrow-forward-iterator ForwardIterator, class T>
 250  requires constructible_from<iter_value_t<ForwardIterator>, const T&>
 251ForwardIterator uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
 252
 253}
 254
 255template <class T, class ...Args>
 256constexpr T* construct_at(T* location, Args&& ...args); // since C++20
 257
 258namespace ranges {
 259  template<class T, class... Args>
 260    constexpr T* construct_at(T* location, Args&&... args); // since C++20
 261}
 262
 263template <class T>
 264void destroy_at(T* location); // constexpr in C++20
 265
 266namespace ranges {
 267  template<destructible T>
 268    constexpr void destroy_at(T* location) noexcept; // since C++20
 269}
 270
 271template <class ForwardIterator>
 272void destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20
 273
 274namespace ranges {
 275  template<nothrow-input-iterator InputIterator, nothrow-sentinel-for<InputIterator> Sentinel>
 276    requires destructible<iter_value_t<InputIterator>>
 277    constexpr InputIterator destroy(InputIterator first, Sentinel last) noexcept; // since C++20
 278  template<nothrow-input-range InputRange>
 279    requires destructible<range_value_t<InputRange>>
 280    constexpr borrowed_iterator_t<InputRange> destroy(InputRange&& range) noexcept; // since C++20
 281}
 282
 283template <class ForwardIterator, class Size>
 284ForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20
 285
 286namespace ranges {
 287  template<nothrow-input-iterator InputIterator>
 288    requires destructible<iter_value_t<InputIterator>>
 289    constexpr InputIterator destroy_n(InputIterator first, iter_difference_t<InputIterator> n) noexcept; // since C++20
 290}
 291
 292template <class InputIterator, class ForwardIterator>
 293 ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
 294
 295namespace ranges {
 296
 297template<class InputIterator, class OutputIterator>
 298using uninitialized_move_result = in_out_result<InputIterator, OutputIterator>; // since C++20
 299
 300template <input_iterator InputIterator, sentinel_for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<O> Sentinel2>
 301  requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>>
 302uninitialized_move_result<InputIterator, OutputIterator>
 303uninitialized_move(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20
 304
 305template<input_range InputRange, nothrow-forward-range OutputRange>
 306  requires constructible_from<range_value_t<OutputRange>, range_rvalue_reference_t<InputRange>>
 307uninitialized_move_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>>
 308uninitialized_move(InputRange&& in_range, OutputRange&& out_range); // since C++20
 309
 310}
 311
 312template <class InputIterator, class Size, class ForwardIterator>
 313 pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
 314
 315namespace ranges {
 316
 317template<class InputIterator, class OutputIterator>
 318using uninitialized_move_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20
 319
 320template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel>
 321  requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>>
 322uninitialized_move_n_result<InputIterator, OutputIterator>
 323uninitialized_move_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20
 324
 325}
 326
 327template <class ForwardIterator>
 328 void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
 329
 330namespace ranges {
 331
 332template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel>
 333  requires default_initializable<iter_value_t<ForwardIterator>>
 334 ForwardIterator uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20
 335
 336template <nothrow-forward-range ForwardRange>
 337  requires default_initializable<range_value_t<ForwardRange>>
 338 borrowed_iterator_t<ForwardRange> uninitialized_value_construct(ForwardRange&& r); // since C++20
 339
 340}
 341
 342template <class ForwardIterator, class Size>
 343 ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
 344
 345namespace ranges {
 346
 347template <nothrow-forward-iterator ForwardIterator>
 348  requires default_initializable<iter_value_t<ForwardIterator>>
 349 ForwardIterator uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
 350
 351}
 352
 353template <class ForwardIterator>
 354 void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
 355
 356namespace ranges {
 357
 358template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel>
 359  requires default_initializable<iter_value_t<ForwardIterator>>
 360 ForwardIterator uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20
 361
 362template <nothrow-forward-range ForwardRange>
 363  requires default_initializable<range_value_t<ForwardRange>>
 364 borrowed_iterator_t<ForwardRange> uninitialized_default_construct(ForwardRange&& r); // since C++20
 365
 366}
 367
 368template <class ForwardIterator, class Size>
 369 ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
 370
 371namespace ranges {
 372
 373template <nothrow-forward-iterator ForwardIterator>
 374  requires default_initializable<iter_value_t<ForwardIterator>>
 375 ForwardIterator uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
 376
 377}
 378
 379template <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17
 380
 381template<class X>
 382class auto_ptr                                  // deprecated in C++11, removed in C++17
 383{
 384public:
 385    typedef X element_type;
 386
 387    explicit auto_ptr(X* p =0) throw();
 388    auto_ptr(auto_ptr&) throw();
 389    template<class Y> auto_ptr(auto_ptr<Y>&) throw();
 390    auto_ptr& operator=(auto_ptr&) throw();
 391    template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
 392    auto_ptr& operator=(auto_ptr_ref<X> r) throw();
 393    ~auto_ptr() throw();
 394
 395    typename add_lvalue_reference<X>::type operator*() const throw();
 396    X* operator->() const throw();
 397    X* get() const throw();
 398    X* release() throw();
 399    void reset(X* p =0) throw();
 400
 401    auto_ptr(auto_ptr_ref<X>) throw();
 402    template<class Y> operator auto_ptr_ref<Y>() throw();
 403    template<class Y> operator auto_ptr<Y>() throw();
 404};
 405
 406template <class T>
 407struct default_delete
 408{
 409    constexpr default_delete() noexcept = default;
 410    template <class U> constexpr default_delete(const default_delete<U>&) noexcept; // constexpr since C++23
 411
 412    constexpr void operator()(T*) const noexcept;                                   // constexpr since C++23
 413};
 414
 415template <class T>
 416struct default_delete<T[]>
 417{
 418    constexpr default_delete() noexcept = default;
 419    template <class U> constexpr default_delete(const default_delete <U[]>&) noexcept; // constexpr since C++23
 420    constexpr void operator()(T*) const noexcept;                                      // constexpr since C++23
 421    template <class U> void operator()(U*) const = delete;
 422};
 423
 424template <class T, class D = default_delete<T>>
 425class unique_ptr
 426{
 427public:
 428    typedef see below pointer;
 429    typedef T element_type;
 430    typedef D deleter_type;
 431
 432    // constructors
 433    constexpr unique_ptr() noexcept;
 434    constexpr explicit unique_ptr(pointer p) noexcept;           // constexpr since C++23
 435    constexpr unique_ptr(pointer p, see below d1) noexcept;      // constexpr since C++23
 436    constexpr unique_ptr(pointer p, see below d2) noexcept;      // constexpr since C++23
 437    constexpr unique_ptr(unique_ptr&& u) noexcept;               // constexpr since C++23
 438    constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
 439    template <class U, class E>
 440        constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;     // constexpr since C++23
 441    template <class U>
 442        unique_ptr(auto_ptr<U>&& u) noexcept;                    // removed in C++17
 443
 444    // destructor
 445    constexpr ~unique_ptr();                                     // constexpr since C++23
 446
 447    // assignment
 448    constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;                         // constexpr since C++23
 449    template <class U, class E>
 450    constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;                   // constexpr since C++23
 451    constexpr unique_ptr& operator=(nullptr_t) noexcept;                              // constexpr since C++23
 452
 453    // observers
 454    constexpr
 455    add_lvalue_reference<T>::type operator*() const noexcept(see below);              // constexpr since C++23
 456    constexpr pointer operator->() const noexcept;                                    // constexpr since C++23
 457    constexpr pointer get() const noexcept;                                           // constexpr since C++23
 458    constexpr deleter_type& get_deleter() noexcept;                                   // constexpr since C++23
 459    constexpr const deleter_type& get_deleter() const noexcept;                       // constexpr since C++23
 460    constexpr explicit operator bool() const noexcept;                                // constexpr since C++23
 461
 462    // modifiers
 463    constexpr pointer release() noexcept;                                             // constexpr since C++23
 464    constexpr void reset(pointer p = pointer()) noexcept;                             // constexpr since C++23
 465    constexpr void swap(unique_ptr& u) noexcept;                                      // constexpr since C++23
 466};
 467
 468template <class T, class D>
 469class unique_ptr<T[], D>
 470{
 471public:
 472    typedef implementation-defined pointer;
 473    typedef T element_type;
 474    typedef D deleter_type;
 475
 476    // constructors
 477    constexpr unique_ptr() noexcept;
 478    constexpr explicit unique_ptr(pointer p) noexcept;          // constexpr since C++23
 479    constexpr unique_ptr(pointer p, see below d) noexcept;      // constexpr since C++23
 480    constexpr unique_ptr(pointer p, see below d) noexcept;      // constexpr since C++23
 481    constexpr unique_ptr(unique_ptr&& u) noexcept;              // constexpr since C++23
 482    template <class U, class E>
 483    constexpr unique_ptr(unique_ptr <U, E>&& u) noexcept;       // constexpr since C++23
 484    constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
 485
 486    // destructor
 487    constexpr ~unique_ptr();                                    // constexpr since C++23
 488
 489    // assignment
 490    constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;        // constexpr since C++23
 491    template <class U, class E>
 492    constexpr unique_ptr& operator=(unique_ptr <U, E>&& u) noexcept; // constexpr since C++23
 493    constexpr unique_ptr& operator=(nullptr_t) noexcept;             // constexpr since C++23
 494
 495    // observers
 496    constexpr T& operator[](size_t i) const;                    // constexpr since C++23
 497    constexpr pointer get() const noexcept;                     // constexpr since C++23
 498    constexpr deleter_type& get_deleter() noexcept;             // constexpr since C++23
 499    constexpr const deleter_type& get_deleter() const noexcept; // constexpr since C++23
 500    constexpr explicit operator bool() const noexcept;          // constexpr since C++23
 501
 502    // modifiers
 503    constexpr pointer release() noexcept;                       // constexpr since C++23
 504    constexpr void reset(pointer p = pointer()) noexcept;       // constexpr since C++23
 505    constexpr void reset(nullptr_t) noexcept;                   // constexpr since C++23
 506  template <class U> void reset(U) = delete;
 507    constexpr void swap(unique_ptr& u) noexcept;                // constexpr since C++23
 508};
 509
 510template <class T, class D>
 511    constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;                 // constexpr since C++23
 512
 513template <class T1, class D1, class T2, class D2>
 514    constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);    // constexpr since C++23
 515template <class T1, class D1, class T2, class D2>
 516    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);              // removed in C++20
 517template <class T1, class D1, class T2, class D2>
 518    bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 519template <class T1, class D1, class T2, class D2>
 520    bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 521template <class T1, class D1, class T2, class D2>
 522    bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 523template <class T1, class D1, class T2, class D2>
 524    bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 525template<class T1, class D1, class T2, class D2>
 526  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
 527                                     typename unique_ptr<T2, D2>::pointer>
 528  compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
 529                             typename unique_ptr<T2, D2>::pointer>
 530    operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);      // C++20
 531
 532template <class T, class D>
 533    constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;   // constexpr since C++23
 534template <class T, class D>
 535    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;             // removed in C++20
 536template <class T, class D>
 537    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;             // removed in C++20
 538template <class T, class D>
 539    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;             // removed in C++20
 540
 541template <class T, class D>
 542    constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t);     // constexpr since C++23
 543template <class T, class D>
 544    constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y);     // constexpr since C++23
 545template <class T, class D>
 546    constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t);    // constexpr since C++23
 547template <class T, class D>
 548    constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y);    // constexpr since C++23
 549template <class T, class D>
 550    constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t);     // constexpr since C++23
 551template <class T, class D>
 552    constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y);     // constexpr since C++23
 553template <class T, class D>
 554    constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t);    // constexpr since C++23
 555template <class T, class D>
 556    constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y);    // constexpr since C++23
 557template<class T, class D>
 558  requires three_way_comparable<typename unique_ptr<T, D>::pointer>
 559  compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
 560    constexpr operator<=>(const unique_ptr<T, D>& x, nullptr_t);        // C++20, constexpr since C++23
 561
 562class bad_weak_ptr
 563    : public std::exception
 564{
 565    bad_weak_ptr() noexcept;
 566};
 567
 568template<class T, class... Args>
 569constexpr unique_ptr<T> make_unique(Args&&... args);                            // C++14, constexpr since C++23
 570template<class T>
 571constexpr unique_ptr<T> make_unique(size_t n);                                  // C++14, constexpr since C++23
 572template<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
 573
 574template<class T>
 575  constexpr unique_ptr<T> make_unique_for_overwrite();                        // T is not array, C++20, constexpr since C++23
 576template<class T>
 577  constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);                // T is U[], C++20, constexpr since C++23
 578template<class T, class... Args>
 579  unspecified make_unique_for_overwrite(Args&&...) = delete;                  // T is U[N], C++20
 580
 581template<class E, class T, class Y, class D>
 582    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
 583
 584template<class T>
 585class shared_ptr
 586{
 587public:
 588    typedef T element_type; // until C++17
 589    typedef remove_extent_t<T> element_type; // since C++17
 590    typedef weak_ptr<T> weak_type; // C++17
 591
 592    // constructors:
 593    constexpr shared_ptr() noexcept;
 594    template<class Y> explicit shared_ptr(Y* p);
 595    template<class Y, class D> shared_ptr(Y* p, D d);
 596    template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
 597    template <class D> shared_ptr(nullptr_t p, D d);
 598    template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
 599    template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
 600    shared_ptr(const shared_ptr& r) noexcept;
 601    template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
 602    shared_ptr(shared_ptr&& r) noexcept;
 603    template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
 604    template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
 605    template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
 606    template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
 607    shared_ptr(nullptr_t) : shared_ptr() { }
 608
 609    // destructor:
 610    ~shared_ptr();
 611
 612    // assignment:
 613    shared_ptr& operator=(const shared_ptr& r) noexcept;
 614    template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
 615    shared_ptr& operator=(shared_ptr&& r) noexcept;
 616    template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
 617    template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
 618    template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
 619
 620    // modifiers:
 621    void swap(shared_ptr& r) noexcept;
 622    void reset() noexcept;
 623    template<class Y> void reset(Y* p);
 624    template<class Y, class D> void reset(Y* p, D d);
 625    template<class Y, class D, class A> void reset(Y* p, D d, A a);
 626
 627    // observers:
 628    T* get() const noexcept;
 629    T& operator*() const noexcept;
 630    T* operator->() const noexcept;
 631    long use_count() const noexcept;
 632    bool unique() const noexcept;  // deprected in C++17, removed in C++20
 633    explicit operator bool() const noexcept;
 634    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
 635    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
 636};
 637
 638template<class T>
 639shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
 640template<class T, class D>
 641shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
 642
 643// shared_ptr comparisons:
 644template<class T, class U>
 645    bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
 646template<class T, class U>
 647    bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;               // removed in C++20
 648template<class T, class U>
 649    bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;                // removed in C++20
 650template<class T, class U>
 651    bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;                // removed in C++20
 652template<class T, class U>
 653    bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;               // removed in C++20
 654template<class T, class U>
 655    bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;               // removed in C++20
 656template<class T, class U>
 657    strong_ordering operator<=>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;   // C++20
 658
 659template <class T>
 660    bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
 661template <class T>
 662    bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
 663template <class T>
 664    bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;               // removed in C++20
 665template <class T>
 666    bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
 667template <class T>
 668    bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;                // removed in C++20
 669template <class T>
 670    bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;                // removed in C++20
 671template <class T>
 672    bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;               // removed in C++20
 673template <class T>
 674    bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
 675template <class T>
 676    bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;                // removed in C++20
 677template <class T>
 678    bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;                // removed in C++20
 679template <class T>
 680    bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;               // removed in C++20
 681template <class T>
 682    bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
 683template<class T>
 684    strong_ordering operator<=>(shared_ptr<T> const& x, nullptr_t) noexcept;   // C++20
 685
 686// shared_ptr specialized algorithms:
 687template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
 688
 689// shared_ptr casts:
 690template<class T, class U>
 691    shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
 692template<class T, class U>
 693    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
 694template<class T, class U>
 695    shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
 696
 697// shared_ptr I/O:
 698template<class E, class T, class Y>
 699    basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
 700
 701// shared_ptr get_deleter:
 702template<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
 703
 704template<class T, class... Args>
 705    shared_ptr<T> make_shared(Args&&... args); // T is not an array
 706template<class T, class A, class... Args>
 707    shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not an array
 708
 709template<class T>
 710    shared_ptr<T> make_shared(size_t N); // T is U[] (since C++20)
 711template<class T, class A>
 712    shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[] (since C++20)
 713
 714template<class T>
 715    shared_ptr<T> make_shared(); // T is U[N] (since C++20)
 716template<class T, class A>
 717    shared_ptr<T> allocate_shared(const A& a); // T is U[N] (since C++20)
 718
 719template<class T>
 720    shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
 721template<class T, class A>
 722    shared_ptr<T> allocate_shared(const A& a, size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
 723
 724template<class T> shared_ptr<T>
 725    make_shared(const remove_extent_t<T>& u); // T is U[N] (since C++20)
 726template<class T, class A>
 727    shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N] (since C++20)
 728
 729template<class T>
 730  shared_ptr<T> make_shared_for_overwrite();                                  // T is not U[], C++20
 731template<class T, class A>
 732  shared_ptr<T> allocate_shared_for_overwrite(const A& a);                    // T is not U[], C++20
 733
 734template<class T>
 735  shared_ptr<T> make_shared_for_overwrite(size_t N);                          // T is U[], C++20
 736template<class T, class A>
 737  shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);          // T is U[], C++20
 738
 739template<class T>
 740class weak_ptr
 741{
 742public:
 743    typedef T element_type; // until C++17
 744    typedef remove_extent_t<T> element_type; // since C++17
 745
 746    // constructors
 747    constexpr weak_ptr() noexcept;
 748    template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
 749    weak_ptr(weak_ptr const& r) noexcept;
 750    template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
 751    weak_ptr(weak_ptr&& r) noexcept;                      // C++14
 752    template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
 753
 754    // destructor
 755    ~weak_ptr();
 756
 757    // assignment
 758    weak_ptr& operator=(weak_ptr const& r) noexcept;
 759    template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
 760    template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
 761    weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
 762    template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
 763
 764    // modifiers
 765    void swap(weak_ptr& r) noexcept;
 766    void reset() noexcept;
 767
 768    // observers
 769    long use_count() const noexcept;
 770    bool expired() const noexcept;
 771    shared_ptr<T> lock() const noexcept;
 772    template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
 773    template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
 774};
 775
 776template<class T>
 777weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
 778
 779// weak_ptr specialized algorithms:
 780template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
 781
 782// class owner_less:
 783template<class T> struct owner_less;
 784
 785template<class T>
 786struct owner_less<shared_ptr<T> >
 787    : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
 788{
 789    typedef bool result_type;
 790    bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
 791    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
 792    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
 793};
 794
 795template<class T>
 796struct owner_less<weak_ptr<T> >
 797    : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
 798{
 799    typedef bool result_type;
 800    bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
 801    bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
 802    bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
 803};
 804
 805template <>  // Added in C++14
 806struct owner_less<void>
 807{
 808    template <class _Tp, class _Up>
 809    bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
 810    template <class _Tp, class _Up>
 811    bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
 812    template <class _Tp, class _Up>
 813    bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
 814    template <class _Tp, class _Up>
 815    bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
 816
 817    typedef void is_transparent;
 818};
 819
 820template<class T>
 821class enable_shared_from_this
 822{
 823protected:
 824    constexpr enable_shared_from_this() noexcept;
 825    enable_shared_from_this(enable_shared_from_this const&) noexcept;
 826    enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
 827    ~enable_shared_from_this();
 828public:
 829    shared_ptr<T> shared_from_this();
 830    shared_ptr<T const> shared_from_this() const;
 831};
 832
 833template<class T>
 834    bool atomic_is_lock_free(const shared_ptr<T>* p);
 835template<class T>
 836    shared_ptr<T> atomic_load(const shared_ptr<T>* p);
 837template<class T>
 838    shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
 839template<class T>
 840    void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
 841template<class T>
 842    void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
 843template<class T>
 844    shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
 845template<class T>
 846    shared_ptr<T>
 847    atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
 848template<class T>
 849    bool
 850    atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
 851template<class T>
 852    bool
 853    atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
 854template<class T>
 855    bool
 856    atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
 857                                          shared_ptr<T> w, memory_order success,
 858                                          memory_order failure);
 859template<class T>
 860    bool
 861    atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
 862                                            shared_ptr<T> w, memory_order success,
 863                                            memory_order failure);
 864// Hash support
 865template <class T> struct hash;
 866template <class T, class D> struct hash<unique_ptr<T, D> >;
 867template <class T> struct hash<shared_ptr<T> >;
 868
 869template <class T, class Alloc>
 870  inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
 871
 872// [allocator.uses.construction], uses-allocator construction
 873template<class T, class Alloc, class... Args>
 874  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
 875                                                  Args&&... args) noexcept;
 876template<class T, class Alloc, class Tuple1, class Tuple2>
 877  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
 878                                                  piecewise_construct_t,
 879                                                  Tuple1&& x, Tuple2&& y) noexcept;
 880template<class T, class Alloc>
 881  constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;   // since C++20
 882template<class T, class Alloc, class U, class V>
 883  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
 884                                                  U&& u, V&& v) noexcept;
 885template<class T, class Alloc, class U, class V>
 886  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++23
 887                                                  pair<U, V>& pr) noexcept;
 888template<class T, class Alloc, class U, class V>
 889  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
 890                                                  const pair<U, V>& pr) noexcept;
 891template<class T, class Alloc, class U, class V>
 892  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
 893                                                  pair<U, V>&& pr) noexcept;
 894template<class T, class Alloc, class U, class V>
 895  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++23
 896                                                  const pair<U, V>&& pr) noexcept;
 897template<class T, class Alloc, pair-like P>
 898  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
 899                                                  P&& p) noexcept;
 900template<class T, class Alloc, class U>
 901  constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
 902                                                  U&& u) noexcept;
 903template<class T, class Alloc, class... Args>
 904  constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);       // since C++20
 905template<class T, class Alloc, class... Args>
 906  constexpr T* uninitialized_construct_using_allocator(T* p,                      // since C++20
 907                                                         const Alloc& alloc, Args&&... args);
 908
 909// [ptr.align]
 910void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
 911
 912template<size_t N, class T>
 913[[nodiscard]] constexpr T* assume_aligned(T* ptr); // since C++20
 914
 915template<size_t Alignment, class T>
 916  bool is_sufficiently_aligned(T* ptr); // since C++26
 917
 918// [out.ptr.t], class template out_ptr_t
 919template<class Smart, class Pointer, class... Args>
 920  class out_ptr_t;                                          // since c++23
 921
 922// [out.ptr], function template out_ptr
 923template<class Pointer = void, class Smart, class... Args>
 924  auto out_ptr(Smart& s, Args&&... args);                   // since c++23
 925
 926// [inout.ptr.t], class template inout_ptr_t
 927template<class Smart, class Pointer, class... Args>
 928  class inout_ptr_t;                                        // since c++23
 929
 930// [inout.ptr], function template inout_ptr
 931template<class Pointer = void, class Smart, class... Args>
 932  auto inout_ptr(Smart& s, Args&&... args);                 // since c++23
 933
 934}  // std
 935
 936*/
 937
 938// clang-format on
 939
 940#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
 941#  include <__cxx03/memory>
 942#else
 943#  include <__config>
 944#  include <__memory/addressof.h>
 945#  include <__memory/align.h>
 946#  include <__memory/allocator.h>
 947#  include <__memory/allocator_arg_t.h>
 948#  include <__memory/allocator_traits.h>
 949#  include <__memory/auto_ptr.h>
 950#  include <__memory/inout_ptr.h>
 951#  include <__memory/is_sufficiently_aligned.h>
 952#  include <__memory/out_ptr.h>
 953#  include <__memory/pointer_traits.h>
 954#  include <__memory/raw_storage_iterator.h>
 955#  include <__memory/shared_ptr.h>
 956#  include <__memory/temporary_buffer.h>
 957#  include <__memory/uninitialized_algorithms.h>
 958#  include <__memory/unique_ptr.h>
 959#  include <__memory/uses_allocator.h>
 960
 961// standard-mandated includes
 962
 963#  if _LIBCPP_STD_VER >= 17
 964#    include <__memory/construct_at.h>
 965#    include <__memory/destroy.h>
 966#  endif
 967
 968#  if _LIBCPP_STD_VER >= 20
 969#    include <__memory/assume_aligned.h>
 970#    include <__memory/concepts.h>
 971#    include <__memory/ranges_construct_at.h>
 972#    include <__memory/ranges_destroy.h>
 973#    include <__memory/ranges_uninitialized_algorithms.h>
 974#    include <__memory/uses_allocator_construction.h>
 975#  endif
 976
 977#  if _LIBCPP_STD_VER >= 23
 978#    include <__memory/allocate_at_least.h>
 979#  endif
 980
 981#  include <version>
 982
 983// [memory.syn]
 984#  include <compare>
 985
 986#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 987#    pragma GCC system_header
 988#  endif
 989
 990#  if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
 991#    include <atomic>
 992#    include <concepts>
 993#    include <cstddef>
 994#    include <cstdint>
 995#    include <cstdlib>
 996#    include <cstring>
 997#    include <iosfwd>
 998#    include <iterator>
 999#    include <new>
1000#    include <stdexcept>
1001#    include <tuple>
1002#    include <type_traits>
1003#    include <typeinfo>
1004#    include <utility>
1005#  endif
1006#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
1007
1008#endif // _LIBCPP_MEMORY