1
1
Ddoc
2
2
3
- $(D_S Compile-time Argument Lists ,
3
+ $(D_S $(TITLE) ,
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 sequences 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
10
- compile-time algorithms that operate on types, symbols and expressions .
11
+ allow a programmer to operate on types, symbols and values, enabling the ability to define
12
+ compile-time algorithms that operate on types, symbols and values .
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 sequences 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 ).
17
- Using term "tuple" to mean compile-time lists is discouraged to avoid confusion, and if encountered
18
+ returned from functions are provided by $(REF Tuple, std, typecons).
19
+ Using the term "tuple" to mean compile-time sequences 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
- symbols (names) and expressions ( values) . One can check the length of this list
32
+ symbols (names) and values. One can check the length of this sequence
31
33
and access any individual element:
32
34
)
33
35
@@ -39,34 +41,36 @@ $(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 sequences 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
54
58
---
55
59
alias AliasSeq(T...) = T;
56
60
---
57
61
58
- $(P All it does is give a specific variadic argument list an externally accessible name so
62
+ $(P All it does is give a specific variadic argument sequence an externally accessible name so
59
63
that it can be worked with in any other context:
60
64
)
61
65
62
66
---
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]);
68
- // or work with a list directly
69
- pragma(msg, AliasSeq!("aaa", 0, double)[2]);
70
+ pragma(msg, Name[0]); // int
71
+ pragma(msg, Name[1]); // 42
72
+ // or work with a sequence directly
73
+ pragma(msg, AliasSeq!("aaa", 0, double)[2]); // double
70
74
---
71
75
72
76
$(H2 $(LNAME2 available-operations, Available operations))
@@ -92,27 +96,27 @@ $(H2 $(LNAME2 available-operations, Available operations))
92
96
93
97
$(H3 $(LNAME2 assignment, Assignment))
94
98
95
- $(P Works only if the list element is a symbol that refers to a mutable variable)
99
+ $(P Works only if the sequence element is a symbol that refers to a mutable variable)
96
100
97
101
---
98
102
import std.meta;
99
103
100
104
void main()
101
105
{
102
106
int x;
103
- alias List = AliasSeq!(10, x);
104
- List [1] = 42;
107
+ alias seq = AliasSeq!(10, x);
108
+ seq [1] = 42;
105
109
assert (x == 42);
106
- // List [0] = 42; // won't compile, can't assign to a constant
110
+ // seq [0] = 42; // won't compile, can't assign to a constant
107
111
}
108
112
---
109
113
110
114
$(H3 $(LNAME2 loops, Loops))
111
115
112
116
$(P D's $(LINK2 spec/statement.html#ForeachStatement, foreach statement) has special
113
- semantics when iterating over compile-time lists . It repeats the body of the loop
114
- for each of the list elements, with the loop iteration "variable" becoming an alias
115
- for each compile-time list element in turn.
117
+ semantics when iterating over compile-time sequences . It repeats the body of the loop
118
+ for each of the sequence elements, with the loop iteration symbol being an alias
119
+ for each compile-time sequence element in turn.
116
120
)
117
121
118
122
---
@@ -130,17 +134,19 @@ $(H2 $(LNAME2 available-operations, Available operations))
130
134
}
131
135
132
136
/* Prints:
133
-
134
137
int
135
138
string
136
139
void()
137
140
*/
138
141
---
139
142
143
+ $(P $(B Note:) $(DDSUBLINK version, staticforeach, Static foreach)
144
+ should be preferred in new code.)
145
+
140
146
$(H2 $(LNAME2 auto-expansion, Auto-expansion))
141
147
142
- $(P One less obvious property of compile-time argument lists is that when used
143
- as an argument to a function or template, they are automatically treated as a list
148
+ $(P One less obvious property of compile-time argument sequences is that when used
149
+ as an argument to a function or template, they are automatically treated as a sequence
144
150
of comma-separated arguments:
145
151
)
146
152
@@ -158,25 +164,29 @@ $(H2 $(LNAME2 auto-expansion, Auto-expansion))
158
164
$(P This will only print `int` during compilation because the last line gets rewritten
159
165
as `alias Dummy = Print0!(int, double)`. If auto-expansion didn't happen,
160
166
`AliasSeq!(int, double)` would be printed instead. This is an inherent part of
161
- the language semantics for variadic lists , and thus also preserved by `AliasSeq`.
167
+ the language semantics for variadic sequences , and thus also preserved by `AliasSeq`.
162
168
)
163
169
164
- $(H2 $(LNAME2 homogenous-lists, Homogenous lists ))
170
+ $(H2 $(LEGACY_LNAME2 homogenous-lists, homogenous-sequences, Homogenous sequences ))
165
171
166
- $(P An ` AliasSeq` that consist of only type or expression ( value) elements are
167
- commonly called "type lists " or "expression lists " respectively. The concept of
168
- a "symbol list " is rarely mentioned explicitly but fits the same pattern.
172
+ $(P An $(ALOCAL AliasSeq, AliasSeq) that consists of only type or value elements are
173
+ commonly called "type sequences " or "value sequences " respectively. The concept of
174
+ a "symbol sequence " is used less frequently but fits the same pattern.
169
175
)
170
176
171
- $(P It is possible to use homogenous type lists in declarations:)
177
+ $(H3 $(LNAME2 type-seq, Type sequences))
178
+
179
+ $(P It is possible to use homogenous type sequences in declarations:)
172
180
173
181
---
174
182
import std.meta;
175
183
alias Params = AliasSeq!(int, double, string);
176
184
void foo(Params); // void foo(int, double, string);
177
185
---
178
186
179
- $(P D supports a special variable declaration syntax where a type list acts as a type:)
187
+ $(H4 $(LNAME2 type-seq-instantiation, Type sequence instantiation))
188
+
189
+ $(P D supports a special variable declaration syntax where a type sequence acts as a type:)
180
190
181
191
---
182
192
import std.meta;
@@ -188,35 +198,72 @@ $(H2 $(LNAME2 homogenous-lists, Homogenous lists))
188
198
variables[1] = 42.0;
189
199
variables[2] = "just a normal variable";
190
200
}
191
-
192
- /* The compiler will rewrite such a declaration to something like this:
193
-
201
+ ---
202
+ $(P The compiler will rewrite such a declaration to something like this:)
203
+ ---
194
204
int __var1;
195
205
double __var2;
196
206
string __var3;
197
207
alias variables = AliasSeq!(__var1, __var2, __var3);
198
- */
199
208
---
200
209
201
- $(P This is also what happens when declaring a variadic template function:)
210
+ $(P So a type sequence instance is a kind of symbol sequence that only aliases
211
+ variables, known as an $(I lvalue sequence).)
212
+
213
+ $(P $(DDSUBLINK spec/template, variadic-templates, Variadic template functions)
214
+ use a type sequence instance for a function parameter:)
202
215
203
216
---
204
217
void foo(T...)(T args)
205
218
{
206
- // 'args' here is a compile-time list of symbols that
207
- // refer to underlying compiler-generated arguments
219
+ // 'T' is a type sequence of argument types.
220
+ // 'args' is an instance of T whose elements are the function parameters
221
+ static assert(is(typeof(args) == T));
222
+ args[0] = T[0].init;
208
223
}
209
224
---
210
225
211
- $(P It is possible to use expression lists with values of the same type to declare array literals:)
226
+ $(P $(B Note:) $(REF Tuple, std, typecons) wraps a type sequence instance,
227
+ preventing auto-expansion, and allowing it to be returned from functions.)
228
+
229
+ $(H3 $(LNAME2 value-seq, Value sequences))
230
+
231
+ $(P It is possible to use a sequence of values of the same type to declare an array literal:)
212
232
213
233
---
214
234
import std.meta;
215
- static assert ([ AliasSeq!(1, 2, 3) ] == [ 1, 2, 3 ]);
235
+ enum e = 3;
236
+ enum arr = [ AliasSeq!(1, 2, e) ];
237
+ static assert(arr == [ 1, 2, 3 ]);
238
+ ---
239
+
240
+ $(P The above sequence is an $(I rvalue sequence), as it is comprised only of literal values
241
+ and manifest constants. Each element's value is known at compile-time.)
242
+
243
+ $(P The following demonstrates use of an $(I lvalue sequence):)
216
244
---
245
+ import std.meta, std.algorithm;
246
+ auto x = 3, y = 7;
247
+ alias pair = AliasSeq!(x, y);
248
+ swap(pair);
249
+ assert(x == 7 && y == 3);
250
+ ---
251
+ $(P As above, such sequences may use $(ALOCAL assignment, assignment).)
252
+
253
+ $(H4 $(LNAME2 tupleof, Aggregate field sequences))
254
+
255
+ $(P $(DDSUBLINK spec/class, class_properties, `.tupleof`) is a
256
+ class/struct instance property that provides an lvalue sequence
257
+ of each field.)
258
+
259
+ $(H3 $(LNAME2 symbol-seq, Symbol sequences))
260
+
261
+ $(P A symbol sequence aliases any named symbol - types, variables, functions and templates -
262
+ but not literals.
263
+ Like an alias sequence, the kind of elements can be mixed.)
217
264
218
265
)
219
266
220
267
Macros:
221
- TITLE=Compile-time Argument Lists
268
+ TITLE=Compile-time Sequences
222
269
SUBNAV=$(SUBNAV_ARTICLES)
0 commit comments