From Jason Turner

[allocator.uses.construction]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpz48vmteq/{from.md → to.md} +173 -20
tmp/tmpz48vmteq/{from.md → to.md} RENAMED
@@ -1,23 +1,176 @@
1
  #### Uses-allocator construction <a id="allocator.uses.construction">[[allocator.uses.construction]]</a>
2
 
3
- *Uses-allocator construction* with allocator `Alloc` refers to the
4
- construction of an object `obj` of type `T`, using constructor arguments
5
- `v1, v2, ..., vN` of types `V1, V2, ..., VN`, respectively, and an
6
- allocator `alloc` of type `Alloc`, according to the following rules:
7
-
8
- - if `uses_allocator_v<T, Alloc>` is `false` and
9
- `is_constructible_v<T, V1, V2, ..., VN>` is `true`, then `obj` is
10
- initialized as `obj(v1, v2, ..., vN)`;
11
- - otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
12
- `is_constructible_v<T, allocator_arg_t, Alloc,` `V1, V2, ..., VN>` is
13
- `true`, then `obj` is initialized as `obj(allocator_arg, alloc, v1,
14
- v2, ..., vN)`;
15
- - otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
16
- `is_constructible_v<T, V1, V2, ..., VN, Alloc>` is `true`, then `obj`
17
- is initialized as `obj(v1, v2, ..., vN, alloc)`;
18
- - otherwise, the request for uses-allocator construction is ill-formed.
19
- \[*Note 1*: An error will result if `uses_allocator_v<T, Alloc>` is
20
- `true` but the specific constructor does not take an allocator. This
21
- definition prevents a silent failure to pass the allocator to an
22
- element. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
 
1
  #### Uses-allocator construction <a id="allocator.uses.construction">[[allocator.uses.construction]]</a>
2
 
3
+ *Uses-allocator construction* with allocator `alloc` and constructor
4
+ arguments `args...` refers to the construction of an object of type `T`
5
+ such that `alloc` is passed to the constructor of `T` if `T` uses an
6
+ allocator type compatible with `alloc`. When applied to the construction
7
+ of an object of type `T`, it is equivalent to initializing it with the
8
+ value of the expression `make_obj_using_allocator<T>(alloc, args...)`,
9
+ described below.
10
+
11
+ The following utility functions support three conventions for passing
12
+ `alloc` to a constructor:
13
+
14
+ - If `T` does not use an allocator compatible with `alloc`, then `alloc`
15
+ is ignored.
16
+ - Otherwise, if `T` has a constructor invocable as
17
+ `T(allocator_arg, alloc, args...)` (leading-allocator convention),
18
+ then uses-allocator construction chooses this constructor form.
19
+ - Otherwise, if `T` has a constructor invocable as `T(args..., alloc)`
20
+ (trailing-allocator convention), then uses-allocator construction
21
+ chooses this constructor form.
22
+
23
+ The `uses_allocator_construction_args` function template takes an
24
+ allocator and argument list and produces (as a tuple) a new argument
25
+ list matching one of the above conventions. Additionally, overloads are
26
+ provided that treat specializations of `pair` such that uses-allocator
27
+ construction is applied individually to the `first` and `second` data
28
+ members. The `make_obj_using_allocator` and
29
+ `uninitialized_construct_using_allocator` function templates apply the
30
+ modified constructor arguments to construct an object of type `T` as a
31
+ return value or in-place, respectively.
32
+
33
+ [*Note 1*: For `uses_allocator_construction_args` and
34
+ `make_obj_using_allocator`, type `T` is not deduced and must therefore
35
+ be specified explicitly by the caller. — *end note*]
36
+
37
+ ``` cpp
38
+ template<class T, class Alloc, class... Args>
39
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
40
+ Args&&... args) noexcept -> see below;
41
+ ```
42
+
43
+ *Constraints:* `T` is not a specialization of `pair`.
44
+
45
+ *Returns:* A `tuple` value determined as follows:
46
+
47
+ - If `uses_allocator_v<T, Alloc>` is `false` and
48
+ `is_constructible_v<T, Args...>` is `true`, return
49
+ `forward_as_tuple(std::forward<Args>(args)...)`.
50
+ - Otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
51
+ `is_constructible_v<T, allocator_arg_t, const Alloc&, Args...>` is
52
+ `true`, return
53
+ ``` cpp
54
+ tuple<allocator_arg_t, const Alloc&, Args&&...>(
55
+ allocator_arg, alloc, std::forward<Args>(args)...)
56
+ ```
57
+ - Otherwise, if `uses_allocator_v<T, Alloc>` is `true` and
58
+ `is_constructible_v<T, Args..., const Alloc&>` is `true`, return
59
+ `forward_as_tuple(std::forward<Args>(args)..., alloc)`.
60
+ - Otherwise, the program is ill-formed.
61
+
62
+ [*Note 1*: This definition prevents a silent failure to pass the
63
+ allocator to a constructor of a type for which
64
+ `uses_allocator_v<T, Alloc>` is `true`. — *end note*]
65
+
66
+ ``` cpp
67
+ template<class T, class Alloc, class Tuple1, class Tuple2>
68
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc, piecewise_construct_t,
69
+ Tuple1&& x, Tuple2&& y)
70
+ noexcept -> see below;
71
+ ```
72
+
73
+ *Constraints:* `T` is a specialization of `pair`.
74
+
75
+ *Effects:* For `T` specified as `pair<T1, T2>`, equivalent to:
76
+
77
+ ``` cpp
78
+ return make_tuple(
79
+ piecewise_construct,
80
+ apply([&alloc](auto&&... args1) {
81
+ return uses_allocator_construction_args<T1>(
82
+ alloc, std::forward<decltype(args1)>(args1)...);
83
+ }, std::forward<Tuple1>(x)),
84
+ apply([&alloc](auto&&... args2) {
85
+ return uses_allocator_construction_args<T2>(
86
+ alloc, std::forward<decltype(args2)>(args2)...);
87
+ }, std::forward<Tuple2>(y)));
88
+ ```
89
+
90
+ ``` cpp
91
+ template<class T, class Alloc>
92
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc) noexcept -> see below;
93
+ ```
94
+
95
+ *Constraints:* `T` is a specialization of `pair`.
96
+
97
+ *Effects:* Equivalent to:
98
+
99
+ ``` cpp
100
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
101
+ tuple<>{}, tuple<>{});
102
+ ```
103
+
104
+ ``` cpp
105
+ template<class T, class Alloc, class U, class V>
106
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
107
+ U&& u, V&& v) noexcept -> see below;
108
+ ```
109
+
110
+ *Constraints:* `T` is a specialization of `pair`.
111
+
112
+ *Effects:* Equivalent to:
113
+
114
+ ``` cpp
115
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
116
+ forward_as_tuple(std::forward<U>(u)),
117
+ forward_as_tuple(std::forward<V>(v)));
118
+ ```
119
+
120
+ ``` cpp
121
+ template<class T, class Alloc, class U, class V>
122
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
123
+ const pair<U,V>& pr) noexcept -> see below;
124
+ ```
125
+
126
+ *Constraints:* `T` is a specialization of `pair`.
127
+
128
+ *Effects:* Equivalent to:
129
+
130
+ ``` cpp
131
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
132
+ forward_as_tuple(pr.first),
133
+ forward_as_tuple(pr.second));
134
+ ```
135
+
136
+ ``` cpp
137
+ template<class T, class Alloc, class U, class V>
138
+ constexpr auto uses_allocator_construction_args(const Alloc& alloc,
139
+ pair<U,V>&& pr) noexcept -> see below;
140
+ ```
141
+
142
+ *Constraints:* `T` is a specialization of `pair`.
143
+
144
+ *Effects:* Equivalent to:
145
+
146
+ ``` cpp
147
+ return uses_allocator_construction_args<T>(alloc, piecewise_construct,
148
+ forward_as_tuple(std::move(pr).first),
149
+ forward_as_tuple(std::move(pr).second));
150
+ ```
151
+
152
+ ``` cpp
153
+ template<class T, class Alloc, class... Args>
154
+ constexpr T make_obj_using_allocator(const Alloc& alloc, Args&&... args);
155
+ ```
156
+
157
+ *Effects:* Equivalent to:
158
+
159
+ ``` cpp
160
+ return make_from_tuple<T>(uses_allocator_construction_args<T>(
161
+ alloc, std::forward<Args>(args)...));
162
+ ```
163
+
164
+ ``` cpp
165
+ template<class T, class Alloc, class... Args>
166
+ constexpr T* uninitialized_construct_using_allocator(T* p, const Alloc& alloc, Args&&... args);
167
+ ```
168
+
169
+ *Effects:* Equivalent to:
170
+
171
+ ``` cpp
172
+ return apply([&]<class... U>(U&&... xs) {
173
+ return construct_at(p, std::forward<U>(xs)...);
174
+ }, uses_allocator_construction_args<T>(alloc, std::forward<Args>(args)...));
175
+ ```
176