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/preprocessor/repetition/enum.hpp> 10 #include <boost/typeof/constant.hpp> 11 #include <boost/typeof/encode_decode.hpp> 12 #include <boost/typeof/vector.hpp> 13 #include <boost/type_traits/enable_if.hpp> 14 #include <boost/type_traits/is_function.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 is_function<T>::value, 44 sizer<typename encode_type<V, T>::type> >::type encode(T&); 45 46 template<class V, class T> 47 typename enable_if_< 48 !is_function<T>::value, 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::type_of::constant<std::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,constant<std::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::type_of::constant<std::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,constant<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::type_of::constant<std::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::type_of::constant<std::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::type_of::constant<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::type_of::constant<std::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::type_of::constant<std::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::type_of::constant<std::size_t,0> > >::type type;\ 183 }; 184 #endif 185 186 #endif//BOOST_TYPEOF_COMPLIANT_TYPEOF_IMPL_HPP_INCLUDED 187