Skip to content

Commit f0c4323

Browse files
authored
[spec/template-mixin.dd] Tweak examples & make them runnable (#3211)
* [spec/template-mixin.dd] Tweak and make examples runnable Use writeln instead of writefln. Tweak Duff's device example. * Remove CODE_HIGHLIGHT breaking example tests * More CODE_HIGHLIGHT
1 parent ba9f289 commit f0c4323

File tree

1 file changed

+86
-59
lines changed

1 file changed

+86
-59
lines changed

spec/template-mixin.dd

Lines changed: 86 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
4851
mixin template Foo()
4952
{
5053
int x = 5;
5154
}
5255

53-
$(CODE_HIGHLIGHT mixin Foo;)
56+
mixin Foo;
5457

5558
struct 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
------
8488
mixin 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+
95102
mixin template Foo()
96103
{
97104
void func() { writeln("Foo.func()"); }
98105
}
99106

100107
class Bar
101108
{
102-
$(CODE_HIGHLIGHT mixin Foo;)
109+
mixin Foo;
103110
}
104111

105112
class 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()
131139
void 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
------
142151
mixin template Foo(alias b)
@@ -147,7 +156,7 @@ mixin template Foo(alias b)
147156
void 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+
206220
int x = 3;
207221

208222
mixin template Foo()
@@ -211,21 +225,25 @@ mixin template Foo()
211225
int y = 5;
212226
}
213227

214-
$(CODE_HIGHLIGHT mixin Foo;)
228+
mixin Foo;
215229
int 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+
229247
mixin 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+
259281
int x = 6;
260282

261283
mixin 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()
301324
mixin Foo!() F;
302325
mixin 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

307330
void 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+
319345
int x = 4;
320346

321347
mixin 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

Comments
 (0)