Sprout でコンパイル時 FizzBuzz
って事でやってみました。
counting_iterator が欲しくなりますね。
[ソース]
#define SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION #include <sprout/algorithm/transform.hpp> #include <sprout/array.hpp> #include <sprout/string.hpp> #include <sprout/string/alias.hpp> #include <sprout/operation.hpp> #include <iostream> template<typename Char> constexpr sprout::basic_string<Char, 1> to_string(Char c){ return sprout::push_front(sprout::to_string(""), c); } template<typename T, typename Result = sprout::string<16> > constexpr Result itoa_impl(T n){ return n <= 10 ? sprout::realign_to<Result>(::to_string(char('0' + n))) : sprout::realign_to<Result>(itoa_impl(n/10) + ::to_string(char('0' + n%10))); } template<typename T, typename Result = sprout::string<16>> constexpr Result itoa(T n){ return n < 0 ? sprout::realign_to<Result>(("-" + itoa_impl(-n))) : sprout::realign_to<Result>(itoa_impl(n)); } struct fizzbuzz{ typedef sprout::string<8> result_type; constexpr result_type operator ()(int n) const{ return n % 15 == 0 ? sprout::realign_to<result_type>(sprout::to_string("FizzBuzz")) : n % 3 == 0 ? sprout::realign_to<result_type>(sprout::to_string("Fizz")) : n % 5 == 0 ? sprout::realign_to<result_type>(sprout::to_string("Buzz")) : sprout::realign_to<result_type>(itoa(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::make_common_array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ); // 値から FizzBuzz の出力へ変換 constexpr sprout::array<string, 15> tmp{}; constexpr auto result = sprout::transform(source.begin(), source.end(), tmp, fizzbuzz()); // コンパイル時に計算結果を確認 constexpr auto fizzbuzz_result = sprout::make_common_array( sprout::realign_to<string>(sprout::to_string("1")), sprout::realign_to<string>(sprout::to_string("2")), sprout::realign_to<string>(sprout::to_string("Fizz")), sprout::realign_to<string>(sprout::to_string("4")), sprout::realign_to<string>(sprout::to_string("Buzz")), sprout::realign_to<string>(sprout::to_string("Fizz")), sprout::realign_to<string>(sprout::to_string("7")), sprout::realign_to<string>(sprout::to_string("8")), sprout::realign_to<string>(sprout::to_string("Fizz")), sprout::realign_to<string>(sprout::to_string("Buzz")), sprout::realign_to<string>(sprout::to_string("11")), sprout::realign_to<string>(sprout::to_string("Fizz")), sprout::realign_to<string>(sprout::to_string("13")), sprout::realign_to<string>(sprout::to_string("14")), sprout::realign_to<string>(sprout::to_string("FizzBuzz")) ); static_assert(result == fizzbuzz_result, ""); // 実行時に出力 for(auto&& str : result){ std::cout << str << ", " } return 0; }