Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:09:41

0001 /// \file
0002 // Range v3 library
0003 //
0004 //  Copyright Eric Niebler 2013-present
0005 //
0006 //  Use, modification and distribution is subject to the
0007 //  Boost Software License, Version 1.0. (See accompanying
0008 //  file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 // Project home: https://github.com/ericniebler/range-v3
0012 //
0013 
0014 #ifndef RANGES_V3_CONTAINER_ACTION_HPP
0015 #define RANGES_V3_CONTAINER_ACTION_HPP
0016 
0017 #include <type_traits>
0018 
0019 #include <meta/meta.hpp>
0020 
0021 #include <range/v3/range_fwd.hpp>
0022 
0023 #include <range/v3/action/concepts.hpp>
0024 #include <range/v3/functional/compose.hpp>
0025 #include <range/v3/functional/concepts.hpp>
0026 #include <range/v3/functional/invoke.hpp>
0027 #include <range/v3/functional/reference_wrapper.hpp>
0028 #include <range/v3/functional/pipeable.hpp>
0029 #include <range/v3/range/concepts.hpp>
0030 #include <range/v3/utility/move.hpp>
0031 #include <range/v3/utility/static_const.hpp>
0032 
0033 #include <range/v3/detail/prologue.hpp>
0034 
0035 namespace ranges
0036 {
0037     /// \addtogroup group-actions
0038     /// @{
0039     struct make_action_closure_fn
0040     {
0041         template<typename Fun>
0042         constexpr actions::action_closure<Fun> operator()(Fun fun) const
0043         {
0044             return actions::action_closure<Fun>{static_cast<Fun &&>(fun)};
0045         }
0046     };
0047 
0048     /// \sa make_action_closure_fn
0049     RANGES_INLINE_VARIABLE(make_action_closure_fn, make_action_closure)
0050 
0051     /// \cond
0052     namespace detail
0053     {
0054         struct action_closure_base_
0055         {};
0056     }
0057     /// \endcond
0058 
0059     /// \concept invocable_action_closure_
0060     /// \brief The \c invocable_action_closure_ concept
0061     template(typename ActionFn, typename Rng)(
0062     concept (invocable_action_closure_)(ActionFn, Rng),
0063         !derived_from<invoke_result_t<ActionFn, Rng>, detail::action_closure_base_>
0064     );
0065     /// \concept invocable_action_closure
0066     /// \brief The \c invocable_action_closure concept
0067     template<typename ActionFn, typename Rng>
0068     CPP_concept invocable_action_closure =
0069         invocable<ActionFn, Rng> &&
0070         CPP_concept_ref(ranges::invocable_action_closure_, ActionFn, Rng);
0071 
0072     namespace actions
0073     {
0074         struct RANGES_STRUCT_WITH_ADL_BARRIER(action_closure_base)
0075           : detail::action_closure_base_
0076         {
0077             // clang-format off
0078             // Piping requires things are passed by value.
0079             template(typename Rng, typename ActionFn)(
0080                 requires (!std::is_lvalue_reference<Rng>::value) AND
0081                 range<Rng> AND invocable_action_closure<ActionFn, Rng &>)
0082             friend constexpr auto
0083             operator|(Rng && rng, action_closure<ActionFn> act)
0084             {
0085                 return aux::move(static_cast<ActionFn &&>(act)(rng));
0086             }
0087 
0088 #ifndef RANGES_WORKAROUND_CLANG_43400
0089             template<typename Rng, typename ActionFn>   // ******************************
0090             friend constexpr auto                       // ******************************
0091             operator|(Rng &,                            // ********* READ THIS **********
0092                       action_closure<ActionFn> const &) // ****** IF YOUR COMPILE *******
0093                 -> CPP_broken_friend_ret(Rng)(          // ******** BREAKS HERE *********
0094                     requires range<Rng>) = delete;      // ******************************
0095             // **************************************************************************
0096             // *    When piping a range into an action, the range must be moved in.     *
0097             // **************************************************************************
0098 #endif // RANGES_WORKAROUND_CLANG_43400
0099 
0100             template<typename ActionFn, typename Pipeable>
0101             friend constexpr auto operator|(action_closure<ActionFn> act, Pipeable pipe)
0102                 -> CPP_broken_friend_ret(action_closure<composed<Pipeable, ActionFn>>)(
0103                     requires (is_pipeable_v<Pipeable>))
0104             {
0105                 return make_action_closure(compose(static_cast<Pipeable &&>(pipe),
0106                                                    static_cast<ActionFn &&>(act)));
0107             }
0108 
0109             template<typename Rng, typename ActionFn>
0110             friend constexpr auto operator|=(Rng & rng, action_closure<ActionFn> act) //
0111                 -> CPP_broken_friend_ret(Rng &)(
0112                     requires range<Rng> && invocable<ActionFn, Rng &>)
0113             {
0114                 static_cast<ActionFn &&>(act)(rng);
0115                 return rng;
0116             }
0117             // clang-format on
0118         };
0119 
0120 #ifdef RANGES_WORKAROUND_CLANG_43400
0121         // clang-format off
0122         namespace RANGES_ADL_BARRIER_FOR(action_closure_base)
0123         {
0124             template(typename Rng, typename ActionFn)(  // *******************************
0125                 requires range<Rng>)                    // *******************************
0126             constexpr Rng                               // ********** READ THIS **********
0127             operator|(Rng &,                            // ******* IF YOUR COMPILE *******
0128                       action_closure<ActionFn> const &) // ********* BREAKS HERE *********
0129                 = delete;                               // *******************************
0130             // ***************************************************************************
0131             // *    When piping a range into an action, the range must be moved in.      *
0132             // ***************************************************************************
0133         } // namespace RANGES_ADL_BARRIER_FOR(action_closure_base)
0134         // clang-format on
0135 #endif    // RANGES_WORKAROUND_CLANG_43400
0136 
0137         template<typename ActionFn>
0138         struct RANGES_EMPTY_BASES action_closure
0139           : action_closure_base
0140           , ActionFn
0141         {
0142             action_closure() = default;
0143 
0144             constexpr explicit action_closure(ActionFn fn)
0145               : ActionFn(static_cast<ActionFn &&>(fn))
0146             {}
0147         };
0148 
0149         /// \cond
0150         /// DEPRECATED STUFF
0151         struct action_access_
0152         {
0153             template<typename Action>
0154             struct impl
0155             {
0156                 // clang-format off
0157                 template<typename... Ts, typename A = Action>
0158                 static constexpr auto CPP_auto_fun(bind)(Ts &&... ts)
0159                 (
0160                     return A::bind(static_cast<Ts &&>(ts)...)
0161                 )
0162                 // clang-format on
0163             };
0164         };
0165 
0166         using action_access RANGES_DEPRECATED(
0167             "action_access and actions::action<> are deprecated. Please "
0168             "replace action<> with action_closure<> and discontinue use of "
0169             "action_access.") = action_access_;
0170 
0171         template<typename>
0172         struct old_action_;
0173 
0174         struct make_action_fn_
0175         {
0176             template<typename Fun>
0177             constexpr old_action_<Fun> operator()(Fun fun) const
0178             {
0179                 return old_action_<Fun>{static_cast<Fun &&>(fun)};
0180             }
0181         };
0182         using make_action_fn RANGES_DEPRECATED(
0183             "make_action_fn is deprecated. Please use "
0184             "make_action_closure instead.") = make_action_fn_;
0185 
0186         namespace
0187         {
0188             RANGES_DEPRECATED(
0189                 "make_action and actions::action<> has been deprecated. Please switch to "
0190                 "make_action_closure and action::action_closure.")
0191             RANGES_INLINE_VAR constexpr auto & make_action =
0192                 static_const<make_action_fn_>::value;
0193         } // namespace
0194 
0195         template<typename Action>
0196         struct old_action_ : pipeable_base
0197         {
0198         private:
0199             Action act_;
0200             friend pipeable_access;
0201 
0202         public:
0203             old_action_() = default;
0204 
0205             constexpr explicit old_action_(Action a) noexcept(
0206                 std::is_nothrow_move_constructible<Action>::value)
0207               : act_(detail::move(a))
0208             {}
0209 
0210             // Calling directly requires things are passed by reference.
0211             template(typename Rng, typename... Rest)(
0212                 requires range<Rng> AND invocable<Action const &, Rng &, Rest...>)
0213             invoke_result_t<Action const &, Rng &, Rest...> //
0214             operator()(Rng & rng, Rest &&... rest) const
0215             {
0216                 return invoke(act_, rng, static_cast<Rest &&>(rest)...);
0217             }
0218 
0219             // Currying overload.
0220             // clang-format off
0221             template(typename... Rest, typename A = Action)(
0222                 requires (sizeof...(Rest) != 0))
0223             auto CPP_auto_fun(operator())(Rest &&... rest)(const)
0224             (
0225                 return make_action_fn_{}(
0226                     action_access_::impl<A>::bind(act_,
0227                                                   static_cast<Rest &&>(rest)...))
0228             )
0229             // clang-format on
0230         };
0231 
0232         template<typename Action>
0233         using action RANGES_DEPRECATED(
0234             "The actions::action<> template is deprecated. Please switch to "
0235             "action_closure") = old_action_<Action>;
0236         /// \endcond
0237     } // namespace actions
0238 
0239     template<typename ActionFn>
0240     RANGES_INLINE_VAR constexpr bool is_pipeable_v<actions::action_closure<ActionFn>> =
0241         true;
0242     /// @}
0243 } // namespace ranges
0244 
0245 #include <range/v3/detail/epilogue.hpp>
0246 
0247 #endif