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