@@ -4,27 +4,29 @@ $(D_S Compile-time Argument Lists,
4
4
5
5
$(HEADERNAV_TOC)
6
6
7
- $(P Compile-time lists is an important metaprogramming concept that comes naturally
7
+ $(H2 $(LNAME2 Background, Background))
8
+
9
+ $(P Compile-time lists are an important metaprogramming concept that comes naturally
8
10
from D support for $(LINK2 variadic-function-templates.html, variadic templates). They
9
- allow a programmer to operate on types, symbols and expressions enabling the ability to define
11
+ allow a programmer to operate on types, symbols and expressions, enabling the ability to define
10
12
compile-time algorithms that operate on types, symbols and expressions.
11
13
)
12
14
13
- $(P For historical reasons those sometimes can be called tuples in documentation or compiler
14
- internals but don't get confused : this doesn 't have much in common with tuples that
15
+ $(P $(B Note:) For historical reasons these lists can sometimes be called tuples in documentation or compiler
16
+ internals, but don't get confused - they don 't have much in common with tuples that
15
17
commonly exist in other languages. Sequences of values of different types that can be
16
- returned from functions are provided by $(LINK2 phobos/std_typecons.html# .Tuple, std.typecons.Tuple).
18
+ returned from functions are provided by $(PHOBOS typecons, .Tuple, std.typecons.Tuple).
17
19
Using term "tuple" to mean compile-time lists is discouraged to avoid confusion, and if encountered
18
20
should result in a $(LINK2 https://issues.dlang.org, documentation bug report).
19
21
)
20
22
21
- $(P Consider this simple snippet :)
23
+ $(P Consider this simple variadic template :)
22
24
23
25
---
24
26
template Variadic(T...) { /* ... */ }
25
27
---
26
28
27
- $(P `T` here is variadic $(LINK2 spec/template.html#TemplateArgumentList, template argument list)
29
+ $(P `T` here is a $(DDSUBLINK spec/template, variadic-templates, TemplateParameterSequence),
28
30
which is a core language feature. It has its own special semantics,
29
31
and, from the programmer's point of view, is most similar to an array of compile-time entities - types,
30
32
symbols (names) and expressions (values). One can check the length of this list
@@ -39,15 +41,17 @@ $(HEADERNAV_TOC)
39
41
pragma(msg, T[1]);
40
42
}
41
43
42
- alias Dummy = Variadic!(int, 42);
44
+ alias dummy = Variadic!(int, 42);
43
45
// prints during compilation:
44
46
// int
45
47
// 42
46
48
---
47
49
48
- $(P However, the language itself does not provide any means to define such lists outside of
50
+ $(H2 $(LNAME2 AliasSeq, AliasSeq))
51
+
52
+ $(P The language itself does not provide any means to define such lists outside of
49
53
a template parameter declaration. Instead, there is a
50
- $(MREF_ALTTEXT simple utility, std, meta) provided by the D standard
54
+ $(MREF_ALTTEXT simple utility, std, meta) provided by the standard
51
55
library:
52
56
)
53
57
@@ -63,10 +67,10 @@ $(HEADERNAV_TOC)
63
67
import std.meta;
64
68
// can alias to some other name
65
69
alias Name = AliasSeq!(int, 42);
66
- pragma(msg, Name[0]);
67
- pragma(msg, Name[1]);
70
+ pragma(msg, Name[0]); // int
71
+ pragma(msg, Name[1]); // 42
68
72
// or work with a list directly
69
- pragma(msg, AliasSeq!("aaa", 0, double)[2]);
73
+ pragma(msg, AliasSeq!("aaa", 0, double)[2]); // double
70
74
---
71
75
72
76
$(H2 $(LNAME2 available-operations, Available operations))
@@ -137,6 +141,9 @@ $(H2 $(LNAME2 available-operations, Available operations))
137
141
*/
138
142
---
139
143
144
+ $(P $(B Note:) $(DDSUBLINK version, staticforeach, Static foreach)
145
+ should be preferred in new code.)
146
+
140
147
$(H2 $(LNAME2 auto-expansion, Auto-expansion))
141
148
142
149
$(P One less obvious property of compile-time argument lists is that when used
@@ -163,11 +170,13 @@ $(H2 $(LNAME2 auto-expansion, Auto-expansion))
163
170
164
171
$(H2 $(LNAME2 homogenous-lists, Homogenous lists))
165
172
166
- $(P An ` AliasSeq` that consist of only type or expression (value) elements are
173
+ $(P An $(ALOCAL AliasSeq, AliasSeq) that consists of only type or expression (value) elements are
167
174
commonly called "type lists" or "expression lists" respectively. The concept of
168
175
a "symbol list" is rarely mentioned explicitly but fits the same pattern.
169
176
)
170
177
178
+ $(H3 $(LNAME2 type-seq, Type lists))
179
+
171
180
$(P It is possible to use homogenous type lists in declarations:)
172
181
173
182
---
@@ -176,6 +185,8 @@ $(H2 $(LNAME2 homogenous-lists, Homogenous lists))
176
185
void foo(Params); // void foo(int, double, string);
177
186
---
178
187
188
+ $(H4 $(LNAME2 type-seq-instantiation, Type list instantiation))
189
+
179
190
$(P D supports a special variable declaration syntax where a type list acts as a type:)
180
191
181
192
---
@@ -188,33 +199,49 @@ $(H2 $(LNAME2 homogenous-lists, Homogenous lists))
188
199
variables[1] = 42.0;
189
200
variables[2] = "just a normal variable";
190
201
}
191
-
192
- /* The compiler will rewrite such a declaration to something like this:
193
-
202
+ ---
203
+ $(P The compiler will rewrite such a declaration to something like this:)
204
+ ---
194
205
int __var1;
195
206
double __var2;
196
207
string __var3;
197
208
alias variables = AliasSeq!(__var1, __var2, __var3);
198
- */
199
209
---
200
210
201
- $(P This is also what happens when declaring a variadic template function:)
211
+ $(P So a type list instance acts as a symbol list that only aliases
212
+ variables.)
213
+
214
+ $(P $(DDSUBLINK spec/template, variadic-templates, Variadic template functions)
215
+ use a type list instance for a function parameter:)
202
216
203
217
---
204
218
void foo(T...)(T args)
205
219
{
206
- // 'args' here is a compile-time list of symbols that
207
- // refer to underlying compiler-generated arguments
220
+ // 'T' is a type list of argument types.
221
+ // 'args' is an instance of T whose elements are the function parameters
222
+ static assert(is(typeof(args) == T));
223
+ args[0] = T[0].init;
208
224
}
209
225
---
210
226
227
+ $(P $(B Note:) $(PHOBOS typecons, .Tuple, std.typecons.Tuple) wraps a type list instance,
228
+ preventing auto-expansion, and allowing it to be returned from functions.)
229
+
230
+ $(H3 $(LNAME2 value-seq, Expression lists))
231
+
211
232
$(P It is possible to use expression lists with values of the same type to declare array literals:)
212
233
213
234
---
214
235
import std.meta;
215
236
static assert ([ AliasSeq!(1, 2, 3) ] == [ 1, 2, 3 ]);
216
237
---
217
238
239
+ $(H4 $(LNAME2 tupleof, Aggregate field lists))
240
+
241
+ $(P $(DDSUBLINK spec/class, class_properties, `.tupleof`) is a
242
+ class/struct instance property that provides an expression list
243
+ of fields.)
244
+
218
245
)
219
246
220
247
Macros:
0 commit comments