@@ -5,7 +5,7 @@ $(SPEC_S Template Mixins,
5
5
$(HEADERNAV_TOC)
6
6
7
7
$(P A $(I TemplateMixin) takes an arbitrary set of declarations from
8
- the body of a $(I TemplateDeclaration) and inserts them
8
+ the body of a $(GLINK2 template, TemplateDeclaration) and inserts them
9
9
into the current context.)
10
10
11
11
$(GRAMMAR
@@ -40,74 +40,81 @@ $(GNAME MixinQualifiedIdentifier):
40
40
is defined. It is analogous to cutting and pasting the body of
41
41
the template into the location of the mixin into a $(LINK2 #mixin_scope, nested scope). It is useful for injecting
42
42
parameterized $(SINGLEQUOTE boilerplate) code, as well as for creating
43
- templated nested functions, which is not possible with
43
+ templated nested functions, which is not always possible with
44
44
template instantiations.
45
45
)
46
46
47
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
47
48
------
49
+ import std.stdio : writeln;
50
+
48
51
mixin template Foo()
49
52
{
50
53
int x = 5;
51
54
}
52
55
53
- $(CODE_HIGHLIGHT mixin Foo;)
56
+ mixin Foo;
54
57
55
58
struct Bar
56
59
{
57
- $(CODE_HIGHLIGHT mixin Foo;)
60
+ mixin Foo;
58
61
}
59
62
60
- void test ()
63
+ void main ()
61
64
{
62
- writefln ("x = %d ", x); // prints 5
65
+ writeln ("x = ", x); // prints 5
63
66
{
64
67
Bar b;
65
68
int x = 3;
66
69
67
- writefln ("b.x = %d ", b.x); // prints 5
68
- writefln ("x = %d ", x); // prints 3
70
+ writeln ("b.x = ", b.x); // prints 5
71
+ writeln ("x = ", x); // prints 3
69
72
{
70
- $(CODE_HIGHLIGHT mixin Foo;)
71
- writefln ("x = %d ", x); // prints 5
73
+ mixin Foo;
74
+ writeln ("x = ", x); // prints 5
72
75
x = 4;
73
- writefln ("x = %d ", x); // prints 4
76
+ writeln ("x = ", x); // prints 4
74
77
}
75
- writefln ("x = %d ", x); // prints 3
78
+ writeln ("x = ", x); // prints 3
76
79
}
77
- writefln ("x = %d ", x); // prints 5
80
+ writeln ("x = ", x); // prints 5
78
81
}
79
82
------
80
-
81
- $(P Mixins can be parameterized:)
83
+ )
84
+ $(P Mixins can be
85
+ $(DDSUBLINK spec/template, template_type_parameters, parameterized):)
82
86
83
87
------
84
88
mixin template Foo(T)
85
89
{
86
90
T x = 5;
87
91
}
88
92
89
- $(CODE_HIGHLIGHT mixin Foo!(int);) // create x of type int
93
+ mixin Foo!(int); // create x of type int
90
94
------
91
95
92
96
$(P Mixins can add virtual functions to a class:)
93
97
98
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
94
99
------
100
+ import std.stdio : writeln;
101
+
95
102
mixin template Foo()
96
103
{
97
104
void func() { writeln("Foo.func()"); }
98
105
}
99
106
100
107
class Bar
101
108
{
102
- $(CODE_HIGHLIGHT mixin Foo;)
109
+ mixin Foo;
103
110
}
104
111
105
112
class Code : Bar
106
113
{
107
114
override void func() { writeln("Code.func()"); }
108
115
}
109
116
110
- void test ()
117
+ void main ()
111
118
{
112
119
Bar b = new Bar();
113
120
b.func(); // calls Foo.func()
@@ -116,6 +123,7 @@ void test()
116
123
b.func(); // calls Code.func()
117
124
}
118
125
------
126
+ )
119
127
120
128
$(P Mixins are evaluated in the scope of where they appear, not the scope
121
129
of the template declaration:)
@@ -131,12 +139,13 @@ mixin template Foo()
131
139
void test()
132
140
{
133
141
int y = 8;
134
- $(CODE_HIGHLIGHT mixin Foo;) // local y is picked up, not global y
142
+ mixin Foo; // local y is picked up, not global y
135
143
assert(abc() == 8);
136
144
}
137
145
------
138
146
139
- $(P Mixins can parameterize symbols using alias parameters:)
147
+ $(P Mixins can parameterize symbols using
148
+ $(DDSUBLINK spec/template, aliasparameters, alias parameters):)
140
149
141
150
------
142
151
mixin template Foo(alias b)
@@ -147,7 +156,7 @@ mixin template Foo(alias b)
147
156
void test()
148
157
{
149
158
int y = 8;
150
- $(CODE_HIGHLIGHT mixin Foo!(y);)
159
+ mixin Foo!(y);
151
160
assert(abc() == 8);
152
161
}
153
162
------
@@ -157,42 +166,44 @@ void test()
157
166
is in bold). A nested function is generated as well as a
158
167
delegate literal, these can be inlined by the compiler:)
159
168
169
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
160
170
------
161
- mixin template duffs_device(alias id1, alias id2, alias s)
171
+ import std.stdio : writeln;
172
+
173
+ mixin template duffs_device(alias low, alias high, alias fun)
162
174
{
163
175
void duff_loop()
164
176
{
165
- if (id1 < id2 )
177
+ if (low < high )
166
178
{
167
- typeof(id1) n = (id2 - id1 + 7) / 8;
168
- switch ((id2 - id1 ) % 8)
179
+ auto n = (high - low + 7) / 8;
180
+ switch ((high - low ) % 8)
169
181
{
170
- case 0: do { s (); goto case;
171
- case 7: s (); goto case;
172
- case 6: s (); goto case;
173
- case 5: s (); goto case;
174
- case 4: s (); goto case;
175
- case 3: s (); goto case;
176
- case 2: s (); goto case;
177
- case 1: s (); continue;
182
+ case 0: do { fun (); goto case;
183
+ case 7: fun (); goto case;
184
+ case 6: fun (); goto case;
185
+ case 5: fun (); goto case;
186
+ case 4: fun (); goto case;
187
+ case 3: fun (); goto case;
188
+ case 2: fun (); goto case;
189
+ case 1: fun (); continue;
178
190
default: assert(0, "Impossible");
179
191
} while (--n > 0);
180
192
}
181
193
}
182
194
}
183
195
}
184
196
185
- void foo() { writeln("foo"); }
186
-
187
- void test()
197
+ void main()
188
198
{
189
199
int i = 1;
190
200
int j = 11;
191
201
192
- mixin duffs_device!(i, j, $(CODE_HIGHLIGHT delegate { foo( ); }) );
202
+ mixin duffs_device!(i, j, delegate { writeln("foo" ); });
193
203
duff_loop(); // executes foo() 10 times
194
204
}
195
205
------
206
+ )
196
207
197
208
$(H2 $(LNAME2 mixin_scope, Mixin Scope))
198
209
@@ -202,7 +213,10 @@ $(H2 $(LNAME2 mixin_scope, Mixin Scope))
202
213
as a declaration in the surrounding scope, the surrounding declaration
203
214
overrides the mixin one:)
204
215
216
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
205
217
------
218
+ import std.stdio : writeln;
219
+
206
220
int x = 3;
207
221
208
222
mixin template Foo()
@@ -211,21 +225,25 @@ mixin template Foo()
211
225
int y = 5;
212
226
}
213
227
214
- $(CODE_HIGHLIGHT mixin Foo;)
228
+ mixin Foo;
215
229
int y = 3;
216
230
217
- void test ()
231
+ void main ()
218
232
{
219
- writefln ("x = %d ", x); // prints 3
220
- writefln ("y = %d ", y); // prints 3
233
+ writeln ("x = ", x); // prints 3
234
+ writeln ("y = ", y); // prints 3
221
235
}
222
236
------
237
+ )
223
238
224
239
$(P If two different mixins are put in the same scope, and each
225
240
define a declaration with the same name, there is an ambiguity
226
241
error when the declaration is referenced:)
227
242
243
+ $(SPEC_RUNNABLE_EXAMPLE_FAIL
228
244
------
245
+ import std.stdio : writeln;
246
+
229
247
mixin template Foo()
230
248
{
231
249
int x = 5;
@@ -238,24 +256,28 @@ mixin template Bar()
238
256
void func(long x) { }
239
257
}
240
258
241
- $(CODE_HIGHLIGHT mixin Foo;)
242
- $(CODE_HIGHLIGHT mixin Bar;)
259
+ mixin Foo;
260
+ mixin Bar;
243
261
244
- void test ()
262
+ void main ()
245
263
{
246
- import std.stdio : writefln;
247
- writefln("x = %d", x); // error, x is ambiguous
264
+ writeln("x = ", x); // error, x is ambiguous
248
265
func(1); // error, func is ambiguous
249
266
}
250
267
------
268
+ )
251
269
$(P The call to $(D func()) is ambiguous because
252
270
Foo.func and Bar.func are in different scopes.
253
271
)
254
272
255
273
$(P If a mixin has an $(I Identifier), it can be used to
256
274
disambiguate between conflicting symbols:
257
275
)
276
+
277
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
258
278
------
279
+ import std.stdio : writeln;
280
+
259
281
int x = 6;
260
282
261
283
mixin template Foo()
@@ -271,19 +293,20 @@ mixin template Bar()
271
293
void func() { }
272
294
}
273
295
274
- $(CODE_HIGHLIGHT mixin Foo F;)
275
- $(CODE_HIGHLIGHT mixin Bar B;)
296
+ mixin Foo F;
297
+ mixin Bar B;
276
298
277
- void test ()
299
+ void main ()
278
300
{
279
- writefln ("y = %d ", y); // prints 7
280
- writefln ("x = %d ", x); // prints 6
281
- writefln ("F.x = %d ", F.x); // prints 5
282
- writefln ("B.x = %d ", B.x); // prints 4
301
+ writeln ("y = ", y); // prints 7
302
+ writeln ("x = ", x); // prints 6
303
+ writeln ("F.x = ", F.x); // prints 5
304
+ writeln ("B.x = ", B.x); // prints 4
283
305
F.func(); // calls Foo.func
284
306
B.func(); // calls Bar.func
285
307
}
286
308
------
309
+ )
287
310
$(P Alias declarations can be used to overload together
288
311
functions declared in different mixins:)
289
312
@@ -301,8 +324,8 @@ mixin template Bar()
301
324
mixin Foo!() F;
302
325
mixin Bar!() B;
303
326
304
- $(CODE_HIGHLIGHT alias func = F.func;)
305
- $(CODE_HIGHLIGHT alias func = B.func;)
327
+ alias func = F.func;
328
+ alias func = B.func;
306
329
307
330
void main()
308
331
{
@@ -315,7 +338,10 @@ void main()
315
338
$(P A mixin has its own scope, even if a declaration is overridden
316
339
by the enclosing one:)
317
340
341
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
318
342
------
343
+ import std.stdio : writeln;
344
+
319
345
int x = 4;
320
346
321
347
mixin template Foo()
@@ -324,14 +350,15 @@ mixin template Foo()
324
350
int bar() { return x; }
325
351
}
326
352
327
- $(CODE_HIGHLIGHT mixin Foo;)
353
+ mixin Foo;
328
354
329
- void test ()
355
+ void main ()
330
356
{
331
- writefln ("x = %d ", x); // prints 4
332
- writefln ("bar() = %d ", bar()); // prints 5
357
+ writeln ("x = ", x); // prints 4
358
+ writeln ("bar() = ", bar()); // prints 5
333
359
}
334
360
------
361
+ )
335
362
336
363
$(SPEC_SUBNAV_PREV_NEXT template, Templates, contracts, Contract Programming)
337
364
)
0 commit comments