]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright (C) 2004 Arkadiy Vertleyb |
2 | // Copyright (C) 2005 Peder Holt | |
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_ENCODING_HPP_INCLUDED | |
7 | #define BOOST_TYPEOF_TEMPLATE_ENCODING_HPP_INCLUDED | |
8 | ||
9 | #include <boost/preprocessor/cat.hpp> | |
10 | #include <boost/preprocessor/repetition/enum_trailing.hpp> | |
11 | #include <boost/preprocessor/control/iif.hpp> | |
12 | #include <boost/preprocessor/detail/is_unary.hpp> | |
13 | #include <boost/preprocessor/repetition/repeat.hpp> | |
14 | #include <boost/preprocessor/tuple/eat.hpp> | |
15 | #include <boost/preprocessor/seq/transform.hpp> | |
16 | #include <boost/preprocessor/seq/for_each_i.hpp> | |
17 | #include <boost/preprocessor/seq/cat.hpp> | |
18 | ||
19 | #include <boost/typeof/encode_decode.hpp> | |
20 | #include <boost/typeof/int_encoding.hpp> | |
21 | ||
22 | #include <boost/typeof/type_template_param.hpp> | |
23 | #include <boost/typeof/integral_template_param.hpp> | |
24 | #include <boost/typeof/template_template_param.hpp> | |
25 | ||
26 | #ifdef __BORLANDC__ | |
27 | #define BOOST_TYPEOF_QUALIFY(P) self_t::P | |
28 | #else | |
29 | #define BOOST_TYPEOF_QUALIFY(P) P | |
30 | #endif | |
31 | // The template parameter description, entered by the user, | |
32 | // is converted into a polymorphic "object" | |
33 | // that is used to generate the code responsible for | |
34 | // encoding/decoding the parameter, etc. | |
35 | ||
36 | // make sure to cat the sequence first, and only then add the prefix. | |
37 | #define BOOST_TYPEOF_MAKE_OBJ(elem) BOOST_PP_CAT(\ | |
38 | BOOST_TYPEOF_MAKE_OBJ,\ | |
39 | BOOST_PP_SEQ_CAT((_) BOOST_TYPEOF_TO_SEQ(elem))\ | |
40 | ) | |
41 | ||
42 | #define BOOST_TYPEOF_TO_SEQ(tokens) BOOST_TYPEOF_ ## tokens ## _BOOST_TYPEOF | |
43 | ||
44 | // BOOST_TYPEOF_REGISTER_TEMPLATE | |
45 | ||
46 | #define BOOST_TYPEOF_REGISTER_TEMPLATE_EXPLICIT_ID(Name, Params, Id)\ | |
47 | BOOST_TYPEOF_REGISTER_TEMPLATE_IMPL(\ | |
48 | Name,\ | |
49 | BOOST_TYPEOF_MAKE_OBJS(BOOST_TYPEOF_TOSEQ(Params)),\ | |
50 | BOOST_PP_SEQ_SIZE(BOOST_TYPEOF_TOSEQ(Params)),\ | |
51 | Id) | |
52 | ||
53 | #define BOOST_TYPEOF_REGISTER_TEMPLATE(Name, Params)\ | |
54 | BOOST_TYPEOF_REGISTER_TEMPLATE_EXPLICIT_ID(Name, Params, BOOST_TYPEOF_UNIQUE_ID()) | |
55 | ||
56 | #define BOOST_TYPEOF_OBJECT_MAKER(s, data, elem)\ | |
57 | BOOST_TYPEOF_MAKE_OBJ(elem) | |
58 | ||
59 | #define BOOST_TYPEOF_MAKE_OBJS(Params)\ | |
60 | BOOST_PP_SEQ_TRANSFORM(BOOST_TYPEOF_OBJECT_MAKER, ~, Params) | |
61 | ||
62 | // As suggested by Paul Mensonides: | |
63 | ||
64 | #define BOOST_TYPEOF_TOSEQ(x)\ | |
65 | BOOST_PP_IIF(\ | |
66 | BOOST_PP_IS_UNARY(x),\ | |
67 | x BOOST_PP_TUPLE_EAT(3), BOOST_PP_REPEAT\ | |
68 | )(x, BOOST_TYPEOF_TOSEQ_2, ~) | |
69 | ||
70 | #define BOOST_TYPEOF_TOSEQ_2(z, n, _) (class) | |
71 | ||
72 | // BOOST_TYPEOF_VIRTUAL | |
73 | ||
74 | #define BOOST_TYPEOF_CAT_4(a, b, c, d) BOOST_TYPEOF_CAT_4_I(a, b, c, d) | |
75 | #define BOOST_TYPEOF_CAT_4_I(a, b, c, d) a ## b ## c ## d | |
76 | ||
77 | #define BOOST_TYPEOF_VIRTUAL(Fun, Obj)\ | |
78 | BOOST_TYPEOF_CAT_4(BOOST_TYPEOF_, BOOST_PP_SEQ_HEAD(Obj), _, Fun) | |
79 | ||
80 | // BOOST_TYPEOF_SEQ_ENUM[_TRAILING][_1] | |
81 | // Two versions provided due to reentrancy issue | |
82 | ||
83 | #define BOOST_TYPEOF_SEQ_EXPAND_ELEMENT(z,n,seq)\ | |
84 | BOOST_PP_SEQ_ELEM(0,seq) (z,n,BOOST_PP_SEQ_ELEM(n,BOOST_PP_SEQ_ELEM(1,seq))) | |
85 | ||
86 | #define BOOST_TYPEOF_SEQ_ENUM(seq,macro)\ | |
87 | BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT,(macro)(seq)) | |
88 | ||
89 | #define BOOST_TYPEOF_SEQ_ENUM_TRAILING(seq,macro)\ | |
90 | BOOST_PP_ENUM_TRAILING(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT,(macro)(seq)) | |
91 | ||
92 | #define BOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1(z,n,seq)\ | |
93 | BOOST_PP_SEQ_ELEM(0,seq) (z,n,BOOST_PP_SEQ_ELEM(n,BOOST_PP_SEQ_ELEM(1,seq))) | |
94 | ||
95 | #define BOOST_TYPEOF_SEQ_ENUM_1(seq,macro)\ | |
96 | BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1,(macro)(seq)) | |
97 | ||
98 | #define BOOST_TYPEOF_SEQ_ENUM_TRAILING_1(seq,macro)\ | |
99 | BOOST_PP_ENUM_TRAILING(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1,(macro)(seq)) | |
100 | ||
101 | // | |
102 | ||
103 | #define BOOST_TYPEOF_PLACEHOLDER(z, n, elem)\ | |
104 | BOOST_TYPEOF_VIRTUAL(PLACEHOLDER, elem)(elem) | |
105 | ||
106 | #define BOOST_TYPEOF_PLACEHOLDER_TYPES(z, n, elem)\ | |
107 | BOOST_TYPEOF_VIRTUAL(PLACEHOLDER_TYPES, elem)(elem, n) | |
108 | ||
109 | #define BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM(r, data, n, elem)\ | |
110 | BOOST_TYPEOF_VIRTUAL(ENCODE, elem)(elem, n) | |
111 | ||
112 | #define BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM(r, data, n, elem)\ | |
113 | BOOST_TYPEOF_VIRTUAL(DECODE, elem)(elem, n) | |
114 | ||
115 | #define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR(z, n, elem) \ | |
116 | BOOST_TYPEOF_VIRTUAL(EXPANDTYPE, elem)(elem) BOOST_PP_CAT(P, n) | |
117 | ||
118 | #define BOOST_TYPEOF_REGISTER_DEFAULT_TEMPLATE_TYPE(Name,Params,ID)\ | |
119 | Name< BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params), P) > | |
120 | ||
121 | //Since we are creating an internal decode struct, we need to use different template names, T instead of P. | |
122 | #define BOOST_TYPEOF_REGISTER_DECODER_TYPE_PARAM_PAIR(z,n,elem) \ | |
123 | BOOST_TYPEOF_VIRTUAL(EXPANDTYPE, elem)(elem) BOOST_PP_CAT(T, n) | |
124 | ||
125 | //Default template param decoding | |
126 | ||
127 | #define BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TYPE(Name,Params)\ | |
128 | typedef Name<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),BOOST_TYPEOF_QUALIFY(P))> type; | |
129 | ||
130 | //Branch the decoding | |
131 | #define BOOST_TYPEOF_TYPEDEF_DECODED_TYPE(Name,Params)\ | |
132 | BOOST_PP_IF(BOOST_TYPEOF_HAS_TEMPLATES(Params),\ | |
133 | BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TEMPLATE_TYPE,\ | |
134 | BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TYPE)(Name,Params) | |
135 | ||
136 | #define BOOST_TYPEOF_REGISTER_TEMPLATE_IMPL(Name, Params, Size, ID)\ | |
137 | BOOST_TYPEOF_BEGIN_ENCODE_NS\ | |
138 | BOOST_TYPEOF_REGISTER_TEMPLATE_TEMPLATE_IMPL(Name, Params, ID)\ | |
139 | template<class V\ | |
140 | BOOST_TYPEOF_SEQ_ENUM_TRAILING(Params, BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR)\ | |
141 | >\ | |
142 | struct encode_type_impl<V, Name<BOOST_PP_ENUM_PARAMS(Size, P)> >\ | |
143 | {\ | |
144 | typedef typename boost::type_of::push_back<V, boost::mpl::size_t<ID> >::type V0;\ | |
145 | BOOST_PP_SEQ_FOR_EACH_I(BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM, ~, Params)\ | |
146 | typedef BOOST_PP_CAT(V, Size) type;\ | |
147 | };\ | |
148 | template<class Iter>\ | |
149 | struct decode_type_impl<boost::mpl::size_t<ID>, Iter>\ | |
150 | {\ | |
151 | typedef decode_type_impl<boost::mpl::size_t<ID>, Iter> self_t;\ | |
152 | typedef boost::mpl::size_t<ID> self_id;\ | |
153 | typedef Iter iter0;\ | |
154 | BOOST_PP_SEQ_FOR_EACH_I(BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM, ~, Params)\ | |
155 | BOOST_TYPEOF_TYPEDEF_DECODED_TYPE(Name, Params)\ | |
156 | typedef BOOST_PP_CAT(iter, Size) iter;\ | |
157 | };\ | |
158 | BOOST_TYPEOF_END_ENCODE_NS | |
159 | ||
160 | #endif//BOOST_TYPEOF_TEMPLATE_ENCODING_HPP_INCLUDED |