Header file range/v3/action/action.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

#include <range/v3/range_concepts.hpp>

#include <range/v3/action/concepts.hpp>

#include <range/v3/utility/functional.hpp>

#include <range/v3/utility/static_const.hpp>

namespace ranges
{
    inline namespace v3
    {
        namespace action
        {
            struct action_access
            {
                template <typename Action>
                struct impl
                {
                    template <typename ... Ts, typename A = Action>
                    static decltype(A::bind(std::forward<Ts>(ts)...)) bind(Ts&&... ts);
                };
            };
            
            struct make_action_fn
            {
                template <typename Fun>
                action<Fun> operator()(Fun fun) const;
            };
            
            inline namespace 
            {
                constexpr auto& make_action = static_const<make_action_fn>::value;
            }
            
            template <typename Action>
            struct action
            : pipeable<action<Action> >
            {
                action() = default;
                
                action(Action a);
                
                template <typename Rng, typename ... Rest, int _concept_requires_104 = 42, typename std::enable_if<(_concept_requires_104==43)||(Range<Rng&>()&&Function<Action, Rng&, Rest&&>()), int>::type ... = 0>
                decltype(action_(rng, std::forward<Rest>(rest)...)) operator()(Rng& rng, Rest&&... rest) const;
                
                template <typename T, typename ... Rest, typename A = Action>
                decltype(make_action(action_access::impl<A>::bind(action_, std::forward<T>(t), std::forward<Rest>(rest)...))) operator()(T&& t, Rest&&... rest) const;
            };
            
            template <typename Rng, typename Action, int _concept_requires_121 = 42, typename std::enable_if<(_concept_requires_121==43)||(is_pipeable<Action>()&&Range<Rng&>()&&Function<bitwise_or, ref_t<Rng&>&&, Action>()&&Same<ref_t<Rng&>, concepts::Function::result_t<bitwise_or, ref_t<Rng&>&&, Action>>()), int>::type=0>
            Rng& operator|=(Rng& rng, Action&& action);
        }
    }
}