Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:32:52

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_CHECK_MATCH_HPP_INCLUDED
0014 #define BOOST_TYPE_ERASURE_CHECK_MATCH_HPP_INCLUDED
0015 
0016 #include <boost/mpl/vector.hpp>
0017 #include <boost/mpl/bool.hpp>
0018 #include <boost/mpl/is_sequence.hpp>
0019 #include <boost/mpl/find_if.hpp>
0020 #include <boost/mpl/not.hpp>
0021 #include <boost/mpl/end.hpp>
0022 #include <boost/type_traits/is_same.hpp>
0023 #include <boost/preprocessor/cat.hpp>
0024 #include <boost/preprocessor/iteration/iterate.hpp>
0025 #include <boost/preprocessor/repetition/repeat.hpp>
0026 #include <boost/preprocessor/repetition/enum_params.hpp>
0027 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0028 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
0029 #include <boost/type_erasure/detail/extract_concept.hpp>
0030 #include <boost/type_erasure/relaxed.hpp>
0031 #include <boost/type_erasure/detail/access.hpp>
0032 
0033 namespace boost {
0034 namespace type_erasure {
0035 
0036 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0037 
0038 template<class T>
0039 struct typeid_;
0040 
0041 template<class Concept>
0042 class binding;
0043 
0044 #endif
0045 
0046 namespace detail {
0047 
0048 template<class P, class T, class Table>
0049 bool maybe_check_table(const T& arg, const Table*& table, boost::mpl::true_)
0050 {
0051     if(table == 0) {
0052         table = &::boost::type_erasure::detail::access::table(arg);
0053         return true;
0054     } else {
0055         return table->template find< ::boost::type_erasure::typeid_<P> >()() ==
0056             ::boost::type_erasure::detail::access::table(arg).
0057                 template find< ::boost::type_erasure::typeid_<P> >()();
0058     }
0059 }
0060 
0061 template<class P, class T, class Table>
0062 bool maybe_check_table(const T&, const Table*&, boost::mpl::false_)
0063 {
0064     return true;
0065 }
0066 
0067 template<class Concept, class T>
0068 struct should_check :
0069     boost::mpl::and_<
0070         ::boost::type_erasure::is_placeholder<T>,
0071         ::boost::type_erasure::is_relaxed<Concept>
0072     >
0073 {};
0074 
0075 }
0076 
0077 #ifdef BOOST_TYPE_ERASURE_DOXYGEN
0078 
0079 /**
0080  * If @ref relaxed is in @c Concept, checks whether the
0081  * arguments to @c f match the types specified by
0082  * @c binding.  If @ref relaxed is not in @c Concept,
0083  * returns true.  If @c binding is not specified, it will
0084  * be deduced from the arguments.
0085  */
0086 template<class Concept, class Op, class... U>
0087 bool check_match(const binding<Concept>& binding_arg, const Op& f, U&&... args);
0088 
0089 /**
0090  * \overload
0091  */
0092 template<class Op, class... U>
0093 bool check_match(const Op& f, U&&... args);
0094 
0095 #else
0096 
0097 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0098 
0099 namespace detail {
0100 
0101 template<class Concept, class R>
0102 bool check_table(const ::boost::type_erasure::binding<Concept>* /*t*/, R(*)())
0103 {
0104     return true;
0105 }
0106 
0107 template<class Concept, class R, class T0, class... T, class U0, class... U>
0108 bool check_table(
0109     const ::boost::type_erasure::binding<Concept>* t,
0110     R(*)(T0, T...),
0111     const U0& arg0,
0112     const U&... arg)
0113 {
0114     typedef typename ::boost::remove_cv<
0115         typename ::boost::remove_reference<T0>::type
0116     >::type t0;
0117     if(!::boost::type_erasure::detail::maybe_check_table<t0>(
0118         arg0,
0119         t,
0120         ::boost::type_erasure::detail::should_check<Concept, t0>()))
0121         return false;
0122 
0123     return check_table(t, static_cast<void(*)(T...)>(0), arg...);
0124 }
0125 
0126 }
0127 
0128 template<class Concept, class Op, class... U>
0129 bool check_match(
0130     const ::boost::type_erasure::binding<Concept>& table,
0131     const Op&,
0132     U&&... arg)
0133 {
0134 
0135     return ::boost::type_erasure::detail::check_table(
0136         &table,
0137         static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0),
0138         arg...);
0139 }
0140 
0141 #ifndef BOOST_TYPE_ERASURE_USE_MP11
0142 
0143 template<
0144     class Op,
0145     class... U
0146 >
0147 bool check_match(
0148     const Op&,
0149     U&&... arg)
0150 {
0151     const ::boost::type_erasure::binding<
0152         typename ::boost::type_erasure::detail::extract_concept<
0153             typename ::boost::type_erasure::detail::get_signature<Op>::type, U...>::type>* p = 0;
0154 
0155     return ::boost::type_erasure::detail::check_table(
0156         p, static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0), arg...);
0157 }
0158 
0159 #else
0160 
0161 namespace detail {
0162 
0163 template<class T>
0164 struct get_args;
0165 
0166 template<class R, class ... T>
0167 struct get_args<R(T...)> { typedef ::boost::mp11::mp_list<T...> type; };
0168 
0169 template<class Sig>
0170 using get_args_t = typename get_args<Sig>::type;
0171 
0172 }
0173 
0174 template<
0175     class Op,
0176     class... U
0177 >
0178 bool check_match(
0179     const Op&,
0180     U&&... arg)
0181 {
0182     const ::boost::type_erasure::binding<
0183         ::boost::type_erasure::detail::extract_concept_t<
0184             ::boost::type_erasure::detail::get_args_t<
0185                 typename ::boost::type_erasure::detail::get_signature<Op>::type
0186             >,
0187             ::boost::mp11::mp_list< ::boost::remove_reference_t<U>...> > >* p = 0;
0188 
0189     return ::boost::type_erasure::detail::check_table(
0190         p, static_cast<typename ::boost::type_erasure::detail::get_signature<Op>::type*>(0), arg...);
0191 }
0192 
0193 #endif
0194 
0195 #else
0196 
0197 #define BOOST_PP_FILENAME_1 <boost/type_erasure/check_match.hpp>
0198 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
0199 #include BOOST_PP_ITERATE()
0200 
0201 #endif
0202 
0203 #endif
0204 
0205 }
0206 }
0207 
0208 #endif
0209 
0210 #else
0211 
0212 namespace detail {
0213 
0214 #define N BOOST_PP_ITERATION()
0215 
0216 #define BOOST_TYPE_ERASURE_CHECK_TABLE(z, n, data)                          \
0217     typedef typename ::boost::remove_cv<                                    \
0218         typename ::boost::remove_reference<BOOST_PP_CAT(T, n)>::type        \
0219     >::type BOOST_PP_CAT(t, n);                                             \
0220     if(!::boost::type_erasure::detail::maybe_check_table<BOOST_PP_CAT(t, n)>(   \
0221         BOOST_PP_CAT(arg, n),                                               \
0222         t,                                                                  \
0223         ::boost::type_erasure::detail::should_check<Concept, BOOST_PP_CAT(t, n)>())) \
0224         return false;
0225 
0226 template<
0227     class Concept,
0228     class R
0229     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
0230     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)>
0231 bool
0232 BOOST_PP_CAT(check_table, N)(
0233     const ::boost::type_erasure::binding<Concept>* t,
0234     R (*)(BOOST_PP_ENUM_PARAMS(N, T))
0235     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, const U, &arg))
0236 {
0237     BOOST_PP_REPEAT(N, BOOST_TYPE_ERASURE_CHECK_TABLE, ~)
0238     return true;
0239 }
0240 
0241 #if N != 0
0242 
0243 template<class Sig BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)>
0244 struct BOOST_PP_CAT(do_extract_concept, N);
0245 
0246 template<
0247     class R
0248     BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)
0249     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0250 >
0251 struct BOOST_PP_CAT(do_extract_concept, N)<
0252     R(BOOST_PP_ENUM_PARAMS(N, T))
0253     BOOST_PP_ENUM_TRAILING_PARAMS(N, U)
0254 >
0255   : ::boost::type_erasure::detail::BOOST_PP_CAT(extract_concept, N)<
0256         BOOST_PP_ENUM_PARAMS(N, T)
0257         BOOST_PP_ENUM_TRAILING_PARAMS(N, U)>
0258 {};
0259 
0260 #endif
0261 
0262 }
0263 
0264 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0265 #define RREF &
0266 #else
0267 #define RREF &&
0268 #endif
0269 
0270 template<
0271     class Concept,
0272     class Op
0273     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0274 >
0275 bool check_match(
0276     const ::boost::type_erasure::binding<Concept>& table,
0277     const Op&
0278     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0279 {
0280 
0281     return ::boost::type_erasure::detail::BOOST_PP_CAT(check_table, N)(
0282         &table,
0283         (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0
0284         BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
0285 }
0286 
0287 #if N != 0
0288 
0289 template<
0290     class Op
0291     BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0292 >
0293 bool check_match(
0294     const Op&
0295     BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0296 {
0297     const ::boost::type_erasure::binding<
0298         typename ::boost::type_erasure::detail::BOOST_PP_CAT(do_extract_concept, N)<
0299             typename ::boost::type_erasure::detail::get_signature<Op>::type,
0300             BOOST_PP_ENUM_PARAMS(N, U)>::type>* p = 0;
0301 
0302     return ::boost::type_erasure::detail::BOOST_PP_CAT(check_table, N)(
0303         p,
0304         (typename ::boost::type_erasure::detail::get_signature<Op>::type*)0
0305         BOOST_PP_ENUM_TRAILING_PARAMS(N, arg));
0306 }
0307 
0308 #undef RREF
0309 #undef BOOST_TYPE_ERASURE_CHECK_TABLE
0310 #undef N
0311 
0312 #endif
0313 
0314 #endif