Header file range/v3/view/view.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

#include <range/v3/range_concepts.hpp>

#include <range/v3/range_traits.hpp>

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

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

namespace ranges
{
    inline namespace v3
    {
        namespace detail
        {
            struct null_pipe
            {
                template <typename Rng>
                void operator()(Rng&&) const;
            };
        }
        
        namespace view
        {
            struct view_access;
            
            struct make_view_fn
            {
                template <typename Fun>
                view<Fun> operator()(Fun fun) const;
            };
            
            inline namespace 
            {
                constexpr auto& make_view = static_const<make_view_fn>::value;
            }
            
            template <typename Rng>
            using ViewableRange = meta::and_<Range<Rng>, meta::or_<std::is_lvalue_reference<Rng>, View<Rng>>>;
            
            template <typename View>
            struct view
            : pipeable<view<View> >
            {
                view() = default;
                
                view(View a);
                
                template <typename Rng, typename ... Rest, int _concept_requires_120 = 42, typename std::enable_if<(_concept_requires_120==43)||(ViewConcept<Rng, Rest>()), int>::type ... = 0>
                decltype(view_(std::forward<Rng>(rng), std::forward<Rest>(rest)...)) operator()(Rng&& rng, Rest&&... rest) const;
                
                template <typename ... Ts, typename V = View>
                decltype(make_view(view_access::impl<V>::bind(view_, std::forward<Ts>(ts)...))) operator()(Ts&&... ts) const;
            };
        }
    }
}

Class ranges::v3::view::view_access

struct view_access
{
    template <typename View>
    struct impl
    {
        template <typename ... Ts, typename V = View>
        static decltype(V::bind(std::forward<Ts>(ts)...)) bind(Ts&&... ts);
    };
};

@{