/// \file // Range v3 library // // Copyright Eric Niebler 2013-present // // Use, modification and distribution is subject to the // Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // Project home: https://github.com/ericniebler/range-v3 // #ifndef RANGES_V3_CONTAINER_ACTION_HPP #define RANGES_V3_CONTAINER_ACTION_HPP #include #include #include #include #include #include #include #include #include #include namespace ranges { /// \addtogroup group-actions /// @{ namespace actions { struct action_access { template struct impl { // clang-format off template static constexpr auto CPP_auto_fun(bind)(Ts &&... ts) ( return A::bind(static_cast(ts)...) ) // clang-format on }; }; struct make_action_fn { template constexpr action operator()(Fun fun) const { return action{detail::move(fun)}; } }; /// \ingroup group-actions /// \relates make_action_fn RANGES_INLINE_VARIABLE(make_action_fn, make_action) template struct action : pipeable_base { private: Action action_; friend pipeable_access; // Piping requires things are passed by value. template static auto pipe(Rng && rng, Act && act) -> CPP_ret(invoke_result_t)( // requires range && invocable && (!std::is_reference::value)) { return invoke(act.action_, detail::move(rng)); } public: action() = default; constexpr explicit action(Action a) noexcept( std::is_nothrow_move_constructible::value) : action_(detail::move(a)) {} // Calling directly requires things are passed by reference. template auto operator()(Rng & rng, Rest &&... rest) const -> CPP_ret(invoke_result_t)( // requires range && invocable) { return invoke(action_, rng, static_cast(rest)...); } // Currying overload. // clang-format off template auto CPP_auto_fun(operator())(T &&t, Rest &&... rest)(const) ( return make_action( action_access::impl::bind(action_, static_cast(t), static_cast(rest)...)) ) // clang-format on }; template auto operator|=(Rng & rng, Action && action) -> CPP_ret(Rng &)( // requires is_pipeable::value && range && invocable, Action &> && same_as< ref_view, invoke_result_t, Action &>>) { views::ref(rng) | action; return rng; } } // namespace actions /// @} } // namespace ranges #endif