Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:01:22

0001 // Boost.TypeErasure library
0002 //
0003 // Copyright 2011 Steven Watanabe
0004 //
0005 // Distributed under the Boost Software License Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // $Id$
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& /*s1*/, const S& /*s2*/)
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 // Provide this specialization manually.
0148 // gcc 4.7.2 fails to instantiate the primary template.
0149 template<>
0150 struct vtable_storage<>
0151 {
0152     vtable_storage() = default;
0153 
0154     template<class Bindings, class Src>
0155     void convert_from(const Src& /*src*/) {}
0156 
0157     bool operator==(const vtable_storage& /*other*/) 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