]>
Commit | Line | Data |
---|---|---|
1 | // Copyright (C) 2004, 2005 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_TYPEOF_IMPL_HPP_INCLUDED | |
7 | #define BOOST_TYPEOF_TYPEOF_IMPL_HPP_INCLUDED | |
8 | ||
9 | #include <boost/mpl/size_t.hpp> | |
10 | #include <boost/preprocessor/repetition/enum.hpp> | |
11 | #include <boost/typeof/encode_decode.hpp> | |
12 | #include <boost/typeof/vector.hpp> | |
13 | #include <boost/type_traits/is_function.hpp> | |
14 | #include <boost/utility/enable_if.hpp> | |
15 | ||
16 | #define BOOST_TYPEOF_VECTOR(n) BOOST_PP_CAT(boost::type_of::vector, n) | |
17 | ||
18 | #define BOOST_TYPEOF_sizer_item(z, n, _)\ | |
19 | char item ## n[V::item ## n ::value]; | |
20 | ||
21 | namespace boost { namespace type_of { | |
22 | template<class V> | |
23 | struct sizer | |
24 | { | |
25 | // char item0[V::item0::value]; | |
26 | // char item1[V::item1::value]; | |
27 | // ... | |
28 | ||
29 | BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_sizer_item, ~) | |
30 | }; | |
31 | }} | |
32 | ||
33 | #undef BOOST_TYPEOF_sizer_item | |
34 | ||
35 | // | |
36 | namespace boost { namespace type_of { | |
37 | # ifdef BOOST_NO_SFINAE | |
38 | template<class V, class T> | |
39 | sizer<typename encode_type<V, T>::type> encode(const T&); | |
40 | # else | |
41 | template<class V, class T> | |
42 | typename enable_if< | |
43 | typename is_function<T>::type, | |
44 | sizer<typename encode_type<V, T>::type> >::type encode(T&); | |
45 | ||
46 | template<class V, class T> | |
47 | typename disable_if< | |
48 | typename is_function<T>::type, | |
49 | sizer<typename encode_type<V, T>::type> >::type encode(const T&); | |
50 | # endif | |
51 | }} | |
52 | // | |
53 | namespace boost { namespace type_of { | |
54 | ||
55 | template<class V> | |
56 | struct decode_begin | |
57 | { | |
58 | typedef typename decode_type<typename V::begin>::type type; | |
59 | }; | |
60 | }} | |
61 | ||
62 | #define BOOST_TYPEOF_TYPEITEM(z, n, expr)\ | |
63 | boost::mpl::size_t<sizeof(boost::type_of::encode<BOOST_TYPEOF_VECTOR(0)<> >(expr).item ## n)> | |
64 | ||
65 | #define BOOST_TYPEOF_ENCODED_VECTOR(Expr) \ | |
66 | BOOST_TYPEOF_VECTOR(BOOST_TYPEOF_LIMIT_SIZE)< \ | |
67 | BOOST_PP_ENUM(BOOST_TYPEOF_LIMIT_SIZE, BOOST_TYPEOF_TYPEITEM, Expr) \ | |
68 | > | |
69 | ||
70 | #define BOOST_TYPEOF(Expr)\ | |
71 | boost::type_of::decode_begin<BOOST_TYPEOF_ENCODED_VECTOR(Expr) >::type | |
72 | ||
73 | #define BOOST_TYPEOF_TPL typename BOOST_TYPEOF | |
74 | ||
75 | //offset_vector is used to delay the insertion of data into the vector in order to allow | |
76 | //encoding to be done in many steps | |
77 | namespace boost { namespace type_of { | |
78 | template<typename V,typename Offset> | |
79 | struct offset_vector { | |
80 | }; | |
81 | ||
82 | template<class V,class Offset,class T> | |
83 | struct push_back<boost::type_of::offset_vector<V,Offset>,T> { | |
84 | typedef offset_vector<V,typename Offset::prior> type; | |
85 | }; | |
86 | ||
87 | template<class V,class T> | |
88 | struct push_back<boost::type_of::offset_vector<V,mpl::size_t<0> >,T> { | |
89 | typedef typename push_back<V,T>::type type; | |
90 | }; | |
91 | }} | |
92 | ||
93 | #define BOOST_TYPEOF_NESTED_TYPEITEM(z, n, expr)\ | |
94 | BOOST_STATIC_CONSTANT(int,BOOST_PP_CAT(value,n) = sizeof(boost::type_of::encode<_typeof_start_vector>(expr).item ## n));\ | |
95 | typedef boost::mpl::size_t<BOOST_PP_CAT(self_t::value,n)> BOOST_PP_CAT(item,n); | |
96 | ||
97 | #ifdef __DMC__ | |
98 | #define BOOST_TYPEOF_NESTED_TYPEITEM_2(z,n,expr)\ | |
99 | typedef typename _typeof_encode_fraction<iteration>::BOOST_PP_CAT(item,n) BOOST_PP_CAT(item,n); | |
100 | ||
101 | #define BOOST_TYPEOF_FRACTIONTYPE()\ | |
102 | BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE,BOOST_TYPEOF_NESTED_TYPEITEM_2,_)\ | |
103 | typedef _typeof_fraction_iter<Pos> fraction_type; | |
104 | #else | |
105 | #define BOOST_TYPEOF_FRACTIONTYPE()\ | |
106 | typedef _typeof_encode_fraction<self_t::iteration> fraction_type; | |
107 | #endif | |
108 | ||
109 | #ifdef __BORLANDC__ | |
110 | namespace boost { namespace type_of { | |
111 | template<typename Pos,typename Iter> | |
112 | struct generic_typeof_fraction_iter { | |
113 | typedef generic_typeof_fraction_iter<Pos,Iter> self_t; | |
114 | static const int pos=(Pos::value); | |
115 | static const int iteration=(pos/5); | |
116 | static const int where=pos%5; | |
117 | typedef typename Iter::template _apply_next<self_t::iteration>::type fraction_type; | |
118 | typedef generic_typeof_fraction_iter<typename Pos::next,Iter> next; | |
119 | typedef typename v_iter<fraction_type,mpl::int_<self_t::where> >::type type; | |
120 | }; | |
121 | }} | |
122 | #define BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr) \ | |
123 | template<int _Typeof_Iteration>\ | |
124 | struct _typeof_encode_fraction {\ | |
125 | typedef _typeof_encode_fraction<_Typeof_Iteration> self_t;\ | |
126 | BOOST_STATIC_CONSTANT(int,_typeof_encode_offset = (_Typeof_Iteration*BOOST_TYPEOF_LIMIT_SIZE));\ | |
127 | typedef boost::type_of::offset_vector<BOOST_TYPEOF_VECTOR(0)<>,boost::mpl::size_t<self_t::_typeof_encode_offset> > _typeof_start_vector;\ | |
128 | BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE,BOOST_TYPEOF_NESTED_TYPEITEM,expr)\ | |
129 | template<int Next>\ | |
130 | struct _apply_next {\ | |
131 | typedef _typeof_encode_fraction<Next> type;\ | |
132 | };\ | |
133 | };\ | |
134 | template<typename Pos>\ | |
135 | struct _typeof_fraction_iter {\ | |
136 | typedef boost::type_of::generic_typeof_fraction_iter<Pos,_typeof_encode_fraction<0> > self_t;\ | |
137 | typedef typename self_t::next next;\ | |
138 | typedef typename self_t::type type;\ | |
139 | }; | |
140 | #else | |
141 | #define BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr) \ | |
142 | template<int _Typeof_Iteration>\ | |
143 | struct _typeof_encode_fraction {\ | |
144 | typedef _typeof_encode_fraction<_Typeof_Iteration> self_t;\ | |
145 | BOOST_STATIC_CONSTANT(int,_typeof_encode_offset = (_Typeof_Iteration*BOOST_TYPEOF_LIMIT_SIZE));\ | |
146 | typedef boost::type_of::offset_vector<BOOST_TYPEOF_VECTOR(0)<>,boost::mpl::size_t<self_t::_typeof_encode_offset> > _typeof_start_vector;\ | |
147 | BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE,BOOST_TYPEOF_NESTED_TYPEITEM,expr)\ | |
148 | };\ | |
149 | template<typename Pos>\ | |
150 | struct _typeof_fraction_iter {\ | |
151 | typedef _typeof_fraction_iter<Pos> self_t;\ | |
152 | BOOST_STATIC_CONSTANT(int,pos=(Pos::value));\ | |
153 | BOOST_STATIC_CONSTANT(int,iteration=(pos/BOOST_TYPEOF_LIMIT_SIZE));\ | |
154 | BOOST_STATIC_CONSTANT(int,where=pos%BOOST_TYPEOF_LIMIT_SIZE);\ | |
155 | BOOST_TYPEOF_FRACTIONTYPE()\ | |
156 | typedef typename boost::type_of::v_iter<fraction_type,boost::mpl::int_<self_t::where> >::type type;\ | |
157 | typedef _typeof_fraction_iter<typename Pos::next> next;\ | |
158 | }; | |
159 | #endif | |
160 | #ifdef __MWERKS__ | |
161 | ||
162 | # define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \ | |
163 | template<typename T>\ | |
164 | struct BOOST_PP_CAT(_typeof_template_,name) {\ | |
165 | BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\ | |
166 | typedef typename boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\ | |
167 | };\ | |
168 | typedef BOOST_PP_CAT(_typeof_template_,name)<int> name; | |
169 | ||
170 | # define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) | |
171 | ||
172 | #else | |
173 | # define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \ | |
174 | struct name {\ | |
175 | BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\ | |
176 | typedef typename boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\ | |
177 | }; | |
178 | ||
179 | # define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \ | |
180 | struct name {\ | |
181 | BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\ | |
182 | typedef boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\ | |
183 | }; | |
184 | #endif | |
185 | ||
186 | #endif//BOOST_TYPEOF_COMPLIANT_TYPEOF_IMPL_HPP_INCLUDED |