typeof_impl.hpp 7.2 KB

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