オレオレ switch case 改良したよー
改良しました。
前回:http://d.hatena.ne.jp/osyo-manga/20110329/1301361828
☆使い方
switch_(値) |=case_(条件)|(式) // | 演算子で式を設定 |=case_(条件) // (式)がない場合は、fall through |=case_(条件)&(値) // & 演算子で評価を行わずに、値をそのまま返す |=case_<型>()|(式) // 引数型でパターンマッチ …
☆前回からの変更点
アダプタに使用している演算子は適当。
Boost.Lambda だとアダプタが使えなかったりします。
型によるパターンマッチは実行時に走査するので、速度を優先するなら mpl::switch_ とか使ったほうがいいです。
☆サンプル
#include <kmt/switch_case.hpp> #include <boost/lexical_cast.hpp> #include <iostream> #include <string> namespace sc = kmt::switch_case; template<typename T> void check(const T& t){ std::string result; result = sc::switch_(t) |=sc::case_<std::string>()&std::string("string") |=sc::case_<int>()&std::string("int") |=sc::default_&std::string("no match"); std::cout << result << std::endl; } void fizz_buzz(int n){ using sc::_; std::string result = sc::switch_(n%3, n%5) |=sc::case_(0,0)|sc::var(std::string("fizz_buzz")) |=sc::case_(0,_)|sc::var(std::string("fizz")) |=sc::case_(_,0)&(std::string("buzz")) // & で渡してもOK |=sc::default_&(boost::lexical_cast<std::string>(n)); std::cout << result << ","; } int main(){ std::string input = "yes"; std::string result = sc::switch_(input) |=sc::case_(std::string("yes")) |=sc::case_(std::string("y")) |=sc::case_(std::string("Y"))|sc::var(std::string("ok")) |=sc::default_&std::string("error"); std::cout << result << std::endl; // 型によるパターンマッチ check(std::string("")); check(0); check(0.0f); // fizz buzz for(int i = 1 ; i < 20 ; ++i){ fizz_buzz(i); } std::cout << std::endl; return 0; }
[出力]
ok string int no match 1,2,fizz,4,buzz,fizz,7,8,fizz,buzz,11,fizz,13,14,fizz_buzz,16,17,fizz,19,
☆今後
- 引数型が複数の場合は Boost.Variant を使用
- 明示的に fall through と break を定義
- 複数の式/値の設定
- ソースがアレなのでなんとかしたい
他になにかあるかな。
見るに耐えないソースはここら辺。