1 // Boost.TypeErasure library
3 // Copyright 2011 Steven Watanabe
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)
11 #if !defined(BOOST_PP_IS_ITERATING)
13 #ifndef BOOST_TYPE_ERASURE_DETAIL_ADAPT_TO_VTABLE_HPP_INCLUDED
14 #define BOOST_TYPE_ERASURE_DETAIL_ADAPT_TO_VTABLE_HPP_INCLUDED
16 #include <boost/detail/workaround.hpp>
17 #include <boost/utility/addressof.hpp>
18 #include <boost/mpl/if.hpp>
19 #include <boost/mpl/eval_if.hpp>
20 #include <boost/mpl/has_xxx.hpp>
21 #include <boost/type_traits/function_traits.hpp>
22 #include <boost/type_traits/remove_cv.hpp>
23 #include <boost/preprocessor/cat.hpp>
24 #include <boost/preprocessor/iteration/iterate.hpp>
25 #include <boost/preprocessor/repetition/enum.hpp>
26 #include <boost/preprocessor/repetition/enum_params.hpp>
27 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
28 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
29 #include <boost/type_erasure/detail/get_signature.hpp>
30 #include <boost/type_erasure/detail/storage.hpp>
31 #include <boost/type_erasure/is_placeholder.hpp>
32 #include <boost/type_erasure/config.hpp>
35 namespace type_erasure {
39 template<class T, class Out>
40 struct get_placeholders;
42 template<class T, class Bindings>
43 struct rebind_placeholders;
45 template<class T, class Bindings>
46 struct rebind_placeholders_in_argument;
48 template<class PrimitiveConcept, class Sig>
49 struct vtable_adapter;
51 template<class PrimitiveConcept, class Sig, class Bindings>
52 struct rebind_placeholders<vtable_adapter<PrimitiveConcept, Sig>, Bindings>
54 typedef vtable_adapter<
55 typename rebind_placeholders<PrimitiveConcept, Bindings>::type,
56 typename rebind_placeholders_in_argument<Sig, Bindings>::type
60 template<class PrimitiveConcept, class Sig, class Out>
61 struct get_placeholders<vtable_adapter<PrimitiveConcept, Sig>, Out>
63 typedef typename get_placeholders<PrimitiveConcept, Out>::type type;
67 struct replace_param_for_vtable
69 typedef typename ::boost::mpl::if_<
70 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
71 const ::boost::type_erasure::detail::storage&,
77 struct replace_param_for_vtable<T&>
79 typedef typename ::boost::mpl::if_<
80 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
81 ::boost::type_erasure::detail::storage&,
87 struct replace_param_for_vtable<const T&>
89 typedef typename ::boost::mpl::if_<
90 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
91 const ::boost::type_erasure::detail::storage&,
96 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
99 struct replace_param_for_vtable<T&&>
101 typedef typename ::boost::mpl::if_<
102 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
103 ::boost::type_erasure::detail::storage&&,
111 struct replace_result_for_vtable
113 typedef typename ::boost::mpl::if_<
114 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
115 ::boost::type_erasure::detail::storage,
121 struct replace_result_for_vtable<T&>
123 typedef typename ::boost::mpl::if_<
124 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
125 ::boost::type_erasure::detail::storage&,
131 struct replace_result_for_vtable<const T&>
133 typedef typename ::boost::mpl::if_<
134 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
135 ::boost::type_erasure::detail::storage&,
140 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
143 struct replace_result_for_vtable<T&&>
145 typedef typename ::boost::mpl::if_<
146 ::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
147 ::boost::type_erasure::detail::storage&&,
155 struct get_vtable_signature;
157 BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
160 struct is_internal_concept :
161 ::boost::type_erasure::detail::has_type<T>
164 template<class PrimitiveConcept>
165 struct adapt_to_vtable
167 typedef ::boost::type_erasure::detail::vtable_adapter<
169 typename ::boost::type_erasure::detail::get_vtable_signature<
170 typename ::boost::type_erasure::detail::get_signature<
177 template<class Concept>
178 struct maybe_adapt_to_vtable
180 typedef typename ::boost::mpl::eval_if<
181 ::boost::type_erasure::detail::is_internal_concept<Concept>,
182 ::boost::mpl::identity<Concept>,
183 ::boost::type_erasure::detail::adapt_to_vtable<Concept>
187 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
188 !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
189 !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
191 template<class PrimitiveConcept, class Sig, class ConceptSig>
192 struct vtable_adapter_impl;
194 template<class PrimitiveConcept, class R, class... T, class R2, class... U>
195 struct vtable_adapter_impl<PrimitiveConcept, R(T...), R2(U...)>
197 typedef R (*type)(T...);
198 static R value(T... arg)
200 return PrimitiveConcept::apply(
201 ::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...);
205 template<class PrimitiveConcept, class... T, class R2, class... U>
206 struct vtable_adapter_impl<PrimitiveConcept, ::boost::type_erasure::detail::storage(T...), R2(U...)>
208 typedef ::boost::type_erasure::detail::storage (*type)(T...);
209 static ::boost::type_erasure::detail::storage value(T... arg)
211 return ::boost::type_erasure::detail::storage(
212 PrimitiveConcept::apply(::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...));
216 template<class PrimitiveConcept, class... T, class R2, class... U>
217 struct vtable_adapter_impl<PrimitiveConcept, ::boost::type_erasure::detail::storage&(T...), R2(U...)>
219 typedef ::boost::type_erasure::detail::storage (*type)(T...);
220 static ::boost::type_erasure::detail::storage value(T... arg)
222 ::boost::type_erasure::detail::storage result;
223 typename ::boost::remove_reference<R2>::type* p =
225 PrimitiveConcept::apply(::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...));
226 result.data = const_cast<void*>(static_cast<const void*>(p));
231 template<class PrimitiveConcept, class... T, class R2, class... U>
232 struct vtable_adapter_impl<PrimitiveConcept, ::boost::type_erasure::detail::storage&&(T...), R2(U...)>
234 typedef ::boost::type_erasure::detail::storage (*type)(T...);
235 static ::boost::type_erasure::detail::storage value(T... arg)
237 ::boost::type_erasure::detail::storage result;
238 R2 tmp = PrimitiveConcept::apply(::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...);
239 typename ::boost::remove_reference<R2>::type* p = ::boost::addressof(tmp);
240 result.data = const_cast<void*>(static_cast<const void*>(p));
245 template<class PrimitiveConcept, class Sig>
246 struct vtable_adapter
247 : vtable_adapter_impl<
250 typename ::boost::type_erasure::detail::get_signature<
256 template<class R, class... T>
257 struct get_vtable_signature<R(T...)>
259 typedef typename ::boost::type_erasure::detail::replace_result_for_vtable<
261 >::type type(typename ::boost::type_erasure::detail::replace_param_for_vtable<T>::type...);
266 #define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/adapt_to_vtable.hpp>
267 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
268 #include BOOST_PP_ITERATE()
280 #define N BOOST_PP_ITERATION()
282 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
284 #define BOOST_TYPE_ERASURE_EXTRACT(z, n, data) \
285 ::boost::type_erasure::detail::extract< \
287 BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) \
288 >(std::forward<BOOST_PP_CAT(T, n)>(BOOST_PP_CAT(arg, n)))
292 #define BOOST_TYPE_ERASURE_EXTRACT(z, n, data) \
293 ::boost::type_erasure::detail::extract< \
295 BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) \
296 >(BOOST_PP_CAT(arg, n))
300 #define BOOST_TYPE_ERASURE_REPLACE_PARAM(z, n, data) \
301 typename ::boost::type_erasure::detail::replace_param_for_vtable< \
302 BOOST_PP_CAT(T, n)>::type
304 template<class PrimitiveConcept, class R
305 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
306 struct vtable_adapter<PrimitiveConcept, R(BOOST_PP_ENUM_PARAMS(N, T))>
308 typedef R (*type)(BOOST_PP_ENUM_PARAMS(N, T));
309 static R value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
311 typedef typename ::boost::function_traits<
312 typename ::boost::type_erasure::detail::get_signature<
316 return PrimitiveConcept::apply(
317 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~));
321 template<class PrimitiveConcept
322 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
323 struct vtable_adapter<PrimitiveConcept, ::boost::type_erasure::detail::storage(BOOST_PP_ENUM_PARAMS(N, T))>
325 typedef ::boost::type_erasure::detail::storage (*type)(BOOST_PP_ENUM_PARAMS(N, T));
326 static ::boost::type_erasure::detail::storage value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
328 typedef typename ::boost::function_traits<
329 typename ::boost::type_erasure::detail::get_signature<
333 return ::boost::type_erasure::detail::storage(
334 PrimitiveConcept::apply(
335 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~)));
339 template<class PrimitiveConcept
340 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
341 struct vtable_adapter<PrimitiveConcept, ::boost::type_erasure::detail::storage&(BOOST_PP_ENUM_PARAMS(N, T))>
343 typedef ::boost::type_erasure::detail::storage (*type)(BOOST_PP_ENUM_PARAMS(N, T));
344 static ::boost::type_erasure::detail::storage value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
346 typedef typename ::boost::function_traits<
347 typename ::boost::type_erasure::detail::get_signature<
351 ::boost::type_erasure::detail::storage result;
352 typename ::boost::remove_reference<typename traits::result_type>::type* p =
354 PrimitiveConcept::apply(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~)));
355 result.data = const_cast<void*>(static_cast<const void*>(p));
360 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
362 template<class PrimitiveConcept
363 BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
364 struct vtable_adapter<PrimitiveConcept, ::boost::type_erasure::detail::storage&&(BOOST_PP_ENUM_PARAMS(N, T))>
366 typedef ::boost::type_erasure::detail::storage (*type)(BOOST_PP_ENUM_PARAMS(N, T));
367 static ::boost::type_erasure::detail::storage value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
369 typedef typename ::boost::function_traits<
370 typename ::boost::type_erasure::detail::get_signature<
374 ::boost::type_erasure::detail::storage result;
375 typename traits::result_type tmp =
376 PrimitiveConcept::apply(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~));
377 typename ::boost::remove_reference<typename traits::result_type>::type* p =
378 ::boost::addressof(tmp);
379 result.data = const_cast<void*>(static_cast<const void*>(p));
386 template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
387 struct get_vtable_signature<R(BOOST_PP_ENUM_PARAMS(N, T))>
389 typedef typename ::boost::type_erasure::detail::replace_result_for_vtable<
391 >::type type(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REPLACE_PARAM, ~));
394 #undef BOOST_TYPE_ERASURE_REPLACE_PARAM
395 #undef BOOST_TYPE_ERASURE_EXTRACT