@@ -27,15 +27,15 @@ $(GNAME MixinQualifiedIdentifier):
27
27
)
28
28
29
29
$(P A $(I TemplateMixin) can occur in declaration lists of modules,
30
- classes, structs, unions, and as a statement.
31
- The $(I MixinTemplateName) refers to a $(I TemplateDeclaration) or
30
+ classes, structs, unions, or as a statement.
31
+ $(I MixinTemplateName) must refer to a $(I TemplateDeclaration) or
32
32
$(I TemplateMixinDeclaration).
33
- If the $(I TemplateDeclaration) has no parameters, the mixin
34
- form that has no !($(I TemplateArgumentList))
35
- can be used.
33
+ If the $(I TemplateDeclaration) requires no parameters, $(I TemplateArguments)
34
+ can be omitted.
36
35
)
37
36
38
- $(P Unlike a template instantiation, a template mixin's body is evaluated
37
+ $(P Unlike a $(DDSUBLINK spec/template, instantiation_scope, template instantiation),
38
+ a template mixin's body is evaluated
39
39
within the scope where the mixin appears, not where the template declaration
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
@@ -44,6 +44,24 @@ $(GNAME MixinQualifiedIdentifier):
44
44
template instantiations.
45
45
)
46
46
47
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
48
+ ------
49
+ int y = 3;
50
+
51
+ mixin template Foo()
52
+ {
53
+ int abc() { return y; }
54
+ }
55
+
56
+ void test()
57
+ {
58
+ int y = 8;
59
+ mixin Foo; // local y is picked up, not global y
60
+ assert(abc() == 8);
61
+ }
62
+ ------
63
+ )
64
+
47
65
$(SPEC_RUNNABLE_EXAMPLE_RUN
48
66
------
49
67
import std.stdio : writeln;
@@ -81,8 +99,11 @@ void main()
81
99
}
82
100
------
83
101
)
102
+
103
+ $(H2 $(LNAME2 parameters, Mixin Parameters))
104
+
84
105
$(P Mixins can be
85
- $(DDSUBLINK spec/template, template_type_parameters , parameterized):)
106
+ $(DDSUBLINK spec/template, parameters , parameterized):)
86
107
87
108
------
88
109
mixin template Foo(T)
@@ -91,57 +112,6 @@ mixin template Foo(T)
91
112
}
92
113
93
114
mixin Foo!(int); // create x of type int
94
- ------
95
-
96
- $(P Mixins can add virtual functions to a class:)
97
-
98
- $(SPEC_RUNNABLE_EXAMPLE_RUN
99
- ------
100
- import std.stdio : writeln;
101
-
102
- mixin template Foo()
103
- {
104
- void func() { writeln("Foo.func()"); }
105
- }
106
-
107
- class Bar
108
- {
109
- mixin Foo;
110
- }
111
-
112
- class Code : Bar
113
- {
114
- override void func() { writeln("Code.func()"); }
115
- }
116
-
117
- void main()
118
- {
119
- Bar b = new Bar();
120
- b.func(); // calls Foo.func()
121
-
122
- b = new Code();
123
- b.func(); // calls Code.func()
124
- }
125
- ------
126
- )
127
-
128
- $(P Mixins are evaluated in the scope of where they appear, not the scope
129
- of the template declaration:)
130
-
131
- ------
132
- int y = 3;
133
-
134
- mixin template Foo()
135
- {
136
- int abc() { return y; }
137
- }
138
-
139
- void test()
140
- {
141
- int y = 8;
142
- mixin Foo; // local y is picked up, not global y
143
- assert(abc() == 8);
144
- }
145
115
------
146
116
147
117
$(P Mixins can parameterize symbols using
@@ -161,6 +131,8 @@ void test()
161
131
}
162
132
------
163
133
134
+ $(H3 $(LNAME2 example, Example))
135
+
164
136
$(P This example uses a mixin to implement a generic Duff's device
165
137
for an arbitrary statement (in this case, the arbitrary statement
166
138
is in bold). A nested function is generated as well as a
@@ -234,6 +206,31 @@ void main()
234
206
writeln("y = ", y); // prints 3
235
207
}
236
208
------
209
+ )
210
+
211
+ $(P A mixin has its own scope, even if a declaration is overridden
212
+ by the enclosing one:)
213
+
214
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
215
+ ------
216
+ import std.stdio : writeln;
217
+
218
+ int x = 4;
219
+
220
+ mixin template Foo()
221
+ {
222
+ int x = 5;
223
+ int bar() { return x; }
224
+ }
225
+
226
+ mixin Foo;
227
+
228
+ void main()
229
+ {
230
+ writeln("x = ", x); // prints 4
231
+ writeln("bar() = ", bar()); // prints 5
232
+ }
233
+ ------
237
234
)
238
235
239
236
$(P If two different mixins are put in the same scope, and each
@@ -267,9 +264,11 @@ void main()
267
264
------
268
265
)
269
266
$(P The call to $(D func()) is ambiguous because
270
- Foo.func and Bar.func are in different scopes.
267
+ ` Foo.func` and ` Bar.func` are in different scopes.
271
268
)
272
269
270
+ $(H3 $(LNAME2 resolving_ambiguities, Resolving Ambiguities))
271
+
273
272
$(P If a mixin has an $(I Identifier), it can be used to
274
273
disambiguate between conflicting symbols:
275
274
)
@@ -307,7 +306,8 @@ void main()
307
306
}
308
307
------
309
308
)
310
- $(P Alias declarations can be used to overload together
309
+ $(P Alias declarations can be used to form an
310
+ $(DDSUBLINK spec/function, overload-sets, overload set) of
311
311
functions declared in different mixins:)
312
312
313
313
-----
@@ -334,32 +334,41 @@ void main()
334
334
}
335
335
-----
336
336
337
+ $(H2 $(LNAME2 virtual_functions, Mixins and Virtual Functions))
337
338
338
- $(P A mixin has its own scope, even if a declaration is overridden
339
- by the enclosing one:)
339
+ $(P Mixins can add virtual functions to a class:)
340
340
341
341
$(SPEC_RUNNABLE_EXAMPLE_RUN
342
342
------
343
343
import std.stdio : writeln;
344
344
345
- int x = 4;
346
-
347
345
mixin template Foo()
348
346
{
349
- int x = 5;
350
- int bar() { return x; }
347
+ void func() { writeln("Foo.func()"); }
351
348
}
352
349
353
- mixin Foo;
350
+ class Bar
351
+ {
352
+ mixin Foo;
353
+ }
354
+
355
+ class Code : Bar
356
+ {
357
+ override void func() { writeln("Code.func()"); }
358
+ }
354
359
355
360
void main()
356
361
{
357
- writeln("x = ", x); // prints 4
358
- writeln("bar() = ", bar()); // prints 5
362
+ Bar b = new Bar();
363
+ b.func(); // calls Foo.func()
364
+
365
+ b = new Code();
366
+ b.func(); // calls Code.func()
359
367
}
360
368
------
361
369
)
362
370
371
+
363
372
$(SPEC_SUBNAV_PREV_NEXT template, Templates, contracts, Contract Programming)
364
373
)
365
374
0 commit comments