File indexing completed on 2025-12-16 10:10:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #if !defined(BOOST_PP_IS_ITERATING)
0012
0013 #ifndef BOOST_TYPE_ERASURE_REQUIRE_MATCH_HPP_INCLUDED
0014 #define BOOST_TYPE_ERASURE_REQUIRE_MATCH_HPP_INCLUDED
0015
0016 #include <boost/throw_exception.hpp>
0017 #include <boost/mpl/bool.hpp>
0018 #include <boost/mpl/and.hpp>
0019 #include <boost/type_traits/is_same.hpp>
0020 #include <boost/preprocessor/cat.hpp>
0021 #include <boost/preprocessor/facilities/intercept.hpp>
0022 #include <boost/preprocessor/iteration/iterate.hpp>
0023 #include <boost/preprocessor/repetition/repeat.hpp>
0024 #include <boost/preprocessor/repetition/enum_params.hpp>
0025 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
0026 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
0027 #include <boost/type_erasure/detail/extract_concept.hpp>
0028 #include <boost/type_erasure/relaxed.hpp>
0029 #include <boost/type_erasure/check_match.hpp>
0030 #include <boost/type_erasure/exception.hpp>
0031
0032 namespace boost {
0033 namespace type_erasure {
0034
0035 #ifndef BOOST_TYPE_ERASURE_DOXYGEN
0036 template<class Concept>
0037 class binding;
0038 #endif
0039
0040 #ifdef BOOST_TYPE_ERASURE_DOXYGEN
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 template<class Concept, class Op, class... U>
0055 void require_match(const binding<Concept>& binding_arg, const Op& f, U&&... args);
0056
0057
0058
0059
0060 template<class Op, class... U>
0061 void require_match(const Op& f, U&&... args);
0062
0063 #else
0064
0065 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
0066
0067 namespace detail {
0068
0069 template<class Concept, class Op, class... U>
0070 void require_match_impl(
0071 ::boost::mpl::true_,
0072 const ::boost::type_erasure::binding<Concept>& table,
0073 const Op& op,
0074 U&&... arg)
0075 {
0076 if(!::boost::type_erasure::check_match(table, op, std::forward<U>(arg)...)) {
0077 BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
0078 }
0079 }
0080
0081 template<class Concept, class Op, class... U>
0082 void require_match_impl(
0083 ::boost::mpl::false_,
0084 const ::boost::type_erasure::binding<Concept>&,
0085 const Op&,
0086 U&&...)
0087 {}
0088
0089 template<class Op, class... U>
0090 void require_match_impl(
0091 ::boost::mpl::true_,
0092 const Op& op,
0093 U&&... arg)
0094 {
0095 if(!::boost::type_erasure::check_match(op, ::std::forward<U>(arg)...)) {
0096 BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
0097 }
0098 }
0099
0100 template<class Op, class... U>
0101 void require_match_impl(
0102 ::boost::mpl::false_,
0103 const Op&,
0104 U&&...)
0105 {}
0106
0107 }
0108
0109 template<class Concept, class Op, class... U>
0110 void require_match(
0111 const ::boost::type_erasure::binding<Concept>& table,
0112 const Op& op,
0113 U&&... arg)
0114 {
0115 ::boost::type_erasure::is_relaxed<Concept> cond;
0116 ::boost::type_erasure::detail::require_match_impl(cond, table, op, ::std::forward<U>(arg)...);
0117 }
0118
0119 #ifndef BOOST_TYPE_ERASURE_USE_MP11
0120
0121 template<class Op, class... U>
0122 void require_match(
0123 const Op& op,
0124 U&&... arg)
0125 {
0126 ::boost::type_erasure::is_relaxed<
0127 typename ::boost::type_erasure::detail::extract_concept<
0128 typename ::boost::type_erasure::detail::get_signature<Op>::type,
0129 U...>::type
0130 > cond;
0131 ::boost::type_erasure::detail::require_match_impl(cond, op, ::std::forward<U>(arg)...);
0132 }
0133
0134 #else
0135
0136 template<class Op, class... U>
0137 void require_match(
0138 const Op& op,
0139 U&&... arg)
0140 {
0141 ::boost::type_erasure::is_relaxed<
0142 ::boost::type_erasure::detail::extract_concept_t<
0143 ::boost::type_erasure::detail::get_args_t<
0144 typename ::boost::type_erasure::detail::get_signature<Op>::type
0145 >,
0146 ::boost::mp11::mp_list< ::boost::remove_reference_t<U>...> >
0147 > cond;
0148 ::boost::type_erasure::detail::require_match_impl(cond, op, ::std::forward<U>(arg)...);
0149 }
0150
0151 #endif
0152
0153 #else
0154
0155 #define BOOST_PP_FILENAME_1 <boost/type_erasure/require_match.hpp>
0156 #define BOOST_PP_ITERATION_LIMITS (0, BOOST_TYPE_ERASURE_MAX_ARITY)
0157 #include BOOST_PP_ITERATE()
0158
0159 #endif
0160
0161 #endif
0162
0163 }
0164 }
0165
0166 #endif
0167
0168 #else
0169
0170 #define N BOOST_PP_ITERATION()
0171
0172 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
0173 #define RREF &
0174 #define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING_PARAMS(N, x)
0175 #else
0176 #define RREF &&
0177 #define BOOST_TYPE_ERASURE_FORWARD_ARGS_I(z, n, data) std::forward<BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, data), n)>(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 1, data), n))
0178 #define BOOST_TYPE_ERASURE_FORWARD_ARGS(N, X, x) BOOST_PP_ENUM_TRAILING(N, BOOST_TYPE_ERASURE_FORWARD_ARGS_I, (X, x))
0179 #endif
0180
0181 namespace detail {
0182
0183 template<
0184 class Concept,
0185 class Op
0186 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0187 >
0188 void require_match_impl(
0189 ::boost::mpl::true_,
0190 const ::boost::type_erasure::binding<Concept>& table,
0191 const Op& op
0192 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0193 {
0194 if(!::boost::type_erasure::check_match
0195 (table, op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg))) {
0196 BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
0197 }
0198 }
0199
0200 template<
0201 class Concept,
0202 class Op
0203 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0204 >
0205 void require_match_impl(
0206 ::boost::mpl::false_,
0207 const ::boost::type_erasure::binding<Concept>&,
0208 const Op&
0209 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF BOOST_PP_INTERCEPT))
0210 {}
0211
0212 #if N != 0
0213
0214 template<
0215 class Op
0216 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0217 >
0218 void require_match_impl(
0219 ::boost::mpl::true_,
0220 const Op& op
0221 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0222 {
0223 if(!::boost::type_erasure::check_match
0224 (op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg))) {
0225 BOOST_THROW_EXCEPTION(::boost::type_erasure::bad_function_call());
0226 }
0227 }
0228
0229 template<
0230 class Op
0231 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0232 >
0233 void require_match_impl(
0234 ::boost::mpl::false_,
0235 const Op&
0236 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF BOOST_PP_INTERCEPT))
0237 {}
0238
0239 #endif
0240
0241 }
0242
0243 template<
0244 class Concept,
0245 class Op
0246 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0247 >
0248 void require_match(
0249 const ::boost::type_erasure::binding<Concept>& table,
0250 const Op& op
0251 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0252 {
0253 ::boost::type_erasure::is_relaxed<Concept> cond;
0254 ::boost::type_erasure::detail::require_match_impl
0255 (cond, table, op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
0256 }
0257
0258 #if N != 0
0259
0260 template<
0261 class Op
0262 BOOST_PP_ENUM_TRAILING_PARAMS(N, class U)
0263 >
0264 void require_match(
0265 const Op& op
0266 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, U, RREF arg))
0267 {
0268 ::boost::type_erasure::is_relaxed<
0269 typename ::boost::type_erasure::detail::BOOST_PP_CAT(do_extract_concept, N)<
0270 typename ::boost::type_erasure::detail::get_signature<Op>::type,
0271 BOOST_PP_ENUM_PARAMS(N, U)>::type
0272 > cond;
0273 ::boost::type_erasure::detail::require_match_impl
0274 (cond, op BOOST_TYPE_ERASURE_FORWARD_ARGS(N, U, arg));
0275 }
0276
0277 #endif
0278
0279 #undef RREF
0280 #undef BOOST_TYPE_ERASURE_FORWARD_ARGS
0281 #undef BOOST_TYPE_ERASURE_FORWARD_ARGS_I
0282 #undef N
0283
0284 #endif