Back to home page

EIC code displayed by LXR

 
 

    


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 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
0005 //  Copyright Casey Carter 2016
0006 //
0007 //  Use, modification and distribution is subject to the
0008 //  Boost Software License, Version 1.0. (See accompanying
0009 //  file LICENSE_1_0.txt or copy at
0010 //  http://www.boost.org/LICENSE_1_0.txt)
0011 //
0012 // Project home: https://github.com/ericniebler/range-v3
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     /// \addtogroup group-functional
0045     /// @{
0046 
0047     /// \cond
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         // clang-format off
0057         /// \concept dereferenceable_part_
0058         /// \brief The \c dereferenceable_part_ concept
0059         template<typename T>
0060         CPP_requires(dereferenceable_part_,
0061             requires(T && t) //
0062             (
0063                 detail::can_reference_(*(T &&) t)
0064             ));
0065         /// \concept dereferenceable_
0066         /// \brief The \c dereferenceable_ concept
0067         template<typename T>
0068         CPP_concept dereferenceable_ = //
0069             CPP_requires_ref(detail::dereferenceable_part_, T);
0070         // clang-format on
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     } // namespace detail
0079     /// \endcond
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     /// \cond
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     /// \endcond
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     /// \cond
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     } // namespace detail
0164     /// \endcond
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  // RANGES_WORKAROUND_MSVC_701385
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 // RANGES_WORKAROUND_MSVC_701385
0181 
0182     /// \cond
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     } // namespace detail
0204     /// \endcond
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     /// \cond
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     /// \endcond
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     } // namespace cpp20
0238 
0239     /// @}
0240 } // namespace ranges
0241 
0242 RANGES_DIAGNOSTIC_POP
0243 
0244 #include <range/v3/detail/epilogue.hpp>
0245 
0246 #endif // RANGES_V3_FUNCTIONAL_INVOKE_HPP