Header file range/v3/range_access.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

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

namespace ranges
{
    inline namespace v3
    {
        struct range_access;
        
        namespace detail
        {
            template <typename T>
            using Cursor = concepts::models<range_access::Cursor, T>;
            
            template <typename T>
            using HasEqualCursor = concepts::models<range_access::HasEqualCursor, T>;
            
            template <typename T>
            using ReadableCursor = concepts::models<range_access::ReadableCursor, T>;
            
            template <typename T, typename U>
            using WritableCursor = concepts::models<range_access::WritableCursor, T, U>;
            
            template <typename T>
            using SizedCursor = concepts::models<range_access::SizedCursor, T>;
            
            template <typename T, typename U>
            using SizedCursorRange = concepts::models<range_access::SizedCursorRange, T, U>;
            
            template <typename T, typename U>
            using OutputCursor = concepts::models<range_access::OutputCursor, T, U>;
            
            template <typename T>
            using InputCursor = concepts::models<range_access::InputCursor, T>;
            
            template <typename T>
            using ForwardCursor = concepts::models<range_access::ForwardCursor, T>;
            
            template <typename T>
            using BidirectionalCursor = concepts::models<range_access::BidirectionalCursor, T>;
            
            template <typename T>
            using RandomAccessCursor = concepts::models<range_access::RandomAccessCursor, T>;
            
            template <typename T>
            using InfiniteCursor = concepts::models<range_access::InfiniteCursor, T>;
            
            template <typename T>
            using cursor_concept = concepts::most_refined<meta::list<range_access::RandomAccessCursor, range_access::BidirectionalCursor, range_access::ForwardCursor, range_access::InputCursor, range_access::Cursor>, T>;
            
            template <typename T>
            using cursor_concept_t = meta::_t<cursor_concept<T>>;
            
            template <typename Cur, bool Readable = (bool)ReadableCursor<Cur>()>
            struct is_writable_cursor_
            : std::true_type
            {};
            
            template <typename Cur>
            struct is_writable_cursor_<Cur, true>
            : WritableCursor<Cur, struct range_access::cursor_value_t<Cur> &&>
            {};
            
            template <typename Cur>
            struct is_writable_cursor
            : detail::is_writable_cursor_<Cur>
            {};
        }
    }
}

Class ranges::v3::range_access

struct range_access
{
    template <typename Cur>
    using single_pass_t = meta::_t<single_pass_<Cur>>;
    
    template <typename Cur>
    using mixin_base_t = meta::_t<mixin_base_<Cur>>;
    
    struct Cursor
    {
        template <typename T>
        decltype(concepts::valid_expr(concepts::model_of<concepts::SemiRegular, T>(), concepts::model_of<concepts::SemiRegular, mixin_base_t<T>>(), concepts::model_of<concepts::Constructible, mixin_base_t<T>, T&&>(), concepts::model_of<concepts::Constructible, mixin_base_t<T>, T const&>(), (t.next(), concepts::void_))) requires_(T&& t);
    };
    
    struct HasEqualCursor
    {
        template <typename T>
        decltype(concepts::valid_expr(concepts::convertible_to<bool>(t.equal(t)))) requires_(T&& t);
    };
    
    struct ReadableCursor
    {
        template <typename T>
        decltype(concepts::valid_expr(t.get())) requires_(T&& t);
    };
    
    struct WritableCursor
    {
        template <typename T, typename U>
        decltype(concepts::valid_expr((t.set((U&&)u), 42))) requires_(T&& t, U&& u);
    };
    
    struct SizedCursor
    {
        template <typename T>
        decltype(concepts::valid_expr(concepts::model_of<concepts::SignedIntegral>(t.distance_to(t)))) requires_(T&& t);
    };
    
    struct SizedCursorRange
    {
        template <typename C, typename S>
        decltype(concepts::valid_expr(concepts::model_of<concepts::SignedIntegral>(s.distance_from(c)))) requires_(C&& c, S&& s);
    };
    
    struct OutputCursor
    : concepts::refines<WritableCursor, Cursor (concepts::_1)>
    {};
    
    struct InputCursor
    : concepts::refines<ReadableCursor, Cursor>
    {};
    
    struct ForwardCursor
    : concepts::refines<InputCursor, HasEqualCursor>
    {
        template <typename T>
        decltype(concepts::valid_expr(concepts::is_false(single_pass_t<uncvref_t<T>>()))) requires_(T&& t);
    };
    
    struct BidirectionalCursor
    : concepts::refines<ForwardCursor>
    {
        template <typename T>
        decltype(concepts::valid_expr((t.prev(), concepts::void_))) requires_(T&& t);
    };
    
    struct RandomAccessCursor
    : concepts::refines<BidirectionalCursor, SizedCursor>
    {
        template <typename T>
        decltype(concepts::valid_expr((t.advance(t.distance_to(t)), concepts::void_))) requires_(T&& t);
    };
    
    struct InfiniteCursor
    {
        template <typename T>
        decltype(concepts::valid_expr(concepts::is_true(typename T::is_infinite{}))) requires_(T&&);
    };
    
    template <typename Rng>
    static constexpr decltype(rng.begin_cursor()) begin_cursor(Rng& rng, long);
    
    template <typename Rng>
    static constexpr decltype(static_cast<Rng const&>(rng).begin_cursor()) begin_cursor(Rng& rng, int);
    
    template <typename Rng>
    static constexpr decltype(rng.end_cursor()) end_cursor(Rng& rng, long);
    
    template <typename Rng>
    static constexpr decltype(static_cast<Rng const&>(rng).end_cursor()) end_cursor(Rng& rng, int);
    
    template <typename Rng>
    static constexpr decltype(rng.begin_adaptor()) begin_adaptor(Rng& rng, long);
    
    template <typename Rng>
    static constexpr decltype(static_cast<Rng const&>(rng).begin_adaptor()) begin_adaptor(Rng& rng, int);
    
    template <typename Rng>
    static constexpr decltype(rng.end_adaptor()) end_adaptor(Rng& rng, long);
    
    template <typename Rng>
    static constexpr decltype(static_cast<Rng const&>(rng).end_adaptor()) end_adaptor(Rng& rng, int);
    
    template <typename Cur>
    static constexpr decltype(pos.get()) get(Cur const& pos) noexcept(noexcept(decltype(pos.get())(pos.get())));
    
    template <typename Cur>
    static constexpr decltype(pos.move()) move(Cur const& pos) noexcept(noexcept(decltype(pos.move())(pos.move())));
    
    template <typename Cur, typename T>
    static constexpr decltype(pos.set((T&&)t)) set(Cur& pos, T&& t) noexcept(noexcept(decltype(pos.set((T&&)t))(pos.set((T&&)t))));
    
    template <typename Cur>
    static constexpr decltype(pos.next()) next(Cur& pos);
    
    template <typename Cur>
    static constexpr decltype(pos.done()) done(Cur const& pos);
    
    template <typename Cur>
    static constexpr decltype(pos0.equal(pos1)) equal(Cur const& pos0, Cur const& pos1);
    
    template <typename Cur, typename S>
    static constexpr decltype(end.equal(pos)) empty(Cur const& pos, S const& end);
    
    template <typename Cur>
    static constexpr decltype(pos.prev()) prev(Cur& pos);
    
    template <typename Cur, typename D>
    static constexpr decltype(pos.advance(n)) advance(Cur& pos, D n);
    
    template <typename Cur>
    static constexpr decltype(pos0.distance_to(pos1)) distance_to(Cur const& pos0, Cur const& pos1);
    
    template <typename Cur, typename S>
    static constexpr decltype(end.distance_from(pos)) distance_to(Cur const& pos, S const& end);
    
    template <typename Cur>
    static constexpr decltype(pos.distance_remaining()) distance_remaining(Cur const& pos);
    
    template <typename Cur>
    using cursor_difference_t = typename cursor_difference<Cur>::type;
    
    template <typename Cur>
    using cursor_value_t = typename cursor_value<Cur>::type;
    
    template <typename BI, int _concept_requires_325 = 42, typename std::enable_if<(_concept_requires_325==43)||(meta::is<meta::_t<std::decay<BI>>, basic_iterator>()), int>::type=0>
    static constexpr decltype(std::forward<BI>(it).pos()) pos(BI&& it) noexcept(noexcept(decltype(std::forward<BI>(it).pos())(std::forward<BI>(it).pos())));
    
    template <typename BS, int _concept_requires_331 = 42, typename std::enable_if<(_concept_requires_331==43)||(meta::is<meta::_t<std::decay<BS>>, basic_sentinel>()), int>::type=0>
    static constexpr decltype(std::forward<BS>(s).end()) end(BS&& s) noexcept(noexcept(decltype(std::forward<BS>(s).end())(std::forward<BS>(s).end())));
    
    template <typename Cur, typename S>
    static constexpr Cur cursor(basic_iterator<Cur, S> it);
    
    template <typename S>
    static constexpr S sentinel(basic_sentinel<S> s);
    
    template <typename RangeAdaptor>
    struct base_range
    : decltype(struct range_access::base_range_2_<RangeAdaptor>())
    {};
    
    template <typename RangeAdaptor>
    struct base_range<RangeAdaptor const>
    : std::add_const<meta::_t<base_range<RangeAdaptor> > >
    {};
    
    template <typename RangeFacade>
    struct view_facade
    : decltype(struct range_access::view_facade_2_<RangeFacade>())
    {};
};

@{