support enum, dependent template parameters

[SVN r2444]
This commit is contained in:
Arkadiy Vertleyb
2005-01-16 20:38:02 +00:00
parent a330151f32
commit 9e10362252
5 changed files with 107 additions and 95 deletions

View File

@ -41,18 +41,14 @@ namespace boost{namespace type_of{
template<size_t n, bool Overflow>
struct pack
{
static const size_t value =
(n + 1) * 2 + (Overflow ? 1 : 0);
enum {value = (n + 1) * 2 + (Overflow ? 1 : 0)};
};
template<size_t m>
struct unpack
{
static const size_t value =
(m / 2) - 1;
static const bool overflow =
(m % 2 == 1);
enum {value = (m / 2) - 1};
enum {overflow = (m % 2 == 1)};
};
////////////////////////////////
@ -84,35 +80,31 @@ namespace boost{namespace type_of{
template<size_t n, class Iter>
struct decode_size_t<n, Iter, false>
{
static const size_t value = n;
enum {value = n};
typedef Iter iter;
};
template<size_t n, class Iter>
struct decode_size_t<n, Iter, true>
{
static const size_t m = boost::mpl::deref<Iter>::type::value;
enum {m = boost::mpl::deref<Iter>::type::value};
static const size_t value = m * 0x3ffffffe + n;
enum {value = (size_t)m * 0x3ffffffe + n};
typedef typename boost::mpl::next<Iter>::type iter;
};
template<class T, class Iter>
struct decode_integral
{
static const size_t m =
boost::mpl::deref<Iter>::type::value;
enum {m = boost::mpl::deref<Iter>::type::value};
static const size_t n =
unpack<m>::value;
enum {n = unpack<m>::value};
static const bool overflow =
unpack<m>::overflow;
enum {overflow = unpack<m>::overflow};
typedef typename boost::mpl::next<Iter>::type nextpos;
static const T value =
decode_size_t<n, nextpos, overflow>::value;
static const T value = (T)(size_t)decode_size_t<n, nextpos, overflow>::value;
typedef typename decode_size_t<n, nextpos, overflow>::iter iter;
};

View File

@ -15,11 +15,8 @@
//////////
#define BOOST_TYPEOF_REGISTER_TEMPLATE_class_ BOOST_TYPEOF_REGISTER_TEMPLATE_typename_
#define BOOST_TYPEOF_REGISTER_TEMPLATE_typename_ (typename) (void) (TYPE)
#define BOOST_TYPEOF_REGISTER_TEMPLATE_integral(x) (x) (x) (VALUE)
#define BOOST_TYPEOF_REGISTER_TEMPLATE_RESULT_TYPE(x) typename x::type
#define BOOST_TYPEOF_REGISTER_TEMPLATE_RESULT_VALUE(x) x::value
#define BOOST_TYPEOF_REGISTER_TEMPLATE_typename_ (typename)(TYPE)
#define BOOST_TYPEOF_REGISTER_TEMPLATE_integral(x) (x)(VALUE)
//////////
@ -64,39 +61,60 @@
///////////
#define BOOST_TYPEOF_INTEGRAL(X) REGISTER_TEMPLATE_INTEGRAL(X) BOOST_TYPEOF_EAT
#define BOOST_TYPEOF_EAT_BOOST_TYPEOF
#define BOOST_TYPEOF_REGISTER_TEMPLATE_INTEGRAL(X) (inte)(gral(X))
///////////
#define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_DESCR(n, Params)\
BOOST_PP_CAT(BOOST_TYPEOF_REGISTER_TEMPLATE_, EAT_SPACE(BOOST_PP_SEQ_ELEM(n, Params)))
#define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_TYPE(n, Params)\
BOOST_PP_SEQ_ELEM(0, BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_DESCR(n, Params))
#define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_SPEC_TYPE(n, Params)\
#define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_SUFFIX(n, Params)\
BOOST_PP_SEQ_ELEM(1, BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_DESCR(n, Params))
#define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_RESULT(n, Params)\
BOOST_PP_CAT(\
BOOST_TYPEOF_REGISTER_TEMPLATE_RESULT_,\
BOOST_PP_SEQ_ELEM(2, BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_DESCR(n, Params))\
)
//////////
#define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR(z, n, Params)\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_TYPE(n, Params) BOOST_PP_CAT(P, n)
#define BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_TYPE(n, Params)\
typedef typename encode_type<\
BOOST_PP_CAT(V, n),\
BOOST_PP_CAT(P, n)\
>::type BOOST_PP_CAT(V, BOOST_PP_INC(n));
#define BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM(z, n, Params)\
typedef typename encode_dispatcher<\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_SPEC_TYPE(n, Params)\
>::encode<BOOST_PP_CAT(V, n), BOOST_PP_CAT(P, n)>::type BOOST_PP_CAT(V, BOOST_PP_INC(n));
#define BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_VALUE(n, Params)\
typedef typename encode_integral<\
BOOST_PP_CAT(V, n),\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_TYPE(n, Params),\
BOOST_PP_CAT(P, n)\
>::type BOOST_PP_CAT(V, BOOST_PP_INC(n));
#define BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_TYPE(n, PARAMS)\
typedef decode_type< BOOST_PP_CAT(iter, n) > BOOST_PP_CAT(d, n);\
typedef typename BOOST_PP_CAT(d, n)::type BOOST_PP_CAT(P, n);\
typedef typename BOOST_PP_CAT(d, n)::iter BOOST_PP_CAT(iter, BOOST_PP_INC(n));
#define BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_VALUE(n, Params)\
typedef decode_integral< BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_TYPE(n, Params), BOOST_PP_CAT(iter, n) > BOOST_PP_CAT(d, n);\
static const BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_TYPE(n, Params) BOOST_PP_CAT(P, n) = BOOST_PP_CAT(d, n)::value;\
typedef typename BOOST_PP_CAT(d, n)::iter BOOST_PP_CAT(iter, BOOST_PP_INC(n));
#define BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM(z, n, Params)\
typedef encode_dispatcher<\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_SPEC_TYPE(n, Params)\
>::decode<BOOST_PP_CAT(iter, n)> BOOST_PP_CAT(d, BOOST_PP_INC(n));\
typedef typename BOOST_PP_CAT(d, BOOST_PP_INC(n))::iter BOOST_PP_CAT(iter, BOOST_PP_INC(n));
BOOST_PP_CAT(\
BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_,\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_SUFFIX(n, Params)\
)(n, Params)
#define BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM_RESULT(z, n, Params)\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_RESULT(n, Params)(BOOST_PP_CAT(d, BOOST_PP_INC(n)))
#define BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM(z, n, Params)\
BOOST_PP_CAT(\
BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_,\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_SUFFIX(n, Params)\
)(n, Params)
#define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR(z, n, Params)\
BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_TYPE(n, Params) BOOST_PP_CAT(P, n)
//////////
@ -113,7 +131,7 @@
BOOST_PP_SEQ_SIZE(Params),\
P)> >\
{\
typedef typename BOOST_TYPEOF_PUSH_BACK<V, mpl::size_t<ID> >::type V0;\
typedef typename BOOST_TYPEOF_PUSH_BACK<V, boost::mpl::size_t<ID> >::type V0;\
BOOST_PP_REPEAT(\
BOOST_PP_SEQ_SIZE(Params),\
BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM,\
@ -128,12 +146,7 @@
BOOST_PP_SEQ_SIZE(Params),\
BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM,\
Params)\
typedef Name<\
BOOST_PP_ENUM(\
BOOST_PP_SEQ_SIZE(Params),\
BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM_RESULT,\
Params)\
> type;\
typedef Name< BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params), P) > type;\
typedef BOOST_PP_CAT(iter, BOOST_PP_SEQ_SIZE(Params)) iter;\
};\
}}}
@ -141,48 +154,4 @@
#define BOOST_TYPEOF_REGISTER_TEMPLATE_X(Name, Params)\
BOOST_TYPEOF_REGISTER_TEMPLATE_X_IMPL(Name, Params, BOOST_TYPEOF_UNIQUE_ID())
//////////
#define BOOST_TYPEOF_spec_integral_dispatcher(r, data, T) \
template<> struct encode_dispatcher<T> \
{ \
template<class V, T n> \
struct encode : encode_integral<V, T, n> \
{}; \
template<class Iter> \
struct decode : decode_integral<T, Iter> \
{}; \
};
namespace boost
{
namespace type_of
{
template<class U = void> struct encode_dispatcher
{
template<class V, class T>
struct encode : encode_type<V, T>
{};
template<class Iter>
struct decode : decode_type<Iter>
{};
};
BOOST_PP_SEQ_FOR_EACH(BOOST_TYPEOF_spec_integral_dispatcher, ~,
(char)
(short)
(int)
(long)
(bool)
(unsigned char)
(unsigned short)
(unsigned int)
(unsigned long)
(signed char)
)
}
}
#undef BOOST_TYPEOF_spec_integral_dispatcher
#endif//BOOST_TYPEOF_COMPLIANT_TEMPLATE_ENCODING_HPP_INCLUDED

View File

@ -62,4 +62,54 @@ void test_spirit2()
throw 0;
}
#pragma message("compiling integral param wrapper...")
namespace test_integral
{
// Enum template parameter
enum E{ONE, TWO, THREE};
template<E e> struct foo
{
static const E value = e;
};
// dependent template parameter
template<class T, T n> struct bar
{};
// multi-word template parameter
template<unsigned long int n> struct blah
{};
}
BOOST_TYPEOF_REGISTER_TEMPLATE_X(test_integral::foo,
(BOOST_TYPEOF_INTEGRAL(test_integral::E))
);
BOOST_TYPEOF_REGISTER_TEMPLATE_X(test_integral::blah,
(BOOST_TYPEOF_INTEGRAL(unsigned long int))
);
BOOST_TYPEOF_REGISTER_TEMPLATE_X(test_integral::bar,
(class)
(BOOST_TYPEOF_INTEGRAL(P0))
);
namespace test_integral
{
void test()
{
foo<TWO> x;
bar<int, 5> xx;
blah<5> xxx;
BOOST_AUTO(y, x);
BOOST_AUTO(yy, xx);
BOOST_AUTO(yyy, xxx);
y;
yy;
yyy;
}
}

View File

@ -19,8 +19,9 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="C:\boost\boost_1_32_0;&quot;C:\ark\boost-sandbox\boost-sandbox&quot;"
AdditionalIncludeDirectories="C:\boost\boost_1_32_0;..\..\..\.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"

View File

@ -1,3 +1,3 @@
g++ -IC:\boost\boost_1_32_0 -I..\..\..\.. -D BOOST_TYPEOF_COMPLIANT -D BOOST_TYPEOF_LIMIT_SIZE=50 -D BOOST_MPL_LIMIT_VECTOR_SIZE=50 odr1.cpp odr2.cpp test_compliant.cpp ..\main.cpp
g++ -IC:\boost\boost_1_32_0 -I..\..\..\.. -D BOOST_TYPEOF_COMPLIANT -D BOOST_TYPEOF_LIMIT_SIZE=50 -D BOOST_MPL_LIMIT_VECTOR_SIZE=50 test_compliant.cpp ..\main.cpp odr1.cpp odr2.cpp
g++ -IC:\boost\boost_1_32_0 -I..\..\..\.. odr1.cpp odr2.cpp test_compliant.cpp ..\main.cpp