substitute.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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. //
  129. // function specializations
  130. //
  131. template <
  132. typename R
  133. , typename... A
  134. , typename Dest
  135. , typename Source
  136. >
  137. struct substitute<
  138. R (*)(A...)
  139. , Dest
  140. , Source
  141. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  142. >
  143. {
  144. private:
  145. typedef typename substitute< R, Dest, Source >::type r;
  146. public:
  147. typedef r (*type)(typename substitute<
  148. A, Dest, Source
  149. >::type...);
  150. };
  151. #else
  152. #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL(N) \
  153. typedef typename substitute< \
  154. BOOST_PP_CAT(U,N), Dest, Source \
  155. >::type BOOST_PP_CAT(u,N); \
  156. /**/
  157. #define BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF(z, N, _) \
  158. BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL( BOOST_PP_INC(N) ) \
  159. /**/
  160. #define BOOST_PP_ITERATION_LIMITS (0,BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
  161. #define BOOST_PP_FILENAME_1 <boost/variant/detail/substitute.hpp>
  162. #include BOOST_PP_ITERATE()
  163. #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF_IMPL
  164. #undef BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF
  165. #endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
  166. #endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
  167. }} // namespace detail::variant
  168. } // namespace boost
  169. #endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_HPP
  170. ///// iteration, depth == 1
  171. #elif BOOST_PP_ITERATION_DEPTH() == 1
  172. #define i BOOST_PP_FRAME_ITERATION(1)
  173. #if i > 0
  174. //
  175. // template specializations
  176. //
  177. template <
  178. template < BOOST_MPL_PP_PARAMS(i,typename P) > class T
  179. , BOOST_MPL_PP_PARAMS(i,typename U)
  180. , typename Dest
  181. , typename Source
  182. >
  183. struct substitute<
  184. T< BOOST_MPL_PP_PARAMS(i,U) >
  185. , Dest
  186. , Source
  187. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<( i )>)
  188. >
  189. {
  190. private:
  191. BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
  192. public:
  193. typedef T< BOOST_MPL_PP_PARAMS(i,u) > type;
  194. };
  195. //
  196. // function specializations
  197. //
  198. template <
  199. typename R
  200. , BOOST_MPL_PP_PARAMS(i,typename U)
  201. , typename Dest
  202. , typename Source
  203. >
  204. struct substitute<
  205. R (*)( BOOST_MPL_PP_PARAMS(i,U) )
  206. , Dest
  207. , Source
  208. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  209. >
  210. {
  211. private:
  212. typedef typename substitute< R, Dest, Source >::type r;
  213. BOOST_MPL_PP_REPEAT(i, BOOST_VARIANT_AUX_SUBSTITUTE_TYPEDEF, _)
  214. public:
  215. typedef r (*type)( BOOST_MPL_PP_PARAMS(i,u) );
  216. };
  217. #elif i == 0
  218. //
  219. // zero-arg function specialization
  220. //
  221. template <
  222. typename R, typename Dest, typename Source
  223. >
  224. struct substitute<
  225. R (*)( void )
  226. , Dest
  227. , Source
  228. BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(mpl::int_<-1>)
  229. >
  230. {
  231. private:
  232. typedef typename substitute< R, Dest, Source >::type r;
  233. public:
  234. typedef r (*type)( void );
  235. };
  236. #endif // i
  237. #undef i
  238. #endif // BOOST_PP_IS_ITERATING