Created
September 22, 2010 17:13
-
-
Save NeoCat/592093 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#include <iostream> | |
using namespace std; | |
namespace vtstring { | |
// 文字列を表す可変引数テンプレート | |
template <char... a> struct vtstring; | |
template <char a, char... b> | |
struct vtstring<a, b...> | |
{ | |
static const int size = 1 + vtstring<b...>::size; // サイズ | |
// C文字列を返す関数 (定数はダメ。初期化リスト未サポートのため?) | |
static const char* c_str() { | |
static const char ret[] = {a,b...,0}; return ret; | |
} | |
}; | |
// NULL | |
template <> | |
struct vtstring<> | |
{ | |
static const int size = 0; | |
static const char* c_str() { return ""; } | |
}; | |
// 文字列の再帰的結合 | |
template <class A, class... B> | |
struct join; | |
// 再帰 | |
template <class A, class B, class... C> | |
struct join<A, B, C...> | |
{ | |
typedef typename join<typename join<A,B>::result, | |
C...>::result result; | |
}; | |
// 結合 | |
template <char... a, char... b> | |
struct join<vtstring<a...>, vtstring<b...>> | |
{ | |
typedef vtstring<a..., b...> result; | |
}; | |
// 数値→文字列変換 | |
template <int n> | |
struct from_int | |
{ // 10以上の場合 | |
typedef typename from_int<n/10>::result tens; | |
typedef typename from_int<n%10>::result ones; | |
typedef typename join<tens, ones>::result result; | |
}; | |
// 10未満の場合 | |
#define DEF_FROM_INT(N) \ | |
template <> struct from_int<N> { typedef vtstring<N+'0'> result; } | |
DEF_FROM_INT(0); | |
DEF_FROM_INT(1); | |
DEF_FROM_INT(2); | |
DEF_FROM_INT(3); | |
DEF_FROM_INT(4); | |
DEF_FROM_INT(5); | |
DEF_FROM_INT(6); | |
DEF_FROM_INT(7); | |
DEF_FROM_INT(8); | |
DEF_FROM_INT(9); | |
}; | |
// FizzBuzz | |
template <int i> | |
struct fizzbuzz { | |
template <int n, int mod3, int mod5> | |
struct fizzbuzz_ { | |
typedef typename vtstring::from_int<n>::result result; | |
}; | |
template <int n, int mod5> | |
struct fizzbuzz_<n, 0, mod5> { | |
typedef vtstring::vtstring<'F','i','z','z'> result; | |
}; | |
template <int n, int mod3> | |
struct fizzbuzz_<n, mod3, 0> { | |
typedef vtstring::vtstring<'B','u','z','z'> result; | |
}; | |
template <int n> | |
struct fizzbuzz_<n, 0, 0> { | |
typedef typename vtstring::vtstring<'F','i','z','z', | |
'B','u','z','z'> result; | |
}; | |
typedef typename vtstring::join< | |
typename fizzbuzz_<i, i%3, i%5>::result, | |
vtstring::vtstring<'\n'> | |
>::result result; | |
}; | |
// i〜maxをループしてTを適用(map)し, Mでfold | |
template <int i, int max, template<int n> class T, | |
template<class... A> class M> | |
struct loopN | |
{ | |
typedef typename M< | |
typename T<i>::result, | |
typename loopN<i+1, max, T, M>::result | |
>::result result; | |
}; | |
// 最後のループ | |
template <int max, template<int n> class T, | |
template<class... A> class M> | |
struct loopN<max, max, T, M> | |
{ | |
typedef typename T<max>::result result; | |
}; | |
int main() | |
{ | |
// Hello World | |
typedef vtstring::vtstring<'H','e','l','l','o',','> str; | |
typedef vtstring::vtstring<'W','o','r','l','d','!'> str2; | |
typedef vtstring::join<str, str2>::result ret; | |
cout << ret::c_str() << endl; | |
// length of vtstring | |
cout << "length: " << ret::size << endl; | |
// Null string | |
typedef vtstring::vtstring<> null; | |
cout << null::c_str(); | |
// int => vtstring | |
cout << vtstring::from_int<100>::result::c_str() << endl; | |
cout << "---" << endl; | |
// fizzbuzz | |
cout << loopN<1,100,fizzbuzz,vtstring::join>::result::c_str(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment