File indexing completed on 2025-01-18 10:09:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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
0049 RANGES_INLINE_VARIABLE(make_action_closure_fn, make_action_closure)
0050
0051
0052 namespace detail
0053 {
0054 struct action_closure_base_
0055 {};
0056 }
0057
0058
0059
0060
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
0066
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
0078
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 &,
0092 action_closure<ActionFn> const &)
0093 -> CPP_broken_friend_ret(Rng)(
0094 requires range<Rng>) = delete;
0095
0096
0097
0098 #endif
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
0118 };
0119
0120 #ifdef RANGES_WORKAROUND_CLANG_43400
0121
0122 namespace RANGES_ADL_BARRIER_FOR(action_closure_base)
0123 {
0124 template(typename Rng, typename ActionFn)(
0125 requires range<Rng>)
0126 constexpr Rng
0127 operator|(Rng &,
0128 action_closure<ActionFn> const &)
0129 = delete;
0130
0131
0132
0133 }
0134
0135 #endif
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
0150
0151 struct action_access_
0152 {
0153 template<typename Action>
0154 struct impl
0155 {
0156
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
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 }
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
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
0220
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
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
0237 }
0238
0239 template<typename ActionFn>
0240 RANGES_INLINE_VAR constexpr bool is_pipeable_v<actions::action_closure<ActionFn>> =
0241 true;
0242
0243 }
0244
0245 #include <range/v3/detail/epilogue.hpp>
0246
0247 #endif