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

344 lines
14 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.

[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<class T, class Alloc> 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.2Requirements[meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2Requirements"))[.](#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[.](#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.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[.](#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[.](#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<class T, class Alloc, class... Args>
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<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<remove_cv_t<T>, Alloc> is false and is_constructible_v<T, Args...> is true,
return forward_as_tuple(std::forward<Args>(args)...)[.](#construction-5.1.sentence-1)
- [(5.2)](#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)](#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)[.](#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<T, Alloc> is true[.](#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](#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<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<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](#construction-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1439)
*Constraints*: remove_cv_t<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<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](#construction-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1460)
*Constraints*: remove_cv_t<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<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](#construction-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1485)
*Constraints*: remove_cv_t<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<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](#construction-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1510)
*Constraints*: remove_cv_t<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<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](#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[.](#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<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](#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](#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)](#construction-20.1)
remove_cvref_t<U> 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.2Header <tuple> 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<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](#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<class T, class Alloc, class... Args>
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<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](#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)...));