substitute.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #if !defined(BOOST_PP_IS_ITERATING)
  2. ///// header body
  3. //-----------------------------------------------------------------------------
  4. // boost variant/detail/substitute.hpp header file
  5. // See http://www.boost.org for updates, documentation, and revision history.
  6. //-----------------------------------------------------------------------------
  7. //
  8. // Copyright (c) 2003
  9. // Eric Friedman
  10. //
  11. // Distributed under the Boost Software License, Version 1.0. (See
  12. // accompanying file LICENSE_1_0.txt or copy at
  13. // http://www.boost.org/LICENSE_1_0.txt)
  14. #ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
  15. #define BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
  16. #include "boost/mpl/aux_/config/ctps.hpp"
  17. #include "boost/variant/detail/substitute_fwd.hpp"
  18. #include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
  19. #include "boost/mpl/aux_/lambda_arity_param.hpp"
  20. #include "boost/mpl/aux_/preprocessor/params.hpp"
  21. #include "boost/mpl/aux_/preprocessor/repeat.hpp"
  22. #include "boost/mpl/int_fwd.hpp"
  23. #include "boost/mpl/limits/arity.hpp"
  24. #include "boost/preprocessor/cat.hpp"
  25. #include "boost/preprocessor/empty.hpp"
  26. #include "boost/preprocessor/arithmetic/inc.hpp"
  27. #include "boost/preprocessor/iterate.hpp"
  28. namespace boost {
  29. namespace detail { namespace variant {
  30. #if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
  31. ///////////////////////////////////////////////////////////////////////////////
  32. // (detail) metafunction substitute
  33. //
  34. // Substitutes one type for another in the given type expression.
  35. //
  36. //
  37. // primary template
  38. //
  39. template <
  40. typename T, typename Dest, typename Source
  41. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(
  42. typename Arity /* = ... (see substitute_fwd.hpp) */
  43. )
  44. >
  45. struct substitute
  46. {
  47. typedef T type;
  48. };
  49. //
  50. // tag substitution specializations
  51. //
  52. #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(CV_) \
  53. template <typename Dest, typename Source> \
  54. struct substitute< \
  55. CV_ Source \
  56. , Dest \
  57. , Source \
  58. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \
  59. > \
  60. { \
  61. typedef CV_ Dest type; \
  62. }; \
  63. /**/
  64. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG( BOOST_PP_EMPTY() )
  65. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const)
  66. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(volatile)
  67. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG(const volatile)
  68. #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_SUBSTITUTE_TAG
  69. //
  70. // pointer specializations
  71. //
  72. #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(CV_) \
  73. template <typename T, typename Dest, typename Source> \
  74. struct substitute< \
  75. T * CV_ \
  76. , Dest \
  77. , Source \
  78. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>) \
  79. > \
  80. { \
  81. typedef typename substitute< \
  82. T, Dest, Source \
  83. >::type * CV_ type; \
  84. }; \
  85. /**/
  86. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER( BOOST_PP_EMPTY() )
  87. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const)
  88. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(volatile)
  89. BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER(const volatile)
  90. #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_IMPL_HANDLE_POINTER
  91. //
  92. // reference specializations
  93. //
  94. template <typename T, typename Dest, typename Source>
  95. struct substitute<
  96. T&
  97. , Dest
  98. , Source
  99. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  100. >
  101. {
  102. typedef typename substitute<
  103. T, Dest, Source
  104. >::type & type;
  105. };
  106. //
  107. // template expression (i.e., F<...>) specializations
  108. //
  109. #if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
  110. template <
  111. template <typename...> class F
  112. , typename... Ts
  113. , typename Dest
  114. , typename Source
  115. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(typename Arity)
  116. >
  117. struct substitute<
  118. F<Ts...>
  119. , Dest
  120. , Source
  121. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(Arity)
  122. >
  123. {
  124. typedef F<typename substitute<
  125. Ts, Dest, Source
  126. >::type...> type;
  127. };
  128. #endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
  129. #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \
  130. typedef typename substitute< \
  131. BOOST_PP_CAT(U,N), Dest, Source \
  132. >::type BOOST_PP_CAT(u,N); \
  133. /**/
  134. #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF(z, N, _) \
  135. BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \
  136. /**/
  137. #define BOOST_PP_ITERATION_LIMITS (0,BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
  138. #define BOOST_PP_FILENAME_1 "boost/variant/detail/substitute.hpp"
  139. #include BOOST_PP_ITERATE()
  140. #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL
  141. #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF
  142. #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
  143. }} // namespace detail::variant
  144. } // namespace boost
  145. #endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
  146. ///// iteration, depth == 1
  147. #elif BOOST_PP_ITERATION_DEPTH() == 1
  148. #define i BOOST_PP_FRAME_ITERATION(1)
  149. #if i > 0
  150. //
  151. // template specializations
  152. //
  153. template <
  154. template < BOOST_MPL_PP_PARAMS(i,typename P) > class T
  155. , BOOST_MPL_PP_PARAMS(i,typename U)
  156. , typename Dest
  157. , typename Source
  158. >
  159. struct substitute<
  160. T< BOOST_MPL_PP_PARAMS(i,U) >
  161. , Dest
  162. , Source
  163. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>)
  164. >
  165. {
  166. private:
  167. BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
  168. public:
  169. typedef T< BOOST_MPL_PP_PARAMS(i,u) > type;
  170. };
  171. //
  172. // function specializations
  173. //
  174. template <
  175. typename R
  176. , BOOST_MPL_PP_PARAMS(i,typename U)
  177. , typename Dest
  178. , typename Source
  179. >
  180. struct substitute<
  181. R (*)( BOOST_MPL_PP_PARAMS(i,U) )
  182. , Dest
  183. , Source
  184. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  185. >
  186. {
  187. private:
  188. typedef typename substitute< R, Dest, Source >::type r;
  189. BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
  190. public:
  191. typedef r (*type)( BOOST_MPL_PP_PARAMS(i,u) );
  192. };
  193. #elif i == 0
  194. //
  195. // zero-arg function specialization
  196. //
  197. template <
  198. typename R, typename Dest, typename Source
  199. >
  200. struct substitute<
  201. R (*)( void )
  202. , Dest
  203. , Source
  204. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  205. >
  206. {
  207. private:
  208. typedef typename substitute< R, Dest, Source >::type r;
  209. public:
  210. typedef r (*type)( void );
  211. };
  212. #endif // i
  213. #undef i
  214. #endif // BOOST_PP_IS_ITERATING