Skip to content

Instantly share code, notes, and snippets.

@randomphrase
Created August 7, 2011 11:33

Revisions

  1. randomphrase revised this gist Apr 16, 2014. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions 99bob.cpp
    Original file line number Diff line number Diff line change
    @@ -34,8 +34,8 @@ struct NumberInEnglish
    typedef char_<'-'> dash;

    typedef vector<
    string<>, // not used
    string<>, // not used
    string<>, // use Ones vector
    string<>, // use Teens vector
    string<'twen','ty'>,
    string<'thir','ty'>,
    string<'four','ty'>,
    @@ -76,8 +76,7 @@ struct NumberInEnglish
    typename copy<
    joint_view<
    typename push_back<typename at<Tens, divides<n, ten> >::type, dash>::type,
    typename at<Ones, modulus<n, ten> >::type
    >,
    typename at<Ones, modulus<n, ten> >::type>,
    back_inserter<string<> >
    >::type,
    typename at<Tens, divides<n, ten> >::type
  2. randomphrase revised this gist Aug 7, 2011. 1 changed file with 13 additions and 6 deletions.
    19 changes: 13 additions & 6 deletions 99bob.cpp
    Original file line number Diff line number Diff line change
    @@ -24,8 +24,11 @@
    using namespace boost::mpl;

    template <typename n>
    struct ToString
    struct NumberInEnglish
    {
    // Can't handle >= 100
    BOOST_MPL_ASSERT(( less<n, int_<100> > ));

    typedef int_<10> ten;
    typedef int_<20> twenty;
    typedef char_<'-'> dash;
    @@ -91,10 +94,10 @@ struct ToString
    >::type type;
    };

    BOOST_MPL_ASSERT(( equal< ToString<int_<4> >::type, string<'four'> > ));
    BOOST_MPL_ASSERT(( equal< ToString<int_<14> >::type, string<'four','teen'> > ));
    BOOST_MPL_ASSERT(( equal< ToString<int_<20> >::type, string<'twen','ty'> > ));
    BOOST_MPL_ASSERT(( equal< ToString<int_<44> >::type, string<'four','ty-f','our'> > ));
    BOOST_MPL_ASSERT(( equal< NumberInEnglish<int_<4> >::type, string<'four'> > ));
    BOOST_MPL_ASSERT(( equal< NumberInEnglish<int_<14> >::type, string<'four','teen'> > ));
    BOOST_MPL_ASSERT(( equal< NumberInEnglish<int_<20> >::type, string<'twen','ty'> > ));
    BOOST_MPL_ASSERT(( equal< NumberInEnglish<int_<44> >::type, string<'four','ty-f','our'> > ));

    template <typename n>
    struct CountBottles
    @@ -104,7 +107,7 @@ struct CountBottles
    typedef typename copy<
    joint_view<
    typename push_back<
    typename ToString<n>::type, char_<' '> >::type,
    typename NumberInEnglish<n>::type, char_<' '> >::type,
    typename if_<
    equal_to<n, int_<1> >,
    Bottle,
    @@ -115,6 +118,10 @@ struct CountBottles
    >::type type;
    };

    BOOST_MPL_ASSERT(( equal< CountBottles<int_<0> >::type, string<'no m','ore ','bott','les'> > ));
    BOOST_MPL_ASSERT(( equal< CountBottles<int_<1> >::type, string<'one ','bott','le'> > ));
    BOOST_MPL_ASSERT(( equal< CountBottles<int_<14> >::type, string<'four','teen',' bot','tles'> > ));

    template <typename n>
    struct Verse
    {
  3. randomphrase created this gist Aug 7, 2011.
    186 changes: 186 additions & 0 deletions 99bob.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,186 @@
    #include <boost/mpl/assert.hpp>
    #include <boost/mpl/at.hpp>
    #include <boost/mpl/back_inserter.hpp>
    #include <boost/mpl/copy.hpp>
    #include <boost/mpl/divides.hpp>
    #include <boost/mpl/empty_sequence.hpp>
    #include <boost/mpl/equal.hpp>
    #include <boost/mpl/equal_to.hpp>
    #include <boost/mpl/fold.hpp>
    #include <boost/mpl/for_each.hpp>
    #include <boost/mpl/if.hpp>
    #include <boost/mpl/joint_view.hpp>
    #include <boost/mpl/less.hpp>
    #include <boost/mpl/minus.hpp>
    #include <boost/mpl/modulus.hpp>
    #include <boost/mpl/push_back.hpp>
    #include <boost/mpl/range_c.hpp>
    #include <boost/mpl/string.hpp>
    #include <boost/mpl/transform.hpp>
    #include <boost/mpl/vector.hpp>

    #include <iostream>

    using namespace boost::mpl;

    template <typename n>
    struct ToString
    {
    typedef int_<10> ten;
    typedef int_<20> twenty;
    typedef char_<'-'> dash;

    typedef vector<
    string<>, // not used
    string<>, // not used
    string<'twen','ty'>,
    string<'thir','ty'>,
    string<'four','ty'>,
    string<'fift','y'>,
    string<'sixt','y'>,
    string<'seve','nty'>,
    string<'eigh','ty'>,
    string<'nine','ty'> > Tens;

    typedef vector<
    string<'no ','more'>,
    string<'one'>,
    string<'two'>,
    string<'thre','e'>,
    string<'four'>,
    string<'five'>,
    string<'six'>,
    string<'seve','n'>,
    string<'eigh','t'>,
    string<'nine'>
    > Ones;

    typedef vector<
    string<'ten'>,
    string<'elev','en'>,
    string<'twel','ve'>,
    string<'thir','teen'>,
    string<'four','teen'>,
    string<'fift','een'>,
    string<'sixt','een'>,
    string<'seve','ntee','n'>,
    string<'eigh','teen'>,
    string<'nine','teen'>
    > Teens;

    typedef if_<
    modulus<n, ten>,
    typename copy<
    joint_view<
    typename push_back<typename at<Tens, divides<n, ten> >::type, dash>::type,
    typename at<Ones, modulus<n, ten> >::type
    >,
    back_inserter<string<> >
    >::type,
    typename at<Tens, divides<n, ten> >::type
    > DoubleDigit;

    typedef typename if_<
    less<n, ten>,
    typename at<Ones, n>::type,
    typename if_<
    less<n, twenty>,
    typename at<Teens, minus<n, ten> >::type,
    typename DoubleDigit::type
    >::type
    >::type type;
    };

    BOOST_MPL_ASSERT(( equal< ToString<int_<4> >::type, string<'four'> > ));
    BOOST_MPL_ASSERT(( equal< ToString<int_<14> >::type, string<'four','teen'> > ));
    BOOST_MPL_ASSERT(( equal< ToString<int_<20> >::type, string<'twen','ty'> > ));
    BOOST_MPL_ASSERT(( equal< ToString<int_<44> >::type, string<'four','ty-f','our'> > ));

    template <typename n>
    struct CountBottles
    {
    typedef string<'bott','le'> Bottle;

    typedef typename copy<
    joint_view<
    typename push_back<
    typename ToString<n>::type, char_<' '> >::type,
    typename if_<
    equal_to<n, int_<1> >,
    Bottle,
    push_back<Bottle, char_<'s'> >::type
    >::type
    >,
    back_inserter<string<> >
    >::type type;
    };

    template <typename n>
    struct Verse
    {
    typedef string<'\n'> NL;
    typedef string<',\n'> CommaNL;
    typedef string<' of ','beer'> OfBeer;
    typedef string<' on ','the ','wall'> OnTheWall;
    typedef string<'take',' one',' dow','n, p','ass ','it a','roun','d,\n'> TakeOneDownPassItAround;

    typedef typename transform<
    vector<
    typename CountBottles<n>::type,
    OfBeer,
    OnTheWall,
    CommaNL,
    typename CountBottles<n>::type,
    OfBeer,
    CommaNL,
    TakeOneDownPassItAround,
    typename CountBottles<typename prior<n>::type>::type,
    OfBeer,
    NL,
    NL
    >,
    c_str<_1>
    >::type strings;
    };

    struct PrintValue
    {
    PrintValue(std::ostream& os) : os_(os) {}
    std::ostream& os_;

    template <typename T>
    void operator() (T t)
    {
    os_ << T::value;
    }
    };

    template <typename n>
    std::ostream& operator<< (std::ostream& os, Verse<n> verse)
    {
    boost::mpl::for_each<typename Verse<n>::strings>(PrintValue(os));
    };

    struct PrintTo
    {
    PrintTo(std::ostream& os) : os_(os) {}
    std::ostream& os_;

    template <typename T>
    void operator() (T t)
    {
    os_ << t;
    }
    };

    int main()
    {
    boost::mpl::for_each<
    range_c<int, 1, 100>,
    lambda<
    Verse<minus<int_<100>, _1> >
    >::type>(
    PrintTo(std::cout));

    return 0;
    }