substitute.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //-----------------------------------------------------------------------------
  2. // boost variant/detail/substitute.hpp header file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2003
  7. // Eric Friedman
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
  13. #define BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
  14. #include <boost/mpl/aux_/config/ctps.hpp>
  15. #include <boost/variant/detail/substitute_fwd.hpp>
  16. #include <boost/variant/variant_fwd.hpp>
  17. #include <boost/mpl/aux_/lambda_arity_param.hpp>
  18. #include <boost/mpl/aux_/preprocessor/params.hpp>
  19. #include <boost/mpl/aux_/preprocessor/repeat.hpp>
  20. #include <boost/mpl/int_fwd.hpp>
  21. #include <boost/mpl/limits/arity.hpp>
  22. #include <boost/preprocessor/empty.hpp>
  23. namespace boost {
  24. namespace detail { namespace variant {
  25. ///////////////////////////////////////////////////////////////////////////////
  26. // (detail) metafunction substitute
  27. //
  28. // Substitutes one type for another in the given type expression.
  29. //
  30. //
  31. // primary template
  32. //
  33. template <
  34. typename T, typename Dest, typename Source
  35. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(
  36. typename Arity /* = ... (see substitute_fwd.hpp) */
  37. )
  38. >
  39. struct substitute
  40. {
  41. typedef T type;
  42. };
  43. //
  44. // tag substitution specializations
  45. //
  46. #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(CV_) \
  47. template <typename Dest, typename Source> \
  48. struct substitute< \
  49. CV_ Source \
  50. , Dest \
  51. , Source \
  52. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \
  53. > \
  54. { \
  55. typedef CV_ Dest type; \
  56. }; \
  57. /**/
  58. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG( BOOST_PP_EMPTY() )
  59. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const)
  60. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(volatile)
  61. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const volatile)
  62. #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG
  63. //
  64. // pointer specializations
  65. //
  66. #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(CV_) \
  67. template <typename T, typename Dest, typename Source> \
  68. struct substitute< \
  69. T * CV_ \
  70. , Dest \
  71. , Source \
  72. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \
  73. > \
  74. { \
  75. typedef typename substitute< \
  76. T, Dest, Source \
  77. >::type * CV_ type; \
  78. }; \
  79. /**/
  80. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER( BOOST_PP_EMPTY() )
  81. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const)
  82. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(volatile)
  83. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const volatile)
  84. #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER
  85. //
  86. // reference specializations
  87. //
  88. template <typename T, typename Dest, typename Source>
  89. struct substitute<
  90. T&
  91. , Dest
  92. , Source
  93. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  94. >
  95. {
  96. typedef typename substitute<
  97. T, Dest, Source
  98. >::type & type;
  99. };
  100. //
  101. // template expression (i.e., F<...>) specializations
  102. //
  103. template <
  104. template <typename...> class F
  105. , typename... Ts
  106. , typename Dest
  107. , typename Source
  108. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
  109. >
  110. struct substitute<
  111. F<Ts...>
  112. , Dest
  113. , Source
  114. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
  115. >
  116. {
  117. typedef F<typename substitute<
  118. Ts, Dest, Source
  119. >::type...> type;
  120. };
  121. //
  122. // function specializations
  123. //
  124. template <
  125. typename R
  126. , typename... A
  127. , typename Dest
  128. , typename Source
  129. >
  130. struct substitute<
  131. R (*)(A...)
  132. , Dest
  133. , Source
  134. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  135. >
  136. {
  137. private:
  138. typedef typename substitute< R, Dest, Source >::type r;
  139. public:
  140. typedef r (*type)(typename substitute<
  141. A, Dest, Source
  142. >::type...);
  143. };
  144. }} // namespace detail::variant
  145. } // namespace boost
  146. #endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP