File indexing completed on 2025-01-30 10:01:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #if !defined(BOOST_PP_IS_ITERATING)
0012
0013 #ifndef BOOST_TYPE_ERASURE_DETAIL_VTABLE_HPP_INCLUDED
0014 #define BOOST_TYPE_ERASURE_DETAIL_VTABLE_HPP_INCLUDED
0015
0016 #include <boost/config.hpp>
0017 #include <boost/mpl/at.hpp>
0018 #include <boost/mpl/size.hpp>
0019 #include <boost/preprocessor/cat.hpp>
0020 #include <boost/preprocessor/expr_if.hpp>
0021 #include <boost/preprocessor/iteration/iterate.hpp>
0022 #include <boost/preprocessor/repetition/enum.hpp>
0023 #include <boost/preprocessor/repetition/enum_params.hpp>
0024 #include <boost/preprocessor/repetition/enum_trailing.hpp>
0025 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0026 #include <boost/preprocessor/repetition/repeat.hpp>
0027 #include <boost/type_erasure/detail/rebind_placeholders.hpp>
0028 #include <boost/type_erasure/config.hpp>
0029
0030 namespace boost {
0031 namespace type_erasure {
0032 namespace detail {
0033
0034 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
0035
0036 template<class... T>
0037 struct stored_arg_pack;
0038
0039 template<class It, class End, class... T>
0040 struct make_arg_pack_impl
0041 {
0042 typedef typename make_arg_pack_impl<
0043 typename ::boost::mpl::next<It>::type,
0044 End,
0045 T...,
0046 typename ::boost::mpl::deref<It>::type
0047 >::type type;
0048 };
0049
0050 template<class End, class... T>
0051 struct make_arg_pack_impl<End, End, T...>
0052 {
0053 typedef stored_arg_pack<T...> type;
0054 };
0055
0056 template<class Seq>
0057 struct make_arg_pack
0058 {
0059 typedef typename make_arg_pack_impl<
0060 typename ::boost::mpl::begin<Seq>::type,
0061 typename ::boost::mpl::end<Seq>::type
0062 >::type type;
0063 };
0064
0065 template<class Args>
0066 struct make_vtable_impl;
0067
0068 template<class Seq>
0069 struct make_vtable
0070 {
0071 typedef typename ::boost::type_erasure::detail::make_vtable_impl<
0072 typename ::boost::type_erasure::detail::make_arg_pack<Seq>::type
0073 >::type type;
0074 };
0075
0076 template<class Table, class Args>
0077 struct make_vtable_init_impl;
0078
0079 template<class Seq, class Table>
0080 struct make_vtable_init
0081 {
0082 typedef typename make_vtable_init_impl<
0083 Table,
0084 typename ::boost::type_erasure::detail::make_arg_pack<Seq>::type
0085 >::type type;
0086 };
0087
0088 template<class T>
0089 struct vtable_entry
0090 {
0091 typename T::type value;
0092 vtable_entry() = default;
0093 constexpr vtable_entry(typename T::type arg) : value(arg) {}
0094 };
0095
0096 template<class... T>
0097 struct compare_vtable;
0098
0099 template<>
0100 struct compare_vtable<> {
0101 template<class S>
0102 static bool apply(const S& , const S& )
0103 {
0104 return true;
0105 }
0106 };
0107
0108 template<class T0, class... T>
0109 struct compare_vtable<T0, T...> {
0110 template<class S>
0111 static bool apply(const S& s1, const S& s2)
0112 {
0113 return static_cast<const vtable_entry<T0>&>(s1).value ==
0114 static_cast<const vtable_entry<T0>&>(s2).value &&
0115 compare_vtable<T...>::apply(s1, s2);
0116 }
0117 };
0118
0119 template<class... T>
0120 struct vtable_storage : vtable_entry<T>...
0121 {
0122 vtable_storage() = default;
0123
0124 constexpr vtable_storage(typename T::type... arg)
0125 : vtable_entry<T>(arg)... {}
0126
0127 template<class Bindings, class Src>
0128 void convert_from(const Src& src)
0129 {
0130 *this = vtable_storage(
0131 src.lookup(
0132 (typename ::boost::type_erasure::detail::rebind_placeholders<
0133 T, Bindings
0134 >::type*)0)...);
0135 }
0136
0137 bool operator==(const vtable_storage& other) const
0138 { return compare_vtable<T...>::apply(*this, other); }
0139
0140 template<class U>
0141 typename U::type lookup(U*) const
0142 {
0143 return static_cast<const vtable_entry<U>*>(this)->value;
0144 }
0145 };
0146
0147
0148
0149 template<>
0150 struct vtable_storage<>
0151 {
0152 vtable_storage() = default;
0153
0154 template<class Bindings, class Src>
0155 void convert_from(const Src& ) {}
0156
0157 bool operator==(const vtable_storage& ) const
0158 { return true; }
0159 };
0160
0161 template<class... T>
0162 struct make_vtable_impl<stored_arg_pack<T...> >
0163 {
0164 typedef vtable_storage<T...> type;
0165 };
0166
0167 template<class Table, class... T>
0168 struct vtable_init
0169 {
0170 static constexpr Table value = Table(T::value...);
0171 };
0172
0173 template<class Table, class... T>
0174 constexpr Table vtable_init<Table, T...>::value;
0175
0176 template<class Table, class... T>
0177 struct make_vtable_init_impl<Table, stored_arg_pack<T...> >
0178 {
0179 typedef vtable_init<Table, T...> type;
0180 };
0181
0182 #else
0183
0184 template<int N>
0185 struct make_vtable_impl;
0186
0187 template<class Seq>
0188 struct make_vtable
0189 {
0190 typedef typename make_vtable_impl<
0191 (::boost::mpl::size<Seq>::value)>::template apply<Seq>::type type;
0192 };
0193
0194 template<int N>
0195 struct make_vtable_init_impl;
0196
0197 template<class Seq, class Table>
0198 struct make_vtable_init
0199 {
0200 typedef typename make_vtable_init_impl<
0201 (::boost::mpl::size<Seq>::value)>::template apply<Seq, Table>::type type;
0202 };
0203
0204 #define BOOST_PP_FILENAME_1 <boost/type_erasure/detail/vtable.hpp>
0205 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_FUNCTIONS)
0206 #include BOOST_PP_ITERATE()
0207
0208 #endif
0209
0210 }
0211 }
0212 }
0213
0214 #endif
0215
0216 #else
0217
0218 #define N BOOST_PP_ITERATION()
0219
0220 #define BOOST_TYPE_ERASURE_VTABLE_ENTRY(z, n, data) \
0221 typename BOOST_PP_CAT(T, n)::type BOOST_PP_CAT(t, n); \
0222 typename BOOST_PP_CAT(T, n)::type lookup(BOOST_PP_CAT(T, n)*) const \
0223 { \
0224 return BOOST_PP_CAT(t, n); \
0225 }
0226
0227 #define BOOST_TYPE_ERASURE_VTABLE_COMPARE(z, n, data) \
0228 && BOOST_PP_CAT(t, n) == other.BOOST_PP_CAT(t, n)
0229
0230 #define BOOST_TYPE_ERASURE_VTABLE_INIT(z, n, data) \
0231 BOOST_PP_CAT(data, n)::value
0232
0233 #define BOOST_TYPE_ERASURE_AT(z, n, data) \
0234 typename ::boost::mpl::at_c<data, n>::type
0235
0236 #define BOOST_TYPE_ERASURE_CONVERT_ELEMENT(z, n, data) \
0237 BOOST_PP_CAT(t, n) = src.lookup( \
0238 (typename ::boost::type_erasure::detail::rebind_placeholders< \
0239 BOOST_PP_CAT(T, n), Bindings \
0240 >::type*)0 \
0241 );
0242
0243 #if N != 0
0244 template<BOOST_PP_ENUM_PARAMS(N, class T)>
0245 #else
0246 template<class D = void>
0247 #endif
0248 struct BOOST_PP_CAT(vtable_storage, N)
0249 {
0250 BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_VTABLE_ENTRY, ~)
0251
0252 template<class Bindings, class Src>
0253 void convert_from(const Src& BOOST_PP_EXPR_IF(N, src))
0254 {
0255 BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CONVERT_ELEMENT, ~)
0256 }
0257
0258 bool operator==(const BOOST_PP_CAT(vtable_storage, N)& BOOST_PP_EXPR_IF(N, other)) const
0259 { return true BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_VTABLE_COMPARE, ~); }
0260 };
0261
0262 template<>
0263 struct make_vtable_impl<N>
0264 {
0265 template<class Seq>
0266 struct apply
0267 {
0268 typedef ::boost::type_erasure::detail::BOOST_PP_CAT(vtable_storage, N)<
0269 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_AT, Seq)
0270 > type;
0271 };
0272 };
0273 template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
0274 struct BOOST_PP_CAT(vtable_init, N)
0275 {
0276 static const Table value;
0277 };
0278
0279 template<class Table BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>
0280 const Table BOOST_PP_CAT(vtable_init, N)<
0281 Table BOOST_PP_ENUM_TRAILING_PARAMS(N, T)>::value =
0282 {
0283 BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_VTABLE_INIT, T)
0284 };
0285
0286 template<>
0287 struct make_vtable_init_impl<N>
0288 {
0289 template<class Seq, class Table>
0290 struct apply
0291 {
0292 typedef ::boost::type_erasure::detail::BOOST_PP_CAT(vtable_init, N)<
0293 Table
0294 BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_AT, Seq)
0295 > type;
0296 };
0297 };
0298
0299 #undef BOOST_TYPE_ERASURE_CONVERT_ELEMENT
0300 #undef BOOST_TYPE_ERASURE_AT
0301 #undef BOOST_TYPE_ERASURE_VTABLE_INIT
0302 #undef BOOST_TYPE_ERASURE_VTABLE_COMPARE
0303 #undef BOOST_TYPE_ERASURE_VTABLE_ENTRY
0304 #undef N
0305
0306 #endif