From Jason Turner

[allocator.uses]

Diff to HTML by rtfpessoa

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