// written by Don Clugston: // http://www.digitalmars.com/d/archives/digitalmars/D/announce/4374.html // http://www.99-bottles-of-beer.net/language-d-1212.html // Displays the "99 bottles of beer" song at compile time, // using the template metaprograming facilities of D. // No executable is generated. No libraries are used. // Illustrates template default values, template string value parameters, // compile-time concatenation of constant strings, static if. module bottles99; template decimaldigit(int n) { const string decimaldigit = "0123456789"[n..n+1]; } template itoa(ulong n) { static if ( n < 10L ) const string itoa = decimaldigit!(n); else const string itoa = itoa!( n / 10L ) ~ decimaldigit!( n % 10L ); } template showHowMany(int n, string where, bool needcapital = false) { static if ( n > 1 ) const string showHowMany = itoa!(n) ~ " bottles of beer" ~ where ~ "\n"; else static if ( n == 1 ) const string showHowMany = "1 bottle of beer" ~ where ~ "\n"; else static if ( needcapital ) const string showHowMany = "No more bottles of beer" ~ where ~ "\n"; else const string showHowMany = "no more bottles of beer" ~ where ~ "\n"; } template beer(int maxbeers, int n = maxbeers) { static if ( n > 0 ) const string beer = showHowMany!(n, " on the wall,", true) ~ showHowMany!(n, ".") ~ "Take one down and pass it around, " ~ "\n" ~ showHowMany!( n - 1 , " on the wall.") ~ "\n" ~ beer!(maxbeers, n - 1); // recurse for subsequent verses. else const string beer = showHowMany!(n, " on the wall,", true) ~ showHowMany!(n, ".") ~ "Go to the store and buy some more, " ~ "\n" ~ showHowMany!( maxbeers, " on the wall."); } pragma(msg, beer!(99));