コンパイル時 FizzBuzz の出力

コンパイル時に FizzBuzz を処理して出力までするのは中3女子の嗜みですよね!
ということでこれを使って、とりあえずコンパイル時にも出力してみた。
Sprout のコードは適当。

[ソース]

#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/mpl/print.hpp>
#include <sprout/algorithm/transform.hpp>
#include <sprout/array.hpp>
#include <sprout/string.hpp>
#include <sprout/string/alias.hpp>
#include <sprout/operation.hpp>
#include <sprout/numeric/iota.hpp>
#include <sprout/pit.hpp>
#include <iostream>


template<std::size_t Index, typename String>
constexpr char
at_c(String const& str){
    return Index >= str.length()
         ? char('\0')
         : str[Index];
}

template<char... cs>
struct chars{};

#define STRING_MAX_LENGTH    10

#define DECL_AT_C(z, n, text)    \
    at_c<n>(text)

#define _(str)    \
    chars<BOOST_PP_ENUM(STRING_MAX_LENGTH, DECL_AT_C, str)>



template<typename String, typename Unique>
constexpr int
print(Unique){
    namespace m =boost::mpl;
    typedef typename m::print<std::tuple<String, Unique>>::type output;
    return 0;
}


struct fizzbuzz{
    typedef sprout::string<8> result_type;

    constexpr result_type
    operator ()(int n) const{
        return n % 15 == 0 ? sprout::to_string("FizzBuzz")
            : n %  3 == 0 ? sprout::to_string("Fizz")
            : n %  5 == 0 ? sprout::to_string("Buzz")
            : sprout::realign_to<result_type>(sprout::to_string(n));
    }
};


int
main(){
    typedef fizzbuzz::result_type string;

    static_assert(fizzbuzz()(1) == "1", "");
    static_assert(fizzbuzz()(2) == "2", "");
    static_assert(fizzbuzz()(3) == "Fizz", "");
    static_assert(fizzbuzz()(5) == "Buzz", "");
    static_assert(fizzbuzz()(15) == "FizzBuzz", "");

    constexpr auto source = sprout::iota(
        sprout::pit<sprout::array<int, 15> >(),
        1
    );

    constexpr auto result = sprout::transform(
        source.begin(),
        source.end(),
        sprout::pit<sprout::array<string, 15> >(),
        fizzbuzz()
    );
    
    // 出力
    print<_(result[0])>([]{});
    print<_(result[1])>([]{});
    print<_(result[2])>([]{});
    print<_(result[3])>([]{});
    print<_(result[4])>([]{});
    print<_(result[5])>([]{});
    print<_(result[6])>([]{});
    print<_(result[6])>([]{});
    print<_(result[7])>([]{});
    print<_(result[8])>([]{});
    print<_(result[9])>([]{});
    print<_(result[10])>([]{});
    print<_(result[11])>([]{});
    print<_(result[12])>([]{});
    print<_(result[13])>([]{});
    print<_(result[14])>([]{});

    return 0;
}

[出力]

In file included from \home\Dropbox\work\software\src\test\cpp\sprout\fizzbuzz3\main.cpp|32| 0:
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'1', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'1', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|80 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'2', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'2', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|81 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|82 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'4', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'4', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|83 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'B', 'u', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'B', 'u', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|84 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|85 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'7', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'7', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|86 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'7', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'7', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|87 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'8', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'8', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|88 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|89 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'B', 'u', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'B', 'u', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|90 col 26| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'1', '1', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'1', '1', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|91 col 27| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'F', 'i', 'z', 'z', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|92 col 27| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'1', '3', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'1', '3', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|93 col 27| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'1', '4', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'1', '4', '\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|94 col 27| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
|| boost/mpl/print.hpp: In instantiation of 'struct boost::mpl::print<std::tuple<chars<'F', 'i', 'z', 'z', 'B', 'u', 'z', 'z', '\000', '\000'>, main()::<lambda()> > >':
main.cpp|39 col 62| required from 'constexpr int print(Unique) [with String = chars<'F', 'i', 'z', 'z', 'B', 'u', 'z', 'z', '\000', '\000'>; Unique = main()::<lambda()>]'
main.cpp|95 col 27| required from here
boost/mpl/print.hpp|55 col 10| warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

見づらいと思うのは気のせいですよ?
print 関数にラムダ式を渡しているのは2回目以降も出力するためですね。
あと最近また Sprout が暴れているらしいので遊びたい欲が…!
コンパイル時のネタがなにかないかなー。

[コンパイラ]

  • g++ (GCC) 4.7.0 20120218 (experimental)