Veiler.Lampads - constexpr-Lambda Library

この記事は[C++ Advent Calendar 2014](http://qiita.com/advent-calendar/2014/cpp)の20日目の記事です．AdCのリンクは記事の下にあります．

---

　I([@wx257osn2](https://twitter.com/wx257osn2))です[^0]．[去年は残念な感じ](https://gist.github.com/wx257osn2/8051199)だったので今年こそはちゃんとした記事を書きたかったのですが，今年も間に合いませんでした…[^1]．ところで[去年の記事](https://gist.github.com/wx257osn2/8051199)を見返してみて気付いたのですが，去年も20日担当だったんですね．来年も20日にしようかしら[^2]．

[^0]: 「あい」です．
[^1]: 実に4週間前から準備を始めたのですが…間に合わないものですねぇ…
[^2]: ネタが有れば，ですが．

# **tl;dr**
1. C++11 constexprな無名関数ライブラリを作ったのでリファレンスと実装解説を行います．
2. 鳥小屋 is 便利


# **はじめに**
　当記事は2014年の暮れにも関わらずC++11の内容を記事にしています．新規格が出た年にもう3年も前の規格を記事にするのは些か憚られるのですが，GCCが「[C++14 constexpr support](https://twitter.com/gnutools/status/534010748318789633)」と発表した後1ヶ月に渡ってHEADがまともに`constexpr`をコンパイルできなくなった[^3]，libstdc++はいつまでも仕事しない，というようにC++14をまともに使えるようになるのは当分先なんじゃないかなぁというのが個人的な感想であります[^4]．そんなわけで，当記事ではC++11を扱います．ご了承ください． ~~C++14使いたい~~

[^3]: 具体的には，ICE / constexpr関数の呼び出しをコンパイル時定数と認識できない / 後で出てくるサンプルコードに対して「奇数の数は0個だ」と返す，などで，**これらはC++11(`-std=c++11`)でも同様に発症していました．**3日か4日か前に直ったみたいです．

[^4]: Clangを使えよ，という声もあるかもしれませんが，Clangのバグに苦しめられた身としては若干手を出したくなくなってきます…尤も，C++14でwhile/forを使えば再帰深度周りのバグも踏まないのでいっそC++14 with Clangに逃げてもいいかなぁとも思うのですが．しかしそれでも大学の鯖で何故か(カーネルが古いせい？)libc++が動かないのでどっちみちlibstdc++が仕事をしないうちはC++11を使っていくしか無いという悲しい現実．とりあえずGCCとMSVCには頑張って頂きたく．なお，一部からは[このような声](https://twitter.com/decimalbloat/status/540544646305161216)も挙がっており，私の望みが無謀・無茶であるのやもしれません．


# **問題提起**
　さて，以下のような問題があったとします．

> 10個の要素を持つ`int`の配列`array`の中から奇数がいくつあるか数えるコードを書け

それに対するC++03時代の解答は以下の様なものになるかと思います，多分．[^5]

[^5]: [私はC++03とBoostをよく知りません．](http://togetter.com/li/455568)

```cpp
#include<boost/lambda/lambda.hpp>
#include<boost/range/algorithm.hpp>
using boost::lambda::_1;

const int array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
const int result = boost::count_if(array, _1 % 2 == 1);
```

rangeやlambda，便利ですよね．
それでは，C++11時代ではどのような回答になるでしょうか．

```cpp
#include<sprout/range/algorithm/count_if.hpp>
#include<sprout/array.hpp>
#include<sprout/functional.hpp>
using sprout::placeholders::_1;

static constexpr auto array = sprout::array<int, 10>{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
static constexpr auto result = sprout::range::count_if(array, sprout::cbind(sprout::modulus<>(), _1,  2));
```

C++11からは`constexpr`の登場によってコンパイル時処理が随分楽に書けるようになったので，この程度のことはコンパイル時に済ませるべきです．Sprout，大変便利ですね．

　しかし，Sproutではrange-based algorithmは実装されていますが，lambdaは実装されていません．そのため，非constexprでは`_1 % 2 == 1`と書けるところが，constexprにしようとすると(最大限`using`しても)`cbind(modulus<>(), _1,  2)`になってしまっています．比較してみると**ラムダ式の方がかっこいい**[要出典]です．ラムダ式で書きたいですよね？

 これを解消するためには，`constexpr`に対応した無名関数ライブラリが必要となります．

 作りました．

# **Veiler.Lampads**
　[Veiler](https://github.com/wx257osn2/veiler).LampadsはC++11のconstexpr lambdaライブラリです．まずはサンプルをご覧ください．
[上述の例](http://sc.yutopp.net/entries/5491350b77777707ecf04200)　/　[簡易テスト](http://sc.yutopp.net/entries/5491341c77777707ecce4200)　　//**鳥小屋はconstexpr-Lambdaを搭載した唯一のオンラインコンパイラです**

## **リファレンス**
　それでは，簡易なリファレンスを以下に示します．

### **基本関数**
　まず，Lampadsでは基本関数と演算子を組み合わせて使いたい無名関数を構築します．基本関数とは，以下に挙げる特別な名前と機能を持った関数です．本記事では便宜上，基本関数は(名前を有していますが)無名関数に含まれるとして扱います．

#### Placeholder
　与えられた引数を返します．`n_`と記述することで第*n*引数を返します．(_n_∈{_m_∈_**Z**_ : _m_≧1})
例えば，`1_`なら第1引数，`2_`なら第2引数…となります．
使用する前に`using veiler::lampads::udl::operator"" _;`が必要です．[^6]

[^6]: Veiler.Lampadsは`_n`の形式のプレースホルダは提供しません．UDLがなんらかの理由で使用できない(e.g. 他のライブラリのものと被る)ために`n_`が使えない，といった場合には`constexpr veiler::lampads::arg_t<N> _n{};`といったように，自分で`veiler::lampads::arg_t<N>`型のオブジェクトを定義して使ってください．また，UDLに対応していないコンパイラではそもそもVeiler.Lampadsを使用することは出来ません． ~~そんな古びたコンパイラは今すぐ窓から投げ捨ててください．~~

```cpp
using veiler::lampads::udl::operator"" _;
static_assert(1_(1, 2, 3) == 1, ""); //第1引数を返す関数
```

#### Variadic Placeholder
　SelfとBind，Polymorphic Member Function Accessorにおいてのみ使用できる関数です．`n_tail`と記述することで第(_n_+1)引数以降の引数列を返します．(_n_∈{_m_∈_**Z**_ : _m_≧0})
つまり，例えば`0_tail`と記述した場合，引数全てを表します．`1_tail`なら第2引数以降の全ての引数を表します．
使用する前に`using veiler::lampads::udl::operator"" _tail;`が必要です．[^7]

[^7]: Veiler.Lampadsは(ry　　　`veiler::lampads::arg_tail_t<N>`を使用してください．

```cpp
using veiler::lampads::udl::operator"" _tail;
using veiler::lampads::bind; //詳細は後述
static constexpr auto f = bind(std::printf, 0_tail); //fはprintfと(ほぼ)同義
f("%d", 1); //1
```

#### Number Of Arguments
　与えられた引数の数を`std::size_t`で返す関数です．`num_of_args`と記述します．

```cpp
using veiler::lampads::num_of_args;
static_assert(num_of_args(1, 2, 3, 4) == 4ul, "");
```

#### Value
　定数関数です．`val(t)`或いは`val<T>(args...)`と記述することで，任意の引数を与えた時に`t`或いは`T(args...)`を返します．また，`veiler::ref(t)`を渡すことで参照を返す関数となります．

```cpp
using veiler::lampads::val;
static_assert(val(1)(3, 4, 5) == 1, ""); //引数は全て無視されます
static_assert(val<veiler::tuple<int, double>>(1, 3.14)() == veiler::make_tuple(1, 3.14), "");
std::string str;
val(veiler::ref(str))() = "abc";
std::cout << str << std::endl; //abc
```

#### If Then Else
　分岐関数です．`if_(cond)[expr1].else_[expr2]`と記述します．(_cond_，_expr1_及び_expr2_はLampadsの無名関数)与えられた引数を用いて条件関数_cond_を実行し，戻り値が`true`か`false`かによって関数_expr1_及び関数_expr2_のいずれかを選択，与えられた引数を用いて呼び出します．

```cpp
using veiler::lampads::udl::operator"" _;
using veiler::lampads::if_;
static constexpr auto cond = if_(1_)[2_].else_[3_]; //第1引数がtrueなら第2引数, falseなら第3引数
static_assert(cond(true, 1, 2) == 1, "");
```

#### Self
　再帰関数です．`self(args...)`と記述することで，「無名関数列_args..._のそれぞれの関数に対して，現在の引数を与えた結果」の列を引数として自身を再帰的に呼び出すことが出来ます．主にIf Then Elseと組み合わせて使います．

```cpp
using veiler::lampads::udl::operator"" _;
using veiler::lampads::udl::operator"" _tail;
using veiler::lampads::if_;
using veiler::lampads::self;
using veiler::lampads::num_of_args;
static constexpr auto fact = //階乗関数
  if_(1_ == 0)[              //第1引数が0なら
    1                        //1を返し
  ].
  else_[                     //そうでないなら
    1_ * self(1_ - 1)        //第1引数 * fact(第1引数 - 1)を返す
  ];
static_assert(fact(4) == 24, "");
static constexpr auto sum = //総和(左畳み込み再帰)
  if_(num_of_args == 1ul)[  //引数の数が1つなら
    1_                      //第1引数を返し
  ].
  else_[                    //そうでないなら
    self(1_ + 2_, 2_tail)   //sum(第1引数 + 第2引数, 第3引数以降)を返す
  ];
static_assert(sum(1, 2, 3, 4, 5) == 15, "");
static_assert(sum(1.5, 2.5, 3.5, 4.5, 5.5) == 17.5, ""); //doubleでも動作
assert(sum(std::string("a"), "b", "c") == "abc"); //実行時文字列処理も可能
```

#### Bind
　部分適用関数です．`bind(f, args...)`と記述することで，「無名関数列_args..._のそれぞれの関数に対して，現在の引数を与えた結果」の列を引数として任意の関数_f_を呼び出すことが出来ます．

```cpp
//GCCでは動作しない(関数ポインタ経由でconstexpr関数を呼び出すと定数式として認識されないバグがあるため)
using veiler::lampads::udl::operator"" _;
using veiler::lampads::val;
using veiler::lampads::bind;
static constexpr auto count_even = bind(
  sprout::range::count_if<sprout::array<int, 5>, decltype(1_ % 2 == 0)>, //実体化して関数のアドレスを取る
                                             1_,      val(1_ % 2 == 0)); //1_ % 2 == 0を  値  と  し  て  渡す
static constexpr auto data = sprout::array<int, 5>{{0, 1, 2, 3, 4}};
static_assert(count_even(data) == 3, "");
```

#### Return Cast
　戻り値キャストです．`ret<Type>(expr)`と記述することで，無名関数_expr_の戻り値を`Type`へキャストして返す無名関数となります．

``` cpp
using veiler::lampads::udl::operator"" _;
using veiler::lampads::udl::operator"" _tail;
using veiler::lampads::if_;
using veiler::lampads::self;
using veiler::lampads::num_of_args;
using veiler::lampads::ret;
static constexpr auto sum = if_(num_of_args == 1ul)[1_].else_[self(1_ + 2_, 2_tail)];
static_assert(ret<int>(sum)(1.5, 2.5, 3.5, 4.5, 5.5) == 17, ""); //sumの結果をdoubleからintに変換
static constexpr auto sum_int = if_(num_of_args == 1ul)[ret<int>(1_)].else_[self(ret<int>(1_) + ret<int>(2_), 2_tail)]; //引数をintに変換してから総和を求める
static_assert(sum_int(1.5, 2.5, 3.5, 4.5, 5.5) == 15, "");
```

### **演算子とキャプチャ**
　Veiler.Lampadsではこれらの基本関数と演算子を組み合わせて任意の無名関数を作ります．演算子を無名関数に適用したものは「『引数で無名関数を評価した結果』に対して演算子を適用する」無名関数となります．
　またこの際，無名関数でないもの(定数や変数など)は可能な限り自動的にValueにラップされ，定数関数となります．これにより，可視範囲内の任意の外部変数や一時オブジェクトの値キャプチャ/ムーブキャプチャが可能です．また，constexpr reference_wrapperライブラリVeiler.Refilを用いる(`veiler::ref(t)`)ことで，参照キャプチャを行うことも出来ます．また，`veiler::move`を用いることでムーブキャプチャも可能です．

### **引数の評価戦略**
　Veiler.Lampadsは複数の評価戦略を持ちます．call-by-valueとcall-by-referenceです．

#### call-by-value
　キャプチャと同様に，普通に渡した場合には値渡しとして扱われますが，`veiler::move`や`veiler::ref`等を用いることでムーブ/参照渡しが可能です．普通のC++の関数に近い引数の取り扱いをします．

#### call-by-reference
　全ての引数をforwardingします．つまり，lvalue referenceを引数に与えればlvalue referenceとして，それ以外の引数は全てmoveして関数を実行します．より高速ですが，C++における引数の扱いとは異なる挙動を示します．

そして，Veiler.Lampadsでは効率を重視して[^8]デフォルトではcall-by-referenceを採用しています．もし評価戦略をcall-by-valueに変更したいのであれば，

```cpp
#define VEILER_LAMPADS_DEFAULT_EVALUATION_STRATEGY pass::by_value
#include <veiler/lampads.hpp>
```
とする必要があります．また，一部の呼び出しについてのみ変更したい場合は，

```cpp
f.call<veiler::lampads::by_value>(args...);
f.call<veiler::lampads::by_reference>(args...);
```
とすることで好きな評価戦略での呼び出しが可能です．

[^8]: 無論，call-by-valueに対しても常に`veiler::ref`などを用いて適切に呼び出せば(最適化がかかるはずなので)call-by-referenceと遜色ない速度は出ます．問題は，例えば上述のsprout::range::count_ifのような関数の引数として渡した際，呼び出し側では`veiler::ref`による修飾が行われないということはほぼ確実であり，そうした際に一々コピーコストが発生するようではパフォーマンスに差支えがあるため，このような方針となっています．

### **Polymorphic Accessor**
　さて，ここでいくつか問題があります．まず，Placeholderを通してメンバにアクセスすることは出来ません．

```cpp
using veiler::lampads::udl::operator"" _;
struct hoge{
  int a, b;
};
(1_.a)(hoge{}); //Error!
```
無論これでは使い物になりません．これを実現するためには，`operator ->*`とメンバポインタを使って間接的なアクセスをすることになります．

```cpp
using veiler::lampads::udl::operator"" _;
struct hoge{
  int a, b;
};
static constexpr hoge h{};
(&1_->*&hoge::a)(h); //OK!
```
これはBoost.Lambdaにも存在する問題とその解法ですが，これには問題があります．まず，`&1_`の部分で`hoge`オブジェクトのアドレスを取る必要が有るため，一度オブジェクトを作った上で参照渡しを行わなければなりません(一時オブジェクトはアドレスが取れませんので，この方法は取れません)．また，メンバポインタによって`1_`は必然的に`hoge`(或いはそれを継承した型)のオブジェクトであることが規定されてしまうのです．せっかくの多相関数なのに，台無しです．

```cpp
using veiler::lampads::udl::operator"" _;
using veiler::lampads::by_value;
struct hoge{
  int a, b;
};
struct fuga{
  double a;
};
static constexpr auto access_a = &1_->*&hoge::a;
static constexpr fuga f{};
access_a(hoge{});                        //Error!
access_a.call<by_value>(veiler::ref(f)); //Error!
```
これを解決するためには，`VEILER_LAMPADS_POLYMORPHIC_MEMBER_ACCESSOR`を使用します．

```cpp
static constexpr VEILER_LAMPADS_POLYMORPHIC_MEMBER_ACCESSOR(a) a{};
using veiler::lampads::udl::operator""_;
using veiler::lampads::by_value;
struct hoge{
  int a, b;
};
struct fuga{
  double a;
};
static constexpr auto access_a = 1_->*a;
static constexpr fuga f{};
access_a(hoge{});                        //OK!
access_a.call<by_value>(veiler::ref(f)); //OK!
```
あるオブジェクトを`obj`，アクセスしたいメンバの名前を`member`としたとき(即ち，`obj.member`へアクセスしたいとき)，`VEILER_LAMPADS_POLYMORPHIC_MEMBER_ACCESSOR(member)`型のオブジェクトを`accessor`とすると，`obj->*accessor`とすることで`obj.member`にアクセスすることが出来ます．また，メンバ関数呼出しにも対応しており，この場合無名関数列`args...`を用いて`obj->*accessor(args...)`とすることで無名関数となります(Bindのような挙動を示します)．

```cpp
static constexpr VEILER_LAMPADS_POLYMORPHIC_MEMBER_ACCESSOR(set) set{};
using veiler::lampads::udl::operator""_;
struct hoge{
  int a;
  constexpr hoge(int a):a(a){}
  int set(int n){return a = n;}
}h(3);
std::cout << h.a << std::endl;   //3
(1_ ->* set(2_))(h, 10);
std::cout << h.a << std::endl;   //10
```
また，基本関数のBindの項で示した例のように，template関数をbindするためにはtemplate引数を埋めて特殊化した形にしなければなりません．これもまた，せっかくの多相が無駄になってしまいます．そこで，`VEILER_LAMPADS_POLYMORPHIC_FUNCTION_ACCESSOR`の出番です．

```cpp
static constexpr VEILER_LAMPADS_POLYMORPHIC_FUNCTION_ACCESSOR(sprout::range::count_if) count_if{};
using veiler::lampads::udl::operator"" _;
using veiler::lampads::val;
using veiler::lampads::bind;
static constexpr auto count_even = bind(count_if, 1_, val(1_ % 2 == 0));
static constexpr auto data = sprout::array<int, 5>{{0, 1, 2, 3, 4}};
static_assert(count_even(data) == 3, ""); //count_if<sprout::array<int, 5>, decltype(1_ % 2 == 0)>
static constexpr auto data2 = sprout::array<int, 10>{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
static_assert(count_even(data2) == 5, ""); //count_if<sprout::array<int, 10>, decltype(1_ % 2 == 0)>
```
<br/>
-----
　簡易な物ですが，リファレンスは以上です．いかがでしたでしょうか．もし「試してみたいけどコンパイラが手元に無い」ですとか，「試してみたいけどcloneするのめんどい」ですとか，そういったことでしたら，ぜひ[こちら](http://sc.yutopp.net/entries/54925daa77777707ec654500)のテンプレをご利用下さい．
　あ　な　た　と　鳥　小　屋　,
今　す　ぐ　L　a　m　p　a　d　s


## **実装について**
　使い方については以上ですが，C++ Advent Calendarを読んでいる皆様のことですから使い方よりライブラリの中身の方が気になることと思います．しかも，[実装](https://github.com/wx257osn2/veiler/blob/master/lampads/lampads.hpp)がめちゃくちゃ汚い[^9]ので読めたものではありませんから，なおさら日本語での解説が必要でしょう．というわけで，実装についても出来る限り書きます．しかし，おそらくある程度の知識(templateやconstexprを用いたC++メタプログラミング(特にtupleを使ったもの)，簡単な関数型プログラミング)を前提とした記述になってしまっていると思うので，仮に分からないことがある場合には[Twitter](https://twitter.com/wx257osn2)に連絡ください．出来る限り分かりやすく説明させていただきます．また，場合によってはこちらに追記もします．
　なお，以下の解説中におけるコードは読みやすさを重視して話題と無関係なコードや`template`修飾子・`typename`修飾子の省略を行っている場合があります．また，記事掲載当時のコードを元に解説を行うため最新版のVeiler.Lampadsでは動作が異なる場合があります．

[^9]: 汚いのは依存関係の都合で定義が飛び散っている(e.g. operator overloadできる場所が限られている都合で`operator[]`と`operator=`の実装が`Lampads<T>`より上部に来ている，それらの実装のために`is_lampads`や`Val`などの定義がさらにその上に来ている，しかし特殊化`is_lampads<Lampads<T>>`やら`Lampads<Val<T>> val(T&&)`やらは`Lampads<T>`の下に来なければならない)こと，Variadic Placeholderを実現するために似たようなコード(`run`と`bind_run`)が各無名関数実装毎に存在すること，Clangのためのworkaroundがいたるところに入り込んでいること，`decltype`による戻り値型の記述で式が毎回重複すること，などが原因です．つまり，一部の式がやたらめったら横に伸びている以外は基本的に「回避できない/しにくい実装上の都合」です．

### **概要**
　Veiler.Lampadsの無名関数はインターフェースとなるテンプレートクラス`Lampads`と，基本関数の実体となるクラス群によって構成されています．

#### `Lampads`
　`Lampads`は関数オブジェクトとして評価戦略に従った引数授受や`result_type`を定義する，といった役割を担います．また，ライブラリの内部においては無名関数であることの表明として用いられます．ユーザーが実際に操作しているのは`Lampads`です．

#### 各基本関数実装
　基本関数の実態はそれぞれクラスとして実装されており，共通のインターフェースを有しています．`Lampads`や相互でインターフェースを叩き合い，計算を行います．`Lampads`によって隠蔽されており，ユーザーが直接触れることはありません．

この2つを交互に見ていくことで，Veiler.Lampadsがどのような仕組みで動いているのかを読み解くことができます．それでは，ケーススタディを通して実装を追ってみましょう．

### **ケース1 : Value**
　まず，最も単純な例として

```cpp
val(1)()
```
について考えてみましょう．無論，この式の期待される結果は`int`型の値`1`です．さて，`val`の定義は以下のようになっています．

```cpp
template<typename T>
constexpr Lampads<Val<unwrap_refil_t<T>>> val(T&& t){
   return Lampads<Val<unwrap_refil_t<T>>>(unwrap_refil_or_copy(veiler::forward<T>(t)));
}
```
即ち，先述の式は

```cpp
Lampads<Val<unwrap_refil_t<int>>>(unwrap_refil_or_copy(veiler::forward<int>(1)))()
```
と同等です．さて，`unwrap_refil_t`や`unwrap_refil_or_copy`とはなんなのでしょうか．

```cpp
template<typename T>
constexpr T unwrap_refil_or_copy(T t){return veiler::move(t);}
template<typename T>
constexpr T& unwrap_refil_or_copy(veiler::refil<T> t){return t.get();}
template<typename T>
using unwrap_refil_t = decltype(unwrap_refil_or_copy(std::declval<T>()));
```
`unwrap_refil_or_copy`は引数が`veiler::refil<T>`であればそれを剥がして中の参照を取り出し，それ以外であれば受け取った引数のコピーを返す，という関数であり，`unwrap_refil_t`はこの操作を行った際の型を返すメタ関数であることがわかりました．`int`は`veiler::refil<T>`ではありませんから，コピーされることになります[^10]．

[^10]: といっても，実際には`unwrap_refil_or_copy(veiler::forward<int>(1))`という呼び出しの通りforwardingされますし，この場合はムーブされますのでコピーコストはかかりません(スカラー型なので最適化が働いて置換される…はず)．

```cpp
Lampads<Val<int>>(1)()
```
前置きが長くなりましたが，ここからが本題です．まずは，インターフェースクラスの`Lampads<T>`について見てみましょう．

```cpp
template<typename T, typename = void>class LampadsImpl;
template<typename T>
class LampadsImpl<T, typename std::enable_if<T::ret_type::depends_on_args == false>::type>{
 public:
  using result_type = typename T::ret_type::template type<>;
 protected:
  template<pass, typename = void>struct call_impl;
  template<typename Dummy>
  struct call_impl<pass::by_value, Dummy>{
    template<typename... Args>
    static constexpr result_type call(const T& t, Args&&... args){
      return veiler::forward<result_type>(t.template run<result_type>(t, unwrap_refil_or_copy(veiler::forward<Args>(args))...));
    }
  };
  template<typename Dummy>
  struct call_impl<pass::by_reference, Dummy>{
    template<typename... Args>
    static constexpr result_type call(const T& t, Args&&... args){
      return veiler::forward<result_type>(t.template run<result_type>(t, veiler::forward<unremove_reference_decay<Args>>(args)...));
    }
  };
};
/*(中略)*/
template<typename T>
class Lampads : public LampadsImpl<T>{
  T t;
  using impl_t = LampadsImpl<T>;
 public:
  /*(中略)*/
  template<typename X, typename... Args>
  explicit constexpr Lampads(X&& x, Args&&... args):t(veiler::forward<X>(x), veiler::forward<Args>(args)...){}
  /*(中略)*/
  template<typename... Args>
  constexpr auto operator()(Args&&... args)const
    ->decltype(impl_t::template call_impl<VEILER_LAMPADS_DEFAULT_EVALUATION_STRATEGY>::call(t, veiler::forward<Args>(args)...)){
        return impl_t::template call_impl<VEILER_LAMPADS_DEFAULT_EVALUATION_STRATEGY>::call(t, veiler::forward<Args>(args)...);
  }
  /*(中略)*/
};
```
本題からそれる部分は省略しましたが，これが`Lampads`の実装となります．さて，今回`T`は`Val<int>`です．まずはコンストラクタが呼ばれます．

```cpp
  T t;
 public:
  template<typename X, typename... Args>
  explicit constexpr Lampads(X&& x, Args&&... args):t(veiler::forward<X>(x), veiler::forward<Args>(args)...){}
```
`T`型のメンバ`t`に引数を全てforwardingしているだけです．つまり，`Val<int>`に`1`を渡しています．それでは次に`Val`について見てみましょう．

```cpp
template<typename T>
class Val{
  T t;
 public:
  struct ret_type:std::true_type{
    template<typename...>using type = T;
    static constexpr bool depends_on_args = false;
  };
  template<typename... Args>
  constexpr Val(Args&&... args):t(veiler::forward<Args>(args)...){}
  template<typename R, typename... Args>
  constexpr T run(Args&&...)const{return t;}
  /*(中略)*/
};
```
`Val`のコンストラクタはメンバ`t`に受け取った引数を投げつけます．結局，`int t`を`1`で初期化するだけです．これで`Lampads<Val<int>>`型のオブジェクトが構築出来ました．次に，関数呼び出しを行います．`Lampads`の`operator()`を見てみましょう．

```cpp
  using impl_t = LampadsImpl<T>;
 public:
  template<typename... Args>
  constexpr auto operator()(Args&&... args)const
    ->decltype(impl_t::template call_impl<VEILER_LAMPADS_DEFAULT_EVALUATION_STRATEGY>::call(t, veiler::forward<Args>(args)...)){
        return impl_t::template call_impl<VEILER_LAMPADS_DEFAULT_EVALUATION_STRATEGY>::call(t, veiler::forward<Args>(args)...);
  }
```
複雑そうに見えますが，大したことはありません．`impl_t`は`LampadsImpl<T>`ですが，これは`Lampads<T>`が継承しているクラスです．そのクラスのメンバである`call_impl<VEILER_LAMPADS_DEFAULT_EVALUATION_STRATEGY>`のメンバ関数`call`を呼び出しているだけです．今回引数はありませんし，`VEILER_LAMPADS_DEFAULT_EVALUEATION_STARTEGY`はリファレンスで述べた通り，デフォルトでは`pass::by_reference`となっていますから，`operator()`の返す式は

```cpp
LampadsImpl<Val<1>>::call_impl<pass::by_reference>::call(t)
```
となります．`LampadsImpl<T>`についてみてみると，

```cpp
 public:
  using result_type = typename T::ret_type::template type<>;
 protected:
  template<pass, typename = void>struct call_impl;
  template<typename Dummy>
  struct call_impl<pass::by_reference, Dummy>{
    template<typename... Args>
    static constexpr result_type call(const T& t, Args&&... args){
      return veiler::forward<result_type>(t.template run<result_type>(t, veiler::forward<unremove_reference_decay<Args>>(args)...));
    }
  };
```
とあります．しつこいようですが，今回無引数で呼び出していますので

```cpp
veiler::forward<result_type>(t.run<result_type>(t))
```
となります．`LampadsImpl<Val<int>>`のメンバとして`result_type`が`Val<int>::ret_type::type<>`のエイリアスとして定義されています．これは`Val`に

```cpp
  struct ret_type:std::true_type{
    template<typename...>using type = T;
    static constexpr bool depends_on_args = false;
  };
```
とあるので`T`，今回で言えば`int`となります．従って，

```cpp
veiler::forward<int>(t.run<int>(t))
```
です．`t`は`Val<int>`であることを思い出してください．`Val`のメンバ関数`run`は以下の様なものでした．

```cpp
  template<typename R, typename... Args>
  constexpr T run(Args&&...)const{return t;}
```
つまり，`Val<int>`のメンバ`int t`を返す関数です．以上より，

```cpp
veiler::forward<int>(1)
```
ですから，期待通り`int`型の値`1`が得られました．

#### **まとめ**
　このケースからは，以下のようなことを学ぶことが出来ます．

1. Valueの実態はテンプレートクラス`Val`である．`val`関数を通して，`Lampads`に包まれた状態でユーザーに提供される．
2. `Lampads<T>`の`T`はメンバクラス`ret_type`を持つ必要がある．`ret_type::type<Args...>`は引数として`Args...`が渡された時の戻り値型となる．
3. `Lampads<T>`の`T`はメンバ関数`run`を持つ．`run`は`T`のオブジェクトと引数を渡され，適切な値を返す．

### **ケース2 : 二項演算**
　次に，

```cpp
(val(1) + 1)()
```
について見て行きましょう．期待される結果は`int`の`2`です．最初のケースで長々やったので，一度扱ったものは飛ばしていきます．

```cpp
(Lampads<Val<int>>(1) + 1)()
```
`Lampads`に対して加算しています．演算子がオーバーロードされていますね．以下が呼び出される`operator +`の定義です．

```cpp
template<typename T, typename U, typename std::enable_if<is_lampads<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::value ||
                                                         is_lampads<typename std::remove_cv<typename std::remove_reference<U>::type>::type>::value>::type* = nullptr>
constexpr Lampads<Add<unwrap_lampads_or_valize_t<T>, unwrap_lampads_or_valize_t<U>>> operator +(T&& t, U&& u){
   return Lampads<Add<unwrap_lampads_or_valize_t<T>, unwrap_lampads_or_valize_t<U>>>(unwrap_lampads_or_valize(veiler::forward<T>(t)), unwrap_lampads_or_valize(veiler::forward<U>(u)));
}
```
長くてごちゃごちゃしてますが，

1. 引数は`(T&&, U&&)`
2. `T``U`少なくとも1つは参照やcv修飾子を外した場合に`Lampads<T>`となる
3. 戻り値型は`Lampads<Add<unwrap_lampads_or_valize_t<T>, unwrap_lampads_or_valize_t<U>>>`である
4. 戻り値は`Lampads<Add<unwrap_lampads_or_valize_t<T>, unwrap_lampads_or_valize_t<U>>>(unwrap_lampads_or_valize(veiler::forward<T>(t)), unwrap_lampads_or_valize(veiler::forward<U>(u)))`である

というだけです．`unwrap_lampads_or_valize`とやらが分かれば何とかなりそうですし，これも名前からして想像がつきますよね？

```cpp
template<typename T>
constexpr Val<unwrap_refil_t<T>> unwrap_lampads_or_valize(T&& t){
   return Val<unwrap_refil_t<T>>(unwrap_refil_or_copy(veiler::forward<T>(t)));
}
template<typename T>
constexpr T unwrap_lampads_or_valize(Lampads<T>&& t){
  return Lampads<T>::_get(veiler::move(t));
}
template<typename T>
constexpr T unwrap_lampads_or_valize(const Lampads<T>& t){
  return Lampads<T>::_get(t);
}
template<typename T>
using unwrap_lampads_or_valize_t = decltype(unwrap_lampads_or_valize(std::declval<T>()));
```
`Lampads<T>`なら中身を取り出し，それ以外なら`unwrap_refil_or_copy`して`Val`に包む[^11]．簡単ですね．

[^11]: 「Val化」を「valize」と表現した筆者の貧弱英語力に笑ったそこのアナタ，より良い名前を見つけてpull-reqしてくださいね．

```cpp
Lampads<Add<unwrap_lampads_or_valize_t<Lampads<Val<int>>>, unwrap_lampads_or_valize_t<int>>>(unwrap_lampads_or_valize(veiler::forward<Lampads<Val<int>>>(Lampads<Val<int>>(1))), unwrap_lampads_or_valize(veiler::forward<int>(1)))()
```
これは，

```cpp
Lampads<Add<Val<int>, Val<int>>>(Val<int>(1), Val<int>(1))()
```
となります．ここで注目して欲しいのは，加算演算子の右辺にあった`int(1)`が`Val<int>(1)`に化けたことです．これがリファレンスで言及したキャプチャ機構の正体です．そして，加算の実態は`Add`というクラスが担っていることが分かります．

　ところで，言うまでもないことですが殆の二項演算でこのような処理がなされます．つまり，

```cpp
3.14 * (Val(2) + 5)
```
の型は

```cpp
Lampads<Mul<Val<double>, Add<Val<int>, Val<int>>>>
```
のようになります．式の構造を型に落としこむ，Expression Templateという技法です．詳細はおググりください[^12]．

[^12]: 一応軽く触れておくと，元々は「コンパイル時に求まる型情報を使って遅延評価を実現すれば，実行時には計算すること増えないし一時オブジェクトを生成せずに計算できるからパフォーマンスアップだ！」みたいな技法です([3日目の西山さんが紹介なさっている](http://blog.livedoor.jp/tek_nishi/archives/8623876.html)Eigenも採用しています，[「高速(テンプレートが展開され、余計な変数が生成されない)」](http://blog.livedoor.jp/tek_nishi/archives/8623876.html)という記述がETのこと)．Boost.LambdaやVeiler.Lampadsといった「式が関数になるタイプの無名関数ライブラリ」もまた，「引数を与えられた時に実際の計算を行う」という遅延評価を行っている，と捉えると何故ETを使っているのか分かりやすいのではないでしょうか．

さて，本題に戻しますと`Add`とはなんぞや，という話です．

```cpp
template<typename T, typename U>
class Add{
  T t;
  U u;
  struct ret_type_t:std::true_type{
    template<typename... Args>
    using type = decltype(std::declval<typename T::ret_type::template type<Args...>>() + std::declval<typename U::ret_type::template type<Args...>>());
    static constexpr bool depends_on_args = T::ret_type::depends_on_args || U::ret_type::depends_on_args;
  };
  /*(中略)*/
 public:
  using ret_type = typename std::conditional<T::ret_type::value && U::ret_type::value, ret_type_t, ret_type_dummy>::type;
  template<typename R, typename S, typename... Args>
  constexpr auto run(const S& s, Args&&... args)const
    ->decltype(t.template run<R>(s, veiler::forward<Args>(args)...)
             + u.template run<R>(s, veiler::forward<Args>(args)...)){
        return t.template run<R>(s, veiler::forward<Args>(args)...)
             + u.template run<R>(s, veiler::forward<Args>(args)...);
  }
  /*(中略)*/
  constexpr Add(const T&  t, const U&  u):t(t),                     u(u)                    {}
  constexpr Add(const T&  t,       U&& u):t(t),                     u(veiler::forward<U>(u)){}
  constexpr Add(      T&& t, const U&  u):t(veiler::forward<T>(t)), u(u)                    {}
  constexpr Add(      T&& t,       U&& u):t(veiler::forward<T>(t)), u(veiler::forward<U>(u)){}
};
```
コンストラクタによってメンバ`t`と`u`に引数がそれぞれそのまま渡ります．ここではどちらも`Val<int>(1)`ですね．`ret_type`は`std::conditional`によって条件分岐が成されていますが，`Val<int>::ret_type::value`は共に`true`ですから，`ret_type_t`が採用されます．従って`Add<Val<int>, Val<int>>::ret_type::type<>`は

```cpp
decltype(std::declval<Val<int>::ret_type::type<>>() + std::declval<Val<int>::ret_type::type<>>())
```
`Val<int>::ret_type::type<>`はケース1でやりましたね．

```cpp
decltype(std::declval<int>() + std::declval<int>())
```
つまり「`int`と`int`を足した結果の型」ですから，`int`となります．また，`ret_type::depends_on_args`も同様に操作していけば`false`となります．
肝心の`run`関数は，「`t`と`u`それぞれの`run`の結果を加算して返す」というものです．`Val<int>`の`run`もまた，ケース1でやりましたからもう分かりますね．答えは確かに`2`となりました．

#### **まとめ**
　このケースからは，以下のようなことを学ぶことが出来ます．

1. Veiler.Lampadsの無名関数はExpression Templateによって生成される．
2. オーバーロードされた二項演算子によって`Lampads`ではないものは`Val`に包まれる．これがキャプチャの正体である．
3. 演算子それぞれに実装の型がある．内部で被演算子の無名関数を呼び出し，その結果に演算子を作用させている．

### **ケース3 : 引数**
　お次は，

```cpp
(1_ + 1)(1)
```
を考えてみましょう．ついに引数が出てきました．やはり期待される結果は2ですが，果たして．
　まずは`1_`について見てみなければなりません．この記法はユーザー定義リテラル(user-defined literals，UDL)を用いて実現しています．

```cpp
template<long long N, char c, char... Chars>
struct udl_to_placeholder{
  using type = typename std::enable_if<'0'<=c && c<='9', typename udl_to_placeholder<N*10 + c-'0', Chars...>::type>::type;
};
template<long long N>
struct udl_to_placeholder<N,'\0'>{using type = Lampads<Placeholder<N>>;};
template<char... Chars>
constexpr typename udl_to_placeholder<0, Chars...,'\0'>::type operator""_(){
   return typename udl_to_placeholder<0, Chars...,'\0'>::type{};
}
```
え？分からない？簡単な事です…

```cpp
N_
```
は

```cpp
Lampads<Placeholder<N>>{}
```
になります(本当にそれだけです，そしてこれ以上の解説はUDLの解説になるので割愛します)．なので，先ほどの式は

```cpp
(Lampads<Placeholder<1>>{} + 1)(1)
```
です．ケース2より，

```cpp
Lampads<Add<Placeholder<1>, Val<int>>>({}, Val<int>(1))(1)
```
となります．それでは，そろそろ`Placeholder`について見て行きましょう．

```cpp
template<long long N>
struct Placeholder{
  struct ret_type:std::true_type{
    template<typename... Args>
    using type = veiler::type_at<veiler::type_tuple<Args...>, N-1>;
    static constexpr bool depends_on_args = true;
  };
  constexpr Placeholder() = default;
  template<typename R, typename S, typename... Args>
  constexpr auto run(const S&, Args&&... args)const
    ->veiler::type_at<veiler::type_tuple<Args...>, N-1>{
    return veiler::get<N-1>(veiler::forward_as_tuple<Args&&...>(veiler::forward<Args>(args)...));
  }
  /*(中略)*/
};
```
`run`は「引数を全て`veiler::tuple`としてforwarding，その中から`N-1`番目の要素を取り出して返す」というコードとなっています．**[tupleは便利](https://gist.github.com/wx257osn2/8051199)ですね．**よって，今回の式は

```cpp
get<1-1>(forward_as_tuple<int&&>(forward<int>(1))) + 1
```
ですから，

```cpp
1 + 1
```
ということで，やはり期待していた通りの答えとなりました．
　ところで，`Val`と違い`Placeholder`は`ret_type::depends_on_args`の値が`true`になっています．`Placeholder<1>::ret_type::value`は`true`なので，`Add<Placeholder<1>, Val<int>>::ret_type`はケース2の時と同じく`Add<Placeholder<1>, Val<int>>::ret_type_t`ですが，

```cpp
struct ret_type_t:std::true_type{
  template<typename... Args>
  using type = decltype(std::declval<typename T::ret_type::template type<Args...>>() + std::declval<typename U::ret_type::template type<Args...>>());
  static constexpr bool depends_on_args = T::ret_type::depends_on_args || U::ret_type::depends_on_args;
};
```
`depends_on_args`は`true || false`，即ち`true`となります．これ，実は`LampadsImpl<T>`今までのケースとは違うものになってしまうのです．

```cpp
template<typename T>
class LampadsImpl<T, typename std::enable_if<T::ret_type::depends_on_args == true>::type>{
 protected:
  template<pass, typename = void>struct call_impl;
  /*(中略)*/
  template<typename Dummy>
  struct call_impl<pass::by_reference, Dummy>{
    template<typename... Args>
    static constexpr auto call(const T& t, Args&&... args)
      ->decltype(t.template run<typename T::ret_type::template type<unremove_reference_decay<Args>...>>(t, veiler::forward<unremove_reference_decay<Args>>(args)...)){
          return t.template run<typename T::ret_type::template type<unremove_reference_decay<Args>...>>(t, veiler::forward<unremove_reference_decay<Args>>(args)...);
    }
  };
};
```
ケース1では触れませんでしたが，`LampadsImpl<T>`は`T::ret_type::depends_on_args`の値によって特殊化されています．そして，`depends_on_args`が`true`である場合，`LampadsImpl<T>::result_type`(率いてはこれを継承している`Lampads<T>`のメンバ`result_type`)が定義されていないことが分かるでしょうか．そもそも，`depends_on_args`，「引数に依存している」という名前を見れば分かるでしょうが，これは「その無名関数の戻り値は引数に依存するか」を表すフラグです．引数に戻り値の型が依存したら，当然`result_type`は定義できませんよね．
　C++における関数オブジェクトは，(特にC++03時代のライブラリと併用する場合)`result_type`が定義されていると何かと都合がいい事が多いです．一方で，多相性を導入するとこれが実現し難い．そのため，Veiler.Lampadsでは無名関数によって`result_type`が定義可能かを自動的に検出し，可能であれば定義する，という方針を取りました．それがこの`ret_type::depends_on_args`なのです．

#### **まとめ**
　このケースからは，以下のようなことを学ぶことが出来ます．

1. Placeholderの実態はテンプレートクラス`Placeholder`である．`operator"" _`を通して，`Lampads`に包まれた状態でユーザーに提供される．
2. `Val`は引数に依存しない．`Placeholder`は引数に依存する．
3. 戻り値型が引数に依存する`Lampads`は，`result_type`が定義されない．これは`LampadsImpl<T>`の特殊化によって成立する．
4. **[tupleは便利](https://gist.github.com/wx257osn2/8051199)である．**

### **ケース4 : キャストと分岐**
　このペースでやっていると文量が恐ろしく長くなるので，そろそろ2つ一気にやりましょう．

```cpp
if_(1_)[0].else_[ret<int>(2_)](false, 1.)
```
Return CastとIf Then Elseです．今回はやや複雑ですが，期待する結果は`1`です．まずは`ret`を展開しましょう．

```cpp
template<typename R, typename T>
constexpr Lampads<Ret<R, T>> ret(Lampads<T>&& t){return Lampads<Ret<R, T>>{Lampads<T>::_get(veiler::move(t))};}
template<typename R, typename T>
constexpr Lampads<Ret<R, T>> ret(const Lampads<T>& t){return Lampads<Ret<R, T>>{Lampads<T>::_get(t)};}
```
`Lampads<T>`をとって中身をそっくりそのまま渡した`Lampads<Ret<R, T>>`を返す．簡単ですね．

```cpp
if_(Lampads<Placeholder<1>>{})[
  0
].else_[
  Lampads<Ret<int, Placeholder<2>>>{}
](false, 1.)
```
次はIf Then Elseを解除しましょう．

```cpp
template<typename C>constexpr If<C> if_(C&& c){return If<C>(veiler::forward<C>(c));}
```
`if_`は関数です．`If`型のオブジェクトを生成するようです．

```cpp
If<Lampads<Placeholder<1>>>(veiler::forward<Lampads<Placeholder<1>>>({}))[
  0
].else_[
  Lampads<Ret<int, Placeholder<2>>>{}
](false, 1.)
```
`If`の中身はというと，

```cpp
template<typename C>class If{
  C&& c;
 public:
  constexpr If(C&& cond):c(veiler::forward<C>(cond)){}
  template<typename T>constexpr IfElseBridge<C, T> operator[](T&& t)const{return IfElseBridge<C, T>(Else<C, T>(veiler::forward<C>(c), veiler::forward<T>(t)));}
};
```
渡された参照`c`をそのまま保持するコンストラクタと，保持した参照`c`及び渡された参照`t`で`IfElseBridge`型のオブジェクトを構築する`operator[]`があります．

```cpp
IfElseBridge<Lampads<Placeholder<1>>, int>(
  Else<Lampads<Placeholder<1>>, int>(
    veiler::forward<Lampads<Placeholder<1>>>({}),
    veiler::forward<int>(0)
  )
)
.else_[
  Lampads<Ret<int, Placeholder<2>>>{}
](false, 1.)
```
段々ややこしくなってきました．`IfElseBridge`は

```cpp
template<typename C, typename T>struct IfElseBridge{
  constexpr IfElseBridge(Else<C,T>&& e):else_(veiler::move(e)){}
  Else<C,T> else_;
};
```
`Else<C, T>`を受け取って，publicメンバの`else_`を初期化するだけのようです．publicメンバなので，直接アクセスできます．実質は，

```cpp
Else<Lampads<Placeholder<1>>, int>(
  veiler::forward<Lampads<Placeholder<1>>>({}),
  veiler::forward<int>(0)
)[
  Lampads<Ret<int, Placeholder<2>>>{}
](false, 1.)
```
こういうことでしょう．最後に，`Else`は

```cpp
template<typename C, typename T>class Else{
  C&& c; T&& t;
 public:
  constexpr Else(C&& c, T&& t):c(veiler::forward<C>(c)),t(veiler::forward<T>(t)){}
  template<typename U>
  constexpr Lampads<IfImpl<unwrap_lampads_or_valize_t<C>, unwrap_lampads_or_valize_t<T>, unwrap_lampads_or_valize_t<U>>> operator[](U&& u)const{
     return Lampads<IfImpl<unwrap_lampads_or_valize_t<C>, unwrap_lampads_or_valize_t<T>, unwrap_lampads_or_valize_t<U>>>(unwrap_lampads_or_valize(veiler::forward<C>(c)),unwrap_lampads_or_valize(veiler::forward<T>(t)),unwrap_lampads_or_valize(veiler::forward<U>(u)));
  }
};
```
ついに`Lampads`や`unwrap_lampads_or_valize`が登場しました．つまり，これで最後です．コンストラクタにおける`c`や`t`の扱いはこれまでと同じなので端折りますが

```cpp
Lampads<IfImpl<
  unwrap_lampads_or_valize_t<Lampads<Placeholder<1>>>,
  unwrap_lampads_or_valize_t<int>,
  unwrap_lampads_or_valize_t<Lampads<Ret<int, Placeholder<2>>>>
>>(
  unwrap_lampads_or_valize(veiler::forward<Lampads<Placeholder<1>>>({})),
  unwrap_lampads_or_valize(veiler::forward<int>(0)),
  unwrap_lampads_or_valize(veiler::forward<Lampads<Ret<int, Placeholder<2>>>>({})),
)(false, 1.)
```
これを展開すると

```cpp
Lampads<IfImpl<
  Placeholder<1>,
  Val<int>,
  Ret<int, Placeholder<2>>
>>(
  Placeholder<1>{},
  Val<int>(0),
  Ret<int, Placeholder<2>>({}),
)(false, 1.)
```
以上が前置きです．`IfImpl`を見てみましょう．

```cpp
template<typename C, typename T, typename U>class IfImpl{
  C c; T t; U u;
  struct ret_type_t:std::true_type{
    template<typename... Args>
    using type = typename _IfImpl_ret_type<T, U>::template type<Args...>;
    static constexpr bool depends_on_args = _IfImpl_ret_type<T, U>::depends_on_args;
  };
 public:
  using ret_type = typename std::conditional<T::ret_type::value || U::ret_type::value, ret_type_t, ret_type_dummy>::type;
  constexpr IfImpl(C c, T t, U u):c(veiler::forward<C>(c)),t(veiler::forward<T>(t)),u(veiler::forward<U>(u)){}
  template<typename R, typename S, typename... Args>
  constexpr auto run(const S& s, Args&&... args)const
    ->typename _IfImpl_ret_type<T, U>::template type<Args...>{
    return c.template run<R>(s,veiler::forward<Args>(args)...)
          ?t.template run<R>(s,veiler::forward<Args>(args)...)
          :u.template run<R>(s,veiler::forward<Args>(args)...);
  }
  /*中略*/
};
```
コンストラクタはもういいでしょう．`run`も誰にでも分かる内容(それぞれの`run`を呼んで条件演算子で分岐するだけ)です．見慣れないものとしては`_IfImpl_ret_type`ぐらいのものですが，これは可能な限りコピーを抑えるために，「出来る限り参照を残した`T::ret_type::<Args...>`と`U::ret_type::type<Args...>`両方から変換可能な型を求める[^13]」メタ関数を物量条件分岐で実現しているサムシングです．載せても無駄に記事が長くなるだけなので，読みたい人は[ソースのl.583-621](https://github.com/wx257osn2/veiler/blob/master/lampads/lampads.hpp#L583-L621)をあたってください．ただの力押しです．1つ言っておくとすれば，今回`depends_on_args`は`false`，つまり`result_type`が定義される状態となります．後述しますが，`Ret<int, T>::ret_type::depends_on_args`は`false`です(戻り値の"型"は`Ret`で固定されるのですから引数には依存しませんよね？)．`Val`のそれと共に`false`ですから，`IfImpl`もまた戻り値型について引数に依存しません．
　再掲しますが，結論としては，以下を求めれば良いと．

[^13]: e.g. `if_(cond)[1_].else_[2_](a, b)`　`a`も`b`も同じ型の変数である場合，参照が返ります．

```cpp
Lampads<IfImpl<
  Placeholder<1>,
  Val<int>,
  Ret<int, Placeholder<2>>
>>(
  Placeholder<1>{},
  Val<int>(0),
  Ret<int, Placeholder<2>>({}),
)(false, 1.)
```
結論から言ってしまえば，第1引数は`false`ですから，`Placeholder<1>{}.run`の返す値は`false`です．ですから，求めるべきは`Ret<int, Placeholder<2>>({}).run(s, false, 1.)`です．`Ret`は以下のようになっています．

```cpp
template<typename RetType, typename T>
class Ret{
  T t;
 public:
  struct ret_type:std::true_type{
    template<typename...>using type = RetType;
    static constexpr bool depends_on_args = false;
  };
  constexpr Ret(T&& t):t(veiler::forward<T>(t)){}
  constexpr Ret(const T& t):t(t){}
  template<typename R, typename S, typename... Args>
  constexpr RetType run(const S& s, Args&&... args)const{return veiler::forward<RetType>(t.template run<R>(s, veiler::forward<Args>(args)...));}
  }
};
```
`Ret<RT, T>::run`は`veiler::forward<RT>(T::run)`となります．簡単ですね．以上より，

```cpp
veiler::forward<int>(1.)
```
ですから，`int`の`1`が答えとなります．

#### **まとめ**
　このケースからは，以下のようなことを学ぶことが出来ます．

1. Return Castの実態はテンプレートクラス`Ret`である．`ret`を通して，`Lampads`に包まれた状態でユーザーに提供される．
2. If Then Elseの実態はテンプレートクラス`IfImpl`である．`if_`や`operator[]`，`else_`を通して，最終的に`Lampads`に包まれた状態でユーザーに提供される．
3. If Then Elseの戻り値型はそれっぽいものがいい感じに決定される(雑)
4. Return Castを使うことで，(その中身がどのような無名関数であろうと)`depends_on_args`を`false`にすることが出来る．`result_type`を定義したいときには都合がいい．


### **ケース5 : 再帰とVariadic Placeholder**
　長々だらだらとやって来ましたが，ついにこのケース5でVeiler.Lampadsの(ほぼ)全貌を掴むことが出来ます．
　さて，ここまで見てきて殆どの方は感じたことと思いますが，ケース1～4に渡って，あることについてあからさまに誤魔化し続けてきています．ケース1のまとめをもう一度見てみましょう．

>#### **まとめ**
>　このケースからは，以下のようなことを学ぶことが出来ます．
>
>1. Valueの実態はテンプレートクラス`Val`である．`val`関数を通して，`Lampads`に包まれた状態でユーザーに提供される．
>2. `Lampads<T>`の`T`はメンバクラス`ret_type`を持つ必要がある．`ret_type::type<Args...>`は引数として`Args...`が渡された時の戻り値型となる．
>3. `Lampads<T>`の`T`はメンバ関数`run`を持つ．`run`は`T`のオブジェクトと引数を渡され，適切な値を返す．

さて，ではここで質問です．`ret_type::type<Args...>`は何のために必要なのでしょうか？`result_type`を定義するため，ではありません．「引数に依存しない時のみ定義される`result_type`のため」であれば，`Args...`を受け取る道理がないからです．また，ケース3を見返してみると，`LampadsImpl<T>::call_impl<pass::by_reference>::call`内で，`t.run`のテンプレート引数として`T::ret_type::type<Args...>`を渡しています．しかし，`Add`も`IfImpl`も`Ret`も`R`として受け取ってそのまま下の`run`に流しているだけだし，`Val`と`Placeholder`は受け取った型`R`をそのまま捨てています．
　もう1つ質問です．`run`は`Lampads<T>::operator()`が受け取った引数以外に`T`のオブジェクトを渡されていますが，これは何故でしょう？先述の`R`と同様に，これもまた`Add`・`IfImpl`・`Ret`はそのまま下に流し，`Val`と`Placeholder`は捨てています．
　そして最後に1つ．今までのコードの殆どで出てきた`/*(中略)*/`には，一体何が書かれているのでしょうか？このように多くのことについて説明を省き続けてきたのは，序盤から出てくる割に仕組みは割と複雑な出力機構に対して起こる疑問「何故std::printfは引数をいくつでも取れるの？」だの「何故std::coutはシフト演算子で出力が出来るの？」だのと同じように，説明をするには前提となる知識が足りなかったからです．今，上述の疑問を解消するためのケースを扱うために必要な道具は揃いました．今回のお題は，以下の式です．

```cpp
if_(num_of_args == 1ul)[1_].else_[self(1_ + 2_, 2_tail)](1, 2, 3, 4)
```
今回の初出は3つ．Number Of Args，Variadic Placeholder，そしてSelfです．期待される結果は`int`の`10`．順番に見て行きましょう．

```cpp
struct NumOfArgs{
  struct ret_type:std::true_type{
    template<typename...>
    using type = std::size_t;
    static constexpr bool depends_on_args = false;
  };
  constexpr NumOfArgs() = default;
  template<typename R, typename S, typename... Args>
  constexpr std::size_t run(const S&, Args&&...)const{
    return sizeof...(Args);
  }
  /*(中略)*/
};
namespace{
constexpr Lampads<NumOfArgs> num_of_args{};
}
```
`num_of_args`は`Lampads<NumOfArgs>`型のオブジェクトそのものです．`NumOfArgs::run`の返すものは`sizeof...(Args)`．戻り値型は`std::size_t`固定なので引数に依存しません．

```cpp
template<long long N, char c, char... Chars>
struct udl_to_variadic_placeholder{
  using type = typename std::enable_if<'0'<=c && c<='9', typename udl_to_variadic_placeholder<N*10 + c-'0', Chars...>::type>::type;
};
template<long long N>
struct udl_to_variadic_placeholder<N,'\0'>{using type = Lampads<VariadicPlaceholder<N>>;};
template<char... Chars>
constexpr typename udl_to_variadic_placeholder<0, Chars...,'\0'>::type operator""_tail(){
   return typename udl_to_variadic_placeholder<0, Chars...,'\0'>::type{};
}
```
続いて，`operator"" _tail`ですが，`operator"" _`の時と殆ど変わりませんね．`2_tail`は`Lampads<VariadicPlaceholder<2>>{}`になります．

```cpp
template<typename... Params>
constexpr Lampads<Self<unwrap_lampads_or_valize_t<Params>...>> self(Params&&... ps){
   return Lampads<Self<unwrap_lampads_or_valize_t<Params>...>>(unwrap_lampads_or_valize(veiler::forward<Params>(ps))...);
}
```
そして`self`です．引数を全て`unwrap_lampads_or_valize`して`Self`のコンストラクタに渡す，というコードです．つまり，あの式は

```cpp
Lampads<IfImpl<
  Eq<
    NumOfArgs,
    Val<unsigned long>
  >,
  Placeholder<1>,
  Self<Add<Placeholder<1>, Placeholder<2>>, VariadicPlaceholder<2>>
>>(
  Eq<NumOfArgs,Val<unsigned long>>{
    NumOfArgs{},
    Val<unsigned long>(1ul)
  },
  Placeholder<1>{},
  Self<Add<Placeholder<1>, Placeholder<2>>, VariadicPlaceholder<2>>{
    Add<Placeholder<1>, Placeholder<2>>{
      Placeholder<1>{},
      Placeholder<2>{}
    },
    VariadicPlaceholder<2>{}
  }
)(1, 2, 3, 4)
```
となります．長いと思うかもしれませんが，下半分の型名を省略すれば

```cpp
Lampads<IfImpl<
  Eq<
    NumOfArgs,
    Val<unsigned long>
  >,
  Placeholder<1>,
  Self<Add<Placeholder<1>, Placeholder<2>>, VariadicPlaceholder<2>>
>>({{},1ul},{},{{{},{}},{}})(1, 2, 3, 4)
```
となりますから，中身は殆どありません．
　さて，今回は改めて`Lampads<T>::call_impl<pass::by_reference>::call`の呼び出しからやり直してみましょう．まず，`LampadsImpl<T>`はどちらが選ばれるのでしょうか．`ret_type::depends_on_args`がカギ，でしたね．`IfImpl::ret_type`は

```cpp
  struct ret_type_t:std::true_type{
    template<typename... Args>
    using type = typename _IfImpl_ret_type<T, U>::template type<Args...>;
    static constexpr bool depends_on_args = _IfImpl_ret_type<T, U>::depends_on_args;
  };
 public:
  using ret_type = typename std::conditional<T::ret_type::value || U::ret_type::value, ret_type_t, ret_type_dummy>::type;
```
ここで，`T`は`Placeholder<1>`ですから，少なくとも`T::ret_type::value`は`true`です．よって`ret_type_t`を参照します．`_IfImpl_ret_type<T, U>`は`T::ret_type`と`U::ret_type`によって分岐していますので，ここで一度`Self`の`ret_type`を調べておきましょう．以下に`Self`を示します．

```cpp
template<typename... Params>
class Self{
  veiler::tuple<Params...> params;
  template<typename R, long long... Indices, typename S, typename Tuple>
  constexpr R run_impl_impl(veiler::index_tuple<Indices...>, const S& s, Tuple&& tpl)const{
    return veiler::forward<R>(s.template run<R>(s, veiler::get<Indices>(veiler::forward<Tuple>(tpl))...));
  }
  template<typename R, long long... Indices, typename S, typename... Args>
  constexpr R run_impl(veiler::index_tuple<Indices...>, const S& s, Args&&... args)const{
    return run_impl_impl<R>(
      veiler::make_index_range<0,
                               tuple_size<decltype(veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<R>(s, veiler::forward<Args>(args)...)...))>{}
      >{},
      s,
      veiler::forward<decltype(veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<R>(s, veiler::forward<Args>(args)...)...))>(
                               veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<R>(s, veiler::forward<Args>(args)...)...))
      );
  }
 public:
  using ret_type = ret_type_dummy;
  constexpr Self(Params&&... ps):params(veiler::forward<Params>(ps)...){}
  template<typename R, typename S, typename... Args>
  constexpr R run(const S& s, Args&&... args)const{return run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...);}
  /*(中略)*/
};
```
`ret_type`が`ret_type_dummy`にaliasされていますね．これは何回か出てきてはいましたが紹介はまだでした．

```cpp
struct ret_type_dummy:std::false_type{
  template<typename...>using type = void;
  static constexpr bool depends_on_args = true;
};
```
戻り値の型`type<Args...>`が`void`なのも目を引きますが，これまではずっと`true`であった`value`が`false`になっています．これは「意味のあるret_typeが定義できない」場合に使うダミーなのです．そして，`_IfImpl_ret_type`で今回の場合に合致するのは，以下の特殊化です．

```cpp
template<typename T, typename U>
struct _IfImpl_ret_type<T, U, typename std::enable_if< T::ret_type::value && !U::ret_type::value>::type>{
  template<typename... Args>
  using type = typename T::ret_type::template type<Args...>;
  static constexpr bool depends_on_args = T::ret_type::depends_on_args;
};
```
`U::ret_type::value`が`false`である場合，`_IfImpl_ret_type`は`T::ret_type`に準ずる，ということです．つまり，`IfImpl::ret_type`は`Placeholder<1>::ret_type`と等しい，ということになります．従って，ケース3を思い出せばよいですね．

```cpp
template<typename T>
class LampadsImpl<T, typename std::enable_if<T::ret_type::depends_on_args == true>::type>{
 protected:
  template<pass, typename = void>struct call_impl;
  /*(中略)*/
  template<typename Dummy>
  struct call_impl<pass::by_reference, Dummy>{
    template<typename... Args>
    static constexpr auto call(const T& t, Args&&... args)
      ->decltype(t.template run<typename T::ret_type::template type<unremove_reference_decay<Args>...>>(t, veiler::forward<unremove_reference_decay<Args>>(args)...)){
          return t.template run<typename T::ret_type::template type<unremove_reference_decay<Args>...>>(t, veiler::forward<unremove_reference_decay<Args>>(args)...);
    }
  };
};
```
ケース3では全く触れませんでしたが，`unremove_reference_decay<T>`とは，

```cpp
template<typename T,
         typename U = typename std::remove_reference<T>::type,
         bool = std::is_array<U>::value || std::is_function<U>::value>
struct unremove_reference_decay_impl;
template<typename T, typename U>
struct unremove_reference_decay_impl<T, U, true>{using type = typename std::decay<U>::type;};
template<typename T, typename U>
struct unremove_reference_decay_impl<T, U, false>{using type = T;};
template<typename T>
using unremove_reference_decay = typename unremove_reference_decay_impl<T>::type;
```
配列や関数を直接受け取った場合，適切なポインタに置き換えるためのメタ関数です(`std::decay`では参照が外れてしまいますが，`unremove_reference_decay`は配列や関数でなければ参照を保持します)．今回は配列や関数は引数に存在しないので無視して構いません．

```cpp
Placeholder<1>::ret_type::type<int, int, int, int>
```
は

```cpp
int
```
ですから，

```cpp
/*tを
IfImpl<
  Eq<
    NumOfArgs,
    Val<unsigned long>
  >,
  Placeholder<1>,
  Self<Add<Placeholder<1>, Placeholder<2>>, VariadicPlaceholder<2>>
>({{},1ul},{},{{{},{}},{}}) とするなら*/
t.run<int>(t, 1, 2, 3, 4)
```
即ち，

```cpp
Eq<NumOfArgs, Val<unsigned long>>{{}, 1ul}.run<int>(t, 1, 2, 3, 4) ?
Placeholder<1>{}.run<int>(t, 1, 2, 3, 4) :
Self<Add<Placeholder<1>, Placeholder<2>>, VariadicPlaceholder<2>>{{{},{}},{}}.run<int>(t, 1, 2, 3, 4);
```
さて，引数の数は`4ul`ですから，`1ul`とは等しくありません．従って，この式は

```cpp
Self<Add<Placeholder<1>, Placeholder<2>>, VariadicPlaceholder<2>>{{{},{}},{}}.run<int>(t, 1, 2, 3, 4);
```
となります．`Self`のコンストラクタは，

```cpp
  veiler::tuple<Params...> params;
  constexpr Self(Params&&... ps):params(veiler::forward<Params>(ps)...){}
```
とありますから，paramsに`Add<Placeholder<1>, Placeholder<2>>{}, VariadicPlaceholder<2>{}`が入ります．そして，`run`は実質`run_impl`への委譲のみです．`run_impl`までを展開しましょう．

```cpp
run_impl_impl<int>(
  veiler::make_index_range<0,
                           tuple_size<decltype(veiler::tuple_cat(veiler::get<index>(params).template bind_run<int>(t, 1, 2, 3, 4)...))>{}
  >{},
  t,
  veiler::forward<decltype(veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<int>(t, 1, 2, 3, 4)...))>(
                           veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<int>(t, 1, 2, 3, 4)...)
  )
)
```
`index`は`run`の時に渡された`index_tuple`の中身で，`Params...`から生成されているので今回は`0, 1`です．従って，


```cpp
run_impl_impl<int>(
  veiler::make_index_range<0,
                           tuple_size<decltype(veiler::tuple_cat(veiler::get<0>(params).bind_run<int>(t, 1, 2, 3, 4),
                                                                 veiler::get<1>(params).bind_run<int>(t, 1, 2, 3, 4)))>{}
  >{},
  t,
  veiler::forward<decltype(veiler::tuple_cat(veiler::get<0>(params).bind_run<int>(t, 1, 2, 3, 4),
                                             veiler::get<1>(params).bind_run<int>(t, 1, 2, 3, 4)))>(
                           veiler::tuple_cat(veiler::get<0>(params).bind_run<int>(t, 1, 2, 3, 4),
                                             veiler::get<1>(params).bind_run<int>(t, 1, 2, 3, 4))
  )
)
```
ですから，`params`の中身を取り出してしまえば

```cpp
run_impl_impl<int>(
  veiler::make_index_range<0,
                           tuple_size<decltype(veiler::tuple_cat(Add<Placeholder<1>, Placeholder<2>>{}.bind_run<int>(t, 1, 2, 3, 4),
                                                                              VariadicPlaceholder<2>{}.bind_run<int>(t, 1, 2, 3, 4)))>{}
  >{},
  t,
  veiler::forward<decltype(veiler::tuple_cat(Add<Placeholder<1>, Placeholder<2>>{}.bind_run<int>(t, 1, 2, 3, 4),
                                                          VariadicPlaceholder<2>{}.bind_run<int>(t, 1, 2, 3, 4)))>(
                           veiler::tuple_cat(Add<Placeholder<1>, Placeholder<2>>{}.bind_run<int>(t, 1, 2, 3, 4),
                                                          VariadicPlaceholder<2>{}.bind_run<int>(t, 1, 2, 3, 4))
  )
)
```
さて，`bind_run`という見かけないメンバ関数が呼ばれています，これが多くの[^15]`/*(中略)*/`の正体です．これは大雑把に言ってしまえば`std::make_tuple(run(args...))`に相当する処理を行っています．何故tupleに包むのかは，以下のコードによって説明できます．

[^15]: `Val`や`Placeholder`等の`Lampads<T>`の`T`に相当するクラスにおける`/*(中略)*/`が`bind_run`に関わるものです．`Lampads`や`LampadsImpl`における`/*(中略)*/`はまた別です．

```cpp
template<long long N>
struct VariadicPlaceholder{
  static_assert(N >= 0, "Veiler.Lampads - VariadicPlaceholder can't be negative.");
 private:
  template<long long... Indices, typename... Args>
  constexpr auto run_impl(veiler::index_tuple<Indices...>, Args&&... args)const
    ->veiler::tuple<veiler::type_at<veiler::type_tuple<Args...>, Indices>...>{
    return veiler::make_tuple(wrap_refil_if_ref(veiler::get<Indices>(veiler::forward_as_tuple<Args&&...>(veiler::forward<Args>(args)...)))...);
  }
 public:
  using ret_type = ret_type_dummy;
  constexpr VariadicPlaceholder() = default;
  template<typename R, typename S, typename... Args>
  constexpr R run(const S&, Args&&...)const; //Veiler.Lampads - can't use variadic placeholder except in self and bind.
  template<typename R, typename S, typename... Args, typename std::enable_if<N < sizeof...(Args)>::type* = nullptr>
  constexpr auto bind_run(const S&, Args&&... args)const
    ->decltype(this->run_impl(veiler::make_index_range<N, sizeof...(Args)>{}, veiler::forward<Args>(args)...)){
        return this->run_impl(veiler::make_index_range<N, sizeof...(Args)>{}, veiler::forward<Args>(args)...);
  }
  template<typename R, typename S, typename... Args, typename std::enable_if<(N >= sizeof...(Args))>::type* = nullptr>
  constexpr auto bind_run(const S&, Args&&...)const
    ->veiler::tuple<>{
    return veiler::make_tuple();
  }
};
```
`VariadicPlaceholder<N>`，0-indexedで第`N`引数より後ろ全てを表すプレースホルダ．これを実現するためには，

1. `Self`側で`VariadicPlacholder<N>`を受け取った時にだけ特殊な操作を実現するか[^16]，
2. 複数の値を返す

必要があります．そう，「複数の値」です．Veiler.Lampadsでは「`tuple`で返す」という方法を選択しました．`VariadicPlaceholder<N>::bind_run(t, args...)`は，第`N`引数以降の引数全てが入った`tuple`を返します．

[^16]: ちゃんと読んだわけではないですが多分SproutのBindに対しての可変長プレースホルダの実装はこれだと思います．プレースホルダ側が特に機能を持っていなかったので．あ，全く触れてませんでしたが，元々Variadic Placeholderの元ネタは[こちら](http://boleros.hateblo.jp/entry/20130720/1374322843)です．

　これで繋がりました．何故`tuple`で包むだけの`bind_run`が各実装に入り込んでいるのか．答えは，Variadic Placeholderを実装するためだったのです．それでは，式を展開します．

```cpp
run_impl_impl<int>(
  veiler::make_index_range<0,
                           tuple_size<decltype(veiler::tuple_cat(make_tuple(1 + 2), make_tuple(3, 4)))>{}
  >{},
  t,
  veiler::forward<decltype(veiler::tuple_cat(make_tuple(1 + 2), make_tuple(3, 4)))>(
                           veiler::tuple_cat(make_tuple(1 + 2), make_tuple(3, 4))
  )
)
```
`tuple_cat`は，引数の全ての`tuple`の中身を展開，再統合する関数ですので，

```cpp
run_impl_impl<int>(
  veiler::make_index_range<0,
                           tuple_size<decltype(make_tuple(1 + 2, 3, 4))>{}
  >{},
  t,
  veiler::forward<decltype(make_tuple(1 + 2, 3, 4))>(
                           make_tuple(1 + 2, 3, 4)
  )
)
```
加算とforwardingを展開して

```cpp
run_impl_impl<int>(
  veiler::make_index_range<0,
                           tuple_size<decltype(make_tuple(3, 3, 4))>{}
  >{},
  t,
  make_tuple(3, 3, 4)
)
```
`tuple_size<T<Types...>>`は`sizeof...(Types)`を得るためのメタ関数ですから，

```cpp
run_impl_impl<int>(
  veiler::make_index_range<0, 3>{},
  t,
  make_tuple(3, 3, 4)
)
```
となります．`run_impl_impl`は

```cpp
  template<typename R, long long... Indices, typename S, typename Tuple>
  constexpr R run_impl_impl(veiler::index_tuple<Indices...>, const S& s, Tuple&& tpl)const{
    return veiler::forward<R>(s.template run<R>(s, veiler::get<Indices>(veiler::forward<Tuple>(tpl))...));
  }
```
ですから，展開すると

```cpp
veiler::forward<int>(t.template run<int>(t, 3, 3, 4))
```
ここで，`t`は元々`Lampads<T>`のメンバですから，再帰が実現しています．2・3度繰り返せば，`10`が得られるでしょう．

　さて，それでは話を最初に戻しましょう．何故`ret_type::type<Args...>`や，`run`の先頭に`t`を渡す必要があったのか，です．結論から言えば共に「`Self`で使うから」で，後者は明らかに`Self`で使っていますが，前者は説明の中ではあまり必要性が感じられなかったのではないでしょうか．先述の`Self`のコードを見ると，`run`，`run_impl`，`run_impl_impl`全ての戻り値型が`R`となっています．何故`decltype`による推論を行わないのでしょうか．簡単な話で，「無限再帰に陥るから」です．`decltype(t.run(~~))`とすると，`t.run(~~)`の中で`t.run(~~)`が出てきてしまいますから，式の形が定まりません．となると，`decltype`のしようがありません．従って，`Self`には`t`のみならず，その戻り値型も渡さなければならないのです．しかも，`Self`の戻り値型は分からない状態で，なんとか戻り値型を取得せねばなりません．この「求められないところは無視しながら分かる範囲で戻り値型を推論する仕組み」こそが`ret_type::type<Args...>`というわけです．そして，「戻り値型が求められない」ことを示すのが`ret_type_dummy`．`Self`と`Self`を含む式，そして`IfImpl`のThen(`T`)とElse(`U`)双方の`ret_type`が`ret_type_dummy`だった場合がこれに該当します．

　ときに，「名前の無い関数の再帰」というのは，関数型プログラミングやラムダ計算に触れたことのない人にとってはなんとも不思議な感じはしないでしょうか．再帰呼び出しするなら，名前が必要なはずですよね．実は「名前の無い関数の再帰」は無名再帰と呼ばれるのですが，有名な無名再帰の手法の1つに「不動点コンビネータ」というものがあります．詳細はおググりいただくとして，具体的には以下の様なコードにおける`fix`が不動点コンビネータとなります．

```cpp
auto fact_impl = [](auto self, int x){
  return x == 0 ? 1 : x * self(x - 1);
};
auto fact = fix(fact_impl);
fact(4) //4 * 3 * 2 * 1 * 1 = 24
```
`fix`は関数`fact_impl`を受け取ると，`fact_impl`の第1引数を`fact_impl`として部分適用した新たな関数を返します．当然，残りの引数`x`を与えてやれば`fact_impl(fact_impl, x)`として呼び出されますから，見事再帰が実現できました，という寸法です．気づきましたでしょうか？`Lampads<T>`は`T`に対する不動点コンビネータなのです．そして，「隠された第0引数」にアクセスするための方法こそが，Selfなのです．

#### **まとめ**
　このケースからは，以下のようなことを学ぶことが出来ます．

1. Number Of Argsの実態はクラス`NumOfArgs`である．`Lampads`に包まれた状態の`num_of_args`がユーザーに提供される．
2. Selfの実態はテンプレートクラス`Self`である．`self`を通して，`Lampads`に包まれた状態でユーザーに提供される．
3. Variadic Placeholderの実態はテンプレートクラス`VariadicPlaceholder`である．`operator"" _tail`を通して，`Lampads`に包まれた状態でユーザーに提供される．
4. `ret_type::type<Args...>`は`Self`の戻り値型を決定するためのメタ関数である．
5. `bind_run`関数はVariadic Templateを実現するために存在する，`tuple`を返す関数である．
6. `run`や`bind_run`の第1引数に渡される`t`は`Self`のために渡される．`Lampads<T>`は`T`の不動点コンビネータとしての役割を持つ．
7. **[tupleは便利](https://gist.github.com/wx257osn2/8051199)である．**[^17]

[^17]: ここまで多用すると，やはり昨年constexprな対数オーダーtupleを実装しておいて本当に良かったなぁと思います．まぁ，[今では](http://togetter.com/li/671683) [対数オーダーなんて](https://github.com/fimbul/shiro) [時代遅れ](https://twitter.com/bolero_MURAKAMI/status/513176025090363393)だったりするのですが…

### **おまけ**
　ケース5によって，Veiler.Lampadsの全貌が見えました．`Lampads`や各無名関数実装に深く入り込んだ~~小汚い~~ハックによって，SelfとVariadic Placholderは成り立っているのです．さて，それでは未解説内容について適当に流していきましょう．ここまで読んできた方なら，もうLampadsを直接読むことも不可能ではないはずです．

#### **Bind**

```cpp
using has_result_type = VEILER_HASTUR_TAG_CREATE(result_type);
template<bool, typename, typename...>class Bind;
template<typename F, typename... Params>
class Bind<true, F, Params...>{
  F f;
  veiler::tuple<Params...> params;
  template<typename R, long long... Indices, typename S, typename... Args>
  constexpr auto run_impl(veiler::index_tuple<Indices...>, const S& s, Args&&... args)const
    ->decltype(veiler::apply(f, veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<R>(s, veiler::forward<Args>(args)...)...))){
        return veiler::apply(f, veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<R>(s, veiler::forward<Args>(args)...)...));
  }
 public:
  struct ret_type:std::true_type{
    template<typename...>
    using type = typename veiler::func_troy<F>::result_type;
    static constexpr bool depends_on_args = false;
  };
  constexpr Bind(F&& f, Params&&... params):f(veiler::forward<F>(f)), params(veiler::forward<Params>(params)...){}
  template<typename R, typename S, typename... Args>
  constexpr auto run(const S& s, Args&&... args)const
    ->decltype(this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...)){
        return this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...);
  }
  template<typename R, typename S, typename... Args>
  constexpr auto bind_run(const S& s, Args&&... args)const
    ->decltype(this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...)){
        return this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...);
  }
};
template<typename F, typename... Params>
class Bind<false, F, Params...>{
  F f;
  veiler::tuple<Params...> params;
  template<typename R, long long... Indices, typename S, typename... Args>
  constexpr auto run_impl(veiler::index_tuple<Indices...>, const S& s, Args&&... args)const
    ->decltype(veiler::apply(f, veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<R>(s, veiler::forward<Args>(args)...)...))){
        return veiler::apply(f, veiler::tuple_cat(veiler::get<Indices>(params).template bind_run<R>(s, veiler::forward<Args>(args)...)...));
  }
 public:
  using ret_type = ret_type_dummy;
  constexpr Bind(F&& f, Params&&... params):f(veiler::forward<F>(f)), params(veiler::forward<Params>(params)...){}
  template<typename R, typename S, typename... Args>
  constexpr auto run(const S& s, Args&&... args)const
    ->decltype(this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...)){
        return this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...);
  }
  template<typename R, typename S, typename... Args>
  constexpr auto bind_run(const S& s, Args&&... args)const
    ->decltype(this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...)){
        return this->run_impl<R>(veiler::make_indexes<Params...>{}, s, veiler::forward<Args>(args)...);
  }
};

template<typename F, typename... Params>
constexpr Lampads<Bind<veiler::hastur<has_result_type>::type<veiler::func_troy<F>>::value, unremove_reference_decay<F>, unwrap_lampads_or_valize_t<Params>...>> bind(F&& f, Params&&... ps){
   return Lampads<Bind<veiler::hastur<has_result_type>::type<veiler::func_troy<F>>::value, unremove_reference_decay<F>, unwrap_lampads_or_valize_t<Params>...>>(veiler::forward<F>(f), unwrap_lampads_or_valize(veiler::forward<Params>(ps))...);
}
```
Bindの実態`Bind`は，「部分適用する関数`F`に`result_type`が存在するか否か」で特殊化されています．具体的には，

1. 関数ポインタ
2. `result_type`が定義された関数オブジェクト

のいずれかであれば，`Bind<F, ...>`は`depends_on_args`が`false`になります．先述の通り，**Veiler.Lampadsは出来る限り`result_type`を定義します**．あとはおおよそ`Self`と同じ動作です．`bind_run`という名前を考えれば当然ですよね？

#### **call-by-value**
　さて，call-by-referenceでの解説を行ってきましたが，call-by-valueではどうなるのでしょうか．これは，`LampadsImpl<T>::call_impl<pass::by_value>::call`を見れば分かります．

```cpp
  template<typename Dummy>
  struct call_impl<pass::by_value, Dummy>{
    template<typename... Args>
    static constexpr auto call(const T& t, Args&&... args)
      ->decltype(t.template run<typename T::ret_type::template type<unwrap_refil_t<Args>...>>(t, unwrap_refil_or_copy(veiler::forward<Args>(args))...)){
          return t.template run<typename T::ret_type::template type<unwrap_refil_t<Args>...>>(t, unwrap_refil_or_copy(veiler::forward<Args>(args))...);
    }
  };
```
簡単ですね．`veiler::refil<T>`なら`T&`に，それ以外はコピーする．そのままです．これは`depends_on_args`が`true`の場合ですが，`false`の場合でも大した差はありません．

#### **Polymorphic Accessor**
　`VEILER_LAMPADS_POLYMORPHIC_MEMBER_ACCESSOR`や`VEILER_LAMPADS_POLYMORPHIC_FUNCTION_ACCESSOR`自体は，実は`Lampads`とは何の関わりもないクラスなのです．特に後者は，引数をforwardingするだけのラッパクラスです．また前者は，`operator->*`をオーバーロードして`a ->* member_accessor`の結果を`a.member`にしているだけです．ですから，Veiler.Lampadsとは関わりのない文脈でも正しく動作します．ただし，member_accessorの`operator()`に関しては都合が変わります．これはリファレンスに

>Bindのような挙動を示します

とある通り，`Lampads`を返すのです．そして，戻り値の型が`operator->*`をさらにオーバーロードしている…という構図です．まぁ，`Self`が読めれば読めるでしょう．

#### **Clangのバグへの対処**
　ここまで解説を行ってきましたが，ここで1つ伝えておかなければならないことがあります．それは，「本解説中のコードはGCC用である」ということです．そう，Veiler.LampadsはGCCとClangでコードが違うのです．実際ファイルを開いてみればわかると思いますが，`VEILER_LAMPADS_RECURSION_*`というマクロが随所に書かれているはずです．これらは，GCCでは全て単に消えます．というのも，Clangのバグに対処するためのworkaroundだからです．
　Clangには「[相互再帰する constexpr 関数テンプレートを実体化すると、テンプレート実体化が無限再帰してコンパイルエラーになる](http://www.boleros.x0.com/doc/sproutwiki/index.yellow.php?%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E6%80%A7%E8%83%BD%E6%AF%94%E8%BC%83)」という致命的なバグがあります．つまり，`Self`の`run`を使ったら再帰深度超過でコンパイルできなくなるということです．これを避けるために，Clangでビルドした時のみ再帰深度の限界を規定しておき，全ての関数呼び出しをカウントして，`Self`(と一応`Bind`)の`run`で「もう1周関数呼び出しできるか」を確認，不可能な程度に再帰カウンタが増えていたら関数呼び出しをダミーに差し替える，というworkaroundを挟んであります．**Veiler.Lampads全体における小汚いハックがSelfを実現させているのです．**

# **謝辞**
　当ライブラリを開発するにあたって，多くの人に助けてもらいました．
　「constexprなラムダライブラリは作れる！」という雑談をした後，当ライブラリの原型となる物を一晩で作って見せてくれた[phi16(@phi16_)](https://twitter.com/phi16_)，昨年のtupleの制作も元はといえばこれのため．私に膨大なモチベーションを与えてくれました．また，`(1_ % 2 == 0)(3) == true`の一件[^18]でも大いにお世話になりました．
[^18]: 戻り値型の推論をした後，全ての無名関数実装の呼び出しに最上位の型を適用する，というトンデモ実装になっていた頃があり，バグを解消するために相談したことがありました．今でいうところの`(ret<bool>(1_) % ret<bool>(val(2)) == ret<bool>(val(0)))(3)`と同じ挙動をしたわけです(`1_`に`int`を与えれば，式全体の戻り値型は`int`同士の比較なので`bool`となります．それが各要素に伝播していって件のような形となり，当然`bool(3)`(`1`)を`bool(2)`(`1`)で割った余りは`0`なので，`true`となります)．

　Variadic PlaceholderやPlaceholder UDLなどは[ボレロ村上(@bolero_MURAKAMI)](https://twitter.com/bolero_MURAKAMI)氏の[アイデア](http://boleros.hateblo.jp/entry/20130720/1374322843)を ~~丸パクリ~~ 参考にさせていただきました．またconstexpr周りのバグは，大抵調べたら氏のブログやスライドが出てくるため，いつもいつも参考にさせて頂いております．
　大変便利な開発環境・[ProcGarden(通称 : 鳥小屋)](http://sc.yutopp.net/)を提供してくれた[ぶんちょう(@yutopp)](https://twitter.com/yutopp)さん．11月入ってからのLampadsのデバッグはほぼ鳥小屋だけでやりました．大変便利．鳥小屋コントリビュータとして今後共頑張ります．
　週26コマの講義による多忙を言い訳にTemple/Deus/Lampadsといったライブラリ群の公開をだらだらと先延ばしにしていた頃に，定数オーダーgetかつコンパイル時間爆速なtupleを一晩で作り上げ，私のやる気スイッチを押してくれた[のじ(@fimbul11)](https://twitter.com/fimbul11)さん．日々刺激を受けております．
　去年のAdCでconstexpr-Lambda書くかも～って言ったら期待を寄せてくれた(覚えがあるものの，ツイートは探しきれず…)[すいかばー(@suibaka)](https://twitter.com/suibaka)さん．1年遅れたけどちゃんと書きましたよ．
　そして，私のTwitterのTLにいらっしゃるC++erの皆様．Veiler.Lampadsは皆様のツイートの産物みたいなものです．

　皆様に多大な感謝を．


-----

明日は@yohhoyさんです．

-----