1595 lines
114 KiB
Markdown
1595 lines
114 KiB
Markdown
[memory]
|
||
|
||
# 20 Memory management library [[mem]](./#mem)
|
||
|
||
## 20.2 Memory [memory]
|
||
|
||
### [20.2.1](#general) General [[memory.general]](memory.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L26)
|
||
|
||
Subclause [memory] describes the contents of the header[<memory>](#header:%3cmemory%3e "20.2.2 Header <memory> synopsis [memory.syn]") and some
|
||
of the contents of the header [<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2 Header <cstdlib> synopsis [cstdlib.syn]")[.](#general-1.sentence-1)
|
||
|
||
### [20.2.2](#syn) Header <memory> synopsis [[memory.syn]](memory.syn)
|
||
|
||
[1](#syn-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L33)
|
||
|
||
The header <memory> defines several types and function templates that
|
||
describe properties of pointers and pointer-like types, manage memory
|
||
for containers and other template types, destroy objects, and
|
||
construct objects in
|
||
uninitialized memory
|
||
buffers ([[pointer.traits]](#pointer.traits "20.2.3 Pointer traits")â[[specialized.addressof]](#specialized.addressof "20.2.11 addressof") and [[specialized.algorithms]](specialized.algorithms "26.11 Specialized <memory> algorithms"))[.](#syn-1.sentence-1)
|
||
|
||
The header also defines the templatesunique_ptr, shared_ptr, weak_ptr,out_ptr_t, inout_ptr_t, and various function
|
||
templates that operate on objects of these types ([[smartptr]](smartptr "20.3 Smart pointers"))[.](#syn-1.sentence-2)
|
||
|
||
[2](#syn-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L45)
|
||
|
||
Let *POINTER_OF*(T) denote a type that is
|
||
|
||
- [(2.1)](#syn-2.1)
|
||
|
||
T::pointer if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") T::pointer is valid and denotes a type,
|
||
|
||
- [(2.2)](#syn-2.2)
|
||
|
||
otherwise, T::element_type* if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") T::element_type is valid and denotes a type,
|
||
|
||
- [(2.3)](#syn-2.3)
|
||
|
||
otherwise, pointer_traits<T>::element_type*[.](#syn-2.sentence-1)
|
||
|
||
[3](#syn-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L59)
|
||
|
||
Let *POINTER_OF_OR*(T, U) denote a type that is:
|
||
|
||
- [(3.1)](#syn-3.1)
|
||
|
||
*POINTER_OF*(T) if *POINTER_OF*(T) is valid and denotes a type,
|
||
|
||
- [(3.2)](#syn-3.2)
|
||
|
||
otherwise, U[.](#syn-3.sentence-1)
|
||
|
||
#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")namespace std {// [[pointer.traits]](#pointer.traits "20.2.3 Pointer traits"), pointer traitstemplate<class Ptr> struct pointer_traits; // freestandingtemplate<class T> struct pointer_traits<T*>; // freestanding// [[pointer.conversion]](#pointer.conversion "20.2.4 Pointer conversion"), pointer conversiontemplate<class T>constexpr T* to_address(T* p) noexcept; // freestandingtemplate<class Ptr>constexpr auto to_address(const Ptr& p) noexcept; // freestanding// [[ptr.align]](#ptr.align "20.2.5 Pointer alignment"), pointer alignmentvoid* align(size_t alignment, size_t size, void*& ptr, size_t& space); // freestandingtemplate<size_t N, class T>constexpr T* assume_aligned(T* ptr); // freestandingtemplate<size_t Alignment, class T>bool is_sufficiently_aligned(T* ptr); // [[obj.lifetime]](#obj.lifetime "20.2.6 Explicit lifetime management"), explicit lifetime managementtemplate<class T> T* start_lifetime_as(void* p) noexcept; // freestandingtemplate<class T>const T* start_lifetime_as(const void* p) noexcept; // freestandingtemplate<class T>volatile T* start_lifetime_as(volatile void* p) noexcept; // freestandingtemplate<class T>const volatile T* start_lifetime_as(const volatile void* p) noexcept; // freestandingtemplate<class T> T* start_lifetime_as_array(void* p, size_t n) noexcept; // freestandingtemplate<class T>const T* start_lifetime_as_array(const void* p, size_t n) noexcept; // freestandingtemplate<class T>volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept; // freestandingtemplate<class T>const volatile T* start_lifetime_as_array(const volatile void* p, // freestanding size_t n) noexcept; template<class T> T* trivially_relocate(T* first, T* last, T* result); // freestandingtemplate<class T>constexpr T* relocate(T* first, T* last, T* result); // freestanding// [[allocator.tag]](#allocator.tag "20.2.7 Allocator argument tag"), allocator argument tagstruct allocator_arg_t { explicit allocator_arg_t() = default; }; // freestandinginline constexpr allocator_arg_t allocator_arg{}; // freestanding// [[allocator.uses]](#allocator.uses "20.2.8 uses_allocator"), uses_allocatortemplate<class T, class Alloc> struct uses_allocator; // freestanding// [[allocator.uses.trait]](#allocator.uses.trait "20.2.8.1 uses_allocator trait"), uses_allocatortemplate<class T, class Alloc>constexpr bool [uses_allocator_v](#lib:uses_allocator_v "20.2.2 Header <memory> synopsis [memory.syn]") = uses_allocator<T, Alloc>::value; // freestanding// [[allocator.uses.construction]](#allocator.uses.construction "20.2.8.2 Uses-allocator construction"), uses-allocator constructiontemplate<class T, class Alloc, class... Args>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding Args&&... args) noexcept; template<class T, class Alloc, class Tuple1, class Tuple2>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding piecewise_construct_t,
|
||
Tuple1&& x, Tuple2&& y) noexcept; template<class T, class Alloc>constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept; // freestandingtemplate<class T, class Alloc, class U, class V>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding U&& u, V&& v) noexcept; template<class T, class Alloc, class U, class V>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding pair<U, V>& pr) noexcept; template<class T, class Alloc, class U, class V>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestandingconst pair<U, V>& pr) noexcept; template<class T, class Alloc, class U, class V>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding pair<U, V>&& pr) noexcept; template<class T, class Alloc, class U, class V>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestandingconst pair<U, V>&& pr) noexcept; template<class T, class Alloc, [*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding P&& p) noexcept; template<class T, class Alloc, class U>constexpr auto uses_allocator_construction_args(const Alloc& alloc, // freestanding U&& u) noexcept; template<class T, class Alloc, class... Args>constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args); // freestandingtemplate<class T, class Alloc, class... Args>constexpr T* uninitialized_construct_using_allocator(T* p, // freestandingconst Alloc& alloc, Args&&... args); // [[allocator.traits]](#allocator.traits "20.2.9 Allocator traits"), allocator traitstemplate<class Alloc> struct allocator_traits; // freestandingtemplate<class Pointer, class SizeType = size_t>struct allocation_result { // freestanding Pointer ptr;
|
||
SizeType count; }; // [[default.allocator]](#default.allocator "20.2.10 The default allocator"), the default allocatortemplate<class T> class allocator; template<class T, class U>constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept; // [[specialized.addressof]](#specialized.addressof "20.2.11 addressof"), addressoftemplate<class T>constexpr T* addressof(T& r) noexcept; // freestandingtemplate<class T>const T* addressof(const T&&) = delete; // freestanding// [[specialized.algorithms]](specialized.algorithms "26.11 Specialized <memory> algorithms"), specialized algorithms// [[special.mem.concepts]](special.mem.concepts "26.11.2 Special memory concepts"), special memory conceptstemplate<class I>concept [*nothrow-input-iterator*](special.mem.concepts#concept:nothrow-input-iterator "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class I>concept [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class I>concept [*nothrow-bidirectional-iterator*](special.mem.concepts#concept:nothrow-bidirectional-iterator "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class I>concept [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class S, class I>concept [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class S, class I>concept [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class R>concept [*nothrow-input-range*](special.mem.concepts#concept:nothrow-input-range "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class R>concept [*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class R>concept [*nothrow-bidirectional-range*](special.mem.concepts#concept:nothrow-bidirectional-range "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class R>concept [*nothrow-random-access-range*](special.mem.concepts#concept:nothrow-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class R>concept [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") = *see below*; // *exposition only*template<class NoThrowForwardIterator>constexpr void uninitialized_default_construct(NoThrowForwardIterator first, // freestanding NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator>void uninitialized_default_construct(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size>constexpr NoThrowForwardIterator
|
||
uninitialized_default_construct_n(NoThrowForwardIterator first, Size n); // freestandingtemplate<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator
|
||
uninitialized_default_construct_n(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") Size n); namespace ranges {template<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>>constexpr I uninitialized_default_construct(I first, S last); // freestandingtemplate<[*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2 Special memory concepts [special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<range_value_t<R>>constexpr borrowed_iterator_t<R> uninitialized_default_construct(R&& r); // freestandingtemplate<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>>constexpr I uninitialized_default_construct_n(I first, // freestanding iter_difference_t<I> n); template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>> I uninitialized_default_construct(Ep&& exec, I first, S last); // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<range_value_t<R>> borrowed_iterator_t<R> uninitialized_default_construct(Ep&& exec, // freestanding-deleted, R&& r); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>> I uninitialized_default_construct_n(Ep&& exec, I first, // freestanding-deleted, iter_difference_t<I> n); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")}template<class NoThrowForwardIterator>constexpr void uninitialized_value_construct(NoThrowForwardIterator first, // freestanding NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator>void uninitialized_value_construct(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size>constexpr NoThrowForwardIterator
|
||
uninitialized_value_construct_n(NoThrowForwardIterator first, Size n); // freestandingtemplate<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator
|
||
uninitialized_value_construct_n(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") Size n); namespace ranges {template<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>>constexpr I uninitialized_value_construct(I first, S last); // freestandingtemplate<[*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2 Special memory concepts [special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<range_value_t<R>>constexpr borrowed_iterator_t<R> uninitialized_value_construct(R&& r); // freestandingtemplate<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>>constexpr I uninitialized_value_construct_n(I first, // freestanding iter_difference_t<I> n); template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>> I uninitialized_value_construct(Ep&& exec, I first, S last); // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<range_value_t<R>> borrowed_iterator_t<R> uninitialized_value_construct(Ep&& exec, // freestanding-deleted, R&& r); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<iter_value_t<I>> I uninitialized_value_construct_n(Ep&& exec, I first, // freestanding-deleted, iter_difference_t<I> n); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")}template<class InputIterator, class NoThrowForwardIterator>constexpr NoThrowForwardIterator uninitialized_copy(InputIterator first, // freestanding InputIterator last,
|
||
NoThrowForwardIterator result); template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy(ExecutionPolicy&& exec, // freestanding-deleted, ForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") ForwardIterator last,
|
||
NoThrowForwardIterator result); template<class InputIterator, class Size, class NoThrowForwardIterator>constexpr NoThrowForwardIterator uninitialized_copy_n(InputIterator first, // freestanding Size n,
|
||
NoThrowForwardIterator result); template<class ExecutionPolicy, class ForwardIterator, class Size, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_copy_n(ExecutionPolicy&& exec, // freestanding-deleted, ForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") Size n,
|
||
NoThrowForwardIterator result); namespace ranges {template<class I, class O>using [uninitialized_copy_result](#lib:uninitialized_copy_result "20.2.2 Header <memory> synopsis [memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S1, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_reference_t<I>>constexpr uninitialized_copy_result<I, O> uninitialized_copy(I ifirst, S1 ilast, O ofirst, S2 olast); // freestandingtemplate<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") IR, [*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2 Special memory concepts [special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<range_value_t<OR>, range_reference_t<IR>>constexpr uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>> uninitialized_copy(IR&& in_range, OR&& out_range); // freestandingtemplate<class I, class O>using [uninitialized_copy_n_result](#lib:uninitialized_copy_n_result "20.2.2 Header <memory> synopsis [memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]") I, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_reference_t<I>>constexpr uninitialized_copy_n_result<I, O> uninitialized_copy_n(I ifirst, iter_difference_t<I> n, // freestanding O ofirst, S olast); template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I> S1, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_reference_t<I>> uninitialized_copy_result<I, O> uninitialized_copy(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted, O ofirst, S2 olast); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*sized-random-access-range*](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") IR, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<range_value_t<OR>, range_reference_t<IR>> uninitialized_copy_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>> uninitialized_copy(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") I, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_reference_t<I>> uninitialized_copy_n_result<I, O> uninitialized_copy_n(Ep&& exec, I ifirst, iter_difference_t<I> n, // freestanding-deleted, O ofirst, S olast); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")}template<class InputIterator, class NoThrowForwardIterator>constexpr NoThrowForwardIterator uninitialized_move(InputIterator first, // freestanding InputIterator last,
|
||
NoThrowForwardIterator result); template<class ExecutionPolicy, class ForwardIterator, class NoThrowForwardIterator> NoThrowForwardIterator uninitialized_move(ExecutionPolicy&& exec, // freestanding-deleted, ForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") ForwardIterator last,
|
||
NoThrowForwardIterator result); template<class InputIterator, class Size, class NoThrowForwardIterator>constexpr pair<InputIterator, NoThrowForwardIterator> uninitialized_move_n(InputIterator first, Size n, // freestanding NoThrowForwardIterator result); template<class ExecutionPolicy, class ForwardIterator, class Size, class NoThrowForwardIterator> pair<ForwardIterator, NoThrowForwardIterator> uninitialized_move_n(ExecutionPolicy&& exec, // freestanding-deleted, ForwardIterator first, Size n, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") NoThrowForwardIterator result); namespace ranges {template<class I, class O>using [uninitialized_move_result](#lib:uninitialized_move_result "20.2.2 Header <memory> synopsis [memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S1, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_rvalue_reference_t<I>>constexpr uninitialized_move_result<I, O> uninitialized_move(I ifirst, S1 ilast, O ofirst, S2 olast); // freestandingtemplate<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]") IR, [*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2 Special memory concepts [special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<range_value_t<OR>, range_rvalue_reference_t<IR>>constexpr uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>> uninitialized_move(IR&& in_range, OR&& out_range); // freestandingtemplate<class I, class O>using [uninitialized_move_n_result](#lib:uninitialized_move_n_result "20.2.2 Header <memory> synopsis [memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]") I, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_rvalue_reference_t<I>>constexpr uninitialized_move_n_result<I, O> uninitialized_move_n(I ifirst, iter_difference_t<I> n, // freestanding O ofirst, S olast); template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I> S1, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_rvalue_reference_t<I>> uninitialized_move_result<I, O> uninitialized_move(Ep&& exec, I ifirst, S1 ilast, // freestanding-deleted, O ofirst, S2 olast); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*sized-random-access-range*](range.refinements#concept:sized-random-access-range "25.4.6 Other range refinements [range.refinements]") IR, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<range_value_t<OR>, range_rvalue_reference_t<IR>> uninitialized_move_result<borrowed_iterator_t<IR>, borrowed_iterator_t<OR>> uninitialized_move(Ep&& exec, IR&& in_range, OR&& out_range); // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13 Concept random_access_iterator [iterator.concept.random.access]") I, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<O>, iter_rvalue_reference_t<I>> uninitialized_move_n_result<I, O> uninitialized_move_n(Ep&& exec, I ifirst, iter_difference_t<I> n, // freestanding-deleted, O ofirst, S olast); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")}template<class NoThrowForwardIterator, class T>constexpr void uninitialized_fill(NoThrowForwardIterator first, // freestanding NoThrowForwardIterator last, const T& x); template<class ExecutionPolicy, class NoThrowForwardIterator, class T>void uninitialized_fill(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") NoThrowForwardIterator last, const T& x); template<class NoThrowForwardIterator, class Size, class T>constexpr NoThrowForwardIterator
|
||
uninitialized_fill_n(NoThrowForwardIterator first, Size n, const T& x); // freestandingtemplate<class ExecutionPolicy, class NoThrowForwardIterator, class Size, class T> NoThrowForwardIterator
|
||
uninitialized_fill_n(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") Size n, const T& x); namespace ranges {template<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<I>, const T&>constexpr I uninitialized_fill(I first, S last, const T& x); // freestandingtemplate<[*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2 Special memory concepts [special.mem.concepts]") R, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<range_value_t<R>, const T&>constexpr borrowed_iterator_t<R> uninitialized_fill(R&& r, const T& x); // freestandingtemplate<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<I>, const T&>constexpr I uninitialized_fill_n(I first, // freestanding iter_difference_t<I> n, const T& x); template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<I>, const T&> I uninitialized_fill(Ep&& exec, I first, S last, const T& x); // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") R, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<range_value_t<R>, const T&> borrowed_iterator_t<R> uninitialized_fill(Ep&& exec, R&& r, // freestanding-deleted,const T& x); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<I>, const T&> I uninitialized_fill_n(Ep&& exec, I first, // freestanding-deleted, iter_difference_t<I> n, const T& x); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")}// [[specialized.construct]](specialized.construct "26.11.8 construct_at"), construct_attemplate<class T, class... Args>constexpr T* construct_at(T* location, Args&&... args); // freestandingnamespace ranges {template<class T, class... Args>constexpr T* construct_at(T* location, Args&&... args); // freestanding}// [[specialized.destroy]](specialized.destroy "26.11.9 destroy"), destroytemplate<class T>constexpr void destroy_at(T* location); // freestandingtemplate<class NoThrowForwardIterator>constexpr void destroy(NoThrowForwardIterator first, // freestanding NoThrowForwardIterator last); template<class ExecutionPolicy, class NoThrowForwardIterator>void destroy(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads") NoThrowForwardIterator last); template<class NoThrowForwardIterator, class Size>constexpr NoThrowForwardIterator destroy_n(NoThrowForwardIterator first, // freestanding Size n); template<class ExecutionPolicy, class NoThrowForwardIterator, class Size> NoThrowForwardIterator destroy_n(ExecutionPolicy&& exec, // freestanding-deleted, NoThrowForwardIterator first, Size n); // see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")namespace ranges {template<[destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]") T>constexpr void destroy_at(T* location) noexcept; // freestandingtemplate<[*nothrow-input-iterator*](special.mem.concepts#concept:nothrow-input-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S>requires [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")<iter_value_t<I>>constexpr I destroy(I first, S last) noexcept; // freestandingtemplate<[*nothrow-input-range*](special.mem.concepts#concept:nothrow-input-range "26.11.2 Special memory concepts [special.mem.concepts]") R>requires [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")<range_value_t<R>>constexpr borrowed_iterator_t<R> destroy(R&& r) noexcept; // freestandingtemplate<[*nothrow-input-iterator*](special.mem.concepts#concept:nothrow-input-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I>requires [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")<iter_value_t<I>>constexpr I destroy_n(I first, iter_difference_t<I> n) noexcept; // freestandingtemplate<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2 Special memory concepts [special.mem.concepts]")<I> S>requires [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")<iter_value_t<I>> I destroy(Ep&& exec, I first, S last) noexcept; // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2 Special memory concepts [special.mem.concepts]") R>requires [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")<range_value_t<R>> borrowed_iterator_t<R> destroy(Ep&& exec, R&& r) noexcept; // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1 Preamble [algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2 Special memory concepts [special.mem.concepts]") I>requires [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")<iter_value_t<I>> I destroy_n(Ep&& exec, I first, iter_difference_t<I> n) noexcept; // freestanding-deleted,// see [[algorithms.parallel.overloads]](algorithms.parallel.overloads "26.3.5 Parallel algorithm overloads")}// [[unique.ptr]](unique.ptr "20.3.1 Unique-ownership pointers"), class template unique_ptrtemplate<class T> struct default_delete; // freestandingtemplate<class T> struct default_delete<T[]>; // freestandingtemplate<class T, class D = default_delete<T>> class unique_ptr; // freestandingtemplate<class T, class D> class unique_ptr<T[], D>; // freestandingtemplate<class T, class... Args>constexpr unique_ptr<T> make_unique(Args&&... args); // T is not arraytemplate<class T>constexpr unique_ptr<T> make_unique(size_t n); // T is U[]template<class T, class... Args>*unspecified* make_unique(Args&&...) = delete; // T is U[N]template<class T>constexpr unique_ptr<T> make_unique_for_overwrite(); // T is not arraytemplate<class T>constexpr unique_ptr<T> make_unique_for_overwrite(size_t n); // T is U[]template<class T, class... Args>*unspecified* make_unique_for_overwrite(Args&&...) = delete; // T is U[N]template<class T, class D>constexpr void swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y) noexcept; // freestandingtemplate<class T1, class D1, class T2, class D2>constexpr bool operator==(const unique_ptr<T1, D1>& x, // freestandingconst unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2>constexpr bool operator<(const unique_ptr<T1, D1>& x, // freestandingconst unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2>constexpr bool operator>(const unique_ptr<T1, D1>& x, // freestandingconst unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2>constexpr bool operator<=(const unique_ptr<T1, D1>& x, // freestandingconst unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2>constexpr bool operator>=(const unique_ptr<T1, D1>& x, // freestandingconst unique_ptr<T2, D2>& y); template<class T1, class D1, class T2, class D2>requires [three_way_comparable_with](cmp.concept#concept:three_way_comparable_with "17.12.4 Concept three_way_comparable [cmp.concept]")<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer>constexpr compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer, typename unique_ptr<T2, D2>::pointer>operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y); // freestandingtemplate<class T, class D>constexpr bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept; // freestandingtemplate<class T, class D>constexpr bool operator<(const unique_ptr<T, D>& x, nullptr_t); // freestandingtemplate<class T, class D>constexpr bool operator<(nullptr_t, const unique_ptr<T, D>& y); // freestandingtemplate<class T, class D>constexpr bool operator>(const unique_ptr<T, D>& x, nullptr_t); // freestandingtemplate<class T, class D>constexpr bool operator>(nullptr_t, const unique_ptr<T, D>& y); // freestandingtemplate<class T, class D>constexpr bool operator<=(const unique_ptr<T, D>& x, nullptr_t); // freestandingtemplate<class T, class D>constexpr bool operator<=(nullptr_t, const unique_ptr<T, D>& y); // freestandingtemplate<class T, class D>constexpr bool operator>=(const unique_ptr<T, D>& x, nullptr_t); // freestandingtemplate<class T, class D>constexpr bool operator>=(nullptr_t, const unique_ptr<T, D>& y); // freestandingtemplate<class T, class D>requires [three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_way_comparable [cmp.concept]")<typename unique_ptr<T, D>::pointer>constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>operator<=>(const unique_ptr<T, D>& x, nullptr_t); // freestandingtemplate<class E, class T, class Y, class D> basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const unique_ptr<Y, D>& p); // [[util.smartptr.weak.bad]](util.smartptr.weak.bad "20.3.2.1 Class bad_weak_ptr"), class bad_weak_ptrclass bad_weak_ptr; // [[util.smartptr.shared]](util.smartptr.shared "20.3.2.2 Class template shared_ptr"), class template shared_ptrtemplate<class T> class shared_ptr; // [[util.smartptr.shared.create]](util.smartptr.shared.create "20.3.2.2.7 Creation"), shared_ptr creationtemplate<class T, class... Args>constexpr shared_ptr<T> make_shared(Args&&... args); // T is not arraytemplate<class T, class A, class... Args>constexpr shared_ptr<T> allocate_shared(const A& a, Args&&... args); // T is not arraytemplate<class T>constexpr shared_ptr<T> make_shared(size_t N); // T is U[]template<class T, class A>constexpr shared_ptr<T> allocate_shared(const A& a, size_t N); // T is U[]template<class T>constexpr shared_ptr<T> make_shared(); // T is U[N]template<class T, class A>constexpr shared_ptr<T> allocate_shared(const A& a); // T is U[N]template<class T>constexpr shared_ptr<T> make_shared(size_t N, const remove_extent_t<T>& u); // T is U[]template<class T, class A>constexpr shared_ptr<T> allocate_shared(const A& a, size_t N, const remove_extent_t<T>& u); // T is U[]template<class T>constexpr shared_ptr<T> make_shared(const remove_extent_t<T>& u); // T is U[N]template<class T, class A>constexpr shared_ptr<T> allocate_shared(const A& a, // T is U[N]const remove_extent_t<T>& u); template<class T>constexpr shared_ptr<T> make_shared_for_overwrite(); // T is not U[]template<class T, class A>constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a); // T is not U[]template<class T>constexpr shared_ptr<T> make_shared_for_overwrite(size_t N); // T is U[]template<class T, class A>constexpr shared_ptr<T> allocate_shared_for_overwrite(const A& a, size_t N); // T is U[]// [[util.smartptr.shared.cmp]](util.smartptr.shared.cmp "20.3.2.2.8 Comparison"), shared_ptr comparisonstemplate<class T, class U>constexpr bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T, class U>constexpr strong_ordering operator<=>(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept; template<class T>constexpr bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept; template<class T>constexpr strong_ordering operator<=>(const shared_ptr<T>& x, nullptr_t) noexcept; // [[util.smartptr.shared.spec]](util.smartptr.shared.spec "20.3.2.2.9 Specialized algorithms"), shared_ptr specialized algorithmstemplate<class T>constexpr void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept; // [[util.smartptr.shared.cast]](util.smartptr.shared.cast "20.3.2.2.10 Casts"), shared_ptr caststemplate<class T, class U>constexpr shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U>constexpr shared_ptr<T> static_pointer_cast(shared_ptr<U>&& r) noexcept; template<class T, class U>constexpr shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U>constexpr shared_ptr<T> dynamic_pointer_cast(shared_ptr<U>&& r) noexcept; template<class T, class U>constexpr shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U>constexpr shared_ptr<T> const_pointer_cast(shared_ptr<U>&& r) noexcept; template<class T, class U> shared_ptr<T> reinterpret_pointer_cast(const shared_ptr<U>& r) noexcept; template<class T, class U> shared_ptr<T> reinterpret_pointer_cast(shared_ptr<U>&& r) noexcept; // [[util.smartptr.getdeleter]](util.smartptr.getdeleter "20.3.2.2.11 get_deleter"), shared_ptr get_deletertemplate<class D, class T>constexpr D* get_deleter(const shared_ptr<T>& p) noexcept; // [[util.smartptr.shared.io]](util.smartptr.shared.io "20.3.2.2.12 I/O"), shared_ptr I/Otemplate<class E, class T, class Y> basic_ostream<E, T>& operator<<(basic_ostream<E, T>& os, const shared_ptr<Y>& p); // [[util.smartptr.weak]](util.smartptr.weak "20.3.2.3 Class template weak_ptr"), class template weak_ptrtemplate<class T> class weak_ptr; // [[util.smartptr.weak.spec]](util.smartptr.weak.spec "20.3.2.3.7 Specialized algorithms"), weak_ptr specialized algorithmstemplate<class T> constexpr void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept; // [[util.smartptr.ownerless]](util.smartptr.ownerless "20.3.2.4 Class template owner_less"), class template owner_lesstemplate<class T = void> struct owner_less; // [[util.smartptr.owner.hash]](util.smartptr.owner.hash "20.3.2.5 Struct owner_hash"), struct owner_hashstruct owner_hash; // [[util.smartptr.owner.equal]](util.smartptr.owner.equal "20.3.2.6 Struct owner_equal"), struct owner_equalstruct owner_equal; // [[util.smartptr.enab]](util.smartptr.enab "20.3.2.7 Class template enable_shared_from_this"), class template enable_shared_from_thistemplate<class T> class enable_shared_from_this; // [[util.smartptr.hash]](util.smartptr.hash "20.3.3 Smart pointer hash support"), hash supporttemplate<class T> struct hash; // freestandingtemplate<class T, class D> struct hash<unique_ptr<T, D>>; // freestandingtemplate<class T> struct hash<shared_ptr<T>>; // [[util.smartptr.atomic]](util.smartptr.atomic "32.5.8.7 Partial specializations for smart pointers"), atomic smart pointerstemplate<class T> struct atomic; // freestandingtemplate<class T> struct atomic<shared_ptr<T>>; template<class T> struct atomic<weak_ptr<T>>; // [[out.ptr.t]](out.ptr.t "20.3.4.1 Class template out_ptr_t"), class template out_ptr_ttemplate<class Smart, class Pointer, class... Args>class out_ptr_t; // freestanding// [[out.ptr]](out.ptr "20.3.4.2 Function template out_ptr"), function template out_ptrtemplate<class Pointer = void, class Smart, class... Args>constexpr auto out_ptr(Smart& s, Args&&... args); // freestanding// [[inout.ptr.t]](inout.ptr.t "20.3.4.3 Class template inout_ptr_t"), class template inout_ptr_ttemplate<class Smart, class Pointer, class... Args>class inout_ptr_t; // freestanding// [[inout.ptr]](inout.ptr "20.3.4.4 Function template inout_ptr"), function template inout_ptrtemplate<class Pointer = void, class Smart, class... Args>constexpr auto inout_ptr(Smart& s, Args&&... args); // freestanding// [[indirect]](indirect "20.4.1 Class template indirect"), class template indirecttemplate<class T, class Allocator = allocator<T>>class indirect; // [[indirect.hash]](indirect.hash "20.4.1.10 Hash support"), hash supporttemplate<class T, class Alloc> struct hash<indirect<T, Alloc>>; // [[polymorphic]](polymorphic "20.4.2 Class template polymorphic"), class template polymorphictemplate<class T, class Allocator = allocator<T>>class polymorphic; namespace pmr {template<class T> using indirect = indirect<T, polymorphic_allocator<T>>; template<class T> using polymorphic = polymorphic<T, polymorphic_allocator<T>>; }}
|
||
|
||
### [20.2.3](#pointer.traits) Pointer traits [[pointer.traits]](pointer.traits)
|
||
|
||
#### [20.2.3.1](#pointer.traits.general) General [[pointer.traits.general]](pointer.traits.general)
|
||
|
||
[1](#pointer.traits.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L745)
|
||
|
||
The class template pointer_traits supplies a uniform interface to certain
|
||
attributes of pointer-like types[.](#pointer.traits.general-1.sentence-1)
|
||
|
||
[ð](#lib:pointer_traits)
|
||
|
||
namespace std {template<class Ptr> struct pointer_traits {*see below*; }; template<class T> struct pointer_traits<T*> {using pointer = T*; using element_type = T; using difference_type = ptrdiff_t; template<class U> using rebind = U*; static constexpr pointer pointer_to(*see below* r) noexcept; };}
|
||
|
||
#### [20.2.3.2](#pointer.traits.types) Member types [[pointer.traits.types]](pointer.traits.types)
|
||
|
||
[1](#pointer.traits.types-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L770)
|
||
|
||
The definitions in this subclause make use of
|
||
the following exposition-only class template and concept:template<class T>struct *ptr-traits-elem* // *exposition only*{ };
|
||
|
||
template<class T> requires requires { typename T::element_type; }struct *ptr-traits-elem*<T>{ using type = typename T::element_type; };
|
||
|
||
template<template<class...> class SomePointer, class T, class... Args>requires (!requires { typename SomePointer<T, Args...>::element_type; })struct *ptr-traits-elem*<SomePointer<T, Args...>>{ using type = T; };
|
||
|
||
template<class Ptr>concept [*has-elem-type*](#concept:has-elem-type "20.2.3.2 Member types [pointer.traits.types]") = // *exposition only*requires { typename *ptr-traits-elem*<Ptr>::type; }
|
||
|
||
[2](#pointer.traits.types-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L792)
|
||
|
||
If Ptr satisfies [*has-elem-type*](#concept:has-elem-type "20.2.3.2 Member types [pointer.traits.types]"),
|
||
a specialization pointer_traits<Ptr> generated from the pointer_traits primary template
|
||
has the following members
|
||
as well as those described in [[pointer.traits.functions]](#pointer.traits.functions "20.2.3.3 Member functions");
|
||
otherwise, such a specialization has no members by any of those names[.](#pointer.traits.types-2.sentence-1)
|
||
|
||
[ð](#lib:pointer,pointer_traits)
|
||
|
||
`using pointer = see below;
|
||
`
|
||
|
||
[3](#pointer.traits.types-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L806)
|
||
|
||
*Type*: Ptr[.](#pointer.traits.types-3.sentence-1)
|
||
|
||
[ð](#lib:element_type,pointer_traits)
|
||
|
||
`using element_type = see below;
|
||
`
|
||
|
||
[4](#pointer.traits.types-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L816)
|
||
|
||
*Type*: typename *ptr-traits-elem*<Ptr>::type[.](#pointer.traits.types-4.sentence-1)
|
||
|
||
[ð](#lib:difference_type,pointer_traits)
|
||
|
||
`using difference_type = see below;
|
||
`
|
||
|
||
[5](#pointer.traits.types-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L826)
|
||
|
||
*Type*: Ptr::difference_type if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Ptr::difference_type is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,ptrdiff_t[.](#pointer.traits.types-5.sentence-1)
|
||
|
||
[ð](#lib:rebind,pointer_traits)
|
||
|
||
`template<class U> using rebind = see below;
|
||
`
|
||
|
||
[6](#pointer.traits.types-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L839)
|
||
|
||
*Alias template*: Ptr::rebind<U> if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Ptr::rebind<U> is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,SomePointer<U, Args> ifPtr is a class template instantiation of the form SomePointer<T, Args>,
|
||
where Args is zero or more type arguments; otherwise, the instantiation ofrebind is ill-formed[.](#pointer.traits.types-6.sentence-1)
|
||
|
||
#### [20.2.3.3](#pointer.traits.functions) Member functions [[pointer.traits.functions]](pointer.traits.functions)
|
||
|
||
[ð](#lib:pointer_to,pointer_traits)
|
||
|
||
`static pointer pointer_traits::pointer_to(see below r);
|
||
static constexpr pointer pointer_traits<T*>::pointer_to(see below r) noexcept;
|
||
`
|
||
|
||
[1](#pointer.traits.functions-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L858)
|
||
|
||
*Mandates*: For the first member function,Ptr::pointer_to(r) is well-formed[.](#pointer.traits.functions-1.sentence-1)
|
||
|
||
[2](#pointer.traits.functions-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L863)
|
||
|
||
*Preconditions*: For the first member function,Ptr::pointer_to(r) returns a pointer to r through which indirection is valid[.](#pointer.traits.functions-2.sentence-1)
|
||
|
||
[3](#pointer.traits.functions-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L869)
|
||
|
||
*Returns*: The first member function returns Ptr::pointer_to(r)[.](#pointer.traits.functions-3.sentence-1)
|
||
|
||
The second member function returns addressof(r)[.](#pointer.traits.functions-3.sentence-2)
|
||
|
||
[4](#pointer.traits.functions-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L874)
|
||
|
||
*Remarks*: If element_type is cv void, the type ofr is unspecified; otherwise, it is element_type&[.](#pointer.traits.functions-4.sentence-1)
|
||
|
||
#### [20.2.3.4](#pointer.traits.optmem) Optional members [[pointer.traits.optmem]](pointer.traits.optmem)
|
||
|
||
[1](#pointer.traits.optmem-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L882)
|
||
|
||
Specializations of pointer_traits may define the member declared
|
||
in this subclause to customize the behavior of the standard library[.](#pointer.traits.optmem-1.sentence-1)
|
||
|
||
A specialization generated from the pointer_traits primary template
|
||
has no member by this name[.](#pointer.traits.optmem-1.sentence-2)
|
||
|
||
[ð](#lib:to_address,pointer_traits)
|
||
|
||
`static element_type* to_address(pointer p) noexcept;
|
||
`
|
||
|
||
[2](#pointer.traits.optmem-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L894)
|
||
|
||
*Returns*: A pointer of type element_type* that references
|
||
the same location as the argument p[.](#pointer.traits.optmem-2.sentence-1)
|
||
|
||
[3](#pointer.traits.optmem-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L899)
|
||
|
||
[*Note [1](#pointer.traits.optmem-note-1)*:
|
||
|
||
This function is intended to be the inverse of pointer_to[.](#pointer.traits.optmem-3.sentence-1)
|
||
|
||
If defined, it customizes the behavior of
|
||
the non-member functionto_address ([[pointer.conversion]](#pointer.conversion "20.2.4 Pointer conversion"))[.](#pointer.traits.optmem-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
### [20.2.4](#pointer.conversion) Pointer conversion [[pointer.conversion]](pointer.conversion)
|
||
|
||
[ð](#lib:to_address)
|
||
|
||
`template<class T> constexpr T* to_address(T* p) noexcept;
|
||
`
|
||
|
||
[1](#pointer.conversion-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L916)
|
||
|
||
*Mandates*: T is not a function type[.](#pointer.conversion-1.sentence-1)
|
||
|
||
[2](#pointer.conversion-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L920)
|
||
|
||
*Returns*: p[.](#pointer.conversion-2.sentence-1)
|
||
|
||
[ð](#lib:to_address_)
|
||
|
||
`template<class Ptr> constexpr auto to_address(const Ptr& p) noexcept;
|
||
`
|
||
|
||
[3](#pointer.conversion-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L931)
|
||
|
||
*Returns*: pointer_traits<Ptr>::to_address(p) if that expression is well-formed
|
||
(see [[pointer.traits.optmem]](#pointer.traits.optmem "20.2.3.4 Optional members")),
|
||
otherwise to_address(p.operator->())[.](#pointer.conversion-3.sentence-1)
|
||
|
||
### [20.2.5](#ptr.align) Pointer alignment [[ptr.align]](ptr.align)
|
||
|
||
[ð](#lib:align)
|
||
|
||
`void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
|
||
`
|
||
|
||
[1](#ptr.align-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L946)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(1.1)](#ptr.align-1.1)
|
||
|
||
alignment is a power of two
|
||
|
||
- [(1.2)](#ptr.align-1.2)
|
||
|
||
ptr represents the address of contiguous storage of at leastspace bytes
|
||
|
||
[2](#ptr.align-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L957)
|
||
|
||
*Effects*: If it is possible to fit size bytes
|
||
of storage aligned by alignment into the buffer pointed to byptr with length space, the function updatesptr to represent the first possible address of such storage
|
||
and decreases space by the number of bytes used for alignment[.](#ptr.align-2.sentence-1)
|
||
|
||
Otherwise, the function does nothing[.](#ptr.align-2.sentence-2)
|
||
|
||
[3](#ptr.align-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L966)
|
||
|
||
*Returns*: A null pointer if the requested aligned buffer
|
||
would not fit into the available space, otherwise the adjusted value
|
||
of ptr[.](#ptr.align-3.sentence-1)
|
||
|
||
[4](#ptr.align-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L972)
|
||
|
||
[*Note [1](#ptr.align-note-1)*:
|
||
|
||
The function updates its ptr and space arguments so that it can be called repeatedly
|
||
with possibly different alignment and size arguments for the same buffer[.](#ptr.align-4.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:assume_aligned)
|
||
|
||
`template<size_t N, class T>
|
||
constexpr T* assume_aligned(T* ptr);
|
||
`
|
||
|
||
[5](#ptr.align-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L988)
|
||
|
||
*Mandates*: N is a power of two[.](#ptr.align-5.sentence-1)
|
||
|
||
[6](#ptr.align-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L992)
|
||
|
||
*Preconditions*: ptr points to an object X of
|
||
a type similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) to T,
|
||
where X has alignment N ([[basic.align]](basic.align "6.8.3 Alignment"))[.](#ptr.align-6.sentence-1)
|
||
|
||
[7](#ptr.align-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L998)
|
||
|
||
*Returns*: ptr[.](#ptr.align-7.sentence-1)
|
||
|
||
[8](#ptr.align-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1002)
|
||
|
||
*Throws*: Nothing[.](#ptr.align-8.sentence-1)
|
||
|
||
[9](#ptr.align-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1006)
|
||
|
||
[*Note [2](#ptr.align-note-2)*:
|
||
|
||
The alignment assumption on an object X expressed by a call to assume_aligned might result in generation of more efficient code[.](#ptr.align-9.sentence-1)
|
||
|
||
It is up to the program to ensure that the assumption actually holds[.](#ptr.align-9.sentence-2)
|
||
|
||
The call does not cause the implementation to verify or enforce this[.](#ptr.align-9.sentence-3)
|
||
|
||
An implementation might only make the assumption
|
||
for those operations on X that access X through the pointer returned by assume_aligned[.](#ptr.align-9.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:is_sufficiently_aligned)
|
||
|
||
`template<size_t Alignment, class T>
|
||
bool is_sufficiently_aligned(T* ptr);
|
||
`
|
||
|
||
[10](#ptr.align-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1026)
|
||
|
||
*Preconditions*: p points to
|
||
an object X of a type similar ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) to T[.](#ptr.align-10.sentence-1)
|
||
|
||
[11](#ptr.align-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1031)
|
||
|
||
*Returns*: true if X has alignment at least Alignment,
|
||
otherwise false[.](#ptr.align-11.sentence-1)
|
||
|
||
[12](#ptr.align-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1036)
|
||
|
||
*Throws*: Nothing[.](#ptr.align-12.sentence-1)
|
||
|
||
### [20.2.6](#obj.lifetime) Explicit lifetime management [[obj.lifetime]](obj.lifetime)
|
||
|
||
[ð](#lib:start_lifetime_as)
|
||
|
||
`template<class T>
|
||
T* start_lifetime_as(void* p) noexcept;
|
||
template<class T>
|
||
const T* start_lifetime_as(const void* p) noexcept;
|
||
template<class T>
|
||
volatile T* start_lifetime_as(volatile void* p) noexcept;
|
||
template<class T>
|
||
const volatile T* start_lifetime_as(const volatile void* p) noexcept;
|
||
`
|
||
|
||
[1](#obj.lifetime-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1056)
|
||
|
||
*Mandates*: T is an implicit-lifetime type ([[basic.types.general]](basic.types.general#term.implicit.lifetime.type "6.9.1 General"))
|
||
and not an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General"))[.](#obj.lifetime-1.sentence-1)
|
||
|
||
[2](#obj.lifetime-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1061)
|
||
|
||
*Preconditions*: [p, (char*)p + sizeof(T)) denotes a region of allocated storage
|
||
that is
|
||
a subset of the region of storage
|
||
reachable through ([[basic.compound]](basic.compound "6.9.4 Compound types")) p and
|
||
suitably aligned for the type T[.](#obj.lifetime-2.sentence-1)
|
||
|
||
[3](#obj.lifetime-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1069)
|
||
|
||
*Effects*: Implicitly creates objects ([[intro.object]](intro.object "6.8.2 Object model")) within the denoted region
|
||
consisting of an object *a* of type T whose address is p, and
|
||
objects nested within *a*,
|
||
as follows:
|
||
The object representation of *a* is the contents of the storage prior to the call to start_lifetime_as[.](#obj.lifetime-3.sentence-1)
|
||
|
||
The value of each created object *o* of trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General")) U is determined in the same manner as for a call
|
||
to bit_cast<U>(E) ([[bit.cast]](bit.cast "22.11.3 Function template bit_cast")),
|
||
where E is an lvalue of type U denoting *o*,
|
||
except that the storage is not accessed[.](#obj.lifetime-3.sentence-2)
|
||
|
||
The value of any other created object is unspecified[.](#obj.lifetime-3.sentence-3)
|
||
|
||
[*Note [1](#obj.lifetime-note-1)*:
|
||
|
||
The unspecified value can be indeterminate[.](#obj.lifetime-3.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[4](#obj.lifetime-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1089)
|
||
|
||
*Returns*: A pointer to the *a* defined in the *Effects* paragraph[.](#obj.lifetime-4.sentence-1)
|
||
|
||
[ð](#lib:start_lifetime_as_array)
|
||
|
||
`template<class T>
|
||
T* start_lifetime_as_array(void* p, size_t n) noexcept;
|
||
template<class T>
|
||
const T* start_lifetime_as_array(const void* p, size_t n) noexcept;
|
||
template<class T>
|
||
volatile T* start_lifetime_as_array(volatile void* p, size_t n) noexcept;
|
||
template<class T>
|
||
const volatile T* start_lifetime_as_array(const volatile void* p, size_t n) noexcept;
|
||
`
|
||
|
||
[5](#obj.lifetime-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1108)
|
||
|
||
*Mandates*: T is a complete type[.](#obj.lifetime-5.sentence-1)
|
||
|
||
[6](#obj.lifetime-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1112)
|
||
|
||
*Preconditions*: p is suitably aligned for an array of T or is null[.](#obj.lifetime-6.sentence-1)
|
||
|
||
n <= size_t(-1) / sizeof(T) is true[.](#obj.lifetime-6.sentence-2)
|
||
|
||
If n > 0 is true,
|
||
[(char*)p, (char*)p + (n * sizeof(T))) denotes
|
||
a region of allocated storage that is
|
||
a subset of the region of storage
|
||
reachable through ([[basic.compound]](basic.compound "6.9.4 Compound types")) p[.](#obj.lifetime-6.sentence-3)
|
||
|
||
[7](#obj.lifetime-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1122)
|
||
|
||
*Effects*: If n > 0 is true,
|
||
equivalent tostart_lifetime_as<U>(p) where U is the type âarray of n Tâ[.](#obj.lifetime-7.sentence-1)
|
||
|
||
Otherwise, there are no effects[.](#obj.lifetime-7.sentence-2)
|
||
|
||
[8](#obj.lifetime-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1130)
|
||
|
||
*Returns*: A pointer to the first element of the created array,
|
||
if any;
|
||
otherwise,
|
||
a pointer that compares equal to p ([[expr.eq]](expr.eq "7.6.10 Equality operators"))[.](#obj.lifetime-8.sentence-1)
|
||
|
||
[ð](#lib:trivially_relocate)
|
||
|
||
`template<class T>
|
||
T* trivially_relocate(T* first, T* last, T* result);
|
||
`
|
||
|
||
[9](#obj.lifetime-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1145)
|
||
|
||
*Mandates*: is_trivially_relocatable_v<T> && !is_const_v<T> is true[.](#obj.lifetime-9.sentence-1)
|
||
|
||
T is not an array of unknown bound[.](#obj.lifetime-9.sentence-2)
|
||
|
||
[10](#obj.lifetime-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1150)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(10.1)](#obj.lifetime-10.1)
|
||
|
||
[first, last) is a valid range[.](#obj.lifetime-10.1.sentence-1)
|
||
|
||
- [(10.2)](#obj.lifetime-10.2)
|
||
|
||
[result, result + (last - first)) denotes a region of storage that
|
||
is a subset of the region reachable through result ([[basic.compound]](basic.compound "6.9.4 Compound types"))
|
||
and suitably aligned for the type T[.](#obj.lifetime-10.2.sentence-1)
|
||
|
||
- [(10.3)](#obj.lifetime-10.3)
|
||
|
||
No element in the range [first, last) is a potentially-overlapping subobject[.](#obj.lifetime-10.3.sentence-1)
|
||
|
||
[11](#obj.lifetime-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1163)
|
||
|
||
*Postconditions*: No effect if result == first is true[.](#obj.lifetime-11.sentence-1)
|
||
|
||
Otherwise, the range denoted by [result, result + (last - first))
|
||
contains objects (including subobjects) whose lifetime has begun and whose
|
||
object representations are the original object representations of the
|
||
corresponding objects in the source range [first, last) except
|
||
for any parts of the object representations used by the implementation to
|
||
represent type information ([[intro.object]](intro.object "6.8.2 Object model"))[.](#obj.lifetime-11.sentence-2)
|
||
|
||
If any of the objects has
|
||
union type, its active member is the same as that of the corresponding object
|
||
in the source range[.](#obj.lifetime-11.sentence-3)
|
||
|
||
If any of the aforementioned objects has a non-static
|
||
data member of reference type, that reference refers to the same entity as
|
||
does the corresponding reference in the source range[.](#obj.lifetime-11.sentence-4)
|
||
|
||
The lifetimes of the
|
||
original objects in the source range have ended[.](#obj.lifetime-11.sentence-5)
|
||
|
||
[12](#obj.lifetime-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1178)
|
||
|
||
*Returns*: result + (last - first)[.](#obj.lifetime-12.sentence-1)
|
||
|
||
[13](#obj.lifetime-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1182)
|
||
|
||
*Throws*: Nothing[.](#obj.lifetime-13.sentence-1)
|
||
|
||
[14](#obj.lifetime-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1186)
|
||
|
||
*Complexity*: Linear in the length of the source range[.](#obj.lifetime-14.sentence-1)
|
||
|
||
[15](#obj.lifetime-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1190)
|
||
|
||
*Remarks*: The destination region of storage is considered reused ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#obj.lifetime-15.sentence-1)
|
||
|
||
No constructors or destructors are invoked[.](#obj.lifetime-15.sentence-2)
|
||
|
||
[*Note [2](#obj.lifetime-note-2)*:
|
||
|
||
Overlapping ranges are supported[.](#obj.lifetime-15.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:relocate)
|
||
|
||
`template<class T>
|
||
constexpr T* relocate(T* first, T* last, T* result);
|
||
`
|
||
|
||
[16](#obj.lifetime-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1207)
|
||
|
||
*Mandates*: is_nothrow_relocatable_v<T> && !is_const_v<T> is true[.](#obj.lifetime-16.sentence-1)
|
||
|
||
T is not an array of unknown bound[.](#obj.lifetime-16.sentence-2)
|
||
|
||
[17](#obj.lifetime-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1212)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(17.1)](#obj.lifetime-17.1)
|
||
|
||
[first, last) is a valid range[.](#obj.lifetime-17.1.sentence-1)
|
||
|
||
- [(17.2)](#obj.lifetime-17.2)
|
||
|
||
[result, result + (last - first)) denotes a region of storage that is
|
||
a subset of the region reachable through result ([[basic.compound]](basic.compound "6.9.4 Compound types"))
|
||
and suitably aligned for the type T[.](#obj.lifetime-17.2.sentence-1)
|
||
|
||
- [(17.3)](#obj.lifetime-17.3)
|
||
|
||
No element in the range [first, last) is a potentially-overlapping
|
||
subobject[.](#obj.lifetime-17.3.sentence-1)
|
||
|
||
[18](#obj.lifetime-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1226)
|
||
|
||
*Effects*:
|
||
|
||
- [(18.1)](#obj.lifetime-18.1)
|
||
|
||
If result == first is true, no effect;
|
||
|
||
- [(18.2)](#obj.lifetime-18.2)
|
||
|
||
otherwise, if not called during constant evaluation and is_trivially_relocatable_v<T> is true, then has
|
||
effects equivalent to: trivially_relocate(first, last, result);
|
||
|
||
- [(18.3)](#obj.lifetime-18.3)
|
||
|
||
otherwise, for each integer i in [0, last - first),
|
||
* [(18.3.1)](#obj.lifetime-18.3.1)
|
||
|
||
if T is an array type, equivalent to: relocate(begin(first[i]), end(first[i]), *start_lifetime_as<T>(result + i));
|
||
|
||
* [(18.3.2)](#obj.lifetime-18.3.2)
|
||
|
||
otherwise, equivalent to: construct_at(result + i, std::move(first[i])); destroy_at(first + i);
|
||
|
||
[19](#obj.lifetime-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1247)
|
||
|
||
*Returns*: result + (last - first)[.](#obj.lifetime-19.sentence-1)
|
||
|
||
[20](#obj.lifetime-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1251)
|
||
|
||
*Throws*: Nothing[.](#obj.lifetime-20.sentence-1)
|
||
|
||
[*Note [3](#obj.lifetime-note-3)*:
|
||
|
||
Overlapping ranges are supported[.](#obj.lifetime-20.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
### [20.2.7](#allocator.tag) Allocator argument tag [[allocator.tag]](allocator.tag)
|
||
|
||
[ð](#lib:allocator_arg_t)
|
||
|
||
`namespace std {
|
||
struct allocator_arg_t { explicit allocator_arg_t() = default; };
|
||
inline constexpr allocator_arg_t allocator_arg{};
|
||
}
|
||
`
|
||
|
||
[1](#allocator.tag-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1271)
|
||
|
||
The allocator_arg_t struct is an empty class type used as a unique type to
|
||
disambiguate constructor and function overloading[.](#allocator.tag-1.sentence-1)
|
||
|
||
Specifically, several types (seetuple [[tuple]](tuple "22.4 Tuples")) have constructors with allocator_arg_t as the first
|
||
argument, immediately followed by an argument of a type that meets the[*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1 General [allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1 General"))[.](#allocator.tag-1.sentence-2)
|
||
|
||
### [20.2.8](#allocator.uses) uses_allocator [[allocator.uses]](allocator.uses)
|
||
|
||
#### [20.2.8.1](#allocator.uses.trait) uses_allocator trait [[allocator.uses.trait]](allocator.uses.trait)
|
||
|
||
[ð](#lib:uses_allocator)
|
||
|
||
`template<class T, class Alloc> struct uses_allocator;
|
||
`
|
||
|
||
[1](#allocator.uses.trait-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1288)
|
||
|
||
*Remarks*: Automatically detects whether T has a nested allocator_type that
|
||
is convertible from Alloc[.](#allocator.uses.trait-1.sentence-1)
|
||
|
||
Meets the [*Cpp17BinaryTypeTrait*](meta.rqmts#:Cpp17BinaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#allocator.uses.trait-1.sentence-2)
|
||
|
||
The implementation shall provide a definition that is
|
||
derived from true_type if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") T::allocator_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) andis_convertible_v<Alloc, T::allocator_type> != false, otherwise it shall be
|
||
derived from false_type[.](#allocator.uses.trait-1.sentence-3)
|
||
|
||
A program may specialize this template to derive fromtrue_type for a program-defined type T that does not have a nestedallocator_type but nonetheless can be constructed with an allocator where
|
||
either:
|
||
|
||
- [(1.1)](#allocator.uses.trait-1.1)
|
||
|
||
the first argument of a constructor has type allocator_arg_t and the
|
||
second argument has type Alloc or
|
||
|
||
- [(1.2)](#allocator.uses.trait-1.2)
|
||
|
||
the last argument of a constructor has type Alloc[.](#allocator.uses.trait-1.sentence-4)
|
||
|
||
#### [20.2.8.2](#allocator.uses.construction) Uses-allocator construction [[allocator.uses.construction]](allocator.uses.construction)
|
||
|
||
[1](#allocator.uses.construction-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1310)
|
||
|
||
[*Uses-allocator construction*](#def:uses-allocator_construction "20.2.8.2 Uses-allocator construction [allocator.uses.construction]") with allocator alloc and constructor arguments args... refers to the construction of an object of type T such that alloc is passed to the constructor of T if T uses an allocator type compatible with alloc[.](#allocator.uses.construction-1.sentence-1)
|
||
|
||
When applied to the construction of an object of type T,
|
||
it is equivalent to initializing it with the value of the expressionmake_obj_using_allocator<T>(alloc, args...), described below[.](#allocator.uses.construction-1.sentence-2)
|
||
|
||
[2](#allocator.uses.construction-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1320)
|
||
|
||
The following utility functions support
|
||
three conventions for passing alloc to a constructor:
|
||
|
||
- [(2.1)](#allocator.uses.construction-2.1)
|
||
|
||
If T does not use an allocator compatible with alloc,
|
||
then alloc is ignored[.](#allocator.uses.construction-2.1.sentence-1)
|
||
|
||
- [(2.2)](#allocator.uses.construction-2.2)
|
||
|
||
Otherwise, if T has a constructor invocable as T(allocator_arg, alloc, args...) (leading-allocator convention),
|
||
then uses-allocator construction chooses this constructor form[.](#allocator.uses.construction-2.2.sentence-1)
|
||
|
||
- [(2.3)](#allocator.uses.construction-2.3)
|
||
|
||
Otherwise, if T has a constructor invocable as T(args..., alloc) (trailing-allocator convention),
|
||
then uses-allocator construction chooses this constructor form[.](#allocator.uses.construction-2.3.sentence-1)
|
||
|
||
[3](#allocator.uses.construction-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1337)
|
||
|
||
The uses_allocator_construction_args function template
|
||
takes an allocator and argument list and
|
||
produces (as a tuple) a new argument list matching one of the above conventions[.](#allocator.uses.construction-3.sentence-1)
|
||
|
||
Additionally, overloads are provided
|
||
that treat specializations of pair such that uses-allocator construction is applied individually
|
||
to the first and second data members[.](#allocator.uses.construction-3.sentence-2)
|
||
|
||
The make_obj_using_allocator anduninitialized_construct_using_allocator function templates
|
||
apply the modified constructor arguments
|
||
to construct an object of type T as a return value or in-place, respectively[.](#allocator.uses.construction-3.sentence-3)
|
||
|
||
[*Note [1](#allocator.uses.construction-note-1)*:
|
||
|
||
For uses_allocator_construction_args andmake_obj_using_allocator, type T is not deduced and must therefore be specified explicitly by the caller[.](#allocator.uses.construction-3.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:uses_allocator_construction_args)
|
||
|
||
`template<class T, class Alloc, class... Args>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||
Args&&... args) noexcept;
|
||
`
|
||
|
||
[4](#allocator.uses.construction-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1364)
|
||
|
||
*Constraints*: remove_cv_t<T> is not a specialization of pair[.](#allocator.uses.construction-4.sentence-1)
|
||
|
||
[5](#allocator.uses.construction-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1368)
|
||
|
||
*Returns*: A tuple value determined as follows:
|
||
|
||
- [(5.1)](#allocator.uses.construction-5.1)
|
||
|
||
If uses_allocator_v<remove_cv_t<T>, Alloc> is false and is_constructible_v<T, Args...> is true,
|
||
return forward_as_tuple(std::forward<Args>(args)...)[.](#allocator.uses.construction-5.1.sentence-1)
|
||
|
||
- [(5.2)](#allocator.uses.construction-5.2)
|
||
|
||
Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, allocator_arg_t, const Alloc&, Args...> is true,
|
||
returntuple<allocator_arg_t, const Alloc&, Args&&...>( allocator_arg, alloc, std::forward<Args>(args)...)
|
||
|
||
- [(5.3)](#allocator.uses.construction-5.3)
|
||
|
||
Otherwise, if uses_allocator_v<remove_cv_t<T>, Alloc> is true and is_constructible_v<T, Args..., const Alloc&> is true,
|
||
return forward_as_tuple(std::forward<Args>(args)..., alloc)[.](#allocator.uses.construction-5.3.sentence-1)
|
||
|
||
- [(5.4)](#allocator.uses.construction-5.4)
|
||
|
||
Otherwise, the program is ill-formed[.](#allocator.uses.construction-5.4.sentence-1)
|
||
|
||
[*Note [2](#allocator.uses.construction-note-2)*:
|
||
|
||
This definition prevents a silent failure
|
||
to pass the allocator to a constructor of a type for whichuses_allocator_v<T, Alloc> is true[.](#allocator.uses.construction-5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:uses_allocator_construction_args_)
|
||
|
||
`template<class T, class Alloc, class Tuple1, class Tuple2>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
|
||
Tuple1&& x, Tuple2&& y) noexcept;
|
||
`
|
||
|
||
[6](#allocator.uses.construction-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1407)
|
||
|
||
Let T1 be T::first_type[.](#allocator.uses.construction-6.sentence-1)
|
||
|
||
Let T2 be T::second_type[.](#allocator.uses.construction-6.sentence-2)
|
||
|
||
[7](#allocator.uses.construction-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1411)
|
||
|
||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#allocator.uses.construction-7.sentence-1)
|
||
|
||
[8](#allocator.uses.construction-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1415)
|
||
|
||
*Effects*: Equivalent to:return make_tuple( piecewise_construct,
|
||
apply([&alloc](auto&&... args1) {return uses_allocator_construction_args<T1>( alloc, std::forward<decltype(args1)>(args1)...); }, std::forward<Tuple1>(x)),
|
||
apply([&alloc](auto&&... args2) {return uses_allocator_construction_args<T2>( alloc, std::forward<decltype(args2)>(args2)...); }, std::forward<Tuple2>(y)));
|
||
|
||
[ð](#lib:uses_allocator_construction_args__)
|
||
|
||
`template<class T, class Alloc>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept;
|
||
`
|
||
|
||
[9](#allocator.uses.construction-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1439)
|
||
|
||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#allocator.uses.construction-9.sentence-1)
|
||
|
||
[10](#allocator.uses.construction-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1443)
|
||
|
||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||
tuple<>{}, tuple<>{});
|
||
|
||
[ð](#lib:uses_allocator_construction_args___)
|
||
|
||
`template<class T, class Alloc, class U, class V>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||
U&& u, V&& v) noexcept;
|
||
`
|
||
|
||
[11](#allocator.uses.construction-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1460)
|
||
|
||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#allocator.uses.construction-11.sentence-1)
|
||
|
||
[12](#allocator.uses.construction-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1464)
|
||
|
||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||
forward_as_tuple(std::forward<U>(u)),
|
||
forward_as_tuple(std::forward<V>(v)));
|
||
|
||
[ð](#lib:uses_allocator_construction_args____)
|
||
|
||
`template<class T, class Alloc, class U, class V>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||
pair<U, V>& pr) noexcept;
|
||
template<class T, class Alloc, class U, class V>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||
const pair<U, V>& pr) noexcept;
|
||
`
|
||
|
||
[13](#allocator.uses.construction-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1485)
|
||
|
||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#allocator.uses.construction-13.sentence-1)
|
||
|
||
[14](#allocator.uses.construction-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1489)
|
||
|
||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||
forward_as_tuple(pr.first),
|
||
forward_as_tuple(pr.second));
|
||
|
||
[ð](#lib:uses_allocator_construction_args_____)
|
||
|
||
`template<class T, class Alloc, class U, class V>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||
pair<U, V>&& pr) noexcept;
|
||
template<class T, class Alloc, class U, class V>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc,
|
||
const pair<U, V>&& pr) noexcept;
|
||
`
|
||
|
||
[15](#allocator.uses.construction-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1510)
|
||
|
||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#allocator.uses.construction-15.sentence-1)
|
||
|
||
[16](#allocator.uses.construction-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1514)
|
||
|
||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||
forward_as_tuple(get<0>(std::move(pr))),
|
||
forward_as_tuple(get<1>(std::move(pr))));
|
||
|
||
[ð](#lib:uses_allocator_construction_args______)
|
||
|
||
`template<class T, class Alloc, [pair-like](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
|
||
`
|
||
|
||
[17](#allocator.uses.construction-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1531)
|
||
|
||
*Constraints*: remove_cv_t<T> is a specialization of pair andremove_cvref_t<P> is not a specialization of ranges::subrange[.](#allocator.uses.construction-17.sentence-1)
|
||
|
||
[18](#allocator.uses.construction-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1536)
|
||
|
||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||
forward_as_tuple(get<0>(std::forward<P>(p))),
|
||
forward_as_tuple(get<1>(std::forward<P>(p))));
|
||
|
||
[ð](#lib:uses_allocator_construction_args_______)
|
||
|
||
`template<class T, class Alloc, class U>
|
||
constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept;
|
||
`
|
||
|
||
[19](#allocator.uses.construction-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1553)
|
||
|
||
Let *FUN* be the function template:template<class A, class B>void *FUN*(const pair<A, B>&);
|
||
|
||
[20](#allocator.uses.construction-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1560)
|
||
|
||
*Constraints*: remove_cv_t<T> is a specialization of pair, and either:
|
||
|
||
- [(20.1)](#allocator.uses.construction-20.1)
|
||
|
||
remove_cvref_t<U> is a specialization of ranges::subrange, or
|
||
|
||
- [(20.2)](#allocator.uses.construction-20.2)
|
||
|
||
U does not satisfy [*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") and
|
||
the expression *FUN*(u) is not well-formed
|
||
when considered as an unevaluated operand[.](#allocator.uses.construction-20.sentence-1)
|
||
|
||
[21](#allocator.uses.construction-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1572)
|
||
|
||
Let *pair-constructor* be an exposition-only class defined as follows:class *pair-constructor* {using *pair-type* = remove_cv_t<T>; // *exposition only*constexpr auto *do-construct*(const *pair-type*& p) const { // *exposition only*return make_obj_using_allocator<*pair-type*>(*alloc_*, p); }constexpr auto *do-construct*(*pair-type*&& p) const { // *exposition only*return make_obj_using_allocator<*pair-type*>(*alloc_*, std::move(p)); }const Alloc& *alloc_*; // *exposition only* U& *u_*; // *exposition only*public:constexpr operator *pair-type*() const {return *do-construct*(std::forward<U>(*u_*)); }};
|
||
|
||
[22](#allocator.uses.construction-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1595)
|
||
|
||
*Returns*: make_tuple(pc),
|
||
where pc is a *pair-constructor* object
|
||
whose *alloc_* member is initialized with alloc and
|
||
whose *u_* member is initialized with u[.](#allocator.uses.construction-22.sentence-1)
|
||
|
||
[ð](#lib:make_obj_using_allocator)
|
||
|
||
`template<class T, class Alloc, class... Args>
|
||
constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
|
||
`
|
||
|
||
[23](#allocator.uses.construction-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1610)
|
||
|
||
*Effects*: Equivalent to:return make_from_tuple<T>(uses_allocator_construction_args<T>( alloc, std::forward<Args>(args)...));
|
||
|
||
[ð](#lib:uninitialized_construct_using_allocator)
|
||
|
||
`template<class T, class Alloc, class... Args>
|
||
constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
|
||
`
|
||
|
||
[24](#allocator.uses.construction-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1626)
|
||
|
||
*Effects*: Equivalent to:return apply([&]<class... U>(U&&... xs) {return construct_at(p, std::forward<U>(xs)...); }, uses_allocator_construction_args<T>(alloc, std::forward<Args>(args)...));
|
||
|
||
### [20.2.9](#allocator.traits) Allocator traits [[allocator.traits]](allocator.traits)
|
||
|
||
#### [20.2.9.1](#allocator.traits.general) General [[allocator.traits.general]](allocator.traits.general)
|
||
|
||
[1](#allocator.traits.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1640)
|
||
|
||
The class template allocator_traits supplies a uniform interface to all
|
||
allocator types[.](#allocator.traits.general-1.sentence-1)
|
||
|
||
An allocator cannot be a non-class type, however, even if allocator_traits supplies the entire required interface[.](#allocator.traits.general-1.sentence-2)
|
||
|
||
[*Note [1](#allocator.traits.general-note-1)*:
|
||
|
||
Thus, it is always possible to create
|
||
a derived class from an allocator[.](#allocator.traits.general-1.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
If a program declares
|
||
an explicit or partial specialization of allocator_traits,
|
||
the program is ill-formed, no diagnostic required[.](#allocator.traits.general-1.sentence-4)
|
||
|
||
[ð](#lib:allocator_traits)
|
||
|
||
namespace std {template<class Alloc> struct allocator_traits {using allocator_type = Alloc; using value_type = typename Alloc::value_type; using pointer = *see below*; using const_pointer = *see below*; using void_pointer = *see below*; using const_void_pointer = *see below*; using difference_type = *see below*; using size_type = *see below*; using propagate_on_container_copy_assignment = *see below*; using propagate_on_container_move_assignment = *see below*; using propagate_on_container_swap = *see below*; using is_always_equal = *see below*; template<class T> using rebind_alloc = *see below*; template<class T> using rebind_traits = allocator_traits<rebind_alloc<T>>; static constexpr pointer allocate(Alloc& a, size_type n); static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint); static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n); static constexpr void deallocate(Alloc& a, pointer p, size_type n); template<class T, class... Args>static constexpr void construct(Alloc& a, T* p, Args&&... args); template<class T>static constexpr void destroy(Alloc& a, T* p); static constexpr size_type max_size(const Alloc& a) noexcept; static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs); };}
|
||
|
||
#### [20.2.9.2](#allocator.traits.types) Member types [[allocator.traits.types]](allocator.traits.types)
|
||
|
||
[ð](#lib:pointer,allocator_traits)
|
||
|
||
`using pointer = see below;
|
||
`
|
||
|
||
[1](#allocator.traits.types-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1705)
|
||
|
||
*Type*: Alloc::pointer if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::pointer is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise, value_type*[.](#allocator.traits.types-1.sentence-1)
|
||
|
||
[ð](#lib:const_pointer,allocator_traits)
|
||
|
||
`using const_pointer = see below;
|
||
`
|
||
|
||
[2](#allocator.traits.types-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1717)
|
||
|
||
*Type*: Alloc::const_pointer if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::const_pointer is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<const value_type>[.](#allocator.traits.types-2.sentence-1)
|
||
|
||
[ð](#lib:void_pointer,allocator_traits)
|
||
|
||
`using void_pointer = see below;
|
||
`
|
||
|
||
[3](#allocator.traits.types-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1730)
|
||
|
||
*Type*: Alloc::void_pointer if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::void_pointer is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<void>[.](#allocator.traits.types-3.sentence-1)
|
||
|
||
[ð](#lib:const_void_pointer,allocator_traits)
|
||
|
||
`using const_void_pointer = see below;
|
||
`
|
||
|
||
[4](#allocator.traits.types-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1743)
|
||
|
||
*Type*: Alloc::const_void_pointer if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::const_void_pointer is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::rebind<const void>[.](#allocator.traits.types-4.sentence-1)
|
||
|
||
[ð](#lib:difference_type,allocator_traits)
|
||
|
||
`using difference_type = see below;
|
||
`
|
||
|
||
[5](#allocator.traits.types-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1756)
|
||
|
||
*Type*: Alloc::difference_type if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::difference_type is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,pointer_traits<pointer>::difference_type[.](#allocator.traits.types-5.sentence-1)
|
||
|
||
[ð](#lib:size_type,allocator_traits)
|
||
|
||
`using size_type = see below;
|
||
`
|
||
|
||
[6](#allocator.traits.types-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1769)
|
||
|
||
*Type*: Alloc::size_type if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::size_type is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,make_unsigned_t<difference_type>[.](#allocator.traits.types-6.sentence-1)
|
||
|
||
[ð](#lib:propagate_on_container_copy_assignment,allocator_traits)
|
||
|
||
`using propagate_on_container_copy_assignment = see below;
|
||
`
|
||
|
||
[7](#allocator.traits.types-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1782)
|
||
|
||
*Type*: Alloc::propagate_on_container_copy_assignment if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_copy_assignment is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#allocator.traits.types-7.sentence-1)
|
||
|
||
[ð](#lib:propagate_on_container_move_assignment,allocator_traits)
|
||
|
||
`using propagate_on_container_move_assignment = see below;
|
||
`
|
||
|
||
[8](#allocator.traits.types-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1795)
|
||
|
||
*Type*: Alloc::propagate_on_container_move_assignment if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_move_assignment is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#allocator.traits.types-8.sentence-1)
|
||
|
||
[ð](#lib:propagate_on_container_swap,allocator_traits)
|
||
|
||
`using propagate_on_container_swap = see below;
|
||
`
|
||
|
||
[9](#allocator.traits.types-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1808)
|
||
|
||
*Type*: Alloc::propagate_on_container_swap if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::propagate_on_container_swap is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwisefalse_type[.](#allocator.traits.types-9.sentence-1)
|
||
|
||
[ð](#lib:is_always_equal,allocator_traits)
|
||
|
||
`using is_always_equal = see below;
|
||
`
|
||
|
||
[10](#allocator.traits.types-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1821)
|
||
|
||
*Type*: Alloc::is_always_equal if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::is_always_equal is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction"));
|
||
otherwise is_empty<Alloc>::type[.](#allocator.traits.types-10.sentence-1)
|
||
|
||
[ð](#lib:rebind_alloc,allocator_traits)
|
||
|
||
`template<class T> using rebind_alloc = see below;
|
||
`
|
||
|
||
[11](#allocator.traits.types-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1834)
|
||
|
||
*Alias template*: Alloc::rebind<T>::other if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Alloc::rebind<T>::other is valid and denotes a
|
||
type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")); otherwise,Alloc<T, Args> if Alloc is a class template instantiation
|
||
of the form Alloc<U, Args>, where Args is zero or more type arguments;
|
||
otherwise, the instantiation of rebind_alloc is ill-formed[.](#allocator.traits.types-11.sentence-1)
|
||
|
||
#### [20.2.9.3](#allocator.traits.members) Static member functions [[allocator.traits.members]](allocator.traits.members)
|
||
|
||
[ð](#lib:allocate,allocator_traits)
|
||
|
||
`static constexpr pointer allocate(Alloc& a, size_type n);
|
||
`
|
||
|
||
[1](#allocator.traits.members-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1851)
|
||
|
||
*Returns*: a.allocate(n)[.](#allocator.traits.members-1.sentence-1)
|
||
|
||
[ð](#lib:allocate,allocator_traits_)
|
||
|
||
`static constexpr pointer allocate(Alloc& a, size_type n, const_void_pointer hint);
|
||
`
|
||
|
||
[2](#allocator.traits.members-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1862)
|
||
|
||
*Returns*: a.allocate(n, hint) if that expression is well-formed; otherwise, a.allocate(n)[.](#allocator.traits.members-2.sentence-1)
|
||
|
||
[ð](#lib:allocate_at_least,allocator_traits)
|
||
|
||
`static constexpr allocation_result<pointer, size_type> allocate_at_least(Alloc& a, size_type n);
|
||
`
|
||
|
||
[3](#allocator.traits.members-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1873)
|
||
|
||
*Returns*: a.allocate_at_least(n) if that expression is well-formed;
|
||
otherwise, {a.allocate(n), n}[.](#allocator.traits.members-3.sentence-1)
|
||
|
||
[ð](#lib:deallocate,allocator_traits)
|
||
|
||
`static constexpr void deallocate(Alloc& a, pointer p, size_type n);
|
||
`
|
||
|
||
[4](#allocator.traits.members-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1885)
|
||
|
||
*Effects*: Calls a.deallocate(p, n)[.](#allocator.traits.members-4.sentence-1)
|
||
|
||
[5](#allocator.traits.members-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1889)
|
||
|
||
*Throws*: Nothing[.](#allocator.traits.members-5.sentence-1)
|
||
|
||
[ð](#lib:construct,allocator_traits)
|
||
|
||
`template<class T, class... Args>
|
||
static constexpr void construct(Alloc& a, T* p, Args&&... args);
|
||
`
|
||
|
||
[6](#allocator.traits.members-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1901)
|
||
|
||
*Effects*: Calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed;
|
||
otherwise, invokes construct_at(p, std::forward<Args>(args)...)[.](#allocator.traits.members-6.sentence-1)
|
||
|
||
[ð](#lib:destroy,allocator_traits)
|
||
|
||
`template<class T>
|
||
static constexpr void destroy(Alloc& a, T* p);
|
||
`
|
||
|
||
[7](#allocator.traits.members-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1915)
|
||
|
||
*Effects*: Calls a.destroy(p) if that call is well-formed; otherwise, invokesdestroy_at(p)[.](#allocator.traits.members-7.sentence-1)
|
||
|
||
[ð](#lib:max_size,allocator_traits)
|
||
|
||
`static constexpr size_type max_size(const Alloc& a) noexcept;
|
||
`
|
||
|
||
[8](#allocator.traits.members-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1927)
|
||
|
||
*Returns*: a.max_size() if that expression is well-formed; otherwise,numeric_limits<size_type>::max() / sizeof(value_type)[.](#allocator.traits.members-8.sentence-1)
|
||
|
||
[ð](#lib:select_on_container_copy_construction,allocator_traits)
|
||
|
||
`static constexpr Alloc select_on_container_copy_construction(const Alloc& rhs);
|
||
`
|
||
|
||
[9](#allocator.traits.members-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1939)
|
||
|
||
*Returns*: rhs.select_on_container_copy_construction() if that expression is
|
||
well-formed; otherwise, rhs[.](#allocator.traits.members-9.sentence-1)
|
||
|
||
#### [20.2.9.4](#allocator.traits.other) Other [[allocator.traits.other]](allocator.traits.other)
|
||
|
||
[1](#allocator.traits.other-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1947)
|
||
|
||
The class template allocation_result has
|
||
the template parameters, data members, and special members specified above[.](#allocator.traits.other-1.sentence-1)
|
||
|
||
It has no base classes or members other than those specified[.](#allocator.traits.other-1.sentence-2)
|
||
|
||
### [20.2.10](#default.allocator) The default allocator [[default.allocator]](default.allocator)
|
||
|
||
#### [20.2.10.1](#default.allocator.general) General [[default.allocator.general]](default.allocator.general)
|
||
|
||
[1](#default.allocator.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1956)
|
||
|
||
All specializations of the default allocator meet the
|
||
allocator completeness requirements ([[allocator.requirements.completeness]](allocator.requirements.completeness "16.4.4.6.2 Allocator completeness requirements"))[.](#default.allocator.general-1.sentence-1)
|
||
|
||
[ð](#lib:allocator)
|
||
|
||
namespace std {template<class T> class allocator {public:using value_type = T; using size_type = size_t; using difference_type = ptrdiff_t; using propagate_on_container_move_assignment = true_type; constexpr allocator() noexcept; constexpr allocator(const allocator&) noexcept; template<class U> constexpr allocator(const allocator<U>&) noexcept; constexpr ~allocator(); constexpr allocator& operator=(const allocator&) = default; constexpr T* allocate(size_t n); constexpr allocation_result<T*> allocate_at_least(size_t n); constexpr void deallocate(T* p, size_t n); };}
|
||
|
||
[2](#default.allocator.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1988)
|
||
|
||
allocator_traits<allocator<T>>::is_always_equal::value is true for any T[.](#default.allocator.general-2.sentence-1)
|
||
|
||
#### [20.2.10.2](#allocator.members) Members [[allocator.members]](allocator.members)
|
||
|
||
[1](#allocator.members-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1994)
|
||
|
||
Except for the destructor, member functions of the default allocator shall not introduce
|
||
data races ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races")) as a result of concurrent calls to those member
|
||
functions from different threads[.](#allocator.members-1.sentence-1)
|
||
|
||
Calls to these functions that allocate or deallocate a
|
||
particular unit of storage shall occur in a single total order, and each such
|
||
deallocation call shall happen before the next allocation (if any) in this order[.](#allocator.members-1.sentence-2)
|
||
|
||
[ð](#lib:allocate,allocator)
|
||
|
||
`constexpr T* allocate(size_t n);
|
||
`
|
||
|
||
[2](#allocator.members-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2007)
|
||
|
||
*Mandates*: T is not an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General"))[.](#allocator.members-2.sentence-1)
|
||
|
||
[3](#allocator.members-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2011)
|
||
|
||
*Returns*: A pointer to the initial element of an array of n T[.](#allocator.members-3.sentence-1)
|
||
|
||
[4](#allocator.members-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2015)
|
||
|
||
*Throws*: bad_array_new_length ifnumeric_limits<size_t>::max() / sizeof(T) < n, orbad_alloc if the storage cannot be obtained[.](#allocator.members-4.sentence-1)
|
||
|
||
[5](#allocator.members-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2021)
|
||
|
||
*Remarks*: The storage for the array
|
||
is obtained by calling ::operator new ([[new.delete]](new.delete "17.6.3 Storage allocation and deallocation")),
|
||
but it is unspecified when or how often this
|
||
function is called[.](#allocator.members-5.sentence-1)
|
||
|
||
This function starts the lifetime of the array object,
|
||
but not that of any of the array elements[.](#allocator.members-5.sentence-2)
|
||
|
||
[ð](#lib:allocate_at_least,allocator)
|
||
|
||
`constexpr allocation_result<T*> allocate_at_least(size_t n);
|
||
`
|
||
|
||
[6](#allocator.members-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2037)
|
||
|
||
*Mandates*: T is not an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General"))[.](#allocator.members-6.sentence-1)
|
||
|
||
[7](#allocator.members-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2041)
|
||
|
||
*Returns*: allocation_result<T*>{ptr, count},
|
||
where ptr is a pointer to
|
||
the initial element of an array of count T andcount ⥠n[.](#allocator.members-7.sentence-1)
|
||
|
||
[8](#allocator.members-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2048)
|
||
|
||
*Throws*: bad_array_new_length if numeric_limits<size_t>::max() / sizeof(T) < n,
|
||
or bad_alloc if the storage cannot be obtained[.](#allocator.members-8.sentence-1)
|
||
|
||
[9](#allocator.members-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2054)
|
||
|
||
*Remarks*: The storage for the array is obtained by calling ::operator new,
|
||
but it is unspecified when or how often this function is called[.](#allocator.members-9.sentence-1)
|
||
|
||
This function starts the lifetime of the array object,
|
||
but not that of any of the array elements[.](#allocator.members-9.sentence-2)
|
||
|
||
[ð](#lib:deallocate,allocator)
|
||
|
||
`constexpr void deallocate(T* p, size_t n);
|
||
`
|
||
|
||
[10](#allocator.members-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2068)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(10.1)](#allocator.members-10.1)
|
||
|
||
If p is memory that was obtained by a call to allocate_at_least,
|
||
let ret be the value returned andreq be the value passed as the first argument to that call[.](#allocator.members-10.1.sentence-1)
|
||
p is equal to ret.ptr andn is a value such that req ⤠n ⤠ret.count[.](#allocator.members-10.1.sentence-2)
|
||
|
||
- [(10.2)](#allocator.members-10.2)
|
||
|
||
Otherwise, p is a pointer value obtained from allocate[.](#allocator.members-10.2.sentence-1)
|
||
n equals the value passed as the first argument
|
||
to the invocation of allocate which returned p[.](#allocator.members-10.2.sentence-2)
|
||
|
||
[11](#allocator.members-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2083)
|
||
|
||
*Effects*: Deallocates the storage referenced by p[.](#allocator.members-11.sentence-1)
|
||
|
||
[12](#allocator.members-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2087)
|
||
|
||
*Remarks*: Uses::operator delete ([[new.delete]](new.delete "17.6.3 Storage allocation and deallocation")),
|
||
but it is unspecified
|
||
when this function is called[.](#allocator.members-12.sentence-1)
|
||
|
||
#### [20.2.10.3](#allocator.globals) Operators [[allocator.globals]](allocator.globals)
|
||
|
||
[ð](#lib:operator==,allocator)
|
||
|
||
`template<class T, class U>
|
||
constexpr bool operator==(const allocator<T>&, const allocator<U>&) noexcept;
|
||
`
|
||
|
||
[1](#allocator.globals-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2104)
|
||
|
||
*Returns*: true[.](#allocator.globals-1.sentence-1)
|
||
|
||
### [20.2.11](#specialized.addressof) addressof [[specialized.addressof]](specialized.addressof)
|
||
|
||
[ð](#lib:addressof)
|
||
|
||
`template<class T> constexpr T* addressof(T& r) noexcept;
|
||
`
|
||
|
||
[1](#specialized.addressof-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2117)
|
||
|
||
*Returns*: The actual address of the object or function referenced by r, even in the
|
||
presence of an overloaded operator&[.](#specialized.addressof-1.sentence-1)
|
||
|
||
[2](#specialized.addressof-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2122)
|
||
|
||
*Remarks*: An expression addressof(E) is a constant subexpression ([[defns.const.subexpr]](defns.const.subexpr "3.15 constant subexpression"))
|
||
if E is an lvalue constant subexpression[.](#specialized.addressof-2.sentence-1)
|
||
|
||
### [20.2.12](#c.malloc) C library memory allocation [[c.malloc]](c.malloc)
|
||
|
||
[1](#c.malloc-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2131)
|
||
|
||
[*Note [1](#c.malloc-note-1)*:
|
||
|
||
The header [<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2 Header <cstdlib> synopsis [cstdlib.syn]") declares the functions described in this subclause[.](#c.malloc-1.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#lib:aligned_alloc)
|
||
|
||
`void* aligned_alloc(size_t alignment, size_t size);
|
||
void* calloc(size_t nmemb, size_t size);
|
||
void* malloc(size_t size);
|
||
`
|
||
|
||
[2](#c.malloc-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2147)
|
||
|
||
*Effects*: These functions have the semantics specified in the C standard library[.](#c.malloc-2.sentence-1)
|
||
|
||
[3](#c.malloc-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2151)
|
||
|
||
*Remarks*: These functions do not attempt to allocate
|
||
storage by calling ::operator new() ([[new.delete]](new.delete "17.6.3 Storage allocation and deallocation"))[.](#c.malloc-3.sentence-1)
|
||
|
||
[4](#c.malloc-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2157)
|
||
|
||
These functions implicitly create objects ([[intro.object]](intro.object "6.8.2 Object model"))
|
||
in the returned region of storage and
|
||
return a pointer to a suitable created object[.](#c.malloc-4.sentence-1)
|
||
|
||
In the case of calloc,
|
||
the objects are created before the storage is zeroed[.](#c.malloc-4.sentence-2)
|
||
|
||
[ð](#lib:realloc)
|
||
|
||
`void* realloc(void* ptr, size_t size);
|
||
`
|
||
|
||
[5](#c.malloc-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2171)
|
||
|
||
*Preconditions*: free(ptr) has well-defined behavior[.](#c.malloc-5.sentence-1)
|
||
|
||
[6](#c.malloc-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2175)
|
||
|
||
*Effects*: If ptr is not null and size is zero,
|
||
the behavior is erroneous and the effects are implementation-defined[.](#c.malloc-6.sentence-1)
|
||
|
||
Otherwise, this function has the semantics specified in the C standard library[.](#c.malloc-6.sentence-2)
|
||
|
||
[7](#c.malloc-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2181)
|
||
|
||
*Remarks*: This function does not attempt to allocate storage
|
||
by calling ::operator new() ([[new.delete]](new.delete "17.6.3 Storage allocation and deallocation"))[.](#c.malloc-7.sentence-1)
|
||
|
||
When a non-null pointer is returned,
|
||
this function implicitly creates objects ([[intro.object]](intro.object "6.8.2 Object model"))
|
||
in the returned region of storage and
|
||
returns a pointer to a suitable created object[.](#c.malloc-7.sentence-2)
|
||
|
||
The objects are created before the storage is copied[.](#c.malloc-7.sentence-3)
|
||
|
||
[ð](#lib:free)
|
||
|
||
`void free(void* ptr);
|
||
`
|
||
|
||
[8](#c.malloc-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2198)
|
||
|
||
*Effects*: This function has the semantics specified in the C standard library[.](#c.malloc-8.sentence-1)
|
||
|
||
[9](#c.malloc-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L2202)
|
||
|
||
*Remarks*: This function does not attempt to
|
||
deallocate storage by calling::operator delete()[.](#c.malloc-9.sentence-1)
|
||
|
||
See also: ISO/IEC 9899:2024, 7.22.3
|