File indexing completed on 2024-11-15 09:32:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
0081
0082
0083
0084
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
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>* , 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