Files
2025-10-25 03:02:53 +03:00

1595 lines
114 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.2Header <memory> synopsis[memory.syn]") and some
of the contents of the header [<cstdlib>](cstdlib.syn#header:%3ccstdlib%3e "17.2.2Header <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.3Pointer traits")–[[specialized.addressof]](#specialized.addressof "20.2.11addressof") and [[specialized.algorithms]](specialized.algorithms "26.11Specialized <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.3Smart 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.3Qualified 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.3Qualified 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.1Header <compare> synopsis")namespace std {// [[pointer.traits]](#pointer.traits "20.2.3Pointer traits"), pointer traitstemplate<class Ptr> struct pointer_traits; // freestandingtemplate<class T> struct pointer_traits<T*>; // freestanding// [[pointer.conversion]](#pointer.conversion "20.2.4Pointer 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.5Pointer 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.6Explicit 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.7Allocator 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.8uses_­allocator"), uses_allocatortemplate<class T, class Alloc> struct uses_allocator; // freestanding// [[allocator.uses.trait]](#allocator.uses.trait "20.2.8.1uses_­allocator trait"), uses_allocatortemplate<class T, class Alloc>constexpr bool [uses_allocator_v](#lib:uses_allocator_v "20.2.2Header <memory> synopsis[memory.syn]") = uses_allocator<T, Alloc>::value; // freestanding// [[allocator.uses.construction]](#allocator.uses.construction "20.2.8.2Uses-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.2Header <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.9Allocator 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.10The 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.11addressof"), addressoftemplate<class T>constexpr T* addressof(T& r) noexcept; // freestandingtemplate<class T>const T* addressof(const T&&) = delete; // freestanding// [[specialized.algorithms]](specialized.algorithms "26.11Specialized <memory> algorithms"), specialized algorithms// [[special.mem.concepts]](special.mem.concepts "26.11.2Special memory concepts"), special memory conceptstemplate<class I>concept [*nothrow-input-iterator*](special.mem.concepts#concept:nothrow-input-iterator "26.11.2Special 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.2Special 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.2Special 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.2Special 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.2Special 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.2Special 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.2Special 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.2Special 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.2Special 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.2Special 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.2Special 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.5Parallel 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.5Parallel algorithm overloads") Size n); namespace ranges {template<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.2Special memory concepts[special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.2Special memory concepts[special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2Special memory concepts[special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.5Parallel 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.5Parallel 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.5Parallel algorithm overloads") Size n); namespace ranges {template<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.2Special memory concepts[special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.2Special memory concepts[special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2Special memory concepts[special.mem.concepts]") R>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I>requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12Concept 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.5Parallel 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.5Parallel 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.5Parallel algorithm overloads") Size n,
NoThrowForwardIterator result); namespace ranges {template<class I, class O>using [uninitialized_copy_result](#lib:uninitialized_copy_result "20.2.2Header <memory> synopsis[memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S1, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.6Other range refinements[range.refinements]") IR, [*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2Special memory concepts[special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.2Header <memory> synopsis[memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.1Preamble[algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S1, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*sized-random-access-range*](range.refinements#concept:sized-random-access-range "25.4.6Other range refinements[range.refinements]") IR, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2Special memory concepts[special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") I, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel 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.5Parallel 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.5Parallel algorithm overloads") NoThrowForwardIterator result); namespace ranges {template<class I, class O>using [uninitialized_move_result](#lib:uninitialized_move_result "20.2.2Header <memory> synopsis[memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S1, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.6Other range refinements[range.refinements]") IR, [*nothrow-forward-range*](special.mem.concepts#concept:nothrow-forward-range "26.11.2Special memory concepts[special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.2Header <memory> synopsis[memory.syn]") = in_out_result<I, O>; // freestandingtemplate<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9Concept input_­iterator[iterator.concept.input]") I, [*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.1Preamble[algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<I> S1, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S2>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*sized-random-access-range*](range.refinements#concept:sized-random-access-range "25.4.6Other range refinements[range.refinements]") IR, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2Special memory concepts[special.mem.concepts]") OR>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") I, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") O, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<O> S>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel 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.5Parallel 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.5Parallel algorithm overloads") Size n, const T& x); namespace ranges {template<[*nothrow-forward-iterator*](special.mem.concepts#concept:nothrow-forward-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.2Special memory concepts[special.mem.concepts]") R, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.2Special memory concepts[special.mem.concepts]") I, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2Special memory concepts[special.mem.concepts]") R, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, class T>requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.5Parallel algorithm overloads")}// [[specialized.construct]](specialized.construct "26.11.8construct_­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.9destroy"), 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.5Parallel 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.5Parallel algorithm overloads")namespace ranges {template<[destructible](concept.destructible#concept:destructible "18.4.10Concept destructible[concept.destructible]") T>constexpr void destroy_at(T* location) noexcept; // freestandingtemplate<[*nothrow-input-iterator*](special.mem.concepts#concept:nothrow-input-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sentinel-for*](special.mem.concepts#concept:nothrow-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S>requires [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.2Special memory concepts[special.mem.concepts]") R>requires [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.2Special memory concepts[special.mem.concepts]") I>requires [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I, [*nothrow-sized-sentinel-for*](special.mem.concepts#concept:nothrow-sized-sentinel-for "26.11.2Special memory concepts[special.mem.concepts]")<I> S>requires [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-sized-random-access-range*](special.mem.concepts#concept:nothrow-sized-random-access-range "26.11.2Special memory concepts[special.mem.concepts]") R>requires [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.5Parallel algorithm overloads")template<[*execution-policy*](algorithms.parallel.defns#concept:execution-policy "26.3.1Preamble[algorithms.parallel.defns]") Ep, [*nothrow-random-access-iterator*](special.mem.concepts#concept:nothrow-random-access-iterator "26.11.2Special memory concepts[special.mem.concepts]") I>requires [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.5Parallel algorithm overloads")}// [[unique.ptr]](unique.ptr "20.3.1Unique-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.4Concept 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.4Concept 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.1Class bad_­weak_­ptr"), class bad_weak_ptrclass bad_weak_ptr; // [[util.smartptr.shared]](util.smartptr.shared "20.3.2.2Class template shared_­ptr"), class template shared_ptrtemplate<class T> class shared_ptr; // [[util.smartptr.shared.create]](util.smartptr.shared.create "20.3.2.2.7Creation"), 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.8Comparison"), 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.9Specialized 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.10Casts"), 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.11get_­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.12I/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.3Class template weak_­ptr"), class template weak_ptrtemplate<class T> class weak_ptr; // [[util.smartptr.weak.spec]](util.smartptr.weak.spec "20.3.2.3.7Specialized 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.4Class template owner_­less"), class template owner_lesstemplate<class T = void> struct owner_less; // [[util.smartptr.owner.hash]](util.smartptr.owner.hash "20.3.2.5Struct owner_­hash"), struct owner_hashstruct owner_hash; // [[util.smartptr.owner.equal]](util.smartptr.owner.equal "20.3.2.6Struct owner_­equal"), struct owner_equalstruct owner_equal; // [[util.smartptr.enab]](util.smartptr.enab "20.3.2.7Class 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.3Smart 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.7Partial 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.1Class 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.2Function 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.3Class 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.4Function 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.1Class template indirect"), class template indirecttemplate<class T, class Allocator = allocator<T>>class indirect; // [[indirect.hash]](indirect.hash "20.4.1.10Hash support"), hash supporttemplate<class T, class Alloc> struct hash<indirect<T, Alloc>>; // [[polymorphic]](polymorphic "20.4.2Class 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.2Member 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.2Member 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.3Member 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.3Qualified names[expr.prim.id.qual]") Ptr::difference_type is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Ptr::rebind<U> is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.4Pointer 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.4Optional 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.6Qualification conversions")) to T,
where X has alignment N ([[basic.align]](basic.align "6.8.3Alignment"))[.](#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.6Qualification 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.1General"))
and not an incomplete type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1General"))[.](#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.4Compound 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.2Object 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.1General")) U is determined in the same manner as for a call
to bit_cast<U>(E) ([[bit.cast]](bit.cast "22.11.3Function 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.4Compound 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.10Equality 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.4Compound 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.2Object 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.4Lifetime"))[.](#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.4Compound 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.4Tuples")) 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.1General[allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1General"))[.](#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.2Requirements[meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2Requirements"))[.](#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.3Qualified names[expr.prim.id.qual]") T::allocator_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3Template 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.2Uses-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.2Header <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.2Header <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.3Qualified names[expr.prim.id.qual]") Alloc::pointer is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::const_pointer is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::void_pointer is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::const_void_pointer is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::difference_type is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::size_type is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::propagate_on_container_copy_assignment is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::propagate_on_container_move_assignment is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::propagate_on_container_swap is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::is_always_equal is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3Template 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.3Qualified names[expr.prim.id.qual]") Alloc::rebind<T>::other is valid and denotes a
type ([[temp.deduct]](temp.deduct "13.10.3Template 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.2Allocator 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.2Multi-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.1General"))[.](#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.3Storage 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.1General"))[.](#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.3Storage 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.15constant 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.2Header <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.3Storage 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.2Object 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.3Storage 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.2Object 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