Header file range/v3/utility/basic_iterator.hpp

#include <meta/meta.hpp>

#include <range/v3/range_fwd.hpp>

#include <range/v3/range_access.hpp>

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

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

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

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

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

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

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

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

namespace ranges
{
    inline namespace v3
    {
        namespace detail
        {
            template <typename I>
            struct postfix_increment_proxy
            {
                using value_type = iterator_value_t<I>;
                
                postfix_increment_proxy() = default;
                
                explicit constexpr postfix_increment_proxy(I const& x);
                
                constexpr value_type& operator*() const;
            };
            
            template <typename I>
            struct writable_postfix_increment_proxy
            {
                using value_type = iterator_value_t<I>;
                
                writable_postfix_increment_proxy() = default;
                
                explicit constexpr writable_postfix_increment_proxy(I x);
                
                constexpr writable_postfix_increment_proxy const& operator*() const;
                
                constexpr operator value_type&() const;
                
                template <typename T, int _concept_requires_106 = 42, typename std::enable_if<(_concept_requires_106==43)||(Writable<I, T const&>()), int>::type=0>
                constexpr void operator=(T const& x) const;
                
                template <typename T, int _concept_requires_114 = 42, typename std::enable_if<(_concept_requires_114==43)||(Writable<I, T&>()), int>::type=0>
                constexpr void operator=(T& x) const;
                
                template <typename T, int _concept_requires_121 = 42, typename std::enable_if<(_concept_requires_121==43)||(Writable<I, aux::move_t<T>&&>()), int>::type=0>
                constexpr void operator=(T&& x) const;
                
                constexpr operator I const&() const;
            };
            
            template <typename Ref, typename Val>
            using is_non_proxy_reference = std::is_convertible<meta::_t<std::remove_reference<Ref>>const volatile*, Val const volatile*>;
            
            template <typename I, typename Val, typename Ref, typename Cat>
            using postfix_increment_result = meta::if_<DerivedFrom<Cat, ranges::forward_iterator_tag>, I, meta::if_<is_non_proxy_reference<Ref, Val>, postfix_increment_proxy<I>, writable_postfix_increment_proxy<I>>>;
            
            template <typename Cur>
            using cursor_reference_t = decltype(range_access::get(std::declval<Cur const&>()));
            
            template <typename Cur>
            decltype(range_access::move(cur)) cursor_move(Cur const& cur, int);
            
            template <typename Cur>
            aux::move_t<cursor_reference_t<Cur>> cursor_move(Cur const& cur, long);
            
            template <typename Cur>
            using cursor_rvalue_reference_t = decltype(detail::cursor_move(std::declval<Cur const&>(), 42));
            
            template <typename Derived, typename Head>
            struct proxy_reference_conversion
            {
                operator Head() const noexcept(noexcept(Head(Head(std::declval<Derived const&>().get_()))));
            };
            
            template <typename Cur, bool Readable = (bool)ReadableCursor<Cur>()>
            struct cursor_traits
            {
                using value_t_ = private_;
                
                using reference_t_ = private_;
                
                using rvalue_reference_t_ = private_;
                
                using common_refs = meta::list<>;
            };
            
            template <typename Cur>
            struct cursor_traits<Cur, true>
            {
                using value_t_ = range_access::cursor_value_t<Cur>;
                
                using reference_t_ = cursor_reference_t<Cur>;
                
                using rvalue_reference_t_ = cursor_rvalue_reference_t<Cur>;
                
                using common_refs = meta::unique<meta::pop_front<tmp3>>;
            };
            
            template <typename Cur, bool Readable = (bool)ReadableCursor<Cur>()>
            struct basic_proxy_reference
            : cursor_traits<Cur>, meta::inherit<meta::transform<typename cursor_traits<Cur>::common_refs, meta::bind_front<meta::quote<proxy_reference_conversion>, basic_proxy_reference<Cur> > > >
            {
                basic_proxy_reference() = default;
                
                basic_proxy_reference(basic_proxy_reference const&) = default;
                
                template <typename OtherCur, int _concept_requires_271 = 42, typename std::enable_if<(_concept_requires_271==43)||(ConvertibleTo<OtherCur*, Cur*>()), int>::type=0>
                constexpr basic_proxy_reference(basic_proxy_reference<OtherCur>const& that) noexcept;
                
                explicit constexpr basic_proxy_reference(Cur& cur) noexcept;
                
                template <int _concept_requires_280 = 42, typename std::enable_if<(_concept_requires_280==43)||(ReadableCursor<Cur>()), int>::type=0>
                constexpr basic_proxy_reference& operator=(basic_proxy_reference&& that);
                
                template <int _concept_requires_286 = 42, typename std::enable_if<(_concept_requires_286==43)||(ReadableCursor<Cur>()), int>::type=0>
                constexpr basic_proxy_reference& operator=(basic_proxy_reference const& that);
                
                template <typename OtherCur, int _concept_requires_294 = 42, typename std::enable_if<(_concept_requires_294==43)||(ReadableCursor<OtherCur>()&&WritableCursor<Cur, cursor_reference_t<OtherCur>>()), int>::type=0>
                constexpr basic_proxy_reference& operator=(basic_proxy_reference<OtherCur>&& that);
                
                template <typename OtherCur, int _concept_requires_302 = 42, typename std::enable_if<(_concept_requires_302==43)||(ReadableCursor<OtherCur>()&&WritableCursor<Cur, cursor_reference_t<OtherCur>>()), int>::type=0>
                constexpr basic_proxy_reference& operator=(basic_proxy_reference<OtherCur>const& that);
                
                template <typename T, int _concept_requires_311 = 42, typename std::enable_if<(_concept_requires_311==43)||(WritableCursor<Cur, T&&>()), int>::type=0>
                constexpr basic_proxy_reference& operator=(T&& t);
            };
            
            ranges::input_iterator_tag iter_cat(range_access::InputCursor*);
            
            ranges::forward_iterator_tag iter_cat(range_access::ForwardCursor*);
            
            ranges::bidirectional_iterator_tag iter_cat(range_access::BidirectionalCursor*);
            
            ranges::random_access_iterator_tag iter_cat(range_access::RandomAccessCursor*);
            
            template <typename Cur, typename S, bool Readable = (bool)ReadableCursor<Cur>()>
            struct iterator_associated_types_base
            {
                using reference = void;
                
                using difference_type = range_access::cursor_difference_t<Cur>;
            };
            
            template <typename Cur, typename S>
            struct iterator_associated_types_base<Cur, S, true>
            : iterator_associated_types_base<Cur, S, false>
            {
                using value_type = range_access::cursor_value_t<Cur>;
                
                using reference = reference_t;
                
                using iterator_category = decltype(detail::iter_cat(_nullptr_v<cursor_concept_t>()));
                
                using pointer = meta::_t<std::add_pointer<reference>>;
                
                using common_reference = common_reference_t<reference&&, value_type&>;
            };
        }
        
        template <typename T>
        struct basic_mixin;
        
        template <typename S>
        struct basic_sentinel
        : range_access::mixin_base_t<S>
        {
            basic_sentinel() = default;
            
            constexpr basic_sentinel(S end);
            
            using range_access::mixin_base_t<S>::mixin_base_t;
        };
        
        struct default_end_cursor
        {
            template <typename Cur>
            static constexpr bool equal(Cur const& pos);
            
            template <typename Cur>
            static constexpr decltype(range_access::distance_remaining(pos)) distance_from(Cur const& pos);
        };
        
        template <typename Cur, typename S>
        struct basic_iterator
        : range_access::mixin_base_t<Cur>, detail::iterator_associated_types_base<Cur, S>
        {
            using typename assoc_types_::difference_type;
            
            constexpr basic_iterator() = default;
            
            constexpr basic_iterator(Cur pos);
            
            template <typename OtherCur, typename OtherS, int _concept_requires_503 = 42, typename std::enable_if<(_concept_requires_503==43)||(ConvertibleTo<OtherCur, Cur>()&&Constructible<range_access::mixin_base_t<Cur>, OtherCur&&>()), int>::type=0>
            constexpr basic_iterator(basic_iterator<OtherCur, OtherS> that);
            
            using range_access::mixin_base_t<Cur>::mixin_base_t;
            
            constexpr reference_t operator*() noexcept(noexcept(std::declval<basic_iterator&>().dereference_(detail::is_writable_cursor<Cur>{})));
            
            constexpr const_reference_t operator*() const noexcept(noexcept(std::declval<basic_iterator const&>().dereference_(detail::is_writable_cursor<Cur>{})));
            
            constexpr basic_iterator& operator++();
            
            constexpr postfix_increment_result_t operator++(int);
            
            template <int _concept_requires_588 = 42, typename std::enable_if<(_concept_requires_588==43)||(detail::BidirectionalCursor<Cur>()), int>::type=0>
            constexpr basic_iterator& operator--();
            
            template <int _concept_requires_595 = 42, typename std::enable_if<(_concept_requires_595==43)||(detail::BidirectionalCursor<Cur>()), int>::type=0>
            constexpr basic_iterator operator--(int);
            
            template <int _concept_requires_603 = 42, typename std::enable_if<(_concept_requires_603==43)||(detail::RandomAccessCursor<Cur>()), int>::type=0>
            constexpr basic_iterator& operator+=(difference_type n);
            
            template <int _concept_requires_624 = 42, typename std::enable_if<(_concept_requires_624==43)||(detail::RandomAccessCursor<Cur>()), int>::type=0>
            constexpr basic_iterator& operator-=(difference_type n);
            
            template <int _concept_requires_684 = 42, typename std::enable_if<(_concept_requires_684==43)||(detail::RandomAccessCursor<Cur>()), int>::type=0>
            constexpr const_reference_t operator[](difference_type n) const;
        };
        
        struct get_cursor_fn;
        
        inline namespace 
        {
            constexpr auto& get_cursor = static_const<get_cursor_fn>::value;
        }
        
        namespace detail
        {
            template <typename C, typename S, int _concept_requires_727 = 42, typename std::enable_if<(_concept_requires_727==43)||(InputCursor<C>()), int>::type=0>
            constexpr decltype(range_access::move(get_cursor(it))) indirect_move(basic_iterator<C, S>const& it) noexcept(noexcept(decltype(range_access::move(get_cursor(it)))(range_access::move(get_cursor(it)))));
        }
    }
}

namespace ranges
{
    inline namespace v3{}
}

namespace ranges
{
    inline namespace v3
    {
        namespace detail
        {
            template <typename Cur, typename S, bool IsReadable = (bool)ReadableCursor<Cur>()>
            struct std_iterator_traits
            : iterator_associated_types_base<Cur, S>
            {
                using iterator_category = std::output_iterator_tag;
                
                using value_type = void;
                
                using reference = void;
                
                using pointer = void;
            };
            
            template <typename Cur, typename S>
            struct std_iterator_traits<Cur, S, true>
            : iterator_associated_types_base<Cur, S>
            {
                using iterator_category = ::meta::_t<downgrade_iterator_category<typename std_iterator_traits::iterator_category, typename std_iterator_traits::reference>>;
            };
        }
    }
}

namespace std{}

Class template ranges::v3::basic_mixin<T>

template <typename T>
struct basic_mixin
{
    template <int _concept_requires_422 = 42, typename std::enable_if<(_concept_requires_422==43)||(DefaultConstructible<T>()), int>::type=0>
    constexpr basic_mixin();
    
    template <int _concept_requires_426 = 42, typename std::enable_if<(_concept_requires_426==43)||(MoveConstructible<T>()), int>::type=0>
    constexpr basic_mixin(T&& t);
    
    template <int _concept_requires_430 = 42, typename std::enable_if<(_concept_requires_430==43)||(CopyConstructible<T>()), int>::type=0>
    constexpr basic_mixin(T const& t);
    
protected:
    using box<T>::get;
};

@{


Class ranges::v3::get_cursor_fn

struct get_cursor_fn
{
    template <typename Cur, typename Sent>
    constexpr Cur& operator()(basic_iterator<Cur, Sent>& it) const noexcept;
    
    template <typename Cur, typename Sent>
    constexpr Cur const& operator()(basic_iterator<Cur, Sent>const& it) const noexcept;
    
    template <typename Cur, typename Sent>
    constexpr Cur operator()(basic_iterator<Cur, Sent>&& it) const noexcept(std::is_nothrow_move_constructible<Cur>::value);
};

Get a cursor from a basic_iterator


Variable ranges::v3::get_cursor

constexpr auto& get_cursor = static_const<get_cursor_fn>::value;

get_cursor_fn