init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
692
Telegram/ThirdParty/range-v3/include/range/v3/view/any_view.hpp
vendored
Normal file
692
Telegram/ThirdParty/range-v3/include/range/v3/view/any_view.hpp
vendored
Normal file
@@ -0,0 +1,692 @@
|
||||
/// \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
|
||||
Reference in New Issue
Block a user