]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (C) 2005 Peder Holt |
2 | // Copyright (C) 2005 Arkadiy Vertleyb | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #ifndef BOOST_TYPEOF_TEMPLATE_TEMPLATE_PARAM_HPP_INCLUDED | |
7 | #define BOOST_TYPEOF_TEMPLATE_TEMPLATE_PARAM_HPP_INCLUDED | |
8 | ||
9 | #include <boost/preprocessor/logical/or.hpp> | |
10 | #include <boost/preprocessor/seq/fold_left.hpp> | |
11 | #include <boost/preprocessor/seq/enum.hpp> | |
12 | ||
13 | #define BOOST_TYPEOF_MAKE_OBJ_template(x) BOOST_TYPEOF_TEMPLATE_PARAM(x) | |
14 | #define BOOST_TYPEOF_TEMPLATE(X) template(X) BOOST_TYPEOF_EAT | |
15 | #define BOOST_TYPEOF_template(X) (template(X)) | |
16 | ||
17 | #define BOOST_TYPEOF_TEMPLATE_PARAM(Params)\ | |
18 | (TEMPLATE_PARAM)\ | |
19 | (Params) | |
20 | ||
21 | #define BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(This)\ | |
22 | BOOST_TYPEOF_TOSEQ(BOOST_PP_SEQ_ELEM(1, This)) | |
23 | ||
24 | //Encode / decode this | |
25 | #define BOOST_TYPEOF_TEMPLATE_PARAM_ENCODE(This, n)\ | |
26 | typedef typename boost::type_of::encode_template<BOOST_PP_CAT(V, n),\ | |
27 | BOOST_PP_CAT(P, n)<BOOST_TYPEOF_SEQ_ENUM(BOOST_TYPEOF_MAKE_OBJS(BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(This)),BOOST_TYPEOF_PLACEHOLDER) >\ | |
28 | >::type BOOST_PP_CAT(V, BOOST_PP_INC(n)); | |
29 | ||
30 | #define BOOST_TYPEOF_TEMPLATE_PARAM_DECODE(This, n)\ | |
31 | typedef boost::type_of::decode_template< BOOST_PP_CAT(iter, n) > BOOST_PP_CAT(d, n);\ | |
32 | typedef typename BOOST_PP_CAT(d, n)::type BOOST_PP_CAT(P, n);\ | |
33 | typedef typename BOOST_PP_CAT(d, n)::iter BOOST_PP_CAT(iter,BOOST_PP_INC(n)); | |
34 | ||
35 | // template<class, unsigned int, ...> class | |
36 | #define BOOST_TYPEOF_TEMPLATE_PARAM_EXPANDTYPE(This) \ | |
37 | template <BOOST_PP_SEQ_ENUM(BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(This)) > class | |
38 | ||
39 | #define BOOST_TYPEOF_TEMPLATE_PARAM_PLACEHOLDER(Param)\ | |
40 | Nested_Template_Template_Arguments_Not_Supported | |
41 | ||
42 | //'template<class,int> class' is reduced to 'class' | |
43 | #define BOOST_TYPEOF_TEMPLATE_PARAM_DECLARATION_TYPE(Param) class | |
44 | ||
45 | // T3<int, (unsigned int)0, ...> | |
46 | #define BOOST_TYPEOF_TEMPLATE_PARAM_PLACEHOLDER_TYPES(Param, n)\ | |
47 | BOOST_PP_CAT(T,n)<BOOST_TYPEOF_SEQ_ENUM_1(BOOST_TYPEOF_MAKE_OBJS(BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(Param)),BOOST_TYPEOF_PLACEHOLDER) > | |
48 | ||
49 | #define BOOST_TYPEOF_TEMPLATE_PARAM_ISTEMPLATE 1 | |
50 | ||
51 | //////////////////////////// | |
52 | // move to encode_decode? | |
53 | ||
54 | BOOST_TYPEOF_BEGIN_ENCODE_NS | |
55 | ||
56 | template<class V, class Type_Not_Registered_With_Typeof_System> struct encode_template_impl; | |
57 | template<class T, class Iter> struct decode_template_impl; | |
58 | ||
59 | BOOST_TYPEOF_END_ENCODE_NS | |
60 | ||
61 | namespace boost { namespace type_of { | |
62 | ||
63 | template<class V, class T> struct encode_template | |
64 | : BOOST_TYPEOF_ENCODE_NS_QUALIFIER::encode_template_impl<V, T> | |
65 | {}; | |
66 | ||
67 | template<class Iter> struct decode_template | |
68 | : BOOST_TYPEOF_ENCODE_NS_QUALIFIER::decode_template_impl<typename Iter::type, typename Iter::next> | |
69 | {}; | |
70 | }} | |
71 | ||
72 | //////////////////////////// | |
73 | // move to template_encoding.hpp? | |
74 | ||
75 | //Template template registration | |
76 | #define BOOST_TYPEOF_REGISTER_TYPE_FOR_TEMPLATE_TEMPLATE(Name,Params,ID)\ | |
77 | template<class V\ | |
78 | BOOST_TYPEOF_SEQ_ENUM_TRAILING(Params,BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR)\ | |
79 | >\ | |
80 | struct encode_template_impl<V,Name<\ | |
81 | BOOST_PP_ENUM_PARAMS(\ | |
82 | BOOST_PP_SEQ_SIZE(Params),\ | |
83 | P)> >\ | |
84 | : boost::type_of::push_back<V, boost::mpl::size_t<ID> >\ | |
85 | {\ | |
86 | };\ | |
87 | template<class Iter> struct decode_template_impl<boost::mpl::size_t<ID>, Iter>\ | |
88 | {\ | |
89 | BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(Params),BOOST_TYPEOF_TYPEDEF_INT_PN,_)\ | |
90 | typedef Name<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_PLACEHOLDER) > type;\ | |
91 | typedef Iter iter;\ | |
92 | }; | |
93 | ||
94 | #define BOOST_TYPEOF_TYPEDEF_INT_PN(z,n,Params) typedef int BOOST_PP_CAT(P,n); | |
95 | ||
96 | #ifdef __BORLANDC__ | |
97 | #define BOOST_TYPEOF_DECODE_NESTED_TEMPLATE_HELPER_NAME BOOST_PP_CAT(\ | |
98 | BOOST_PP_CAT(\ | |
99 | BOOST_PP_CAT(\ | |
100 | decode_nested_template_helper,\ | |
101 | BOOST_TYPEOF_REGISTRATION_GROUP\ | |
102 | ),0x10000\ | |
103 | ),__LINE__\ | |
104 | ) | |
105 | #define BOOST_TYPEOF_REGISTER_DECODE_NESTED_TEMPLATE_HELPER_IMPL(Name,Params,ID)\ | |
106 | struct BOOST_TYPEOF_DECODE_NESTED_TEMPLATE_HELPER_NAME {\ | |
107 | template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECLARE_DECODER_TYPE_PARAM_PAIR) >\ | |
108 | struct decode_params;\ | |
109 | template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECODER_TYPE_PARAM_PAIR) >\ | |
110 | struct decode_params<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_PLACEHOLDER_TYPES) >\ | |
111 | {\ | |
112 | typedef Name<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),T)> type;\ | |
113 | };\ | |
114 | }; | |
115 | //Template template param decoding | |
116 | #define BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TEMPLATE_TYPE(Name,Params)\ | |
117 | typedef typename BOOST_TYPEOF_DECODE_NESTED_TEMPLATE_HELPER_NAME::decode_params<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),P)>::type type; | |
118 | ||
119 | #else | |
120 | #define BOOST_TYPEOF_REGISTER_DECODE_NESTED_TEMPLATE_HELPER_IMPL(Name,Params,ID) | |
121 | ||
122 | //Template template param decoding | |
123 | #define BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TEMPLATE_TYPE(Name,Params)\ | |
124 | template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECLARE_DECODER_TYPE_PARAM_PAIR) >\ | |
125 | struct decode_params;\ | |
126 | template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECODER_TYPE_PARAM_PAIR) >\ | |
127 | struct decode_params<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_PLACEHOLDER_TYPES) >\ | |
128 | {\ | |
129 | typedef Name<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),T)> type;\ | |
130 | };\ | |
131 | typedef typename decode_params<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),P)>::type type; | |
132 | #endif | |
133 | #define BOOST_TYPEOF_REGISTER_DECLARE_DECODER_TYPE_PARAM_PAIR(z,n,elem) \ | |
134 | BOOST_TYPEOF_VIRTUAL(DECLARATION_TYPE, elem)(elem) BOOST_PP_CAT(T, n) | |
135 | ||
136 | // BOOST_TYPEOF_HAS_TEMPLATES | |
137 | #define BOOST_TYPEOF_HAS_TEMPLATES(Params)\ | |
138 | BOOST_PP_SEQ_FOLD_LEFT(BOOST_TYPEOF_HAS_TEMPLATES_OP, 0, Params) | |
139 | ||
140 | #define BOOST_TYPEOF_HAS_TEMPLATES_OP(s, state, elem)\ | |
141 | BOOST_PP_OR(state, BOOST_TYPEOF_VIRTUAL(ISTEMPLATE, elem)) | |
142 | ||
143 | //Define template template arguments | |
144 | #define BOOST_TYPEOF_REGISTER_TEMPLATE_TEMPLATE_IMPL(Name,Params,ID)\ | |
145 | BOOST_PP_IF(BOOST_TYPEOF_HAS_TEMPLATES(Params),\ | |
146 | BOOST_TYPEOF_REGISTER_DECODE_NESTED_TEMPLATE_HELPER_IMPL,\ | |
147 | BOOST_TYPEOF_REGISTER_TYPE_FOR_TEMPLATE_TEMPLATE)(Name,Params,ID) | |
148 | ||
149 | #endif //BOOST_TYPEOF_TEMPLATE_TEMPLATE_PARAM_HPP_INCLUDED |