@@ -5,7 +5,7 @@ $(SPEC_S Template Mixins,
55$(HEADERNAV_TOC)
66
77 $(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
99 into the current context.)
1010
1111$(GRAMMAR
@@ -40,74 +40,81 @@ $(GNAME MixinQualifiedIdentifier):
4040 is defined. It is analogous to cutting and pasting the body of
4141 the template into the location of the mixin into a $(LINK2 #mixin_scope, nested scope). It is useful for injecting
4242 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
4444 template instantiations.
4545 )
4646
47+ $(SPEC_RUNNABLE_EXAMPLE_RUN
4748------
49+ import std.stdio : writeln;
50+
4851mixin template Foo()
4952{
5053 int x = 5;
5154}
5255
53- $(CODE_HIGHLIGHT mixin Foo;)
56+ mixin Foo;
5457
5558struct Bar
5659{
57- $(CODE_HIGHLIGHT mixin Foo;)
60+ mixin Foo;
5861}
5962
60- void test ()
63+ void main ()
6164{
62- writefln ("x = %d ", x); // prints 5
65+ writeln ("x = ", x); // prints 5
6366 {
6467 Bar b;
6568 int x = 3;
6669
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
6972 {
70- $(CODE_HIGHLIGHT mixin Foo;)
71- writefln ("x = %d ", x); // prints 5
73+ mixin Foo;
74+ writeln ("x = ", x); // prints 5
7275 x = 4;
73- writefln ("x = %d ", x); // prints 4
76+ writeln ("x = ", x); // prints 4
7477 }
75- writefln ("x = %d ", x); // prints 3
78+ writeln ("x = ", x); // prints 3
7679 }
77- writefln ("x = %d ", x); // prints 5
80+ writeln ("x = ", x); // prints 5
7881}
7982------
80-
81- $(P Mixins can be parameterized:)
83+ )
84+ $(P Mixins can be
85+ $(DDSUBLINK spec/template, template_type_parameters, parameterized):)
8286
8387------
8488mixin template Foo(T)
8589{
8690 T x = 5;
8791}
8892
89- $(CODE_HIGHLIGHT mixin Foo!(int);) // create x of type int
93+ mixin Foo!(int); // create x of type int
9094------
9195
9296 $(P Mixins can add virtual functions to a class:)
9397
98+ $(SPEC_RUNNABLE_EXAMPLE_RUN
9499------
100+ import std.stdio : writeln;
101+
95102mixin template Foo()
96103{
97104 void func() { writeln("Foo.func()"); }
98105}
99106
100107class Bar
101108{
102- $(CODE_HIGHLIGHT mixin Foo;)
109+ mixin Foo;
103110}
104111
105112class Code : Bar
106113{
107114 override void func() { writeln("Code.func()"); }
108115}
109116
110- void test ()
117+ void main ()
111118{
112119 Bar b = new Bar();
113120 b.func(); // calls Foo.func()
@@ -116,6 +123,7 @@ void test()
116123 b.func(); // calls Code.func()
117124}
118125------
126+ )
119127
120128 $(P Mixins are evaluated in the scope of where they appear, not the scope
121129 of the template declaration:)
@@ -131,12 +139,13 @@ mixin template Foo()
131139void test()
132140{
133141 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
135143 assert(abc() == 8);
136144}
137145------
138146
139- $(P Mixins can parameterize symbols using alias parameters:)
147+ $(P Mixins can parameterize symbols using
148+ $(DDSUBLINK spec/template, aliasparameters, alias parameters):)
140149
141150------
142151mixin template Foo(alias b)
@@ -147,7 +156,7 @@ mixin template Foo(alias b)
147156void test()
148157{
149158 int y = 8;
150- $(CODE_HIGHLIGHT mixin Foo!(y);)
159+ mixin Foo!(y);
151160 assert(abc() == 8);
152161}
153162------
@@ -157,42 +166,44 @@ void test()
157166 is in bold). A nested function is generated as well as a
158167 delegate literal, these can be inlined by the compiler:)
159168
169+ $(SPEC_RUNNABLE_EXAMPLE_RUN
160170------
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)
162174{
163175 void duff_loop()
164176 {
165- if (id1 < id2 )
177+ if (low < high )
166178 {
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)
169181 {
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;
178190 default: assert(0, "Impossible");
179191 } while (--n > 0);
180192 }
181193 }
182194 }
183195}
184196
185- void foo() { writeln("foo"); }
186-
187- void test()
197+ void main()
188198{
189199 int i = 1;
190200 int j = 11;
191201
192- mixin duffs_device!(i, j, $(CODE_HIGHLIGHT delegate { foo( ); }) );
202+ mixin duffs_device!(i, j, delegate { writeln("foo" ); });
193203 duff_loop(); // executes foo() 10 times
194204}
195205------
206+ )
196207
197208$(H2 $(LNAME2 mixin_scope, Mixin Scope))
198209
@@ -202,7 +213,10 @@ $(H2 $(LNAME2 mixin_scope, Mixin Scope))
202213 as a declaration in the surrounding scope, the surrounding declaration
203214 overrides the mixin one:)
204215
216+ $(SPEC_RUNNABLE_EXAMPLE_RUN
205217------
218+ import std.stdio : writeln;
219+
206220int x = 3;
207221
208222mixin template Foo()
@@ -211,21 +225,25 @@ mixin template Foo()
211225 int y = 5;
212226}
213227
214- $(CODE_HIGHLIGHT mixin Foo;)
228+ mixin Foo;
215229int y = 3;
216230
217- void test ()
231+ void main ()
218232{
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
221235}
222236------
237+ )
223238
224239 $(P If two different mixins are put in the same scope, and each
225240 define a declaration with the same name, there is an ambiguity
226241 error when the declaration is referenced:)
227242
243+ $(SPEC_RUNNABLE_EXAMPLE_FAIL
228244------
245+ import std.stdio : writeln;
246+
229247mixin template Foo()
230248{
231249 int x = 5;
@@ -238,24 +256,28 @@ mixin template Bar()
238256 void func(long x) { }
239257}
240258
241- $(CODE_HIGHLIGHT mixin Foo;)
242- $(CODE_HIGHLIGHT mixin Bar;)
259+ mixin Foo;
260+ mixin Bar;
243261
244- void test ()
262+ void main ()
245263{
246- import std.stdio : writefln;
247- writefln("x = %d", x); // error, x is ambiguous
264+ writeln("x = ", x); // error, x is ambiguous
248265 func(1); // error, func is ambiguous
249266}
250267------
268+ )
251269 $(P The call to $(D func()) is ambiguous because
252270 Foo.func and Bar.func are in different scopes.
253271 )
254272
255273 $(P If a mixin has an $(I Identifier), it can be used to
256274 disambiguate between conflicting symbols:
257275 )
276+
277+ $(SPEC_RUNNABLE_EXAMPLE_RUN
258278------
279+ import std.stdio : writeln;
280+
259281int x = 6;
260282
261283mixin template Foo()
@@ -271,19 +293,20 @@ mixin template Bar()
271293 void func() { }
272294}
273295
274- $(CODE_HIGHLIGHT mixin Foo F;)
275- $(CODE_HIGHLIGHT mixin Bar B;)
296+ mixin Foo F;
297+ mixin Bar B;
276298
277- void test ()
299+ void main ()
278300{
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
283305 F.func(); // calls Foo.func
284306 B.func(); // calls Bar.func
285307}
286308------
309+ )
287310 $(P Alias declarations can be used to overload together
288311 functions declared in different mixins:)
289312
@@ -301,8 +324,8 @@ mixin template Bar()
301324mixin Foo!() F;
302325mixin Bar!() B;
303326
304- $(CODE_HIGHLIGHT alias func = F.func;)
305- $(CODE_HIGHLIGHT alias func = B.func;)
327+ alias func = F.func;
328+ alias func = B.func;
306329
307330void main()
308331{
@@ -315,7 +338,10 @@ void main()
315338 $(P A mixin has its own scope, even if a declaration is overridden
316339 by the enclosing one:)
317340
341+ $(SPEC_RUNNABLE_EXAMPLE_RUN
318342------
343+ import std.stdio : writeln;
344+
319345int x = 4;
320346
321347mixin template Foo()
@@ -324,14 +350,15 @@ mixin template Foo()
324350 int bar() { return x; }
325351}
326352
327- $(CODE_HIGHLIGHT mixin Foo;)
353+ mixin Foo;
328354
329- void test ()
355+ void main ()
330356{
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
333359}
334360------
361+ )
335362
336363$(SPEC_SUBNAV_PREV_NEXT template, Templates, contracts, Contract Programming)
337364)
0 commit comments