Header file range/v3/range_concepts.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

#include <range/v3/begin_end.hpp>

#include <range/v3/size.hpp>

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

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

namespace std{}

namespace ranges
{
    inline namespace v3
    {
        namespace concepts
        {
            struct Range
            {
                template <typename T>
                using iterator_t = decltype(begin(std::declval<T&>()));
                
                template <typename T>
                using sentinel_t = decltype(end(std::declval<T&>()));
                
                template <typename T>
                using difference_t = concepts::WeaklyIncrementable::difference_t<iterator_t<T>>;
                
                template <typename T>
                decltype(concepts::valid_expr(concepts::model_of<Sentinel>(end(t), begin(t)))) requires_(T&& t);
            };
            
            struct OutputRange
            : refines<struct ranges::v3::concepts::Range (_1)>
            {
                template <typename T, typename V>
                decltype(concepts::valid_expr(concepts::model_of<OutputIterator, Range::iterator_t<T>, V&&>())) requires_(T&&, V&&);
            };
            
            struct InputRange
            : refines<struct ranges::v3::concepts::Range>
            {
                template <typename T>
                using category_t = concepts::InputIterator::category_t<iterator_t<T>>;
                
                template <typename T>
                using value_t = concepts::Readable::value_t<iterator_t<T>>;
                
                template <typename T>
                using reference_t = concepts::Readable::reference_t<iterator_t<T>>;
                
                template <typename T>
                using rvalue_reference_t = concepts::Readable::rvalue_reference_t<iterator_t<T>>;
                
                template <typename T>
                using common_reference_t = concepts::Readable::common_reference_t<iterator_t<T>>;
                
                template <typename T>
                decltype(concepts::valid_expr(concepts::model_of<InputIterator>(begin(t)))) requires_(T&& t);
            };
            
            struct ForwardRange
            : refines<struct ranges::v3::concepts::InputRange>
            {
                template <typename T>
                decltype(concepts::valid_expr(concepts::model_of<ForwardIterator>(begin(t)))) requires_(T&& t);
            };
            
            struct BidirectionalRange
            : refines<struct ranges::v3::concepts::ForwardRange>
            {
                template <typename T>
                decltype(concepts::valid_expr(concepts::model_of<BidirectionalIterator>(begin(t)))) requires_(T&& t);
            };
            
            struct RandomAccessRange
            : refines<struct ranges::v3::concepts::BidirectionalRange>
            {
                template <typename T>
                decltype(concepts::valid_expr(concepts::model_of<RandomAccessIterator>(begin(t)))) requires_(T&& t);
            };
            
            struct BoundedRange
            : refines<struct ranges::v3::concepts::Range>
            {
                template <typename T>
                decltype(concepts::valid_expr(concepts::same_type(begin(t), end(t)))) requires_(T&& t);
            };
            
            struct SizedRange
            : refines<struct ranges::v3::concepts::Range>
            {
                template <typename T>
                using size_t = decltype(size(val<T>()));
                
                template <typename T>
                decltype(concepts::valid_expr(concepts::is_false(disable_sized_range<uncvref_t<T>>()), size(t))) requires_(T&& t);
            };
            
            struct ContainerLike_;
            
            struct View
            : refines<struct ranges::v3::concepts::Range>
            {
                template <typename T>
                decltype(concepts::valid_expr(concepts::model_of<SemiRegular, uncvref_t<T>>(), concepts::is_true(is_view<T>()))) requires_(T&&);
            };
            
            struct OutputView
            : refines<struct ranges::v3::concepts::View (_1), struct ranges::v3::concepts::OutputRange>
            {};
            
            struct InputView
            : refines<struct ranges::v3::concepts::View, struct ranges::v3::concepts::InputRange>
            {};
            
            struct ForwardView
            : refines<struct ranges::v3::concepts::InputView, struct ranges::v3::concepts::ForwardRange>
            {};
            
            struct BidirectionalView
            : refines<struct ranges::v3::concepts::ForwardView, struct ranges::v3::concepts::BidirectionalRange>
            {};
            
            struct RandomAccessView
            : refines<struct ranges::v3::concepts::BidirectionalView, struct ranges::v3::concepts::RandomAccessRange>
            {};
            
            struct BoundedView
            : refines<struct ranges::v3::concepts::View, struct ranges::v3::concepts::BoundedRange>
            {};
            
            struct SizedView
            : refines<struct ranges::v3::concepts::View, struct ranges::v3::concepts::SizedRange>
            {};
        }
        
        template <typename T>
        using Range = concepts::models<concepts::Range, T>;
        
        template <typename T, typename V>
        using OutputRange = concepts::models<concepts::OutputRange, T, V>;
        
        template <typename T>
        using InputRange = concepts::models<concepts::InputRange, T>;
        
        template <typename T>
        using ForwardRange = concepts::models<concepts::ForwardRange, T>;
        
        template <typename T>
        using BidirectionalRange = concepts::models<concepts::BidirectionalRange, T>;
        
        template <typename T>
        using RandomAccessRange = concepts::models<concepts::RandomAccessRange, T>;
        
        template <typename T>
        using BoundedRange = concepts::models<concepts::BoundedRange, T>;
        
        template <typename T>
        using SizedRange = concepts::models<concepts::SizedRange, T>;
        
        template <typename T>
        using ContainerLike_ = concepts::models<concepts::ContainerLike_, T>;
        
        template <typename T>
        using View = concepts::models<concepts::View, T>;
        
        template <typename T, typename V>
        using OutputView = concepts::models<concepts::OutputView, T, V>;
        
        template <typename T>
        using InputView = concepts::models<concepts::InputView, T>;
        
        template <typename T>
        using ForwardView = concepts::models<concepts::ForwardView, T>;
        
        template <typename T>
        using BidirectionalView = concepts::models<concepts::BidirectionalView, T>;
        
        template <typename T>
        using RandomAccessView = concepts::models<concepts::RandomAccessView, T>;
        
        template <typename T>
        using BoundedView = concepts::models<concepts::BoundedView, T>;
        
        template <typename T>
        using SizedView = concepts::models<concepts::SizedView, T>;
        
        template <typename T>
        using range_concept = concepts::most_refined<meta::list<concepts::RandomAccessRange, concepts::BidirectionalRange, concepts::ForwardRange, concepts::InputRange>, T>;
        
        template <typename T>
        using range_concept_t = meta::_t<range_concept<T>>;
        
        template <typename T>
        using bounded_range_concept = concepts::most_refined<meta::list<concepts::BoundedRange, concepts::Range>, T>;
        
        template <typename T>
        using bounded_range_concept_t = meta::_t<bounded_range_concept<T>>;
        
        template <typename T>
        using sized_range_concept = concepts::most_refined<meta::list<concepts::SizedRange, concepts::Range>, T>;
        
        template <typename T>
        using sized_range_concept_t = meta::_t<sized_range_concept<T>>;
        
        template <typename T>
        using bounded_view_concept = concepts::most_refined<meta::list<concepts::BoundedView, concepts::View>, T>;
        
        template <typename T>
        using bounded_view_concept_t = meta::_t<bounded_view_concept<T>>;
        
        template <typename T>
        using sized_view_concept = concepts::most_refined<meta::list<concepts::SizedView, concepts::View>, T>;
        
        template <typename T>
        using sized_view_concept_t = meta::_t<sized_view_concept<T>>;
        
        template <typename T>
        using view_concept = concepts::most_refined<meta::list<concepts::View, concepts::Range>, T>;
        
        template <typename T>
        using view_concept_t = meta::_t<view_concept<T>>;
        
        namespace detail
        {
            template <typename T>
            struct is_view_impl_
            : std::integral_constant<_Bool, Range<T>() && (!ContainerLike_<T>() || DerivedFrom<T, view_base>())>
            {};
            
            template <typename T, std::size_t N>
            struct is_view_impl_<T[N]>
            : std::false_type
            {};
        }
        
        template <typename T>
        struct disable_sized_range
        : std::false_type
        {};
        
        template <typename T, typename Enable>
        struct is_view
        : meta::if_<std::is_same<T, uncvref_t<T> >, detail::is_view_impl_<T>, is_view<uncvref_t<T> > >
        {};
        
        template <typename T>
        struct is_view<std::initializer_list<T>>
        : std::false_type
        {};
        
        template <typename Key, typename Compare, typename Alloc>
        struct is_view<std::set<Key, Compare, Alloc>>
        : std::false_type
        {};
        
        template <typename Key, typename Compare, typename Alloc>
        struct is_view<std::multiset<Key, Compare, Alloc>>
        : std::false_type
        {};
        
        template <typename Key, typename Hash, typename Pred, typename Alloc>
        struct is_view<std::unordered_set<Key, Hash, Pred, Alloc>>
        : std::false_type
        {};
        
        template <typename Key, typename Hash, typename Pred, typename Alloc>
        struct is_view<std::unordered_multiset<Key, Hash, Pred, Alloc>>
        : std::false_type
        {};
    }
}

Class ranges::v3::concepts::ContainerLike_

struct ContainerLike_
: refines<struct ranges::v3::concepts::InputRange>
{
    template <typename T>
    decltype(concepts::valid_expr(concepts::is_false(std::is_same<reference_t<detail::as_ref_t<T>>, reference_t<detail::as_cref_t<T>>>()))) requires_(T&&);
};

INTERNAL ONLY A type is ContainerLike_ if it is Range and the const-ness of its reference type is sensitive to the const-ness of the Container


Alias template ranges::v3::ContainerLike_<T>

template <typename T>
using ContainerLike_ = concepts::models<concepts::ContainerLike_, T>;

INTERNAL ONLY


Alias template ranges::v3::range_concept<T>

template <typename T>
using range_concept = concepts::most_refined<meta::list<concepts::RandomAccessRange, concepts::BidirectionalRange, concepts::ForwardRange, concepts::InputRange>, T>;

/////////////////////////////////////////////////////////////////////////////////////////


Alias template ranges::v3::bounded_range_concept<T>

template <typename T>
using bounded_range_concept = concepts::most_refined<meta::list<concepts::BoundedRange, concepts::Range>, T>;

/////////////////////////////////////////////////////////////////////////////////////////


Alias template ranges::v3::sized_range_concept<T>

template <typename T>
using sized_range_concept = concepts::most_refined<meta::list<concepts::SizedRange, concepts::Range>, T>;

/////////////////////////////////////////////////////////////////////////////////////////


Alias template ranges::v3::bounded_view_concept<T>

template <typename T>
using bounded_view_concept = concepts::most_refined<meta::list<concepts::BoundedView, concepts::View>, T>;

/////////////////////////////////////////////////////////////////////////////////////////


Alias template ranges::v3::sized_view_concept<T>

template <typename T>
using sized_view_concept = concepts::most_refined<meta::list<concepts::SizedView, concepts::View>, T>;

/////////////////////////////////////////////////////////////////////////////////////////


Alias template ranges::v3::view_concept<T>

template <typename T>
using view_concept = concepts::most_refined<meta::list<concepts::View, concepts::Range>, T>;

/////////////////////////////////////////////////////////////////////////////////////////