続・SWITCH

2007/11/6のSWITCHマクロを無意味に機能強化
これを使えば、誰でもスパゲティプログラムが書ける(書いてどうする)。
俺はプリプロセスを通した後のコードを読めねぇ。
変更点

    • 複数の条件にマッチさせるためのマクロ CONTINUE を追加
    • 優先順序付きの条件マクロWEAK_…群を追加
    • 範囲指定のマクロRANGEが閉区間のみだったが、開区間の指定もできるように範囲指定の方法を変える。
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