Created
February 28, 2012 19:14
-
-
Save falgon/1934458 to your computer and use it in GitHub Desktop.
コンパイル時FizzBuzz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define BOOST_MPL_LIMIT_STRING_SIZE 128 | |
#include<iostream> | |
#include<boost/mpl/string.hpp> | |
#include<boost/mpl/fold.hpp> | |
#include<boost/mpl/size_t.hpp> | |
#include<boost/type_traits.hpp> | |
#include<boost/type_traits/conditional.hpp> | |
namespace mpl=boost::mpl; | |
template<int ac,int base,int exp> | |
struct power_core:power_core<ac*base,base,exp-1>{}; | |
template<int ac,int base> | |
struct power_core<ac,base,0>{ | |
enum : int{val=ac}; | |
}; | |
template<int base,int exp> | |
struct power:power_core<1,base,exp>{}; | |
template<int de,size_t i> | |
struct digits_core:digits_core<de+1,i/10>{}; | |
template<int de> | |
struct digits_core<de,0>{ | |
enum : int{val=de}; | |
}; | |
template<int i> | |
struct num_digits:digits_core<0,i>{}; | |
template<> | |
struct num_digits<0>{ | |
enum : int{val=1}; | |
}; | |
template<int i> | |
struct digit_to_char{ | |
enum : char{val=i+0x30}; | |
}; | |
template<size_t i,int place> | |
struct digit_at{ | |
enum : char{val=(i/power<10,place>::val)%10}; | |
}; | |
struct nullpo{ | |
enum : char{val='\0'}; | |
}; | |
template<size_t i,int place> | |
struct alt_char:digit_to_char<digit_at<i,place>::val>{}; | |
template<size_t i,int offset,int numDig,bool range> | |
struct offset_char_core_checked{}; | |
template<size_t i,int offset,int numDig> | |
struct offset_char_core_checked<i,offset,numDig,false>:nullpo{}; | |
template<size_t i,int offset,int numDig> | |
struct offset_char_core_checked<i,offset,numDig,true>:alt_char<i,(numDig-offset)-1>{}; | |
template<size_t i,int offset,int numDig> | |
struct offset_char_core:offset_char_core_checked<i,offset,numDig,offset< numDig>{}; | |
template<size_t i,int offset> | |
struct offset_char:offset_char_core<i,offset,num_digits<i>::val>{}; | |
template<size_t i> | |
struct IntToStr{ | |
static const char str[]; | |
typedef typename mpl::string< | |
offset_char<i, 0>::val, | |
offset_char<i, 1>::val, | |
offset_char<i, 2>::val, | |
offset_char<i, 3>::val, | |
offset_char<i, 4>::val, | |
offset_char<i, 5>::val, | |
nullpo::val>::type type; | |
}; | |
template<size_t i> | |
const char IntToStr<i>::str[]={ | |
offset_char<i, 0>::val, | |
offset_char<i, 1>::val, | |
offset_char<i, 2>::val, | |
offset_char<i, 3>::val, | |
offset_char<i, 4>::val, | |
offset_char<i, 5>::val, | |
offset_char<i, 6>::val, | |
offset_char<i, 7>::val, | |
offset_char<i, 8>::val, | |
offset_char<i, 9>::val, | |
nullpo::val | |
}; | |
template<class Str,class Str1> | |
struct concat:mpl::insert_range<Str,typename mpl::end<Str>::type,Str1>{}; | |
template<class Str,class Str1,typename Str2> | |
struct concat3:mpl::insert_range<Str,typename mpl::end<Str>::type,typename concat<Str1,Str2>::type>{}; | |
typedef typename mpl::string<'f','i','z','z'>::type fizz; | |
typedef typename mpl::string<'b','u','z','z'>::type buzz; | |
typedef typename mpl::string<'\r', '\n'>::type mpendl; | |
typedef typename concat<fizz, buzz>::type fizzbuzz; | |
template<int N> | |
struct FizzBuzz{ | |
typedef typename concat3<typename FizzBuzz<N-1>::type, | |
typename boost::conditional<!(N%15),typename fizzbuzz::type, | |
typename boost::conditional<!(N%3), typename fizz::type, | |
typename boost::conditional<!(N%5), typename buzz::type, | |
typename IntToStr<N>::type>::type | |
>::type | |
>::type, | |
typename mpendl::type | |
>::type type; | |
}; | |
template<> | |
struct FizzBuzz<1>{ | |
typedef mpl::string<'1','\r','\n'>::type type; | |
}; | |
int main() | |
{ | |
std::cout<<mpl::c_str<FizzBuzz<26>::type>::value<<std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
C++ language completely differs from the C language.