080219966d2cd10c4b7604822ab37bb1f460545d
[senf.git] / boost / typeof / typeof_impl.hpp
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(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<iteration> fraction_type;
107 #endif
108
109 #define BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr) \
110         template<int _Typeof_Iteration>\
111         struct _typeof_encode_fraction {\
112             BOOST_STATIC_CONSTANT(int,_typeof_encode_offset = (_Typeof_Iteration*BOOST_TYPEOF_LIMIT_SIZE));\
113             typedef boost::type_of::offset_vector<BOOST_TYPEOF_VECTOR(0)<>,boost::mpl::size_t<_typeof_encode_offset> > _typeof_start_vector;\
114             BOOST_PP_REPEAT(BOOST_TYPEOF_LIMIT_SIZE,BOOST_TYPEOF_NESTED_TYPEITEM,expr)\
115         };\
116         template<typename Pos>\
117         struct _typeof_fraction_iter {\
118             BOOST_STATIC_CONSTANT(int,pos=(Pos::value));\
119             BOOST_STATIC_CONSTANT(int,iteration=(pos/BOOST_TYPEOF_LIMIT_SIZE));\
120             BOOST_STATIC_CONSTANT(int,where=pos%BOOST_TYPEOF_LIMIT_SIZE);\
121             BOOST_TYPEOF_FRACTIONTYPE();\
122             typedef typename boost::type_of::v_iter<fraction_type,boost::mpl::int_<where> >::type type;\
123             typedef _typeof_fraction_iter<typename Pos::next> next;\
124         };
125
126 #ifdef __MWERKS__
127
128 # define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \
129 template<typename T>\
130 struct BOOST_PP_CAT(_typeof_template_,name) {\
131     BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\
132     typedef typename boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\
133 };\
134 typedef BOOST_PP_CAT(_typeof_template_,name)<int> name;
135
136 # define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) BOOST_TYPEOF_NESTED_TYPEDEF(name,expr);
137
138 #else
139 # define BOOST_TYPEOF_NESTED_TYPEDEF_TPL(name,expr) \
140     struct name {\
141         BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\
142         typedef typename boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\
143     };
144
145 # define BOOST_TYPEOF_NESTED_TYPEDEF(name,expr) \
146     struct name {\
147         BOOST_TYPEOF_NESTED_TYPEDEF_IMPL(expr)\
148         typedef boost::type_of::decode_type<_typeof_fraction_iter<boost::mpl::size_t<0> > >::type type;\
149     };
150 #endif
151
152 #endif//BOOST_TYPEOF_COMPLIANT_TYPEOF_IMPL_HPP_INCLUDED