[allocator.uses] # 20 Memory management library [[mem]](./#mem) ## 20.2 Memory [[memory]](memory#allocator.uses) ### 20.2.8 uses_allocator [allocator.uses] #### [20.2.8.1](#trait) uses_allocator trait [[allocator.uses.trait]](allocator.uses.trait) [🔗](#lib:uses_allocator) `template struct uses_allocator; ` [1](#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[.](#trait-1.sentence-1) Meets the [*Cpp17BinaryTypeTrait*](meta.rqmts#:Cpp17BinaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#trait-1.sentence-2) The implementation shall provide a definition that is derived from true_type if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") T​::​allocator_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) andis_convertible_v != false, otherwise it shall be derived from false_type[.](#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)](#trait-1.1) the first argument of a constructor has type allocator_arg_t and the second argument has type Alloc or - [(1.2)](#trait-1.2) the last argument of a constructor has type Alloc[.](#trait-1.sentence-4) #### [20.2.8.2](#construction) Uses-allocator construction [[allocator.uses.construction]](allocator.uses.construction) [1](#construction-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1310) [*Uses-allocator construction*](#def:uses-allocator_construction "20.2.8.2 Uses-allocator construction [allocator.uses.construction]") with allocator alloc and constructor arguments args... refers to the construction of an object of type T such that alloc is passed to the constructor of T if T uses an allocator type compatible with alloc[.](#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(alloc, args...), described below[.](#construction-1.sentence-2) [2](#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)](#construction-2.1) If T does not use an allocator compatible with alloc, then alloc is ignored[.](#construction-2.1.sentence-1) - [(2.2)](#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[.](#construction-2.2.sentence-1) - [(2.3)](#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[.](#construction-2.3.sentence-1) [3](#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[.](#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[.](#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[.](#construction-3.sentence-3) [*Note [1](#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[.](#construction-3.sentence-4) — *end note*] [🔗](#lib:uses_allocator_construction_args) `template constexpr auto uses_allocator_construction_args(const Alloc& alloc, Args&&... args) noexcept; ` [4](#construction-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1364) *Constraints*: remove_cv_t is not a specialization of pair[.](#construction-4.sentence-1) [5](#construction-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1368) *Returns*: A tuple value determined as follows: - [(5.1)](#construction-5.1) If uses_allocator_v, Alloc> is false and is_constructible_v is true, return forward_as_tuple(std​::​forward(args)...)[.](#construction-5.1.sentence-1) - [(5.2)](#construction-5.2) Otherwise, if uses_allocator_v, Alloc> is true and is_constructible_v is true, returntuple( allocator_arg, alloc, std::forward(args)...) - [(5.3)](#construction-5.3) Otherwise, if uses_allocator_v, Alloc> is true and is_constructible_v is true, return forward_as_tuple(std​::​forward(args)..., alloc)[.](#construction-5.3.sentence-1) - [(5.4)](#construction-5.4) Otherwise, the program is ill-formed[.](#construction-5.4.sentence-1) [*Note [2](#construction-note-2)*: This definition prevents a silent failure to pass the allocator to a constructor of a type for whichuses_allocator_v is true[.](#construction-5.sentence-2) — *end note*] [🔗](#lib:uses_allocator_construction_args_) `template constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t, Tuple1&& x, Tuple2&& y) noexcept; ` [6](#construction-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1407) Let T1 be T​::​first_type[.](#construction-6.sentence-1) Let T2 be T​::​second_type[.](#construction-6.sentence-2) [7](#construction-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1411) *Constraints*: remove_cv_t is a specialization of pair[.](#construction-7.sentence-1) [8](#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( alloc, std::forward(args1)...); }, std::forward(x)), apply([&alloc](auto&&... args2) {return uses_allocator_construction_args( alloc, std::forward(args2)...); }, std::forward(y))); [🔗](#lib:uses_allocator_construction_args__) `template constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept; ` [9](#construction-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1439) *Constraints*: remove_cv_t is a specialization of pair[.](#construction-9.sentence-1) [10](#construction-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1443) *Effects*: Equivalent to:return uses_allocator_construction_args(alloc, piecewise_construct, tuple<>{}, tuple<>{}); [🔗](#lib:uses_allocator_construction_args___) `template constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u, V&& v) noexcept; ` [11](#construction-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1460) *Constraints*: remove_cv_t is a specialization of pair[.](#construction-11.sentence-1) [12](#construction-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1464) *Effects*: Equivalent to:return uses_allocator_construction_args(alloc, piecewise_construct, forward_as_tuple(std::forward(u)), forward_as_tuple(std::forward(v))); [🔗](#lib:uses_allocator_construction_args____) `template constexpr auto uses_allocator_construction_args(const Alloc& alloc, pair& pr) noexcept; template constexpr auto uses_allocator_construction_args(const Alloc& alloc, const pair& pr) noexcept; ` [13](#construction-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1485) *Constraints*: remove_cv_t is a specialization of pair[.](#construction-13.sentence-1) [14](#construction-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1489) *Effects*: Equivalent to:return uses_allocator_construction_args(alloc, piecewise_construct, forward_as_tuple(pr.first), forward_as_tuple(pr.second)); [🔗](#lib:uses_allocator_construction_args_____) `template constexpr auto uses_allocator_construction_args(const Alloc& alloc, pair&& pr) noexcept; template constexpr auto uses_allocator_construction_args(const Alloc& alloc, const pair&& pr) noexcept; ` [15](#construction-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1510) *Constraints*: remove_cv_t is a specialization of pair[.](#construction-15.sentence-1) [16](#construction-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1514) *Effects*: Equivalent to:return uses_allocator_construction_args(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 synopsis [tuple.syn]") P> constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept; ` [17](#construction-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1531) *Constraints*: remove_cv_t is a specialization of pair andremove_cvref_t

is not a specialization of ranges​::​subrange[.](#construction-17.sentence-1) [18](#construction-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1536) *Effects*: Equivalent to:return uses_allocator_construction_args(alloc, piecewise_construct, forward_as_tuple(get<0>(std::forward

(p))), forward_as_tuple(get<1>(std::forward

(p)))); [🔗](#lib:uses_allocator_construction_args_______) `template constexpr auto uses_allocator_construction_args(const Alloc& alloc, U&& u) noexcept; ` [19](#construction-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1553) Let *FUN* be the function template:templatevoid *FUN*(const pair&); [20](#construction-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1560) *Constraints*: remove_cv_t is a specialization of pair, and either: - [(20.1)](#construction-20.1) remove_cvref_t is a specialization of ranges​::​subrange, or - [(20.2)](#construction-20.2) U does not satisfy [*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header synopsis [tuple.syn]") and the expression *FUN*(u) is not well-formed when considered as an unevaluated operand[.](#construction-20.sentence-1) [21](#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; // *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_*)); }}; [22](#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[.](#construction-22.sentence-1) [🔗](#lib:make_obj_using_allocator) `template constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args); ` [23](#construction-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1610) *Effects*: Equivalent to:return make_from_tuple(uses_allocator_construction_args( alloc, std::forward(args)...)); [🔗](#lib:uninitialized_construct_using_allocator) `template constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args); ` [24](#construction-24) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1626) *Effects*: Equivalent to:return apply([&](U&&... xs) {return construct_at(p, std::forward(xs)...); }, uses_allocator_construction_args(alloc, std::forward(args)...));