get_placeholders.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // Boost.TypeErasure library
  2. //
  3. // Copyright 2011 Steven Watanabe
  4. //
  5. // Distributed under the Boost Software License Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // $Id$
  10. #if !defined(BOOST_PP_IS_ITERATING)
  11. #ifndef BOOST_TYPE_ERASURE_DETAIL_GET_PLACEHOLDERS_HPP_INCLUDED
  12. #define BOOST_TYPE_ERASURE_DETAIL_GET_PLACEHOLDERS_HPP_INCLUDED
  13. #include <boost/mpl/eval_if.hpp>
  14. #include <boost/mpl/identity.hpp>
  15. #include <boost/mpl/insert.hpp>
  16. #include <boost/preprocessor/cat.hpp>
  17. #include <boost/preprocessor/iteration/iterate.hpp>
  18. #include <boost/preprocessor/repetition/enum.hpp>
  19. #include <boost/preprocessor/repetition/enum_params.hpp>
  20. #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  21. #include <boost/type_erasure/detail/meta.hpp>
  22. #include <boost/type_erasure/config.hpp>
  23. #include <boost/type_erasure/is_placeholder.hpp>
  24. namespace boost {
  25. namespace type_erasure {
  26. namespace detail {
  27. #ifdef BOOST_TYPE_ERASURE_USE_MP11
  28. template<class T>
  29. struct get_placeholders_in_argument_impl
  30. {
  31. template<class Out>
  32. using apply = ::boost::type_erasure::detail::eval_if<
  33. ::boost::type_erasure::is_placeholder<T>::value,
  34. ::boost::mp11::mp_set_push_back,
  35. ::boost::type_erasure::detail::first,
  36. Out, T
  37. >;
  38. };
  39. template<class T>
  40. struct get_placeholders_in_argument_impl<T&>
  41. {
  42. template<class Out>
  43. using apply = typename ::boost::type_erasure::detail::get_placeholders_in_argument_impl<T>::template apply<Out>;
  44. };
  45. template<class T>
  46. struct get_placeholders_in_argument_impl<T&&>
  47. {
  48. template<class Out>
  49. using apply = typename ::boost::type_erasure::detail::get_placeholders_in_argument_impl<T>::template apply<Out>;
  50. };
  51. template<class T>
  52. struct get_placeholders_in_argument_impl<const T>
  53. {
  54. template<class Out>
  55. using apply = typename ::boost::type_erasure::detail::get_placeholders_in_argument_impl<T>::template apply<Out>;
  56. };
  57. template<class Out, class T>
  58. using get_placeholders_f = typename get_placeholders_in_argument_impl<T>::template apply<Out>;
  59. template<class Out, class... T>
  60. using get_placeholders_impl =
  61. ::boost::mp11::mp_fold<
  62. ::boost::mp11::mp_list<T...>,
  63. Out,
  64. ::boost::type_erasure::detail::get_placeholders_f
  65. >;
  66. template<class R, class... T>
  67. struct get_placeholders_in_argument_impl<R(T...)>
  68. {
  69. template<class Out>
  70. using apply = ::boost::type_erasure::detail::get_placeholders_impl<Out, R, T...>;
  71. };
  72. template<class R, class C, class... T>
  73. struct get_placeholders_in_argument_impl<R (C::*)(T...)>
  74. {
  75. template<class Out>
  76. using apply = ::boost::type_erasure::detail::get_placeholders_impl<Out, R, C, T...>;
  77. };
  78. template<class R, class C, class... T>
  79. struct get_placeholders_in_argument_impl<R (C::*)(T...) const>
  80. {
  81. template<class Out>
  82. using apply = ::boost::type_erasure::detail::get_placeholders_impl<Out, R, C, T...>;
  83. };
  84. template<class T, class Out>
  85. struct get_placeholders;
  86. template<template<class...> class F, class... T, class Out>
  87. struct get_placeholders<F<T...>, Out>
  88. {
  89. using type = ::boost::type_erasure::detail::get_placeholders_impl<Out, T...>;
  90. };
  91. template<class T, class Out>
  92. using get_placeholders_t = typename ::boost::type_erasure::detail::get_placeholders<T, Out>::type;
  93. #else
  94. template<class T, class Out>
  95. struct get_placeholders_in_argument
  96. {
  97. typedef typename ::boost::mpl::eval_if<
  98. ::boost::type_erasure::is_placeholder<T>,
  99. ::boost::mpl::insert<Out, T>,
  100. ::boost::mpl::identity<Out>
  101. >::type type;
  102. };
  103. template<class T, class Out>
  104. struct get_placeholders;
  105. template<class T, class Out>
  106. struct get_placeholders_in_argument<T&, Out>
  107. {
  108. typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
  109. T,
  110. Out
  111. >::type type;
  112. };
  113. template<class T, class Out>
  114. struct get_placeholders_in_argument<const T, Out>
  115. {
  116. typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
  117. T,
  118. Out
  119. >::type type;
  120. };
  121. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  122. template<class Out, class... T>
  123. struct get_placeholders_impl;
  124. template<class Out, class T0, class... T>
  125. struct get_placeholders_impl<Out, T0, T...>
  126. {
  127. typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
  128. T0,
  129. typename get_placeholders_impl<Out, T...>::type
  130. >::type type;
  131. };
  132. template<class Out>
  133. struct get_placeholders_impl<Out>
  134. {
  135. typedef Out type;
  136. };
  137. template<template<class...> class T, class... U, class Out>
  138. struct get_placeholders<T<U...>, Out>
  139. {
  140. typedef typename get_placeholders_impl<Out, U...>::type type;
  141. };
  142. template<class R, class... T, class Out>
  143. struct get_placeholders_in_argument<R(T...), Out>
  144. {
  145. typedef typename get_placeholders_impl<Out, R, T...>::type type;
  146. };
  147. template<class R, class C, class... T, class Out>
  148. struct get_placeholders_in_argument<R (C::*)(T...), Out>
  149. {
  150. typedef typename get_placeholders_impl<Out, R, C, T...>::type type;
  151. };
  152. template<class R, class C, class... T, class Out>
  153. struct get_placeholders_in_argument<R (C::*)(T...) const, Out>
  154. {
  155. typedef typename get_placeholders_impl<Out, R, C, T...>::type type;
  156. };
  157. #else
  158. #define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/get_placeholders.hpp>
  159. #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
  160. #include BOOST_PP_ITERATE()
  161. #endif
  162. #endif
  163. }
  164. }
  165. }
  166. #endif
  167. #else
  168. #define N BOOST_PP_ITERATION()
  169. #define BOOST_TYPE_ERASURE_GET_PLACEHOLDER(z, n, data) \
  170. typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument< \
  171. BOOST_PP_CAT(data, n), BOOST_PP_CAT(type, n)>::type \
  172. BOOST_PP_CAT(type, BOOST_PP_INC(n));
  173. #if N != 0
  174. template<template<BOOST_PP_ENUM_PARAMS(N, class T)> class T,
  175. BOOST_PP_ENUM_PARAMS(N, class T), class Out>
  176. struct get_placeholders<T<BOOST_PP_ENUM_PARAMS(N, T)>, Out>
  177. {
  178. typedef Out type0;
  179. BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_GET_PLACEHOLDER, T)
  180. typedef BOOST_PP_CAT(type, N) type;
  181. };
  182. #endif
  183. template<class R
  184. BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Out>
  185. struct get_placeholders_in_argument<R(BOOST_PP_ENUM_PARAMS(N, T)), Out>
  186. {
  187. typedef typename ::boost::type_erasure::detail::get_placeholders_in_argument<
  188. R,
  189. Out
  190. >::type type0;
  191. BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_GET_PLACEHOLDER, T)
  192. typedef BOOST_PP_CAT(type, N) type;
  193. };
  194. #undef BOOST_TYPE_ERASURE_GET_PLACEHOLDER
  195. #undef N
  196. #endif