/* Orion Lawlor's not-so-simple C++ programs.
A carefully obfuscated partial-specialization template
metaprogram to spit out the lyrics to "9 bottles of beer".
*/
#include <iostream>
#define i " of beer"<<r;}
#define j (char *r){std::cout<<
#define s <<" bottle"
#define L template<int O>void
#define J template<>void
L l j O s"s"i J l<1>j 1 s i J l<0>j
"No more"s"s"i L I(){l<O>(" on the wall,\n");
l<O>(",\nTake one down, pass it around,\n");
l<O-1>(" on the wall.\n\n");I<O-1>();}J I<0>(){}
main() {I<9>();}
/*<@>
<@> ******** Program output: ********
<@> 9 bottles of beer on the wall,
<@> 9 bottles of beer,
<@> Take one down, pass it around,
<@> 8 bottles of beer on the wall.
<@> 
<@> 8 bottles of beer on the wall,
<@> 8 bottles of beer,
<@> Take one down, pass it around,
<@> 7 bottles of beer on the wall.
<@> 
<@> 7 bottles of beer on the wall,
<@> 7 bottles of beer,
<@> Take one down, pass it around,
<@> 6 bottles of beer on the wall.
<@> 
<@> 6 bottles of beer on the wall,
<@> 6 bottles of beer,
<@> Take one down, pass it around,
<@> 5 bottles of beer on the wall.
<@> 
<@> 5 bottles of beer on the wall,
<@> 5 bottles of beer,
<@> Take one down, pass it around,
<@> 4 bottles of beer on the wall.
<@> 
<@> 4 bottles of beer on the wall,
<@> 4 bottles of beer,
<@> Take one down, pass it around,
<@> 3 bottles of beer on the wall.
<@> 
<@> 3 bottles of beer on the wall,
<@> 3 bottles of beer,
<@> Take one down, pass it around,
<@> 2 bottles of beer on the wall.
<@> 
<@> 2 bottles of beer on the wall,
<@> 2 bottles of beer,
<@> Take one down, pass it around,
<@> 1 bottle of beer on the wall.
<@> 
<@> 1 bottle of beer on the wall,
<@> 1 bottle of beer,
<@> Take one down, pass it around,
<@> No more bottles of beer on the wall.
<@> 
<@> */
