99 bottles of beer

明らかにもっと共通部分を括りだす事が出来るのですが、なんとなく暇つぶしに書いたという感じなので。99だとWandboxで出力制限に引っかかってしまったようなので、ボトルを9つに減らしました。

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/comparison/not_equal.hpp>
#include <boost/preprocessor/comparison/greater.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/repetition/for.hpp>
#include <boost/preprocessor/tuple/elem.hpp>

#define SEQ_IMPL_I(r, state) \
   BOOST_PP_NOT_EQUAL( \
      BOOST_PP_TUPLE_ELEM(2, 0, state), \
      BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(2, 1, state)) \
   )

#define SEQ_IMPL_II(r, state) \
   ( \
      BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(2, 0, state)), \
      BOOST_PP_TUPLE_ELEM(2, 1, state) \
   )

#define PRINT_I(x) \
x bottles of beer on the wall x bottles of beer. \
Take one down and pass it around x bottles of beer on the wall.

#define PRINT_II \
1 bottle of beer on the wall 1 bottle of beer. \
Take one down and pass it around no more bottles of beer on the wall.

#define PRINT_III \
No more bottles of beer on the wall no more bottles of beer. \
Go to the store and buy some more 99 bottles of beer on the wall.

#define COND(x) BOOST_PP_IF(BOOST_PP_GREATER(x, 1), PRINT_I(x), BOOST_PP_IIF(x, PRINT_II, PRINT_III))

#define SEQ(r, state) COND(BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(2, 0, state)))

#define BOTTLES BOOST_PP_FOR((10, 0), SEQ_IMPL_I, SEQ_IMPL_II, SEQ)

BOTTLES