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)
9
// $Id: adapt_to_vtable.hpp 83325 2013-03-05 22:24:25Z steven_watanabe $
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/utility/addressof.hpp>
17
#include <boost/mpl/if.hpp>
18
#include <boost/mpl/eval_if.hpp>
19
#include <boost/mpl/has_xxx.hpp>
20
#include <boost/type_traits/function_traits.hpp>
21
#include <boost/type_traits/remove_cv.hpp>
22
#include <boost/preprocessor/cat.hpp>
23
#include <boost/preprocessor/iteration/iterate.hpp>
24
#include <boost/preprocessor/repetition/enum.hpp>
25
#include <boost/preprocessor/repetition/enum_params.hpp>
26
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
27
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
28
#include <boost/type_erasure/detail/get_signature.hpp>
29
#include <boost/type_erasure/detail/storage.hpp>
30
#include <boost/type_erasure/is_placeholder.hpp>
31
#include <boost/type_erasure/config.hpp>
34
namespace type_erasure {
38
template<class T, class Bindings>
39
struct rebind_placeholders;
41
template<class T, class Bindings>
42
struct rebind_placeholders_in_argument;
44
template<class PrimitiveConcept, class Sig>
45
struct vtable_adapter;
47
template<class PrimitiveConcept, class Sig, class Bindings>
48
struct rebind_placeholders<vtable_adapter<PrimitiveConcept, Sig>, Bindings>
50
typedef vtable_adapter<
51
typename rebind_placeholders<PrimitiveConcept, Bindings>::type,
52
typename rebind_placeholders_in_argument<Sig, Bindings>::type
57
struct replace_param_for_vtable
59
typedef typename ::boost::mpl::if_<
60
::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
61
const ::boost::type_erasure::detail::storage&,
67
struct replace_param_for_vtable<T&>
69
typedef typename ::boost::mpl::if_<
70
::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
71
::boost::type_erasure::detail::storage&,
77
struct replace_param_for_vtable<const T&>
79
typedef typename ::boost::mpl::if_<
80
::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
81
const ::boost::type_erasure::detail::storage&,
86
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
89
struct replace_param_for_vtable<T&&>
91
typedef typename ::boost::mpl::if_<
92
::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
93
::boost::type_erasure::detail::storage&&,
101
struct replace_result_for_vtable
103
typedef typename ::boost::mpl::if_<
104
::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
105
::boost::type_erasure::detail::storage,
111
struct replace_result_for_vtable<T&>
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<const 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&,
130
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
133
struct replace_result_for_vtable<T&&>
135
typedef typename ::boost::mpl::if_<
136
::boost::type_erasure::is_placeholder<typename ::boost::remove_cv<T>::type>,
137
::boost::type_erasure::detail::storage&&,
145
struct get_vtable_signature;
147
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
150
struct is_internal_concept :
151
::boost::type_erasure::detail::has_type<T>
154
template<class PrimitiveConcept>
155
struct adapt_to_vtable
157
typedef ::boost::type_erasure::detail::vtable_adapter<
159
typename ::boost::type_erasure::detail::get_vtable_signature<
160
typename ::boost::type_erasure::detail::get_signature<
167
template<class Concept>
168
struct maybe_adapt_to_vtable
170
typedef typename ::boost::mpl::eval_if<
171
::boost::type_erasure::detail::is_internal_concept<Concept>,
172
::boost::mpl::identity<Concept>,
173
::boost::type_erasure::detail::adapt_to_vtable<Concept>
177
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
179
template<class PrimitiveConcept, class Sig, class ConceptSig>
180
struct vtable_adapter_impl;
182
template<class PrimitiveConcept, class R, class... T, class R2, class... U>
183
struct vtable_adapter_impl<PrimitiveConcept, R(T...), R2(U...)>
185
typedef R (*type)(T...);
186
static R value(T... arg)
188
return PrimitiveConcept::apply(
189
::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...);
193
template<class PrimitiveConcept, class... T, class R2, class... U>
194
struct vtable_adapter_impl<PrimitiveConcept, ::boost::type_erasure::detail::storage&(T...), R2(U...)>
196
typedef ::boost::type_erasure::detail::storage (*type)(T...);
197
static ::boost::type_erasure::detail::storage value(T... arg)
199
::boost::type_erasure::detail::storage result;
200
typename ::boost::remove_reference<R2>::type* p =
202
PrimitiveConcept::apply(::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...));
203
result.data = const_cast<void*>(static_cast<const void*>(p));
208
template<class PrimitiveConcept, class... T, class R2, class... U>
209
struct vtable_adapter_impl<PrimitiveConcept, ::boost::type_erasure::detail::storage&&(T...), R2(U...)>
211
typedef ::boost::type_erasure::detail::storage (*type)(T...);
212
static ::boost::type_erasure::detail::storage value(T... arg)
214
::boost::type_erasure::detail::storage result;
215
R2 tmp = PrimitiveConcept::apply(::boost::type_erasure::detail::extract<U>(std::forward<T>(arg))...);
216
typename ::boost::remove_reference<R2>::type* p = ::boost::addressof(tmp);
217
result.data = const_cast<void*>(static_cast<const void*>(p));
222
template<class PrimitiveConcept, class Sig>
223
struct vtable_adapter
224
: vtable_adapter_impl<
227
typename ::boost::type_erasure::detail::get_signature<
233
template<class R, class... T>
234
struct get_vtable_signature<R(T...)>
236
typedef typename ::boost::type_erasure::detail::replace_result_for_vtable<
238
>::type type(typename ::boost::type_erasure::detail::replace_param_for_vtable<T>::type...);
243
#define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/adapt_to_vtable.hpp>
244
#define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
245
#include BOOST_PP_ITERATE()
257
#define N BOOST_PP_ITERATION()
259
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
261
#define BOOST_TYPE_ERASURE_EXTRACT(z, n, data) \
262
::boost::type_erasure::detail::extract< \
264
BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) \
265
>(std::forward<BOOST_PP_CAT(T, n)>(BOOST_PP_CAT(arg, n)))
269
#define BOOST_TYPE_ERASURE_EXTRACT(z, n, data) \
270
::boost::type_erasure::detail::extract< \
272
BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type) \
273
>(BOOST_PP_CAT(arg, n))
277
#define BOOST_TYPE_ERASURE_REPLACE_PARAM(z, n, data) \
278
typename ::boost::type_erasure::detail::replace_param_for_vtable< \
279
BOOST_PP_CAT(T, n)>::type
281
template<class PrimitiveConcept, class R
282
BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
283
struct vtable_adapter<PrimitiveConcept, R(BOOST_PP_ENUM_PARAMS(N, T))>
285
typedef R (*type)(BOOST_PP_ENUM_PARAMS(N, T));
286
static R value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
288
typedef typename ::boost::function_traits<
289
typename ::boost::type_erasure::detail::get_signature<
293
return PrimitiveConcept::apply(
294
BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~));
298
template<class PrimitiveConcept
299
BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
300
struct vtable_adapter<PrimitiveConcept, ::boost::type_erasure::detail::storage&(BOOST_PP_ENUM_PARAMS(N, T))>
302
typedef ::boost::type_erasure::detail::storage (*type)(BOOST_PP_ENUM_PARAMS(N, T));
303
static ::boost::type_erasure::detail::storage value(BOOST_PP_ENUM_BINARY_PARAMS(N, T, arg))
305
typedef typename ::boost::function_traits<
306
typename ::boost::type_erasure::detail::get_signature<
310
::boost::type_erasure::detail::storage result;
311
typename ::boost::remove_reference<typename traits::result_type>::type* p =
313
PrimitiveConcept::apply(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~)));
314
result.data = const_cast<void*>(static_cast<const void*>(p));
319
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
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
::boost::type_erasure::detail::storage result;
334
typename traits::result_type tmp =
335
PrimitiveConcept::apply(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_EXTRACT, ~));
336
typename ::boost::remove_reference<typename traits::result_type>::type* p =
337
::boost::addressof(tmp);
338
result.data = const_cast<void*>(static_cast<const void*>(p));
345
template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
346
struct get_vtable_signature<R(BOOST_PP_ENUM_PARAMS(N, T))>
348
typedef typename ::boost::type_erasure::detail::replace_result_for_vtable<
350
>::type type(BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_REPLACE_PARAM, ~));
353
#undef BOOST_TYPE_ERASURE_REPLACE_PARAM
354
#undef BOOST_TYPE_ERASURE_EXTRACT