void show_many(const many& xs){ std::cout << "["; for(int i = 0; i < xs.size(); i++){ if(i > 0){ std::cout << ", "; } show_any(xs[i]); } std::cout << "]"; }
int total3(many& xs){ ENTRYPOINT: int i; boost::any x; int result = 0; for(i = 0; i < xs.size(); i++){ x = xs[i]; #ifdef VERBOSE std::cout << "xs:"; show_many(xs); std::cout << ", x:"; show_any(x); std::cout << ", i:" << i << ", result:" << result << std::endl; #endif if(is_integer(x)){ result += any_cast<int>(x); }else{ // result += total(any_cast<many>(x))相当のことを実現するために // 1: 現在のローカル変数をスタックに保存する stack.push(make_tuple(xs, i, x, result)); // 2: 引数xsを書き換える xs = any_cast<many>(x); // 3: 関数冒頭へジャンプ goto ENTRYPOINT; RETURNPOINT: // 6: 呼び出された関数からreturnするとここに戻ってくる // 7: スタックに保存しておいた値を復元する frame_t f = stack.top(); stack.pop(); xs = std::get<0>(f); i = std::get<1>(f); x = std::get<2>(f); result = std::get<3>(f); // 8: 関数の返り値を使う result += function_result; } } // ループが終わったのでreturn result;に相当することをやる if(!stack.empty()){ // スタックが空でないなら // 4: 返り値を決められた場所に保存 function_result = result; // 5: 関数呼び出し直後(上記6)に戻る goto RETURNPOINT; } // スタックが空の時は自前管理の呼び出しではないので本物のreturnをする return result; }
int total2(const many& xs){ int i; boost::any x; int result = 0; for(i = 0; i < xs.size(); i++){ x = xs[i]; #ifdef VERBOSE std::cout << "xs:"; show_many(xs); std::cout << ", x:"; show_any(x); std::cout << ", i:" << i << ", result:" << result << std::endl; #endif if(is_integer(x)){ result += any_cast<int>(x); }else{ result += total2(any_cast<many>(x)); } } return result; }
template <class T, class S> bool operator==(const S& s, const many<T>& m) { return m.size() == s.size() && S(m.begin(), m.end()) == s; }