Warning, file /include/range/v3/functional/invoke.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef RANGES_V3_FUNCTIONAL_INVOKE_HPP
0015 #define RANGES_V3_FUNCTIONAL_INVOKE_HPP
0016
0017 #include <functional>
0018 #include <type_traits>
0019
0020 #include <meta/meta.hpp>
0021
0022 #include <concepts/concepts.hpp>
0023
0024 #include <range/v3/range_fwd.hpp>
0025
0026 #include <range/v3/utility/static_const.hpp>
0027
0028 #include <range/v3/detail/prologue.hpp>
0029
0030 RANGES_DIAGNOSTIC_PUSH
0031 RANGES_DIAGNOSTIC_IGNORE_CXX17_COMPAT
0032 RANGES_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
0033
0034 #ifndef RANGES_CONSTEXPR_INVOKE
0035 #ifdef RANGES_WORKAROUND_CLANG_23135
0036 #define RANGES_CONSTEXPR_INVOKE 0
0037 #else
0038 #define RANGES_CONSTEXPR_INVOKE 1
0039 #endif
0040 #endif
0041
0042 namespace ranges
0043 {
0044
0045
0046
0047
0048 namespace detail
0049 {
0050 RANGES_DIAGNOSTIC_PUSH
0051 RANGES_DIAGNOSTIC_IGNORE_VOID_PTR_DEREFERENCE
0052
0053 template<typename U>
0054 U & can_reference_(U &&);
0055
0056
0057
0058
0059 template<typename T>
0060 CPP_requires(dereferenceable_part_,
0061 requires(T && t)
0062 (
0063 detail::can_reference_(*(T &&) t)
0064 ));
0065
0066
0067 template<typename T>
0068 CPP_concept dereferenceable_ =
0069 CPP_requires_ref(detail::dereferenceable_part_, T);
0070
0071
0072 RANGES_DIAGNOSTIC_POP
0073
0074 template<typename T>
0075 RANGES_INLINE_VAR constexpr bool is_reference_wrapper_v =
0076 meta::is<T, reference_wrapper>::value ||
0077 meta::is<T, std::reference_wrapper>::value;
0078 }
0079
0080
0081 template<typename T>
0082 RANGES_INLINE_VAR constexpr bool is_reference_wrapper_v =
0083 detail::is_reference_wrapper_v<detail::decay_t<T>>;
0084
0085 template<typename T>
0086 using is_reference_wrapper = meta::bool_<is_reference_wrapper_v<T>>;
0087
0088
0089 template<typename T>
0090 using is_reference_wrapper_t RANGES_DEPRECATED(
0091 "is_reference_wrapper_t is deprecated.") = meta::_t<is_reference_wrapper<T>>;
0092
0093
0094 struct invoke_fn
0095 {
0096 private:
0097 template(typename, typename T1)(
0098 requires detail::dereferenceable_<T1>)
0099 static constexpr decltype(auto) coerce(T1 && t1, long)
0100 noexcept(noexcept(*static_cast<T1 &&>(t1)))
0101 {
0102 return *static_cast<T1 &&>(t1);
0103 }
0104
0105 template(typename T, typename T1)(
0106 requires derived_from<detail::decay_t<T1>, T>)
0107 static constexpr T1 && coerce(T1 && t1, int) noexcept
0108 {
0109 return static_cast<T1 &&>(t1);
0110 }
0111
0112 template(typename, typename T1)(
0113 requires detail::is_reference_wrapper_v<detail::decay_t<T1>>)
0114 static constexpr decltype(auto) coerce(T1 && t1, int) noexcept
0115 {
0116 return static_cast<T1 &&>(t1).get();
0117 }
0118
0119 public:
0120 template<typename F, typename T, typename T1, typename... Args>
0121 constexpr auto operator()(F T::*f, T1&& t1, Args&&... args) const
0122 noexcept(noexcept((invoke_fn::coerce<T>((T1&&) t1, 0).*f)((Args&&) args...)))
0123 -> decltype((invoke_fn::coerce<T>((T1&&) t1, 0).*f)((Args&&) args...))
0124 {
0125 return (invoke_fn::coerce<T>((T1&&) t1, 0).*f)((Args&&) args...);
0126 }
0127
0128 template<typename D, typename T, typename T1>
0129 constexpr auto operator()(D T::*f, T1&& t1) const
0130 noexcept(noexcept(invoke_fn::coerce<T>((T1&&) t1, 0).*f))
0131 -> decltype(invoke_fn::coerce<T>((T1&&) t1, 0).*f)
0132 {
0133 return invoke_fn::coerce<T>((T1&&) t1, 0).*f;
0134 }
0135
0136 template<typename F, typename... Args>
0137 CPP_PP_IIF(RANGES_CONSTEXPR_INVOKE)(CPP_PP_EXPAND, CPP_PP_EAT)(constexpr)
0138 auto operator()(F&& f, Args&&... args) const
0139 noexcept(noexcept(((F&&) f)((Args&&) args...)))
0140 -> decltype(((F&&) f)((Args&&) args...))
0141 {
0142 return ((F&&) f)((Args&&) args...);
0143 }
0144 };
0145
0146 RANGES_INLINE_VARIABLE(invoke_fn, invoke)
0147
0148 #ifdef RANGES_WORKAROUND_MSVC_701385
0149
0150 namespace detail
0151 {
0152 template<typename Void, typename Fun, typename... Args>
0153 struct _invoke_result_
0154 {};
0155
0156 template<typename Fun, typename... Args>
0157 struct _invoke_result_<
0158 meta::void_<decltype(invoke(std::declval<Fun>(), std::declval<Args>()...))>,
0159 Fun, Args...>
0160 {
0161 using type = decltype(invoke(std::declval<Fun>(), std::declval<Args>()...));
0162 };
0163 }
0164
0165
0166 template<typename Fun, typename... Args>
0167 using invoke_result = detail::_invoke_result_<void, Fun, Args...>;
0168
0169 template<typename Fun, typename... Args>
0170 using invoke_result_t = meta::_t<invoke_result<Fun, Args...>>;
0171
0172 #else
0173 template<typename Fun, typename... Args>
0174 using invoke_result_t =
0175 decltype(invoke(std::declval<Fun>(), std::declval<Args>()...));
0176
0177 template<typename Fun, typename... Args>
0178 struct invoke_result : meta::defer<invoke_result_t, Fun, Args...>
0179 {};
0180 #endif
0181
0182
0183 namespace detail
0184 {
0185 template<bool IsInvocable>
0186 struct is_nothrow_invocable_impl_
0187 {
0188 template<typename Fn, typename... Args>
0189 static constexpr bool apply() noexcept
0190 {
0191 return false;
0192 }
0193 };
0194 template<>
0195 struct is_nothrow_invocable_impl_<true>
0196 {
0197 template<typename Fn, typename... Args>
0198 static constexpr bool apply() noexcept
0199 {
0200 return noexcept(invoke(std::declval<Fn>(), std::declval<Args>()...));
0201 }
0202 };
0203 }
0204
0205
0206 template<typename Fn, typename... Args>
0207 RANGES_INLINE_VAR constexpr bool is_invocable_v =
0208 meta::is_trait<invoke_result<Fn, Args...>>::value;
0209
0210 template<typename Fn, typename... Args>
0211 RANGES_INLINE_VAR constexpr bool is_nothrow_invocable_v =
0212 detail::is_nothrow_invocable_impl_<is_invocable_v<Fn, Args...>>::template apply<
0213 Fn, Args...>();
0214
0215
0216 template<typename Sig>
0217 struct RANGES_DEPRECATED(
0218 "ranges::result_of is deprecated. "
0219 "Please use ranges::invoke_result") result_of
0220 {};
0221
0222 template<typename Fun, typename... Args>
0223 struct RANGES_DEPRECATED(
0224 "ranges::result_of is deprecated. "
0225 "Please use ranges::invoke_result") result_of<Fun(Args...)>
0226 : meta::defer<invoke_result_t, Fun, Args...>
0227 {};
0228
0229
0230 namespace cpp20
0231 {
0232 using ranges::invoke;
0233 using ranges::invoke_result;
0234 using ranges::invoke_result_t;
0235 using ranges::is_invocable_v;
0236 using ranges::is_nothrow_invocable_v;
0237 }
0238
0239
0240 }
0241
0242 RANGES_DIAGNOSTIC_POP
0243
0244 #include <range/v3/detail/epilogue.hpp>
0245
0246 #endif