mirror of https://github.com/axmolengine/axmol.git
693 lines
23 KiB
C++
693 lines
23 KiB
C++
/// \file
|
|
// Range v3 library
|
|
//
|
|
// Copyright Eric Niebler 2014-present
|
|
// Copyright Casey Carter 2017
|
|
//
|
|
// Use, modification and distribution is subject to the
|
|
// Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// Project home: https://github.com/ericniebler/range-v3
|
|
//
|
|
|
|
#ifndef RANGES_V3_VIEW_ANY_VIEW_HPP
|
|
#define RANGES_V3_VIEW_ANY_VIEW_HPP
|
|
|
|
#include <type_traits>
|
|
#include <typeinfo>
|
|
#include <utility>
|
|
|
|
#include <range/v3/range_fwd.hpp>
|
|
|
|
#include <range/v3/iterator/default_sentinel.hpp>
|
|
#include <range/v3/range/access.hpp>
|
|
#include <range/v3/range/concepts.hpp>
|
|
#include <range/v3/range/traits.hpp>
|
|
#include <range/v3/utility/addressof.hpp>
|
|
#include <range/v3/utility/memory.hpp>
|
|
#include <range/v3/view/all.hpp>
|
|
#include <range/v3/view/facade.hpp>
|
|
|
|
#include <range/v3/detail/prologue.hpp>
|
|
|
|
RANGES_DIAGNOSTIC_PUSH
|
|
RANGES_DIAGNOSTIC_IGNORE_INCONSISTENT_OVERRIDE
|
|
RANGES_DIAGNOSTIC_SUGGEST_OVERRIDE
|
|
|
|
namespace ranges
|
|
{
|
|
/// \brief An enum that denotes the supported subset of range concepts supported by a
|
|
/// range.
|
|
enum class category
|
|
{
|
|
none = 0, ///<\brief No concepts met.
|
|
input = 1, ///<\brief satisfies ranges::concepts::input_range
|
|
forward = 3, ///<\brief satisfies ranges::concepts::forward_range
|
|
bidirectional = 7, ///<\brief satisfies ranges::concepts::bidirectional_range
|
|
random_access = 15, ///<\brief satisfies ranges::concepts::random_access_range
|
|
mask = random_access, ///<\brief Mask away any properties other than iterator
|
|
///< category
|
|
sized = 16, ///<\brief satisfies ranges::concepts::sized_range
|
|
};
|
|
|
|
/** \name Binary operators for ranges::category
|
|
* \relates ranges::category
|
|
* \{
|
|
*/
|
|
constexpr category operator&(category lhs, category rhs) noexcept
|
|
{
|
|
return static_cast<category>(
|
|
static_cast<meta::_t<std::underlying_type<category>>>(lhs) &
|
|
static_cast<meta::_t<std::underlying_type<category>>>(rhs));
|
|
}
|
|
|
|
constexpr category operator|(category lhs, category rhs) noexcept
|
|
{
|
|
return static_cast<category>(
|
|
static_cast<meta::_t<std::underlying_type<category>>>(lhs) |
|
|
static_cast<meta::_t<std::underlying_type<category>>>(rhs));
|
|
}
|
|
|
|
constexpr category operator^(category lhs, category rhs) noexcept
|
|
{
|
|
return static_cast<category>(
|
|
static_cast<meta::_t<std::underlying_type<category>>>(lhs) ^
|
|
static_cast<meta::_t<std::underlying_type<category>>>(rhs));
|
|
}
|
|
|
|
constexpr category operator~(category lhs) noexcept
|
|
{
|
|
return static_cast<category>(
|
|
~static_cast<meta::_t<std::underlying_type<category>>>(lhs));
|
|
}
|
|
|
|
constexpr category & operator&=(category & lhs, category rhs) noexcept
|
|
{
|
|
return (lhs = lhs & rhs);
|
|
}
|
|
|
|
constexpr category & operator|=(category & lhs, category rhs) noexcept
|
|
{
|
|
return (lhs = lhs | rhs);
|
|
}
|
|
|
|
constexpr category & operator^=(category & lhs, category rhs) noexcept
|
|
{
|
|
return (lhs = lhs ^ rhs);
|
|
}
|
|
//!\}
|
|
|
|
/// \brief For a given range, return a ranges::category enum with the satisfied
|
|
/// concepts.
|
|
template<typename Rng>
|
|
constexpr category get_categories() noexcept
|
|
{
|
|
return (input_range<Rng> ? category::input : category::none) |
|
|
(forward_range<Rng> ? category::forward : category::none) |
|
|
(bidirectional_range<Rng> ? category::bidirectional : category::none) |
|
|
(random_access_range<Rng> ? category::random_access : category::none) |
|
|
(sized_range<Rng> ? category::sized : category::none);
|
|
}
|
|
|
|
/// \cond
|
|
namespace detail
|
|
{
|
|
// workaround the fact that typeid ignores cv-qualifiers
|
|
template<typename>
|
|
struct rtti_tag
|
|
{};
|
|
|
|
struct any_ref
|
|
{
|
|
any_ref() = default;
|
|
template<typename T>
|
|
constexpr any_ref(T & obj) noexcept
|
|
: obj_(detail::addressof(obj))
|
|
#ifndef NDEBUG
|
|
, info_(&typeid(rtti_tag<T>))
|
|
#endif
|
|
{}
|
|
template<typename T>
|
|
T & get() const noexcept
|
|
{
|
|
RANGES_ASSERT(obj_ && info_ && *info_ == typeid(rtti_tag<T>));
|
|
return *const_cast<T *>(static_cast<T const volatile *>(obj_));
|
|
}
|
|
|
|
private:
|
|
void const volatile * obj_ = nullptr;
|
|
#ifndef NDEBUG
|
|
std::type_info const * info_ = nullptr;
|
|
#endif
|
|
};
|
|
|
|
template<typename Base>
|
|
struct cloneable : Base
|
|
{
|
|
using Base::Base;
|
|
virtual ~cloneable() override = default;
|
|
cloneable() = default;
|
|
cloneable(cloneable const &) = delete;
|
|
cloneable & operator=(cloneable const &) = delete;
|
|
virtual std::unique_ptr<cloneable> clone() const = 0;
|
|
};
|
|
|
|
// clang-format off
|
|
/// \concept any_compatible_range_
|
|
/// \brief The \c any_compatible_range_ concept
|
|
template(typename Rng, typename Ref)(
|
|
concept (any_compatible_range_)(Rng, Ref),
|
|
convertible_to<range_reference_t<Rng>, Ref>
|
|
);
|
|
/// \concept any_compatible_range
|
|
/// \brief The \c any_compatible_range concept
|
|
template<typename Rng, typename Ref>
|
|
CPP_concept any_compatible_range =
|
|
CPP_concept_ref(detail::any_compatible_range_, Rng, Ref);
|
|
// clang-format on
|
|
|
|
template<typename Rng, typename = void>
|
|
struct any_view_sentinel_impl
|
|
: private box<sentinel_t<Rng>, any_view_sentinel_impl<Rng>>
|
|
{
|
|
private:
|
|
using box_t = typename any_view_sentinel_impl::box;
|
|
|
|
public:
|
|
any_view_sentinel_impl() = default;
|
|
any_view_sentinel_impl(Rng & rng)
|
|
: box_t(ranges::end(rng))
|
|
{}
|
|
void init(Rng & rng) noexcept
|
|
{
|
|
box_t::get() = ranges::end(rng);
|
|
}
|
|
sentinel_t<Rng> const & get(Rng &) const noexcept
|
|
{
|
|
return box_t::get();
|
|
}
|
|
};
|
|
|
|
template<typename Rng>
|
|
struct any_view_sentinel_impl<
|
|
Rng, meta::void_<decltype(ranges::end(std::declval<Rng const &>()))>>
|
|
{
|
|
any_view_sentinel_impl() = default;
|
|
any_view_sentinel_impl(Rng &) noexcept
|
|
{}
|
|
void init(Rng &) noexcept
|
|
{}
|
|
sentinel_t<Rng> get(Rng & rng) const noexcept
|
|
{
|
|
return ranges::end(rng);
|
|
}
|
|
};
|
|
|
|
template<typename Ref, bool Sized = false>
|
|
struct any_input_view_interface
|
|
{
|
|
virtual ~any_input_view_interface() = default;
|
|
virtual void init() = 0;
|
|
virtual bool done() = 0;
|
|
virtual Ref read() const = 0;
|
|
virtual void next() = 0;
|
|
};
|
|
template<typename Ref>
|
|
struct any_input_view_interface<Ref, true> : any_input_view_interface<Ref, false>
|
|
{
|
|
virtual std::size_t size() = 0;
|
|
};
|
|
|
|
template<typename Ref>
|
|
struct any_input_cursor
|
|
{
|
|
using single_pass = std::true_type;
|
|
|
|
any_input_cursor() = default;
|
|
constexpr any_input_cursor(any_input_view_interface<Ref> & view) noexcept
|
|
: view_{detail::addressof(view)}
|
|
{}
|
|
Ref read() const
|
|
{
|
|
return view_->read();
|
|
}
|
|
void next()
|
|
{
|
|
view_->next();
|
|
}
|
|
bool equal(any_input_cursor const &) const noexcept
|
|
{
|
|
return true;
|
|
}
|
|
bool equal(default_sentinel_t) const
|
|
{
|
|
return !view_ || view_->done();
|
|
}
|
|
|
|
private:
|
|
any_input_view_interface<Ref> * view_ = nullptr;
|
|
};
|
|
|
|
template<typename Rng, typename Ref, bool Sized = false>
|
|
struct RANGES_EMPTY_BASES any_input_view_impl
|
|
: any_input_view_interface<Ref, Sized>
|
|
, private any_view_sentinel_impl<Rng>
|
|
{
|
|
CPP_assert(any_compatible_range<Rng, Ref>);
|
|
CPP_assert(!Sized || (bool)sized_range<Rng>);
|
|
|
|
explicit any_input_view_impl(Rng rng)
|
|
: rng_{std::move(rng)}
|
|
{}
|
|
any_input_view_impl(any_input_view_impl const &) = delete;
|
|
any_input_view_impl & operator=(any_input_view_impl const &) = delete;
|
|
|
|
private:
|
|
using sentinel_box_t = any_view_sentinel_impl<Rng>;
|
|
|
|
virtual void init() override
|
|
{
|
|
sentinel_box_t::init(rng_);
|
|
current_ = ranges::begin(rng_);
|
|
}
|
|
virtual bool done() override
|
|
{
|
|
return current_ == sentinel_box_t::get(rng_);
|
|
}
|
|
virtual Ref read() const override
|
|
{
|
|
return *current_;
|
|
}
|
|
virtual void next() override
|
|
{
|
|
++current_;
|
|
}
|
|
std::size_t size() // override-ish
|
|
{
|
|
return static_cast<std::size_t>(ranges::size(rng_));
|
|
}
|
|
|
|
RANGES_NO_UNIQUE_ADDRESS Rng rng_;
|
|
RANGES_NO_UNIQUE_ADDRESS iterator_t<Rng> current_{};
|
|
};
|
|
|
|
template<typename Ref, category Cat = category::forward, typename enable = void>
|
|
struct any_cursor_interface;
|
|
|
|
template<typename Ref, category Cat>
|
|
struct any_cursor_interface<
|
|
Ref, Cat, meta::if_c<(Cat & category::mask) == category::forward>>
|
|
{
|
|
virtual ~any_cursor_interface() = default;
|
|
virtual any_ref iter()
|
|
const = 0; // returns a const ref to the cursor's wrapped iterator
|
|
virtual Ref read() const = 0;
|
|
virtual bool equal(any_cursor_interface const &) const = 0;
|
|
virtual void next() = 0;
|
|
};
|
|
|
|
template<typename Ref, category Cat>
|
|
struct any_cursor_interface<
|
|
Ref, Cat, meta::if_c<(Cat & category::mask) == category::bidirectional>>
|
|
: any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>
|
|
{
|
|
virtual void prev() = 0;
|
|
};
|
|
|
|
template<typename Ref, category Cat>
|
|
struct any_cursor_interface<
|
|
Ref, Cat, meta::if_c<(Cat & category::mask) == category::random_access>>
|
|
: any_cursor_interface<Ref, (Cat & ~category::mask) | category::bidirectional>
|
|
{
|
|
virtual void advance(std::ptrdiff_t) = 0;
|
|
virtual std::ptrdiff_t distance_to(any_cursor_interface const &) const = 0;
|
|
};
|
|
|
|
template<typename Ref, category Cat>
|
|
using any_cloneable_cursor_interface = cloneable<any_cursor_interface<Ref, Cat>>;
|
|
|
|
template<typename I, typename Ref, category Cat>
|
|
struct any_cursor_impl : any_cloneable_cursor_interface<Ref, Cat>
|
|
{
|
|
CPP_assert(convertible_to<iter_reference_t<I>, Ref>);
|
|
CPP_assert((Cat & category::forward) == category::forward);
|
|
|
|
any_cursor_impl() = default;
|
|
any_cursor_impl(I it)
|
|
: it_{std::move(it)}
|
|
{}
|
|
|
|
private:
|
|
using Forward =
|
|
any_cursor_interface<Ref, (Cat & ~category::mask) | category::forward>;
|
|
|
|
I it_;
|
|
|
|
any_ref iter() const override
|
|
{
|
|
return it_;
|
|
}
|
|
Ref read() const override
|
|
{
|
|
return *it_;
|
|
}
|
|
bool equal(Forward const & that_) const override
|
|
{
|
|
auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
|
|
return that.it_ == it_;
|
|
}
|
|
void next() override
|
|
{
|
|
++it_;
|
|
}
|
|
std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> clone()
|
|
const override
|
|
{
|
|
return detail::make_unique<any_cursor_impl>(it_);
|
|
}
|
|
void prev() // override (sometimes; it's complicated)
|
|
{
|
|
--it_;
|
|
}
|
|
void advance(std::ptrdiff_t n) // override-ish
|
|
{
|
|
it_ += n;
|
|
}
|
|
std::ptrdiff_t distance_to(
|
|
any_cursor_interface<Ref, Cat> const & that_) const // override-ish
|
|
{
|
|
auto & that = polymorphic_downcast<any_cursor_impl const &>(that_);
|
|
return static_cast<std::ptrdiff_t>(that.it_ - it_);
|
|
}
|
|
};
|
|
|
|
struct fully_erased_view
|
|
{
|
|
virtual bool at_end(
|
|
any_ref) = 0; // any_ref is a const ref to a wrapped iterator
|
|
// to be compared to the erased view's last sentinel
|
|
protected:
|
|
~fully_erased_view() = default;
|
|
};
|
|
|
|
struct any_sentinel
|
|
{
|
|
any_sentinel() = default;
|
|
constexpr explicit any_sentinel(fully_erased_view & view) noexcept
|
|
: view_{&view}
|
|
{}
|
|
|
|
private:
|
|
template<typename, category>
|
|
friend struct any_cursor;
|
|
|
|
fully_erased_view * view_ = nullptr;
|
|
};
|
|
|
|
template<typename Ref, category Cat>
|
|
struct any_cursor
|
|
{
|
|
private:
|
|
CPP_assert((Cat & category::forward) == category::forward);
|
|
|
|
std::unique_ptr<any_cloneable_cursor_interface<Ref, Cat>> ptr_;
|
|
|
|
template<typename Rng>
|
|
using impl_t = any_cursor_impl<iterator_t<Rng>, Ref, Cat>;
|
|
|
|
public:
|
|
any_cursor() = default;
|
|
template(typename Rng)(
|
|
requires (!same_as<detail::decay_t<Rng>, any_cursor>) AND
|
|
forward_range<Rng> AND
|
|
any_compatible_range<Rng, Ref>)
|
|
explicit any_cursor(Rng && rng)
|
|
: ptr_{detail::make_unique<impl_t<Rng>>(begin(rng))}
|
|
{}
|
|
any_cursor(any_cursor &&) = default;
|
|
any_cursor(any_cursor const & that)
|
|
: ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
|
|
{}
|
|
any_cursor & operator=(any_cursor &&) = default;
|
|
any_cursor & operator=(any_cursor const & that)
|
|
{
|
|
ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
|
|
return *this;
|
|
}
|
|
Ref read() const
|
|
{
|
|
RANGES_EXPECT(ptr_);
|
|
return ptr_->read();
|
|
}
|
|
bool equal(any_cursor const & that) const
|
|
{
|
|
RANGES_EXPECT(!ptr_ == !that.ptr_);
|
|
return !ptr_ || ptr_->equal(*that.ptr_);
|
|
}
|
|
bool equal(any_sentinel const & that) const
|
|
{
|
|
RANGES_EXPECT(!ptr_ == !that.view_);
|
|
return !ptr_ || that.view_->at_end(ptr_->iter());
|
|
}
|
|
void next()
|
|
{
|
|
RANGES_EXPECT(ptr_);
|
|
ptr_->next();
|
|
}
|
|
CPP_member
|
|
auto prev() //
|
|
-> CPP_ret(void)(
|
|
requires (category::bidirectional == (Cat & category::bidirectional)))
|
|
{
|
|
RANGES_EXPECT(ptr_);
|
|
ptr_->prev();
|
|
}
|
|
CPP_member
|
|
auto advance(std::ptrdiff_t n) //
|
|
-> CPP_ret(void)(
|
|
requires (category::random_access == (Cat & category::random_access)))
|
|
{
|
|
RANGES_EXPECT(ptr_);
|
|
ptr_->advance(n);
|
|
}
|
|
CPP_member
|
|
auto distance_to(any_cursor const & that) const //
|
|
-> CPP_ret(std::ptrdiff_t)(
|
|
requires (category::random_access == (Cat & category::random_access)))
|
|
{
|
|
RANGES_EXPECT(!ptr_ == !that.ptr_);
|
|
return !ptr_ ? 0 : ptr_->distance_to(*that.ptr_);
|
|
}
|
|
};
|
|
|
|
template<typename Ref, category Cat,
|
|
bool = (Cat & category::sized) == category::sized>
|
|
struct any_view_interface : fully_erased_view
|
|
{
|
|
CPP_assert((Cat & category::forward) == category::forward);
|
|
|
|
virtual ~any_view_interface() = default;
|
|
virtual any_cursor<Ref, Cat> begin_cursor() = 0;
|
|
};
|
|
template<typename Ref, category Cat>
|
|
struct any_view_interface<Ref, Cat, true> : any_view_interface<Ref, Cat, false>
|
|
{
|
|
virtual std::size_t size() = 0;
|
|
};
|
|
|
|
template<typename Ref, category Cat>
|
|
using any_cloneable_view_interface = cloneable<any_view_interface<Ref, Cat>>;
|
|
|
|
template<typename Rng, typename Ref, category Cat>
|
|
struct RANGES_EMPTY_BASES any_view_impl
|
|
: any_cloneable_view_interface<Ref, Cat>
|
|
, private box<Rng, any_view_impl<Rng, Ref, Cat>>
|
|
, private any_view_sentinel_impl<Rng>
|
|
{
|
|
CPP_assert((Cat & category::forward) == category::forward);
|
|
CPP_assert(any_compatible_range<Rng, Ref>);
|
|
CPP_assert((Cat & category::sized) == category::none ||
|
|
(bool)sized_range<Rng>);
|
|
|
|
any_view_impl() = default;
|
|
any_view_impl(Rng rng)
|
|
: range_box_t{std::move(rng)}
|
|
, sentinel_box_t{range_box_t::get()}
|
|
// NB: initialization order dependence
|
|
{}
|
|
|
|
private:
|
|
using range_box_t = box<Rng, any_view_impl>;
|
|
using sentinel_box_t = any_view_sentinel_impl<Rng>;
|
|
|
|
any_cursor<Ref, Cat> begin_cursor() override
|
|
{
|
|
return any_cursor<Ref, Cat>{range_box_t::get()};
|
|
}
|
|
bool at_end(any_ref it_) override
|
|
{
|
|
auto & it = it_.get<iterator_t<Rng> const>();
|
|
return it == sentinel_box_t::get(range_box_t::get());
|
|
}
|
|
std::unique_ptr<any_cloneable_view_interface<Ref, Cat>> clone() const override
|
|
{
|
|
return detail::make_unique<any_view_impl>(range_box_t::get());
|
|
}
|
|
std::size_t size() // override-ish
|
|
{
|
|
return static_cast<std::size_t>(ranges::size(range_box_t::get()));
|
|
}
|
|
};
|
|
} // namespace detail
|
|
/// \endcond
|
|
|
|
/// \brief A type-erased view
|
|
/// \ingroup group-views
|
|
template<typename Ref, category Cat = category::input, typename enable = void>
|
|
struct any_view
|
|
: view_facade<any_view<Ref, Cat>,
|
|
(Cat & category::sized) == category::sized ? finite : unknown>
|
|
{
|
|
friend range_access;
|
|
CPP_assert((Cat & category::forward) == category::forward);
|
|
|
|
any_view() = default;
|
|
template(typename Rng)(
|
|
requires //
|
|
(!same_as<detail::decay_t<Rng>, any_view>) AND
|
|
input_range<Rng> AND
|
|
detail::any_compatible_range<Rng, Ref>)
|
|
any_view(Rng && rng)
|
|
: any_view(static_cast<Rng &&>(rng),
|
|
meta::bool_<(get_categories<Rng>() & Cat) == Cat>{})
|
|
{}
|
|
any_view(any_view &&) = default;
|
|
any_view(any_view const & that)
|
|
: ptr_{that.ptr_ ? that.ptr_->clone() : nullptr}
|
|
{}
|
|
any_view & operator=(any_view &&) = default;
|
|
any_view & operator=(any_view const & that)
|
|
{
|
|
ptr_ = (that.ptr_ ? that.ptr_->clone() : nullptr);
|
|
return *this;
|
|
}
|
|
|
|
CPP_member
|
|
auto size() //
|
|
-> CPP_ret(std::size_t)(
|
|
requires (category::sized == (Cat & category::sized)))
|
|
{
|
|
return ptr_ ? ptr_->size() : 0;
|
|
}
|
|
|
|
private:
|
|
template<typename Rng>
|
|
using impl_t = detail::any_view_impl<views::all_t<Rng>, Ref, Cat>;
|
|
template<typename Rng>
|
|
any_view(Rng && rng, std::true_type)
|
|
: ptr_{detail::make_unique<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
|
|
{}
|
|
template<typename Rng>
|
|
any_view(Rng &&, std::false_type)
|
|
{
|
|
static_assert(
|
|
(get_categories<Rng>() & Cat) == Cat,
|
|
"The range passed to any_view() does not model the requested category");
|
|
}
|
|
|
|
detail::any_cursor<Ref, Cat> begin_cursor()
|
|
{
|
|
return ptr_ ? ptr_->begin_cursor() : detail::value_init{};
|
|
}
|
|
detail::any_sentinel end_cursor() noexcept
|
|
{
|
|
return detail::any_sentinel{*ptr_};
|
|
}
|
|
|
|
std::unique_ptr<detail::any_cloneable_view_interface<Ref, Cat>> ptr_;
|
|
};
|
|
|
|
// input and not forward
|
|
template<typename Ref, category Cat>
|
|
struct any_view<Ref, Cat, meta::if_c<(Cat & category::forward) == category::input>>
|
|
: view_facade<any_view<Ref, Cat, void>,
|
|
(Cat & category::sized) == category::sized ? finite : unknown>
|
|
{
|
|
friend range_access;
|
|
|
|
any_view() = default;
|
|
template(typename Rng)(
|
|
requires //
|
|
(!same_as<detail::decay_t<Rng>, any_view>) AND
|
|
input_range<Rng> AND
|
|
detail::any_compatible_range<Rng, Ref>)
|
|
any_view(Rng && rng)
|
|
: ptr_{std::make_shared<impl_t<Rng>>(views::all(static_cast<Rng &&>(rng)))}
|
|
{}
|
|
|
|
CPP_member
|
|
auto size() //
|
|
-> CPP_ret(std::size_t)(
|
|
requires (category::sized == (Cat & category::sized)))
|
|
{
|
|
return ptr_ ? ptr_->size() : 0;
|
|
}
|
|
|
|
private:
|
|
template<typename Rng>
|
|
using impl_t =
|
|
detail::any_input_view_impl<views::all_t<Rng>, Ref,
|
|
(Cat & category::sized) == category::sized>;
|
|
|
|
detail::any_input_cursor<Ref> begin_cursor()
|
|
{
|
|
if(!ptr_)
|
|
return {};
|
|
|
|
ptr_->init();
|
|
return detail::any_input_cursor<Ref>{*ptr_};
|
|
}
|
|
|
|
std::shared_ptr<detail::any_input_view_interface<Ref, (Cat & category::sized) ==
|
|
category::sized>>
|
|
ptr_;
|
|
};
|
|
|
|
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
|
template(typename Rng)(
|
|
requires view_<Rng>)
|
|
any_view(Rng &&)
|
|
->any_view<range_reference_t<Rng>, get_categories<Rng>()>;
|
|
#endif
|
|
|
|
template<typename Ref>
|
|
using any_input_view RANGES_DEPRECATED(
|
|
"Use any_view<Ref, category::input> instead.") = any_view<Ref, category::input>;
|
|
|
|
template<typename Ref>
|
|
using any_forward_view RANGES_DEPRECATED(
|
|
"Use any_view<Ref, category::forward> instead.") =
|
|
any_view<Ref, category::forward>;
|
|
|
|
template<typename Ref>
|
|
using any_bidirectional_view RANGES_DEPRECATED(
|
|
"Use any_view<Ref, category::bidirectional> instead.") =
|
|
any_view<Ref, category::bidirectional>;
|
|
|
|
template<typename Ref>
|
|
using any_random_access_view RANGES_DEPRECATED(
|
|
"Use any_view<Ref, category::random_access> instead.") =
|
|
any_view<Ref, category::random_access>;
|
|
} // namespace ranges
|
|
|
|
#include <range/v3/detail/satisfy_boost_range.hpp>
|
|
RANGES_SATISFY_BOOST_RANGE(::ranges::any_view)
|
|
|
|
RANGES_DIAGNOSTIC_POP
|
|
|
|
#include <range/v3/detail/epilogue.hpp>
|
|
|
|
#endif
|