続・SWITCH
2007/11/6のSWITCHマクロを無意味に機能強化
これを使えば、誰でもスパゲティプログラムが書ける(書いてどうする)。
俺はプリプロセスを通した後のコードを読めねぇ。
変更点
namespace ns_switch { template<class C> inline const C* select(const char* str, const wchar_t* wcs) { return str; } template<> inline const wchar_t* select<wchar_t>(const char* str, const wchar_t* wcs) { return wcs; } template <class T, T v> struct constant { typedef T type; static const T value = v; }; template <bool flag, class T, class U> struct select_type { typedef U type; }; template <class T, class U> struct select_type<true,T,U> { typedef T type; }; template <class T, class U> struct is_same_type:ns_switch::constant<bool, false> {}; template <class T> struct is_same_type<T,T>:ns_switch::constant<bool, true> {}; #define STR2(X) #X #define STR(X) STR2(X) #define WSTR(X) CAT(L,STR(X)) #define CAT2(X,Y) X##Y #define CAT(X,Y) CAT2(X,Y) #define SIZE(X) (sizeof(X)/sizeof((X)[0])) template <class T, char LP='-', char RP='-'> class range_t; template <class T> class range_t<T,'[',']'> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return low <= x && x <= high; } private: T low; T high; }; template <class T> class range_t<T,'[',')'> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return low <= x && x < high; } private: T low; T high; }; template <class T> class range_t<T,'(',']'> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return low < x && x <= high; } private: T low; T high; }; template <class T> class range_t<T,'(',')'> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return low < x && x < high; } private: T low; T high; }; template <class T> class range_t<T,']','['> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return x <= low || high <= x; } private: T low; T high; }; template <class T> class range_t<T,']','('> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return x <= low || high < x; } private: T low; T high; }; template <class T> class range_t<T,')','['> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return x < low || high <= x; } private: T low; T high; }; template <class T> class range_t<T,')','('> { public: range_t(const T& l, const T& h):low(l),high(h){} bool check(const T& x) const { return x < low || high < x; } private: T low; T high; }; template <class T> class range_t<T,']','-'> { public: range_t(const T& l):low(l){} bool check(const T& x) const { return x <= low; } const range_t& x() const {return *this; } range_t<T,']','['> operator[](const T& h) const { return range_t<T,']','['>(low,h); } range_t<T,']','('> operator()(const T& h) const { return range_t<T,']','('>(low,h); } private: T low; }; template <class T> class range_t<T,')','-'> { public: range_t(const T& l):low(l){} bool check(const T& x) const { return x < low; } const range_t& x() const {return *this; } range_t<T,')','['> operator[](const T& h) const { return range_t<T,')','['>(low,h); } range_t<T,')','('> operator()(const T& h) const { return range_t<T,')','('>(low,h); } private: T low; }; template <class T> class range_t<T,'-','['> { public: range_t(const T& h):high(h){} bool check(const T& x) const { return high <= x; } private: T high; }; template <class T> class range_t<T,'-','('> { public: range_t(const T& h):high(h){} bool check(const T& x) const { return high < x; } private: T high; }; template <class T, char LP> class range_t<T,LP,'-'> { public: range_t<T,LP,']'> operator[](const T& h) const { return range_t<T,LP,']'>(low,h); } range_t<T,LP,')'> operator()(const T& h) const { return range_t<T,LP,')'>(low,h); } range_t(const T& l):low(l){} private: T low; }; template <class T> struct range_t<T,'*','*'> { range_t() {} range_t<T,'-','['> operator[](const T& h) const { return range_t<T,'-','['>(h); } range_t<T,'-','('> operator()(const T& h) const { return range_t<T,'-','('>(h); } }; template <class T> struct range_t<T,'*','-'> { range_t() {} range_t<T,']','-'> operator[](const T& l) const { return range_t<T,']','-'>(l); } range_t<T,')','-'> operator()(const T& l) const { return range_t<T,')','-'>(l); } range_t<T,'*','*'> x() const {return range_t<T,'*','*'>(); } }; template <class T> struct range_t<T,'-','-'> { range_t() {} range_t<T,'[','-'> operator[](const T& l) const { return range_t<T,'[','-'>(l); } range_t<T,'(','-'> operator()(const T& l) const { return range_t<T,'(','-'>(l); } range_t<T,'*','-'> x() const {return range_t<T,'*','-'>(); } }; template <class T> struct switchtype { typedef T type; }; template <class T> struct same_type { typedef T type; }; template <class CHAR> struct switchtype<CHAR*> { typedef std::basic_string<CHAR> type; }; template <class CHAR,int N> struct switchtype<const CHAR[N]> { typedef std::basic_string<CHAR> type; }; template <class CHAR,int N> struct switchtype<CHAR[N]> { typedef std::basic_string<CHAR> type; }; template <class CHAR> struct switchtype<const CHAR[]> { typedef std::basic_string<CHAR> type; }; template <class CHAR> struct switchtype<CHAR[]> { typedef std::basic_string<CHAR> type; }; #define IS_SAME(X,Y) ns_switch::is_same_type<ns_switch:: \ same_type<__typeof(X)>::type::value_type,Y>::value #define SWITCHL CAT(_SWITCHL, __LINE__) #define SWITCH(X) do { unsigned int weaklevel=0; \ bool contflag=false; void* LABEL=0; \ const ns_switch::switchtype<__typeof(X)>::type&_(X); if(0) #define CASE(Y) COND(_== Y) #define MATCH(X) COND(XMATCH(X)) #define XMATCH(X) \ boost::regex_search(_, \ boost::basic_regex<ns_switch::same_type<__typeof(_)> \ ::type::value_type> \ (ns_switch::select \ <ns_switch::select_type<IS_SAME(_,char), \ char, wchar_t \ >::type \ >(STR(X),WSTR(X))+1, \ ns_switch::select_type<IS_SAME(_,char), \ ns_switch::constant<int, SIZE(STR(X))>, \ ns_switch::constant<int, SIZE(WSTR(X))> \ >::type::value-3, \ boost::regex_constants::match_default )) #define CONTINUE if(contflag&&LABEL) { contflag=false; LABEL=0; } \ else{ contflag=true; LABEL=0; } } if(0) { #define COND(Y) goto SWITCHL; } else if(Y) { SWITCHL: #define DEFAULT goto SWITCHL; } else { \ if(!weaklevel&&!contflag&&!LABEL) LABEL=&&SWITCHL; } \ if(0) { SWITCHL: contflag=true; #define WEAK_COND(L,Y) goto SWITCHL; } else if(Y) { \ if((weaklevel<L&&LABEL&&!contflag)|| \ (weaklevel==L)&&!contflag&&!LABEL) \ {weaklevel=L; LABEL=&&SWITCHL;} } \ if(0) { SWITCHL: contflag=true; #define WEAK_CASE(L,Y) WEAK_COND(L, _== Y) #define WEAK_MATCH(L,X) WEAK_COND(L, XMATCH(X)) #define RANGE(X) COND( ns_switch::range_t<__typeof(_)>()X.check(_)) #define XRANGE(X,Y) COND( ns_switch::range_t<__typeof(_)> \ ().x()X.x()Y.check(_)) #define WEAK_RANGE(L,X) WEAK_COND(L,ns_switch::range_t \ <__typeof(_)>()X.check(_)) #define WEAK_XRANGE(L,X,Y) WEAK_COND(L,ns_switch::range_t \ <__typeof(_)>().x()X.x()Y.check(_)) #define ENDSWITCH else { if(LABEL) goto *LABEL; } } while(0) } // end ns_switch