template_template_param.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright (C) 2005 Peder Holt
  2. // Copyright (C) 2005 Arkadiy Vertleyb
  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_TEMPLATE_PARAM_HPP_INCLUDED
  6. #define BOOST_TYPEOF_TEMPLATE_TEMPLATE_PARAM_HPP_INCLUDED
  7. #include <boost/preprocessor/logical/or.hpp>
  8. #include <boost/preprocessor/seq/fold_left.hpp>
  9. #include <boost/preprocessor/seq/enum.hpp>
  10. #define BOOST_TYPEOF_MAKE_OBJ_template(x) BOOST_TYPEOF_TEMPLATE_PARAM(x)
  11. #define BOOST_TYPEOF_TEMPLATE(X) template(X) BOOST_TYPEOF_EAT
  12. #define BOOST_TYPEOF_template(X) (template(X))
  13. #define BOOST_TYPEOF_TEMPLATE_PARAM(Params)\
  14. (TEMPLATE_PARAM)\
  15. (Params)
  16. #define BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(This)\
  17. BOOST_TYPEOF_TOSEQ(BOOST_PP_SEQ_ELEM(1, This))
  18. //Encode / decode this
  19. #define BOOST_TYPEOF_TEMPLATE_PARAM_ENCODE(This, n)\
  20. typedef typename boost::type_of::encode_template<BOOST_PP_CAT(V, n),\
  21. BOOST_PP_CAT(P, n)<BOOST_TYPEOF_SEQ_ENUM(BOOST_TYPEOF_MAKE_OBJS(BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(This)),BOOST_TYPEOF_PLACEHOLDER) >\
  22. >::type BOOST_PP_CAT(V, BOOST_PP_INC(n));
  23. #define BOOST_TYPEOF_TEMPLATE_PARAM_DECODE(This, n)\
  24. typedef boost::type_of::decode_template< BOOST_PP_CAT(iter, n) > BOOST_PP_CAT(d, n);\
  25. typedef typename BOOST_PP_CAT(d, n)::type BOOST_PP_CAT(P, n);\
  26. typedef typename BOOST_PP_CAT(d, n)::iter BOOST_PP_CAT(iter,BOOST_PP_INC(n));
  27. // template<class, unsigned int, ...> class
  28. #define BOOST_TYPEOF_TEMPLATE_PARAM_EXPANDTYPE(This) \
  29. template <BOOST_PP_SEQ_ENUM(BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(This)) > class
  30. #define BOOST_TYPEOF_TEMPLATE_PARAM_PLACEHOLDER(Param)\
  31. Nested_Template_Template_Arguments_Not_Supported
  32. //'template<class,int> class' is reduced to 'class'
  33. #define BOOST_TYPEOF_TEMPLATE_PARAM_DECLARATION_TYPE(Param) class
  34. // T3<int, (unsigned int)0, ...>
  35. #define BOOST_TYPEOF_TEMPLATE_PARAM_PLACEHOLDER_TYPES(Param, n)\
  36. BOOST_PP_CAT(T,n)<BOOST_TYPEOF_SEQ_ENUM_1(BOOST_TYPEOF_MAKE_OBJS(BOOST_TYPEOF_TEMPLATE_PARAM_GETPARAMS(Param)),BOOST_TYPEOF_PLACEHOLDER) >
  37. #define BOOST_TYPEOF_TEMPLATE_PARAM_ISTEMPLATE 1
  38. ////////////////////////////
  39. // move to encode_decode?
  40. BOOST_TYPEOF_BEGIN_ENCODE_NS
  41. template<class V, class Type_Not_Registered_With_Typeof_System> struct encode_template_impl;
  42. template<class T, class Iter> struct decode_template_impl;
  43. BOOST_TYPEOF_END_ENCODE_NS
  44. namespace boost { namespace type_of {
  45. template<class V, class T> struct encode_template
  46. : BOOST_TYPEOF_ENCODE_NS_QUALIFIER::encode_template_impl<V, T>
  47. {};
  48. template<class Iter> struct decode_template
  49. : BOOST_TYPEOF_ENCODE_NS_QUALIFIER::decode_template_impl<typename Iter::type, typename Iter::next>
  50. {};
  51. }}
  52. ////////////////////////////
  53. // move to template_encoding.hpp?
  54. //Template template registration
  55. #define BOOST_TYPEOF_REGISTER_TYPE_FOR_TEMPLATE_TEMPLATE(Name,Params,ID)\
  56. template<class V\
  57. BOOST_TYPEOF_SEQ_ENUM_TRAILING(Params,BOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR)\
  58. >\
  59. struct encode_template_impl<V,Name<\
  60. BOOST_PP_ENUM_PARAMS(\
  61. BOOST_PP_SEQ_SIZE(Params),\
  62. P)> >\
  63. : boost::type_of::push_back<V, boost::type_of::constant<std::size_t,ID> >\
  64. {\
  65. };\
  66. template<class Iter> struct decode_template_impl<boost::type_of::constant<std::size_t,ID>, Iter>\
  67. {\
  68. BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(Params),BOOST_TYPEOF_TYPEDEF_INT_PN,_)\
  69. typedef Name<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_PLACEHOLDER) > type;\
  70. typedef Iter iter;\
  71. };
  72. #define BOOST_TYPEOF_TYPEDEF_INT_PN(z,n,Params) typedef int BOOST_PP_CAT(P,n);
  73. #ifdef __BORLANDC__
  74. #define BOOST_TYPEOF_DECODE_NESTED_TEMPLATE_HELPER_NAME BOOST_PP_CAT(\
  75. BOOST_PP_CAT(\
  76. BOOST_PP_CAT(\
  77. decode_nested_template_helper,\
  78. BOOST_TYPEOF_REGISTRATION_GROUP\
  79. ),0x10000\
  80. ),__LINE__\
  81. )
  82. #define BOOST_TYPEOF_REGISTER_DECODE_NESTED_TEMPLATE_HELPER_IMPL(Name,Params,ID)\
  83. struct BOOST_TYPEOF_DECODE_NESTED_TEMPLATE_HELPER_NAME {\
  84. template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECLARE_DECODER_TYPE_PARAM_PAIR) >\
  85. struct decode_params;\
  86. template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECODER_TYPE_PARAM_PAIR) >\
  87. struct decode_params<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_PLACEHOLDER_TYPES) >\
  88. {\
  89. typedef Name<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),T)> type;\
  90. };\
  91. };
  92. //Template template param decoding
  93. #define BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TEMPLATE_TYPE(Name,Params)\
  94. typedef typename BOOST_TYPEOF_DECODE_NESTED_TEMPLATE_HELPER_NAME::decode_params<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),P)>::type type;
  95. #else
  96. #define BOOST_TYPEOF_REGISTER_DECODE_NESTED_TEMPLATE_HELPER_IMPL(Name,Params,ID)
  97. //Template template param decoding
  98. #define BOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TEMPLATE_TYPE(Name,Params)\
  99. template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECLARE_DECODER_TYPE_PARAM_PAIR) >\
  100. struct decode_params;\
  101. template<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_REGISTER_DECODER_TYPE_PARAM_PAIR) >\
  102. struct decode_params<BOOST_TYPEOF_SEQ_ENUM(Params,BOOST_TYPEOF_PLACEHOLDER_TYPES) >\
  103. {\
  104. typedef Name<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),T)> type;\
  105. };\
  106. typedef typename decode_params<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(Params),P)>::type type;
  107. #endif
  108. #define BOOST_TYPEOF_REGISTER_DECLARE_DECODER_TYPE_PARAM_PAIR(z,n,elem) \
  109. BOOST_TYPEOF_VIRTUAL(DECLARATION_TYPE, elem)(elem) BOOST_PP_CAT(T, n)
  110. // BOOST_TYPEOF_HAS_TEMPLATES
  111. #define BOOST_TYPEOF_HAS_TEMPLATES(Params)\
  112. BOOST_PP_SEQ_FOLD_LEFT(BOOST_TYPEOF_HAS_TEMPLATES_OP, 0, Params)
  113. #define BOOST_TYPEOF_HAS_TEMPLATES_OP(s, state, elem)\
  114. BOOST_PP_OR(state, BOOST_TYPEOF_VIRTUAL(ISTEMPLATE, elem))
  115. //Define template template arguments
  116. #define BOOST_TYPEOF_REGISTER_TEMPLATE_TEMPLATE_IMPL(Name,Params,ID)\
  117. BOOST_PP_IF(BOOST_TYPEOF_HAS_TEMPLATES(Params),\
  118. BOOST_TYPEOF_REGISTER_DECODE_NESTED_TEMPLATE_HELPER_IMPL,\
  119. BOOST_TYPEOF_REGISTER_TYPE_FOR_TEMPLATE_TEMPLATE)(Name,Params,ID)
  120. #endif //BOOST_TYPEOF_TEMPLATE_TEMPLATE_PARAM_HPP_INCLUDED