rebind_placeholders.hpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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_REBIND_PLACEHOLDERS_HPP_INCLUDED
  12. #define BOOST_TYPE_ERASURE_DETAIL_REBIND_PLACEHOLDERS_HPP_INCLUDED
  13. #include <boost/mpl/eval_if.hpp>
  14. #include <boost/mpl/identity.hpp>
  15. #include <boost/mpl/at.hpp>
  16. #include <boost/mpl/has_key.hpp>
  17. #include <boost/mpl/not.hpp>
  18. #include <boost/mpl/or.hpp>
  19. #include <boost/mpl/assert.hpp>
  20. #include <boost/preprocessor/cat.hpp>
  21. #include <boost/preprocessor/iteration/iterate.hpp>
  22. #include <boost/preprocessor/repetition/enum.hpp>
  23. #include <boost/preprocessor/repetition/enum_params.hpp>
  24. #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  25. #include <boost/type_erasure/config.hpp>
  26. #include <boost/type_erasure/detail/meta.hpp>
  27. #include <boost/type_erasure/is_placeholder.hpp>
  28. namespace boost {
  29. namespace type_erasure {
  30. template<class F>
  31. struct deduced;
  32. namespace detail {
  33. template<class T, class Bindings>
  34. struct rebind_placeholders
  35. {
  36. typedef void type;
  37. };
  38. template<class T>
  39. struct identity
  40. {
  41. typedef T type;
  42. };
  43. template<class PrimitiveConcept, class Sig>
  44. struct vtable_adapter;
  45. #ifdef BOOST_TYPE_ERASURE_USE_MP11
  46. template<class T, class Bindings>
  47. using rebind_placeholders_t = typename rebind_placeholders<T, Bindings>::type;
  48. template<class T, class Bindings>
  49. using rebind_one_placeholder = ::boost::mp11::mp_second< ::boost::mp11::mp_map_find<Bindings, T> >;
  50. template<class T>
  51. struct rebind_placeholders_in_argument_impl
  52. {
  53. template<class Bindings>
  54. using apply = ::boost::type_erasure::detail::eval_if<
  55. ::boost::mp11::mp_map_contains<Bindings, T>::value,
  56. ::boost::type_erasure::detail::rebind_one_placeholder,
  57. ::boost::type_erasure::detail::first,
  58. T,
  59. Bindings
  60. >;
  61. };
  62. template<class T, class Bindings>
  63. using rebind_placeholders_in_argument_t = typename ::boost::type_erasure::detail::rebind_placeholders_in_argument_impl<T>::template apply<Bindings>;
  64. template<class T, class Bindings>
  65. using rebind_placeholders_in_argument = ::boost::mpl::identity< ::boost::type_erasure::detail::rebind_placeholders_in_argument_t<T, Bindings> >;
  66. template<class T>
  67. struct rebind_placeholders_in_argument_impl<T&>
  68. {
  69. template<class Bindings>
  70. using apply = rebind_placeholders_in_argument_t<T, Bindings>&;
  71. };
  72. template<class T>
  73. struct rebind_placeholders_in_argument_impl<T&&>
  74. {
  75. template<class Bindings>
  76. using apply = rebind_placeholders_in_argument_t<T, Bindings>&&;
  77. };
  78. template<class T>
  79. struct rebind_placeholders_in_argument_impl<const T>
  80. {
  81. template<class Bindings>
  82. using apply = rebind_placeholders_in_argument_t<T, Bindings> const;
  83. };
  84. template<class F, class Bindings>
  85. using rebind_placeholders_in_deduced =
  86. typename ::boost::type_erasure::deduced<
  87. ::boost::type_erasure::detail::rebind_placeholders_t<F, Bindings>
  88. >::type;
  89. template<class F, class Bindings>
  90. using rebind_deduced_placeholder =
  91. ::boost::mp11::mp_second<
  92. ::boost::mp11::mp_map_find<Bindings, ::boost::type_erasure::deduced<F> >
  93. >;
  94. template<class F>
  95. struct rebind_placeholders_in_argument_impl<
  96. ::boost::type_erasure::deduced<F>
  97. >
  98. {
  99. template<class Bindings>
  100. using apply = ::boost::type_erasure::detail::eval_if<
  101. ::boost::mp11::mp_map_contains<Bindings, ::boost::type_erasure::deduced<F> >::value,
  102. ::boost::type_erasure::detail::rebind_deduced_placeholder,
  103. ::boost::type_erasure::detail::rebind_placeholders_in_deduced,
  104. F,
  105. Bindings
  106. >;
  107. };
  108. template<class R, class... T>
  109. struct rebind_placeholders_in_argument_impl<R(T...)>
  110. {
  111. template<class Bindings>
  112. using apply =
  113. rebind_placeholders_in_argument_t<R, Bindings>
  114. (rebind_placeholders_in_argument_t<T, Bindings>...);
  115. };
  116. template<class R, class C, class... T>
  117. struct rebind_placeholders_in_argument_impl<R (C::*)(T...)>
  118. {
  119. template<class Bindings>
  120. using apply =
  121. rebind_placeholders_in_argument_t<R, Bindings>
  122. (rebind_placeholders_in_argument_t<C, Bindings>::*)
  123. (rebind_placeholders_in_argument_t<T, Bindings>...);
  124. };
  125. template<class R, class C, class... T>
  126. struct rebind_placeholders_in_argument_impl<R (C::*)(T...) const>
  127. {
  128. template<class Bindings>
  129. using apply =
  130. rebind_placeholders_in_argument_t<R, Bindings>
  131. (rebind_placeholders_in_argument_t<C, Bindings>::*)
  132. (rebind_placeholders_in_argument_t<T, Bindings>...) const;
  133. };
  134. template<template<class...> class T, class... U, class Bindings>
  135. struct rebind_placeholders<T<U...>, Bindings>
  136. {
  137. typedef ::boost::type_erasure::detail::make_mp_list<Bindings> xBindings;
  138. typedef T<rebind_placeholders_in_argument_t<U, xBindings>...> type;
  139. };
  140. template<class PrimitiveConcept, class Sig, class Bindings>
  141. struct rebind_placeholders<vtable_adapter<PrimitiveConcept, Sig>, Bindings>
  142. {
  143. typedef ::boost::type_erasure::detail::make_mp_list<Bindings> xBindings;
  144. typedef vtable_adapter<
  145. rebind_placeholders_t<PrimitiveConcept, xBindings>,
  146. rebind_placeholders_in_argument_t<Sig, xBindings>
  147. > type;
  148. };
  149. #else
  150. template<class T, class Bindings>
  151. struct rebind_placeholders_in_argument
  152. {
  153. BOOST_MPL_ASSERT((boost::mpl::or_<
  154. ::boost::mpl::not_< ::boost::type_erasure::is_placeholder<T> >,
  155. ::boost::mpl::has_key<Bindings, T>
  156. >));
  157. typedef typename ::boost::mpl::eval_if<
  158. ::boost::type_erasure::is_placeholder<T>,
  159. ::boost::mpl::at<Bindings, T>,
  160. ::boost::type_erasure::detail::identity<T>
  161. >::type type;
  162. };
  163. template<class PrimitiveConcept, class Sig, class Bindings>
  164. struct rebind_placeholders<vtable_adapter<PrimitiveConcept, Sig>, Bindings>
  165. {
  166. typedef vtable_adapter<
  167. typename rebind_placeholders<PrimitiveConcept, Bindings>::type,
  168. typename rebind_placeholders_in_argument<Sig, Bindings>::type
  169. > type;
  170. };
  171. template<class T, class Bindings>
  172. struct rebind_placeholders_in_argument<T&, Bindings>
  173. {
  174. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  175. T,
  176. Bindings
  177. >::type& type;
  178. };
  179. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
  180. template<class T, class Bindings>
  181. struct rebind_placeholders_in_argument<T&&, Bindings>
  182. {
  183. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  184. T,
  185. Bindings
  186. >::type&& type;
  187. };
  188. #endif
  189. template<class T, class Bindings>
  190. struct rebind_placeholders_in_argument<const T, Bindings>
  191. {
  192. typedef const typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  193. T,
  194. Bindings
  195. >::type type;
  196. };
  197. template<class F, class Bindings>
  198. struct rebind_placeholders_in_deduced
  199. {
  200. typedef typename ::boost::type_erasure::deduced<
  201. typename ::boost::type_erasure::detail::rebind_placeholders<F, Bindings>::type
  202. >::type type;
  203. };
  204. template<class F, class Bindings>
  205. struct rebind_placeholders_in_argument<
  206. ::boost::type_erasure::deduced<F>,
  207. Bindings
  208. >
  209. {
  210. typedef typename ::boost::mpl::eval_if<
  211. ::boost::mpl::has_key<Bindings, ::boost::type_erasure::deduced<F> >,
  212. ::boost::mpl::at<Bindings, ::boost::type_erasure::deduced<F> >,
  213. ::boost::type_erasure::detail::rebind_placeholders_in_deduced<
  214. F,
  215. Bindings
  216. >
  217. >::type type;
  218. };
  219. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
  220. template<template<class...> class T, class... U, class Bindings>
  221. struct rebind_placeholders<T<U...>, Bindings>
  222. {
  223. typedef T<typename rebind_placeholders_in_argument<U, Bindings>::type...> type;
  224. };
  225. template<class R, class... T, class Bindings>
  226. struct rebind_placeholders_in_argument<R(T...), Bindings>
  227. {
  228. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  229. R,
  230. Bindings
  231. >::type type(typename rebind_placeholders_in_argument<T, Bindings>::type...);
  232. };
  233. template<class R, class C, class... T, class Bindings>
  234. struct rebind_placeholders_in_argument<R (C::*)(T...), Bindings>
  235. {
  236. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  237. R,
  238. Bindings
  239. >::type (rebind_placeholders_in_argument<C, Bindings>::type::*type)
  240. (typename rebind_placeholders_in_argument<T, Bindings>::type...);
  241. };
  242. template<class R, class C, class... T, class Bindings>
  243. struct rebind_placeholders_in_argument<R (C::*)(T...) const, Bindings>
  244. {
  245. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  246. R,
  247. Bindings
  248. >::type (rebind_placeholders_in_argument<C, Bindings>::type::*type)
  249. (typename rebind_placeholders_in_argument<T, Bindings>::type...) const;
  250. };
  251. #else
  252. #define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/rebind_placeholders.hpp>
  253. #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
  254. #include BOOST_PP_ITERATE()
  255. #endif
  256. #endif
  257. }
  258. }
  259. }
  260. #endif
  261. #else
  262. #define N BOOST_PP_ITERATION()
  263. #define BOOST_TYPE_ERASURE_REBIND(z, n, data) \
  264. typename rebind_placeholders_in_argument<BOOST_PP_CAT(data, n), Bindings>::type
  265. #if N != 0
  266. template<template<BOOST_PP_ENUM_PARAMS(N, class T)> class T,
  267. BOOST_PP_ENUM_PARAMS(N, class T), class Bindings>
  268. struct rebind_placeholders<T<BOOST_PP_ENUM_PARAMS(N, T)>, Bindings>
  269. {
  270. typedef T<BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, T)> type;
  271. };
  272. #endif
  273. template<class R
  274. BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Bindings>
  275. struct rebind_placeholders_in_argument<R(BOOST_PP_ENUM_PARAMS(N, T)), Bindings>
  276. {
  277. typedef typename ::boost::type_erasure::detail::rebind_placeholders_in_argument<
  278. R,
  279. Bindings
  280. >::type type(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REBIND, T));
  281. };
  282. #undef BOOST_TYPE_ERASURE_REBIND
  283. #undef N
  284. #endif