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;
}
Beispiel #4
0
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;
}