Header file range/v3/view/any_view.hpp

#include <range/v3/range_fwd.hpp>

#include <range/v3/begin_end.hpp>

#include <range/v3/range_traits.hpp>

#include <range/v3/range_concepts.hpp>

#include <range/v3/view_facade.hpp>

#include <range/v3/view/all.hpp>

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

namespace ranges
{
    inline namespace v3
    {
        enum class category
        {
            input,
            forward,
            bidirectional,
            random_access,
        };
        
        namespace detail
        {
            struct any_object
            {
                virtual ~any_object() = default;
            };
            
            template <typename T>
            struct object
            : ranges::v3::detail::any_object
            {
                object() = default;
                
                object(T o);
                
                T& get();
                
                T const& get() const;
            };
            
            template <typename Ref, category Cat = category::input>
            struct any_cursor_interface
            {
                virtual ~any_cursor_interface() = default;
                
                virtual any_object const& iter() const = 0
                
                virtual Ref get() const = 0
                
                virtual bool equal(any_cursor_interface const&) const = 0
                
                virtual void next() = 0
                
                virtual any_cursor_interface* clone_() const = 0
                
                any_cursor_interface* clone() const;
            };
            
            template <typename Ref>
            struct any_cursor_interface<Ref, category::forward>
            : any_cursor_interface<Ref, enum category::input>
            {
                any_cursor_interface* clone() const;
            };
            
            template <typename Ref>
            struct any_cursor_interface<Ref, category::bidirectional>
            : any_cursor_interface<Ref, enum category::forward>
            {
                virtual void prev() = 0
                
                any_cursor_interface* clone() const;
            };
            
            template <typename Ref>
            struct any_cursor_interface<Ref, category::random_access>
            : any_cursor_interface<Ref, enum category::bidirectional>
            {
                virtual void advance(std::ptrdiff_t) = 0
                
                virtual std::ptrdiff_t distance_to(any_cursor_interface const&) const = 0
                
                any_cursor_interface* clone() const;
            };
            
            template <typename I, typename Ref, category Cat>
            struct any_cursor_impl
            : any_cursor_interface<Ref, Cat>
            {
                any_cursor_impl() = default;
                
                any_cursor_impl(I it);
                
                object<I>const& iter() const;
                
                Ref get() const;
                
                bool equal(Input const& that) const;
                
                void next();
                
                any_cursor_impl* clone_() const;
                
                void prev();
                
                void advance(std::ptrdiff_t n);
                
                std::ptrdiff_t distance_to(any_cursor_interface<Ref, category::random_access>const& that) const;
            };
            
            struct any_sentinel_interface
            {
                virtual ~any_sentinel_interface() = default;
                
                virtual bool equal(any_object const&) const = 0
                
                virtual any_sentinel_interface* clone() const = 0
            };
            
            template <typename S, typename I>
            struct any_sentinel_impl
            : ranges::v3::detail::any_sentinel_interface
            {
                any_sentinel_impl() = default;
                
                any_sentinel_impl(S s);
                
                virtual bool equal(any_object const& that) const override;
                
                virtual any_sentinel_impl* clone() const override;
            };
            
            template <typename Ref, category Cat>
            struct any_cursor
            {
                using single_pass = meta::bool_<Cat==category::input>;
                
                any_cursor() = default;
                
                template <typename Rng, int _concept_requires_218 = 42, typename std::enable_if<(_concept_requires_218==43)||(!Same<detail::decay_t<Rng>, any_cursor>()), int>::type=0, int _concept_requires_219 = 42, typename std::enable_if<(_concept_requires_219==43)||(InputRange<Rng>()&&ConvertibleTo<range_reference_t<Rng>, Ref>()), int>::type=0>
                any_cursor(Rng&& rng, begin_tag);
                
                any_cursor(any_cursor&&) = default;
                
                any_cursor(any_cursor const& that);
                
                any_cursor& operator=(any_cursor&&) = default;
                
                any_cursor& operator=(any_cursor const& that);
                
                Ref get() const;
                
                bool equal(any_cursor const& that) const;
                
                void next();
                
                template <int _concept_requires_249 = 42, typename std::enable_if<(_concept_requires_249==43)||(Cat>=category::bidirectional), int>::type=0>
                void prev();
                
                template <int _concept_requires_255 = 42, typename std::enable_if<(_concept_requires_255==43)||(Cat>=category::random_access), int>::type=0>
                void advance(std::ptrdiff_t n);
                
                template <int _concept_requires_261 = 42, typename std::enable_if<(_concept_requires_261==43)||(Cat>=category::random_access), int>::type=0>
                std::ptrdiff_t distance_to(any_cursor const& that) const;
            };
            
            struct any_sentinel
            {
                any_sentinel() = default;
                
                template <typename Rng, int _concept_requires_276 = 42, typename std::enable_if<(_concept_requires_276==43)||(!Same<detail::decay_t<Rng>, any_sentinel>()), int>::type=0, int _concept_requires_277 = 42, typename std::enable_if<(_concept_requires_277==43)||(InputRange<Rng>()), int>::type=0>
                any_sentinel(Rng&& rng, end_tag);
                
                any_sentinel(any_sentinel&&) = default;
                
                any_sentinel(any_sentinel const& that);
                
                any_sentinel& operator=(any_sentinel&&) = default;
                
                any_sentinel& operator=(any_sentinel const& that);
                
                template <typename Ref, category Cat>
                bool equal(any_cursor<Ref, Cat>const& that) const;
            };
            
            template <typename Ref, category Cat>
            struct any_view_interface
            {
                virtual ~any_view_interface() = default;
                
                virtual any_cursor<Ref, Cat> begin_cursor() = 0
                
                virtual any_sentinel end_cursor() = 0
                
                virtual any_view_interface* clone() const = 0
            };
            
            template <typename Rng, typename Ref, category Cat>
            struct any_view_impl
            : any_view_interface<Ref, Cat>
            {
                any_view_impl() = default;
                
                any_view_impl(Rng rng);
                
                virtual any_cursor<Ref, Cat> begin_cursor() override;
                
                virtual any_sentinel end_cursor() override;
                
                virtual any_view_interface<Ref, Cat>* clone() const override;
            };
            
            constexpr category to_cat_(concepts::InputRange*);
            
            constexpr category to_cat_(concepts::ForwardRange*);
            
            constexpr category to_cat_(concepts::BidirectionalRange*);
            
            constexpr category to_cat_(concepts::RandomAccessRange*);
        }
        
        template <typename Ref, category Cat = category::input>
        struct any_view;
        
        template <typename Ref>
        using any_input_view = any_view<Ref, category::input>;
        
        template <typename Ref>
        using any_forward_view = any_view<Ref, category::forward>;
        
        template <typename Ref>
        using any_bidirectional_view = any_view<Ref, category::bidirectional>;
        
        template <typename Ref>
        using any_random_access_view = any_view<Ref, category::random_access>;
    }
}

Class template ranges::v3::any_view<Ref, Cat>

template <typename Ref, category Cat = category::input>
struct any_view
: view_facade<any_view<Ref, Cat>, unknown>
{
    any_view() = default;
    
    template <typename Rng, int _concept_requires_373 = 42, typename std::enable_if<(_concept_requires_373==43)||(!Same<detail::decay_t<Rng>, any_view>()), int>::type=0, int _concept_requires_374 = 42, typename std::enable_if<(_concept_requires_374==43)||(InputRange<Rng>()&&ConvertibleTo<range_reference_t<Rng>, Ref>()), int>::type=0>
    any_view(Rng&& rng);
    
    any_view(any_view&&) = default;
    
    any_view(any_view const& that);
    
    any_view& operator=(any_view&&) = default;
    
    any_view& operator=(any_view const& that);
};

A type-erased view