今度こそ

※日付が間違っていたのでエントリーを移動
typeofできた。残念ながら途中で型にID振るためのカウンタを作るのが面倒になったので、コード中に謎の数値が散見されるが気にしてはいけない。
型と整数をパラメータとして取るテンプレートも扱えるようにするあたりが多分一番難しかったところ。それ以外はまぁ平凡なTMPのコード。ただ一月も経てば読めなくなるだけである。Boost.Preprocessorを使えばもっと短くなるかも知れないが、その場合は読めなくなるのが2週間ぐらいまで短くなるぐらいの違いでしかないので使わなかった。それはそうと、こういうコード書くときのインデントのスタイルは決まってないから悩むなぁ。
追記:コード中のリテラル 50 を BOOST_MPL_LIMIT_VECTOR_SIZE に修正


#if !defined EXIST_TYPEOF_HPP_INCLUDED_
#define EXIST_TYPEOF_HPP_INCLUDED_

#define BOOST_MPL_LIMIT_VECTOR_SIZE 50

#include <boost/mpl/vector.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/alias.hpp>
#include <boost/mpl/size.hpp>


#define EXIST_TYPEOF_PUSH_BACK(V, val) typename mpl::push_back<V, mpl::size_t<val> >::type
#define EXIST_TYPEOF_ENCODE(V, M, T) typename encode_type_impl<V, M, T>::type
#define EXIST_TYPEOF_POP_FRONT(V) typename mpl::pop_front<V>::type
#define EXIST_TYPEOF_FRONT(V) typename mpl::front<V>::type
#define EXIST_TYPEOF_DECODE(V, M) decode_type_impl<EXIST_TYPEOF_POP_FRONT(V), M, EXIST_TYPEOF_FRONT(V)>


namespace exist { namespace type_of {

template<size_t n>
struct sizer {
char size[n + 1];
};


template<typename Vector,
template<typename, typename> class Map,
typename T>
struct encode_type_impl {
typedef typename Map<Vector, T>::type type;
};


template<typename Vector,
template<typename, typename> class Map,
typename val>
struct decode_type_impl {
typedef typename Map<Vector, val>::type type;
typedef typename Map<Vector, val>::rest rest;
};


// modified type, function type, member pointer type
#define EXIST_TYPEOF_SPACE
#define EXIST_TYPEOF_PATTERN_PLANE(name, cv, T) T cv name
#define EXIST_TYPEOF_PATTERN_PTR(name, _, T) T * name
#define EXIST_TYPEOF_PATTERN_REF(name, _, T) T & name
#define EXIST_TYPEOF_PATTERN_FUN0(name, _, T) T name()
#define EXIST_TYPEOF_PATTERN_FUN1(name, _, T1, T2) T1 name(T2)
#define EXIST_TYPEOF_PATTERN_FUN2(name, _, T1, T2, T3) T1 name(T2, T3)
#define EXIST_TYPEOF_PATTERN_FUN3(name, _, T1, T2, T3, T4) T1 name(T2, T3, T4)
#define EXIST_TYPEOF_PATTERN_MEM_PTR(name, _, T1, T2) T2 (T1::* name)
#define EXIST_TYPEOF_PATTERN_MEM_FUN0(name, cv, T1, T2) T2 (T1::* name)() cv
#define EXIST_TYPEOF_PATTERN_MEM_FUN1(name, cv, T1, T2, T3) T2 (T1::* name)(T3) cv
#define EXIST_TYPEOF_PATTERN_MEM_FUN2(name, cv, T1, T2, T3, T4) T2 (T1::* name)(T3, T4) cv
#define EXIST_TYPEOF_PATTERN_MEM_FUN3(name, cv, T1, T2, T3, T4, T5) T2 (T1::* name)(T3, T4, T5) cv


#define EXIST_TYPEOF_ENCODE_DECODE_DEF_1(id, pattern, cv) \
template<typename Vector, \
template<typename, typename> class Map, \
typename T> \
struct encode_type_impl<Vector, Map, pattern(EXIST_TYPEOF_SPACE, cv, T) > { \
typedef EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_PUSH_BACK(Vector, id), Map, T) type; \
}; \
template<typename Vector, \
template<typename, typename> class Map> \
struct decode_type_impl<Vector, Map, mpl::size_t<id> > { \
typedef EXIST_TYPEOF_DECODE(Vector, Map) decode1; \
typedef typename decode1::type type1; \
typedef pattern(type, cv, type1); \
typedef typename decode1::rest rest; \
};

#define EXIST_TYPEOF_ENCODE_DECODE_DEF_2(id, pattern, cv) \
template<typename Vector, \
template<typename, typename> class Map, \
typename T1, \
typename T2> \
struct encode_type_impl<Vector, Map, pattern(EXIST_TYPEOF_SPACE, cv, T1, T2) > { \
typedef EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_PUSH_BACK(Vector, id), Map, T1), \
Map, T2) type; \
}; \
template<typename Vector, template<typename, typename> class Map> \
struct decode_type_impl<Vector, Map, mpl::size_t<id> > { \
typedef EXIST_TYPEOF_DECODE(Vector, Map) decode1; \
typedef EXIST_TYPEOF_DECODE(typename decode1::rest, Map) decode2; \
typedef typename decode1::type type1; \
typedef typename decode2::type type2; \
typedef pattern(type, cv, type1, type2); \
typedef typename decode2::rest rest; \
};

#define EXIST_TYPEOF_ENCODE_DECODE_DEF_3(id, pattern, cv) \
template<typename Vector, \
template<typename, typename> class Map, \
typename T1, \
typename T2, \
typename T3> \
struct encode_type_impl<Vector, Map, pattern(EXIST_TYPEOF_SPACE, cv, T1, T2, T3) > { \
typedef EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_PUSH_BACK(Vector, id), Map, T1), \
Map, T2), \
Map, T3) type; \
}; \
template<typename Vector, template<typename, typename> class Map> \
struct decode_type_impl<Vector, Map, mpl::size_t<id> > { \
typedef EXIST_TYPEOF_DECODE(Vector, Map) decode1; \
typedef EXIST_TYPEOF_DECODE(typename decode1::rest, Map) decode2; \
typedef EXIST_TYPEOF_DECODE(typename decode2::rest, Map) decode3; \
typedef typename decode1::type type1; \
typedef typename decode2::type type2; \
typedef typename decode3::type type3; \
typedef pattern(type, cv, type1, type2, type3); \
typedef typename decode3::rest rest; \
};

#define EXIST_TYPEOF_ENCODE_DECODE_DEF_4(id, pattern, cv) \
template<typename Vector, \
template<typename, typename> class Map, \
typename T1, \
typename T2, \
typename T3, \
typename T4> \
struct encode_type_impl<Vector, Map, pattern(EXIST_TYPEOF_SPACE, cv, T1, T2, T3, T4) > { \
typedef EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_PUSH_BACK(Vector, id), Map, T1), \
Map, T2), \
Map, T3), \
Map, T4) type; \
}; \
template<typename Vector, template<typename, typename> class Map> \
struct decode_type_impl<Vector, Map, mpl::size_t<id> > { \
typedef EXIST_TYPEOF_DECODE(Vector, Map) decode1; \
typedef EXIST_TYPEOF_DECODE(typename decode1::rest, Map) decode2; \
typedef EXIST_TYPEOF_DECODE(typename decode2::rest, Map) decode3; \
typedef EXIST_TYPEOF_DECODE(typename decode3::rest, Map) decode4; \
typedef typename decode1::type type1; \
typedef typename decode2::type type2; \
typedef typename decode3::type type3; \
typedef typename decode4::type type4; \
typedef pattern(type, cv, type1, type2, type3, type4); \
typedef typename decode4::rest rest; \
};

#define EXIST_TYPEOF_ENCODE_DECODE_DEF_5(id, pattern, cv) \
template<typename Vector, \
template<typename, typename> class Map, \
typename T1, \
typename T2, \
typename T3, \
typename T4, \
typename T5> \
struct encode_type_impl<Vector, Map, pattern(EXIST_TYPEOF_SPACE, cv, T1, T2, T3, T4, T5) > { \
typedef EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_ENCODE( \
EXIST_TYPEOF_PUSH_BACK(Vector, id), Map, T1), \
Map, T2), \
Map, T3), \
Map, T4), \
Map, T5) type; \
}; \
template<typename Vector, template<typename, typename> class Map> \
struct decode_type_impl<Vector, Map, mpl::size_t<id> > { \
typedef EXIST_TYPEOF_DECODE(Vector, Map) decode1; \
typedef EXIST_TYPEOF_DECODE(typename decode1::rest, Map) decode2; \
typedef EXIST_TYPEOF_DECODE(typename decode2::rest, Map) decode3; \
typedef EXIST_TYPEOF_DECODE(typename decode3::rest, Map) decode4; \
typedef EXIST_TYPEOF_DECODE(typename decode4::rest, Map) decode5; \
typedef typename decode1::type type1; \
typedef typename decode2::type type2; \
typedef typename decode3::type type3; \
typedef typename decode4::type type4; \
typedef typename decode5::type type5; \
typedef pattern(type, cv, type1, type2, type3, type4, type5); \
typedef typename decode5::rest rest; \
};

#define EXIST_TYPEOF_ALL_CV_CASE_DEF(id, def_n, pattern) \
def_n(id, pattern, EXIST_TYPEOF_SPACE) \
def_n(id + 1, pattern, const) \
def_n(id + 2, pattern, volatile) \
def_n(id + 3, pattern, const volatile)

EXIST_TYPEOF_ENCODE_DECODE_DEF_1(0, EXIST_TYPEOF_PATTERN_PLANE, const)
EXIST_TYPEOF_ENCODE_DECODE_DEF_1(1, EXIST_TYPEOF_PATTERN_PLANE, volatile)
EXIST_TYPEOF_ENCODE_DECODE_DEF_1(2, EXIST_TYPEOF_PATTERN_PLANE, const volatile)
EXIST_TYPEOF_ENCODE_DECODE_DEF_1(3, EXIST_TYPEOF_PATTERN_PTR, EXIST_TYPEOF_SPACE)
EXIST_TYPEOF_ENCODE_DECODE_DEF_1(4, EXIST_TYPEOF_PATTERN_REF, EXIST_TYPEOF_SPACE)
EXIST_TYPEOF_ENCODE_DECODE_DEF_1(5, EXIST_TYPEOF_PATTERN_FUN0, EXIST_TYPEOF_SPACE)
EXIST_TYPEOF_ENCODE_DECODE_DEF_2(6, EXIST_TYPEOF_PATTERN_FUN1, EXIST_TYPEOF_SPACE)
EXIST_TYPEOF_ENCODE_DECODE_DEF_3(7, EXIST_TYPEOF_PATTERN_FUN2, EXIST_TYPEOF_SPACE)
EXIST_TYPEOF_ENCODE_DECODE_DEF_4(8, EXIST_TYPEOF_PATTERN_FUN3, EXIST_TYPEOF_SPACE)
EXIST_TYPEOF_ENCODE_DECODE_DEF_2(9, EXIST_TYPEOF_PATTERN_MEM_PTR, EXIST_TYPEOF_SPACE)
EXIST_TYPEOF_ALL_CV_CASE_DEF(10, EXIST_TYPEOF_ENCODE_DECODE_DEF_2, EXIST_TYPEOF_PATTERN_MEM_FUN0)
EXIST_TYPEOF_ALL_CV_CASE_DEF(14, EXIST_TYPEOF_ENCODE_DECODE_DEF_3, EXIST_TYPEOF_PATTERN_MEM_FUN1)
EXIST_TYPEOF_ALL_CV_CASE_DEF(18, EXIST_TYPEOF_ENCODE_DECODE_DEF_4, EXIST_TYPEOF_PATTERN_MEM_FUN2)
EXIST_TYPEOF_ALL_CV_CASE_DEF(22, EXIST_TYPEOF_ENCODE_DECODE_DEF_5, EXIST_TYPEOF_PATTERN_MEM_FUN3)


#undef EXIST_TYPEOF_SPACE
#undef EXIST_TYPEOF_PATTERN_PLANE
#undef EXIST_TYPEOF_PATTERN_PTR
#undef EXIST_TYPEOF_PATTERN_REF
#undef EXIST_TYPEOF_PATTERN_FUN0
#undef EXIST_TYPEOF_PATTERN_FUN1
#undef EXIST_TYPEOF_PATTERN_FUN2
#undef EXIST_TYPEOF_PATTERN_FUN3
#undef EXIST_TYPEOF_PATTERN_MEM_PTR
#undef EXIST_TYPEOF_PATTERN_MEM_FUN0
#undef EXIST_TYPEOF_PATTERN_MEM_FUN1
#undef EXIST_TYPEOF_PATTERN_MEM_FUN2
#undef EXIST_TYPEOF_PATTERN_MEM_FUN3

#undef EXIST_TYPEOF_ENCODE_DECODE_DEF_1
#undef EXIST_TYPEOF_ENCODE_DECODE_DEF_2
#undef EXIST_TYPEOF_ENCODE_DECODE_DEF_3
#undef EXIST_TYPEOF_ENCODE_DECODE_DEF_4
#undef EXIST_TYPEOF_ENCODE_DECODE_DEF_5
#undef EXIST_TYPEOF_ALL_CV_CASE_DEF

// array
template<typename Vector,
template<typename, typename> class Map,
typename T,
size_t n>
struct encode_type_impl<Vector, Map, T[n]> {
typedef EXIST_TYPEOF_PUSH_BACK(
EXIST_TYPEOF_ENCODE(
EXIST_TYPEOF_PUSH_BACK(Vector, 26), Map, T),
n) type;
};


template<typename Vector,template<typename, typename> class Map>
struct decode_type_impl<Vector, Map, mpl::size_t<26> > {
typedef EXIST_TYPEOF_DECODE(Vector, Map) decode;
typedef typename decode::type type[mpl::front<typename decode::rest>::type::value];
typedef EXIST_TYPEOF_POP_FRONT(typename decode::rest) rest;
};


// template parameter
template<typename Vector,
template<typename, typename> class Map,
template<typename> class TC,
typename T>
struct encode_type_impl<Vector, Map, TC<T> > {
typedef EXIST_TYPEOF_ENCODE(Vector, Map, T) type;
};


#define EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(valueType) \
template<typename Vector, \
template<typename, typename> class Map, \
template<valueType> class TC, \
valueType val> \
struct encode_type_impl<Vector, Map, TC<val> > { \
typedef EXIST_TYPEOF_PUSH_BACK(EXIST_TYPEOF_PUSH_BACK(Vector, 27), val) type; \
};


EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(char)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(signed char)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(unsigned char)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(short)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(unsigned short)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(int)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(unsigned int)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(long)
EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF(unsigned long)


#undef EXIST_TYPEOF_ENCODE_NONTYPE_TEMPLATE_PARAM_DEF


template<typename Vector, template<typename, typename> class Map>
struct decode_type_impl<Vector, Map, mpl::size_t<27> > {
typedef mpl::size_t<mpl::front<Vector>::type::value> type;
typedef EXIST_TYPEOF_POP_FRONT(Vector) rest;
};


template<typename Decoder, typename TypeParam>
struct decode_template_param {
typedef typename Decoder::template set<TypeParam>::type type;
};


template<typename Decoder, size_t val>
struct decode_template_param<Decoder, mpl::size_t<val> > {
typedef typename Decoder::template set<val>::type type;
};


// end of decode
template<typename Vector, template<typename, typename> class Map>
struct decode_type_impl<Vector, Map, mpl::size_t<28> > {
typedef mpl::void_ type;
typedef Vector rest;
};

}} // namespace exist { namespace { type_of


namespace { namespace type_of {

template<typename Vector, typename T>
struct encode_map;


template<typename Vector, typename val>
struct decode_map;


template<typename T>
struct encode_type {
typedef
typename mpl::copy<
typename mpl::transform<
mpl::range_c<
size_t,
mpl::size<
typename exist::type_of::encode_type_impl<
mpl::vector<>,
encode_map,
T>::type>::value,
BOOST_MPL_LIMIT_VECTOR_SIZE >,
mpl::always<mpl::size_t<28> >,
mpl::back_inserter<mpl::vector0<> > >::type,
mpl::back_inserter<
typename exist::type_of::encode_type_impl<
mpl::vector<>,
encode_map,
T>::type> >::type
type;
};


template<typename Vector>
struct decode_type
: public exist::type_of::decode_type_impl<
EXIST_TYPEOF_POP_FRONT(Vector),
decode_map,
EXIST_TYPEOF_FRONT(Vector)>
{};


template<size_t index, typename Expr>
exist::type_of::sizer<
mpl::at_c<
typename encode_type<Expr>::type,
index>::type::value>
encode_result_type(Expr const &);

}} // namespace { namespace type_of {


#undef EXIST_TYPEOF_PUSH_BACK
#undef EXIST_TYPEOF_ENCODE
#undef EXIST_TYPEOF_FRONT
#undef EXIST_TYPEOF_POP_FRONT
#undef EXIST_TYPEOF_DECODE


#define EXIST_TYPEOF_REGIST_TYPE_IMPL(id, type_) \
namespace { namespace type_of { \
template<typename Vector> \
struct encode_map<Vector, type_ > { \
typedef typename mpl::push_back<Vector, mpl::size_t<id> >::type type; \
}; \
template<typename Vector> \
struct decode_map<Vector, mpl::size_t<id> > { \
typedef type_ type; \
typedef Vector rest; \
}; \
}}

#define EXIST_TYPEOF_REGIST_TEMPLATE_1_IMPL(id, template_, param1_type) \
namespace { namespace type_of { \
template<typename Vector, param1_type param1> \
struct encode_map<Vector, template_<param1> > { \
template<param1_type> struct param1_wrapper; \
typedef typename \
exist::type_of::encode_type_impl< \
typename mpl::push_back<Vector, mpl::size_t<id> >::type, \
::type_of::encode_map, \
param1_wrapper<param1> >::type \
type; \
}; \
template<typename Vector> \
struct decode_map<Vector, mpl::size_t<id> > { \
typedef \
exist::type_of::decode_type_impl< \
typename mpl::pop_front<Vector>::type, \
::type_of::decode_map, \
typename mpl::front<Vector>::type> \
decode1; \
struct param_decoder { \
template<param1_type param1> struct set { \
typedef template_<param1> type; \
}; \
}; \
typedef \
typename exist::type_of::decode_template_param< \
param_decoder, \
typename decode1::type>::type \
type; \
typedef typename decode1::rest rest; \
}; \
}}

#define EXIST_TYPEOF_REGIST_TEMPLATE_2_IMPL(id, template_, param1_type, param2_type) \
namespace { namespace type_of { \
template<typename Vector, param1_type param1, param2_type param2> \
struct encode_map<Vector, template_<param1, param2> > { \
template<param1_type> struct param1_wrapper; \
template<param2_type> struct param2_wrapper; \
typedef typename \
exist::type_of::encode_type_impl< \
typename exist::type_of::encode_type_impl< \
typename mpl::push_back<Vector, mpl::size_t<id> >::type, \
::type_of::encode_map, \
param1_wrapper<param1> >::type, \
::type_of::encode_map, \
param2_wrapper<param2> >::type \
type; \
}; \
template<typename Vector> \
struct decode_map<Vector, mpl::size_t<id> > { \
typedef \
exist::type_of::decode_type_impl< \
typename mpl::pop_front<Vector>::type, \
::type_of::decode_map, \
typename mpl::front<Vector>::type> \
decode1; \
typedef \
exist::type_of::decode_type_impl< \
typename mpl::pop_front<typename decode1::rest>::type, \
::type_of::decode_map, \
typename mpl::front<typename decode1::rest>::type> \
decode2; \
struct param_decoder { \
template<param1_type param1> struct set { \
struct param_decoder { \
template<param2_type param2> struct set { \
typedef template_<param1, param2> type; \
}; \
}; \
typedef \
typename exist::type_of::decode_template_param< \
param_decoder, \
typename decode2::type>::type \
type; \
}; \
}; \
typedef \
typename exist::type_of::decode_template_param< \
param_decoder, \
typename decode1::type>::type \
type; \
typedef typename decode2::rest rest; \
}; \
}}

#define EXIST_TYPEOF_REGIST_TEMPLATE_3_IMPL(id, template_, param1_type, param2_type, param3_type) \
namespace { namespace type_of { \
template<typename Vector, param1_type param1, param2_type param2, param3_type param3> \
struct encode_map<Vector, template_<param1, param2, param3> > { \
template<param1_type> struct param1_wrapper; \
template<param2_type> struct param2_wrapper; \
template<param3_type> struct param3_wrapper; \
typedef typename \
exist::type_of::encode_type_impl< \
typename exist::type_of::encode_type_impl< \
typename exist::type_of::encode_type_impl< \
typename mpl::push_back<Vector, mpl::size_t<id> >::type, \
::type_of::encode_map, \
param1_wrapper<param1> >::type, \
::type_of::encode_map, \
param2_wrapper<param2> >::type, \
::type_of::encode_map, \
param3_wrapper<param3> >::type \
type; \
}; \
template<typename Vector> \
struct decode_map<Vector, mpl::size_t<id> > { \
typedef \
exist::type_of::decode_type_impl< \
typename mpl::pop_front<Vector>::type, \
::type_of::decode_map, \
typename mpl::front<Vector>::type> \
decode1; \
typedef \
exist::type_of::decode_type_impl< \
typename mpl::pop_front<typename decode1::rest>::type, \
::type_of::decode_map, \
typename mpl::front<typename decode1::rest>::type> \
decode2; \
typedef \
exist::type_of::decode_type_impl< \
typename mpl::pop_front<typename decode2::rest>::type, \
::type_of::decode_map, \
typename mpl::front<typename decode2::rest>::type> \
decode3; \
struct param_decoder { \
template<param1_type param1> struct set { \
struct param_decoder { \
template<param2_type param2> struct set { \
struct param_decoder { \
template<param3_type param3> struct set { \
typedef template_<param1, param2, param3> type; \
}; \
}; \
typedef \
typename exist::type_of::decode_template_param< \
param_decoder, \
typename decode3::type>::type \
type; \
}; \
}; \
typedef \
typename exist::type_of::decode_template_param< \
param_decoder, \
typename decode2::type>::type \
type; \
}; \
}; \
typedef \
typename exist::type_of::decode_template_param< \
param_decoder, \
typename decode1::type>::type \
type; \
typedef typename decode3::rest rest; \
}; \
}}


#define EXIST_TYPEOF(expr) \
::type_of::decode_type< \
mpl::vector50< \
mpl::size_t<sizeof(::type_of::encode_result_type<0>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<1>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<2>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<3>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<4>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<5>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<6>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<7>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<8>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<9>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<10>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<11>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<12>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<13>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<14>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<15>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<16>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<17>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<18>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<19>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<20>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<21>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<22>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<23>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<24>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<25>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<26>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<27>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<28>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<29>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<30>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<31>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<32>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<33>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<34>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<35>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<36>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<37>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<38>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<39>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<40>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<41>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<42>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<43>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<44>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<45>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<46>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<47>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<48>(expr).size) - 1>, \
mpl::size_t<sizeof(::type_of::encode_result_type<49>(expr).size) - 1> > >::type


#define EXIST_AUTO(name, expr) \
EXIST_TYPEOF(expr) name = expr


EXIST_TYPEOF_REGIST_TYPE_IMPL(29, void)
EXIST_TYPEOF_REGIST_TYPE_IMPL(30, char)
EXIST_TYPEOF_REGIST_TYPE_IMPL(31, signed char)
EXIST_TYPEOF_REGIST_TYPE_IMPL(32, unsigned char)
EXIST_TYPEOF_REGIST_TYPE_IMPL(33, short)
EXIST_TYPEOF_REGIST_TYPE_IMPL(34, unsigned short)
EXIST_TYPEOF_REGIST_TYPE_IMPL(35, int)
EXIST_TYPEOF_REGIST_TYPE_IMPL(36, unsigned int)
EXIST_TYPEOF_REGIST_TYPE_IMPL(37, long)
EXIST_TYPEOF_REGIST_TYPE_IMPL(38, unsigned long)
EXIST_TYPEOF_REGIST_TYPE_IMPL(39, float)
EXIST_TYPEOF_REGIST_TYPE_IMPL(40, double)
EXIST_TYPEOF_REGIST_TYPE_IMPL(41, long double)
EXIST_TYPEOF_REGIST_TYPE_IMPL(42, wchar_t)


#endif // EXIST_TYPEOF_HPP_INCLUDED_