Init
This commit is contained in:
311
cppdraft/allocator/uses/construction.md
Normal file
311
cppdraft/allocator/uses/construction.md
Normal file
@@ -0,0 +1,311 @@
|
||||
[allocator.uses.construction]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.uses.construction)
|
||||
|
||||
### 20.2.8 uses_allocator [[allocator.uses]](allocator.uses#construction)
|
||||
|
||||
#### 20.2.8.2 Uses-allocator construction [allocator.uses.construction]
|
||||
|
||||
[1](#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[.](#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[.](#1.sentence-2)
|
||||
|
||||
[2](#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)](#2.1)
|
||||
|
||||
If T does not use an allocator compatible with alloc,
|
||||
then alloc is ignored[.](#2.1.sentence-1)
|
||||
|
||||
- [(2.2)](#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[.](#2.2.sentence-1)
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
Otherwise, if T has a constructor invocable as T(args..., alloc) (trailing-allocator convention),
|
||||
then uses-allocator construction chooses this constructor form[.](#2.3.sentence-1)
|
||||
|
||||
[3](#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[.](#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[.](#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[.](#3.sentence-3)
|
||||
|
||||
[*Note [1](#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[.](#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](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1364)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is not a specialization of pair[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1368)
|
||||
|
||||
*Returns*: A tuple value determined as follows:
|
||||
|
||||
- [(5.1)](#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)...)[.](#5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#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)](#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)[.](#5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
Otherwise, the program is ill-formed[.](#5.4.sentence-1)
|
||||
|
||||
[*Note [2](#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[.](#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](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1407)
|
||||
|
||||
Let T1 be T::first_type[.](#6.sentence-1)
|
||||
|
||||
Let T2 be T::second_type[.](#6.sentence-2)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1411)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#7.sentence-1)
|
||||
|
||||
[8](#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](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1439)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#9.sentence-1)
|
||||
|
||||
[10](#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](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1460)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#11.sentence-1)
|
||||
|
||||
[12](#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](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1485)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#13.sentence-1)
|
||||
|
||||
[14](#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](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1510)
|
||||
|
||||
*Constraints*: remove_cv_t<T> is a specialization of pair[.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/memory.tex#L1514)
|
||||
|
||||
*Effects*: Equivalent to:return uses_allocator_construction_args<T>(alloc, piecewise_construct,
|
||||
forward_as_tuple(get<0>(std::move(pr))),
|
||||
forward_as_tuple(get<1>(std::move(pr))));
|
||||
|
||||
[ð](#lib:uses_allocator_construction_args______)
|
||||
|
||||
`template<class T, class Alloc, [pair-like](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") P>
|
||||
constexpr auto uses_allocator_construction_args(const Alloc& alloc, P&& p) noexcept;
|
||||
`
|
||||
|
||||
[17](#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[.](#17.sentence-1)
|
||||
|
||||
[18](#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](#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](#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)](#20.1)
|
||||
|
||||
remove_cvref_t<U> is a specialization of ranges::subrange, or
|
||||
|
||||
- [(20.2)](#20.2)
|
||||
|
||||
U does not satisfy [*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]") and
|
||||
the expression *FUN*(u) is not well-formed
|
||||
when considered as an unevaluated operand[.](#20.sentence-1)
|
||||
|
||||
[21](#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](#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[.](#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](#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](#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)...));
|
||||
39
cppdraft/allocator/uses/trait.md
Normal file
39
cppdraft/allocator/uses/trait.md
Normal file
@@ -0,0 +1,39 @@
|
||||
[allocator.uses.trait]
|
||||
|
||||
# 20 Memory management library [[mem]](./#mem)
|
||||
|
||||
## 20.2 Memory [[memory]](memory#allocator.uses.trait)
|
||||
|
||||
### 20.2.8 uses_allocator [[allocator.uses]](allocator.uses#trait)
|
||||
|
||||
#### 20.2.8.1 uses_allocator trait [allocator.uses.trait]
|
||||
|
||||
[ð](#lib:uses_allocator)
|
||||
|
||||
`template<class T, class Alloc> struct uses_allocator;
|
||||
`
|
||||
|
||||
[1](#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[.](#1.sentence-1)
|
||||
|
||||
Meets the [*Cpp17BinaryTypeTrait*](meta.rqmts#:Cpp17BinaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))[.](#1.sentence-2)
|
||||
|
||||
The implementation shall provide a definition that is
|
||||
derived from true_type if the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") T::allocator_type is valid and denotes a type ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) andis_convertible_v<Alloc, T::allocator_type> != false, otherwise it shall be
|
||||
derived from false_type[.](#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)](#1.1)
|
||||
|
||||
the first argument of a constructor has type allocator_arg_t and the
|
||||
second argument has type Alloc or
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
the last argument of a constructor has type Alloc[.](#1.sentence-4)
|
||||
Reference in New Issue
Block a user