Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / include / memory
blob24ba82f43ddd30907eb8fc9bf71c554a12c8b4ba
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 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_MEMORY
11 #define _LIBCPP_MEMORY
14     memory synopsis
16 namespace std
19 struct allocator_arg_t { };
20 inline constexpr allocator_arg_t allocator_arg = allocator_arg_t();
22 template <class T, class Alloc> struct uses_allocator;
24 template <class Ptr>
25 struct pointer_traits
27     typedef Ptr pointer;
28     typedef <details> element_type;
29     typedef <details> difference_type;
31     template <class U> using rebind = <details>;
33     static pointer pointer_to(<details>);
36 template <class T>
37 struct pointer_traits<T*>
39     typedef T* pointer;
40     typedef T element_type;
41     typedef ptrdiff_t difference_type;
43     template <class U> using rebind = U*;
45     static pointer pointer_to(<details>) noexcept; // constexpr in C++20
48 template <class T> constexpr T* to_address(T* p) noexcept; // C++20
49 template <class Ptr> constexpr auto to_address(const Ptr& p) noexcept; // C++20
51 template <class Alloc>
52 struct allocator_traits
54     typedef Alloc                        allocator_type;
55     typedef typename allocator_type::value_type
56                                          value_type;
58     typedef Alloc::pointer | value_type* pointer;
59     typedef Alloc::const_pointer
60           | pointer_traits<pointer>::rebind<const value_type>
61                                          const_pointer;
62     typedef Alloc::void_pointer
63           | pointer_traits<pointer>::rebind<void>
64                                          void_pointer;
65     typedef Alloc::const_void_pointer
66           | pointer_traits<pointer>::rebind<const void>
67                                          const_void_pointer;
68     typedef Alloc::difference_type
69           | pointer_traits<pointer>::difference_type
70                                          difference_type;
71     typedef Alloc::size_type
72           | make_unsigned<difference_type>::type
73                                          size_type;
74     typedef Alloc::propagate_on_container_copy_assignment
75           | false_type                   propagate_on_container_copy_assignment;
76     typedef Alloc::propagate_on_container_move_assignment
77           | false_type                   propagate_on_container_move_assignment;
78     typedef Alloc::propagate_on_container_swap
79           | false_type                   propagate_on_container_swap;
80     typedef Alloc::is_always_equal
81           | is_empty                     is_always_equal;
83     template <class T> using rebind_alloc  = Alloc::rebind<T>::other | Alloc<T, Args...>;
84     template <class T> using rebind_traits = allocator_traits<rebind_alloc<T>>;
86     static pointer allocate(allocator_type& a, size_type n);                          // constexpr and [[nodiscard]] in C++20
87     static pointer allocate(allocator_type& a, size_type n, const_void_pointer hint); // constexpr and [[nodiscard]] in C++20
89     static void deallocate(allocator_type& a, pointer p, size_type n) noexcept; // constexpr in C++20
91     template <class T, class... Args>
92     static void construct(allocator_type& a, T* p, Args&&... args); // constexpr in C++20
94     template <class T>
95     static void destroy(allocator_type& a, T* p); // constexpr in C++20
97     static size_type max_size(const allocator_type& a); // noexcept in C++14, constexpr in C++20
98     static allocator_type select_on_container_copy_construction(const allocator_type& a); // constexpr in C++20
101 template<class Pointer>
102 struct allocation_result {
103     Pointer ptr;
104     size_t count;
105 }; // since C++23
107 template<class Allocator>
108 [[nodiscard]] constexpr allocation_result<typename allocator_traits<Allocator>::pointer>
109     allocate_at_least(Allocator& a, size_t n); // since C++23
111 template <>
112 class allocator<void> // removed in C++20
114 public:
115     typedef void*                                 pointer;
116     typedef const void*                           const_pointer;
117     typedef void                                  value_type;
119     template <class _Up> struct rebind {typedef allocator<_Up> other;};
122 template <class T>
123 class allocator
125 public:
126     typedef size_t    size_type;
127     typedef ptrdiff_t difference_type;
128     typedef T*        pointer;                           // deprecated in C++17, removed in C++20
129     typedef const T*  const_pointer;                     // deprecated in C++17, removed in C++20
130     typedef typename add_lvalue_reference<T>::type
131                       reference;                         // deprecated in C++17, removed in C++20
132     typedef typename add_lvalue_reference<const T>::type
133                       const_reference;                   // deprecated in C++17, removed in C++20
135     typedef T         value_type;
137     template <class U> struct rebind {typedef allocator<U> other;}; // deprecated in C++17, removed in C++20
139     typedef true_type propagate_on_container_move_assignment;
140     typedef true_type is_always_equal;
142     constexpr allocator() noexcept;                      // constexpr in C++20
143     constexpr allocator(const allocator&) noexcept;      // constexpr in C++20
144     template <class U>
145       constexpr allocator(const allocator<U>&) noexcept; // constexpr in C++20
146     ~allocator();                                        // constexpr in C++20
147     pointer address(reference x) const noexcept;             // deprecated in C++17, removed in C++20
148     const_pointer address(const_reference x) const noexcept; // deprecated in C++17, removed in C++20
149     T* allocate(size_t n, const void* hint);          // deprecated in C++17, removed in C++20
150     T* allocate(size_t n);                              // constexpr in C++20
151     void deallocate(T* p, size_t n) noexcept;           // constexpr in C++20
152     size_type max_size() const noexcept;              // deprecated in C++17, removed in C++20
153     template<class U, class... Args>
154         void construct(U* p, Args&&... args);         // deprecated in C++17, removed in C++20
155     template <class U>
156         void destroy(U* p);                           // deprecated in C++17, removed in C++20
159 template <class T, class U>
160 bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // constexpr in C++20
162 template <class T, class U>
163 bool operator!=(const allocator<T>&, const allocator<U>&) noexcept; // removed in C++20
165 template <class OutputIterator, class T>
166 class raw_storage_iterator // deprecated in C++17, removed in C++20
167     : public iterator<output_iterator_tag, void, void, void, void> // until C++17
169 public:
170     typedef output_iterator_tag iterator_category;
171     typedef void                value_type;
172     typedef void                difference_type; // until C++20
173     typedef ptrdiff_t           difference_type; // since C++20
174     typedef void                pointer;
175     typedef void                reference;
177     explicit raw_storage_iterator(OutputIterator x);
178     raw_storage_iterator& operator*();
179     raw_storage_iterator& operator=(const T& element);
180     raw_storage_iterator& operator++();
181     raw_storage_iterator  operator++(int);
184 template <class T> pair<T*,ptrdiff_t> get_temporary_buffer(ptrdiff_t n) noexcept;
185 template <class T> void               return_temporary_buffer(T* p) noexcept;
187 template <class T> T* addressof(T& r) noexcept;
188 template <class T> T* addressof(const T&& r) noexcept = delete;
190 template <class InputIterator, class ForwardIterator>
191 ForwardIterator
192 uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator result);
194 namespace ranges {
196 template<class InputIterator, class OutputIterator>
197 using uninitialized_copy_result = in_out_result<InputIterator, OutputIterator>; // since C++20
199 template<input_iterator InputIterator, sentinel-for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel2>
200   requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>>
201 uninitialized_copy_result<InputIterator, OutputIterator>
202 uninitialized_copy(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20
204 template<input_range InputRange, nothrow-forward-range OutputRange>
205   requires constructible_from<range_value_t<OutputRange>, range_reference_t<InputRange>>
206 uninitialized_copy_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>>
207 uninitialized_copy(InputRange&& in_range, OutputRange&& out_range); // since C++20
211 template <class InputIterator, class Size, class ForwardIterator>
212 ForwardIterator
213 uninitialized_copy_n(InputIterator first, Size n, ForwardIterator result);
215 namespace ranges {
217 template<class InputIterator, class OutputIterator>
218 using uninitialized_copy_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20
220 template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel>
221   requires constructible_from<iter_value_t<OutputIterator>, iter_reference_t<InputIterator>>
222 uninitialized_copy_n_result<InputIterator, OutputIterator>
223 uninitialized_copy_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20
227 template <class ForwardIterator, class T>
228 void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& x);
230 namespace ranges {
232 template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel, class T>
233   requires constructible_from<iter_value_t<ForwardIterator>, const T&>
234 ForwardIterator uninitialized_fill(ForwardIterator first, Sentinel last, const T& x); // since C++20
236 template <nothrow-forward-range ForwardRange, class T>
237   requires constructible_from<range_value_t<ForwardRange>, const T&>
238 borrowed_iterator_t<ForwardRange> uninitialized_fill(ForwardRange&& range, const T& x); // since C++20
242 template <class ForwardIterator, class Size, class T>
243 ForwardIterator
244 uninitialized_fill_n(ForwardIterator first, Size n, const T& x);
246 namespace ranges {
248 template <nothrow-forward-iterator ForwardIterator, class T>
249   requires constructible_from<iter_value_t<ForwardIterator>, const T&>
250 ForwardIterator uninitialized_fill_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
254 template <class T, class ...Args>
255 constexpr T* construct_at(T* location, Args&& ...args); // since C++20
257 namespace ranges {
258   template<class T, class... Args>
259     constexpr T* construct_at(T* location, Args&&... args); // since C++20
262 template <class T>
263 void destroy_at(T* location); // constexpr in C++20
265 namespace ranges {
266   template<destructible T>
267     constexpr void destroy_at(T* location) noexcept; // since C++20
270 template <class ForwardIterator>
271 void destroy(ForwardIterator first, ForwardIterator last); // constexpr in C++20
273 namespace ranges {
274   template<nothrow-input-iterator InputIterator, nothrow-sentinel-for<InputIterator> Sentinel>
275     requires destructible<iter_value_t<InputIterator>>
276     constexpr InputIterator destroy(InputIterator first, Sentinel last) noexcept; // since C++20
277   template<nothrow-input-range InputRange>
278     requires destructible<range_value_t<InputRange>>
279     constexpr borrowed_iterator_t<InputRange> destroy(InputRange&& range) noexcept; // since C++20
282 template <class ForwardIterator, class Size>
283 ForwardIterator destroy_n(ForwardIterator first, Size n); // constexpr in C++20
285 namespace ranges {
286   template<nothrow-input-iterator InputIterator>
287     requires destructible<iter_value_t<InputIterator>>
288     constexpr InputIterator destroy_n(InputIterator first, iter_difference_t<InputIterator> n) noexcept; // since C++20
291 template <class InputIterator, class ForwardIterator>
292  ForwardIterator uninitialized_move(InputIterator first, InputIterator last, ForwardIterator result);
294 namespace ranges {
296 template<class InputIterator, class OutputIterator>
297 using uninitialized_move_result = in_out_result<InputIterator, OutputIterator>; // since C++20
299 template <input_iterator InputIterator, sentinel_for<InputIterator> Sentinel1, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<O> Sentinel2>
300   requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>>
301 uninitialized_move_result<InputIterator, OutputIterator>
302 uninitialized_move(InputIterator ifirst, Sentinel1 ilast, OutputIterator ofirst, Sentinel2 olast); // since C++20
304 template<input_range InputRange, nothrow-forward-range OutputRange>
305   requires constructible_from<range_value_t<OutputRange>, range_rvalue_reference_t<InputRange>>
306 uninitialized_move_result<borrowed_iterator_t<InputRange>, borrowed_iterator_t<OutputRange>>
307 uninitialized_move(InputRange&& in_range, OutputRange&& out_range); // since C++20
311 template <class InputIterator, class Size, class ForwardIterator>
312  pair<InputIterator,ForwardIterator> uninitialized_move_n(InputIterator first, Size n, ForwardIterator result);
314 namespace ranges {
316 template<class InputIterator, class OutputIterator>
317 using uninitialized_move_n_result = in_out_result<InputIterator, OutputIterator>; // since C++20
319 template<input_iterator InputIterator, nothrow-forward-iterator OutputIterator, nothrow-sentinel-for<OutputIterator> Sentinel>
320   requires constructible_from<iter_value_t<OutputIterator>, iter_rvalue_reference_t<InputIterator>>
321 uninitialized_move_n_result<InputIterator, OutputIterator>
322 uninitialized_move_n(InputIterator ifirst, iter_difference_t<InputIterator> n, OutputIterator ofirst, Sentinel olast); // since C++20
326 template <class ForwardIterator>
327  void uninitialized_value_construct(ForwardIterator first, ForwardIterator last);
329 namespace ranges {
331 template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel>
332   requires default_initializable<iter_value_t<ForwardIterator>>
333  ForwardIterator uninitialized_value_construct(ForwardIterator first, Sentinel last); // since C++20
335 template <nothrow-forward-range ForwardRange>
336   requires default_initializable<range_value_t<ForwardRange>>
337  borrowed_iterator_t<ForwardRange> uninitialized_value_construct(ForwardRange&& r); // since C++20
341 template <class ForwardIterator, class Size>
342  ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size n);
344 namespace ranges {
346 template <nothrow-forward-iterator ForwardIterator>
347   requires default_initializable<iter_value_t<ForwardIterator>>
348  ForwardIterator uninitialized_value_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
352 template <class ForwardIterator>
353  void uninitialized_default_construct(ForwardIterator first, ForwardIterator last);
355 namespace ranges {
357 template <nothrow-forward-iterator ForwardIterator, nothrow-sentinel-for<ForwardIterator> Sentinel>
358   requires default_initializable<iter_value_t<ForwardIterator>>
359  ForwardIterator uninitialized_default_construct(ForwardIterator first, Sentinel last); // since C++20
361 template <nothrow-forward-range ForwardRange>
362   requires default_initializable<range_value_t<ForwardRange>>
363  borrowed_iterator_t<ForwardRange> uninitialized_default_construct(ForwardRange&& r); // since C++20
367 template <class ForwardIterator, class Size>
368  ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size n);
370 namespace ranges {
372 template <nothrow-forward-iterator ForwardIterator>
373   requires default_initializable<iter_value_t<ForwardIterator>>
374  ForwardIterator uninitialized_default_construct_n(ForwardIterator first, iter_difference_t<ForwardIterator> n); // since C++20
378 template <class Y> struct auto_ptr_ref {};      // deprecated in C++11, removed in C++17
380 template<class X>
381 class auto_ptr                                  // deprecated in C++11, removed in C++17
383 public:
384     typedef X element_type;
386     explicit auto_ptr(X* p =0) throw();
387     auto_ptr(auto_ptr&) throw();
388     template<class Y> auto_ptr(auto_ptr<Y>&) throw();
389     auto_ptr& operator=(auto_ptr&) throw();
390     template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
391     auto_ptr& operator=(auto_ptr_ref<X> r) throw();
392     ~auto_ptr() throw();
394     typename add_lvalue_reference<X>::type operator*() const throw();
395     X* operator->() const throw();
396     X* get() const throw();
397     X* release() throw();
398     void reset(X* p =0) throw();
400     auto_ptr(auto_ptr_ref<X>) throw();
401     template<class Y> operator auto_ptr_ref<Y>() throw();
402     template<class Y> operator auto_ptr<Y>() throw();
405 template <class T>
406 struct default_delete
408     constexpr default_delete() noexcept = default;
409     template <class U> constexpr default_delete(const default_delete<U>&) noexcept; // constexpr since C++23
411     constexpr void operator()(T*) const noexcept;                                   // constexpr since C++23
414 template <class T>
415 struct default_delete<T[]>
417     constexpr default_delete() noexcept = default;
418     template <class U> constexpr default_delete(const default_delete <U[]>&) noexcept; // constexpr since C++23
419     constexpr void operator()(T*) const noexcept;                                      // constexpr since C++23
420     template <class U> void operator()(U*) const = delete;
423 template <class T, class D = default_delete<T>>
424 class unique_ptr
426 public:
427     typedef see below pointer;
428     typedef T element_type;
429     typedef D deleter_type;
431     // constructors
432     constexpr unique_ptr() noexcept;
433     constexpr explicit unique_ptr(pointer p) noexcept;           // constexpr since C++23
434     constexpr unique_ptr(pointer p, see below d1) noexcept;      // constexpr since C++23
435     constexpr unique_ptr(pointer p, see below d2) noexcept;      // constexpr since C++23
436     constexpr unique_ptr(unique_ptr&& u) noexcept;               // constexpr since C++23
437     constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
438     template <class U, class E>
439         constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept;     // constexpr since C++23
440     template <class U>
441         unique_ptr(auto_ptr<U>&& u) noexcept;                    // removed in C++17
443     // destructor
444     constexpr ~unique_ptr();                                     // constexpr since C++23
446     // assignment
447     constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;                         // constexpr since C++23
448     template <class U, class E>
449     constexpr unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept;                   // constexpr since C++23
450     constexpr unique_ptr& operator=(nullptr_t) noexcept;                              // constexpr since C++23
452     // observers
453     typename constexpr add_lvalue_reference<T>::type operator*() const;               // constexpr since C++23
454     constexpr pointer operator->() const noexcept;                                    // constexpr since C++23
455     constexpr pointer get() const noexcept;                                           // constexpr since C++23
456     constexpr deleter_type& get_deleter() noexcept;                                   // constexpr since C++23
457     constexpr const deleter_type& get_deleter() const noexcept;                       // constexpr since C++23
458     constexpr explicit operator bool() const noexcept;                                // constexpr since C++23
460     // modifiers
461     constexpr pointer release() noexcept;                                             // constexpr since C++23
462     constexpr void reset(pointer p = pointer()) noexcept;                             // constexpr since C++23
463     constexpr void swap(unique_ptr& u) noexcept;                                      // constexpr since C++23
466 template <class T, class D>
467 class unique_ptr<T[], D>
469 public:
470     typedef implementation-defined pointer;
471     typedef T element_type;
472     typedef D deleter_type;
474     // constructors
475     constexpr unique_ptr() noexcept;
476     constexpr explicit unique_ptr(pointer p) noexcept;          // constexpr since C++23
477     constexpr unique_ptr(pointer p, see below d) noexcept;      // constexpr since C++23
478     constexpr unique_ptr(pointer p, see below d) noexcept;      // constexpr since C++23
479     constexpr unique_ptr(unique_ptr&& u) noexcept;              // constexpr since C++23
480     template <class U, class E>
481     constexpr unique_ptr(unique_ptr <U, E>&& u) noexcept;       // constexpr since C++23
482     constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
484     // destructor
485     constexpr ~unique_ptr();                                    // constexpr since C++23
487     // assignment
488     constexpr unique_ptr& operator=(unique_ptr&& u) noexcept;        // constexpr since C++23
489     template <class U, class E>
490     constexpr unique_ptr& operator=(unique_ptr <U, E>&& u) noexcept; // constexpr since C++23
491     constexpr unique_ptr& operator=(nullptr_t) noexcept;             // constexpr since C++23
493     // observers
494     constexpr T& operator[](size_t i) const;                    // constexpr since C++23
495     constexpr pointer get() const noexcept;                     // constexpr since C++23
496     constexpr deleter_type& get_deleter() noexcept;             // constexpr since C++23
497     constexpr const deleter_type& get_deleter() const noexcept; // constexpr since C++23
498     constexpr explicit operator bool() const noexcept;          // constexpr since C++23
500     // modifiers
501     constexpr pointer release() noexcept;                       // constexpr since C++23
502     constexpr void reset(pointer p = pointer()) noexcept;       // constexpr since C++23
503     constexpr void reset(nullptr_t) noexcept;                   // constexpr since C++23
504   template <class U> void reset(U) = delete;
505     constexpr void swap(unique_ptr& u) noexcept;                // constexpr since C++23
508 template <class T, class D>
509     constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept;                 // constexpr since C++23
511 template <class T1, class D1, class T2, class D2>
512     constexpr bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);    // constexpr since C++23
513 template <class T1, class D1, class T2, class D2>
514     bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);              // removed in C++20
515 template <class T1, class D1, class T2, class D2>
516     bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
517 template <class T1, class D1, class T2, class D2>
518     bool operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
519 template <class T1, class D1, class T2, class D2>
520     bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
521 template <class T1, class D1, class T2, class D2>
522     bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
523 template<class T1, class D1, class T2, class D2>
524   requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
525                                      typename unique_ptr<T2, D2>::pointer>
526   compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
527                              typename unique_ptr<T2, D2>::pointer>
528     operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);      // C++20
530 template <class T, class D>
531     constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;   // constexpr since C++23
532 template <class T, class D>
533     bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;             // removed in C++20
534 template <class T, class D>
535     bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;             // removed in C++20
536 template <class T, class D>
537     bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;             // removed in C++20
539 template <class T, class D>
540     constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t);     // constexpr since C++23
541 template <class T, class D>
542     constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y);     // constexpr since C++23
543 template <class T, class D>
544     constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t);    // constexpr since C++23
545 template <class T, class D>
546     constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y);    // constexpr since C++23
547 template <class T, class D>
548     constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t);     // constexpr since C++23
549 template <class T, class D>
550     constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y);     // constexpr since C++23
551 template <class T, class D>
552     constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t);    // constexpr since C++23
553 template <class T, class D>
554     constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y);    // constexpr since C++23
555 template<class T, class D>
556   requires three_way_comparable<typename unique_ptr<T, D>::pointer>
557   compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
558     constexpr operator<=>(const unique_ptr<T, D>& x, nullptr_t);        // C++20, constexpr since C++23
560 class bad_weak_ptr
561     : public std::exception
563     bad_weak_ptr() noexcept;
566 template<class T, class... Args>
567 constexpr unique_ptr<T> make_unique(Args&&... args);                            // C++14, constexpr since C++23
568 template<class T>
569 constexpr unique_ptr<T> make_unique(size_t n);                                  // C++14, constexpr since C++23
570 template<class T, class... Args> unspecified   make_unique(Args&&...) = delete; // C++14, T == U[N]
572 template<class T>
573   constexpr unique_ptr<T> make_unique_for_overwrite();                        // T is not array, C++20, constexpr since C++23
574 template<class T>
575   constexpr unique_ptr<T> make_unique_for_overwrite(size_t n);                // T is U[], C++20, constexpr since C++23
576 template<class T, class... Args>
577   unspecified make_unique_for_overwrite(Args&&...) = delete;                  // T is U[N], C++20
579 template<class E, class T, class Y, class D>
580     basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, unique_ptr<Y, D> const& p);
582 template<class T>
583 class shared_ptr
585 public:
586     typedef T element_type; // until C++17
587     typedef remove_extent_t<T> element_type; // since C++17
588     typedef weak_ptr<T> weak_type; // C++17
590     // constructors:
591     constexpr shared_ptr() noexcept;
592     template<class Y> explicit shared_ptr(Y* p);
593     template<class Y, class D> shared_ptr(Y* p, D d);
594     template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
595     template <class D> shared_ptr(nullptr_t p, D d);
596     template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
597     template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
598     shared_ptr(const shared_ptr& r) noexcept;
599     template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
600     shared_ptr(shared_ptr&& r) noexcept;
601     template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
602     template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
603     template<class Y> shared_ptr(auto_ptr<Y>&& r);          // removed in C++17
604     template <class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);
605     shared_ptr(nullptr_t) : shared_ptr() { }
607     // destructor:
608     ~shared_ptr();
610     // assignment:
611     shared_ptr& operator=(const shared_ptr& r) noexcept;
612     template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
613     shared_ptr& operator=(shared_ptr&& r) noexcept;
614     template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
615     template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
616     template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
618     // modifiers:
619     void swap(shared_ptr& r) noexcept;
620     void reset() noexcept;
621     template<class Y> void reset(Y* p);
622     template<class Y, class D> void reset(Y* p, D d);
623     template<class Y, class D, class A> void reset(Y* p, D d, A a);
625     // observers:
626     T* get() const noexcept;
627     T& operator*() const noexcept;
628     T* operator->() const noexcept;
629     long use_count() const noexcept;
630     bool unique() const noexcept;
631     explicit operator bool() const noexcept;
632     template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
633     template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
636 template<class T>
637 shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
638 template<class T, class D>
639 shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
641 // shared_ptr comparisons:
642 template<class T, class U>
643     bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;
644 template<class T, class U>
645     bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;               // removed in C++20
646 template<class T, class U>
647     bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;                // removed in C++20
648 template<class T, class U>
649     bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;                // removed in C++20
650 template<class T, class U>
651     bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;               // removed in C++20
652 template<class T, class U>
653     bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;               // removed in C++20
654 template<class T, class U>
655     strong_ordering operator<=>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept;   // C++20
657 template <class T>
658     bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept;
659 template <class T>
660     bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
661 template <class T>
662     bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept;               // removed in C++20
663 template <class T>
664     bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
665 template <class T>
666     bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept;                // removed in C++20
667 template <class T>
668     bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept;                // removed in C++20
669 template <class T>
670     bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept;               // removed in C++20
671 template <class T>
672     bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
673 template <class T>
674     bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept;                // removed in C++20
675 template <class T>
676     bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept;                // removed in C++20
677 template <class T>
678     bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept;               // removed in C++20
679 template <class T>
680     bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept;               // removed in C++20
681 template<class T>
682     strong_ordering operator<=>(shared_ptr<T> const& x, nullptr_t) noexcept;   // C++20
684 // shared_ptr specialized algorithms:
685 template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept;
687 // shared_ptr casts:
688 template<class T, class U>
689     shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r) noexcept;
690 template<class T, class U>
691     shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r) noexcept;
692 template<class T, class U>
693     shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r) noexcept;
695 // shared_ptr I/O:
696 template<class E, class T, class Y>
697     basic_ostream<E, T>& operator<< (basic_ostream<E, T>& os, shared_ptr<Y> const& p);
699 // shared_ptr get_deleter:
700 template<class D, class T> D* get_deleter(shared_ptr<T> const& p) noexcept;
702 template<class T, class... Args>
703     shared_ptr<T> make_shared(Args&&... args); // T is not an array
704 template<class T, class A, class... Args>
705     shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not an array
707 template<class T>
708     shared_ptr<T> make_shared(size_t N); // T is U[] (since C++20)
709 template<class T, class A>
710     shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[] (since C++20)
712 template<class T>
713     shared_ptr<T> make_shared(); // T is U[N] (since C++20)
714 template<class T, class A>
715     shared_ptr<T> allocate_shared(const A& a); // T is U[N] (since C++20)
717 template<class T>
718     shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
719 template<class T, class A>
720     shared_ptr<T> allocate_shared(const A& a, size_t N, const remove_extent_t<T>& u); // T is U[] (since C++20)
722 template<class T> shared_ptr<T>
723     make_shared(const remove_extent_t<T>& u); // T is U[N] (since C++20)
724 template<class T, class A>
725     shared_ptr<T> allocate_shared(const A& a, const remove_extent_t<T>& u); // T is U[N] (since C++20)
727 template<class T>
728   shared_ptr<T> make_shared_for_overwrite();                                  // T is not U[], C++20
729 template<class T, class A>
730   shared_ptr<T> allocate_shared_for_overwrite(const A& a);                    // T is not U[], C++20
732 template<class T>
733   shared_ptr<T> make_shared_for_overwrite(size_t N);                          // T is U[], C++20
734 template<class T, class A>
735   shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N);          // T is U[], C++20
737 template<class T>
738 class weak_ptr
740 public:
741     typedef T element_type; // until C++17
742     typedef remove_extent_t<T> element_type; // since C++17
744     // constructors
745     constexpr weak_ptr() noexcept;
746     template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
747     weak_ptr(weak_ptr const& r) noexcept;
748     template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
749     weak_ptr(weak_ptr&& r) noexcept;                      // C++14
750     template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept; // C++14
752     // destructor
753     ~weak_ptr();
755     // assignment
756     weak_ptr& operator=(weak_ptr const& r) noexcept;
757     template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
758     template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
759     weak_ptr& operator=(weak_ptr&& r) noexcept;                      // C++14
760     template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept; // C++14
762     // modifiers
763     void swap(weak_ptr& r) noexcept;
764     void reset() noexcept;
766     // observers
767     long use_count() const noexcept;
768     bool expired() const noexcept;
769     shared_ptr<T> lock() const noexcept;
770     template<class U> bool owner_before(shared_ptr<U> const& b) const noexcept;
771     template<class U> bool owner_before(weak_ptr<U> const& b) const noexcept;
774 template<class T>
775 weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
777 // weak_ptr specialized algorithms:
778 template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
780 // class owner_less:
781 template<class T> struct owner_less;
783 template<class T>
784 struct owner_less<shared_ptr<T> >
785     : binary_function<shared_ptr<T>, shared_ptr<T>, bool>
787     typedef bool result_type;
788     bool operator()(shared_ptr<T> const&, shared_ptr<T> const&) const noexcept;
789     bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
790     bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
793 template<class T>
794 struct owner_less<weak_ptr<T> >
795     : binary_function<weak_ptr<T>, weak_ptr<T>, bool>
797     typedef bool result_type;
798     bool operator()(weak_ptr<T> const&, weak_ptr<T> const&) const noexcept;
799     bool operator()(shared_ptr<T> const&, weak_ptr<T> const&) const noexcept;
800     bool operator()(weak_ptr<T> const&, shared_ptr<T> const&) const noexcept;
803 template <>  // Added in C++14
804 struct owner_less<void>
806     template <class _Tp, class _Up>
807     bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
808     template <class _Tp, class _Up>
809     bool operator()( shared_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
810     template <class _Tp, class _Up>
811     bool operator()(   weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const noexcept;
812     template <class _Tp, class _Up>
813     bool operator()(   weak_ptr<_Tp> const& __x,   weak_ptr<_Up> const& __y) const noexcept;
815     typedef void is_transparent;
818 template<class T>
819 class enable_shared_from_this
821 protected:
822     constexpr enable_shared_from_this() noexcept;
823     enable_shared_from_this(enable_shared_from_this const&) noexcept;
824     enable_shared_from_this& operator=(enable_shared_from_this const&) noexcept;
825     ~enable_shared_from_this();
826 public:
827     shared_ptr<T> shared_from_this();
828     shared_ptr<T const> shared_from_this() const;
831 template<class T>
832     bool atomic_is_lock_free(const shared_ptr<T>* p);
833 template<class T>
834     shared_ptr<T> atomic_load(const shared_ptr<T>* p);
835 template<class T>
836     shared_ptr<T> atomic_load_explicit(const shared_ptr<T>* p, memory_order mo);
837 template<class T>
838     void atomic_store(shared_ptr<T>* p, shared_ptr<T> r);
839 template<class T>
840     void atomic_store_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
841 template<class T>
842     shared_ptr<T> atomic_exchange(shared_ptr<T>* p, shared_ptr<T> r);
843 template<class T>
844     shared_ptr<T>
845     atomic_exchange_explicit(shared_ptr<T>* p, shared_ptr<T> r, memory_order mo);
846 template<class T>
847     bool
848     atomic_compare_exchange_weak(shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
849 template<class T>
850     bool
851     atomic_compare_exchange_strong( shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
852 template<class T>
853     bool
854     atomic_compare_exchange_weak_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
855                                           shared_ptr<T> w, memory_order success,
856                                           memory_order failure);
857 template<class T>
858     bool
859     atomic_compare_exchange_strong_explicit(shared_ptr<T>* p, shared_ptr<T>* v,
860                                             shared_ptr<T> w, memory_order success,
861                                             memory_order failure);
862 // Hash support
863 template <class T> struct hash;
864 template <class T, class D> struct hash<unique_ptr<T, D> >;
865 template <class T> struct hash<shared_ptr<T> >;
867 template <class T, class Alloc>
868   inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
870 // [allocator.uses.construction], uses-allocator construction
871 template<class T, class Alloc, class... Args>
872   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
873                                                   Args&&... args) noexcept;
874 template<class T, class Alloc, class Tuple1, class Tuple2>
875   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
876                                                   piecewise_construct_t,
877                                                   Tuple1&& x, Tuple2&& y) noexcept;
878 template<class T, class Alloc>
879   constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;   // since C++20
880 template<class T, class Alloc, class U, class V>
881   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
882                                                   U&& u, V&& v) noexcept;
883 template<class T, class Alloc, class U, class V>
884   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++23
885                                                   pair<U, V>& pr) noexcept;
886 template<class T, class Alloc, class U, class V>
887   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
888                                                   const pair<U, V>& pr) noexcept;
889 template<class T, class Alloc, class U, class V>
890   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
891                                                   pair<U, V>&& pr) noexcept;
892 template<class T, class Alloc, class U, class V>
893   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++23
894                                                   const pair<U, V>&& pr) noexcept;
895 template<class T, class Alloc, pair-like P>
896   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
897                                                   P&& p) noexcept;
898 template<class T, class Alloc, class U>
899   constexpr auto uses_allocator_construction_args(const Alloc& alloc,             // since C++20
900                                                   U&& u) noexcept;
901 template<class T, class Alloc, class... Args>
902   constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);       // since C++20
903 template<class T, class Alloc, class... Args>
904   constexpr T* uninitialized_construct_using_allocator(T* p,                      // since C++20
905                                                          const Alloc& alloc, Args&&... args);
907 // [ptr.align]
908 void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
910 template<size_t N, class T>
911 [[nodiscard]] constexpr T* assume_aligned(T* ptr); // since C++20
913 }  // std
917 #include <__assert> // all public C++ headers provide the assertion handler
918 #include <__config>
919 #include <__memory/addressof.h>
920 #include <__memory/align.h>
921 #include <__memory/allocate_at_least.h>
922 #include <__memory/allocation_guard.h>
923 #include <__memory/allocator.h>
924 #include <__memory/allocator_arg_t.h>
925 #include <__memory/allocator_traits.h>
926 #include <__memory/assume_aligned.h>
927 #include <__memory/auto_ptr.h>
928 #include <__memory/compressed_pair.h>
929 #include <__memory/concepts.h>
930 #include <__memory/construct_at.h>
931 #include <__memory/pointer_traits.h>
932 #include <__memory/ranges_construct_at.h>
933 #include <__memory/ranges_uninitialized_algorithms.h>
934 #include <__memory/raw_storage_iterator.h>
935 #include <__memory/shared_ptr.h>
936 #include <__memory/temporary_buffer.h>
937 #include <__memory/uninitialized_algorithms.h>
938 #include <__memory/unique_ptr.h>
939 #include <__memory/uses_allocator.h>
940 #include <__memory/uses_allocator_construction.h>
941 #include <version>
943 // standard-mandated includes
945 // [memory.syn]
946 #include <compare>
948 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
949 #  pragma GCC system_header
950 #endif
952 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
953 #  include <atomic>
954 #  include <concepts>
955 #  include <cstddef>
956 #  include <cstdint>
957 #  include <cstdlib>
958 #  include <cstring>
959 #  include <iosfwd>
960 #  include <iterator>
961 #  include <new>
962 #  include <stdexcept>
963 #  include <tuple>
964 #  include <type_traits>
965 #  include <typeinfo>
966 #  include <utility>
967 #endif
969 #endif // _LIBCPP_MEMORY