1 // written by Don Clugston:
2 // https://www.digitalmars.com/d/archives/digitalmars/D/announce/4374.html
3 // http://www.99-bottles-of-beer.net/language-d-1212.html
5 // Generates the "99 bottles of beer" song at compile time,
6 // using the template metaprograming facilities of D.
7 // No executable is generated. No libraries are used.
8 // Illustrates template default values, template string value parameters,
9 // compile-time concatenation of constant strings, static if.
13 template decimaldigit(int n
) {
14 const string decimaldigit
= "0123456789"[n
..n
+1];
17 template itoa(ulong n
)
20 const string itoa
= decimaldigit
!(n
);
22 const string itoa
= itoa
!( n
/ 10L ) ~ decimaldigit
!( n
% 10L );
25 template showHowMany(int n
, string where
, bool needcapital
= false)
28 const string showHowMany
= itoa
!(n
) ~ " bottles of beer" ~ where
~ "\n";
29 else static if ( n
== 1 )
30 const string showHowMany
= "1 bottle of beer" ~ where
~ "\n";
31 else static if ( needcapital
)
32 const string showHowMany
= "No more bottles of beer" ~ where
~ "\n";
34 const string showHowMany
= "no more bottles of beer" ~ where
~ "\n";
37 template beer(int maxbeers
, int n
= maxbeers
)
40 const string beer
= showHowMany
!(n
, " on the wall,", true)
41 ~ showHowMany
!(n
, ".")
42 ~ "Take one down and pass it around," ~ "\n"
43 ~ showHowMany
!( n
- 1 , " on the wall.")
44 ~ "\n" ~ beer
!(maxbeers
, n
- 1); // recurse for subsequent verses.
46 const string beer
= showHowMany
!(n
, " on the wall,", true)
47 ~ showHowMany
!(n
, ".")
48 ~ "Go to the store and buy some more," ~ "\n"
49 ~ showHowMany
!( maxbeers
, " on the wall.");
52 enum expected
= `99 bottles of beer on the wall,
54 Take one down and pass it around,
55 98 bottles of beer on the wall.
57 98 bottles of beer on the wall,
59 Take one down and pass it around,
60 97 bottles of beer on the wall.
62 97 bottles of beer on the wall,
64 Take one down and pass it around,
65 96 bottles of beer on the wall.
67 96 bottles of beer on the wall,
69 Take one down and pass it around,
70 95 bottles of beer on the wall.
72 95 bottles of beer on the wall,
74 Take one down and pass it around,
75 94 bottles of beer on the wall.
77 94 bottles of beer on the wall,
79 Take one down and pass it around,
80 93 bottles of beer on the wall.
82 93 bottles of beer on the wall,
84 Take one down and pass it around,
85 92 bottles of beer on the wall.
87 92 bottles of beer on the wall,
89 Take one down and pass it around,
90 91 bottles of beer on the wall.
92 91 bottles of beer on the wall,
94 Take one down and pass it around,
95 90 bottles of beer on the wall.
97 90 bottles of beer on the wall,
99 Take one down and pass it around,
100 89 bottles of beer on the wall.
102 89 bottles of beer on the wall,
104 Take one down and pass it around,
105 88 bottles of beer on the wall.
107 88 bottles of beer on the wall,
109 Take one down and pass it around,
110 87 bottles of beer on the wall.
112 87 bottles of beer on the wall,
114 Take one down and pass it around,
115 86 bottles of beer on the wall.
117 86 bottles of beer on the wall,
119 Take one down and pass it around,
120 85 bottles of beer on the wall.
122 85 bottles of beer on the wall,
124 Take one down and pass it around,
125 84 bottles of beer on the wall.
127 84 bottles of beer on the wall,
129 Take one down and pass it around,
130 83 bottles of beer on the wall.
132 83 bottles of beer on the wall,
134 Take one down and pass it around,
135 82 bottles of beer on the wall.
137 82 bottles of beer on the wall,
139 Take one down and pass it around,
140 81 bottles of beer on the wall.
142 81 bottles of beer on the wall,
144 Take one down and pass it around,
145 80 bottles of beer on the wall.
147 80 bottles of beer on the wall,
149 Take one down and pass it around,
150 79 bottles of beer on the wall.
152 79 bottles of beer on the wall,
154 Take one down and pass it around,
155 78 bottles of beer on the wall.
157 78 bottles of beer on the wall,
159 Take one down and pass it around,
160 77 bottles of beer on the wall.
162 77 bottles of beer on the wall,
164 Take one down and pass it around,
165 76 bottles of beer on the wall.
167 76 bottles of beer on the wall,
169 Take one down and pass it around,
170 75 bottles of beer on the wall.
172 75 bottles of beer on the wall,
174 Take one down and pass it around,
175 74 bottles of beer on the wall.
177 74 bottles of beer on the wall,
179 Take one down and pass it around,
180 73 bottles of beer on the wall.
182 73 bottles of beer on the wall,
184 Take one down and pass it around,
185 72 bottles of beer on the wall.
187 72 bottles of beer on the wall,
189 Take one down and pass it around,
190 71 bottles of beer on the wall.
192 71 bottles of beer on the wall,
194 Take one down and pass it around,
195 70 bottles of beer on the wall.
197 70 bottles of beer on the wall,
199 Take one down and pass it around,
200 69 bottles of beer on the wall.
202 69 bottles of beer on the wall,
204 Take one down and pass it around,
205 68 bottles of beer on the wall.
207 68 bottles of beer on the wall,
209 Take one down and pass it around,
210 67 bottles of beer on the wall.
212 67 bottles of beer on the wall,
214 Take one down and pass it around,
215 66 bottles of beer on the wall.
217 66 bottles of beer on the wall,
219 Take one down and pass it around,
220 65 bottles of beer on the wall.
222 65 bottles of beer on the wall,
224 Take one down and pass it around,
225 64 bottles of beer on the wall.
227 64 bottles of beer on the wall,
229 Take one down and pass it around,
230 63 bottles of beer on the wall.
232 63 bottles of beer on the wall,
234 Take one down and pass it around,
235 62 bottles of beer on the wall.
237 62 bottles of beer on the wall,
239 Take one down and pass it around,
240 61 bottles of beer on the wall.
242 61 bottles of beer on the wall,
244 Take one down and pass it around,
245 60 bottles of beer on the wall.
247 60 bottles of beer on the wall,
249 Take one down and pass it around,
250 59 bottles of beer on the wall.
252 59 bottles of beer on the wall,
254 Take one down and pass it around,
255 58 bottles of beer on the wall.
257 58 bottles of beer on the wall,
259 Take one down and pass it around,
260 57 bottles of beer on the wall.
262 57 bottles of beer on the wall,
264 Take one down and pass it around,
265 56 bottles of beer on the wall.
267 56 bottles of beer on the wall,
269 Take one down and pass it around,
270 55 bottles of beer on the wall.
272 55 bottles of beer on the wall,
274 Take one down and pass it around,
275 54 bottles of beer on the wall.
277 54 bottles of beer on the wall,
279 Take one down and pass it around,
280 53 bottles of beer on the wall.
282 53 bottles of beer on the wall,
284 Take one down and pass it around,
285 52 bottles of beer on the wall.
287 52 bottles of beer on the wall,
289 Take one down and pass it around,
290 51 bottles of beer on the wall.
292 51 bottles of beer on the wall,
294 Take one down and pass it around,
295 50 bottles of beer on the wall.
297 50 bottles of beer on the wall,
299 Take one down and pass it around,
300 49 bottles of beer on the wall.
302 49 bottles of beer on the wall,
304 Take one down and pass it around,
305 48 bottles of beer on the wall.
307 48 bottles of beer on the wall,
309 Take one down and pass it around,
310 47 bottles of beer on the wall.
312 47 bottles of beer on the wall,
314 Take one down and pass it around,
315 46 bottles of beer on the wall.
317 46 bottles of beer on the wall,
319 Take one down and pass it around,
320 45 bottles of beer on the wall.
322 45 bottles of beer on the wall,
324 Take one down and pass it around,
325 44 bottles of beer on the wall.
327 44 bottles of beer on the wall,
329 Take one down and pass it around,
330 43 bottles of beer on the wall.
332 43 bottles of beer on the wall,
334 Take one down and pass it around,
335 42 bottles of beer on the wall.
337 42 bottles of beer on the wall,
339 Take one down and pass it around,
340 41 bottles of beer on the wall.
342 41 bottles of beer on the wall,
344 Take one down and pass it around,
345 40 bottles of beer on the wall.
347 40 bottles of beer on the wall,
349 Take one down and pass it around,
350 39 bottles of beer on the wall.
352 39 bottles of beer on the wall,
354 Take one down and pass it around,
355 38 bottles of beer on the wall.
357 38 bottles of beer on the wall,
359 Take one down and pass it around,
360 37 bottles of beer on the wall.
362 37 bottles of beer on the wall,
364 Take one down and pass it around,
365 36 bottles of beer on the wall.
367 36 bottles of beer on the wall,
369 Take one down and pass it around,
370 35 bottles of beer on the wall.
372 35 bottles of beer on the wall,
374 Take one down and pass it around,
375 34 bottles of beer on the wall.
377 34 bottles of beer on the wall,
379 Take one down and pass it around,
380 33 bottles of beer on the wall.
382 33 bottles of beer on the wall,
384 Take one down and pass it around,
385 32 bottles of beer on the wall.
387 32 bottles of beer on the wall,
389 Take one down and pass it around,
390 31 bottles of beer on the wall.
392 31 bottles of beer on the wall,
394 Take one down and pass it around,
395 30 bottles of beer on the wall.
397 30 bottles of beer on the wall,
399 Take one down and pass it around,
400 29 bottles of beer on the wall.
402 29 bottles of beer on the wall,
404 Take one down and pass it around,
405 28 bottles of beer on the wall.
407 28 bottles of beer on the wall,
409 Take one down and pass it around,
410 27 bottles of beer on the wall.
412 27 bottles of beer on the wall,
414 Take one down and pass it around,
415 26 bottles of beer on the wall.
417 26 bottles of beer on the wall,
419 Take one down and pass it around,
420 25 bottles of beer on the wall.
422 25 bottles of beer on the wall,
424 Take one down and pass it around,
425 24 bottles of beer on the wall.
427 24 bottles of beer on the wall,
429 Take one down and pass it around,
430 23 bottles of beer on the wall.
432 23 bottles of beer on the wall,
434 Take one down and pass it around,
435 22 bottles of beer on the wall.
437 22 bottles of beer on the wall,
439 Take one down and pass it around,
440 21 bottles of beer on the wall.
442 21 bottles of beer on the wall,
444 Take one down and pass it around,
445 20 bottles of beer on the wall.
447 20 bottles of beer on the wall,
449 Take one down and pass it around,
450 19 bottles of beer on the wall.
452 19 bottles of beer on the wall,
454 Take one down and pass it around,
455 18 bottles of beer on the wall.
457 18 bottles of beer on the wall,
459 Take one down and pass it around,
460 17 bottles of beer on the wall.
462 17 bottles of beer on the wall,
464 Take one down and pass it around,
465 16 bottles of beer on the wall.
467 16 bottles of beer on the wall,
469 Take one down and pass it around,
470 15 bottles of beer on the wall.
472 15 bottles of beer on the wall,
474 Take one down and pass it around,
475 14 bottles of beer on the wall.
477 14 bottles of beer on the wall,
479 Take one down and pass it around,
480 13 bottles of beer on the wall.
482 13 bottles of beer on the wall,
484 Take one down and pass it around,
485 12 bottles of beer on the wall.
487 12 bottles of beer on the wall,
489 Take one down and pass it around,
490 11 bottles of beer on the wall.
492 11 bottles of beer on the wall,
494 Take one down and pass it around,
495 10 bottles of beer on the wall.
497 10 bottles of beer on the wall,
499 Take one down and pass it around,
500 9 bottles of beer on the wall.
502 9 bottles of beer on the wall,
504 Take one down and pass it around,
505 8 bottles of beer on the wall.
507 8 bottles of beer on the wall,
509 Take one down and pass it around,
510 7 bottles of beer on the wall.
512 7 bottles of beer on the wall,
514 Take one down and pass it around,
515 6 bottles of beer on the wall.
517 6 bottles of beer on the wall,
519 Take one down and pass it around,
520 5 bottles of beer on the wall.
522 5 bottles of beer on the wall,
524 Take one down and pass it around,
525 4 bottles of beer on the wall.
527 4 bottles of beer on the wall,
529 Take one down and pass it around,
530 3 bottles of beer on the wall.
532 3 bottles of beer on the wall,
534 Take one down and pass it around,
535 2 bottles of beer on the wall.
537 2 bottles of beer on the wall,
539 Take one down and pass it around,
540 1 bottle of beer on the wall.
542 1 bottle of beer on the wall,
544 Take one down and pass it around,
545 no more bottles of beer on the wall.
547 No more bottles of beer on the wall,
548 no more bottles of beer.
549 Go to the store and buy some more,
550 99 bottles of beer on the wall.
553 static assert(beer
!(99) == expected
);