@@ -36,6 +36,38 @@ auto f(T) {
36
36
};
37
37
----
38
38
39
+ === `apply_sequence`
40
+
41
+ A xref:type_traits.adoc#_type_list_and_value_list[`type_list` or a `value_list`]
42
+ can be unpacked and passed as individual template arguments with
43
+ `apply_sequence`. A function object whose call operator is a variadic function
44
+ template with no runtime arguments is called with the pack of arguments.
45
+
46
+ [source,cpp]
47
+ ----
48
+ using L1 = stdx::type_list<std::integral_constant<int, 1>,
49
+ std::integral_constant<int, 2>>;
50
+ int x = stdx::apply_sequence<L1>([&] <typename... Ts> () { return (0 + ... + Ts::value); });
51
+ // x is 3
52
+
53
+ using L2 = stdx::value_list<1, 2>;
54
+ int y = stdx::apply_sequence<L1>([&] <auto... Vs> () { return (0 + ... + Vs); });
55
+ // y is 3
56
+ ----
57
+
58
+ `apply_sequence` can also be used with a
59
+ https://en.cppreference.com/w/cpp/utility/integer_sequence[`std::integer_sequence`]:
60
+
61
+ [source,cpp]
62
+ ----
63
+ using L3 = stdx::make_index_sequence<3>;
64
+ auto y = stdx::apply_sequence<L3>([&] <auto... Vs> () { y += V; });
65
+ // y is 3
66
+ ----
67
+
68
+ NOTE: If the function iterates the pack by folding over `operator,` then
69
+ xref:type_traits.adoc#_template_for_each[`template_for_each`] is probably what you want.
70
+
39
71
=== `is_function_object_v`
40
72
41
73
`is_function_object_v` is a variable template that detects whether a type is a
@@ -52,6 +84,17 @@ stdx::is_function_object_v<decltype(lam)>; // true
52
84
stdx::is_function_object_v<decltype(gen_lam)>; // true
53
85
----
54
86
87
+ === `is_same_unqualified_v`
88
+
89
+ `is_same_unqualified_v` is a variable template that detects whether a two types
90
+ are the same are removing top-level cv-qualifications and references, if any.
91
+
92
+ [source,cpp]
93
+ ----
94
+ stdx::is_same_unqualified_v<int, int const&>; // true
95
+ stdx::is_same_unqualified_v<int, void>; // false
96
+ ----
97
+
55
98
=== `is_specialization_of_v`
56
99
57
100
`is_specialization_of_v` is a variable template that detects whether a type is a
@@ -112,31 +155,12 @@ NOTE: Detecting structurality of a type is not yet possible in the general case,
112
155
so there are certain structural types for which this trait will be `false`. In
113
156
practice those types should be rare, and there should be no false positives.
114
157
115
- === `type_or_t`
116
-
117
- `type_or_t` is an alias template that selects a type based on whether or not it
118
- passes a predicate. If not, a default is returned.
119
-
120
- [source,cpp]
121
- ----
122
- using A = int *;
123
- using T = stdx::type_or_t<std::is_pointer, A>; // A
124
-
125
- using B = int;
126
- using X = stdx::type_or_t<std::is_pointer, B>; // void (implicit default)
127
- using Y = stdx::type_or_t<std::is_pointer, B, float>; // float (explicit default)
128
- ----
129
-
130
- === `type_list` and `value_list`
131
-
132
- `type_list` is an empty `struct` templated over any number of types.
133
- `value_list` is an empty `struct` templated over any number of NTTPs.
134
-
135
158
=== `template_for_each`
136
159
137
- A `type_list` or a `value_list` can be iterated with `template_for_each`. A
138
- function object whose call operator is a unary function template with no runtime
139
- arguments is passed to each of these functions.
160
+ A xref:type_traits.adoc#_type_list_and_value_list[`type_list` or a `value_list`]
161
+ can be iterated with `template_for_each`. A function object whose call operator
162
+ is a unary function template with no runtime arguments is called with each
163
+ element of the list.
140
164
141
165
[source,cpp]
142
166
----
@@ -158,21 +182,31 @@ https://en.cppreference.com/w/cpp/utility/integer_sequence[`std::integer_sequenc
158
182
[source,cpp]
159
183
----
160
184
using L3 = stdx::make_index_sequence<3>;
161
- int y{};
185
+ std::size_t y{};
162
186
stdx::template_for_each<L3>([&] <auto V> () { y += V; });
163
187
// y is now 3
164
188
----
165
189
166
190
NOTE: A primary use case of `template_for_each` is to be able to use a list of
167
191
tag types without those types having to be complete.
168
192
169
- === `is_same_unqualified_v `
193
+ === `type_or_t `
170
194
171
- `is_same_unqualified_v ` is a variable template that detects whether a two types
172
- are the same are removing top-level cv-qualifications and references, if any .
195
+ `type_or_t ` is an alias template that selects a type based on whether or not it
196
+ passes a predicate. If not, a default is returned .
173
197
174
198
[source,cpp]
175
199
----
176
- stdx::is_same_unqualified_v<int, int const&>; // true
177
- stdx::is_same_unqualified_v<int, void>; // false
200
+ using A = int *;
201
+ using T = stdx::type_or_t<std::is_pointer, A>; // A
202
+
203
+ using B = int;
204
+ using X = stdx::type_or_t<std::is_pointer, B>; // void (implicit default)
205
+ using Y = stdx::type_or_t<std::is_pointer, B, float>; // float (explicit default)
178
206
----
207
+
208
+ === `type_list` and `value_list`
209
+
210
+ `type_list` is an empty `struct` templated over any number of types.
211
+ `value_list` is an empty `struct` templated over any number of NTTPs.
212
+
0 commit comments