using namespace OTL;

ことのほったんは,昨日の地下室にて。IndexBoardを実装するとき3^nをtemplate引数に渡そうとしたら,うーん,どうしよう。template引数じゃ関数で書けないし。。しかしまて,3^nってtemplateでかけるんじゃないのか。ってことで,まずはpowerを。

template 
class power {
public:
  static const int val = N * power::val;
};

template 
class power {
public:
  static const int val = N;
};

部分特殊化はクラスにしかできない。最初は関数オブジェクトにしていたが,それじゃtemplateに渡せないんでstatic constにしたら通りましたと。
こんなに見事にできるとは思っていなかったんで,調子に乗ってfibやfactも完成。だんだん盛り上がってくると,もっとすごいことできないかと。そうだ! πを計算しよう。なるたけ簡単な展開公式を探すと,分数のみで展開できるらしい。

template 
struct iter_pi {
  static const double val = 4.0/(4*N+1) - 4.0/(4*N+3) + iter_pi::val;
};

template 
struct iter_pi {
  static const double val = 0;
};

残念ながら,gccのtemplate展開は最大で500こまでっぽかったので(後に,最大ではんなくて連続でなのかもしれない?),ふつうにやると3.13までしか達成せず。そこで,上の1手展開して状態でiter_pi<0, 400>にし,ついに3.14達成! その後,もっと深く計算できる方法も発見できたり。
なんか,この辺のこと論理演習でやったような気がしてきたぞ。ここら辺駆使したら,素数判定とかできるんじゃないのかとか言い出す。

template 
struct is_prime {
  static const bool val = (N % M != 0) && is_prime::val;
};

template 
struct is_prime {
  static const bool val = true;
};

ってことはだ,N番目の素数も出せるんじゃん?? そのためには,if文が必要だったりするのだが,trueもfalseも評価してしまうと,if文を作れない! どっかの演習でやりましたね。ついに断念かと思ったが,trueならデクリメントしてfalseならデクリメントしない。ということは,conditionの結果を引き算すればいいじゃん!

template 
struct nth_prime {
  static const int val =  nth_prime::val>::val;
};

template 
struct nth_prime {
  static const int val = N-1;
};

やった! 30番目の素数は113だそうだ。
そういや,sinも展開できるな。

template 
struct iter_sin {
  static const double x = to_radian::val;
  static const double val = x / fact<2*N+1>::val - x * x * iter_sin::val;
};

template 
struct iter_sin {
  static const double val = 0;
};

sin 30°は0.499955らしい。すばらしい。
とまぁ,こんなことして結局IndexBoardなんぞできなかった一日でした。F氏とかいたら,もっともりあがっていたんだろうに。