File indexing completed on 2025-01-18 09:38:14
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_HOF_GUARD_APPLY_H
0009 #define BOOST_HOF_GUARD_APPLY_H
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 #include <boost/hof/detail/result_of.hpp>
0059 #include <boost/hof/detail/forward.hpp>
0060 #include <boost/hof/detail/static_const_var.hpp>
0061
0062 #ifdef _MSC_VER
0063 #pragma warning(push)
0064 #pragma warning(disable: 4003)
0065 #endif
0066
0067 #define BOOST_HOF_DETAIL_FOREACH_QUAL(m, data) \
0068 m(, data) \
0069 m(const, data) \
0070 m(volatile, data) \
0071 m(const volatile, data)
0072
0073 namespace boost { namespace hof {
0074
0075 namespace detail {
0076 #if BOOST_HOF_HAS_MANUAL_DEDUCTION || BOOST_HOF_NO_EXPRESSION_SFINAE
0077 struct apply_mem_fn
0078 {
0079 template<class...>
0080 struct convertible_args;
0081
0082 template<class T, class U, class=void>
0083 struct is_convertible_args
0084 : std::false_type
0085 {};
0086
0087 template<class... Ts, class... Us>
0088 struct is_convertible_args<
0089 convertible_args<Ts...>,
0090 convertible_args<Us...>,
0091 typename std::enable_if<(
0092 sizeof...(Ts) == sizeof...(Us)
0093 )>::type
0094 >
0095 : and_<std::is_convertible<Ts, Us>...>
0096 {};
0097
0098 template<class From, class To>
0099 struct is_compatible
0100 : std::is_convertible<
0101 typename std::add_pointer<typename std::remove_reference<From>::type>::type,
0102 typename std::add_pointer<typename std::remove_reference<To>::type>::type
0103 >
0104 {};
0105
0106 #define BOOST_HOF_APPLY_MEM_FN_CALL(cv, data) \
0107 template <class R, class Base, class Derived, class... Ts, class... Us, class=typename std::enable_if<and_< \
0108 is_compatible<Derived, cv Base>, \
0109 is_convertible_args<convertible_args<Us...>, convertible_args<Ts...>> \
0110 >::value>::type> \
0111 constexpr R operator()(R (Base::*mf)(Ts...) cv, Derived&& ref, Us &&... xs) const \
0112 BOOST_HOF_RETURNS_DEDUCE_NOEXCEPT((BOOST_HOF_FORWARD(Derived)(ref).*mf)(BOOST_HOF_FORWARD(Us)(xs)...)) \
0113 { \
0114 return (BOOST_HOF_FORWARD(Derived)(ref).*mf)(BOOST_HOF_FORWARD(Us)(xs)...); \
0115 }
0116 BOOST_HOF_DETAIL_FOREACH_QUAL(BOOST_HOF_APPLY_MEM_FN_CALL, ~)
0117 };
0118
0119 struct apply_mem_data
0120 {
0121 template<class T, class R>
0122 struct match_qualifier
0123 { typedef R type; };
0124
0125 #define BOOST_HOF_APPLY_MEM_DATA_MATCH(cv, ref) \
0126 template<class T, class R> \
0127 struct match_qualifier<cv T ref, R> \
0128 : match_qualifier<T, cv R ref> \
0129 {};
0130
0131 BOOST_HOF_DETAIL_FOREACH_QUAL(BOOST_HOF_APPLY_MEM_DATA_MATCH,&)
0132 BOOST_HOF_DETAIL_FOREACH_QUAL(BOOST_HOF_APPLY_MEM_DATA_MATCH,&&)
0133
0134 template <class Base, class R, class Derived, class=typename std::enable_if<(
0135 std::is_base_of<Base, typename std::decay<Derived>::type>::value
0136 )>::type>
0137 constexpr typename match_qualifier<Derived, R>::type
0138 operator()(R Base::*pmd, Derived&& ref) const noexcept
0139 {
0140 return BOOST_HOF_FORWARD(Derived)(ref).*pmd;
0141 }
0142 };
0143
0144 template<class T, class U=decltype(*std::declval<T>())>
0145 struct apply_deref
0146 { typedef U type; };
0147
0148 #endif
0149
0150 struct apply_f
0151 {
0152 #if BOOST_HOF_HAS_MANUAL_DEDUCTION || BOOST_HOF_NO_EXPRESSION_SFINAE
0153 template<class F, class T, class... Ts, class=typename std::enable_if<(
0154 std::is_member_function_pointer<typename std::decay<F>::type>::value
0155 )>::type>
0156 constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<T>, id_<Ts>...)
0157 operator()(F&& f, T&& obj, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
0158 (
0159 apply_mem_fn()(f, BOOST_HOF_FORWARD(T)(obj), BOOST_HOF_FORWARD(Ts)(xs)...)
0160 );
0161
0162 template<class F, class T, class... Ts, class U=typename apply_deref<T>::type, class=typename std::enable_if<(
0163 std::is_member_function_pointer<typename std::decay<F>::type>::value
0164 )>::type>
0165 constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<U>, id_<Ts>...)
0166 operator()(F&& f, T&& obj, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
0167 (
0168 apply_mem_fn()(f, *BOOST_HOF_FORWARD(T)(obj), BOOST_HOF_FORWARD(Ts)(xs)...)
0169 );
0170
0171 template<class F, class T, class... Ts, class=typename std::enable_if<(
0172 std::is_member_function_pointer<typename std::decay<F>::type>::value
0173 )>::type>
0174 constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_fn, id_<F>, id_<T&>, id_<Ts>...)
0175 operator()(F&& f, const std::reference_wrapper<T>& ref, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
0176 (
0177 apply_mem_fn()(f, ref.get(), BOOST_HOF_FORWARD(Ts)(xs)...)
0178 );
0179
0180 template<class F, class T, class=typename std::enable_if<(
0181 std::is_member_object_pointer<typename std::decay<F>::type>::value
0182 )>::type>
0183 constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<T>)
0184 operator()(F&& f, T&& obj) const BOOST_HOF_SFINAE_MANUAL_RETURNS
0185 (
0186 apply_mem_data()(f, BOOST_HOF_FORWARD(T)(obj))
0187 );
0188
0189 template<class F, class T, class U=typename apply_deref<T>::type, class=typename std::enable_if<(
0190 std::is_member_object_pointer<typename std::decay<F>::type>::value
0191 )>::type>
0192 constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<U>)
0193 operator()(F&& f, T&& obj) const BOOST_HOF_SFINAE_MANUAL_RETURNS
0194 (
0195 apply_mem_data()(f, *BOOST_HOF_FORWARD(T)(obj))
0196 );
0197
0198 template<class F, class T, class=typename std::enable_if<(
0199 std::is_member_object_pointer<typename std::decay<F>::type>::value
0200 )>::type>
0201 constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(apply_mem_data, id_<F>, id_<T&>)
0202 operator()(F&& f, const std::reference_wrapper<T>& ref) const BOOST_HOF_SFINAE_MANUAL_RETURNS
0203 (
0204 apply_mem_data()(f, ref.get())
0205 );
0206
0207 #else
0208
0209 template <class Base, class T, class Derived>
0210 constexpr auto operator()(T Base::*pmd, Derived&& ref) const
0211 BOOST_HOF_RETURNS(BOOST_HOF_FORWARD(Derived)(ref).*pmd);
0212
0213 template <class PMD, class Pointer>
0214 constexpr auto operator()(PMD&& pmd, Pointer&& ptr) const
0215 BOOST_HOF_RETURNS((*BOOST_HOF_FORWARD(Pointer)(ptr)).*BOOST_HOF_FORWARD(PMD)(pmd));
0216
0217 template <class Base, class T, class Derived>
0218 constexpr auto operator()(T Base::*pmd, const std::reference_wrapper<Derived>& ref) const
0219 BOOST_HOF_RETURNS(ref.get().*pmd);
0220
0221 template <class Base, class T, class Derived, class... Args>
0222 constexpr auto operator()(T Base::*pmf, Derived&& ref, Args&&... args) const
0223 BOOST_HOF_RETURNS((BOOST_HOF_FORWARD(Derived)(ref).*pmf)(BOOST_HOF_FORWARD(Args)(args)...));
0224
0225 template <class PMF, class Pointer, class... Args>
0226 constexpr auto operator()(PMF&& pmf, Pointer&& ptr, Args&&... args) const
0227 BOOST_HOF_RETURNS(((*BOOST_HOF_FORWARD(Pointer)(ptr)).*BOOST_HOF_FORWARD(PMF)(pmf))(BOOST_HOF_FORWARD(Args)(args)...));
0228
0229 template <class Base, class T, class Derived, class... Args>
0230 constexpr auto operator()(T Base::*pmf, const std::reference_wrapper<Derived>& ref, Args&&... args) const
0231 BOOST_HOF_RETURNS((ref.get().*pmf)(BOOST_HOF_FORWARD(Args)(args)...));
0232
0233 #endif
0234 template<class F, class... Ts>
0235 constexpr BOOST_HOF_SFINAE_MANUAL_RESULT(F, id_<Ts>...)
0236 operator()(F&& f, Ts&&... xs) const BOOST_HOF_SFINAE_MANUAL_RETURNS
0237 (
0238 f(BOOST_HOF_FORWARD(Ts)(xs)...)
0239 );
0240 };
0241
0242 }
0243
0244 BOOST_HOF_DECLARE_STATIC_VAR(apply, detail::apply_f);
0245
0246 }}
0247
0248 #ifdef _MSC_VER
0249 #pragma warning(pop)
0250 #endif
0251
0252 #endif