template_encoding.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // Copyright (C) 2004 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_TEMPLATE_ENCODING_HPP_INCLUDED
  6. #define BOOST_TYPEOF_TEMPLATE_ENCODING_HPP_INCLUDED
  7. #include <boost/preprocessor/cat.hpp>
  8. #include <boost/preprocessor/repetition/enum_trailing.hpp>
  9. #include <boost/preprocessor/control/iif.hpp>
  10. #include <boost/preprocessor/detail/is_unary.hpp>
  11. #include <boost/preprocessor/repetition/repeat.hpp>
  12. #include <boost/preprocessor/tuple/eat.hpp>
  13. #include <boost/preprocessor/seq/transform.hpp>
  14. #include <boost/preprocessor/seq/for_each_i.hpp>
  15. #include <boost/preprocessor/seq/cat.hpp>
  16. #include <boost/typeof/encode_decode.hpp>
  17. #include <boost/typeof/int_encoding.hpp>
  18. #include <boost/typeof/type_template_param.hpp>
  19. #include <boost/typeof/integral_template_param.hpp>
  20. #include <boost/typeof/template_template_param.hpp>
  21. #ifdef __BORLANDC__
  22. #define BOOST_TYPEOF_QUALIFY(P) self_t::P
  23. #else
  24. #define BOOST_TYPEOF_QUALIFY(P) P
  25. #endif
  26. // The template parameter description, entered by the user,
  27. // is converted into a polymorphic "object"
  28. // that is used to generate the code responsible for
  29. // encoding/decoding the parameter, etc.
  30. // make sure to cat the sequence first, and only then add the prefix.
  31. #define BOOST_TYPEOF_MAKE_OBJ(elem) BOOST_PP_CAT(\
  32. BOOST_TYPEOF_MAKE_OBJ,\
  33. BOOST_PP_SEQ_CAT((_) BOOST_TYPEOF_TO_SEQ(elem))\
  34. )
  35. #define BOOST_TYPEOF_TO_SEQ(tokens) BOOST_TYPEOF_ ## tokens ## _BOOST_TYPEOF
  36. // BOOST_TYPEOF_REGISTER_TEMPLATE
  37. #define BOOST_TYPEOF_REGISTER_TEMPLATE_EXPLICIT_ID(Name, Params, Id)\
  38. BOOST_TYPEOF_REGISTER_TEMPLATE_IMPL(\
  39. Name,\
  40. BOOST_TYPEOF_MAKE_OBJS(BOOST_TYPEOF_TOSEQ(Params)),\
  41. BOOST_PP_SEQ_SIZE(BOOST_TYPEOF_TOSEQ(Params)),\
  42. Id)
  43. #define BOOST_TYPEOF_REGISTER_TEMPLATE(Name, Params)\
  44. BOOST_TYPEOF_REGISTER_TEMPLATE_EXPLICIT_ID(Name, Params, BOOST_TYPEOF_UNIQUE_ID())
  45. #define BOOST_TYPEOF_OBJECT_MAKER(s, data, elem)\
  46. BOOST_TYPEOF_MAKE_OBJ(elem)
  47. #define BOOST_TYPEOF_MAKE_OBJS(Params)\
  48. BOOST_PP_SEQ_TRANSFORM(BOOST_TYPEOF_OBJECT_MAKER, ~, Params)
  49. // As suggested by Paul Mensonides:
  50. #define BOOST_TYPEOF_TOSEQ(x)\
  51. BOOST_PP_IIF(\
  52. BOOST_PP_IS_UNARY(x),\
  53. x BOOST_PP_TUPLE_EAT(3), BOOST_PP_REPEAT\
  54. )(x, BOOST_TYPEOF_TOSEQ_2, ~)
  55. #define BOOST_TYPEOF_TOSEQ_2(z, n, _) (class)
  56. // BOOST_TYPEOF_VIRTUAL
  57. #define BOOST_TYPEOF_CAT_4(a, b, c, d) BOOST_TYPEOF_CAT_4_I(a, b, c, d)
  58. #define BOOST_TYPEOF_CAT_4_I(a, b, c, d) a ## b ## c ## d
  59. #define BOOST_TYPEOF_VIRTUAL(Fun, Obj)\
  60. BOOST_TYPEOF_CAT_4(BOOST_TYPEOF_, BOOST_PP_SEQ_HEAD(Obj), _, Fun)
  61. // BOOST_TYPEOF_SEQ_ENUM[_TRAILING][_1]
  62. // Two versions provided due to reentrancy issue
  63. #define BOOST_TYPEOF_SEQ_EXPAND_ELEMENT(z,n,seq)\
  64. BOOST_PP_SEQ_ELEM(0,seq) (z,n,BOOST_PP_SEQ_ELEM(n,BOOST_PP_SEQ_ELEM(1,seq)))
  65. #define BOOST_TYPEOF_SEQ_ENUM(seq,macro)\
  66. BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT,(macro)(seq))
  67. #define BOOST_TYPEOF_SEQ_ENUM_TRAILING(seq,macro)\
  68. BOOST_PP_ENUM_TRAILING(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT,(macro)(seq))
  69. #define BOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1(z,n,seq)\
  70. BOOST_PP_SEQ_ELEM(0,seq) (z,n,BOOST_PP_SEQ_ELEM(n,BOOST_PP_SEQ_ELEM(1,seq)))
  71. #define BOOST_TYPEOF_SEQ_ENUM_1(seq,macro)\
  72. BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1,(macro)(seq))
  73. #define BOOST_TYPEOF_SEQ_ENUM_TRAILING_1(seq,macro)\
  74. BOOST_PP_ENUM_TRAILING(BOOST_PP_SEQ_SIZE(seq),BOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1,(macro)(seq))
  75. //
  76. #define BOOST_TYPEOF_PLACEHOLDER(z, n, elem)\
  77. BOOST_TYPEOF_VIRTUAL(PLACEHOLDER, elem)(elem)
  78. #define BOOST_TYPEOF_PLACEHOLDER_TYPES(z, n, elem)\
  79. BOOST_TYPEOF_VIRTUAL(PLACEHOLDER_TYPES, elem)(elem, n)
  80. #define BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM(r, data, n, elem)\
  81. BOOST_TYPEOF_VIRTUAL(ENCODE, elem)(elem, n)
  82. #define BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM(r, data, n, elem)\
  83. BOOST_TYPEOF_VIRTUAL(DECODE, elem)(elem, n)
  84. #define BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR(z, n, elem) \
  85. BOOST_TYPEOF_VIRTUAL(EXPANDTYPE, elem)(elem) BOOST_PP_CAT(P, n)
  86. #define BOOST_TYPEOF_REGISTER_DEFAULT_TEMPLATE_TYPE(Name,Params,ID)\
  87. Name< BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params), P) >
  88. //Since we are creating an internal decode struct, we need to use different template names, T instead of P.
  89. #define BOOST_TYPEOF_REGISTER_DECODER_TYPE_PARAM_PAIR(z,n,elem) \
  90. BOOST_TYPEOF_VIRTUAL(EXPANDTYPE, elem)(elem) BOOST_PP_CAT(T, n)
  91. //Default template param decoding
  92. #define BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TYPE(Name,Params)\
  93. typedef Name<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),BOOST_TYPEOF_QUALIFY(P))> type;
  94. //Branch the decoding
  95. #define BOOST_TYPEOF_TYPEDEF_DECODED_TYPE(Name,Params)\
  96. BOOST_PP_IF(BOOST_TYPEOF_HAS_TEMPLATES(Params),\
  97. BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TEMPLATE_TYPE,\
  98. BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TYPE)(Name,Params)
  99. #define BOOST_TYPEOF_REGISTER_TEMPLATE_IMPL(Name, Params, Size, ID)\
  100. BOOST_TYPEOF_BEGIN_ENCODE_NS\
  101. BOOST_TYPEOF_REGISTER_TEMPLATE_TEMPLATE_IMPL(Name, Params, ID)\
  102. template<class V\
  103. BOOST_TYPEOF_SEQ_ENUM_TRAILING(Params, BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR)\
  104. >\
  105. struct encode_type_impl<V, Name<BOOST_PP_ENUM_PARAMS(Size, P)> >\
  106. {\
  107. typedef typename boost::type_of::push_back<V, boost::type_of::constant<std::size_t,ID> >::type V0;\
  108. BOOST_PP_SEQ_FOR_EACH_I(BOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM, ~, Params)\
  109. typedef BOOST_PP_CAT(V, Size) type;\
  110. };\
  111. template<class Iter>\
  112. struct decode_type_impl<boost::type_of::constant<std::size_t,ID>, Iter>\
  113. {\
  114. typedef decode_type_impl<boost::type_of::constant<std::size_t,ID>, Iter> self_t;\
  115. typedef boost::type_of::constant<std::size_t,ID> self_id;\
  116. typedef Iter iter0;\
  117. BOOST_PP_SEQ_FOR_EACH_I(BOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM, ~, Params)\
  118. BOOST_TYPEOF_TYPEDEF_DECODED_TYPE(Name, Params)\
  119. typedef BOOST_PP_CAT(iter, Size) iter;\
  120. };\
  121. BOOST_TYPEOF_END_ENCODE_NS
  122. #endif//BOOST_TYPEOF_TEMPLATE_ENCODING_HPP_INCLUDED