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:
575
Telegram/ThirdParty/range-v3/include/range/v3/view/adaptor.hpp
vendored
Normal file
575
Telegram/ThirdParty/range-v3/include/range/v3/view/adaptor.hpp
vendored
Normal file
@@ -0,0 +1,575 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_ADAPTOR_HPP
|
||||
#define RANGES_V3_VIEW_ADAPTOR_HPP
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/compressed_pair.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Derived>
|
||||
using begin_adaptor_t = detail::decay_t<decltype(
|
||||
range_access::begin_adaptor(std::declval<Derived &>()))>;
|
||||
|
||||
template<typename Derived>
|
||||
using end_adaptor_t = detail::decay_t<decltype(
|
||||
range_access::end_adaptor(std::declval<Derived &>()))>;
|
||||
|
||||
template<typename Derived>
|
||||
using adapted_iterator_t = detail::decay_t<decltype(
|
||||
std::declval<begin_adaptor_t<Derived>>().begin(std::declval<Derived &>()))>;
|
||||
|
||||
template<typename Derived>
|
||||
using adapted_sentinel_t = detail::decay_t<decltype(
|
||||
std::declval<end_adaptor_t<Derived>>().end(std::declval<Derived &>()))>;
|
||||
|
||||
struct adaptor_base_current_mem_fn
|
||||
{};
|
||||
|
||||
template<typename BaseIter, typename Adapt>
|
||||
constexpr int which_adaptor_value_(priority_tag<0>)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
template<typename BaseIter, typename Adapt>
|
||||
constexpr always_<int, decltype(Adapt::read(std::declval<BaseIter const &>(),
|
||||
adaptor_base_current_mem_fn{}))> //
|
||||
which_adaptor_value_(priority_tag<1>)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
template<typename BaseIter, typename Adapt>
|
||||
constexpr always_<int, typename Adapt::value_type> //
|
||||
which_adaptor_value_(priority_tag<2>)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
template<typename BaseIter, typename Adapt,
|
||||
int = detail::which_adaptor_value_<BaseIter, Adapt>(priority_tag<2>{})>
|
||||
struct adaptor_value_type_
|
||||
{
|
||||
compressed_pair<BaseIter, Adapt> data_;
|
||||
};
|
||||
template<typename BaseIter, typename Adapt>
|
||||
struct adaptor_value_type_<BaseIter, Adapt, 1>
|
||||
{
|
||||
using value_type = iter_value_t<BaseIter>;
|
||||
compressed_pair<BaseIter, Adapt> data_;
|
||||
};
|
||||
template<typename BaseIter, typename Adapt>
|
||||
struct adaptor_value_type_<BaseIter, Adapt, 2>
|
||||
{
|
||||
#ifdef RANGES_WORKAROUND_MSVC_688606
|
||||
using value_type = typename indirectly_readable_traits<Adapt>::value_type;
|
||||
#else // ^^^ workaround ^^^ / vvv no workaround vvv
|
||||
using value_type = typename Adapt::value_type;
|
||||
#endif // RANGES_WORKAROUND_MSVC_688606
|
||||
compressed_pair<BaseIter, Adapt> data_;
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename BaseIt, typename Adapt>
|
||||
struct adaptor_cursor;
|
||||
|
||||
template<typename BaseSent, typename Adapt>
|
||||
struct base_adaptor_sentinel;
|
||||
|
||||
struct adaptor_base
|
||||
{
|
||||
adaptor_base() = default;
|
||||
adaptor_base(adaptor_base &&) = default;
|
||||
adaptor_base(adaptor_base const &) = default;
|
||||
adaptor_base & operator=(adaptor_base &&) = default;
|
||||
adaptor_base & operator=(adaptor_base const &) = default;
|
||||
|
||||
adaptor_base(detail::ignore_t, detail::ignore_t = {}, detail::ignore_t = {})
|
||||
{}
|
||||
// clang-format off
|
||||
template<typename Rng>
|
||||
static constexpr auto CPP_auto_fun(begin)(Rng &rng)
|
||||
(
|
||||
return ranges::begin(rng.base())
|
||||
)
|
||||
template<typename Rng>
|
||||
static constexpr auto CPP_auto_fun(end)(Rng &rng)
|
||||
(
|
||||
return ranges::end(rng.base())
|
||||
)
|
||||
// clang-format on
|
||||
template(typename I)(
|
||||
requires equality_comparable<I>)
|
||||
static bool equal(I const & it0, I const & it1)
|
||||
{
|
||||
return it0 == it1;
|
||||
}
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
static iter_reference_t<I> read(I const & it,
|
||||
detail::adaptor_base_current_mem_fn = {})
|
||||
noexcept(noexcept(iter_reference_t<I>(*it)))
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
static void next(I & it)
|
||||
{
|
||||
++it;
|
||||
}
|
||||
template(typename I)(
|
||||
requires bidirectional_iterator<I>)
|
||||
static void prev(I & it)
|
||||
{
|
||||
--it;
|
||||
}
|
||||
template(typename I)(
|
||||
requires random_access_iterator<I>)
|
||||
static void advance(I & it, iter_difference_t<I> n)
|
||||
{
|
||||
it += n;
|
||||
}
|
||||
template(typename I)(
|
||||
requires sized_sentinel_for<I, I>)
|
||||
static iter_difference_t<I> distance_to(I const & it0, I const & it1)
|
||||
{
|
||||
return it1 - it0;
|
||||
}
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
static constexpr bool empty(I const & it, S const & last)
|
||||
{
|
||||
return it == last;
|
||||
}
|
||||
};
|
||||
|
||||
// Build a sentinel out of a sentinel into the adapted range, and an
|
||||
// adaptor that customizes behavior.
|
||||
template<typename BaseSent, typename Adapt>
|
||||
struct base_adaptor_sentinel
|
||||
{
|
||||
private:
|
||||
template<typename, typename>
|
||||
friend struct adaptor_cursor;
|
||||
RANGES_NO_UNIQUE_ADDRESS compressed_pair<BaseSent, Adapt> data_;
|
||||
|
||||
public:
|
||||
base_adaptor_sentinel() = default;
|
||||
base_adaptor_sentinel(BaseSent sent, Adapt adapt)
|
||||
: data_{std::move(sent), std::move(adapt)}
|
||||
{}
|
||||
|
||||
// All sentinels into adapted ranges have a base() member for fetching
|
||||
// the underlying sentinel.
|
||||
BaseSent base() const
|
||||
{
|
||||
return data_.first();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Adaptor accessor
|
||||
Adapt & get()
|
||||
{
|
||||
return data_.second();
|
||||
}
|
||||
Adapt const & get() const
|
||||
{
|
||||
return data_.second();
|
||||
}
|
||||
};
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename BaseSent, typename Adapt>
|
||||
meta::id<base_adaptor_sentinel<BaseSent, Adapt>> base_adaptor_sentinel_2_(long);
|
||||
|
||||
template<typename BaseSent, typename Adapt>
|
||||
meta::id<typename Adapt::template mixin<base_adaptor_sentinel<BaseSent, Adapt>>>
|
||||
base_adaptor_sentinel_2_(int);
|
||||
|
||||
template<typename BaseSent, typename Adapt>
|
||||
struct base_adaptor_sentinel_
|
||||
: decltype(base_adaptor_sentinel_2_<BaseSent, Adapt>(42))
|
||||
{};
|
||||
|
||||
template<typename BaseSent, typename Adapt>
|
||||
using adaptor_sentinel_ = meta::_t<base_adaptor_sentinel_<BaseSent, Adapt>>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename BaseSent, typename Adapt>
|
||||
struct adaptor_sentinel : detail::adaptor_sentinel_<BaseSent, Adapt>
|
||||
{
|
||||
using detail::adaptor_sentinel_<BaseSent, Adapt>::adaptor_sentinel_;
|
||||
};
|
||||
|
||||
// Build a cursor out of an iterator into the adapted range, and an
|
||||
// adaptor that customizes behavior.
|
||||
template<typename BaseIter, typename Adapt>
|
||||
struct adaptor_cursor : private detail::adaptor_value_type_<BaseIter, Adapt>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
template<typename, typename>
|
||||
friend struct adaptor_cursor;
|
||||
using base_t = detail::adaptor_value_type_<BaseIter, Adapt>;
|
||||
using single_pass = meta::bool_<(bool)range_access::single_pass_t<Adapt>() ||
|
||||
(bool)single_pass_iterator_<BaseIter>>;
|
||||
|
||||
struct basic_adaptor_mixin : basic_mixin<adaptor_cursor>
|
||||
{
|
||||
basic_adaptor_mixin() = default;
|
||||
#ifndef _MSC_VER
|
||||
using basic_mixin<adaptor_cursor>::basic_mixin;
|
||||
#else
|
||||
constexpr explicit basic_adaptor_mixin(adaptor_cursor && cur)
|
||||
: basic_mixin<adaptor_cursor>(static_cast<adaptor_cursor &&>(cur))
|
||||
{}
|
||||
constexpr explicit basic_adaptor_mixin(adaptor_cursor const & cur)
|
||||
: basic_mixin<adaptor_cursor>(cur)
|
||||
{}
|
||||
#endif
|
||||
// All iterators into adapted ranges have a base() member for fetching
|
||||
// the underlying iterator.
|
||||
BaseIter base() const
|
||||
{
|
||||
return basic_adaptor_mixin::basic_mixin::get().data_.first();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Adaptor accessor
|
||||
Adapt & get()
|
||||
{
|
||||
return basic_adaptor_mixin::basic_mixin::get().data_.second();
|
||||
}
|
||||
const Adapt & get() const
|
||||
{
|
||||
return basic_adaptor_mixin::basic_mixin::get().data_.second();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Adapt_>
|
||||
static meta::id<basic_adaptor_mixin> basic_adaptor_mixin_2_(long);
|
||||
|
||||
template<typename Adapt_>
|
||||
static meta::id<typename Adapt_::template mixin<basic_adaptor_mixin>>
|
||||
basic_adaptor_mixin_2_(int);
|
||||
|
||||
using mixin = meta::_t<decltype(basic_adaptor_mixin_2_<Adapt>(42))>;
|
||||
|
||||
template<typename A = Adapt, typename R = decltype(std::declval<A const &>().read(
|
||||
std::declval<BaseIter const &>()))>
|
||||
R read() const noexcept(
|
||||
noexcept(std::declval<A const &>().read(std::declval<BaseIter const &>())))
|
||||
{
|
||||
using V = range_access::cursor_value_t<adaptor_cursor>;
|
||||
static_assert(common_reference_with<R &&, V &>,
|
||||
"In your adaptor, you've specified a value type that does not "
|
||||
"share a common reference type with the return type of read.");
|
||||
return this->data_.second().read(this->data_.first());
|
||||
}
|
||||
template<typename A = Adapt, typename = decltype(std::declval<A &>().next(
|
||||
std::declval<BaseIter &>()))>
|
||||
void next()
|
||||
{
|
||||
this->data_.second().next(this->data_.first());
|
||||
}
|
||||
template<typename A = Adapt,
|
||||
typename = decltype(std::declval<A const &>().equal(
|
||||
std::declval<BaseIter const &>(), std::declval<BaseIter const &>(),
|
||||
std::declval<A const &>()))>
|
||||
bool equal_(adaptor_cursor const & that, int) const
|
||||
{
|
||||
return this->data_.second().equal(
|
||||
this->data_.first(), that.data_.first(), that.data_.second());
|
||||
}
|
||||
template<typename A = Adapt,
|
||||
typename = decltype(std::declval<A const &>().equal(
|
||||
std::declval<BaseIter const &>(), std::declval<BaseIter const &>()))>
|
||||
bool equal_(adaptor_cursor const & that, long) const
|
||||
{
|
||||
return this->data_.second().equal(this->data_.first(), that.data_.first());
|
||||
}
|
||||
template<typename C = adaptor_cursor>
|
||||
auto equal(adaptor_cursor const & that) const
|
||||
-> decltype(std::declval<C const &>().equal_(that, 42))
|
||||
{
|
||||
return this->equal_(that, 42);
|
||||
}
|
||||
template<typename S, typename A,
|
||||
typename = decltype(std::declval<A const &>().empty(
|
||||
std::declval<BaseIter const &>(), std::declval<Adapt const &>(),
|
||||
std::declval<S const &>()))>
|
||||
constexpr bool equal_(adaptor_sentinel<S, A> const & that, int) const
|
||||
{
|
||||
return that.data_.second().empty(
|
||||
this->data_.first(), this->data_.second(), that.data_.first());
|
||||
}
|
||||
template<typename S, typename A,
|
||||
typename = decltype(std::declval<A const &>().empty(
|
||||
std::declval<BaseIter const &>(), std::declval<S const &>()))>
|
||||
constexpr bool equal_(adaptor_sentinel<S, A> const & that, long) const
|
||||
{
|
||||
return that.data_.second().empty(this->data_.first(), that.data_.first());
|
||||
}
|
||||
template<typename S, typename A>
|
||||
constexpr auto equal(adaptor_sentinel<S, A> const & that) const
|
||||
-> decltype(std::declval<adaptor_cursor const &>().equal_(that, 42))
|
||||
{
|
||||
return this->equal_(that, 42);
|
||||
}
|
||||
template<typename A = Adapt, typename = decltype(std::declval<A &>().prev(
|
||||
std::declval<BaseIter &>()))>
|
||||
void prev()
|
||||
{
|
||||
this->data_.second().prev(this->data_.first());
|
||||
}
|
||||
template<typename A = Adapt, typename = decltype(std::declval<A &>().advance(
|
||||
std::declval<BaseIter &>(), 0))>
|
||||
void advance(iter_difference_t<BaseIter> n)
|
||||
{
|
||||
this->data_.second().advance(this->data_.first(), n);
|
||||
}
|
||||
template<typename A = Adapt,
|
||||
typename R = decltype(std::declval<A const &>().distance_to(
|
||||
std::declval<BaseIter const &>(), std::declval<BaseIter const &>(),
|
||||
std::declval<A const &>()))>
|
||||
R distance_to_(adaptor_cursor const & that, int) const
|
||||
{
|
||||
return this->data_.second().distance_to(
|
||||
this->data_.first(), that.data_.first(), that.data_.second());
|
||||
}
|
||||
template<typename A = Adapt,
|
||||
typename R = decltype(std::declval<A const &>().distance_to(
|
||||
std::declval<BaseIter const &>(), std::declval<BaseIter const &>()))>
|
||||
R distance_to_(adaptor_cursor const & that, long) const
|
||||
{
|
||||
return this->data_.second().distance_to(this->data_.first(),
|
||||
that.data_.first());
|
||||
}
|
||||
template<typename C = adaptor_cursor>
|
||||
auto distance_to(adaptor_cursor const & that) const
|
||||
-> decltype(std::declval<C const &>().distance_to_(that, 42))
|
||||
{
|
||||
return this->distance_to_(that, 42);
|
||||
}
|
||||
// If the adaptor has an iter_move function, use it.
|
||||
template<typename A = Adapt,
|
||||
typename X = decltype(std::declval<A const &>().iter_move(
|
||||
std::declval<BaseIter const &>()))>
|
||||
X iter_move_(int) const noexcept(noexcept(
|
||||
std::declval<A const &>().iter_move(std::declval<BaseIter const &>())))
|
||||
{
|
||||
using V = range_access::cursor_value_t<adaptor_cursor>;
|
||||
using R = decltype(this->data_.second().read(this->data_.first()));
|
||||
static_assert(
|
||||
common_reference_with<X &&, V const &>,
|
||||
"In your adaptor, the result of your iter_move member function does "
|
||||
"not share a common reference with your value type.");
|
||||
static_assert(
|
||||
common_reference_with<R &&, X &&>,
|
||||
"In your adaptor, the result of your iter_move member function does "
|
||||
"not share a common reference with the result of your read member "
|
||||
"function.");
|
||||
return this->data_.second().iter_move(this->data_.first());
|
||||
}
|
||||
// If there is no iter_move member and the adaptor has not overridden the read
|
||||
// member function, then dispatch to the base iterator's iter_move function.
|
||||
template<typename A = Adapt,
|
||||
typename R = decltype(std::declval<A const &>().read(
|
||||
std::declval<BaseIter const &>(),
|
||||
detail::adaptor_base_current_mem_fn{})),
|
||||
typename X = iter_rvalue_reference_t<BaseIter>>
|
||||
X iter_move_(long) const
|
||||
noexcept(noexcept(X(ranges::iter_move(std::declval<BaseIter const &>()))))
|
||||
{
|
||||
return ranges::iter_move(this->data_.first());
|
||||
}
|
||||
// If the adaptor does not have an iter_move function but overrides the read
|
||||
// member function, apply std::move to the result of calling read.
|
||||
template<typename A = Adapt,
|
||||
typename R = decltype(
|
||||
std::declval<A const &>().read(std::declval<BaseIter const &>())),
|
||||
typename X = aux::move_t<R>>
|
||||
X iter_move_(detail::ignore_t) const noexcept(noexcept(X(static_cast<X &&>(
|
||||
std::declval<A const &>().read(std::declval<BaseIter const &>())))))
|
||||
{
|
||||
using V = range_access::cursor_value_t<adaptor_cursor>;
|
||||
static_assert(
|
||||
common_reference_with<X &&, V const &>,
|
||||
"In your adaptor, you've specified a value type that does not share a "
|
||||
"common "
|
||||
"reference type with the result of moving the result of the read member "
|
||||
"function. Consider defining an iter_move function in your adaptor.");
|
||||
return static_cast<X &&>(this->data_.second().read(this->data_.first()));
|
||||
}
|
||||
// Gives users a way to override the default iter_move function in their adaptors.
|
||||
auto move() const
|
||||
noexcept(noexcept(std::declval<const adaptor_cursor &>().iter_move_(42)))
|
||||
-> decltype(std::declval<const adaptor_cursor &>().iter_move_(42))
|
||||
{
|
||||
return iter_move_(42);
|
||||
}
|
||||
|
||||
public:
|
||||
adaptor_cursor() = default;
|
||||
adaptor_cursor(BaseIter iter, Adapt adapt)
|
||||
: base_t{{std::move(iter), std::move(adapt)}}
|
||||
{}
|
||||
template(typename OtherIter, typename OtherAdapt)(
|
||||
requires //
|
||||
(!same_as<adaptor_cursor<OtherIter, OtherAdapt>, adaptor_cursor>) AND
|
||||
convertible_to<OtherIter, BaseIter> AND
|
||||
convertible_to<OtherAdapt, Adapt>)
|
||||
adaptor_cursor(adaptor_cursor<OtherIter, OtherAdapt> that)
|
||||
: base_t{{std::move(that.data_.first()), std::move(that.data_.second())}}
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename D>
|
||||
using adaptor_cursor_t =
|
||||
adaptor_cursor<detail::adapted_iterator_t<D>, detail::begin_adaptor_t<D>>;
|
||||
|
||||
template<typename D>
|
||||
using adaptor_sentinel_t = meta::if_c<
|
||||
same_as<detail::adapted_iterator_t<D>, detail::adapted_sentinel_t<D>> &&
|
||||
same_as<detail::begin_adaptor_t<D>, detail::end_adaptor_t<D>>,
|
||||
adaptor_cursor_t<D>,
|
||||
adaptor_sentinel<detail::adapted_sentinel_t<D>, detail::end_adaptor_t<D>>>;
|
||||
|
||||
template<typename Derived, typename BaseRng,
|
||||
cardinality Cardinality /*= range_cardinality<BaseRng>::value*/>
|
||||
struct view_adaptor : view_facade<Derived, Cardinality>
|
||||
{
|
||||
private:
|
||||
friend Derived;
|
||||
friend range_access;
|
||||
friend adaptor_base;
|
||||
CPP_assert(viewable_range<BaseRng>);
|
||||
using base_range_t = views::all_t<BaseRng>;
|
||||
using view_facade<Derived, Cardinality>::derived;
|
||||
|
||||
base_range_t rng_;
|
||||
|
||||
constexpr adaptor_base begin_adaptor() const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
constexpr adaptor_base end_adaptor() const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
static constexpr adaptor_cursor_t<D> begin_cursor_(D & d) noexcept(noexcept(
|
||||
adaptor_cursor_t<D>{std::declval<detail::begin_adaptor_t<D> &>().begin(d),
|
||||
range_access::begin_adaptor(d)}))
|
||||
{
|
||||
auto adapt = range_access::begin_adaptor(d);
|
||||
auto pos = adapt.begin(d);
|
||||
return {std::move(pos), std::move(adapt)};
|
||||
}
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived>)
|
||||
constexpr auto begin_cursor() noexcept(
|
||||
noexcept(view_adaptor::begin_cursor_(std::declval<D &>())))
|
||||
-> decltype(view_adaptor::begin_cursor_(std::declval<D &>()))
|
||||
{
|
||||
return view_adaptor::begin_cursor_(derived());
|
||||
}
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived> AND range<base_range_t const>)
|
||||
constexpr auto begin_cursor() const
|
||||
noexcept(noexcept(view_adaptor::begin_cursor_(std::declval<D const &>())))
|
||||
-> decltype(view_adaptor::begin_cursor_(std::declval<D const &>()))
|
||||
{
|
||||
return view_adaptor::begin_cursor_(derived());
|
||||
}
|
||||
|
||||
template<typename D>
|
||||
static constexpr adaptor_sentinel_t<D> end_cursor_(D & d) noexcept(noexcept(
|
||||
adaptor_sentinel_t<D>{std::declval<detail::end_adaptor_t<D> &>().end(d),
|
||||
range_access::end_adaptor(d)}))
|
||||
{
|
||||
auto adapt = range_access::end_adaptor(d);
|
||||
auto pos = adapt.end(d);
|
||||
return {std::move(pos), std::move(adapt)};
|
||||
}
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived>)
|
||||
constexpr auto end_cursor() noexcept(
|
||||
noexcept(view_adaptor::end_cursor_(std::declval<D &>())))
|
||||
-> decltype(view_adaptor::end_cursor_(std::declval<D &>()))
|
||||
{
|
||||
return view_adaptor::end_cursor_(derived());
|
||||
}
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived> AND range<base_range_t const>)
|
||||
constexpr auto end_cursor() const noexcept(
|
||||
noexcept(view_adaptor::end_cursor_(std::declval<D const &>())))
|
||||
-> decltype(view_adaptor::end_cursor_(std::declval<D const &>()))
|
||||
{
|
||||
return view_adaptor::end_cursor_(derived());
|
||||
}
|
||||
|
||||
protected:
|
||||
~view_adaptor() = default;
|
||||
|
||||
public:
|
||||
view_adaptor() = default;
|
||||
view_adaptor(view_adaptor &&) = default;
|
||||
view_adaptor(view_adaptor const &) = default;
|
||||
view_adaptor & operator=(view_adaptor &&) = default;
|
||||
view_adaptor & operator=(view_adaptor const &) = default;
|
||||
constexpr explicit view_adaptor(BaseRng && rng)
|
||||
: rng_(views::all(static_cast<BaseRng &&>(rng)))
|
||||
{}
|
||||
constexpr base_range_t & base() noexcept
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
/// \overload
|
||||
constexpr base_range_t const & base() const noexcept
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
65
Telegram/ThirdParty/range-v3/include/range/v3/view/addressof.hpp
vendored
Normal file
65
Telegram/ThirdParty/range-v3/include/range/v3/view/addressof.hpp
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Andrey Diduh 2019
|
||||
//
|
||||
// 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_ADDRESSOF_HPP
|
||||
#define RANGES_V3_VIEW_ADDRESSOF_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/utility/addressof.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
struct addressof_fn
|
||||
{
|
||||
private:
|
||||
struct take_address
|
||||
{
|
||||
template<typename V>
|
||||
constexpr V * operator()(V & value) const noexcept
|
||||
{
|
||||
return detail::addressof(value);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
std::is_lvalue_reference<range_reference_t<Rng>>::value) //
|
||||
constexpr auto CPP_auto_fun(operator())(Rng && rng)(const) //
|
||||
(
|
||||
return transform(all(static_cast<Rng &&>(rng)), take_address{}) //
|
||||
)
|
||||
};
|
||||
|
||||
/// \relates addressof_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<addressof_fn>, addressof)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_VIEW_ADDRESSOF_HPP
|
||||
189
Telegram/ThirdParty/range-v3/include/range/v3/view/adjacent_filter.hpp
vendored
Normal file
189
Telegram/ThirdParty/range-v3/include/range/v3/view/adjacent_filter.hpp
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_ADJACENT_FILTER_HPP
|
||||
#define RANGES_V3_VIEW_ADJACENT_FILTER_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/adjacent_find.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// clang-format off
|
||||
/// \concept adjacent_filter_constraints_
|
||||
/// \brief The \c adjacent_filter_constraints_ concept
|
||||
template(typename Rng, typename Pred)(
|
||||
concept (adjacent_filter_constraints_)(Rng, Pred),
|
||||
indirect_binary_predicate_<Pred, iterator_t<Rng>, iterator_t<Rng>>
|
||||
);
|
||||
/// \concept adjacent_filter_constraints
|
||||
/// \brief The \c adjacent_filter_constraints concept
|
||||
template<typename Rng, typename Pred>
|
||||
CPP_concept adjacent_filter_constraints =
|
||||
viewable_range<Rng> && forward_range<Rng> &&
|
||||
CPP_concept_ref(detail::adjacent_filter_constraints_, Rng, Pred);
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Pred>
|
||||
struct RANGES_EMPTY_BASES adjacent_filter_view
|
||||
: view_adaptor<adjacent_filter_view<Rng, Pred>, Rng,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
, private box<semiregular_box_t<Pred>, adjacent_filter_view<Rng, Pred>>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
template<bool Const>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
friend struct adaptor<!Const>;
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
using Parent = meta::const_if_c<Const, adjacent_filter_view>;
|
||||
Parent * rng_;
|
||||
|
||||
public:
|
||||
adaptor() = default;
|
||||
constexpr adaptor(Parent * rng) noexcept
|
||||
: rng_(rng)
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const && CPP_NOT(Other)) //
|
||||
constexpr adaptor(adaptor<Other> that)
|
||||
: rng_(that.rng_)
|
||||
{}
|
||||
constexpr void next(iterator_t<CRng> & it) const
|
||||
{
|
||||
auto const last = ranges::end(rng_->base());
|
||||
auto & pred = rng_->adjacent_filter_view::box::get();
|
||||
RANGES_EXPECT(it != last);
|
||||
for(auto tmp = it; ++it != last; tmp = it)
|
||||
if(invoke(pred, *tmp, *it))
|
||||
break;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto prev(iterator_t<CRng> & it) const //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<CRng>)
|
||||
{
|
||||
auto const first = ranges::begin(rng_->base());
|
||||
auto & pred = rng_->adjacent_filter_view::box::get();
|
||||
RANGES_EXPECT(it != first);
|
||||
--it;
|
||||
while(it != first)
|
||||
{
|
||||
auto tmp = it;
|
||||
if(invoke(pred, *--tmp, *it))
|
||||
break;
|
||||
it = tmp;
|
||||
}
|
||||
}
|
||||
void distance_to() = delete;
|
||||
};
|
||||
constexpr adaptor<false> begin_adaptor() noexcept
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto begin_adaptor() const noexcept //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires detail::adjacent_filter_constraints<Rng const, Pred const>)
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
constexpr adaptor<false> end_adaptor() noexcept
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() const noexcept //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires detail::adjacent_filter_constraints<Rng const, Pred const>)
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
|
||||
public:
|
||||
adjacent_filter_view() = default;
|
||||
constexpr adjacent_filter_view(Rng rng, Pred pred)
|
||||
: adjacent_filter_view::view_adaptor{detail::move(rng)}
|
||||
, adjacent_filter_view::box(detail::move(pred))
|
||||
{}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Rng>)
|
||||
adjacent_filter_view(Rng &&, Fun)
|
||||
->adjacent_filter_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct adjacent_filter_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires detail::adjacent_filter_constraints<Rng, Pred>)
|
||||
constexpr adjacent_filter_view<all_t<Rng>, Pred> //
|
||||
operator()(Rng && rng, Pred pred) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(pred)};
|
||||
}
|
||||
};
|
||||
|
||||
struct adjacent_filter_fn : adjacent_filter_base_fn
|
||||
{
|
||||
using adjacent_filter_base_fn::operator();
|
||||
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(adjacent_filter_base_fn{}, std::move(pred)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates adjacent_filter_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(adjacent_filter_fn, adjacent_filter)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::adjacent_filter_view)
|
||||
|
||||
#endif
|
||||
186
Telegram/ThirdParty/range-v3/include/range/v3/view/adjacent_remove_if.hpp
vendored
Normal file
186
Telegram/ThirdParty/range-v3/include/range/v3/view/adjacent_remove_if.hpp
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_ADJACENT_REMOVE_IF_HPP
|
||||
#define RANGES_V3_VIEW_ADJACENT_REMOVE_IF_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/utility/box.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Pred>
|
||||
struct RANGES_EMPTY_BASES adjacent_remove_if_view
|
||||
: view_adaptor<adjacent_remove_if_view<Rng, Pred>, Rng,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
, private box<semiregular_box_t<Pred>, adjacent_remove_if_view<Rng, Pred>>
|
||||
{
|
||||
adjacent_remove_if_view() = default;
|
||||
constexpr adjacent_remove_if_view(Rng rng, Pred pred)
|
||||
: adjacent_remove_if_view::view_adaptor{detail::move(rng)}
|
||||
, adjacent_remove_if_view::box(detail::move(pred))
|
||||
{}
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
adjacent_remove_if_view * rng_;
|
||||
|
||||
public:
|
||||
adaptor() = default;
|
||||
constexpr adaptor(adjacent_remove_if_view * rng) noexcept
|
||||
: rng_(rng)
|
||||
{}
|
||||
static constexpr iterator_t<Rng> begin(adjacent_remove_if_view & rng)
|
||||
{
|
||||
return *rng.begin_;
|
||||
}
|
||||
constexpr void next(iterator_t<Rng> & it) const
|
||||
{
|
||||
RANGES_ASSERT(it != ranges::end(rng_->base()));
|
||||
rng_->satisfy_forward(++it);
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto prev(iterator_t<Rng> & it) const //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<Rng>)
|
||||
{
|
||||
rng_->satisfy_reverse(it);
|
||||
}
|
||||
void advance() = delete;
|
||||
void distance_to() = delete;
|
||||
};
|
||||
constexpr adaptor begin_adaptor()
|
||||
{
|
||||
cache_begin();
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() //
|
||||
-> CPP_ret(adaptor)(
|
||||
requires common_range<Rng>)
|
||||
{
|
||||
if(bidirectional_range<Rng>)
|
||||
cache_begin();
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() noexcept //
|
||||
-> CPP_ret(adaptor_base)(
|
||||
requires (!common_range<Rng>))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
constexpr void satisfy_forward(iterator_t<Rng> & it)
|
||||
{
|
||||
auto const last = ranges::end(this->base());
|
||||
if(it == last)
|
||||
return;
|
||||
auto & pred = this->adjacent_remove_if_view::box::get();
|
||||
for(auto nxt = it; ++nxt != last && invoke(pred, *it, *nxt); it = nxt)
|
||||
;
|
||||
}
|
||||
constexpr void satisfy_reverse(iterator_t<Rng> & it)
|
||||
{
|
||||
auto const & first = *begin_;
|
||||
RANGES_ASSERT(it != first);
|
||||
(void)first;
|
||||
auto prv = it;
|
||||
--it;
|
||||
if(prv == ranges::end(this->base()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto & pred = this->adjacent_remove_if_view::box::get();
|
||||
for(; invoke(pred, *it, *prv); prv = it, --it)
|
||||
RANGES_ASSERT(it != first);
|
||||
}
|
||||
|
||||
void cache_begin()
|
||||
{
|
||||
if(begin_)
|
||||
return;
|
||||
auto it = ranges::begin(this->base());
|
||||
satisfy_forward(it);
|
||||
begin_.emplace(std::move(it));
|
||||
}
|
||||
|
||||
detail::non_propagating_cache<iterator_t<Rng>> begin_;
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Rng>)
|
||||
adjacent_remove_if_view(Rng &&, Fun)
|
||||
-> adjacent_remove_if_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct adjacent_remove_if_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng> AND
|
||||
indirect_binary_predicate_<Pred, iterator_t<Rng>, iterator_t<Rng>>)
|
||||
constexpr adjacent_remove_if_view<all_t<Rng>, Pred> //
|
||||
operator()(Rng && rng, Pred pred) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(pred)};
|
||||
}
|
||||
};
|
||||
|
||||
struct adjacent_remove_if_fn : adjacent_remove_if_base_fn
|
||||
{
|
||||
using adjacent_remove_if_base_fn::operator();
|
||||
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(adjacent_remove_if_base_fn{}, std::move(pred)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates adjacent_remove_if_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(adjacent_remove_if_fn, adjacent_remove_if)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::adjacent_remove_if_view)
|
||||
|
||||
#endif
|
||||
126
Telegram/ThirdParty/range-v3/include/range/v3/view/all.hpp
vendored
Normal file
126
Telegram/ThirdParty/range-v3/include/range/v3/view/all.hpp
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_ALL_HPP
|
||||
#define RANGES_V3_VIEW_ALL_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/ref.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
struct all_fn
|
||||
{
|
||||
private:
|
||||
/// If it's a view already, pass it though.
|
||||
template<typename T>
|
||||
static constexpr auto from_range_(T && t, std::true_type, detail::ignore_t,
|
||||
detail::ignore_t)
|
||||
{
|
||||
return static_cast<T &&>(t);
|
||||
}
|
||||
|
||||
/// If it is container-like, turn it into a view, being careful
|
||||
/// to preserve the Sized-ness of the range.
|
||||
template<typename T>
|
||||
static constexpr auto from_range_(T && t, std::false_type, std::true_type,
|
||||
detail::ignore_t)
|
||||
{
|
||||
return ranges::views::ref(t);
|
||||
}
|
||||
|
||||
/// Not a view and not an lvalue? If it's a borrowed_range, then
|
||||
/// return a subrange holding the range's begin/end.
|
||||
template<typename T>
|
||||
static constexpr auto from_range_(T && t, std::false_type, std::false_type,
|
||||
std::true_type)
|
||||
{
|
||||
return make_subrange(static_cast<T &&>(t));
|
||||
}
|
||||
|
||||
public:
|
||||
template(typename T)(
|
||||
requires range<T &> AND viewable_range<T>)
|
||||
constexpr auto operator()(T && t) const
|
||||
{
|
||||
return all_fn::from_range_(static_cast<T &&>(t),
|
||||
meta::bool_<view_<uncvref_t<T>>>{},
|
||||
std::is_lvalue_reference<T>{},
|
||||
meta::bool_<borrowed_range<T>>{});
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
RANGES_DEPRECATED("Passing a reference_wrapper to views::all is deprecated.")
|
||||
constexpr ref_view<T> operator()(std::reference_wrapper<T> r) const
|
||||
{
|
||||
return ranges::views::ref(r.get());
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates all_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<all_fn>, all)
|
||||
|
||||
template<typename Rng>
|
||||
using all_t = decltype(all(std::declval<Rng>()));
|
||||
} // namespace views
|
||||
|
||||
template<typename Rng>
|
||||
struct identity_adaptor : Rng
|
||||
{
|
||||
CPP_assert(view_<Rng>);
|
||||
|
||||
identity_adaptor() = default;
|
||||
constexpr explicit identity_adaptor(Rng const & rng)
|
||||
: Rng(rng)
|
||||
{}
|
||||
constexpr explicit identity_adaptor(Rng && rng)
|
||||
: Rng(detail::move(rng))
|
||||
{}
|
||||
};
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::all;
|
||||
using ranges::views::all_t;
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng>)
|
||||
using all_view RANGES_DEPRECATED(
|
||||
"Please use ranges::cpp20::views::all_t instead.") =
|
||||
ranges::views::all_t<Rng>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
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
|
||||
22
Telegram/ThirdParty/range-v3/include/range/v3/view/bounded.hpp
vendored
Normal file
22
Telegram/ThirdParty/range-v3/include/range/v3/view/bounded.hpp
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_BOUNDED_HPP
|
||||
#define RANGES_V3_VIEW_BOUNDED_HPP
|
||||
|
||||
#include <range/v3/detail/config.hpp>
|
||||
RANGES_DEPRECATED_HEADER(
|
||||
"This header is deprecated. Please #include <range/v3/view/common.hpp> instead.")
|
||||
|
||||
#include <range/v3/view/common.hpp>
|
||||
|
||||
#endif
|
||||
94
Telegram/ThirdParty/range-v3/include/range/v3/view/c_str.hpp
vendored
Normal file
94
Telegram/ThirdParty/range-v3/include/range/v3/view/c_str.hpp
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_C_STR_HPP
|
||||
#define RANGES_V3_VIEW_C_STR_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/delimit.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
struct is_char_type_ : std::false_type
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct is_char_type_<char> : std::true_type
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct is_char_type_<wchar_t> : std::true_type
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct is_char_type_<char16_t> : std::true_type
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct is_char_type_<char32_t> : std::true_type
|
||||
{};
|
||||
|
||||
template<typename T>
|
||||
using is_char_type = is_char_type_<meta::_t<std::remove_cv<T>>>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
/// View a `\0`-terminated C string (e.g. from a const char*) as a
|
||||
/// range.
|
||||
struct c_str_fn
|
||||
{
|
||||
// Fixed-length
|
||||
template(typename Char, std::size_t N)(
|
||||
requires detail::is_char_type<Char>::value) //
|
||||
ranges::subrange<Char *> operator()(Char (&sz)[N]) const
|
||||
{
|
||||
return {&sz[0], &sz[N - 1]};
|
||||
}
|
||||
|
||||
// Null-terminated
|
||||
template(typename Char)(
|
||||
requires detail::is_char_type<Char>::value) //
|
||||
ranges::delimit_view<
|
||||
ranges::subrange<Char *, ranges::unreachable_sentinel_t>,
|
||||
meta::_t<std::remove_cv<Char>>> //
|
||||
operator()(Char * sz) const volatile
|
||||
{
|
||||
using ch_t = meta::_t<std::remove_cv<Char>>;
|
||||
return ranges::views::delimit(sz, ch_t(0));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates c_str_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(c_str_fn, c_str)
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
202
Telegram/ThirdParty/range-v3/include/range/v3/view/cache1.hpp
vendored
Normal file
202
Telegram/ThirdParty/range-v3/include/range/v3/view/cache1.hpp
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_CACHE1_HPP
|
||||
#define RANGES_V3_VIEW_CACHE1_HPP
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/detail/range_access.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct cache1_view : view_facade<cache1_view<Rng>, range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
CPP_assert(view_<Rng>);
|
||||
CPP_assert(input_range<Rng>);
|
||||
CPP_assert(constructible_from<range_value_t<Rng>, range_reference_t<Rng>>);
|
||||
friend range_access;
|
||||
Rng rng_;
|
||||
bool dirty_ = true;
|
||||
detail::non_propagating_cache<range_value_t<Rng>> cache_;
|
||||
|
||||
CPP_member
|
||||
auto update_(range_reference_t<Rng> && val) //
|
||||
-> CPP_ret(void)(
|
||||
requires assignable_from<range_value_t<Rng> &, range_reference_t<Rng>>)
|
||||
{
|
||||
if(!cache_)
|
||||
cache_.emplace(static_cast<range_reference_t<Rng> &&>(val));
|
||||
else
|
||||
*cache_ = static_cast<range_reference_t<Rng> &&>(val);
|
||||
}
|
||||
CPP_member
|
||||
auto update_(range_reference_t<Rng> && val) //
|
||||
-> CPP_ret(void)(
|
||||
requires (!assignable_from<range_value_t<Rng> &, range_reference_t<Rng>>))
|
||||
{
|
||||
cache_.emplace(static_cast<range_reference_t<Rng> &&>(val));
|
||||
}
|
||||
|
||||
struct cursor;
|
||||
|
||||
struct sentinel
|
||||
{
|
||||
private:
|
||||
friend cursor;
|
||||
sentinel_t<Rng> last_;
|
||||
|
||||
public:
|
||||
sentinel() = default;
|
||||
constexpr explicit sentinel(sentinel_t<Rng> last)
|
||||
: last_(std::move(last))
|
||||
{}
|
||||
};
|
||||
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
cache1_view * parent_;
|
||||
iterator_t<Rng> current_;
|
||||
|
||||
public:
|
||||
using value_type = range_value_t<Rng>;
|
||||
using single_pass = std::true_type;
|
||||
using difference_type = range_difference_t<Rng>;
|
||||
|
||||
cursor() = default;
|
||||
|
||||
constexpr explicit cursor(cache1_view * parent, iterator_t<Rng> current)
|
||||
: parent_(parent)
|
||||
, current_(std::move(current))
|
||||
{}
|
||||
range_value_t<Rng> && read() const
|
||||
{
|
||||
if(parent_->dirty_)
|
||||
{
|
||||
parent_->update_(*current_);
|
||||
parent_->dirty_ = false;
|
||||
}
|
||||
return std::move(*parent_->cache_);
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++current_;
|
||||
parent_->dirty_ = true;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return current_ == that.current_;
|
||||
}
|
||||
bool equal(sentinel const & that) const
|
||||
{
|
||||
return current_ == that.last_;
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(cursor const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires sized_sentinel_for<iterator_t<Rng>, iterator_t<Rng>>)
|
||||
{
|
||||
return that.current_ - current_;
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(sentinel const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>)
|
||||
{
|
||||
return that.last_ - current_;
|
||||
}
|
||||
};
|
||||
|
||||
cursor begin_cursor()
|
||||
{
|
||||
dirty_ = true;
|
||||
return cursor{this, ranges::begin(rng_)};
|
||||
}
|
||||
|
||||
cursor end_cursor_impl(std::true_type)
|
||||
{
|
||||
return cursor{this, ranges::end(rng_)};
|
||||
}
|
||||
sentinel end_cursor_impl(std::false_type)
|
||||
{
|
||||
return sentinel{ranges::end(rng_)};
|
||||
}
|
||||
auto end_cursor()
|
||||
{
|
||||
return end_cursor_impl(meta::bool_<(bool)common_range<Rng>>{});
|
||||
}
|
||||
|
||||
public:
|
||||
cache1_view() = default;
|
||||
constexpr explicit cache1_view(Rng rng)
|
||||
: rng_{std::move(rng)}
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(rng_);
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
cache1_view(Rng &&) //
|
||||
-> cache1_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct cache1_fn
|
||||
{
|
||||
/// \brief Caches the most recent element within the view so that
|
||||
/// dereferencing the view's iterator multiple times doesn't incur any
|
||||
/// recomputation. This can be useful in adaptor pipelines that include
|
||||
/// combinations of \c view::filter and \c view::transform, for instance.
|
||||
/// \note \c views::cache1 is always single-pass.
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
constructible_from<range_value_t<Rng>, range_reference_t<Rng>>)
|
||||
constexpr cache1_view<all_t<Rng>> operator()(Rng && rng) const //
|
||||
{
|
||||
return cache1_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates cache1_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<cache1_fn>, cache1)
|
||||
} // namespace views
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::cache1_view)
|
||||
|
||||
#endif
|
||||
508
Telegram/ThirdParty/range-v3/include/range/v3/view/cartesian_product.hpp
vendored
Normal file
508
Telegram/ThirdParty/range-v3/include/range/v3/view/cartesian_product.hpp
vendored
Normal file
@@ -0,0 +1,508 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-2014.
|
||||
// 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_CARTESIAN_PRODUCT_HPP
|
||||
#define RANGES_V3_VIEW_CARTESIAN_PRODUCT_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/utility/tuple_algorithm.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/empty.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/view.hpp> // for dereference_fn
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename State, typename Value>
|
||||
using product_cardinality = std::integral_constant<
|
||||
cardinality,
|
||||
State::value == 0 || Value::value == 0
|
||||
? static_cast<cardinality>(0)
|
||||
: State::value == unknown || Value::value == unknown
|
||||
? unknown
|
||||
: State::value == infinite || Value::value == infinite
|
||||
? infinite
|
||||
: State::value == finite || Value::value == finite
|
||||
? finite
|
||||
: static_cast<cardinality>(
|
||||
State::value * Value::value)>;
|
||||
|
||||
struct cartesian_size_fn
|
||||
{
|
||||
template(typename Size, typename Rng)(
|
||||
requires integer_like_<Size> AND sized_range<Rng> AND
|
||||
common_with<Size, range_size_t<Rng>>)
|
||||
common_type_t<Size, range_size_t<Rng>> operator()(Size s, Rng && rng) const
|
||||
{
|
||||
using S = common_type_t<Size, range_size_t<Rng>>;
|
||||
return static_cast<S>(s) * static_cast<S>(ranges::size(rng));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Views>
|
||||
using cartesian_product_cardinality =
|
||||
meta::fold<meta::list<range_cardinality<Views>...>,
|
||||
std::integral_constant<cardinality, static_cast<cardinality>(
|
||||
(sizeof...(Views) > 0))>,
|
||||
meta::quote<detail::product_cardinality>>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
// clang-format off
|
||||
/// \concept cartesian_produce_view_can_const
|
||||
/// \brief The \c cartesian_produce_view_can_const concept
|
||||
template<typename...Views>
|
||||
CPP_concept cartesian_produce_view_can_const =
|
||||
and_v<range<Views const>...>;
|
||||
|
||||
/// \concept cartesian_produce_view_can_size_
|
||||
/// \brief The \c cartesian_produce_view_can_size_ concept
|
||||
template(typename IsConst, typename... Views)(
|
||||
concept (cartesian_produce_view_can_size_)(IsConst, Views...),
|
||||
and_v<common_with<std::uintmax_t, range_size_t<meta::const_if<IsConst, Views>>>...>
|
||||
);
|
||||
/// \concept cartesian_produce_view_can_size
|
||||
/// \brief The \c cartesian_produce_view_can_size concept
|
||||
template<typename IsConst, typename...Views>
|
||||
CPP_concept cartesian_produce_view_can_size =
|
||||
and_v<sized_range<meta::const_if<IsConst, Views>>...> &&
|
||||
CPP_concept_ref(ranges::cartesian_produce_view_can_size_, IsConst, Views...);
|
||||
|
||||
/// \concept cartesian_produce_view_can_distance_
|
||||
/// \brief The \c cartesian_produce_view_can_distance_ concept
|
||||
template(typename IsConst, typename... Views)(
|
||||
concept (cartesian_produce_view_can_distance_)(IsConst, Views...),
|
||||
and_v<sized_sentinel_for<
|
||||
iterator_t<meta::const_if<IsConst, Views>>,
|
||||
iterator_t<meta::const_if<IsConst, Views>>>...>
|
||||
);
|
||||
/// \concept cartesian_produce_view_can_distance
|
||||
/// \brief The \c cartesian_produce_view_can_distance concept
|
||||
template<typename IsConst, typename...Views>
|
||||
CPP_concept cartesian_produce_view_can_distance =
|
||||
cartesian_produce_view_can_size<IsConst, Views...> &&
|
||||
CPP_concept_ref(ranges::cartesian_produce_view_can_distance_, IsConst, Views...);
|
||||
|
||||
/// \concept cartesian_produce_view_can_random_
|
||||
/// \brief The \c cartesian_produce_view_can_random_ concept
|
||||
template(typename IsConst, typename... Views)(
|
||||
concept (cartesian_produce_view_can_random_)(IsConst, Views...),
|
||||
and_v<random_access_iterator<iterator_t<meta::const_if<IsConst, Views>>>...>
|
||||
);
|
||||
/// \concept cartesian_produce_view_can_random
|
||||
/// \brief The \c cartesian_produce_view_can_random concept
|
||||
template<typename IsConst, typename...Views>
|
||||
CPP_concept cartesian_produce_view_can_random =
|
||||
cartesian_produce_view_can_distance<IsConst, Views...> &&
|
||||
CPP_concept_ref(ranges::cartesian_produce_view_can_random_, IsConst, Views...);
|
||||
|
||||
/// \concept cartesian_produce_view_can_bidi_
|
||||
/// \brief The \c cartesian_produce_view_can_bidi_ concept
|
||||
template(typename IsConst, typename... Views)(
|
||||
concept (cartesian_produce_view_can_bidi_)(IsConst, Views...),
|
||||
and_v<common_range<meta::const_if<IsConst, Views>>...,
|
||||
bidirectional_iterator<iterator_t<meta::const_if<IsConst, Views>>>...>
|
||||
);
|
||||
/// \concept cartesian_produce_view_can_bidi
|
||||
/// \brief The \c cartesian_produce_view_can_bidi concept
|
||||
template<typename IsConst, typename...Views>
|
||||
CPP_concept cartesian_produce_view_can_bidi =
|
||||
cartesian_produce_view_can_random<IsConst, Views...> ||
|
||||
CPP_concept_ref(ranges::cartesian_produce_view_can_bidi_, IsConst, Views...);
|
||||
// clang-format on
|
||||
|
||||
template<typename... Views>
|
||||
struct cartesian_product_view
|
||||
: view_facade<cartesian_product_view<Views...>,
|
||||
detail::cartesian_product_cardinality<Views...>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
CPP_assert(and_v<(forward_range<Views> && view_<Views>)...>);
|
||||
CPP_assert(sizeof...(Views) != 0);
|
||||
|
||||
static constexpr auto my_cardinality =
|
||||
detail::cartesian_product_cardinality<Views...>::value;
|
||||
|
||||
std::tuple<Views...> views_;
|
||||
|
||||
template<bool IsConst_>
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
using IsConst = meta::bool_<IsConst_>;
|
||||
friend cursor<true>;
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst_, T>;
|
||||
using difference_type =
|
||||
common_type_t<std::intmax_t, range_difference_t<Views>...>;
|
||||
|
||||
constify_if<cartesian_product_view> * view_;
|
||||
std::tuple<iterator_t<constify_if<Views>>...> its_;
|
||||
|
||||
void next_(meta::size_t<1>)
|
||||
{
|
||||
auto & v = std::get<0>(view_->views_);
|
||||
auto & i = std::get<0>(its_);
|
||||
auto const last = ranges::end(v);
|
||||
RANGES_EXPECT(i != last);
|
||||
++i;
|
||||
}
|
||||
template<std::size_t N>
|
||||
void next_(meta::size_t<N>)
|
||||
{
|
||||
auto & v = std::get<N - 1>(view_->views_);
|
||||
auto & i = std::get<N - 1>(its_);
|
||||
auto const last = ranges::end(v);
|
||||
RANGES_EXPECT(i != last);
|
||||
if(++i == last)
|
||||
{
|
||||
i = ranges::begin(v);
|
||||
next_(meta::size_t<N - 1>{});
|
||||
}
|
||||
}
|
||||
void prev_(meta::size_t<0>)
|
||||
{
|
||||
RANGES_EXPECT(false);
|
||||
}
|
||||
template<std::size_t N>
|
||||
void prev_(meta::size_t<N>)
|
||||
{
|
||||
auto & v = std::get<N - 1>(view_->views_);
|
||||
auto & i = std::get<N - 1>(its_);
|
||||
if(i == ranges::begin(v))
|
||||
{
|
||||
CPP_assert(cartesian_produce_view_can_bidi<IsConst, Views...>);
|
||||
// cartesian_produce_view_can_bidi<IsConst, Views...> implies this
|
||||
// advance call is O(1)
|
||||
ranges::advance(i, ranges::end(v));
|
||||
prev_(meta::size_t<N - 1>{});
|
||||
}
|
||||
--i;
|
||||
}
|
||||
bool equal_(cursor const &, meta::size_t<0>) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
template<std::size_t N>
|
||||
bool equal_(cursor const & that, meta::size_t<N>) const
|
||||
{
|
||||
return std::get<N - 1>(its_) == std::get<N - 1>(that.its_) &&
|
||||
equal_(that, meta::size_t<N - 1>{});
|
||||
}
|
||||
difference_type distance_(cursor const & that, meta::size_t<1>) const
|
||||
{
|
||||
return difference_type{std::get<0>(that.its_) - std::get<0>(its_)};
|
||||
}
|
||||
template<std::size_t N>
|
||||
difference_type distance_(cursor const & that, meta::size_t<N>) const
|
||||
{
|
||||
difference_type const d = distance_(that, meta::size_t<N - 1>{});
|
||||
auto const scale = ranges::distance(std::get<N - 1>(view_->views_));
|
||||
auto const increment = std::get<N - 1>(that.its_) - std::get<N - 1>(its_);
|
||||
return difference_type{d * scale + increment};
|
||||
}
|
||||
void advance_(meta::size_t<0>, difference_type)
|
||||
{
|
||||
RANGES_EXPECT(false);
|
||||
}
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_DIVIDE_BY_ZERO
|
||||
template<std::size_t N>
|
||||
void advance_(meta::size_t<N>, difference_type n)
|
||||
{
|
||||
if(n == 0)
|
||||
return;
|
||||
|
||||
auto & i = std::get<N - 1>(its_);
|
||||
auto const my_size = static_cast<difference_type>(
|
||||
ranges::size(std::get<N - 1>(view_->views_)));
|
||||
auto const first = ranges::begin(std::get<N - 1>(view_->views_));
|
||||
|
||||
auto const idx = static_cast<difference_type>(i - first);
|
||||
RANGES_EXPECT(0 <= idx);
|
||||
RANGES_EXPECT(idx < my_size || (N == 1 && idx == my_size && n < 0));
|
||||
RANGES_EXPECT(n < INTMAX_MAX - idx);
|
||||
n += idx;
|
||||
|
||||
auto n_div = n / my_size;
|
||||
auto n_mod = n % my_size;
|
||||
|
||||
if(RANGES_CONSTEXPR_IF(N != 1))
|
||||
{
|
||||
if(n_mod < 0)
|
||||
{
|
||||
n_mod += my_size;
|
||||
--n_div;
|
||||
}
|
||||
advance_(meta::size_t<N - 1>{}, n_div);
|
||||
}
|
||||
RANGES_EXPECT(0 <= n_mod && n_mod < my_size);
|
||||
|
||||
if(RANGES_CONSTEXPR_IF(N == 1))
|
||||
{
|
||||
if(n_div > 0)
|
||||
{
|
||||
RANGES_EXPECT(n_div == 1);
|
||||
RANGES_EXPECT(n_mod == 0);
|
||||
n_mod = my_size;
|
||||
}
|
||||
else if(n_div < 0)
|
||||
{
|
||||
RANGES_EXPECT(n_div == -1);
|
||||
RANGES_EXPECT(n_mod == 0);
|
||||
}
|
||||
}
|
||||
|
||||
using D = iter_difference_t<decltype(first)>;
|
||||
i = first + static_cast<D>(n_mod);
|
||||
}
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
void check_at_end_(meta::size_t<1>, bool at_end = false)
|
||||
{
|
||||
if(at_end)
|
||||
ranges::advance(std::get<0>(its_),
|
||||
ranges::end(std::get<0>(view_->views_)));
|
||||
}
|
||||
template<std::size_t N>
|
||||
void check_at_end_(meta::size_t<N>, bool at_end = false)
|
||||
{
|
||||
return check_at_end_(
|
||||
meta::size_t<N - 1>{},
|
||||
at_end || bool(std::get<N - 1>(its_) ==
|
||||
ranges::end(std::get<N - 1>(view_->views_))));
|
||||
}
|
||||
cursor(end_tag, constify_if<cartesian_product_view> * view,
|
||||
std::true_type) // common_with
|
||||
: cursor(begin_tag{}, view)
|
||||
{
|
||||
CPP_assert(
|
||||
common_range<meta::at_c<meta::list<constify_if<Views>...>, 0>>);
|
||||
std::get<0>(its_) = ranges::end(std::get<0>(view->views_));
|
||||
}
|
||||
cursor(end_tag, constify_if<cartesian_product_view> * view,
|
||||
std::false_type) // !common_with
|
||||
: cursor(begin_tag{}, view)
|
||||
{
|
||||
using View0 = meta::at_c<meta::list<constify_if<Views>...>, 0>;
|
||||
CPP_assert(!common_range<View0> && random_access_range<View0> &&
|
||||
sized_range<View0>);
|
||||
std::get<0>(its_) += ranges::distance(std::get<0>(view->views_));
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = std::tuple<range_value_t<Views>...>;
|
||||
|
||||
cursor() = default;
|
||||
explicit cursor(begin_tag, constify_if<cartesian_product_view> * view)
|
||||
: view_(view)
|
||||
, its_(tuple_transform(view->views_, ranges::begin))
|
||||
{
|
||||
// If any of the constituent views is empty, the cartesian_product is
|
||||
// empty and this "begin" iterator needs to become an "end" iterator.
|
||||
check_at_end_(meta::size_t<sizeof...(Views)>{});
|
||||
}
|
||||
explicit cursor(end_tag, constify_if<cartesian_product_view> * view)
|
||||
: cursor(
|
||||
end_tag{}, view,
|
||||
meta::bool_<
|
||||
common_range<meta::at_c<meta::list<constify_if<Views>...>, 0>>>{})
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires IsConst_ AND CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: view_(that.view_)
|
||||
, its_(std::move(that.its_))
|
||||
{}
|
||||
common_tuple<range_reference_t<constify_if<Views>>...> read() const
|
||||
{
|
||||
return tuple_transform(its_, detail::dereference_fn{});
|
||||
}
|
||||
void next()
|
||||
{
|
||||
next_(meta::size_t<sizeof...(Views)>{});
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return std::get<0>(its_) == ranges::end(std::get<0>(view_->views_));
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return equal_(that, meta::size_t<sizeof...(Views)>{});
|
||||
}
|
||||
CPP_member
|
||||
auto prev() -> CPP_ret(void)(
|
||||
requires cartesian_produce_view_can_bidi<IsConst, Views...>)
|
||||
{
|
||||
prev_(meta::size_t<sizeof...(Views)>{});
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(distance_to)(cursor const & that)(
|
||||
const requires cartesian_produce_view_can_distance<IsConst, Views...>)
|
||||
{
|
||||
return distance_(that, meta::size_t<sizeof...(Views)>{});
|
||||
}
|
||||
CPP_member
|
||||
auto advance(difference_type n) //
|
||||
-> CPP_ret(void)(
|
||||
requires cartesian_produce_view_can_random<IsConst, Views...>)
|
||||
{
|
||||
advance_(meta::size_t<sizeof...(Views)>{}, n);
|
||||
}
|
||||
};
|
||||
cursor<false> begin_cursor()
|
||||
{
|
||||
return cursor<false>{begin_tag{}, this};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_cursor() const //
|
||||
-> CPP_ret(cursor<true>)(
|
||||
requires cartesian_produce_view_can_const<Views...>)
|
||||
{
|
||||
return cursor<true>{begin_tag{}, this};
|
||||
}
|
||||
CPP_member
|
||||
auto end_cursor() //
|
||||
-> CPP_ret(cursor<false>)(
|
||||
requires cartesian_produce_view_can_bidi<std::false_type, Views...>)
|
||||
{
|
||||
return cursor<false>{end_tag{}, this};
|
||||
}
|
||||
CPP_member
|
||||
auto end_cursor() const //
|
||||
-> CPP_ret(cursor<true>)(
|
||||
requires cartesian_produce_view_can_bidi<std::true_type, Views...>)
|
||||
{
|
||||
return cursor<true>{end_tag{}, this};
|
||||
}
|
||||
CPP_member
|
||||
auto end_cursor() const //
|
||||
-> CPP_ret(default_sentinel_t)(
|
||||
requires (!cartesian_produce_view_can_bidi<std::true_type, Views...>))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
cartesian_product_view() = default;
|
||||
constexpr explicit cartesian_product_view(Views... views)
|
||||
: views_{detail::move(views)...}
|
||||
{}
|
||||
template(typename...)(
|
||||
requires (my_cardinality >= 0)) //
|
||||
static constexpr std::size_t size() noexcept
|
||||
{
|
||||
return std::size_t{my_cardinality};
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires (my_cardinality < 0) &&
|
||||
cartesian_produce_view_can_size<std::true_type, Views...>)
|
||||
{
|
||||
return tuple_foldl(views_, std::uintmax_t{1}, detail::cartesian_size_fn{});
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires (my_cardinality < 0) &&
|
||||
cartesian_produce_view_can_size<std::false_type, Views...>)
|
||||
{
|
||||
return tuple_foldl(views_, std::uintmax_t{1}, detail::cartesian_size_fn{});
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename... Rng>
|
||||
cartesian_product_view(Rng &&...) //
|
||||
-> cartesian_product_view<views::all_t<Rng>...>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct cartesian_product_fn
|
||||
{
|
||||
constexpr empty_view<std::tuple<>> operator()() const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
template(typename... Rngs)(
|
||||
requires (sizeof...(Rngs) != 0) AND
|
||||
concepts::and_v<(forward_range<Rngs> && viewable_range<Rngs>)...>)
|
||||
constexpr cartesian_product_view<all_t<Rngs>...> operator()(Rngs &&... rngs)
|
||||
const
|
||||
{
|
||||
return cartesian_product_view<all_t<Rngs>...>{
|
||||
all(static_cast<Rngs &&>(rngs))...};
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
template(typename Rng0)(
|
||||
requires forward_range<Rng0> AND viewable_range<Rng0>)
|
||||
constexpr cartesian_product_view<all_t<Rng0>> operator()(Rng0 && rng0) const
|
||||
{
|
||||
return cartesian_product_view<all_t<Rng0>>{
|
||||
all(static_cast<Rng0 &&>(rng0))};
|
||||
}
|
||||
template(typename Rng0, typename Rng1)(
|
||||
requires forward_range<Rng0> AND viewable_range<Rng0> AND
|
||||
forward_range<Rng1> AND viewable_range<Rng1>)
|
||||
constexpr cartesian_product_view<all_t<Rng0>, all_t<Rng1>> //
|
||||
operator()(Rng0 && rng0, Rng1 && rng1) const
|
||||
{
|
||||
return cartesian_product_view<all_t<Rng0>, all_t<Rng1>>{
|
||||
all(static_cast<Rng0 &&>(rng0)), //
|
||||
all(static_cast<Rng1 &&>(rng1))};
|
||||
}
|
||||
template(typename Rng0, typename Rng1, typename Rng2)(
|
||||
requires forward_range<Rng0> AND viewable_range<Rng0> AND
|
||||
forward_range<Rng1> AND viewable_range<Rng1> AND
|
||||
forward_range<Rng2> AND viewable_range<Rng2>)
|
||||
constexpr cartesian_product_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>> //
|
||||
operator()(Rng0 && rng0, Rng1 && rng1, Rng2 && rng2) const
|
||||
{
|
||||
return cartesian_product_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>>{
|
||||
all(static_cast<Rng0 &&>(rng0)), //
|
||||
all(static_cast<Rng1 &&>(rng1)), //
|
||||
all(static_cast<Rng2 &&>(rng2))};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
RANGES_INLINE_VARIABLE(cartesian_product_fn, cartesian_product)
|
||||
} // namespace views
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
463
Telegram/ThirdParty/range-v3/include/range/v3/view/chunk.hpp
vendored
Normal file
463
Telegram/ThirdParty/range-v3/include/range/v3/view/chunk.hpp
vendored
Normal file
@@ -0,0 +1,463 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_CHUNK_HPP
|
||||
#define RANGES_V3_VIEW_CHUNK_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/box.hpp>
|
||||
#include <range/v3/utility/optional.hpp> // for non_propagating_cache
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/take.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Rng, bool Const>
|
||||
constexpr bool can_sized_sentinel_() noexcept
|
||||
{
|
||||
using I = iterator_t<meta::const_if_c<Const, Rng>>;
|
||||
return (bool)sized_sentinel_for<I, I>;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
struct zero
|
||||
{
|
||||
zero() = default;
|
||||
constexpr explicit zero(T const &) noexcept
|
||||
{}
|
||||
constexpr zero & operator=(T const &) noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
constexpr zero const & operator=(T const &) const noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
constexpr operator T() const
|
||||
{
|
||||
return T(0);
|
||||
}
|
||||
constexpr T exchange(T const &) const
|
||||
{
|
||||
return T(0);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, bool IsForwardRange>
|
||||
struct chunk_view_
|
||||
: view_adaptor<chunk_view_<Rng, IsForwardRange>, Rng,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
CPP_assert(forward_range<Rng>);
|
||||
|
||||
template<bool Const>
|
||||
using offset_t =
|
||||
meta::if_c<bidirectional_range<meta::const_if_c<Const, Rng>> ||
|
||||
detail::can_sized_sentinel_<Rng, Const>(),
|
||||
range_difference_t<Rng>, detail::zero<range_difference_t<Rng>>>;
|
||||
|
||||
range_difference_t<Rng> n_ = 0;
|
||||
|
||||
template<bool Const>
|
||||
struct RANGES_EMPTY_BASES adaptor
|
||||
: adaptor_base
|
||||
, private box<offset_t<Const>>
|
||||
{
|
||||
private:
|
||||
friend adaptor<!Const>;
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
|
||||
range_difference_t<CRng> n_;
|
||||
sentinel_t<CRng> end_;
|
||||
|
||||
constexpr offset_t<Const> const & offset() const
|
||||
{
|
||||
offset_t<Const> const & result = this->box<offset_t<Const>>::get();
|
||||
RANGES_EXPECT(0 <= result && result < n_);
|
||||
return result;
|
||||
}
|
||||
constexpr offset_t<Const> & offset()
|
||||
{
|
||||
return const_cast<offset_t<Const> &>(
|
||||
const_cast<adaptor const &>(*this).offset());
|
||||
}
|
||||
|
||||
public:
|
||||
adaptor() = default;
|
||||
constexpr adaptor(meta::const_if_c<Const, chunk_view_> * cv)
|
||||
: box<offset_t<Const>>{0}
|
||||
, n_((RANGES_EXPECT(0 < cv->n_), cv->n_))
|
||||
, end_(ranges::end(cv->base()))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
constexpr adaptor(adaptor<Other> that)
|
||||
: box<offset_t<Const>>(that.offset())
|
||||
, n_(that.n_)
|
||||
, end_(that.end_)
|
||||
{}
|
||||
constexpr auto read(iterator_t<CRng> const & it) const
|
||||
-> decltype(views::take(make_subrange(it, end_), n_))
|
||||
{
|
||||
RANGES_EXPECT(it != end_);
|
||||
RANGES_EXPECT(0 == offset());
|
||||
return views::take(make_subrange(it, end_), n_);
|
||||
}
|
||||
constexpr void next(iterator_t<CRng> & it)
|
||||
{
|
||||
RANGES_EXPECT(it != end_);
|
||||
RANGES_EXPECT(0 == offset());
|
||||
offset() = ranges::advance(it, n_, end_);
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto prev(iterator_t<CRng> & it) //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<CRng>)
|
||||
{
|
||||
ranges::advance(it, -n_ + offset());
|
||||
offset() = 0;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto distance_to(iterator_t<CRng> const & here,
|
||||
iterator_t<CRng> const & there,
|
||||
adaptor const & that) const
|
||||
-> CPP_ret(range_difference_t<Rng>)(
|
||||
requires (detail::can_sized_sentinel_<Rng, Const>()))
|
||||
{
|
||||
auto const delta = (there - here) + (that.offset() - offset());
|
||||
// This can fail for cyclic base ranges when the chunk size does not
|
||||
// divide the cycle length. Such iterator pairs are NOT in the domain of
|
||||
// -.
|
||||
RANGES_ENSURE(0 == delta % n_);
|
||||
return delta / n_;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto advance(iterator_t<CRng> & it, range_difference_t<Rng> n) //
|
||||
-> CPP_ret(void)(
|
||||
requires random_access_range<CRng>)
|
||||
{
|
||||
using Limits = std::numeric_limits<range_difference_t<CRng>>;
|
||||
if(0 < n)
|
||||
{
|
||||
RANGES_EXPECT(0 == offset());
|
||||
RANGES_EXPECT(n <= Limits::max() / n_);
|
||||
auto const remainder = ranges::advance(it, n * n_, end_) % n_;
|
||||
RANGES_EXPECT(0 <= remainder && remainder < n_);
|
||||
offset() = remainder;
|
||||
}
|
||||
else if(0 > n)
|
||||
{
|
||||
RANGES_EXPECT(n >= Limits::min() / n_);
|
||||
ranges::advance(it, n * n_ + offset());
|
||||
offset() = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
constexpr adaptor<simple_view<Rng>()> begin_adaptor()
|
||||
{
|
||||
return adaptor<simple_view<Rng>()>{this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto begin_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires forward_range<Rng const>)
|
||||
{
|
||||
return adaptor<true>{this};
|
||||
}
|
||||
template<typename Size>
|
||||
constexpr Size size_(Size base_size) const
|
||||
{
|
||||
auto const n = static_cast<Size>(n_);
|
||||
return base_size / n + (0 != (base_size % n));
|
||||
}
|
||||
|
||||
public:
|
||||
chunk_view_() = default;
|
||||
constexpr chunk_view_(Rng rng, range_difference_t<Rng> n)
|
||||
: chunk_view_::view_adaptor(detail::move(rng))
|
||||
, n_((RANGES_EXPECT(0 < n), n))
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return size_(ranges::size(this->base()));
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return size_(ranges::size(this->base()));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct chunk_view_<Rng, false>
|
||||
: view_facade<chunk_view_<Rng, false>,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
CPP_assert(input_range<Rng> && !forward_range<Rng>);
|
||||
|
||||
using iter_cache_t = detail::non_propagating_cache<iterator_t<Rng>>;
|
||||
|
||||
Rng base_;
|
||||
range_difference_t<Rng> n_;
|
||||
range_difference_t<Rng> remainder_;
|
||||
mutable iter_cache_t it_cache_;
|
||||
|
||||
constexpr iterator_t<Rng> & it() noexcept
|
||||
{
|
||||
return *it_cache_;
|
||||
}
|
||||
constexpr iterator_t<Rng> const & it() const noexcept
|
||||
{
|
||||
return *it_cache_;
|
||||
}
|
||||
|
||||
struct outer_cursor
|
||||
{
|
||||
private:
|
||||
struct inner_view : view_facade<inner_view, finite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
using value_type = range_value_t<Rng>;
|
||||
|
||||
chunk_view_ * rng_ = nullptr;
|
||||
|
||||
constexpr bool done() const noexcept
|
||||
{
|
||||
RANGES_EXPECT(rng_);
|
||||
return rng_->remainder_ == 0;
|
||||
}
|
||||
constexpr bool equal(default_sentinel_t) const noexcept
|
||||
{
|
||||
return done();
|
||||
}
|
||||
constexpr iter_reference_t<iterator_t<Rng>> read() const
|
||||
{
|
||||
RANGES_EXPECT(!done());
|
||||
return *rng_->it();
|
||||
}
|
||||
constexpr iter_rvalue_reference_t<iterator_t<Rng>> move() const
|
||||
{
|
||||
RANGES_EXPECT(!done());
|
||||
return ranges::iter_move(rng_->it());
|
||||
}
|
||||
constexpr void next()
|
||||
{
|
||||
RANGES_EXPECT(!done());
|
||||
++rng_->it();
|
||||
--rng_->remainder_;
|
||||
if(rng_->remainder_ != 0 && rng_->it() == ranges::end(rng_->base_))
|
||||
rng_->remainder_ = 0;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto distance_to(default_sentinel_t) const
|
||||
-> CPP_ret(range_difference_t<Rng>)(
|
||||
requires sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>)
|
||||
{
|
||||
RANGES_EXPECT(rng_);
|
||||
auto const d = ranges::end(rng_->base_) - rng_->it();
|
||||
return ranges::min(d, rng_->remainder_);
|
||||
}
|
||||
|
||||
public:
|
||||
inner_view() = default;
|
||||
constexpr explicit inner_view(chunk_view_ * view) noexcept
|
||||
: rng_{view}
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>)
|
||||
{
|
||||
using size_type = detail::iter_size_t<iterator_t<Rng>>;
|
||||
return static_cast<size_type>(distance_to(default_sentinel_t{}));
|
||||
}
|
||||
};
|
||||
|
||||
chunk_view_ * rng_ = nullptr;
|
||||
|
||||
public:
|
||||
using value_type = inner_view;
|
||||
|
||||
outer_cursor() = default;
|
||||
constexpr explicit outer_cursor(chunk_view_ * view) noexcept
|
||||
: rng_{view}
|
||||
{}
|
||||
constexpr inner_view read() const
|
||||
{
|
||||
RANGES_EXPECT(!done());
|
||||
return inner_view{rng_};
|
||||
}
|
||||
constexpr bool done() const
|
||||
{
|
||||
RANGES_EXPECT(rng_);
|
||||
return rng_->it() == ranges::end(rng_->base_) && rng_->remainder_ != 0;
|
||||
}
|
||||
constexpr bool equal(default_sentinel_t) const
|
||||
{
|
||||
return done();
|
||||
}
|
||||
constexpr void next()
|
||||
{
|
||||
RANGES_EXPECT(!done());
|
||||
ranges::advance(rng_->it(), rng_->remainder_, ranges::end(rng_->base_));
|
||||
rng_->remainder_ = rng_->n_;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto distance_to(default_sentinel_t) const
|
||||
-> CPP_ret(range_difference_t<Rng>)(
|
||||
requires sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>)
|
||||
{
|
||||
RANGES_EXPECT(rng_);
|
||||
auto d = ranges::end(rng_->base_) - rng_->it();
|
||||
if(d < rng_->remainder_)
|
||||
return 1;
|
||||
|
||||
d -= rng_->remainder_;
|
||||
d = (d + rng_->n_ - 1) / rng_->n_;
|
||||
d += (rng_->remainder_ != 0);
|
||||
return d;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr outer_cursor begin_cursor() noexcept
|
||||
{
|
||||
it_cache_ = ranges::begin(base_);
|
||||
return outer_cursor{this};
|
||||
}
|
||||
template<typename Size>
|
||||
constexpr Size size_(Size base_size) const
|
||||
{
|
||||
auto const n = static_cast<Size>(this->n_);
|
||||
return base_size / n + (0 != base_size % n);
|
||||
}
|
||||
|
||||
public:
|
||||
chunk_view_() = default;
|
||||
constexpr chunk_view_(Rng rng, range_difference_t<Rng> n)
|
||||
: base_(detail::move(rng))
|
||||
, n_((RANGES_EXPECT(0 < n), n))
|
||||
, remainder_(n)
|
||||
, it_cache_{nullopt}
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return size_(ranges::size(base_));
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return size_(ranges::size(base_));
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return base_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct chunk_view : chunk_view_<Rng, (bool)forward_range<Rng>>
|
||||
{
|
||||
chunk_view() = default;
|
||||
constexpr chunk_view(Rng rng, range_difference_t<Rng> n)
|
||||
: chunk_view_<Rng, (bool)forward_range<Rng>>(static_cast<Rng &&>(rng), n)
|
||||
{}
|
||||
};
|
||||
|
||||
// Need to keep extra state for input_range, but forward_range is transparent
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<chunk_view<Rng>> =
|
||||
enable_borrowed_range<Rng> && forward_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
chunk_view(Rng &&, range_difference_t<Rng>)
|
||||
-> chunk_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
// In: range<T>
|
||||
// Out: range<range<T>>, where each inner range has $n$ elements.
|
||||
// The last range may have fewer.
|
||||
struct chunk_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
constexpr chunk_view<all_t<Rng>> //
|
||||
operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), n};
|
||||
}
|
||||
};
|
||||
|
||||
struct chunk_fn : chunk_base_fn
|
||||
{
|
||||
using chunk_base_fn::operator();
|
||||
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int n) const
|
||||
{
|
||||
return make_view_closure(bind_back(chunk_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates chunk_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(chunk_fn, chunk)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::chunk_view)
|
||||
|
||||
#endif
|
||||
170
Telegram/ThirdParty/range-v3/include/range/v3/view/chunk_by.hpp
vendored
Normal file
170
Telegram/ThirdParty/range-v3/include/range/v3/view/chunk_by.hpp
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Hui Xie 2021
|
||||
//
|
||||
// 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_CHUNK_BY_HPP
|
||||
#define RANGES_V3_VIEW_CHUNK_BY_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/adjacent_find.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/not_fn.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/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Fun>
|
||||
struct chunk_by_view
|
||||
: view_facade<chunk_by_view<Rng, Fun>,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
Rng rng_;
|
||||
// cached version of the end of the first subrange / start of the second subrange
|
||||
detail::non_propagating_cache<iterator_t<Rng>> second_;
|
||||
semiregular_box_t<Fun> fun_;
|
||||
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
friend chunk_by_view;
|
||||
iterator_t<Rng> cur_;
|
||||
iterator_t<Rng> next_cur_;
|
||||
sentinel_t<Rng> last_;
|
||||
semiregular_box_ref_or_val_t<Fun, false> fun_;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
template<typename I = iterator_t<Rng>>
|
||||
subrange<I> read() const
|
||||
{
|
||||
return {cur_, next_cur_};
|
||||
}
|
||||
#else
|
||||
subrange<iterator_t<Rng>> read() const
|
||||
{
|
||||
return {cur_, next_cur_};
|
||||
}
|
||||
#endif
|
||||
void next()
|
||||
{
|
||||
cur_ = next_cur_;
|
||||
auto partition_cur = adjacent_find(cur_, last_, not_fn(fun_));
|
||||
next_cur_ =
|
||||
partition_cur != last_ ? ranges::next(partition_cur) : partition_cur;
|
||||
}
|
||||
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return cur_ == last_;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return cur_ == that.cur_;
|
||||
}
|
||||
cursor(semiregular_box_ref_or_val_t<Fun, false> fun, iterator_t<Rng> first,
|
||||
iterator_t<Rng> next_cur, sentinel_t<Rng> last)
|
||||
: cur_(first)
|
||||
, next_cur_(next_cur)
|
||||
, last_(last)
|
||||
, fun_(fun)
|
||||
{}
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
};
|
||||
cursor begin_cursor()
|
||||
{
|
||||
auto first = ranges::begin(rng_);
|
||||
auto last = ranges::end(rng_);
|
||||
if(!second_)
|
||||
{
|
||||
auto partition_cur = adjacent_find(first, last, not_fn(fun_));
|
||||
second_ =
|
||||
partition_cur != last ? ranges::next(partition_cur) : partition_cur;
|
||||
}
|
||||
return {fun_, first, *second_, last};
|
||||
}
|
||||
|
||||
public:
|
||||
chunk_by_view() = default;
|
||||
constexpr chunk_by_view(Rng rng, Fun fun)
|
||||
: rng_(std::move(rng))
|
||||
, fun_(std::move(fun))
|
||||
{}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Fun>) chunk_by_view(Rng &&, Fun)
|
||||
->chunk_by_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct chunk_by_base_fn
|
||||
{
|
||||
template(typename Rng, typename Fun)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng> AND //
|
||||
indirect_relation<Fun, iterator_t<Rng>>) //
|
||||
constexpr chunk_by_view<all_t<Rng>, Fun>
|
||||
operator()(Rng && rng, Fun fun) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(fun)};
|
||||
}
|
||||
};
|
||||
|
||||
struct chunk_by_fn : chunk_by_base_fn
|
||||
{
|
||||
using chunk_by_base_fn::operator();
|
||||
|
||||
template<typename Fun>
|
||||
constexpr auto operator()(Fun fun) const
|
||||
{
|
||||
return make_view_closure(bind_back(chunk_by_base_fn{}, std::move(fun)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates chunk_by_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(chunk_by_fn, chunk_by)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::chunk_by_view)
|
||||
|
||||
#endif
|
||||
235
Telegram/ThirdParty/range-v3/include/range/v3/view/common.hpp
vendored
Normal file
235
Telegram/ThirdParty/range-v3/include/range/v3/view/common.hpp
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_COMMON_HPP
|
||||
#define RANGES_V3_VIEW_COMMON_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/common_iterator.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// clang-format off
|
||||
/// \concept random_access_and_sized_range
|
||||
/// \brief The \c random_access_and_sized_range concept
|
||||
template<typename R>
|
||||
CPP_concept random_access_and_sized_range =
|
||||
random_access_range<R> && sized_range<R>;
|
||||
// clang-format on
|
||||
|
||||
template<typename R>
|
||||
using common_view_iterator_t =
|
||||
meta::if_c<random_access_and_sized_range<R>, iterator_t<R>,
|
||||
common_iterator_t<iterator_t<R>, sentinel_t<R>>>;
|
||||
|
||||
template<typename Rng>
|
||||
struct is_common_range : meta::bool_<common_range<Rng>>
|
||||
{};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename Rng, bool = detail::is_common_range<Rng>::value>
|
||||
struct common_view : view_interface<common_view<Rng>, range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
CPP_assert(view_<Rng>);
|
||||
CPP_assert(!(common_range<Rng> && view_<Rng>));
|
||||
Rng rng_;
|
||||
|
||||
sentinel_t<Rng> end_(std::false_type)
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
iterator_t<Rng> end_(std::true_type)
|
||||
{
|
||||
return ranges::begin(rng_) + ranges::distance(rng_);
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>>)
|
||||
sentinel_t<meta::const_if_c<Const, Rng>> end_(std::false_type) const
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>>)
|
||||
iterator_t<meta::const_if_c<Const, Rng>> end_(std::true_type) const
|
||||
{
|
||||
return ranges::begin(rng_) + ranges::distance(rng_);
|
||||
}
|
||||
|
||||
public:
|
||||
common_view() = default;
|
||||
explicit common_view(Rng rng)
|
||||
: rng_(detail::move(rng))
|
||||
{}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
|
||||
detail::common_view_iterator_t<Rng> begin()
|
||||
{
|
||||
return detail::common_view_iterator_t<Rng>{ranges::begin(rng_)};
|
||||
}
|
||||
detail::common_view_iterator_t<Rng> end()
|
||||
{
|
||||
return detail::common_view_iterator_t<Rng>{
|
||||
end_(meta::bool_<detail::random_access_and_sized_range<Rng>>{})};
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(rng_);
|
||||
}
|
||||
|
||||
template(bool Const = true)(
|
||||
requires range<meta::const_if_c<Const, Rng>>)
|
||||
auto begin() const
|
||||
-> detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>
|
||||
{
|
||||
return detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>{
|
||||
ranges::begin(rng_)};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires range<meta::const_if_c<Const, Rng>>)
|
||||
auto end() const
|
||||
-> detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>
|
||||
{
|
||||
return detail::common_view_iterator_t<meta::const_if_c<Const, Rng>>{
|
||||
end_(meta::bool_<detail::random_access_and_sized_range<
|
||||
meta::const_if_c<Const, Rng>>>{})};
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(rng_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng, bool B>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<common_view<Rng, B>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng)(
|
||||
requires (!common_range<Rng>)) //
|
||||
common_view(Rng &&)
|
||||
->common_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
template<typename Rng>
|
||||
struct common_view<Rng, true> : identity_adaptor<Rng>
|
||||
{
|
||||
CPP_assert(common_range<Rng>);
|
||||
using identity_adaptor<Rng>::identity_adaptor;
|
||||
};
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct cpp20_common_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND common_range<Rng>)
|
||||
all_t<Rng> operator()(Rng && rng) const
|
||||
{
|
||||
return all(static_cast<Rng &&>(rng));
|
||||
}
|
||||
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND (!common_range<Rng>)) //
|
||||
common_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return common_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
struct common_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng>)
|
||||
common_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return common_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates common_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<common_fn>, common)
|
||||
} // namespace views
|
||||
/// @}
|
||||
|
||||
/// \cond
|
||||
template<typename Rng>
|
||||
using bounded_view RANGES_DEPRECATED(
|
||||
"The name bounded_view is deprecated. "
|
||||
"Please use common_view instead.") = common_view<Rng>;
|
||||
/// \endcond
|
||||
|
||||
namespace views
|
||||
{
|
||||
/// \cond
|
||||
namespace
|
||||
{
|
||||
RANGES_DEPRECATED(
|
||||
"The name views::bounded is deprecated. "
|
||||
"Please use views::common instead.")
|
||||
RANGES_INLINE_VAR constexpr auto & bounded = common;
|
||||
} // namespace
|
||||
|
||||
template<typename Rng>
|
||||
using bounded_t RANGES_DEPRECATED("The name views::bounded_t is deprecated.") =
|
||||
decltype(common(std::declval<Rng>()));
|
||||
/// \endcond
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
RANGES_INLINE_VARIABLE(
|
||||
ranges::views::view_closure<ranges::views::cpp20_common_fn>, common)
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires view_<Rng> && (!common_range<Rng>)) //
|
||||
using common_view = ranges::common_view<Rng>;
|
||||
} // namespace cpp20
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::common_view)
|
||||
|
||||
#endif
|
||||
452
Telegram/ThirdParty/range-v3/include/range/v3/view/concat.hpp
vendored
Normal file
452
Telegram/ThirdParty/range-v3/include/range/v3/view/concat.hpp
vendored
Normal file
@@ -0,0 +1,452 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-2014.
|
||||
//
|
||||
// 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_CONCAT_HPP
|
||||
#define RANGES_V3_VIEW_CONCAT_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/arithmetic.hpp>
|
||||
#include <range/v3/functional/compose.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/utility/tuple_algorithm.hpp>
|
||||
#include <range/v3/utility/variant.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename State, typename Value>
|
||||
using concat_cardinality_ = std::integral_constant<
|
||||
cardinality,
|
||||
State::value == infinite || Value::value == infinite
|
||||
? infinite
|
||||
: State::value == unknown || Value::value == unknown
|
||||
? unknown
|
||||
: State::value == finite || Value::value == finite
|
||||
? finite
|
||||
: static_cast<cardinality>(State::value + Value::value)>;
|
||||
|
||||
template<typename... Rngs>
|
||||
using concat_cardinality =
|
||||
meta::fold<meta::list<range_cardinality<Rngs>...>,
|
||||
std::integral_constant<cardinality, static_cast<cardinality>(0)>,
|
||||
meta::quote<concat_cardinality_>>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename... Rngs>
|
||||
struct concat_view
|
||||
: view_facade<concat_view<Rngs...>, detail::concat_cardinality<Rngs...>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
using difference_type_ = common_type_t<range_difference_t<Rngs>...>;
|
||||
static constexpr std::size_t cranges{sizeof...(Rngs)};
|
||||
std::tuple<Rngs...> rngs_;
|
||||
|
||||
template<bool IsConst>
|
||||
struct cursor;
|
||||
|
||||
template<bool IsConst>
|
||||
struct sentinel
|
||||
{
|
||||
private:
|
||||
friend struct sentinel<!IsConst>;
|
||||
friend struct cursor<IsConst>;
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst, T>;
|
||||
using concat_view_t = constify_if<concat_view>;
|
||||
sentinel_t<constify_if<meta::back<meta::list<Rngs...>>>> end_;
|
||||
|
||||
public:
|
||||
sentinel() = default;
|
||||
sentinel(concat_view_t * rng, end_tag)
|
||||
: end_(end(std::get<cranges - 1>(rng->rngs_)))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
sentinel(sentinel<Other> that)
|
||||
: end_(std::move(that.end_))
|
||||
{}
|
||||
};
|
||||
|
||||
template<bool IsConst>
|
||||
struct cursor
|
||||
{
|
||||
using difference_type = common_type_t<range_difference_t<Rngs>...>;
|
||||
|
||||
private:
|
||||
friend struct cursor<!IsConst>;
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst, T>;
|
||||
using concat_view_t = constify_if<concat_view>;
|
||||
concat_view_t * rng_;
|
||||
variant<iterator_t<constify_if<Rngs>>...> its_;
|
||||
|
||||
template<std::size_t N>
|
||||
void satisfy(meta::size_t<N>)
|
||||
{
|
||||
RANGES_EXPECT(its_.index() == N);
|
||||
if(ranges::get<N>(its_) == end(std::get<N>(rng_->rngs_)))
|
||||
{
|
||||
ranges::emplace<N + 1>(its_, begin(std::get<N + 1>(rng_->rngs_)));
|
||||
this->satisfy(meta::size_t<N + 1>{});
|
||||
}
|
||||
}
|
||||
void satisfy(meta::size_t<cranges - 1>)
|
||||
{
|
||||
RANGES_EXPECT(its_.index() == cranges - 1);
|
||||
}
|
||||
struct next_fun
|
||||
{
|
||||
cursor * pos;
|
||||
template(typename I, std::size_t N)(
|
||||
requires input_iterator<I>)
|
||||
void operator()(indexed_element<I, N> it) const
|
||||
{
|
||||
RANGES_ASSERT(it.get() != end(std::get<N>(pos->rng_->rngs_)));
|
||||
++it.get();
|
||||
pos->satisfy(meta::size_t<N>{});
|
||||
}
|
||||
};
|
||||
struct prev_fun
|
||||
{
|
||||
cursor * pos;
|
||||
template(typename I)(
|
||||
requires bidirectional_iterator<I>)
|
||||
void operator()(indexed_element<I, 0> it) const
|
||||
{
|
||||
RANGES_ASSERT(it.get() != begin(std::get<0>(pos->rng_->rngs_)));
|
||||
--it.get();
|
||||
}
|
||||
template(typename I, std::size_t N)(
|
||||
requires (N != 0) AND bidirectional_iterator<I>)
|
||||
void operator()(indexed_element<I, N> it) const
|
||||
{
|
||||
if(it.get() == begin(std::get<N>(pos->rng_->rngs_)))
|
||||
{
|
||||
auto && rng = std::get<N - 1>(pos->rng_->rngs_);
|
||||
ranges::emplace<N - 1>(
|
||||
pos->its_,
|
||||
ranges::next(ranges::begin(rng), ranges::end(rng)));
|
||||
pos->its_.visit_i(*this);
|
||||
}
|
||||
else
|
||||
--it.get();
|
||||
}
|
||||
};
|
||||
struct advance_fwd_fun
|
||||
{
|
||||
cursor * pos;
|
||||
difference_type n;
|
||||
template(typename I)(
|
||||
requires random_access_iterator<I>)
|
||||
void operator()(indexed_element<I, cranges - 1> it) const
|
||||
{
|
||||
ranges::advance(it.get(), n);
|
||||
}
|
||||
template(typename I, std::size_t N)(
|
||||
requires random_access_iterator<I>)
|
||||
void operator()(indexed_element<I, N> it) const
|
||||
{
|
||||
auto last = ranges::end(std::get<N>(pos->rng_->rngs_));
|
||||
// BUGBUG If distance(it, last) > n, then using bounded advance
|
||||
// is O(n) when it need not be since the last iterator position
|
||||
// is actually not interesting. Only the "rest" is needed, which
|
||||
// can sometimes be O(1).
|
||||
auto rest = ranges::advance(it.get(), n, std::move(last));
|
||||
pos->satisfy(meta::size_t<N>{});
|
||||
if(rest != 0)
|
||||
pos->its_.visit_i(advance_fwd_fun{pos, rest});
|
||||
}
|
||||
};
|
||||
struct advance_rev_fun
|
||||
{
|
||||
cursor * pos;
|
||||
difference_type n;
|
||||
template(typename I)(
|
||||
requires random_access_iterator<I>)
|
||||
void operator()(indexed_element<I, 0> it) const
|
||||
{
|
||||
ranges::advance(it.get(), n);
|
||||
}
|
||||
template(typename I, std::size_t N)(
|
||||
requires random_access_iterator<I>)
|
||||
void operator()(indexed_element<I, N> it) const
|
||||
{
|
||||
auto first = ranges::begin(std::get<N>(pos->rng_->rngs_));
|
||||
if(it.get() == first)
|
||||
{
|
||||
auto && rng = std::get<N - 1>(pos->rng_->rngs_);
|
||||
ranges::emplace<N - 1>(
|
||||
pos->its_,
|
||||
ranges::next(ranges::begin(rng), ranges::end(rng)));
|
||||
pos->its_.visit_i(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rest = ranges::advance(it.get(), n, std::move(first));
|
||||
if(rest != 0)
|
||||
pos->its_.visit_i(advance_rev_fun{pos, rest});
|
||||
}
|
||||
}
|
||||
};
|
||||
[[noreturn]] static difference_type distance_to_(meta::size_t<cranges>,
|
||||
cursor const &,
|
||||
cursor const &)
|
||||
{
|
||||
RANGES_EXPECT(false);
|
||||
}
|
||||
template<std::size_t N>
|
||||
static difference_type distance_to_(meta::size_t<N>, cursor const & from,
|
||||
cursor const & to)
|
||||
{
|
||||
if(from.its_.index() > N)
|
||||
return cursor::distance_to_(meta::size_t<N + 1>{}, from, to);
|
||||
if(from.its_.index() == N)
|
||||
{
|
||||
if(to.its_.index() == N)
|
||||
return distance(ranges::get<N>(from.its_),
|
||||
ranges::get<N>(to.its_));
|
||||
return distance(ranges::get<N>(from.its_),
|
||||
end(std::get<N>(from.rng_->rngs_))) +
|
||||
cursor::distance_to_(meta::size_t<N + 1>{}, from, to);
|
||||
}
|
||||
if(from.its_.index() < N && to.its_.index() > N)
|
||||
return distance(std::get<N>(from.rng_->rngs_)) +
|
||||
cursor::distance_to_(meta::size_t<N + 1>{}, from, to);
|
||||
RANGES_EXPECT(to.its_.index() == N);
|
||||
return distance(begin(std::get<N>(from.rng_->rngs_)),
|
||||
ranges::get<N>(to.its_));
|
||||
}
|
||||
|
||||
public:
|
||||
// BUGBUG what about rvalue_reference and common_reference?
|
||||
using reference = common_reference_t<range_reference_t<constify_if<Rngs>>...>;
|
||||
using single_pass = meta::or_c<single_pass_iterator_<iterator_t<Rngs>>...>;
|
||||
cursor() = default;
|
||||
cursor(concat_view_t * rng, begin_tag)
|
||||
: rng_(rng)
|
||||
, its_{emplaced_index<0>, begin(std::get<0>(rng->rngs_))}
|
||||
{
|
||||
this->satisfy(meta::size_t<0>{});
|
||||
}
|
||||
cursor(concat_view_t * rng, end_tag)
|
||||
: rng_(rng)
|
||||
, its_{emplaced_index<cranges - 1>, end(std::get<cranges - 1>(rng->rngs_))}
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires IsConst && CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: rng_(that.rng_)
|
||||
, its_(std::move(that.its_))
|
||||
{}
|
||||
reference read() const
|
||||
{
|
||||
// Kind of a dumb implementation. Surely there's a better way.
|
||||
return ranges::get<0>(unique_variant(its_.visit(
|
||||
compose(convert_to<reference>{}, detail::dereference_fn{}))));
|
||||
}
|
||||
void next()
|
||||
{
|
||||
its_.visit_i(next_fun{this});
|
||||
}
|
||||
CPP_member
|
||||
auto equal(cursor const & pos) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires //
|
||||
equality_comparable<variant<iterator_t<constify_if<Rngs>>...>>)
|
||||
{
|
||||
return its_ == pos.its_;
|
||||
}
|
||||
bool equal(sentinel<IsConst> const & pos) const
|
||||
{
|
||||
return its_.index() == cranges - 1 &&
|
||||
ranges::get<cranges - 1>(its_) == pos.end_;
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires and_v<bidirectional_range<Rngs>...>)
|
||||
{
|
||||
its_.visit_i(prev_fun{this});
|
||||
}
|
||||
CPP_member
|
||||
auto advance(difference_type n) //
|
||||
-> CPP_ret(void)(
|
||||
requires and_v<random_access_range<Rngs>...>)
|
||||
{
|
||||
if(n > 0)
|
||||
its_.visit_i(advance_fwd_fun{this, n});
|
||||
else if(n < 0)
|
||||
its_.visit_i(advance_rev_fun{this, n});
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(cursor const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires and_v<sized_sentinel_for<iterator_t<Rngs>,
|
||||
iterator_t<Rngs>>...>)
|
||||
{
|
||||
if(its_.index() <= that.its_.index())
|
||||
return cursor::distance_to_(meta::size_t<0>{}, *this, that);
|
||||
return -cursor::distance_to_(meta::size_t<0>{}, that, *this);
|
||||
}
|
||||
};
|
||||
cursor<meta::and_c<simple_view<Rngs>()...>::value> begin_cursor()
|
||||
{
|
||||
return {this, begin_tag{}};
|
||||
}
|
||||
meta::if_<meta::and_c<(bool)common_range<Rngs>...>,
|
||||
cursor<meta::and_c<simple_view<Rngs>()...>::value>,
|
||||
sentinel<meta::and_c<simple_view<Rngs>()...>::value>>
|
||||
end_cursor()
|
||||
{
|
||||
return {this, end_tag{}};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_cursor() const //
|
||||
-> CPP_ret(cursor<true>)(
|
||||
requires and_v<range<Rngs const>...>)
|
||||
{
|
||||
return {this, begin_tag{}};
|
||||
}
|
||||
CPP_member
|
||||
auto end_cursor() const //
|
||||
-> CPP_ret(
|
||||
meta::if_<meta::and_c<(bool)common_range<Rngs const>...>, //
|
||||
cursor<true>, //
|
||||
sentinel<true>>)(
|
||||
requires and_v<range<Rngs const>...>)
|
||||
{
|
||||
return {this, end_tag{}};
|
||||
}
|
||||
|
||||
public:
|
||||
concat_view() = default;
|
||||
explicit concat_view(Rngs... rngs)
|
||||
: rngs_{std::move(rngs)...}
|
||||
{}
|
||||
CPP_member
|
||||
constexpr auto size() const //
|
||||
-> CPP_ret(std::size_t)(
|
||||
requires (detail::concat_cardinality<Rngs...>::value >= 0))
|
||||
{
|
||||
return static_cast<std::size_t>(detail::concat_cardinality<Rngs...>::value);
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires(detail::concat_cardinality<Rngs...>::value < 0) &&
|
||||
and_v<sized_range<Rngs const>...>)
|
||||
{
|
||||
using size_type = common_type_t<range_size_t<Rngs const>...>;
|
||||
return tuple_foldl(
|
||||
tuple_transform(rngs_,
|
||||
[](auto && r) -> size_type { return ranges::size(r); }),
|
||||
size_type{0},
|
||||
plus{});
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires (detail::concat_cardinality<Rngs...>::value < 0) &&
|
||||
and_v<sized_range<Rngs>...>)
|
||||
{
|
||||
using size_type = common_type_t<range_size_t<Rngs>...>;
|
||||
return tuple_foldl(
|
||||
tuple_transform(rngs_,
|
||||
[](auto && r) -> size_type { return ranges::size(r); }),
|
||||
size_type{0},
|
||||
plus{});
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename... Rng>
|
||||
concat_view(Rng &&...) //
|
||||
-> concat_view<views::all_t<Rng>...>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct concat_fn
|
||||
{
|
||||
template(typename... Rngs)(
|
||||
requires and_v<(viewable_range<Rngs> && input_range<Rngs>)...>)
|
||||
concat_view<all_t<Rngs>...> operator()(Rngs &&... rngs) const
|
||||
{
|
||||
return concat_view<all_t<Rngs>...>{all(static_cast<Rngs &&>(rngs))...};
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
all_t<Rng> operator()(Rng && rng) const //
|
||||
{
|
||||
return all(static_cast<Rng &&>(rng));
|
||||
}
|
||||
// MSVC doesn't like variadics in operator() for some reason
|
||||
#if defined(_MSC_VER)
|
||||
template(typename Rng0, typename Rng1)(
|
||||
requires viewable_range<Rng0> AND input_range<Rng0> AND
|
||||
viewable_range<Rng1> AND input_range<Rng1>)
|
||||
concat_view<all_t<Rng0>, all_t<Rng1>> operator()(Rng0 && rng0, Rng1 && rng1)
|
||||
const
|
||||
{
|
||||
return concat_view<all_t<Rng0>, all_t<Rng1>>{
|
||||
all(static_cast<Rng0 &&>(rng0)),
|
||||
all(static_cast<Rng1 &&>(rng1))};
|
||||
}
|
||||
template(typename Rng0, typename Rng1, typename Rng2)(
|
||||
requires viewable_range<Rng0> AND input_range<Rng0> AND
|
||||
viewable_range<Rng1> AND input_range<Rng1> AND
|
||||
viewable_range<Rng2> AND input_range<Rng2>)
|
||||
concat_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>> //
|
||||
operator()(Rng0 && rng0, Rng1 && rng1, Rng2 && rng2) const
|
||||
{
|
||||
return concat_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>>{
|
||||
all(static_cast<Rng0 &&>(rng0)),
|
||||
all(static_cast<Rng1 &&>(rng1)),
|
||||
all(static_cast<Rng2 &&>(rng2))};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/// \relates concat_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(concat_fn, concat)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::concat_view)
|
||||
|
||||
#endif
|
||||
142
Telegram/ThirdParty/range-v3/include/range/v3/view/const.hpp
vendored
Normal file
142
Telegram/ThirdParty/range-v3/include/range/v3/view/const.hpp
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_CONST_HPP
|
||||
#define RANGES_V3_VIEW_CONST_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/utility/common_type.hpp>
|
||||
#include <range/v3/utility/move.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct const_view : view_adaptor<const_view<Rng>, Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
template<bool Const>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
using value_ = range_value_t<CRng>;
|
||||
using reference_ =
|
||||
common_reference_t<value_ const &&, range_reference_t<CRng>>;
|
||||
using rvalue_reference_ =
|
||||
common_reference_t<value_ const &&, range_rvalue_reference_t<CRng>>;
|
||||
adaptor() = default;
|
||||
template(bool Other)(
|
||||
requires Const && CPP_NOT(Other)) //
|
||||
constexpr adaptor(adaptor<Other>)
|
||||
{}
|
||||
reference_ read(iterator_t<CRng> const & it) const
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
rvalue_reference_ iter_move(iterator_t<CRng> const & it) const
|
||||
noexcept(noexcept(rvalue_reference_(ranges::iter_move(it))))
|
||||
{
|
||||
return ranges::iter_move(it);
|
||||
}
|
||||
};
|
||||
adaptor<simple_view<Rng>()> begin_adaptor()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
adaptor<simple_view<Rng>()> end_adaptor()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
CPP_member
|
||||
auto end_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
const_view() = default;
|
||||
explicit const_view(Rng rng)
|
||||
: const_view::view_adaptor{std::move(rng)}
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<const_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
const_view(Rng &&) //
|
||||
-> const_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct const_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
const_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return const_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates const_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<const_fn>, const_)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::const_view)
|
||||
|
||||
#endif
|
||||
127
Telegram/ThirdParty/range-v3/include/range/v3/view/counted.hpp
vendored
Normal file
127
Telegram/ThirdParty/range-v3/include/range/v3/view/counted.hpp
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_COUNTED_HPP
|
||||
#define RANGES_V3_VIEW_COUNTED_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/counted_iterator.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename I>
|
||||
struct counted_view : view_interface<counted_view<I>, finite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
I it_;
|
||||
iter_difference_t<I> n_;
|
||||
|
||||
public:
|
||||
counted_view() = default;
|
||||
counted_view(I it, iter_difference_t<I> n)
|
||||
: it_(it)
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(0 <= n_);
|
||||
}
|
||||
counted_iterator<I> begin() const
|
||||
{
|
||||
return make_counted_iterator(it_, n_);
|
||||
}
|
||||
default_sentinel_t end() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
auto size() const
|
||||
{
|
||||
return static_cast<detail::iter_size_t<I>>(n_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<counted_view<I>> = true;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename I>
|
||||
counted_view(I, iter_difference_t<I>)
|
||||
-> counted_view<I>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct cpp20_counted_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I> AND (!random_access_iterator<I>)) //
|
||||
subrange<counted_iterator<I>, default_sentinel_t> //
|
||||
operator()(I it, iter_difference_t<I> n) const
|
||||
{
|
||||
return {make_counted_iterator(std::move(it), n), default_sentinel};
|
||||
}
|
||||
template(typename I)(
|
||||
requires random_access_iterator<I>)
|
||||
subrange<I> operator()(I it, iter_difference_t<I> n) const
|
||||
{
|
||||
return {it, it + n};
|
||||
}
|
||||
};
|
||||
|
||||
struct counted_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I> AND (!random_access_iterator<I>)) //
|
||||
counted_view<I> operator()(I it, iter_difference_t<I> n) const
|
||||
{
|
||||
return {std::move(it), n};
|
||||
}
|
||||
template(typename I)(
|
||||
requires random_access_iterator<I>)
|
||||
subrange<I> operator()(I it, iter_difference_t<I> n) const
|
||||
{
|
||||
return {it, it + n};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates counted_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(counted_fn, counted)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
RANGES_INLINE_VARIABLE(ranges::views::cpp20_counted_fn, counted)
|
||||
}
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::counted_view)
|
||||
|
||||
#endif
|
||||
245
Telegram/ThirdParty/range-v3/include/range/v3/view/cycle.hpp
vendored
Normal file
245
Telegram/ThirdParty/range-v3/include/range/v3/view/cycle.hpp
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
/// \file cycle.hpp
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
// Copyright Gonzalo Brito Gadeschi 2015
|
||||
// Copyright Casey Carter 2015
|
||||
//
|
||||
// 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_CYCLE_HPP
|
||||
#define RANGES_V3_VIEW_CYCLE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/box.hpp>
|
||||
#include <range/v3/utility/get.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, bool /* = (bool) is_infinite<Rng>() */>
|
||||
struct RANGES_EMPTY_BASES cycled_view
|
||||
: view_facade<cycled_view<Rng>, infinite>
|
||||
, private detail::non_propagating_cache<iterator_t<Rng>, cycled_view<Rng>,
|
||||
!common_range<Rng>>
|
||||
{
|
||||
private:
|
||||
CPP_assert(forward_range<Rng> && !is_infinite<Rng>::value);
|
||||
friend range_access;
|
||||
Rng rng_;
|
||||
|
||||
using cache_t = detail::non_propagating_cache<iterator_t<Rng>, cycled_view<Rng>,
|
||||
!common_range<Rng>>;
|
||||
|
||||
template<bool IsConst>
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend struct cursor<!IsConst>;
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst, T>;
|
||||
using cycled_view_t = constify_if<cycled_view>;
|
||||
using CRng = constify_if<Rng>;
|
||||
using iterator = iterator_t<CRng>;
|
||||
|
||||
cycled_view_t * rng_{};
|
||||
iterator it_{};
|
||||
std::intmax_t n_ = 0;
|
||||
|
||||
iterator get_end_(std::true_type, bool = false) const
|
||||
{
|
||||
return ranges::end(rng_->rng_);
|
||||
}
|
||||
template<bool CanBeEmpty = false>
|
||||
iterator get_end_(std::false_type, meta::bool_<CanBeEmpty> = {}) const
|
||||
{
|
||||
auto & end_ = static_cast<cache_t &>(*rng_);
|
||||
RANGES_EXPECT(CanBeEmpty || end_);
|
||||
if(CanBeEmpty && !end_)
|
||||
end_ = ranges::next(it_, ranges::end(rng_->rng_));
|
||||
return *end_;
|
||||
}
|
||||
void set_end_(std::true_type) const
|
||||
{}
|
||||
void set_end_(std::false_type) const
|
||||
{
|
||||
auto & end_ = static_cast<cache_t &>(*rng_);
|
||||
if(!end_)
|
||||
end_ = it_;
|
||||
}
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
cursor(cycled_view_t * rng)
|
||||
: rng_(rng)
|
||||
, it_(ranges::begin(rng->rng_))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: rng_(that.rng_)
|
||||
, it_(std::move(that.it_))
|
||||
{}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(read)()(const)
|
||||
(
|
||||
return *it_
|
||||
)
|
||||
// clang-format on
|
||||
CPP_member
|
||||
auto equal(cursor const & pos) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires equality_comparable<iterator>)
|
||||
{
|
||||
RANGES_EXPECT(rng_ == pos.rng_);
|
||||
return n_ == pos.n_ && it_ == pos.it_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
auto const last = ranges::end(rng_->rng_);
|
||||
RANGES_EXPECT(it_ != last);
|
||||
if(++it_ == last)
|
||||
{
|
||||
++n_;
|
||||
this->set_end_(meta::bool_<(bool)common_range<CRng>>{});
|
||||
it_ = ranges::begin(rng_->rng_);
|
||||
}
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<CRng>)
|
||||
{
|
||||
if(it_ == ranges::begin(rng_->rng_))
|
||||
{
|
||||
RANGES_EXPECT(n_ > 0); // decrementing the begin iterator?!
|
||||
--n_;
|
||||
it_ = this->get_end_(meta::bool_<(bool)common_range<CRng>>{});
|
||||
}
|
||||
--it_;
|
||||
}
|
||||
template(typename Diff)(
|
||||
requires random_access_range<CRng> AND
|
||||
detail::integer_like_<Diff>)
|
||||
void advance(Diff n)
|
||||
{
|
||||
auto const first = ranges::begin(rng_->rng_);
|
||||
auto const last = this->get_end_(meta::bool_<(bool)common_range<CRng>>{},
|
||||
meta::bool_<true>());
|
||||
auto const dist = last - first;
|
||||
auto const d = it_ - first;
|
||||
auto const off = (d + n) % dist;
|
||||
n_ += (d + n) / dist;
|
||||
RANGES_EXPECT(n_ >= 0);
|
||||
using D = range_difference_t<Rng>;
|
||||
it_ = first + static_cast<D>(off < 0 ? off + dist : off);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(distance_to)(cursor const & that)(const //
|
||||
requires sized_sentinel_for<iterator, iterator>)
|
||||
{
|
||||
RANGES_EXPECT(that.rng_ == rng_);
|
||||
auto const first = ranges::begin(rng_->rng_);
|
||||
auto const last = this->get_end_(meta::bool_<(bool)common_range<Rng>>{},
|
||||
meta::bool_<true>());
|
||||
auto const dist = last - first;
|
||||
return (that.n_ - n_) * dist + (that.it_ - it_);
|
||||
}
|
||||
};
|
||||
|
||||
CPP_member
|
||||
auto begin_cursor() //
|
||||
-> CPP_ret(cursor<false>)(
|
||||
requires (!simple_view<Rng>() || !common_range<Rng const>))
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_cursor() const //
|
||||
-> CPP_ret(cursor<true>)(
|
||||
requires common_range<Rng const>)
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
unreachable_sentinel_t end_cursor() const
|
||||
{
|
||||
return unreachable;
|
||||
}
|
||||
|
||||
public:
|
||||
cycled_view() = default;
|
||||
/// \pre <tt>!empty(rng)</tt>
|
||||
explicit cycled_view(Rng rng)
|
||||
: rng_(std::move(rng))
|
||||
{
|
||||
RANGES_EXPECT(!ranges::empty(rng_));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct cycled_view<Rng, true> : identity_adaptor<Rng>
|
||||
{
|
||||
CPP_assert(is_infinite<Rng>::value);
|
||||
using identity_adaptor<Rng>::identity_adaptor;
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
cycled_view(Rng &&) //
|
||||
-> cycled_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
/// Returns an infinite range that endlessly repeats the source
|
||||
/// range.
|
||||
struct cycle_fn
|
||||
{
|
||||
/// \pre <tt>!empty(rng)</tt>
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng>)
|
||||
cycled_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return cycled_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates cycle_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<cycle_fn>, cycle)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::cycled_view)
|
||||
|
||||
#endif
|
||||
132
Telegram/ThirdParty/range-v3/include/range/v3/view/delimit.hpp
vendored
Normal file
132
Telegram/ThirdParty/range-v3/include/range/v3/view/delimit.hpp
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_DELIMIT_HPP
|
||||
#define RANGES_V3_VIEW_DELIMIT_HPP
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Val>
|
||||
struct delimit_view
|
||||
: view_adaptor<delimit_view<Rng, Val>, Rng,
|
||||
is_finite<Rng>::value ? finite : unknown>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
Val value_;
|
||||
|
||||
struct sentinel_adaptor : adaptor_base
|
||||
{
|
||||
sentinel_adaptor() = default;
|
||||
sentinel_adaptor(Val value)
|
||||
: value_(std::move(value))
|
||||
{}
|
||||
template<class I, class S>
|
||||
bool empty(I const & it, S const & last) const
|
||||
{
|
||||
return it == last || *it == value_;
|
||||
}
|
||||
Val value_;
|
||||
};
|
||||
|
||||
sentinel_adaptor end_adaptor() const
|
||||
{
|
||||
return {value_};
|
||||
}
|
||||
|
||||
public:
|
||||
delimit_view() = default;
|
||||
constexpr delimit_view(Rng rng, Val value)
|
||||
: delimit_view::view_adaptor{std::move(rng)}
|
||||
, value_(std::move(value))
|
||||
{}
|
||||
};
|
||||
|
||||
// the begin iterator will be an iterator into the underlying view (conditionally
|
||||
// borrowed) and the end iterator owns the value to be compared against (borrowed)
|
||||
template<typename Rng, typename Val>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<delimit_view<Rng, Val>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Val)(
|
||||
requires copy_constructible<Val>)
|
||||
delimit_view(Rng &&, Val)
|
||||
-> delimit_view<views::all_t<Rng>, Val>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct delimit_base_fn
|
||||
{
|
||||
template(typename I_, typename Val, typename I = detail::decay_t<I_>)(
|
||||
requires (!range<I_>) AND convertible_to<I_, I> AND input_iterator<I> AND
|
||||
semiregular<Val> AND
|
||||
equality_comparable_with<Val, iter_reference_t<I>>)
|
||||
constexpr auto operator()(I_ && begin_, Val value) const
|
||||
-> delimit_view<subrange<I, unreachable_sentinel_t>, Val>
|
||||
{
|
||||
return {{static_cast<I_ &&>(begin_), {}}, std::move(value)};
|
||||
}
|
||||
|
||||
template(typename Rng, typename Val)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND semiregular<
|
||||
Val> AND equality_comparable_with<Val, range_reference_t<Rng>>)
|
||||
constexpr auto operator()(Rng && rng, Val value) const //
|
||||
-> delimit_view<all_t<Rng>, Val>
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(value)};
|
||||
}
|
||||
};
|
||||
|
||||
struct delimit_fn : delimit_base_fn
|
||||
{
|
||||
using delimit_base_fn::operator();
|
||||
|
||||
template<typename Val>
|
||||
constexpr auto operator()(Val value) const
|
||||
{
|
||||
return make_view_closure(bind_back(delimit_base_fn{}, std::move(value)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates delimit_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(delimit_fn, delimit)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::delimit_view)
|
||||
|
||||
#endif
|
||||
203
Telegram/ThirdParty/range-v3/include/range/v3/view/drop.hpp
vendored
Normal file
203
Telegram/ThirdParty/range-v3/include/range/v3/view/drop.hpp
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_DROP_HPP
|
||||
#define RANGES_V3_VIEW_DROP_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/min.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/box.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct RANGES_EMPTY_BASES drop_view
|
||||
: view_interface<drop_view<Rng>,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
, private detail::non_propagating_cache<iterator_t<Rng>, drop_view<Rng>,
|
||||
!random_access_range<Rng>>
|
||||
{
|
||||
private:
|
||||
using difference_type_ = range_difference_t<Rng>;
|
||||
Rng rng_;
|
||||
difference_type_ n_;
|
||||
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>>)
|
||||
iterator_t<meta::const_if_c<Const, Rng>> //
|
||||
get_begin_(std::true_type, std::true_type) const
|
||||
{
|
||||
CPP_assert(random_access_range<meta::const_if_c<Const, Rng>>);
|
||||
return next(ranges::begin(rng_), n_, ranges::end(rng_));
|
||||
}
|
||||
iterator_t<Rng> get_begin_(std::true_type, std::false_type)
|
||||
{
|
||||
CPP_assert(random_access_range<Rng>);
|
||||
return next(ranges::begin(rng_), n_, ranges::end(rng_));
|
||||
}
|
||||
iterator_t<Rng> get_begin_(std::false_type, detail::ignore_t)
|
||||
{
|
||||
CPP_assert(!random_access_range<Rng>);
|
||||
using cache_t =
|
||||
detail::non_propagating_cache<iterator_t<Rng>, drop_view<Rng>>;
|
||||
auto & begin_ = static_cast<cache_t &>(*this);
|
||||
if(!begin_)
|
||||
begin_ = next(ranges::begin(rng_), n_, ranges::end(rng_));
|
||||
return *begin_;
|
||||
}
|
||||
|
||||
public:
|
||||
drop_view() = default;
|
||||
drop_view(Rng rng, difference_type_ n)
|
||||
: rng_(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
}
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
return this->get_begin_(meta::bool_<random_access_range<Rng>>{},
|
||||
std::false_type{});
|
||||
}
|
||||
sentinel_t<Rng> end()
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
|
||||
iterator_t<meta::const_if_c<Const, Rng>> begin() const
|
||||
{
|
||||
return this->get_begin_(std::true_type{}, std::true_type{});
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
|
||||
sentinel_t<meta::const_if_c<Const, Rng>> end() const
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
auto const s = ranges::size(rng_);
|
||||
auto const n = static_cast<range_size_t<Rng const>>(n_);
|
||||
return s < n ? 0 : s - n;
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
auto const s = ranges::size(rng_);
|
||||
auto const n = static_cast<range_size_t<Rng>>(n_);
|
||||
return s < n ? 0 : s - n;
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
drop_view(Rng &&, range_difference_t<Rng>)
|
||||
-> drop_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct drop_base_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
static auto impl_(Rng && rng, range_difference_t<Rng> n, input_range_tag)
|
||||
-> drop_view<all_t<Rng>>
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), n};
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires borrowed_range<Rng> AND sized_range<Rng>)
|
||||
static subrange<iterator_t<Rng>, sentinel_t<Rng>> //
|
||||
impl_(Rng && rng, range_difference_t<Rng> n, random_access_range_tag)
|
||||
{
|
||||
return {begin(rng) + ranges::min(n, distance(rng)), end(rng)};
|
||||
}
|
||||
|
||||
public:
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
auto operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
return drop_base_fn::impl_(
|
||||
static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
|
||||
}
|
||||
};
|
||||
|
||||
struct drop_fn : drop_base_fn
|
||||
{
|
||||
using drop_base_fn::operator();
|
||||
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int n) const
|
||||
{
|
||||
return make_view_closure(bind_back(drop_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates drop_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(drop_fn, drop)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::drop;
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires view_<Rng>)
|
||||
using drop_view = ranges::drop_view<Rng>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::drop_view)
|
||||
|
||||
#endif
|
||||
184
Telegram/ThirdParty/range-v3/include/range/v3/view/drop_exactly.hpp
vendored
Normal file
184
Telegram/ThirdParty/range-v3/include/range/v3/view/drop_exactly.hpp
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_DROP_EXACTLY_HPP
|
||||
#define RANGES_V3_VIEW_DROP_EXACTLY_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/box.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct RANGES_EMPTY_BASES drop_exactly_view
|
||||
: view_interface<drop_exactly_view<Rng>,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
, private detail::non_propagating_cache<iterator_t<Rng>, drop_exactly_view<Rng>,
|
||||
!random_access_range<Rng>>
|
||||
{
|
||||
private:
|
||||
using difference_type_ = range_difference_t<Rng>;
|
||||
Rng rng_;
|
||||
difference_type_ n_;
|
||||
|
||||
// random_access_range == true
|
||||
template(bool Const = true)(
|
||||
requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
|
||||
iterator_t<meta::const_if_c<Const, Rng>> get_begin_(std::true_type) const
|
||||
{
|
||||
return next(ranges::begin(rng_), n_);
|
||||
}
|
||||
iterator_t<Rng> get_begin_(std::true_type)
|
||||
{
|
||||
return next(ranges::begin(rng_), n_);
|
||||
}
|
||||
// random_access_range == false
|
||||
iterator_t<Rng> get_begin_(std::false_type)
|
||||
{
|
||||
using cache_t =
|
||||
detail::non_propagating_cache<iterator_t<Rng>, drop_exactly_view<Rng>>;
|
||||
auto & begin_ = static_cast<cache_t &>(*this);
|
||||
if(!begin_)
|
||||
begin_ = next(ranges::begin(rng_), n_);
|
||||
return *begin_;
|
||||
}
|
||||
|
||||
public:
|
||||
drop_exactly_view() = default;
|
||||
drop_exactly_view(Rng rng, difference_type_ n)
|
||||
: rng_(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
}
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
return this->get_begin_(meta::bool_<random_access_range<Rng>>{});
|
||||
}
|
||||
sentinel_t<Rng> end()
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
|
||||
iterator_t<meta::const_if_c<Const, Rng>> begin() const
|
||||
{
|
||||
return this->get_begin_(std::true_type{});
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND random_access_range<meta::const_if_c<Const, Rng>>)
|
||||
sentinel_t<meta::const_if_c<Const, Rng>> end() const
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(rng_) - static_cast<range_size_t<Rng const>>(n_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(rng_) - static_cast<range_size_t<Rng>>(n_);
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_exactly_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
drop_exactly_view(Rng &&, range_difference_t<Rng>)
|
||||
->drop_exactly_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct drop_exactly_base_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
static auto impl_(Rng && rng, range_difference_t<Rng> n, input_range_tag)
|
||||
-> drop_exactly_view<all_t<Rng>>
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), n};
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires borrowed_range<Rng>)
|
||||
static subrange<iterator_t<Rng>, sentinel_t<Rng>> //
|
||||
impl_(Rng && rng, range_difference_t<Rng> n, random_access_range_tag)
|
||||
{
|
||||
return {begin(rng) + n, end(rng)};
|
||||
}
|
||||
|
||||
public:
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
auto operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
return drop_exactly_base_fn::impl_(
|
||||
static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
|
||||
}
|
||||
};
|
||||
|
||||
struct drop_exactly_fn : drop_exactly_base_fn
|
||||
{
|
||||
using drop_exactly_base_fn::operator();
|
||||
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int n) const
|
||||
{
|
||||
return make_view_closure(bind_back(drop_exactly_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates drop_exactly_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(drop_exactly_fn, drop_exactly)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::drop_exactly_view)
|
||||
|
||||
#endif
|
||||
373
Telegram/ThirdParty/range-v3/include/range/v3/view/drop_last.hpp
vendored
Normal file
373
Telegram/ThirdParty/range-v3/include/range/v3/view/drop_last.hpp
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Andrey Diduh 2019
|
||||
//
|
||||
// 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_DROP_LAST_HPP
|
||||
#define RANGES_V3_VIEW_DROP_LAST_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/counted_iterator.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
namespace drop_last_view
|
||||
{
|
||||
template<typename Rng>
|
||||
range_size_t<Rng> get_size(Rng & rng, range_difference_t<Rng> n_)
|
||||
{
|
||||
RANGES_EXPECT(n_ >= 0);
|
||||
range_size_t<Rng> const initial_size = ranges::size(rng);
|
||||
range_size_t<Rng> const n = static_cast<range_size_t<Rng>>(n_);
|
||||
return initial_size > n ? initial_size - n : 0;
|
||||
}
|
||||
|
||||
template(typename Rng)(
|
||||
requires random_access_range<Rng> AND sized_range<Rng>)
|
||||
iterator_t<Rng> get_end(Rng & rng, range_difference_t<Rng> n, int)
|
||||
{
|
||||
return begin(rng) + static_cast<range_difference_t<Rng>>(
|
||||
drop_last_view::get_size(rng, n));
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires bidirectional_range<Rng> AND common_range<Rng>)
|
||||
iterator_t<Rng> get_end(Rng & rng, range_difference_t<Rng> n, long)
|
||||
{
|
||||
return prev(end(rng), n, begin(rng));
|
||||
}
|
||||
|
||||
enum class mode_enum
|
||||
{
|
||||
bidi,
|
||||
forward,
|
||||
sized,
|
||||
invalid
|
||||
};
|
||||
|
||||
template<mode_enum Mode>
|
||||
using mode_t = std::integral_constant<mode_enum, Mode>;
|
||||
|
||||
using mode_bidi = mode_t<mode_enum::bidi>;
|
||||
using mode_forward = mode_t<mode_enum::forward>;
|
||||
using mode_sized = mode_t<mode_enum::sized>;
|
||||
using mode_invalid = mode_t<mode_enum::invalid>;
|
||||
|
||||
template<typename Rng>
|
||||
constexpr mode_enum get_mode() noexcept
|
||||
{
|
||||
// keep range bound
|
||||
// Sized Bidi O(N)
|
||||
return (random_access_range<Rng> && view_<Rng> && sized_range<Rng>) ||
|
||||
(bidirectional_range<Rng> && view_<Rng> &&
|
||||
common_range<Rng>)
|
||||
? mode_enum::bidi //
|
||||
: sized_range<Rng> && view_<Rng> //
|
||||
? mode_enum::sized //
|
||||
: forward_range<Rng> && view_<Rng> //
|
||||
? mode_enum::forward //
|
||||
: mode_enum::invalid; //
|
||||
|
||||
// max performance
|
||||
// Sized Bidi O(1)
|
||||
// Sized Bidi use mode::sized instead of mode::bidi - thus become unbound.
|
||||
/*return (random_access_range<Rng> && view_<Rng> && sized_range<Rng> &&
|
||||
view_<Rng>) || (bidirectional_range<Rng> && view_<Rng> &&
|
||||
common_range<Rng> && view_<Rng>) ? mode::bidi : sized_range<Rng> &&
|
||||
view_<Rng> ? mode::sized : bidirectional_range<Rng> && view_<Rng> &&
|
||||
common_range<Rng> && view_<Rng> ? mode::bidi : forward_range<Rng> &&
|
||||
view_<Rng> ? mode::forward : mode::invalid;*/
|
||||
}
|
||||
|
||||
template<typename Rng>
|
||||
using mode_of = mode_t<drop_last_view::get_mode<Rng>()>;
|
||||
} // namespace drop_last_view
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename Rng, typename = detail::drop_last_view::mode_of<Rng>>
|
||||
struct drop_last_view
|
||||
{};
|
||||
|
||||
template<typename Rng>
|
||||
struct drop_last_view<Rng, detail::drop_last_view::mode_bidi>
|
||||
: view_interface<drop_last_view<Rng, detail::drop_last_view::mode_bidi>,
|
||||
is_finite<Rng>::value
|
||||
? finite
|
||||
: range_cardinality<Rng>::value> // finite at best
|
||||
{
|
||||
CPP_assert(
|
||||
(random_access_range<Rng> && view_<Rng> && sized_range<Rng>) ||
|
||||
(bidirectional_range<Rng> && view_<Rng> && common_range<Rng>));
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
using difference_t = range_difference_t<Rng>;
|
||||
|
||||
Rng rng_;
|
||||
difference_t n_;
|
||||
detail::non_propagating_cache<iterator_t<Rng>> end_;
|
||||
|
||||
public:
|
||||
drop_last_view() = default;
|
||||
constexpr drop_last_view(Rng rng, difference_t n)
|
||||
: rng_(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
}
|
||||
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
return ranges::begin(rng_);
|
||||
}
|
||||
sentinel_t<Rng> end()
|
||||
{
|
||||
if(!end_)
|
||||
end_ = detail::drop_last_view::get_end(rng_, n_, 0);
|
||||
return *end_;
|
||||
}
|
||||
template(typename CRng = Rng const)(
|
||||
requires random_access_range<CRng> AND sized_range<CRng>)
|
||||
iterator_t<CRng> begin() const
|
||||
{
|
||||
return ranges::begin(rng_);
|
||||
}
|
||||
template(typename CRng = Rng const)(
|
||||
requires random_access_range<CRng> AND sized_range<CRng>)
|
||||
iterator_t<CRng> end() const
|
||||
{
|
||||
return detail::drop_last_view::get_end(rng_, n_, 0);
|
||||
}
|
||||
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return detail::drop_last_view::get_size(rng_, n_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return detail::drop_last_view::get_size(rng_, n_);
|
||||
}
|
||||
|
||||
Rng & base()
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
Rng const & base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct drop_last_view<Rng, detail::drop_last_view::mode_forward>
|
||||
: view_adaptor<drop_last_view<Rng, detail::drop_last_view::mode_forward>, Rng,
|
||||
is_finite<Rng>::value
|
||||
? finite
|
||||
: range_cardinality<Rng>::value> // finite at best (but
|
||||
// unknown is expected)
|
||||
{
|
||||
CPP_assert(forward_range<Rng> && view_<Rng>);
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
using difference_t = range_difference_t<Rng>;
|
||||
difference_t n_;
|
||||
detail::non_propagating_cache<iterator_t<Rng>> probe_begin;
|
||||
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
iterator_t<Rng> probe_;
|
||||
|
||||
adaptor() = default;
|
||||
adaptor(iterator_t<Rng> probe_first)
|
||||
: probe_(std::move(probe_first))
|
||||
{}
|
||||
void next(iterator_t<Rng> & it)
|
||||
{
|
||||
++it;
|
||||
++probe_;
|
||||
}
|
||||
};
|
||||
|
||||
struct sentinel_adaptor : adaptor_base
|
||||
{
|
||||
template<typename I, typename S>
|
||||
bool empty(I const &, adaptor const & ia, S const & s) const
|
||||
{
|
||||
return ia.probe_ == s;
|
||||
}
|
||||
};
|
||||
|
||||
adaptor begin_adaptor()
|
||||
{
|
||||
if(!probe_begin)
|
||||
probe_begin = next(begin(this->base()), n_, end(this->base()));
|
||||
return {*probe_begin};
|
||||
}
|
||||
sentinel_adaptor end_adaptor()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
drop_last_view() = default;
|
||||
constexpr drop_last_view(Rng rng, difference_t n)
|
||||
: drop_last_view::view_adaptor(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
}
|
||||
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return detail::drop_last_view::get_size(this->base(), n_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return detail::drop_last_view::get_size(this->base(), n_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct drop_last_view<Rng, detail::drop_last_view::mode_sized>
|
||||
: view_interface<drop_last_view<Rng, detail::drop_last_view::mode_sized>, finite>
|
||||
{
|
||||
CPP_assert(sized_range<Rng> && view_<Rng>);
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
using difference_t = range_difference_t<Rng>;
|
||||
Rng rng_;
|
||||
difference_t n_;
|
||||
|
||||
public:
|
||||
drop_last_view() = default;
|
||||
constexpr drop_last_view(Rng rng, difference_t n)
|
||||
: rng_(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
}
|
||||
|
||||
counted_iterator<iterator_t<Rng>> begin()
|
||||
{
|
||||
return {ranges::begin(rng_), static_cast<difference_t>(size())};
|
||||
}
|
||||
template(typename CRng = Rng const)(
|
||||
requires sized_range<CRng>)
|
||||
counted_iterator<iterator_t<CRng>> begin() const
|
||||
{
|
||||
return {ranges::begin(rng_), static_cast<difference_t>(size())};
|
||||
}
|
||||
default_sentinel_t end() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
range_size_t<Rng> size()
|
||||
{
|
||||
return detail::drop_last_view::get_size(this->base(), n_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return detail::drop_last_view::get_size(this->base(), n_);
|
||||
}
|
||||
|
||||
Rng & base()
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
Rng const & base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng, typename T>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_last_view<Rng, T>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
drop_last_view(Rng &&, range_difference_t<Rng>)
|
||||
-> drop_last_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct drop_last_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires sized_range<Rng> || forward_range<Rng>)
|
||||
constexpr auto operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
-> drop_last_view<all_t<Rng>>
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), n};
|
||||
}
|
||||
};
|
||||
|
||||
struct drop_last_fn : drop_last_base_fn
|
||||
{
|
||||
using drop_last_base_fn::operator();
|
||||
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int n) const
|
||||
{
|
||||
return make_view_closure(bind_back(drop_last_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
RANGES_INLINE_VARIABLE(drop_last_fn, drop_last)
|
||||
} // namespace views
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::drop_last_view)
|
||||
|
||||
#endif
|
||||
165
Telegram/ThirdParty/range-v3/include/range/v3/view/drop_while.hpp
vendored
Normal file
165
Telegram/ThirdParty/range-v3/include/range/v3/view/drop_while.hpp
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_DROP_WHILE_HPP
|
||||
#define RANGES_V3_VIEW_DROP_WHILE_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/find_if_not.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/compose.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Pred>
|
||||
struct drop_while_view
|
||||
: view_interface<drop_while_view<Rng, Pred>,
|
||||
is_finite<Rng>::value ? finite : unknown>
|
||||
{
|
||||
private:
|
||||
Rng rng_;
|
||||
RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Pred> pred_;
|
||||
detail::non_propagating_cache<iterator_t<Rng>> begin_;
|
||||
|
||||
iterator_t<Rng> get_begin_()
|
||||
{
|
||||
if(!begin_)
|
||||
begin_ = find_if_not(rng_, std::ref(pred_));
|
||||
return *begin_;
|
||||
}
|
||||
|
||||
public:
|
||||
drop_while_view() = default;
|
||||
drop_while_view(Rng rng, Pred pred)
|
||||
: rng_(std::move(rng))
|
||||
, pred_(std::move(pred))
|
||||
{}
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
return get_begin_();
|
||||
}
|
||||
sentinel_t<Rng> end()
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
// unlike take_while_view, drop_while_view is transparently safe because we only
|
||||
// need the predicate to find begin()
|
||||
template<typename Rng, typename Pred>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<drop_while_view<Rng, Pred>> =
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Fun>)
|
||||
drop_while_view(Rng &&, Fun)
|
||||
-> drop_while_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
template<typename Rng, typename Pred>
|
||||
RANGES_INLINE_VAR constexpr bool disable_sized_range<drop_while_view<Rng, Pred>> =
|
||||
true;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct drop_while_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, iterator_t<Rng>>)
|
||||
auto operator()(Rng && rng, Pred pred) const
|
||||
-> drop_while_view<all_t<Rng>, Pred>
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(pred)};
|
||||
}
|
||||
template(typename Rng, typename Pred, typename Proj)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<composed<Pred, Proj>, iterator_t<Rng>>)
|
||||
auto operator()(Rng && rng, Pred pred, Proj proj) const
|
||||
-> drop_while_view<all_t<Rng>, composed<Pred, Proj>>
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
compose(std::move(pred), std::move(proj))};
|
||||
}
|
||||
};
|
||||
|
||||
struct drop_while_bind_fn
|
||||
{
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const // TODO: underconstrained
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(drop_while_base_fn{}, std::move(pred)));
|
||||
}
|
||||
template(typename Pred, typename Proj)(
|
||||
requires (!range<Pred>)) // TODO: underconstrained
|
||||
constexpr auto operator()(Pred && pred, Proj proj) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
drop_while_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
|
||||
}
|
||||
};
|
||||
|
||||
struct RANGES_EMPTY_BASES drop_while_fn
|
||||
: drop_while_base_fn, drop_while_bind_fn
|
||||
{
|
||||
using drop_while_base_fn::operator();
|
||||
using drop_while_bind_fn::operator();
|
||||
};
|
||||
|
||||
/// \relates drop_while_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(drop_while_fn, drop_while)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::drop_while;
|
||||
}
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, iterator_t<Rng>>)
|
||||
using drop_while_view = ranges::drop_while_view<Rng, Pred>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::drop_while_view)
|
||||
|
||||
#endif
|
||||
85
Telegram/ThirdParty/range-v3/include/range/v3/view/empty.hpp
vendored
Normal file
85
Telegram/ThirdParty/range-v3/include/range/v3/view/empty.hpp
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_EMPTY_HPP
|
||||
#define RANGES_V3_VIEW_EMPTY_HPP
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/view/interface.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename T>
|
||||
struct empty_view : view_interface<empty_view<T>, (cardinality)0>
|
||||
{
|
||||
static_assert(std::is_object<T>::value,
|
||||
"The template parameter to empty_view must be an object type.");
|
||||
empty_view() = default;
|
||||
static constexpr T * begin() noexcept
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
static constexpr T * end() noexcept
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
static constexpr std::size_t size() noexcept
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
static constexpr T * data() noexcept
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
RANGES_DEPRECATED(
|
||||
"Replace views::empty<T>() with views::empty<T>. "
|
||||
"It is now a variable template.")
|
||||
empty_view operator()() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<empty_view<T>> = true;
|
||||
|
||||
namespace views
|
||||
{
|
||||
template<typename T>
|
||||
RANGES_INLINE_VAR constexpr empty_view<T> empty{};
|
||||
}
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::empty;
|
||||
}
|
||||
template(typename T)(
|
||||
requires std::is_object<T>::value) //
|
||||
using empty_view = ranges::empty_view<T>;
|
||||
} // namespace cpp20
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::empty_view)
|
||||
|
||||
#endif
|
||||
123
Telegram/ThirdParty/range-v3/include/range/v3/view/enumerate.hpp
vendored
Normal file
123
Telegram/ThirdParty/range-v3/include/range/v3/view/enumerate.hpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Casey Carter 2018-present
|
||||
//
|
||||
// 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_ENUMERATE_HPP
|
||||
#define RANGES_V3_VIEW_ENUMERATE_HPP
|
||||
|
||||
#include <range/v3/core.hpp>
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/zip.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// Counts from zero up.
|
||||
// See https://github.com/ericniebler/range-v3/issues/1141
|
||||
// for why we don't just use iota_view.
|
||||
template<typename Size, typename Diff>
|
||||
struct index_view : view_facade<index_view<Size, Diff>, infinite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
struct cursor
|
||||
{
|
||||
using difference_type = Diff;
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
Size index_{0};
|
||||
|
||||
Size read() const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++index_;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return that.index_ == index_;
|
||||
}
|
||||
void prev()
|
||||
{
|
||||
--index_;
|
||||
}
|
||||
void advance(Diff n)
|
||||
{
|
||||
index_ += static_cast<Size>(n);
|
||||
}
|
||||
Diff distance_to(cursor const & that) const
|
||||
{
|
||||
return static_cast<Diff>(static_cast<Diff>(that.index_) -
|
||||
static_cast<Diff>(index_));
|
||||
}
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
};
|
||||
cursor begin_cursor() const
|
||||
{
|
||||
return cursor{};
|
||||
}
|
||||
unreachable_sentinel_t end_cursor() const
|
||||
{
|
||||
return unreachable;
|
||||
}
|
||||
|
||||
public:
|
||||
index_view() = default;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename Size, typename Diff>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<detail::index_view<Size, Diff>> =
|
||||
true;
|
||||
|
||||
/// \endcond
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
/// Lazily pairs each element in a source range with
|
||||
/// its corresponding index.
|
||||
struct enumerate_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng>)
|
||||
auto operator()(Rng && rng) const
|
||||
{
|
||||
using D = range_difference_t<Rng>;
|
||||
using S = detail::iter_size_t<iterator_t<Rng>>;
|
||||
return zip(detail::index_view<S, D>(), all(static_cast<Rng &&>(rng)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates enumerate_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<enumerate_fn>, enumerate)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
197
Telegram/ThirdParty/range-v3/include/range/v3/view/exclusive_scan.hpp
vendored
Normal file
197
Telegram/ThirdParty/range-v3/include/range/v3/view/exclusive_scan.hpp
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Mitsutaka Takeda 2018-present
|
||||
//
|
||||
// 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_EXCLUSIVE_SCAN_HPP
|
||||
#define RANGES_V3_VIEW_EXCLUSIVE_SCAN_HPP
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/arithmetic.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
// clang-format off
|
||||
/// \concept exclusive_scan_constraints_
|
||||
/// \brief The \c exclusive_scan_constraints_ concept
|
||||
template(typename Rng, typename T, typename Fun)(
|
||||
concept (exclusive_scan_constraints_)(Rng, T, Fun),
|
||||
invocable<Fun &, T, range_reference_t<Rng>> AND
|
||||
assignable_from<T &, invoke_result_t<Fun &, T, range_reference_t<Rng>>>
|
||||
);
|
||||
/// \concept exclusive_scan_constraints
|
||||
/// \brief The \c exclusive_scan_constraints concept
|
||||
template<typename Rng, typename T, typename Fun>
|
||||
CPP_concept exclusive_scan_constraints =
|
||||
viewable_range<Rng> && input_range<Rng> &&
|
||||
copy_constructible<T> &&
|
||||
CPP_concept_ref(ranges::exclusive_scan_constraints_, Rng, T, Fun);
|
||||
// clang-format on
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename T, typename Fun>
|
||||
struct exclusive_scan_view : view_adaptor<exclusive_scan_view<Rng, T, Fun>, Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
CPP_assert(exclusive_scan_constraints<Rng, T, Fun>);
|
||||
|
||||
semiregular_box_t<T> init_;
|
||||
semiregular_box_t<Fun> fun_;
|
||||
using single_pass = meta::bool_<single_pass_iterator_<iterator_t<Rng>>>;
|
||||
using use_sentinel_t = meta::bool_<!common_range<Rng> || single_pass{}>;
|
||||
|
||||
template<bool IsConst>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
friend struct adaptor<!IsConst>;
|
||||
using exclusive_scan_view_t = meta::const_if_c<IsConst, exclusive_scan_view>;
|
||||
using CRng = meta::const_if_c<IsConst, Rng>;
|
||||
semiregular_box_t<T> sum_;
|
||||
exclusive_scan_view_t * rng_;
|
||||
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(move_or_copy_init)(std::false_type)
|
||||
(
|
||||
return (rng_->init_)
|
||||
)
|
||||
|
||||
// If the base range is single-pass, we can move the init value.
|
||||
auto CPP_auto_fun(move_or_copy_init)(std::true_type)
|
||||
(
|
||||
return std::move(rng_->init_)
|
||||
)
|
||||
// clang-format on
|
||||
public : using single_pass = exclusive_scan_view::single_pass;
|
||||
adaptor() = default;
|
||||
adaptor(exclusive_scan_view_t * rng)
|
||||
: rng_(rng)
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
adaptor(adaptor<Other> that)
|
||||
: rng_(that.rng_)
|
||||
{}
|
||||
iterator_t<CRng> begin(exclusive_scan_view_t &)
|
||||
{
|
||||
sum_ = move_or_copy_init(single_pass{});
|
||||
return ranges::begin(rng_->base());
|
||||
}
|
||||
T read(iterator_t<CRng> const &) const
|
||||
{
|
||||
return sum_;
|
||||
}
|
||||
void next(iterator_t<CRng> & it)
|
||||
{
|
||||
RANGES_EXPECT(it != ranges::end(rng_->base()));
|
||||
sum_ = invoke(rng_->fun_, static_cast<T &&>(std::move(sum_)), *it);
|
||||
++it;
|
||||
}
|
||||
void prev() = delete;
|
||||
};
|
||||
|
||||
adaptor<false> begin_adaptor()
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
meta::if_<use_sentinel_t, adaptor_base, adaptor<false>> end_adaptor()
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires exclusive_scan_constraints<Rng const, T, Fun const>)
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
auto end_adaptor() const
|
||||
-> CPP_ret(meta::if_<use_sentinel_t, adaptor_base, adaptor<true>>)(
|
||||
requires exclusive_scan_constraints<Rng const, T, Fun const>)
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
|
||||
public:
|
||||
exclusive_scan_view() = default;
|
||||
constexpr exclusive_scan_view(Rng rng, T init, Fun fun)
|
||||
: exclusive_scan_view::view_adaptor{std::move(rng)}
|
||||
, init_(std::move(init))
|
||||
, fun_(std::move(fun))
|
||||
{}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename T, typename Fun)(
|
||||
requires copy_constructible<T> AND copy_constructible<Fun>)
|
||||
exclusive_scan_view(Rng &&, T, Fun) //
|
||||
-> exclusive_scan_view<views::all_t<Rng>, T, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct exclusive_scan_base_fn
|
||||
{
|
||||
template(typename Rng, typename T, typename Fun = plus)(
|
||||
requires exclusive_scan_constraints<Rng, T, Fun>)
|
||||
constexpr exclusive_scan_view<all_t<Rng>, T, Fun> //
|
||||
operator()(Rng && rng, T init, Fun fun = Fun{}) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(init), std::move(fun)};
|
||||
}
|
||||
};
|
||||
|
||||
struct exclusive_scan_fn : exclusive_scan_base_fn
|
||||
{
|
||||
using exclusive_scan_base_fn::operator();
|
||||
|
||||
template<typename T, typename Fun = plus>
|
||||
constexpr auto operator()(T init, Fun fun = {}) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(exclusive_scan_base_fn{}, std::move(init), std::move(fun)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates exclusive_scan_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(exclusive_scan_fn, exclusive_scan)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_VIEW_EXCLUSIVE_SCAN_HPP
|
||||
137
Telegram/ThirdParty/range-v3/include/range/v3/view/facade.hpp
vendored
Normal file
137
Telegram/ThirdParty/range-v3/include/range/v3/view/facade.hpp
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_FACADE_HPP
|
||||
#define RANGES_V3_VIEW_FACADE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/basic_iterator.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Derived>
|
||||
using begin_cursor_t = detail::decay_t<decltype(
|
||||
range_access::begin_cursor(std::declval<Derived &>()))>;
|
||||
|
||||
template<typename Derived>
|
||||
using end_cursor_t = detail::decay_t<decltype(
|
||||
range_access::end_cursor(std::declval<Derived &>()))>;
|
||||
|
||||
template<typename Derived>
|
||||
using facade_iterator_t = basic_iterator<begin_cursor_t<Derived>>;
|
||||
|
||||
template<typename Derived>
|
||||
using facade_sentinel_t =
|
||||
meta::if_c<same_as<begin_cursor_t<Derived>, end_cursor_t<Derived>>,
|
||||
facade_iterator_t<Derived>, end_cursor_t<Derived>>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// \brief A utility for constructing a view from a (derived) type that
|
||||
/// implements begin and end cursors.
|
||||
/// \tparam Derived A type that derives from `view_facade` and implements
|
||||
/// begin and end cursors. This type is permitted to be incomplete.
|
||||
/// \tparam Cardinality The cardinality of this view: `finite`, `infinite`,
|
||||
/// or `unknown`. See `ranges::cardinality`.
|
||||
template<typename Derived, cardinality Cardinality>
|
||||
struct view_facade : view_interface<Derived, Cardinality>
|
||||
{
|
||||
protected:
|
||||
friend range_access;
|
||||
struct view_as_cursor : Derived
|
||||
{
|
||||
view_as_cursor() = default;
|
||||
explicit view_as_cursor(Derived const * derived)
|
||||
: Derived(*derived)
|
||||
{}
|
||||
explicit operator bool() = delete;
|
||||
explicit operator bool() const = delete;
|
||||
};
|
||||
// Default implementations
|
||||
constexpr view_as_cursor begin_cursor() const
|
||||
{
|
||||
return view_as_cursor{static_cast<Derived const *>(this)};
|
||||
}
|
||||
constexpr default_sentinel_t end_cursor() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
/// Let `d` be `static_cast<Derived &>(*this)`. Let `b` be
|
||||
/// `std::as_const(d).begin_cursor()` if that expression is well-formed;
|
||||
/// otherwise, let `b` be `d.begin_cursor()`. Let `B` be the type of
|
||||
/// `b`.
|
||||
/// \return `ranges::basic_iterator<B>(b)`
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived>)
|
||||
constexpr auto begin() -> detail::facade_iterator_t<D>
|
||||
{
|
||||
return detail::facade_iterator_t<D>{
|
||||
range_access::begin_cursor(*static_cast<Derived *>(this))};
|
||||
}
|
||||
/// \overload
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived>)
|
||||
constexpr auto begin() const -> detail::facade_iterator_t<D const>
|
||||
{
|
||||
return detail::facade_iterator_t<D const>{
|
||||
range_access::begin_cursor(*static_cast<Derived const *>(this))};
|
||||
}
|
||||
/// Let `d` be `static_cast<Derived &>(*this)`. Let `e` be
|
||||
/// `std::as_const(d).end_cursor()` if that expression is well-formed;
|
||||
/// otherwise, let `e` be `d.end_cursor()`. Let `E` be the type of
|
||||
/// `e`.
|
||||
/// \return `ranges::basic_iterator<E>(e)` if `E` is the same
|
||||
/// as `B` computed above for `begin()`; otherwise, return `e`.
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived>)
|
||||
constexpr auto end() -> detail::facade_sentinel_t<D>
|
||||
{
|
||||
return static_cast<detail::facade_sentinel_t<D>>(
|
||||
range_access::end_cursor(*static_cast<Derived *>(this)));
|
||||
}
|
||||
/// \overload
|
||||
template(typename D = Derived)(
|
||||
requires same_as<D, Derived>)
|
||||
constexpr auto end() const -> detail::facade_sentinel_t<D const>
|
||||
{
|
||||
return static_cast<detail::facade_sentinel_t<D const>>(
|
||||
range_access::end_cursor(*static_cast<Derived const *>(this)));
|
||||
}
|
||||
};
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
171
Telegram/ThirdParty/range-v3/include/range/v3/view/filter.hpp
vendored
Normal file
171
Telegram/ThirdParty/range-v3/include/range/v3/view/filter.hpp
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_FILTER_HPP
|
||||
#define RANGES_V3_VIEW_FILTER_HPP
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/compose.hpp>
|
||||
#include <range/v3/functional/not_fn.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/remove_if.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Pred>
|
||||
struct filter_view : remove_if_view<Rng, logical_negate<Pred>>
|
||||
{
|
||||
filter_view() = default;
|
||||
constexpr filter_view(Rng rng, Pred pred)
|
||||
: filter_view::remove_if_view{std::move(rng), not_fn(std::move(pred))}
|
||||
{}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Pred)(
|
||||
requires input_range<Rng> AND indirect_unary_predicate<Pred, iterator_t<Rng>> AND
|
||||
view_<Rng> AND std::is_object<Pred>::value) //
|
||||
filter_view(Rng &&, Pred)
|
||||
->filter_view<views::all_t<Rng>, Pred>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct filter_fn;
|
||||
|
||||
/// Given a source range and a unary predicate,
|
||||
/// present a view of the elements that satisfy the predicate.
|
||||
struct cpp20_filter_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, iterator_t<Rng>>)
|
||||
constexpr filter_view<all_t<Rng>, Pred> operator()(Rng && rng, Pred pred) //
|
||||
const
|
||||
{
|
||||
return filter_view<all_t<Rng>, Pred>{all(static_cast<Rng &&>(rng)),
|
||||
std::move(pred)};
|
||||
}
|
||||
};
|
||||
|
||||
struct cpp20_filter_fn : cpp20_filter_base_fn
|
||||
{
|
||||
using cpp20_filter_base_fn::operator();
|
||||
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(cpp20_filter_base_fn{}, std::move(pred)));
|
||||
}
|
||||
};
|
||||
|
||||
/// Given a source range, unary predicate, and optional projection,
|
||||
/// present a view of the elements that satisfy the predicate.
|
||||
struct filter_base_fn : cpp20_filter_base_fn
|
||||
{
|
||||
using cpp20_filter_base_fn::operator();
|
||||
|
||||
template(typename Rng, typename Pred, typename Proj)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, projected<iterator_t<Rng>, Proj>>)
|
||||
constexpr filter_view<all_t<Rng>, composed<Pred, Proj>> //
|
||||
operator()(Rng && rng, Pred pred, Proj proj) const
|
||||
{
|
||||
return filter_view<all_t<Rng>, composed<Pred, Proj>>{
|
||||
all(static_cast<Rng &&>(rng)),
|
||||
compose(std::move(pred), std::move(proj))};
|
||||
}
|
||||
};
|
||||
|
||||
/// # ranges::views::filter
|
||||
/// The filter view takes in a predicate function `T -> bool` and converts an
|
||||
/// input range of `T` into an output range of `T` by keeping all elements for
|
||||
/// which the predicate returns true.
|
||||
///
|
||||
/// ## Example
|
||||
/// \snippet example/view/filter.cpp filter example
|
||||
///
|
||||
/// ### Output
|
||||
/// \include example/view/filter_golden.txt
|
||||
///
|
||||
/// ## Syntax
|
||||
/// ```cpp
|
||||
/// auto output_range = input_range | ranges::views::filter(filter_func);
|
||||
/// ```
|
||||
///
|
||||
/// ## Parameters
|
||||
/// <pre><b>filter_func</b></pre>
|
||||
/// - Called once for each element of the input range
|
||||
/// - Returns true for elements that should present in the output range
|
||||
///
|
||||
/// <pre><b>input_range</b></pre>
|
||||
/// - The range of elements to filter
|
||||
/// - Reference type: `T`
|
||||
///
|
||||
/// <pre><b>output_range</b></pre>
|
||||
/// - The range of filtered values
|
||||
/// - Is either a `forward_range` or the concept satisfied by the input
|
||||
/// - Is a `common_range` if the input is a `common_range`
|
||||
/// - Is not a `sized_range` or `borrowed_range`
|
||||
/// - Reference type: `T`
|
||||
///
|
||||
struct filter_fn : filter_base_fn
|
||||
{
|
||||
using filter_base_fn::operator();
|
||||
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const
|
||||
{
|
||||
return make_view_closure(bind_back(filter_base_fn{}, std::move(pred)));
|
||||
}
|
||||
|
||||
template(typename Pred, typename Proj)(
|
||||
requires (!range<Pred>))
|
||||
constexpr auto operator()(Pred pred, Proj proj) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(filter_base_fn{}, std::move(pred), std::move(proj)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates filter_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(filter_fn, filter)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
RANGES_INLINE_VARIABLE(ranges::views::cpp20_filter_fn, filter)
|
||||
}
|
||||
template(typename V, typename Pred)(
|
||||
requires input_range<V> AND indirect_unary_predicate<Pred, iterator_t<V>> AND
|
||||
view_<V> AND std::is_object<Pred>::value) //
|
||||
using filter_view = ranges::filter_view<V, Pred>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::filter_view)
|
||||
|
||||
#endif
|
||||
138
Telegram/ThirdParty/range-v3/include/range/v3/view/for_each.hpp
vendored
Normal file
138
Telegram/ThirdParty/range-v3/include/range/v3/view/for_each.hpp
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_FOR_EACH_HPP
|
||||
#define RANGES_V3_VIEW_FOR_EACH_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/generate_n.hpp>
|
||||
#include <range/v3/view/join.hpp>
|
||||
#include <range/v3/view/repeat_n.hpp>
|
||||
#include <range/v3/view/single.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
namespace views
|
||||
{
|
||||
/// Lazily applies an unary function to each element in the source
|
||||
/// range that returns another range (possibly empty), flattening
|
||||
/// the result.
|
||||
struct for_each_base_fn
|
||||
{
|
||||
template(typename Rng, typename Fun)(
|
||||
requires viewable_range<Rng> AND transformable_range<Rng, Fun> AND
|
||||
joinable_range<transform_view<all_t<Rng>, Fun>>)
|
||||
constexpr auto operator()(Rng && rng, Fun fun) const
|
||||
{
|
||||
return join(transform(static_cast<Rng &&>(rng), std::move(fun)));
|
||||
}
|
||||
};
|
||||
|
||||
struct for_each_fn : for_each_base_fn
|
||||
{
|
||||
using for_each_base_fn::operator();
|
||||
|
||||
template<typename Fun>
|
||||
constexpr auto operator()(Fun fun) const
|
||||
{
|
||||
return make_view_closure(bind_back(for_each_base_fn{}, std::move(fun)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates for_each_fn
|
||||
RANGES_INLINE_VARIABLE(for_each_fn, for_each)
|
||||
} // namespace views
|
||||
|
||||
struct yield_fn
|
||||
{
|
||||
template(typename V)(
|
||||
requires copy_constructible<V>)
|
||||
single_view<V> operator()(V v) const
|
||||
{
|
||||
return views::single(std::move(v));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates yield_fn
|
||||
RANGES_INLINE_VARIABLE(yield_fn, yield)
|
||||
|
||||
struct yield_from_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires view_<Rng>)
|
||||
Rng operator()(Rng rng) const
|
||||
{
|
||||
return rng;
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates yield_from_fn
|
||||
RANGES_INLINE_VARIABLE(yield_from_fn, yield_from)
|
||||
|
||||
struct yield_if_fn
|
||||
{
|
||||
template<typename V>
|
||||
repeat_n_view<V> operator()(bool b, V v) const
|
||||
{
|
||||
return views::repeat_n(std::move(v), b ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates yield_if_fn
|
||||
RANGES_INLINE_VARIABLE(yield_if_fn, yield_if)
|
||||
|
||||
struct lazy_yield_if_fn
|
||||
{
|
||||
template(typename F)(
|
||||
requires invocable<F &>)
|
||||
generate_n_view<F> operator()(bool b, F f) const
|
||||
{
|
||||
return views::generate_n(std::move(f), b ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates lazy_yield_if_fn
|
||||
RANGES_INLINE_VARIABLE(lazy_yield_if_fn, lazy_yield_if)
|
||||
/// @}
|
||||
|
||||
/// \cond
|
||||
template(typename Rng, typename Fun)(
|
||||
requires viewable_range<Rng> AND views::transformable_range<Rng, Fun> AND
|
||||
input_range<invoke_result_t<Fun &, range_reference_t<Rng>>>)
|
||||
auto
|
||||
operator>>=(Rng && rng, Fun fun)
|
||||
{
|
||||
return views::for_each(static_cast<Rng &&>(rng), std::move(fun));
|
||||
}
|
||||
/// \endcond
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
120
Telegram/ThirdParty/range-v3/include/range/v3/view/generate.hpp
vendored
Normal file
120
Telegram/ThirdParty/range-v3/include/range/v3/view/generate.hpp
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_GENERATE_HPP
|
||||
#define RANGES_V3_VIEW_GENERATE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename G>
|
||||
struct generate_view : view_facade<generate_view<G>, infinite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
using result_t = invoke_result_t<G &>;
|
||||
semiregular_box_t<G> gen_;
|
||||
detail::non_propagating_cache<result_t> val_;
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
generate_view * view_;
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
explicit cursor(generate_view * view)
|
||||
: view_(view)
|
||||
{}
|
||||
result_t && read() const
|
||||
{
|
||||
if(!view_->val_)
|
||||
view_->val_.emplace(view_->gen_());
|
||||
return static_cast<result_t &&>(static_cast<result_t &>(*view_->val_));
|
||||
}
|
||||
void next()
|
||||
{
|
||||
if(view_->val_)
|
||||
view_->val_.reset();
|
||||
else
|
||||
static_cast<void>(view_->gen_());
|
||||
}
|
||||
};
|
||||
cursor begin_cursor()
|
||||
{
|
||||
return cursor{this};
|
||||
}
|
||||
unreachable_sentinel_t end_cursor() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
generate_view() = default;
|
||||
explicit generate_view(G g)
|
||||
: gen_(std::move(g))
|
||||
{}
|
||||
result_t & cached()
|
||||
{
|
||||
return *val_;
|
||||
}
|
||||
};
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct generate_fn
|
||||
{
|
||||
template(typename G)(
|
||||
requires invocable<G &> AND copy_constructible<G> AND
|
||||
std::is_object<detail::decay_t<invoke_result_t<G &>>>::value AND
|
||||
constructible_from<detail::decay_t<invoke_result_t<G &>>,
|
||||
invoke_result_t<G &>> AND
|
||||
assignable_from<detail::decay_t<invoke_result_t<G &>> &,
|
||||
invoke_result_t<G &>>)
|
||||
generate_view<G> operator()(G g) const
|
||||
{
|
||||
return generate_view<G>{std::move(g)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates generate_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(generate_fn, generate)
|
||||
} // namespace views
|
||||
/// \@}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::generate_view)
|
||||
|
||||
#endif
|
||||
127
Telegram/ThirdParty/range-v3/include/range/v3/view/generate_n.hpp
vendored
Normal file
127
Telegram/ThirdParty/range-v3/include/range/v3/view/generate_n.hpp
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_GENERATE_N_HPP
|
||||
#define RANGES_V3_VIEW_GENERATE_N_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/generate.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename G>
|
||||
struct generate_n_view : view_facade<generate_n_view<G>, finite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
using result_t = invoke_result_t<G &>;
|
||||
semiregular_box_t<G> gen_;
|
||||
detail::non_propagating_cache<result_t> val_;
|
||||
std::size_t n_;
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
generate_n_view * rng_;
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
explicit cursor(generate_n_view * rng)
|
||||
: rng_(rng)
|
||||
{}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return 0 == rng_->n_;
|
||||
}
|
||||
result_t && read() const
|
||||
{
|
||||
if(!rng_->val_)
|
||||
rng_->val_.emplace(rng_->gen_());
|
||||
return static_cast<result_t &&>(static_cast<result_t &>(*rng_->val_));
|
||||
}
|
||||
void next()
|
||||
{
|
||||
RANGES_EXPECT(0 != rng_->n_);
|
||||
if(rng_->val_)
|
||||
rng_->val_.reset();
|
||||
else
|
||||
static_cast<void>(rng_->gen_());
|
||||
--rng_->n_;
|
||||
}
|
||||
};
|
||||
cursor begin_cursor()
|
||||
{
|
||||
return cursor{this};
|
||||
}
|
||||
|
||||
public:
|
||||
generate_n_view() = default;
|
||||
explicit generate_n_view(G g, std::size_t n)
|
||||
: gen_(std::move(g))
|
||||
, n_(n)
|
||||
{}
|
||||
result_t & cached()
|
||||
{
|
||||
return *val_;
|
||||
}
|
||||
std::size_t size() const
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
};
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct generate_n_fn
|
||||
{
|
||||
template(typename G)(
|
||||
requires invocable<G &> AND copy_constructible<G> AND
|
||||
std::is_object<detail::decay_t<invoke_result_t<G &>>>::value AND
|
||||
constructible_from<detail::decay_t<invoke_result_t<G &>>,
|
||||
invoke_result_t<G &>> AND
|
||||
assignable_from<detail::decay_t<invoke_result_t<G &>> &,
|
||||
invoke_result_t<G &>>)
|
||||
generate_n_view<G> operator()(G g, std::size_t n) const
|
||||
{
|
||||
return generate_n_view<G>{std::move(g), n};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates generate_n_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(generate_n_fn, generate_n)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::generate_n_view)
|
||||
|
||||
#endif
|
||||
112
Telegram/ThirdParty/range-v3/include/range/v3/view/getlines.hpp
vendored
Normal file
112
Telegram/ThirdParty/range-v3/include/range/v3/view/getlines.hpp
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_GETLINES_HPP
|
||||
#define RANGES_V3_VIEW_GETLINES_HPP
|
||||
|
||||
#include <istream>
|
||||
#include <string>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
struct getlines_view : view_facade<getlines_view, unknown>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
std::istream * sin_;
|
||||
std::string str_;
|
||||
char delim_;
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
using single_pass = std::true_type;
|
||||
getlines_view * rng_ = nullptr;
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
explicit cursor(getlines_view * rng)
|
||||
: rng_(rng)
|
||||
{}
|
||||
void next()
|
||||
{
|
||||
rng_->next();
|
||||
}
|
||||
std::string & read() const noexcept
|
||||
{
|
||||
return rng_->str_;
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return !rng_->sin_;
|
||||
}
|
||||
bool equal(cursor that) const
|
||||
{
|
||||
return !rng_->sin_ == !that.rng_->sin_;
|
||||
}
|
||||
};
|
||||
void next()
|
||||
{
|
||||
if(!std::getline(*sin_, str_, delim_))
|
||||
sin_ = nullptr;
|
||||
}
|
||||
cursor begin_cursor()
|
||||
{
|
||||
return cursor{this};
|
||||
}
|
||||
|
||||
public:
|
||||
getlines_view() = default;
|
||||
getlines_view(std::istream & sin, char delim = '\n')
|
||||
: sin_(&sin)
|
||||
, str_{}
|
||||
, delim_(delim)
|
||||
{
|
||||
this->next(); // prime the pump
|
||||
}
|
||||
std::string & cached() noexcept
|
||||
{
|
||||
return str_;
|
||||
}
|
||||
};
|
||||
|
||||
/// \cond
|
||||
using getlines_range RANGES_DEPRECATED(
|
||||
"getlines_range has been renamed getlines_view") = getlines_view;
|
||||
/// \endcond
|
||||
|
||||
struct getlines_fn
|
||||
{
|
||||
getlines_view operator()(std::istream & sin, char delim = '\n') const
|
||||
{
|
||||
return getlines_view{sin, delim};
|
||||
}
|
||||
};
|
||||
|
||||
RANGES_INLINE_VARIABLE(getlines_fn, getlines)
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
213
Telegram/ThirdParty/range-v3/include/range/v3/view/group_by.hpp
vendored
Normal file
213
Telegram/ThirdParty/range-v3/include/range/v3/view/group_by.hpp
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_GROUP_BY_HPP
|
||||
#define RANGES_V3_VIEW_GROUP_BY_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/find_if_not.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.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/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/take_while.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/config.hpp>
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
// TODO group_by could support Input ranges by keeping mutable state in
|
||||
// the range itself. The group_by view would then be mutable-only and
|
||||
// Input.
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Fun>
|
||||
struct group_by_view
|
||||
: view_facade<group_by_view<Rng, Fun>,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
Rng rng_;
|
||||
// cached version of the end of the first subrange / start of the second subrange
|
||||
detail::non_propagating_cache<iterator_t<Rng>> second_;
|
||||
semiregular_box_t<Fun> fun_;
|
||||
|
||||
struct pred
|
||||
{
|
||||
iterator_t<Rng> first_;
|
||||
semiregular_box_ref_or_val_t<Fun, false> fun_;
|
||||
bool operator()(range_reference_t<Rng> r) const
|
||||
{
|
||||
return invoke(fun_, *first_, r);
|
||||
}
|
||||
};
|
||||
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
friend group_by_view;
|
||||
iterator_t<Rng> cur_;
|
||||
iterator_t<Rng> next_cur_;
|
||||
sentinel_t<Rng> last_;
|
||||
semiregular_box_ref_or_val_t<Fun, false> fun_;
|
||||
|
||||
struct mixin : basic_mixin<cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
#ifndef _MSC_VER
|
||||
using basic_mixin<cursor>::basic_mixin;
|
||||
#else
|
||||
constexpr explicit mixin(cursor && cur)
|
||||
: basic_mixin<cursor>(static_cast<cursor &&>(cur))
|
||||
{}
|
||||
constexpr explicit mixin(cursor const & cur)
|
||||
: basic_mixin<cursor>(cur)
|
||||
{}
|
||||
#endif
|
||||
iterator_t<Rng> base() const
|
||||
{
|
||||
return this->get().cur_;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
template<typename I = iterator_t<Rng>>
|
||||
subrange<I> read() const
|
||||
{
|
||||
return {cur_, next_cur_};
|
||||
}
|
||||
#else
|
||||
subrange<iterator_t<Rng>> read() const
|
||||
{
|
||||
return {cur_, next_cur_};
|
||||
}
|
||||
#endif
|
||||
void next()
|
||||
{
|
||||
cur_ = next_cur_;
|
||||
next_cur_ = cur_ != last_
|
||||
? find_if_not(ranges::next(cur_), last_, pred{cur_, fun_})
|
||||
: cur_;
|
||||
}
|
||||
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return cur_ == last_;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return cur_ == that.cur_;
|
||||
}
|
||||
cursor(semiregular_box_ref_or_val_t<Fun, false> fun, iterator_t<Rng> first,
|
||||
iterator_t<Rng> next_cur, sentinel_t<Rng> last)
|
||||
: cur_(first)
|
||||
, next_cur_(next_cur)
|
||||
, last_(last)
|
||||
, fun_(fun)
|
||||
{}
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
};
|
||||
cursor begin_cursor()
|
||||
{
|
||||
auto b = ranges::begin(rng_);
|
||||
auto e = ranges::end(rng_);
|
||||
if(!second_)
|
||||
{
|
||||
second_ = b != e ? find_if_not(ranges::next(b), e, pred{b, fun_}) : b;
|
||||
}
|
||||
return {fun_, b, *second_, e};
|
||||
}
|
||||
|
||||
public:
|
||||
group_by_view() = default;
|
||||
constexpr group_by_view(Rng rng, Fun fun)
|
||||
: rng_(std::move(rng))
|
||||
, fun_(std::move(fun))
|
||||
{}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Fun>)
|
||||
group_by_view(Rng &&, Fun)
|
||||
->group_by_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct group_by_base_fn
|
||||
{
|
||||
template(typename Rng, typename Fun)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng> AND
|
||||
indirect_relation<Fun, iterator_t<Rng>>)
|
||||
RANGES_DEPRECATED(
|
||||
"views::group_by is deprecated. Please use views::chunk_by instead. "
|
||||
"Note that views::chunk_by evaluates the predicate between adjacent "
|
||||
"elements.")
|
||||
constexpr group_by_view<all_t<Rng>, Fun> operator()(Rng && rng, Fun fun) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(fun)};
|
||||
}
|
||||
};
|
||||
|
||||
struct group_by_fn : group_by_base_fn
|
||||
{
|
||||
using group_by_base_fn::operator();
|
||||
|
||||
template<typename Fun>
|
||||
RANGES_DEPRECATED(
|
||||
"views::group_by is deprecated. Please use views::chunk_by instead. "
|
||||
"Note that views::chunk_by evaluates the predicate between adjacent "
|
||||
"elements.")
|
||||
constexpr auto operator()(Fun fun) const
|
||||
{
|
||||
return make_view_closure(bind_back(group_by_base_fn{}, std::move(fun)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates group_by_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(group_by_fn, group_by)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::group_by_view)
|
||||
|
||||
#endif
|
||||
80
Telegram/ThirdParty/range-v3/include/range/v3/view/indices.hpp
vendored
Normal file
80
Telegram/ThirdParty/range-v3/include/range/v3/view/indices.hpp
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
// Copyright Gonzalo Brito Gadeschi
|
||||
//
|
||||
// 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_INDICES_HPP
|
||||
#define RANGES_V3_VIEW_INDICES_HPP
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/iota.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
/// Half-open range of indices: [from, to).
|
||||
struct indices_fn : iota_view<std::size_t>
|
||||
{
|
||||
indices_fn() = default;
|
||||
|
||||
template(typename Val)(
|
||||
requires integral<Val>)
|
||||
iota_view<Val, Val> operator()(Val to) const
|
||||
{
|
||||
return {Val(), to};
|
||||
}
|
||||
template(typename Val)(
|
||||
requires integral<Val>)
|
||||
iota_view<Val, Val> operator()(Val from, Val to) const
|
||||
{
|
||||
return {from, to};
|
||||
}
|
||||
};
|
||||
|
||||
/// Inclusive range of indices: [from, to].
|
||||
struct closed_indices_fn
|
||||
{
|
||||
template(typename Val)(
|
||||
requires integral<Val>)
|
||||
closed_iota_view<Val> operator()(Val to) const
|
||||
{
|
||||
return {Val(), to};
|
||||
}
|
||||
template(typename Val)(
|
||||
requires integral<Val>)
|
||||
closed_iota_view<Val> operator()(Val from, Val to) const
|
||||
{
|
||||
return {from, to};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates indices_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(indices_fn, indices)
|
||||
|
||||
/// \relates closed_indices_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(closed_indices_fn, closed_indices)
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_VIEW_INDICES_HPP
|
||||
156
Telegram/ThirdParty/range-v3/include/range/v3/view/indirect.hpp
vendored
Normal file
156
Telegram/ThirdParty/range-v3/include/range/v3/view/indirect.hpp
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_INDIRECT_HPP
|
||||
#define RANGES_V3_VIEW_INDIRECT_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/move.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct indirect_view : view_adaptor<indirect_view<Rng>, Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
template<bool IsConst>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
friend adaptor<!IsConst>;
|
||||
using CRng = meta::const_if_c<IsConst, Rng>;
|
||||
|
||||
adaptor() = default;
|
||||
template(bool Other)(
|
||||
requires IsConst && CPP_NOT(Other)) //
|
||||
constexpr adaptor(adaptor<Other>) noexcept
|
||||
{}
|
||||
|
||||
// clang-format off
|
||||
constexpr auto CPP_auto_fun(read)(iterator_t<CRng> const &it)(const)
|
||||
(
|
||||
return **it
|
||||
)
|
||||
constexpr auto CPP_auto_fun(iter_move)(iterator_t<CRng> const &it)(const)
|
||||
(
|
||||
return ranges::iter_move(*it)
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
CPP_member
|
||||
constexpr auto begin_adaptor() noexcept //
|
||||
-> CPP_ret(adaptor<false>)(
|
||||
requires (!simple_view<Rng>()))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto begin_adaptor() const noexcept //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() noexcept //
|
||||
-> CPP_ret(adaptor<false>)(
|
||||
requires (!simple_view<Rng>()))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() const noexcept //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
indirect_view() = default;
|
||||
constexpr explicit indirect_view(Rng rng)
|
||||
: indirect_view::view_adaptor{detail::move(rng)}
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<indirect_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
indirect_view(Rng &&) //
|
||||
-> indirect_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct indirect_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
// We shouldn't need to strip references to test if something
|
||||
// is readable. https://github.com/ericniebler/stl2/issues/594
|
||||
// indirectly_readable<range_reference_t<Rng>>)
|
||||
((bool)indirectly_readable<range_value_t<Rng>>)) // Cast to bool needed
|
||||
// for GCC (???))
|
||||
constexpr auto operator()(Rng && rng) const
|
||||
{
|
||||
return indirect_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates indirect_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<indirect_fn>, indirect)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::indirect_view)
|
||||
|
||||
#endif
|
||||
515
Telegram/ThirdParty/range-v3/include/range/v3/view/interface.hpp
vendored
Normal file
515
Telegram/ThirdParty/range-v3/include/range/v3/view/interface.hpp
vendored
Normal file
@@ -0,0 +1,515 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_INTERFACE_HPP
|
||||
#define RANGES_V3_VIEW_INTERFACE_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/common_iterator.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
#if defined(RANGES_WORKAROUND_GCC_91525)
|
||||
#define CPP_template_gcc_workaround CPP_template_sfinae
|
||||
#else
|
||||
#define CPP_template_gcc_workaround template
|
||||
#endif
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename From, typename To = From>
|
||||
struct slice_bounds
|
||||
{
|
||||
From from;
|
||||
To to;
|
||||
template(typename F, typename T)(
|
||||
requires convertible_to<F, From> AND convertible_to<T, To>)
|
||||
constexpr slice_bounds(F f, T t)
|
||||
: from(static_cast<From>(f))
|
||||
, to(static_cast<To>(t))
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Int>
|
||||
struct from_end_
|
||||
{
|
||||
Int dist_;
|
||||
|
||||
constexpr explicit from_end_(Int dist)
|
||||
: dist_(dist)
|
||||
{}
|
||||
|
||||
template(typename Other)(
|
||||
requires integer_like_<Other> AND explicitly_convertible_to<Other, Int>)
|
||||
constexpr operator from_end_<Other>() const
|
||||
{
|
||||
return from_end_<Other>{static_cast<Other>(dist_)};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
using from_end_of_t = from_end_<range_difference_t<Rng>>;
|
||||
|
||||
// clang-format off
|
||||
/// \concept _can_empty_
|
||||
/// \brief The \c _can_empty_ concept
|
||||
template<typename Rng>
|
||||
CPP_requires(_can_empty_,
|
||||
requires(Rng & rng) //
|
||||
(
|
||||
ranges::empty(rng)
|
||||
));
|
||||
/// \concept can_empty_
|
||||
/// \brief The \c can_empty_ concept
|
||||
template<typename Rng>
|
||||
CPP_concept can_empty_ = //
|
||||
CPP_requires_ref(detail::_can_empty_, Rng);
|
||||
// clang-format on
|
||||
|
||||
template<cardinality C>
|
||||
RANGES_INLINE_VAR constexpr bool has_fixed_size_ = (C >= 0 || C == infinite);
|
||||
|
||||
template<bool>
|
||||
struct dependent_
|
||||
{
|
||||
template<typename T>
|
||||
using invoke = T;
|
||||
};
|
||||
|
||||
template<typename Stream, typename Rng>
|
||||
Stream & print_rng_(Stream & sout, Rng & rng)
|
||||
{
|
||||
sout << '[';
|
||||
auto it = ranges::begin(rng);
|
||||
auto const e = ranges::end(rng);
|
||||
if(it != e)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
sout << *it;
|
||||
if(++it == e)
|
||||
break;
|
||||
sout << ',';
|
||||
}
|
||||
}
|
||||
sout << ']';
|
||||
return sout;
|
||||
}
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Derived, cardinality Cardinality /* = finite*/>
|
||||
struct view_interface : basic_view<Cardinality>
|
||||
{
|
||||
protected:
|
||||
template<bool B>
|
||||
using D = meta::invoke<detail::dependent_<B>, Derived>;
|
||||
|
||||
constexpr Derived & derived() noexcept
|
||||
{
|
||||
CPP_assert(derived_from<Derived, view_interface>);
|
||||
return static_cast<Derived &>(*this);
|
||||
}
|
||||
/// \overload
|
||||
constexpr Derived const & derived() const noexcept
|
||||
{
|
||||
CPP_assert(derived_from<Derived, view_interface>);
|
||||
return static_cast<Derived const &>(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
view_interface() = default;
|
||||
view_interface(view_interface &&) = default;
|
||||
view_interface(view_interface const &) = default;
|
||||
view_interface & operator=(view_interface &&) = default;
|
||||
view_interface & operator=(view_interface const &) = default;
|
||||
/// \brief Test whether a range can be empty:
|
||||
CPP_member
|
||||
constexpr auto empty() const noexcept //
|
||||
-> CPP_ret(bool)(
|
||||
requires (detail::has_fixed_size_<Cardinality>))
|
||||
{
|
||||
return Cardinality == 0;
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
|
||||
(!forward_range<D<True>>) AND sized_range<D<True>>)
|
||||
constexpr bool empty() //
|
||||
noexcept(noexcept(bool(ranges::size(std::declval<D<True> &>()) == 0)))
|
||||
{
|
||||
return ranges::size(derived()) == 0;
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
|
||||
(!forward_range<D<True> const>) AND sized_range<D<True> const>)
|
||||
constexpr bool empty() const //
|
||||
noexcept(noexcept(bool(ranges::size(std::declval<D<True> const &>()) == 0)))
|
||||
{
|
||||
return ranges::size(derived()) == 0;
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND (!detail::has_fixed_size_<Cardinality>) AND
|
||||
forward_range<D<True>>)
|
||||
constexpr bool empty() noexcept(
|
||||
noexcept(bool(ranges::begin(std::declval<D<True> &>()) ==
|
||||
ranges::end(std::declval<D<True> &>()))))
|
||||
{
|
||||
return bool(ranges::begin(derived()) == ranges::end(derived()));
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND (!detail::has_fixed_size_<Cardinality>) AND
|
||||
forward_range<D<True> const>)
|
||||
constexpr bool empty() const
|
||||
noexcept(noexcept(bool(ranges::begin(std::declval<D<True> const &>()) ==
|
||||
ranges::end(std::declval<D<True> const &>()))))
|
||||
{
|
||||
return bool(ranges::begin(derived()) == ranges::end(derived()));
|
||||
}
|
||||
CPP_template_gcc_workaround(bool True = true)(
|
||||
requires True && detail::can_empty_<D<True>>) // clang-format off
|
||||
constexpr explicit operator bool()
|
||||
noexcept(noexcept(ranges::empty(std::declval<D<True> &>())))
|
||||
{
|
||||
return !ranges::empty(derived());
|
||||
}
|
||||
// clang-format on
|
||||
/// \overload
|
||||
CPP_template_gcc_workaround(bool True = true)(
|
||||
requires True && detail::can_empty_<D<True> const>) // clang-format off
|
||||
constexpr explicit operator bool() const
|
||||
noexcept(noexcept(ranges::empty(std::declval<D<True> const &>())))
|
||||
{
|
||||
return !ranges::empty(derived());
|
||||
}
|
||||
// clang-format on
|
||||
/// If the size of the range is known at compile-time and finite,
|
||||
/// return it.
|
||||
template(bool True = true, int = 42)(
|
||||
requires True AND (Cardinality >= 0)) //
|
||||
static constexpr std::size_t size() noexcept
|
||||
{
|
||||
return static_cast<std::size_t>(Cardinality);
|
||||
}
|
||||
/// If `sized_sentinel_for<sentinel_t<Derived>, iterator_t<Derived>>` is
|
||||
/// satisfied, and if `Derived` is a `forward_range`, then return
|
||||
/// `end - begin` cast to an unsigned integer.
|
||||
template(bool True = true)(
|
||||
requires True AND (Cardinality < 0) AND
|
||||
sized_sentinel_for<sentinel_t<D<True>>, iterator_t<D<True>>> AND
|
||||
forward_range<D<True>>)
|
||||
constexpr detail::iter_size_t<iterator_t<D<True>>> size()
|
||||
{
|
||||
using size_type = detail::iter_size_t<iterator_t<D<True>>>;
|
||||
return static_cast<size_type>(derived().end() - derived().begin());
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND (Cardinality < 0) AND
|
||||
sized_sentinel_for<sentinel_t<D<True> const>,
|
||||
iterator_t<D<True> const>> AND
|
||||
forward_range<D<True> const>)
|
||||
constexpr detail::iter_size_t<iterator_t<D<True>>> size() const //
|
||||
{
|
||||
using size_type = detail::iter_size_t<iterator_t<D<True>>>;
|
||||
return static_cast<size_type>(derived().end() - derived().begin());
|
||||
}
|
||||
/// Access the first element in a range:
|
||||
template(bool True = true)(
|
||||
requires True AND forward_range<D<True>>)
|
||||
constexpr range_reference_t<D<True>> front()
|
||||
{
|
||||
return *derived().begin();
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND forward_range<D<True> const>)
|
||||
constexpr range_reference_t<D<True> const> front() const
|
||||
{
|
||||
return *derived().begin();
|
||||
}
|
||||
/// Access the last element in a range:
|
||||
template(bool True = true)(
|
||||
requires True AND common_range<D<True>> AND bidirectional_range<D<True>>)
|
||||
constexpr range_reference_t<D<True>> back()
|
||||
{
|
||||
return *prev(derived().end());
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND common_range<D<True> const> AND
|
||||
bidirectional_range<D<True> const>)
|
||||
constexpr range_reference_t<D<True> const> back() const
|
||||
{
|
||||
return *prev(derived().end());
|
||||
}
|
||||
/// Simple indexing:
|
||||
template(bool True = true)(
|
||||
requires True AND random_access_range<D<True>>)
|
||||
constexpr range_reference_t<D<True>> operator[](range_difference_t<D<True>> n)
|
||||
{
|
||||
return derived().begin()[n];
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND random_access_range<D<True> const>)
|
||||
constexpr range_reference_t<D<True> const> //
|
||||
operator[](range_difference_t<D<True>> n) const
|
||||
{
|
||||
return derived().begin()[n];
|
||||
}
|
||||
/// Returns a pointer to the block of memory
|
||||
/// containing the elements of a contiguous range:
|
||||
template(bool True = true)(
|
||||
requires True AND contiguous_iterator<iterator_t<D<True>>>)
|
||||
constexpr std::add_pointer_t<range_reference_t<D<True>>> data() //
|
||||
{
|
||||
return std::addressof(*ranges::begin(derived()));
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND contiguous_iterator<iterator_t<D<True> const>>)
|
||||
constexpr std::add_pointer_t<range_reference_t<D<True> const>> data() const //
|
||||
{
|
||||
return std::addressof(*ranges::begin(derived()));
|
||||
}
|
||||
/// Returns a reference to the element at specified location pos, with bounds
|
||||
/// checking.
|
||||
template(bool True = true)(
|
||||
requires True AND random_access_range<D<True>> AND sized_range<D<True>>)
|
||||
constexpr range_reference_t<D<True>> at(range_difference_t<D<True>> n)
|
||||
{
|
||||
using size_type = range_size_t<Derived>;
|
||||
if(n < 0 || size_type(n) >= ranges::size(derived()))
|
||||
{
|
||||
throw std::out_of_range("view_interface::at");
|
||||
}
|
||||
return derived().begin()[n];
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true)(
|
||||
requires True AND random_access_range<D<True> const> AND
|
||||
sized_range<D<True> const>)
|
||||
constexpr range_reference_t<D<True> const> at(range_difference_t<D<True>> n) const
|
||||
{
|
||||
using size_type = range_size_t<Derived const>;
|
||||
if(n < 0 || size_type(n) >= ranges::size(derived()))
|
||||
{
|
||||
throw std::out_of_range("view_interface::at");
|
||||
}
|
||||
return derived().begin()[n];
|
||||
}
|
||||
/// Python-ic slicing:
|
||||
// rng[{4,6}]
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True> &>)
|
||||
constexpr auto
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True> const &>)
|
||||
constexpr auto
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) const &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True>>)
|
||||
constexpr auto
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &&
|
||||
{
|
||||
return Slice{}(detail::move(derived()), offs.from, offs.to);
|
||||
}
|
||||
// rng[{4,end-2}]
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True> &> AND sized_range<D<True> &>)
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>,
|
||||
detail::from_end_of_t<D<True>>> offs) &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True> const &> AND
|
||||
sized_range<D<True> const &>)
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>,
|
||||
detail::from_end_of_t<D<True>>> offs) const &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True>> AND sized_range<D<True>>)
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>,
|
||||
detail::from_end_of_t<D<True>>> offs) &&
|
||||
{
|
||||
return Slice{}(detail::move(derived()), offs.from, offs.to);
|
||||
}
|
||||
// rng[{end-4,end-2}]
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND (forward_range<D<True> &> ||
|
||||
(input_range<D<True> &> && sized_range<D<True> &>))) //
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
|
||||
detail::from_end_of_t<D<True>>> offs) &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND
|
||||
(forward_range<D<True> const &> ||
|
||||
(input_range<D<True> const &> && sized_range<D<True> const &>))) //
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
|
||||
detail::from_end_of_t<D<True>>> offs) const &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND
|
||||
(forward_range<D<True>> ||
|
||||
(input_range<D<True>> && sized_range<D<True>>))) //
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
|
||||
detail::from_end_of_t<D<True>>> offs) &&
|
||||
{
|
||||
return Slice{}(detail::move(derived()), offs.from, offs.to);
|
||||
}
|
||||
// rng[{4,end}]
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True> &>)
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True> const &>)
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) const &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND input_range<D<True>>)
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &&
|
||||
{
|
||||
return Slice{}(detail::move(derived()), offs.from, offs.to);
|
||||
}
|
||||
// rng[{end-4,end}]
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND
|
||||
(forward_range<D<True> &> ||
|
||||
(input_range<D<True> &> && sized_range<D<True> &>))) //
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND
|
||||
(forward_range<D<True> const &> ||
|
||||
(input_range<D<True> const &> && sized_range<D<True> const &>))) //
|
||||
constexpr auto //
|
||||
operator[](
|
||||
detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) const &
|
||||
{
|
||||
return Slice{}(derived(), offs.from, offs.to);
|
||||
}
|
||||
/// \overload
|
||||
template(bool True = true, typename Slice = views::slice_fn)(
|
||||
requires True AND
|
||||
(forward_range<D<True>> ||
|
||||
(input_range<D<True>> && sized_range<D<True>>))) //
|
||||
constexpr auto //
|
||||
operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &&
|
||||
{
|
||||
return Slice{}(detail::move(derived()), offs.from, offs.to);
|
||||
}
|
||||
private:
|
||||
#ifndef RANGES_V3_DISABLE_IO
|
||||
/// \brief Print a range to an ostream
|
||||
template<bool True = true>
|
||||
friend auto operator<<(std::ostream & sout, Derived const & rng)
|
||||
-> CPP_broken_friend_ret(std::ostream &)(
|
||||
requires True && input_range<D<True> const>)
|
||||
{
|
||||
return detail::print_rng_(sout, rng);
|
||||
}
|
||||
/// \overload
|
||||
template<bool True = true>
|
||||
friend auto operator<<(std::ostream & sout, Derived & rng)
|
||||
-> CPP_broken_friend_ret(std::ostream &)(
|
||||
requires True && (!range<D<True> const>) && input_range<D<True>>)
|
||||
{
|
||||
return detail::print_rng_(sout, rng);
|
||||
}
|
||||
/// \overload
|
||||
template<bool True = true>
|
||||
friend auto operator<<(std::ostream & sout, Derived && rng)
|
||||
-> CPP_broken_friend_ret(std::ostream &)(
|
||||
requires True && (!range<D<True> const>) && input_range<D<True>>)
|
||||
{
|
||||
return detail::print_rng_(sout, rng);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
namespace cpp20
|
||||
{
|
||||
template(typename Derived)(
|
||||
requires std::is_class<Derived>::value AND
|
||||
same_as<Derived, meta::_t<std::remove_cv<Derived>>>)
|
||||
using view_interface = ranges::view_interface<Derived, ranges::unknown>;
|
||||
}
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
254
Telegram/ThirdParty/range-v3/include/range/v3/view/intersperse.hpp
vendored
Normal file
254
Telegram/ThirdParty/range-v3/include/range/v3/view/intersperse.hpp
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_INTERSPERSE_HPP
|
||||
#define RANGES_V3_VIEW_INTERSPERSE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct intersperse_view
|
||||
: view_adaptor<intersperse_view<Rng>, Rng,
|
||||
(range_cardinality<Rng>::value > 0)
|
||||
? static_cast<cardinality>(range_cardinality<Rng>::value * 2 - 1)
|
||||
: range_cardinality<Rng>::value>
|
||||
{
|
||||
intersperse_view() = default;
|
||||
constexpr intersperse_view(Rng rng, range_value_t<Rng> val)
|
||||
: intersperse_view::view_adaptor{detail::move(rng)}
|
||||
, val_(detail::move(val))
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
auto const n = ranges::size(this->base());
|
||||
return n ? n * 2 - 1 : 0;
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
auto const n = ranges::size(this->base());
|
||||
return n ? n * 2 - 1 : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
template<bool Const>
|
||||
struct cursor_adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
friend struct cursor_adaptor<!Const>;
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
bool toggle_ = false;
|
||||
range_value_t<Rng> val_;
|
||||
|
||||
public:
|
||||
cursor_adaptor() = default;
|
||||
constexpr explicit cursor_adaptor(range_value_t<Rng> const & val)
|
||||
: val_{val}
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
cursor_adaptor(cursor_adaptor<Other> that)
|
||||
: toggle_(that.toggle_)
|
||||
, val_(std::move(that.val_))
|
||||
{}
|
||||
template<typename View>
|
||||
constexpr iterator_t<CRng> begin(View & view)
|
||||
{
|
||||
auto first = ranges::begin(view.base());
|
||||
toggle_ = first != ranges::end(view.base());
|
||||
return first;
|
||||
}
|
||||
constexpr range_value_t<Rng> read(iterator_t<CRng> const & it) const
|
||||
{
|
||||
return toggle_ ? *it : val_;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto equal(iterator_t<CRng> const & it0,
|
||||
iterator_t<CRng> const & it1,
|
||||
cursor_adaptor const & other) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires sentinel_for<iterator_t<CRng>, iterator_t<CRng>>)
|
||||
{
|
||||
return it0 == it1 && toggle_ == other.toggle_;
|
||||
}
|
||||
constexpr void next(iterator_t<CRng> & it)
|
||||
{
|
||||
if(toggle_)
|
||||
++it;
|
||||
toggle_ = !toggle_;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto prev(iterator_t<CRng> & it) //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<CRng>)
|
||||
{
|
||||
toggle_ = !toggle_;
|
||||
if(toggle_)
|
||||
--it;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto distance_to(iterator_t<CRng> const & it,
|
||||
iterator_t<CRng> const & other_it,
|
||||
cursor_adaptor const & other) const
|
||||
-> CPP_ret(range_difference_t<Rng>)(
|
||||
requires sized_sentinel_for<iterator_t<CRng>, iterator_t<CRng>>)
|
||||
{
|
||||
return (other_it - it) * 2 + (other.toggle_ - toggle_);
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto advance(iterator_t<CRng> & it, range_difference_t<CRng> n) //
|
||||
-> CPP_ret(void)(
|
||||
requires random_access_range<CRng>)
|
||||
{
|
||||
ranges::advance(it, n >= 0 ? (n + toggle_) / 2 : (n - !toggle_) / 2);
|
||||
if(n % 2 != 0)
|
||||
toggle_ = !toggle_;
|
||||
}
|
||||
};
|
||||
template<bool Const>
|
||||
struct sentinel_adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
|
||||
public:
|
||||
sentinel_adaptor() = default;
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
sentinel_adaptor(sentinel_adaptor<Other>)
|
||||
{}
|
||||
static constexpr bool empty(iterator_t<CRng> const & it,
|
||||
cursor_adaptor<Const> const &,
|
||||
sentinel_t<CRng> const & sent)
|
||||
{
|
||||
return it == sent;
|
||||
}
|
||||
};
|
||||
constexpr cursor_adaptor<false> begin_adaptor()
|
||||
{
|
||||
return cursor_adaptor<false>{val_};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto begin_adaptor() const //
|
||||
-> CPP_ret(cursor_adaptor<true>)(
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return cursor_adaptor<true>{val_};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() //
|
||||
-> CPP_ret(cursor_adaptor<false>)(
|
||||
requires common_range<Rng> && (!single_pass_iterator_<iterator_t<Rng>>))
|
||||
{
|
||||
return cursor_adaptor<false>{val_};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() noexcept //
|
||||
-> CPP_ret(sentinel_adaptor<false>)(
|
||||
requires (!common_range<Rng>) || single_pass_iterator_<iterator_t<Rng>>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>> AND
|
||||
common_range<meta::const_if_c<Const, Rng>> AND
|
||||
(!single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng>>>)) //
|
||||
constexpr cursor_adaptor<Const> end_adaptor() const
|
||||
{
|
||||
return cursor_adaptor<true>{val_};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>> AND
|
||||
(!common_range<meta::const_if_c<Const, Rng>> ||
|
||||
single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng>>>)) //
|
||||
constexpr sentinel_adaptor<Const> end_adaptor() const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
range_value_t<Rng> val_;
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<intersperse_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
intersperse_view(Rng &&, range_value_t<Rng>)
|
||||
-> intersperse_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct intersperse_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
convertible_to<range_reference_t<Rng>, range_value_t<Rng>> AND
|
||||
semiregular<range_value_t<Rng>>)
|
||||
constexpr intersperse_view<all_t<Rng>> //
|
||||
operator()(Rng && rng, range_value_t<Rng> val) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(val)};
|
||||
}
|
||||
};
|
||||
|
||||
struct intersperse_fn : intersperse_base_fn
|
||||
{
|
||||
using intersperse_base_fn::operator();
|
||||
|
||||
template(typename T)(
|
||||
requires copyable<T>)
|
||||
constexpr auto operator()(T t) const
|
||||
{
|
||||
return make_view_closure(bind_back(intersperse_base_fn{}, std::move(t)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates intersperse_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(intersperse_fn, intersperse)
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::intersperse_view)
|
||||
|
||||
#endif
|
||||
591
Telegram/ThirdParty/range-v3/include/range/v3/view/iota.hpp
vendored
Normal file
591
Telegram/ThirdParty/range-v3/include/range/v3/view/iota.hpp
vendored
Normal file
@@ -0,0 +1,591 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_IOTA_HPP
|
||||
#define RANGES_V3_VIEW_IOTA_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/diffmax_t.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/delimit.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH
|
||||
RANGES_DIAGNOSTIC_IGNORE_TRUNCATION
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<std::size_t N, typename = void>
|
||||
struct promote_as_signed_
|
||||
{
|
||||
// This shouldn't cause us to LOSE precision, but maybe it doesn't
|
||||
// net us any either.
|
||||
static_assert(sizeof(std::intmax_t) * CHAR_BIT >= N,
|
||||
"Possible extended integral type?");
|
||||
using difference_type = diffmax_t;
|
||||
};
|
||||
|
||||
template<std::size_t N>
|
||||
struct promote_as_signed_<N, enable_if_t<(N < 16)>>
|
||||
{
|
||||
using difference_type = std::int_fast16_t;
|
||||
};
|
||||
|
||||
template<std::size_t N>
|
||||
struct promote_as_signed_<N, enable_if_t<(N >= 16 && N < 32)>>
|
||||
{
|
||||
using difference_type = std::int_fast32_t;
|
||||
};
|
||||
|
||||
template<std::size_t N>
|
||||
struct promote_as_signed_<N, enable_if_t<(N >= 32 && N < 64)>>
|
||||
{
|
||||
using difference_type = std::int_fast64_t;
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
using iota_difference_t = typename meta::conditional_t<
|
||||
std::is_integral<I>::value && sizeof(I) == sizeof(iter_difference_t<I>),
|
||||
promote_as_signed_<sizeof(iter_difference_t<I>) * CHAR_BIT>,
|
||||
with_difference_type_<iter_difference_t<I>>>::difference_type;
|
||||
|
||||
// clang-format off
|
||||
/// \concept _decrementable_
|
||||
/// \brief The \c _decrementable_ concept
|
||||
template<typename I>
|
||||
CPP_requires(_decrementable_,
|
||||
requires(I i) //
|
||||
(
|
||||
--i,
|
||||
i--,
|
||||
concepts::requires_<same_as<I&, decltype(--i)>>,
|
||||
concepts::requires_<same_as<I, decltype(i--)>>
|
||||
));
|
||||
/// \concept decrementable_
|
||||
/// \brief The \c decrementable_ concept
|
||||
template<typename I>
|
||||
CPP_concept decrementable_ =
|
||||
incrementable<I> &&
|
||||
CPP_requires_ref(detail::_decrementable_, I);
|
||||
|
||||
/// \concept _advanceable_
|
||||
/// \brief The \c _advanceable_ concept
|
||||
template<typename I>
|
||||
CPP_requires(_advanceable_,
|
||||
requires(I i, I const j, iota_difference_t<I> const n) //
|
||||
(
|
||||
j - j,
|
||||
i += n,
|
||||
i -= n,
|
||||
static_cast<I>(j - n),
|
||||
static_cast<I>(j + n),
|
||||
static_cast<I>(n + j),
|
||||
// NOT TO SPEC:
|
||||
// Unsigned integers are advanceable, but subtracting them results in
|
||||
// an unsigned integral, which is not the same as the difference type,
|
||||
// which is signed.
|
||||
concepts::requires_<convertible_to<decltype(j - j), iota_difference_t<I>>>,
|
||||
concepts::requires_<same_as<I&, decltype(i += n)>>,
|
||||
concepts::requires_<same_as<I&, decltype(i -= n)>> //,
|
||||
// concepts::requires_<convertible_to<decltype(i - n), I>>,
|
||||
// concepts::requires_<convertible_to<decltype(i + n), I>>,
|
||||
// concepts::requires_<convertible_to<decltype(n + i), I>>
|
||||
));
|
||||
/// \concept advanceable_
|
||||
/// \brief The \c advanceable_ concept
|
||||
template<typename I>
|
||||
CPP_concept advanceable_ =
|
||||
decrementable_<I> && totally_ordered<I> &&
|
||||
CPP_requires_ref(detail::_advanceable_, I);
|
||||
// clang-format on
|
||||
|
||||
template(typename I)(
|
||||
requires (!unsigned_integral<I>)) //
|
||||
void iota_advance_(I & i, iota_difference_t<I> n)
|
||||
{
|
||||
// TODO: bounds-check this
|
||||
i += n;
|
||||
}
|
||||
|
||||
template(typename Int)(
|
||||
requires unsigned_integral<Int>)
|
||||
void iota_advance_(Int & i, iota_difference_t<Int> n)
|
||||
{
|
||||
// TODO: bounds-check this
|
||||
if(n >= 0)
|
||||
i += static_cast<Int>(n);
|
||||
else
|
||||
i -= static_cast<Int>(-n);
|
||||
}
|
||||
|
||||
template(typename I)(
|
||||
requires advanceable_<I> AND (!integral<I>)) //
|
||||
iota_difference_t<I> iota_distance_(I const & i, I const & s)
|
||||
{
|
||||
return static_cast<iota_difference_t<I>>(s - i);
|
||||
}
|
||||
|
||||
template(typename Int)(
|
||||
requires signed_integral<Int>)
|
||||
iota_difference_t<Int> iota_distance_(Int i0, Int i1)
|
||||
{
|
||||
// TODO: bounds-check this
|
||||
return static_cast<iota_difference_t<Int>>(
|
||||
static_cast<iota_difference_t<Int>>(i1) -
|
||||
static_cast<iota_difference_t<Int>>(i0));
|
||||
}
|
||||
|
||||
template(typename Int)(
|
||||
requires unsigned_integral<Int>)
|
||||
iota_difference_t<Int> iota_distance_(Int i0, Int i1)
|
||||
{
|
||||
// TODO: bounds-check this
|
||||
return (i0 > i1) ? static_cast<iota_difference_t<Int>>(
|
||||
-static_cast<iota_difference_t<Int>>(i0 - i1))
|
||||
: static_cast<iota_difference_t<Int>>(i1 - i0);
|
||||
}
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// An iota view in a closed range
|
||||
template<typename From, typename To /* = From */>
|
||||
struct RANGES_EMPTY_BASES closed_iota_view
|
||||
: view_facade<closed_iota_view<From, To>, finite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
From from_ = From();
|
||||
RANGES_NO_UNIQUE_ADDRESS To to_ = To();
|
||||
|
||||
struct cursor
|
||||
{
|
||||
using difference_type = detail::iota_difference_t<From>;
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
From from_ = From();
|
||||
RANGES_NO_UNIQUE_ADDRESS To to_ = To();
|
||||
bool done_ = false;
|
||||
|
||||
From read() const
|
||||
{
|
||||
RANGES_EXPECT(!done_);
|
||||
return from_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
RANGES_EXPECT(!done_);
|
||||
if(from_ == to_)
|
||||
done_ = true;
|
||||
else
|
||||
++from_;
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return done_;
|
||||
}
|
||||
CPP_member
|
||||
auto equal(cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires equality_comparable<From>)
|
||||
{
|
||||
return that.from_ == from_ && that.done_ == done_;
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires detail::decrementable_<From>)
|
||||
{
|
||||
if(done_)
|
||||
done_ = false;
|
||||
else
|
||||
--from_;
|
||||
}
|
||||
CPP_member
|
||||
auto advance(difference_type n) //
|
||||
-> CPP_ret(void)(
|
||||
requires detail::advanceable_<From>)
|
||||
{
|
||||
if(n > 0)
|
||||
{
|
||||
RANGES_ENSURE(detail::iota_distance_(from_, to_) >= n - !done_);
|
||||
detail::iota_advance_(
|
||||
from_,
|
||||
n - (done_ = (detail::iota_distance_(from_, to_) <= n - !done_)));
|
||||
}
|
||||
else if(n < 0)
|
||||
detail::iota_advance_(from_, n + std::exchange(done_, false));
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(cursor const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires detail::advanceable_<From>)
|
||||
{
|
||||
using D = difference_type;
|
||||
return static_cast<D>(detail::iota_distance_(from_, that.from_)) +
|
||||
((D)that.done_ - (D)done_);
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(default_sentinel_t) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires sized_sentinel_for<To, From>)
|
||||
{
|
||||
return difference_type(to_ - from_) + !done_;
|
||||
}
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
constexpr cursor(From from, To to, bool done = false)
|
||||
: from_(std::move(from))
|
||||
, to_(std::move(to))
|
||||
, done_(done)
|
||||
{}
|
||||
};
|
||||
|
||||
cursor begin_cursor() const
|
||||
{
|
||||
return {from_, to_};
|
||||
}
|
||||
CPP_member
|
||||
auto end_cursor() const //
|
||||
-> CPP_ret(cursor)(
|
||||
requires same_as<From, To>)
|
||||
{
|
||||
return {to_, to_, true};
|
||||
}
|
||||
CPP_member
|
||||
auto end_cursor() const //
|
||||
-> CPP_ret(default_sentinel_t)(
|
||||
requires (!same_as<From, To>))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
constexpr void check_bounds_(std::true_type)
|
||||
{
|
||||
RANGES_EXPECT(from_ <= to_);
|
||||
}
|
||||
constexpr void check_bounds_(std::false_type)
|
||||
{}
|
||||
|
||||
public:
|
||||
closed_iota_view() = default;
|
||||
constexpr closed_iota_view(meta::id_t<From> from, meta::id_t<To> to)
|
||||
: from_(std::move(from))
|
||||
, to_(std::move(to))
|
||||
{
|
||||
check_bounds_(meta::bool_<totally_ordered_with<From, To>>{});
|
||||
}
|
||||
};
|
||||
|
||||
template<typename From, typename To>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<closed_iota_view<From, To>> =
|
||||
true;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename From, typename To)(
|
||||
requires weakly_incrementable<From> AND semiregular<To> AND
|
||||
(!integral<From> || !integral<To> ||
|
||||
std::is_signed<From>::value == std::is_signed<To>::value)) //
|
||||
closed_iota_view(From, To)
|
||||
->closed_iota_view<From, To>;
|
||||
#endif
|
||||
|
||||
template<typename From, typename To /* = unreachable_sentinel_t*/>
|
||||
struct RANGES_EMPTY_BASES iota_view
|
||||
: view_facade<iota_view<From, To>,
|
||||
same_as<To, unreachable_sentinel_t>
|
||||
? infinite
|
||||
: std::is_integral<From>::value && std::is_integral<To>::value
|
||||
? finite
|
||||
: unknown>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
From from_ = From();
|
||||
RANGES_NO_UNIQUE_ADDRESS To to_ = To();
|
||||
|
||||
struct cursor;
|
||||
struct sentinel
|
||||
{
|
||||
private:
|
||||
friend struct cursor;
|
||||
RANGES_NO_UNIQUE_ADDRESS To to_;
|
||||
|
||||
public:
|
||||
sentinel() = default;
|
||||
constexpr explicit sentinel(To to)
|
||||
: to_(std::move(to))
|
||||
{}
|
||||
};
|
||||
|
||||
struct cursor
|
||||
{
|
||||
using difference_type = detail::iota_difference_t<From>;
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
From from_;
|
||||
|
||||
From read() const
|
||||
{
|
||||
return from_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++from_;
|
||||
}
|
||||
bool equal(sentinel const & that) const
|
||||
{
|
||||
return from_ == that.to_;
|
||||
}
|
||||
CPP_member
|
||||
auto equal(cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires equality_comparable<From>)
|
||||
{
|
||||
return that.from_ == from_;
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires detail::decrementable_<From>)
|
||||
{
|
||||
--from_;
|
||||
}
|
||||
CPP_member
|
||||
auto advance(difference_type n) //
|
||||
-> CPP_ret(void)(
|
||||
requires detail::advanceable_<From>)
|
||||
{
|
||||
detail::iota_advance_(from_, n);
|
||||
}
|
||||
// Not to spec: TODO the relational operators will effectively be constrained
|
||||
// with Advanceable, but they should be constrained with totally_ordered.
|
||||
// Reimplement iota_view without view_facade or basic_iterator.
|
||||
CPP_member
|
||||
auto distance_to(cursor const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires detail::advanceable_<From>)
|
||||
{
|
||||
return detail::iota_distance_(from_, that.from_);
|
||||
}
|
||||
// Extension: see https://github.com/ericniebler/stl2/issues/613
|
||||
CPP_member
|
||||
auto distance_to(sentinel const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires sized_sentinel_for<To, From>)
|
||||
{
|
||||
return that.to_ - from_;
|
||||
}
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
constexpr explicit cursor(From from)
|
||||
: from_(std::move(from))
|
||||
{}
|
||||
};
|
||||
cursor begin_cursor() const
|
||||
{
|
||||
return cursor{from_};
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(end_cursor)()(const //
|
||||
requires(same_as<To, unreachable_sentinel_t>))
|
||||
{
|
||||
return unreachable;
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(end_cursor)()(const //
|
||||
requires(!same_as<To, unreachable_sentinel_t>))
|
||||
{
|
||||
return meta::conditional_t<same_as<From, To>, cursor, sentinel>{to_};
|
||||
}
|
||||
constexpr void check_bounds_(std::true_type)
|
||||
{
|
||||
RANGES_EXPECT(from_ <= to_);
|
||||
}
|
||||
constexpr void check_bounds_(std::false_type)
|
||||
{}
|
||||
|
||||
public:
|
||||
#ifdef RANGES_WORKAROUND_MSVC_934264
|
||||
constexpr
|
||||
#endif // RANGES_WORKAROUND_MSVC_934264
|
||||
iota_view() = default;
|
||||
constexpr explicit iota_view(From from)
|
||||
: from_(std::move(from))
|
||||
{}
|
||||
constexpr iota_view(meta::id_t<From> from, meta::id_t<To> to)
|
||||
: from_(std::move(from))
|
||||
, to_(std::move(to))
|
||||
{
|
||||
check_bounds_(meta::bool_<totally_ordered_with<From, To>>{});
|
||||
}
|
||||
};
|
||||
|
||||
template<typename From, typename To>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<iota_view<From, To>> = true;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename From, typename To)(
|
||||
requires weakly_incrementable<From> AND semiregular<To> AND
|
||||
(!integral<From> || !integral<To> ||
|
||||
std::is_signed<From>::value == std::is_signed<To>::value)) //
|
||||
iota_view(From, To)
|
||||
->iota_view<From, To>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct iota_fn
|
||||
{
|
||||
template(typename From)(
|
||||
requires weakly_incrementable<From>)
|
||||
iota_view<From> operator()(From value) const
|
||||
{
|
||||
return iota_view<From>{std::move(value)};
|
||||
}
|
||||
template(typename From, typename To)(
|
||||
requires weakly_incrementable<From> AND semiregular<To> AND
|
||||
detail::weakly_equality_comparable_with_<From, To> AND
|
||||
(!integral<From> || !integral<To> ||
|
||||
std::is_signed<From>::value == std::is_signed<To>::value)) //
|
||||
iota_view<From, To> operator()(From from, To to) const
|
||||
{
|
||||
return {std::move(from), std::move(to)};
|
||||
}
|
||||
};
|
||||
|
||||
struct closed_iota_fn
|
||||
{
|
||||
template(typename From, typename To)(
|
||||
requires weakly_incrementable<From> AND semiregular<To> AND
|
||||
detail::weakly_equality_comparable_with_<From, To> AND
|
||||
(!integral<From> || !integral<To> ||
|
||||
std::is_signed<From>::value == std::is_signed<To>::value)) //
|
||||
closed_iota_view<From, To> operator()(From from, To to) const
|
||||
{
|
||||
return {std::move(from), std::move(to)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates iota_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(iota_fn, iota)
|
||||
|
||||
/// \relates closed_iota_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(closed_iota_fn, closed_iota)
|
||||
|
||||
/// # ranges::views::ints
|
||||
/// The ints view returns a range of monotonically increasing ints.
|
||||
///
|
||||
/// ## Example
|
||||
/// \snippet example/view/ints.cpp ints example
|
||||
///
|
||||
/// ### Output
|
||||
/// \include example/view/ints_golden.txt
|
||||
///
|
||||
/// ## Syntax
|
||||
/// ```cpp
|
||||
/// auto output_range = ranges::views::ints(lower_bound, upper_bound);
|
||||
/// ```
|
||||
///
|
||||
/// ## Parameters
|
||||
/// <pre><b>lower_bound</b></pre>
|
||||
/// - Optional lower bound
|
||||
///
|
||||
/// <pre><b>upper_bound</b></pre>
|
||||
/// - Exclusive upper bound
|
||||
/// - Required when `lower_bound` is specified
|
||||
/// - To create an infinite range with a `lower_bound`, use
|
||||
/// `ranges::unreachable` as the `upper_bound`
|
||||
///
|
||||
/// <pre><b>output_range</b></pre>
|
||||
/// - Range of monotonically increasing ints
|
||||
/// - When an `upper_bound` is not specified, the range is quasi-infinite
|
||||
///
|
||||
struct ints_fn : iota_view<int>
|
||||
{
|
||||
ints_fn() = default;
|
||||
|
||||
template(typename Val)(
|
||||
requires integral<Val>)
|
||||
RANGES_DEPRECATED(
|
||||
"This potentially confusing API is deprecated. Prefer to "
|
||||
"explicitly specify the upper bound as with ranges::unreachable, as in "
|
||||
"views::ints( n, unreachable )")
|
||||
constexpr iota_view<Val> operator()(Val value) const //
|
||||
{
|
||||
return iota_view<Val>{value};
|
||||
}
|
||||
template(typename Val)(
|
||||
requires integral<Val>)
|
||||
constexpr iota_view<Val> operator()(Val value, unreachable_sentinel_t) const
|
||||
{
|
||||
return iota_view<Val>{value};
|
||||
}
|
||||
template(typename Val)(
|
||||
requires integral<Val>)
|
||||
constexpr iota_view<Val, Val> operator()(Val from, Val to) const
|
||||
{
|
||||
return {from, to};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates ints_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(ints_fn, ints)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::iota;
|
||||
}
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::closed_iota_view)
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::iota_view)
|
||||
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
123
Telegram/ThirdParty/range-v3/include/range/v3/view/istream.hpp
vendored
Normal file
123
Telegram/ThirdParty/range-v3/include/range/v3/view/istream.hpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_ISTREAM_HPP
|
||||
#define RANGES_V3_VIEW_ISTREAM_HPP
|
||||
|
||||
#include <istream>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Val>
|
||||
struct istream_view : view_facade<istream_view<Val>, unknown>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
std::istream * sin_;
|
||||
semiregular_box_t<Val> obj_;
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
using single_pass = std::true_type;
|
||||
istream_view * rng_ = nullptr;
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
explicit cursor(istream_view * rng)
|
||||
: rng_(rng)
|
||||
{}
|
||||
void next()
|
||||
{
|
||||
rng_->next();
|
||||
}
|
||||
Val & read() const noexcept
|
||||
{
|
||||
return rng_->cached();
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return !rng_->sin_;
|
||||
}
|
||||
bool equal(cursor that) const
|
||||
{
|
||||
return !rng_->sin_ == !that.rng_->sin_;
|
||||
}
|
||||
};
|
||||
void next()
|
||||
{
|
||||
if(!(*sin_ >> cached()))
|
||||
sin_ = nullptr;
|
||||
}
|
||||
cursor begin_cursor()
|
||||
{
|
||||
return cursor{this};
|
||||
}
|
||||
|
||||
public:
|
||||
istream_view() = default;
|
||||
explicit istream_view(std::istream & sin)
|
||||
: sin_(&sin)
|
||||
, obj_{}
|
||||
{
|
||||
next(); // prime the pump
|
||||
}
|
||||
Val & cached() noexcept
|
||||
{
|
||||
return obj_;
|
||||
}
|
||||
};
|
||||
|
||||
/// \cond
|
||||
template<typename Val>
|
||||
using istream_range RANGES_DEPRECATED(
|
||||
"istream_range<T> has been renamed to istream_view<T>") = istream_view<Val>;
|
||||
/// \endcond
|
||||
|
||||
/// \cond
|
||||
namespace _istream_
|
||||
{
|
||||
/// \endcond
|
||||
template(typename Val)(
|
||||
requires copy_constructible<Val> AND default_constructible<Val>)
|
||||
inline istream_view<Val> istream(std::istream & sin)
|
||||
{
|
||||
return istream_view<Val>{sin};
|
||||
}
|
||||
/// \cond
|
||||
} // namespace _istream_
|
||||
using namespace _istream_;
|
||||
/// \endcond
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
template<typename Val>
|
||||
using basic_istream_view = ::ranges::istream_view<Val>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
649
Telegram/ThirdParty/range-v3/include/range/v3/view/join.hpp
vendored
Normal file
649
Telegram/ThirdParty/range-v3/include/range/v3/view/join.hpp
vendored
Normal file
@@ -0,0 +1,649 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_JOIN_HPP
|
||||
#define RANGES_V3_VIEW_JOIN_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/range_for.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/utility/variant.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/single.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// Compute the cardinality of a joined range
|
||||
constexpr cardinality join_cardinality_(
|
||||
cardinality Outer, cardinality Inner,
|
||||
cardinality Joiner = static_cast<cardinality>(0)) noexcept
|
||||
{
|
||||
return Outer == infinite || Inner == infinite ||
|
||||
(Joiner == infinite && Outer != 0 && Outer != 1)
|
||||
? infinite
|
||||
: Outer == unknown || Inner == unknown ||
|
||||
(Joiner == unknown && Outer != 0 && Outer != 1)
|
||||
? unknown
|
||||
: Outer == finite || Inner == finite ||
|
||||
(Joiner == finite && Outer != 0 && Outer != 1)
|
||||
? finite
|
||||
: static_cast<cardinality>(
|
||||
Outer * Inner +
|
||||
(Outer == 0 ? 0 : (Outer - 1) * Joiner));
|
||||
}
|
||||
|
||||
template<typename Range>
|
||||
constexpr cardinality join_cardinality() noexcept
|
||||
{
|
||||
return detail::join_cardinality_(
|
||||
range_cardinality<Range>::value,
|
||||
range_cardinality<range_reference_t<Range>>::value);
|
||||
}
|
||||
|
||||
template<typename Range, typename JoinRange>
|
||||
constexpr cardinality join_cardinality() noexcept
|
||||
{
|
||||
return detail::join_cardinality_(
|
||||
range_cardinality<Range>::value,
|
||||
range_cardinality<range_reference_t<Range>>::value,
|
||||
range_cardinality<JoinRange>::value);
|
||||
}
|
||||
|
||||
template<typename Inner>
|
||||
struct store_inner_
|
||||
{
|
||||
non_propagating_cache<std::remove_cv_t<Inner>> inner_ = {};
|
||||
|
||||
template<typename OuterIt>
|
||||
constexpr auto && update_inner_(OuterIt && it)
|
||||
{
|
||||
return inner_.emplace_deref(it);
|
||||
}
|
||||
constexpr Inner & get_inner_(ignore_t) noexcept
|
||||
{
|
||||
return *inner_;
|
||||
}
|
||||
};
|
||||
|
||||
struct pass_thru_inner_
|
||||
{
|
||||
// Intentionally promote xvalues to lvalues here:
|
||||
template<typename OuterIt>
|
||||
static constexpr auto && update_inner_(OuterIt && it) noexcept
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
template<typename OuterIt>
|
||||
static constexpr decltype(auto) get_inner_(OuterIt && outer_it)
|
||||
{
|
||||
return *outer_it;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
using join_view_inner =
|
||||
meta::conditional_t<!std::is_reference<range_reference_t<Rng>>::value,
|
||||
store_inner_<range_reference_t<Rng>>, pass_thru_inner_>;
|
||||
|
||||
// clang-format off
|
||||
/// \concept has_member_arrow_
|
||||
/// \brief The \c has_member_arrow_ concept
|
||||
template<typename I>
|
||||
CPP_requires(has_member_arrow_,
|
||||
requires(I i) //
|
||||
(
|
||||
i.operator->()
|
||||
));
|
||||
|
||||
/// \concept has_arrow_
|
||||
/// \brief The \c has_arrow_ concept
|
||||
template<typename I>
|
||||
CPP_concept has_arrow_ =
|
||||
input_iterator<I> &&
|
||||
(std::is_pointer<I>::value || CPP_requires_ref(detail::has_member_arrow_, I));
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
// Join a range of ranges
|
||||
template<typename Rng>
|
||||
struct RANGES_EMPTY_BASES join_view
|
||||
: view_facade<join_view<Rng>, detail::join_cardinality<Rng>()>
|
||||
, private detail::join_view_inner<Rng>
|
||||
{
|
||||
CPP_assert(input_range<Rng> && view_<Rng>);
|
||||
CPP_assert(input_range<range_reference_t<Rng>>);
|
||||
|
||||
join_view() = default;
|
||||
explicit join_view(Rng rng)
|
||||
: outer_(views::all(std::move(rng)))
|
||||
{}
|
||||
// Not to spec
|
||||
CPP_member
|
||||
static constexpr auto size() //
|
||||
-> CPP_ret(std::size_t)(
|
||||
requires (detail::join_cardinality<Rng>() >= 0))
|
||||
{
|
||||
return static_cast<std::size_t>(detail::join_cardinality<Rng>());
|
||||
}
|
||||
// Not to spec
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires(detail::join_cardinality<Rng>() < 0) &&
|
||||
(range_cardinality<Rng>::value >= 0) &&
|
||||
forward_range<Rng> &&
|
||||
sized_range<range_reference_t<Rng>>)
|
||||
{
|
||||
range_size_t<range_reference_t<Rng>> n = 0;
|
||||
RANGES_FOR(auto && inner, outer_)
|
||||
n += ranges::size(inner);
|
||||
return n;
|
||||
}
|
||||
// // ericniebler/stl2#605
|
||||
constexpr Rng base() const
|
||||
{
|
||||
return outer_;
|
||||
}
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
Rng outer_{};
|
||||
|
||||
template<bool Const>
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
using Parent = meta::conditional_t<Const, join_view const, join_view>;
|
||||
using COuter = meta::conditional_t<Const, Rng const, Rng>;
|
||||
using CInner = range_reference_t<COuter>;
|
||||
using ref_is_glvalue = std::is_reference<CInner>;
|
||||
|
||||
Parent * rng_ = nullptr;
|
||||
iterator_t<COuter> outer_it_{};
|
||||
iterator_t<CInner> inner_it_{};
|
||||
|
||||
void satisfy()
|
||||
{
|
||||
for(; outer_it_ != ranges::end(rng_->outer_); ++outer_it_)
|
||||
{
|
||||
auto && inner = rng_->update_inner_(outer_it_);
|
||||
inner_it_ = ranges::begin(inner);
|
||||
if(inner_it_ != ranges::end(inner))
|
||||
return;
|
||||
}
|
||||
if(RANGES_CONSTEXPR_IF(ref_is_glvalue::value))
|
||||
inner_it_ = iterator_t<CInner>();
|
||||
}
|
||||
|
||||
public:
|
||||
using single_pass = meta::bool_<single_pass_iterator_<iterator_t<COuter>> ||
|
||||
single_pass_iterator_<iterator_t<CInner>> ||
|
||||
!ref_is_glvalue::value>;
|
||||
cursor() = default;
|
||||
template<typename BeginOrEnd>
|
||||
constexpr cursor(Parent * rng, BeginOrEnd begin_or_end)
|
||||
: rng_{rng}
|
||||
, outer_it_(begin_or_end(rng->outer_))
|
||||
{
|
||||
satisfy();
|
||||
}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other) AND
|
||||
convertible_to<iterator_t<Rng>, iterator_t<COuter>> AND
|
||||
convertible_to<iterator_t<range_reference_t<Rng>>,
|
||||
iterator_t<CInner>>)
|
||||
constexpr cursor(cursor<Other> that)
|
||||
: rng_(that.rng_)
|
||||
, outer_it_(std::move(that.outer_it_))
|
||||
, inner_it_(std::move(that.inner_it_))
|
||||
{}
|
||||
CPP_member
|
||||
constexpr auto arrow() //
|
||||
-> CPP_ret(iterator_t<CInner>)(
|
||||
requires detail::has_arrow_<iterator_t<CInner>>)
|
||||
{
|
||||
return inner_it_;
|
||||
}
|
||||
constexpr bool equal(default_sentinel_t) const
|
||||
{
|
||||
return outer_it_ == ranges::end(rng_->outer_);
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto equal(cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires ref_is_glvalue::value && //
|
||||
equality_comparable<iterator_t<COuter>> && //
|
||||
equality_comparable<iterator_t<CInner>>)
|
||||
{
|
||||
return outer_it_ == that.outer_it_ && inner_it_ == that.inner_it_;
|
||||
}
|
||||
constexpr void next()
|
||||
{
|
||||
auto && inner_rng = rng_->get_inner_(outer_it_);
|
||||
if(++inner_it_ == ranges::end(inner_rng))
|
||||
{
|
||||
++outer_it_;
|
||||
satisfy();
|
||||
}
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires ref_is_glvalue::value && //
|
||||
bidirectional_range<COuter> && //
|
||||
bidirectional_range<CInner> && //
|
||||
common_range<CInner>) // ericniebler/stl2#606
|
||||
{
|
||||
if(outer_it_ == ranges::end(rng_->outer_))
|
||||
inner_it_ = ranges::end(*--outer_it_);
|
||||
while(inner_it_ == ranges::begin(*outer_it_))
|
||||
inner_it_ = ranges::end(*--outer_it_);
|
||||
--inner_it_;
|
||||
}
|
||||
// clang-format off
|
||||
constexpr auto CPP_auto_fun(read)()(const)
|
||||
(
|
||||
return *inner_it_
|
||||
)
|
||||
constexpr auto CPP_auto_fun(move)()(const)
|
||||
(
|
||||
return iter_move(inner_it_)
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
static constexpr bool use_const_always() noexcept
|
||||
{
|
||||
return simple_view<Rng>() && std::is_reference<range_reference_t<Rng>>::value;
|
||||
}
|
||||
struct end_cursor_fn
|
||||
{
|
||||
constexpr auto operator()(join_view * this_, std::true_type) const
|
||||
{
|
||||
return cursor<use_const_always()>{this_, ranges::end};
|
||||
}
|
||||
constexpr auto operator()(join_view *, std::false_type) const
|
||||
{
|
||||
return default_sentinel_t{};
|
||||
}
|
||||
};
|
||||
struct cend_cursor_fn
|
||||
{
|
||||
constexpr auto operator()(join_view const * this_, std::true_type) const
|
||||
{
|
||||
return cursor<true>{this_, ranges::end};
|
||||
}
|
||||
constexpr auto operator()(join_view const *, std::false_type) const
|
||||
{
|
||||
return default_sentinel_t{};
|
||||
}
|
||||
};
|
||||
|
||||
constexpr cursor<use_const_always()> begin_cursor()
|
||||
{
|
||||
return {this, ranges::begin};
|
||||
}
|
||||
|
||||
template(bool Const = true)(
|
||||
requires Const AND input_range<meta::const_if_c<Const, Rng>> AND
|
||||
std::is_reference<range_reference_t<meta::const_if_c<Const, Rng>>>::value)
|
||||
constexpr cursor<Const> begin_cursor() const
|
||||
{
|
||||
return {this, ranges::begin};
|
||||
}
|
||||
|
||||
constexpr auto end_cursor()
|
||||
{
|
||||
using cond =
|
||||
meta::bool_<std::is_reference<range_reference_t<Rng>>::value &&
|
||||
forward_range<Rng> && forward_range<range_reference_t<Rng>> &&
|
||||
common_range<Rng> && common_range<range_reference_t<Rng>>>;
|
||||
return end_cursor_fn{}(this, cond{});
|
||||
}
|
||||
|
||||
template(bool Const = true)(
|
||||
requires Const AND input_range<meta::const_if_c<Const, Rng>> AND
|
||||
std::is_reference<range_reference_t<meta::const_if_c<Const, Rng>>>::value)
|
||||
constexpr auto end_cursor() const
|
||||
{
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
using cond =
|
||||
meta::bool_<std::is_reference<range_reference_t<CRng>>::value &&
|
||||
forward_range<CRng> &&
|
||||
forward_range<range_reference_t<CRng>> &&
|
||||
common_range<CRng> && common_range<range_reference_t<CRng>>>;
|
||||
return cend_cursor_fn{}(this, cond{});
|
||||
}
|
||||
};
|
||||
|
||||
// Join a range of ranges, inserting a range of values between them.
|
||||
// TODO: Support const iteration when range_reference_t<Rng> is a true reference.
|
||||
template<typename Rng, typename ValRng>
|
||||
struct join_with_view
|
||||
: view_facade<join_with_view<Rng, ValRng>, detail::join_cardinality<Rng, ValRng>()>
|
||||
, private detail::join_view_inner<Rng>
|
||||
{
|
||||
CPP_assert(input_range<Rng>);
|
||||
CPP_assert(input_range<range_reference_t<Rng>>);
|
||||
CPP_assert(forward_range<ValRng>);
|
||||
CPP_assert(
|
||||
common_with<range_value_t<range_reference_t<Rng>>, range_value_t<ValRng>>);
|
||||
CPP_assert(semiregular<common_type_t<range_value_t<range_reference_t<Rng>>,
|
||||
range_value_t<ValRng>>>);
|
||||
|
||||
join_with_view() = default;
|
||||
join_with_view(Rng rng, ValRng val)
|
||||
: outer_(views::all(std::move(rng)))
|
||||
, val_(views::all(std::move(val)))
|
||||
{}
|
||||
CPP_member
|
||||
static constexpr auto size() //
|
||||
-> CPP_ret(std::size_t)(
|
||||
requires (detail::join_cardinality<Rng, ValRng>() >= 0))
|
||||
{
|
||||
return static_cast<std::size_t>(detail::join_cardinality<Rng, ValRng>());
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires(detail::join_cardinality<Rng, ValRng>() < 0) &&
|
||||
(range_cardinality<Rng>::value >= 0) && forward_range<Rng> &&
|
||||
sized_range<range_reference_t<Rng>> && sized_range<ValRng>)
|
||||
{
|
||||
range_size_t<range_reference_t<Rng>> n = 0;
|
||||
RANGES_FOR(auto && inner, outer_)
|
||||
n += ranges::size(inner);
|
||||
return n + (range_cardinality<Rng>::value == 0
|
||||
? 0
|
||||
: ranges::size(val_) * (range_cardinality<Rng>::value - 1));
|
||||
}
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
using Outer = views::all_t<Rng>;
|
||||
// Intentionally promote xvalues to lvalues here:
|
||||
using Inner = views::all_t<range_reference_t<Outer> &>;
|
||||
|
||||
Outer outer_{};
|
||||
views::all_t<ValRng> val_{};
|
||||
|
||||
class cursor
|
||||
{
|
||||
join_with_view * rng_ = nullptr;
|
||||
iterator_t<Outer> outer_it_{};
|
||||
variant<iterator_t<ValRng>, iterator_t<Inner>> cur_{};
|
||||
|
||||
void satisfy()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
if(cur_.index() == 0)
|
||||
{
|
||||
if(ranges::get<0>(cur_) != ranges::end(rng_->val_))
|
||||
break;
|
||||
// Intentionally promote xvalues to lvalues here:
|
||||
auto && inner = rng_->update_inner_(outer_it_);
|
||||
ranges::emplace<1>(cur_, ranges::begin(inner));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto && inner = rng_->get_inner_(outer_it_);
|
||||
if(ranges::get<1>(cur_) != ranges::end(inner))
|
||||
break;
|
||||
if(++outer_it_ == ranges::end(rng_->outer_))
|
||||
break;
|
||||
ranges::emplace<0>(cur_, ranges::begin(rng_->val_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = common_type_t<range_value_t<Inner>, range_value_t<ValRng>>;
|
||||
using reference =
|
||||
common_reference_t<range_reference_t<Inner>, range_reference_t<ValRng>>;
|
||||
using rvalue_reference = common_reference_t<range_rvalue_reference_t<Inner>,
|
||||
range_rvalue_reference_t<ValRng>>;
|
||||
using single_pass = std::true_type;
|
||||
cursor() = default;
|
||||
cursor(join_with_view * rng)
|
||||
: rng_{rng}
|
||||
, outer_it_(ranges::begin(rng->outer_))
|
||||
{
|
||||
if(outer_it_ != ranges::end(rng->outer_))
|
||||
{
|
||||
auto && inner = rng_->update_inner_(outer_it_);
|
||||
ranges::emplace<1>(cur_, ranges::begin(inner));
|
||||
satisfy();
|
||||
}
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return outer_it_ == ranges::end(rng_->outer_);
|
||||
}
|
||||
void next()
|
||||
{
|
||||
// visit(cur_, [](auto& it){ ++it; });
|
||||
if(cur_.index() == 0)
|
||||
{
|
||||
auto & it = ranges::get<0>(cur_);
|
||||
RANGES_ASSERT(it != ranges::end(rng_->val_));
|
||||
++it;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto & it = ranges::get<1>(cur_);
|
||||
#ifndef NDEBUG
|
||||
auto && inner = rng_->get_inner_(outer_it_);
|
||||
RANGES_ASSERT(it != ranges::end(inner));
|
||||
#endif
|
||||
++it;
|
||||
}
|
||||
satisfy();
|
||||
}
|
||||
reference read() const
|
||||
{
|
||||
// return visit(cur_, [](auto& it) -> reference { return *it; });
|
||||
if(cur_.index() == 0)
|
||||
return *ranges::get<0>(cur_);
|
||||
else
|
||||
return *ranges::get<1>(cur_);
|
||||
}
|
||||
rvalue_reference move() const
|
||||
{
|
||||
// return visit(cur_, [](auto& it) -> rvalue_reference { return
|
||||
// iter_move(it); });
|
||||
if(cur_.index() == 0)
|
||||
return iter_move(ranges::get<0>(cur_));
|
||||
else
|
||||
return iter_move(ranges::get<1>(cur_));
|
||||
}
|
||||
};
|
||||
cursor begin_cursor()
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
};
|
||||
|
||||
namespace views
|
||||
{
|
||||
/// \cond
|
||||
// Don't forget to update views::for_each whenever this set
|
||||
// of concepts changes
|
||||
// clang-format off
|
||||
/// \concept joinable_range_
|
||||
/// \brief The \c joinable_range_ concept
|
||||
template(typename Rng)(
|
||||
concept (joinable_range_)(Rng),
|
||||
input_range<range_reference_t<Rng>>
|
||||
);
|
||||
/// \concept joinable_range
|
||||
/// \brief The \c joinable_range concept
|
||||
template<typename Rng>
|
||||
CPP_concept joinable_range =
|
||||
viewable_range<Rng> && input_range<Rng> &&
|
||||
CPP_concept_ref(views::joinable_range_, Rng);
|
||||
|
||||
/// \concept joinable_with_range_
|
||||
/// \brief The \c joinable_with_range_ concept
|
||||
template(typename Rng, typename ValRng)(
|
||||
concept (joinable_with_range_)(Rng, ValRng),
|
||||
common_with<
|
||||
range_value_t<ValRng>,
|
||||
range_value_t<range_reference_t<Rng>>> AND
|
||||
semiregular<
|
||||
common_type_t<
|
||||
range_value_t<ValRng>,
|
||||
range_value_t<range_reference_t<Rng>>>> AND
|
||||
common_reference_with<
|
||||
range_reference_t<ValRng>,
|
||||
range_reference_t<range_reference_t<Rng>>> AND
|
||||
common_reference_with<
|
||||
range_rvalue_reference_t<ValRng>,
|
||||
range_rvalue_reference_t<range_reference_t<Rng>>>
|
||||
);
|
||||
/// \concept joinable_with_range
|
||||
/// \brief The \c joinable_with_range concept
|
||||
template<typename Rng, typename ValRng>
|
||||
CPP_concept joinable_with_range =
|
||||
joinable_range<Rng> &&
|
||||
viewable_range<ValRng> && forward_range<ValRng> &&
|
||||
CPP_concept_ref(views::joinable_with_range_, Rng, ValRng);
|
||||
// clang-format on
|
||||
/// \endcond
|
||||
|
||||
struct cpp20_join_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires joinable_range<Rng>)
|
||||
join_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return join_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
struct join_base_fn : cpp20_join_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
using inner_value_t = range_value_t<range_reference_t<Rng>>;
|
||||
public:
|
||||
using cpp20_join_fn::operator();
|
||||
|
||||
template(typename Rng)(
|
||||
requires joinable_with_range<Rng, single_view<inner_value_t<Rng>>>)
|
||||
join_with_view<all_t<Rng>, single_view<inner_value_t<Rng>>> //
|
||||
operator()(Rng && rng, inner_value_t<Rng> v) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), single(std::move(v))};
|
||||
}
|
||||
|
||||
template(typename Rng, typename ValRng)(
|
||||
requires joinable_with_range<Rng, ValRng>)
|
||||
join_with_view<all_t<Rng>, all_t<ValRng>> //
|
||||
operator()(Rng && rng, ValRng && val) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), all(static_cast<ValRng &&>(val))};
|
||||
}
|
||||
|
||||
/// \cond
|
||||
template<typename Rng, typename T>
|
||||
invoke_result_t<join_base_fn, Rng, T &> //
|
||||
operator()(Rng && rng, detail::reference_wrapper_<T> r) const
|
||||
{
|
||||
return (*this)(static_cast<Rng &&>(rng), r.get());
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
struct join_bind_fn
|
||||
{
|
||||
template(typename T)(
|
||||
requires (!joinable_range<T>)) // TODO: underconstrained
|
||||
constexpr auto operator()(T && t)const
|
||||
{
|
||||
return make_view_closure(bind_back(join_base_fn{}, static_cast<T &&>(t)));
|
||||
}
|
||||
template(typename T)(
|
||||
requires (!joinable_range<T &>) AND range<T &>)
|
||||
constexpr auto operator()(T & t) const
|
||||
{
|
||||
return make_view_closure(bind_back(join_base_fn{},
|
||||
detail::reference_wrapper_<T>(t)));
|
||||
}
|
||||
};
|
||||
|
||||
struct RANGES_EMPTY_BASES join_fn
|
||||
: join_base_fn, join_bind_fn
|
||||
{
|
||||
using join_base_fn::operator();
|
||||
using join_bind_fn::operator();
|
||||
};
|
||||
|
||||
/// \relates join_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<join_fn>, join)
|
||||
} // namespace views
|
||||
/// @}
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng)(
|
||||
requires views::joinable_range<Rng>)
|
||||
explicit join_view(Rng &&)
|
||||
->join_view<views::all_t<Rng>>;
|
||||
|
||||
template(typename Rng, typename ValRng)(
|
||||
requires views::joinable_with_range<Rng, ValRng>)
|
||||
explicit join_with_view(Rng &&, ValRng &&)
|
||||
->join_with_view<views::all_t<Rng>, views::all_t<ValRng>>;
|
||||
#endif
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
RANGES_INLINE_VARIABLE(
|
||||
ranges::views::view_closure<ranges::views::cpp20_join_fn>, join)
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires input_range<Rng> AND view_<Rng> AND
|
||||
input_range<iter_reference_t<iterator_t<Rng>>>) //
|
||||
using join_view = ranges::join_view<Rng>;
|
||||
} // namespace cpp20
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::join_view)
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::join_with_view)
|
||||
|
||||
#endif
|
||||
123
Telegram/ThirdParty/range-v3/include/range/v3/view/linear_distribute.hpp
vendored
Normal file
123
Telegram/ThirdParty/range-v3/include/range/v3/view/linear_distribute.hpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Casey Carter 2017
|
||||
// Copyright Gonzalo Brito Gadeschi 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_LINEAR_DISTRIBUTE_HPP
|
||||
#define RANGES_V3_VIEW_LINEAR_DISTRIBUTE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
template<typename T>
|
||||
struct linear_distribute_view : view_facade<linear_distribute_view<T>, finite>
|
||||
{
|
||||
CPP_assert(std::is_arithmetic<T>());
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
using Calc = meta::conditional_t<std::is_floating_point<T>::value, T, double>;
|
||||
|
||||
T from_, to_;
|
||||
Calc delta_;
|
||||
std::ptrdiff_t n_;
|
||||
|
||||
constexpr T read() const noexcept
|
||||
{
|
||||
return from_;
|
||||
}
|
||||
constexpr bool equal(default_sentinel_t) const noexcept
|
||||
{
|
||||
return n_ == 0;
|
||||
}
|
||||
constexpr bool equal(linear_distribute_view const & other) const noexcept
|
||||
{
|
||||
bool const eq = n_ == other.n_;
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_FLOAT_EQUAL
|
||||
RANGES_EXPECT(to_ == other.to_);
|
||||
RANGES_EXPECT(!eq || from_ == other.from_);
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
return eq;
|
||||
}
|
||||
constexpr void next() noexcept
|
||||
{
|
||||
RANGES_EXPECT(n_ > 0);
|
||||
--n_;
|
||||
if(n_ == 0)
|
||||
{
|
||||
from_ = to_;
|
||||
}
|
||||
else
|
||||
{
|
||||
from_ = T(to_ - (delta_ * Calc(n_ - 1)));
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr linear_distribute_view() = default;
|
||||
constexpr linear_distribute_view(T from, T to, std::ptrdiff_t n) noexcept
|
||||
: from_(from)
|
||||
, to_(to)
|
||||
, delta_(n > 1 ? (to - from) / Calc(n - 1) : 0)
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n_ > 0);
|
||||
RANGES_EXPECT(to_ >= from_);
|
||||
}
|
||||
constexpr std::size_t size() const noexcept
|
||||
{
|
||||
return static_cast<std::size_t>(n_);
|
||||
}
|
||||
};
|
||||
|
||||
/// Distributes `n` values linearly in the closed interval [`from`, `to`].
|
||||
///
|
||||
/// \pre `from <= to && n > 0`
|
||||
///
|
||||
/// If `from == to`, returns n-times `to`.
|
||||
/// If `n == 1` returns `to`.
|
||||
struct linear_distribute_fn
|
||||
{
|
||||
template(typename T)(
|
||||
requires std::is_arithmetic<T>::value)
|
||||
constexpr auto operator()(T from, T to, std::ptrdiff_t n) const
|
||||
{
|
||||
return linear_distribute_view<T>{from, to, n};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates linear_distribute_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(linear_distribute_fn, linear_distribute)
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
150
Telegram/ThirdParty/range-v3/include/range/v3/view/map.hpp
vendored
Normal file
150
Telegram/ThirdParty/range-v3/include/range/v3/view/map.hpp
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_MAP_HPP
|
||||
#define RANGES_V3_VIEW_MAP_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
// TODO: Reuse subrange's pair_like concept here and have get_first and get_second
|
||||
// dispatch through get<>()
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
constexpr T & get_first_second_helper(T & t, std::true_type) noexcept
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template(typename T)(
|
||||
requires move_constructible<T>)
|
||||
constexpr T get_first_second_helper(T & t, std::false_type) //
|
||||
noexcept(std::is_nothrow_move_constructible<T>::value)
|
||||
{
|
||||
return std::move(t);
|
||||
}
|
||||
|
||||
template<typename P, typename E>
|
||||
using get_first_second_tag = meta::bool_<std::is_lvalue_reference<P>::value ||
|
||||
std::is_lvalue_reference<E>::value>;
|
||||
|
||||
struct get_first
|
||||
{
|
||||
// clang-format off
|
||||
template<typename Pair>
|
||||
constexpr auto CPP_auto_fun(operator())(Pair &&p)(const)
|
||||
(
|
||||
return get_first_second_helper(
|
||||
p.first,
|
||||
get_first_second_tag<Pair, decltype(p.first)>{})
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
struct get_second
|
||||
{
|
||||
// clang-format off
|
||||
template<typename Pair>
|
||||
constexpr auto CPP_auto_fun(operator())(Pair &&p)(const)
|
||||
(
|
||||
return get_first_second_helper(
|
||||
p.second,
|
||||
get_first_second_tag<Pair, decltype(p.second)>{})
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
/// \concept kv_pair_like_
|
||||
/// \brief The \c kv_pair_like_ concept
|
||||
template<typename T>
|
||||
CPP_concept kv_pair_like_ =
|
||||
invocable<get_first const &, T> &&
|
||||
invocable<get_second const &, T>;
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
struct keys_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
detail::kv_pair_like_<range_reference_t<Rng>>)
|
||||
keys_range_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), detail::get_first{}};
|
||||
}
|
||||
};
|
||||
|
||||
struct values_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
detail::kv_pair_like_<range_reference_t<Rng>>)
|
||||
values_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), detail::get_second{}};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates keys_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<keys_fn>, keys)
|
||||
|
||||
/// \relates values_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<values_fn>, values)
|
||||
} // namespace views
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<keys_range_view<Rng>> =
|
||||
enable_borrowed_range<Rng>;
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<values_view<Rng>> =
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::keys;
|
||||
using ranges::views::values;
|
||||
} // namespace views
|
||||
// TODO(@cjdb): provide implementation for elements_view
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
136
Telegram/ThirdParty/range-v3/include/range/v3/view/move.hpp
vendored
Normal file
136
Telegram/ThirdParty/range-v3/include/range/v3/view/move.hpp
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_MOVE_HPP
|
||||
#define RANGES_V3_VIEW_MOVE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct move_view : view_adaptor<move_view<Rng>, Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
template<bool Const>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
adaptor() = default;
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
constexpr adaptor(adaptor<Other>)
|
||||
{}
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
using value_type = range_value_t<Rng>;
|
||||
range_rvalue_reference_t<CRng> read(iterator_t<CRng> const & it) const
|
||||
{
|
||||
return ranges::iter_move(it);
|
||||
}
|
||||
range_rvalue_reference_t<CRng> iter_move(iterator_t<CRng> const & it) const
|
||||
{
|
||||
return ranges::iter_move(it);
|
||||
}
|
||||
};
|
||||
adaptor<simple_view<Rng>()> begin_adaptor()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
adaptor<simple_view<Rng>()> end_adaptor()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires input_range<Rng const>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
CPP_member
|
||||
auto end_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires input_range<Rng const>)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
move_view() = default;
|
||||
explicit move_view(Rng rng)
|
||||
: move_view::view_adaptor{std::move(rng)}
|
||||
{}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<move_view<Rng>> =
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
move_view(Rng &&) //
|
||||
-> move_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct move_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
move_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return move_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates move_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<move_fn>, move)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::move_view)
|
||||
|
||||
#endif
|
||||
233
Telegram/ThirdParty/range-v3/include/range/v3/view/partial_sum.hpp
vendored
Normal file
233
Telegram/ThirdParty/range-v3/include/range/v3/view/partial_sum.hpp
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_PARTIAL_SUM_HPP
|
||||
#define RANGES_V3_VIEW_PARTIAL_SUM_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/arithmetic.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/addressof.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// clang-format off
|
||||
/// \concept partial_sum_view_constraints_
|
||||
/// \brief The \c partial_sum_view_constraints_ concept
|
||||
template(typename Rng, typename Fun)(
|
||||
concept (partial_sum_view_constraints_)(Rng, Fun),
|
||||
copy_constructible<range_value_t<Rng>> AND
|
||||
constructible_from<range_value_t<Rng>, range_reference_t<Rng>> AND
|
||||
assignable_from<range_value_t<Rng> &, range_reference_t<Rng>> AND
|
||||
indirectly_binary_invocable_<Fun &, iterator_t<Rng>, iterator_t<Rng>> AND
|
||||
assignable_from<
|
||||
range_value_t<Rng> &,
|
||||
indirect_result_t<Fun &, iterator_t<Rng>, iterator_t<Rng>>>
|
||||
);
|
||||
/// \concept partial_sum_view_constraints
|
||||
/// \brief The \c partial_sum_view_constraints concept
|
||||
template<typename Rng, typename Fun>
|
||||
CPP_concept partial_sum_view_constraints =
|
||||
input_range<Rng> &&
|
||||
copy_constructible<Fun> &&
|
||||
CPP_concept_ref(detail::partial_sum_view_constraints_, Rng, Fun);
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Fun>
|
||||
struct partial_sum_view
|
||||
: view_facade<partial_sum_view<Rng, Fun>, range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
CPP_assert(view_<Rng>);
|
||||
CPP_assert(detail::partial_sum_view_constraints<Rng, Fun>);
|
||||
|
||||
RANGES_NO_UNIQUE_ADDRESS Rng base_{};
|
||||
RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Fun> fun_;
|
||||
|
||||
template<bool IsConst>
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend cursor<true>;
|
||||
|
||||
using Parent = meta::const_if_c<IsConst, partial_sum_view>;
|
||||
using Base = meta::const_if_c<IsConst, Rng>;
|
||||
|
||||
Parent * parent_ = nullptr;
|
||||
RANGES_NO_UNIQUE_ADDRESS iterator_t<Base> current_{};
|
||||
RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<range_value_t<Rng>> sum_;
|
||||
|
||||
public:
|
||||
using single_pass = meta::bool_<single_pass_iterator_<iterator_t<Base>>>;
|
||||
|
||||
cursor() = default;
|
||||
constexpr explicit cursor(Parent * rng)
|
||||
: parent_{rng}
|
||||
, current_(ranges::begin(rng->base_))
|
||||
{
|
||||
if(current_ != ranges::end(rng->base_))
|
||||
sum_ = *current_;
|
||||
}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other) AND
|
||||
convertible_to<iterator_t<Rng> const &,
|
||||
iterator_t<Base>>)
|
||||
constexpr cursor(cursor<Other> const & that)
|
||||
: parent_{that.parent_}
|
||||
, current_(that.current_)
|
||||
, sum_(that.sum_)
|
||||
{}
|
||||
constexpr range_value_t<Rng> read() const
|
||||
{
|
||||
RANGES_EXPECT(current_ != ranges::end(parent_->base_));
|
||||
return sum_;
|
||||
}
|
||||
constexpr void next()
|
||||
{
|
||||
auto last = ranges::end(parent_->base_);
|
||||
RANGES_EXPECT(current_ != last);
|
||||
if(++current_ != last)
|
||||
{
|
||||
auto & sum = static_cast<range_value_t<Rng> &>(sum_);
|
||||
using F = meta::const_if_c<IsConst, Fun>;
|
||||
auto & f = static_cast<F &>(parent_->fun_);
|
||||
sum = invoke(f, sum, *current_);
|
||||
}
|
||||
}
|
||||
constexpr bool equal(default_sentinel_t) const
|
||||
{
|
||||
return current_ == ranges::end(parent_->base_);
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr bool CPP_fun(equal)(cursor const & that)(const //
|
||||
requires equality_comparable<iterator_t<Base>>)
|
||||
{
|
||||
RANGES_EXPECT(parent_ == that.parent_);
|
||||
return current_ == that.current_;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr cursor<false> begin_cursor()
|
||||
{
|
||||
return cursor<false>{this};
|
||||
}
|
||||
template(typename CRng = Rng const)(
|
||||
requires detail::partial_sum_view_constraints<CRng, Fun const>)
|
||||
constexpr cursor<true> begin_cursor() const
|
||||
{
|
||||
return cursor<true>{this};
|
||||
}
|
||||
|
||||
public:
|
||||
partial_sum_view() = default;
|
||||
constexpr partial_sum_view(Rng rng, Fun fun) noexcept(
|
||||
std::is_nothrow_move_constructible<Rng>::value &&
|
||||
std::is_nothrow_move_constructible<Fun>::value)
|
||||
: base_(std::move(rng))
|
||||
, fun_(std::move(fun))
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(base_);
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(base_);
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Fun>)
|
||||
partial_sum_view(Rng &&, Fun)
|
||||
-> partial_sum_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct partial_sum_base_fn
|
||||
{
|
||||
template(typename Rng, typename Fun = plus)(
|
||||
requires detail::partial_sum_view_constraints<all_t<Rng>, Fun>)
|
||||
constexpr partial_sum_view<all_t<Rng>, Fun> //
|
||||
operator()(Rng && rng, Fun fun = {}) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(fun)};
|
||||
}
|
||||
};
|
||||
|
||||
struct partial_sum_fn : partial_sum_base_fn
|
||||
{
|
||||
using partial_sum_base_fn::operator();
|
||||
|
||||
template(typename Fun)(
|
||||
requires (!range<Fun>))
|
||||
constexpr auto operator()(Fun && fun) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(partial_sum_base_fn{}, static_cast<Fun &&>(fun)));
|
||||
}
|
||||
template<typename Fun = plus>
|
||||
RANGES_DEPRECATED(
|
||||
"Use \"ranges::views::partial_sum\" instead of "
|
||||
"\"ranges::views::partial_sum()\".")
|
||||
constexpr auto
|
||||
operator()() const
|
||||
{
|
||||
return make_view_closure(bind_back(partial_sum_base_fn{}, Fun{}));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates partial_sum_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<partial_sum_fn>, partial_sum)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::partial_sum_view)
|
||||
|
||||
#endif
|
||||
125
Telegram/ThirdParty/range-v3/include/range/v3/view/ref.hpp
vendored
Normal file
125
Telegram/ThirdParty/range-v3/include/range/v3/view/ref.hpp
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_REF_HPP
|
||||
#define RANGES_V3_VIEW_REF_HPP
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/addressof.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
template<typename Rng>
|
||||
struct ref_view;
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<ref_view<Rng>> = true;
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct ref_view : view_interface<ref_view<Rng>, range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
CPP_assert(range<Rng>);
|
||||
static_assert(std::is_object<Rng>::value, "");
|
||||
Rng * rng_ = nullptr; // exposition only
|
||||
public:
|
||||
constexpr ref_view() noexcept = default;
|
||||
constexpr ref_view(Rng & rng) noexcept
|
||||
: rng_(detail::addressof(rng))
|
||||
{}
|
||||
constexpr Rng & base() const noexcept
|
||||
{
|
||||
return *rng_;
|
||||
}
|
||||
constexpr iterator_t<Rng> begin() const noexcept(noexcept(ranges::begin(*rng_)))
|
||||
{
|
||||
return ranges::begin(*rng_);
|
||||
}
|
||||
constexpr sentinel_t<Rng> end() const noexcept(noexcept(ranges::end(*rng_)))
|
||||
{
|
||||
return ranges::end(*rng_);
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto empty() const noexcept(noexcept(ranges::empty(*rng_)))
|
||||
-> CPP_ret(bool)(
|
||||
requires detail::can_empty_<Rng>)
|
||||
{
|
||||
return ranges::empty(*rng_);
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
noexcept(noexcept(ranges::size(*rng_))) //
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(*rng_);
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(data)()(const //
|
||||
noexcept(noexcept(ranges::data(*rng_))) //
|
||||
requires contiguous_range<Rng>)
|
||||
{
|
||||
return ranges::data(*rng_);
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename R)(
|
||||
requires range<R>)
|
||||
ref_view(R &) //
|
||||
-> ref_view<R>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct ref_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires range<Rng>)
|
||||
constexpr ref_view<Rng> operator()(Rng & rng) const noexcept
|
||||
{
|
||||
return ref_view<Rng>(rng);
|
||||
}
|
||||
template<typename Rng>
|
||||
void operator()(Rng const && rng) const = delete;
|
||||
};
|
||||
|
||||
/// \relates const_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(ref_fn, ref)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires std::is_object<Rng>::value) //
|
||||
using ref_view = ranges::ref_view<Rng>;
|
||||
}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::ref_view)
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
109
Telegram/ThirdParty/range-v3/include/range/v3/view/remove.hpp
vendored
Normal file
109
Telegram/ThirdParty/range-v3/include/range/v3/view/remove.hpp
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Andrey Diduh 2019
|
||||
//
|
||||
// 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_REMOVE_HPP
|
||||
#define RANGES_V3_VIEW_REMOVE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/comparisons.hpp>
|
||||
#include <range/v3/view/remove_if.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
struct remove_base_fn
|
||||
{
|
||||
private:
|
||||
template<typename Value>
|
||||
struct pred_
|
||||
{
|
||||
Value value_;
|
||||
template(typename T)(
|
||||
requires equality_comparable_with<T, Value const &>)
|
||||
bool operator()(T && other) const
|
||||
{
|
||||
return static_cast<T &&>(other) == value_;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
template(typename Rng, typename Value)(
|
||||
requires move_constructible<Value> AND viewable_range<Rng> AND
|
||||
input_range<Rng> AND
|
||||
indirectly_comparable<iterator_t<Rng>, Value const *, equal_to>)
|
||||
constexpr auto operator()(Rng && rng, Value value) const
|
||||
{
|
||||
return remove_if(static_cast<Rng &&>(rng),
|
||||
pred_<Value>{std::move(value)});
|
||||
}
|
||||
|
||||
template(typename Rng, typename Value, typename Proj)(
|
||||
requires move_constructible<Value> AND viewable_range<Rng> AND
|
||||
input_range<Rng> AND
|
||||
indirectly_comparable<iterator_t<Rng>, Value const *, equal_to, Proj>)
|
||||
constexpr auto operator()(Rng && rng, Value value, Proj proj) const
|
||||
{
|
||||
return remove_if(static_cast<Rng &&>(rng),
|
||||
pred_<Value>{std::move(value)},
|
||||
std::move(proj));
|
||||
}
|
||||
};
|
||||
|
||||
struct remove_bind_fn
|
||||
{
|
||||
template<typename Value>
|
||||
constexpr auto operator()(Value value) const // TODO: underconstrained
|
||||
{
|
||||
return make_view_closure(bind_back(remove_base_fn{}, std::move(value)));
|
||||
}
|
||||
template(typename Value, typename Proj)(
|
||||
requires (!range<Value>)) // TODO: underconstrained
|
||||
constexpr auto operator()(Value && value, Proj proj) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
remove_base_fn{}, static_cast<Value &&>(value), std::move(proj)));
|
||||
}
|
||||
};
|
||||
|
||||
struct RANGES_EMPTY_BASES remove_fn
|
||||
: remove_base_fn, remove_bind_fn
|
||||
{
|
||||
using remove_base_fn::operator();
|
||||
using remove_bind_fn::operator();
|
||||
};
|
||||
|
||||
/// \relates remove_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(remove_fn, remove)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_VIEW_REMOVE_HPP
|
||||
209
Telegram/ThirdParty/range-v3/include/range/v3/view/remove_if.hpp
vendored
Normal file
209
Telegram/ThirdParty/range-v3/include/range/v3/view/remove_if.hpp
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_REMOVE_IF_HPP
|
||||
#define RANGES_V3_VIEW_REMOVE_IF_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/compose.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/box.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Pred>
|
||||
struct RANGES_EMPTY_BASES remove_if_view
|
||||
: view_adaptor<remove_if_view<Rng, Pred>, Rng,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
, private box<semiregular_box_t<Pred>>
|
||||
{
|
||||
remove_if_view() = default;
|
||||
constexpr remove_if_view(Rng rng, Pred pred)
|
||||
: remove_if_view::view_adaptor{detail::move(rng)}
|
||||
, remove_if_view::box(detail::move(pred))
|
||||
{}
|
||||
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
adaptor() = default;
|
||||
constexpr adaptor(remove_if_view * rng) noexcept
|
||||
: rng_(rng)
|
||||
{}
|
||||
static constexpr iterator_t<Rng> begin(remove_if_view & rng)
|
||||
{
|
||||
return *rng.begin_;
|
||||
}
|
||||
constexpr void next(iterator_t<Rng> & it) const
|
||||
{
|
||||
RANGES_ASSERT(it != ranges::end(rng_->base()));
|
||||
rng_->satisfy_forward(++it);
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto prev(iterator_t<Rng> & it) const //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<Rng>)
|
||||
{
|
||||
rng_->satisfy_reverse(it);
|
||||
}
|
||||
void advance() = delete;
|
||||
void distance_to() = delete;
|
||||
|
||||
private:
|
||||
remove_if_view * rng_;
|
||||
};
|
||||
constexpr adaptor begin_adaptor()
|
||||
{
|
||||
cache_begin();
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() const noexcept //
|
||||
-> CPP_ret(adaptor_base)(
|
||||
requires (!common_range<Rng>))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() //
|
||||
-> CPP_ret(adaptor)(
|
||||
requires common_range<Rng>)
|
||||
{
|
||||
if(bidirectional_range<Rng>)
|
||||
cache_begin();
|
||||
return {this};
|
||||
}
|
||||
|
||||
constexpr void satisfy_forward(iterator_t<Rng> & it)
|
||||
{
|
||||
auto const last = ranges::end(this->base());
|
||||
auto & pred = this->remove_if_view::box::get();
|
||||
while(it != last && invoke(pred, *it))
|
||||
++it;
|
||||
}
|
||||
constexpr void satisfy_reverse(iterator_t<Rng> & it)
|
||||
{
|
||||
RANGES_ASSERT(begin_);
|
||||
auto const & first = *begin_;
|
||||
auto & pred = this->remove_if_view::box::get();
|
||||
do
|
||||
{
|
||||
RANGES_ASSERT(it != first);
|
||||
(void)first;
|
||||
--it;
|
||||
} while(invoke(pred, *it));
|
||||
}
|
||||
|
||||
constexpr void cache_begin()
|
||||
{
|
||||
if(begin_)
|
||||
return;
|
||||
auto it = ranges::begin(this->base());
|
||||
satisfy_forward(it);
|
||||
begin_.emplace(std::move(it));
|
||||
}
|
||||
|
||||
detail::non_propagating_cache<iterator_t<Rng>> begin_;
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Pred)(
|
||||
requires copy_constructible<Pred>)
|
||||
remove_if_view(Rng &&, Pred)
|
||||
-> remove_if_view<views::all_t<Rng>, Pred>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
/// Given a source range, unary predicate, and optional projection,
|
||||
/// present a view of the elements that do not satisfy the predicate.
|
||||
struct remove_if_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, iterator_t<Rng>>)
|
||||
constexpr remove_if_view<all_t<Rng>, Pred> operator()(Rng && rng, Pred pred)
|
||||
const
|
||||
{
|
||||
return remove_if_view<all_t<Rng>, Pred>{all(static_cast<Rng &&>(rng)),
|
||||
std::move(pred)};
|
||||
}
|
||||
template(typename Rng, typename Pred, typename Proj)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, projected<iterator_t<Rng>, Proj>>)
|
||||
constexpr remove_if_view<all_t<Rng>, composed<Pred, Proj>> //
|
||||
operator()(Rng && rng, Pred pred, Proj proj) const
|
||||
{
|
||||
return remove_if_view<all_t<Rng>, composed<Pred, Proj>>{
|
||||
all(static_cast<Rng &&>(rng)),
|
||||
compose(std::move(pred), std::move(proj))};
|
||||
}
|
||||
};
|
||||
|
||||
struct remove_if_bind_fn
|
||||
{
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const // TODO: underconstrained
|
||||
{
|
||||
return make_view_closure(bind_back(remove_if_base_fn{}, std::move(pred)));
|
||||
}
|
||||
template(typename Pred, typename Proj)(
|
||||
requires (!range<Pred>)) // TODO: underconstrained
|
||||
constexpr auto operator()(Pred && pred, Proj proj) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
remove_if_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
|
||||
}
|
||||
};
|
||||
|
||||
struct RANGES_EMPTY_BASES remove_if_fn
|
||||
: remove_if_base_fn, remove_if_bind_fn
|
||||
{
|
||||
using remove_if_base_fn::operator();
|
||||
using remove_if_bind_fn::operator();
|
||||
};
|
||||
|
||||
/// \relates remove_if_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(remove_if_fn, remove_if)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::remove_if_view)
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
123
Telegram/ThirdParty/range-v3/include/range/v3/view/repeat.hpp
vendored
Normal file
123
Telegram/ThirdParty/range-v3/include/range/v3/view/repeat.hpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_REPEAT_HPP
|
||||
#define RANGES_V3_VIEW_REPEAT_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
// Ordinarily, a view shouldn't contain its elements. This is so that copying
|
||||
// and assigning ranges is O(1), and also so that in the event of element
|
||||
// mutation, all the copies of the range see the mutation the same way. The
|
||||
// repeat_view *does* own its lone element, though. This is OK because:
|
||||
// - O(N) copying is fine when N==1 as it is in this case, and
|
||||
// - The element is immutable, so there is no potential for incorrect
|
||||
// semantics.
|
||||
template<typename Val>
|
||||
struct repeat_view : view_facade<repeat_view<Val>, infinite>
|
||||
{
|
||||
private:
|
||||
semiregular_box_t<Val> value_;
|
||||
friend range_access;
|
||||
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
Val const * value_;
|
||||
std::ptrdiff_t n_ = 0;
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
explicit cursor(Val const & value)
|
||||
: value_(std::addressof(value))
|
||||
{}
|
||||
Val const & read() const noexcept
|
||||
{
|
||||
return *value_;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return n_ == that.n_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++n_;
|
||||
}
|
||||
void prev()
|
||||
{
|
||||
--n_;
|
||||
}
|
||||
void advance(std::ptrdiff_t d)
|
||||
{
|
||||
n_ += d;
|
||||
}
|
||||
std::ptrdiff_t distance_to(cursor const & that) const
|
||||
{
|
||||
return that.n_ - n_;
|
||||
}
|
||||
};
|
||||
cursor begin_cursor() const
|
||||
{
|
||||
return cursor{value_};
|
||||
}
|
||||
unreachable_sentinel_t end_cursor() const
|
||||
{
|
||||
return unreachable;
|
||||
}
|
||||
|
||||
public:
|
||||
repeat_view() = default;
|
||||
constexpr explicit repeat_view(Val value)
|
||||
: value_(detail::move(value))
|
||||
{}
|
||||
};
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct repeat_fn
|
||||
{
|
||||
template(typename Val)(
|
||||
requires copy_constructible<Val>)
|
||||
repeat_view<Val> operator()(Val value) const
|
||||
{
|
||||
return repeat_view<Val>{std::move(value)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates repeat_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(repeat_fn, repeat)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::repeat_view)
|
||||
|
||||
#endif
|
||||
131
Telegram/ThirdParty/range-v3/include/range/v3/view/repeat_n.hpp
vendored
Normal file
131
Telegram/ThirdParty/range-v3/include/range/v3/view/repeat_n.hpp
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_REPEAT_N_HPP
|
||||
#define RANGES_V3_VIEW_REPEAT_N_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
// Ordinarily, a view shouldn't contain its elements. This is so that copying
|
||||
// and assigning ranges is O(1), and also so that in the event of element
|
||||
// mutation, all the copies of the range see the mutation the same way. The
|
||||
// repeat_n_view *does* own its lone element, though. This is OK because:
|
||||
// - O(N) copying is fine when N==1 as it is in this case, and
|
||||
// - The element is immutable, so there is no potential for incorrect
|
||||
// semantics.
|
||||
template<typename Val>
|
||||
struct repeat_n_view : view_facade<repeat_n_view<Val>, finite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
semiregular_box_t<Val> value_;
|
||||
std::ptrdiff_t n_;
|
||||
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
Val const * value_;
|
||||
std::ptrdiff_t n_;
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
cursor(Val const & value, std::ptrdiff_t n)
|
||||
: value_(std::addressof(value))
|
||||
, n_(n)
|
||||
{}
|
||||
Val const & read() const
|
||||
{
|
||||
return *value_;
|
||||
}
|
||||
constexpr bool equal(default_sentinel_t) const
|
||||
{
|
||||
return 0 == n_;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return n_ == that.n_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
RANGES_EXPECT(0 != n_);
|
||||
--n_;
|
||||
}
|
||||
void prev()
|
||||
{
|
||||
++n_;
|
||||
}
|
||||
void advance(std::ptrdiff_t n)
|
||||
{
|
||||
n_ -= n;
|
||||
}
|
||||
std::ptrdiff_t distance_to(cursor const & that) const
|
||||
{
|
||||
return n_ - that.n_;
|
||||
}
|
||||
};
|
||||
cursor begin_cursor() const
|
||||
{
|
||||
return {value_, n_};
|
||||
}
|
||||
|
||||
public:
|
||||
repeat_n_view() = default;
|
||||
constexpr repeat_n_view(Val value, std::ptrdiff_t n)
|
||||
: value_(detail::move(value))
|
||||
, n_((RANGES_EXPECT(0 <= n), n))
|
||||
{}
|
||||
constexpr std::size_t size() const
|
||||
{
|
||||
return static_cast<std::size_t>(n_);
|
||||
}
|
||||
};
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct repeat_n_fn
|
||||
{
|
||||
template(typename Val)(
|
||||
requires copy_constructible<Val>)
|
||||
repeat_n_view<Val> operator()(Val value, std::ptrdiff_t n) const
|
||||
{
|
||||
return repeat_n_view<Val>{std::move(value), n};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates repeat_n_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(repeat_n_fn, repeat_n)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::repeat_n_view)
|
||||
|
||||
#endif
|
||||
142
Telegram/ThirdParty/range-v3/include/range/v3/view/replace.hpp
vendored
Normal file
142
Telegram/ThirdParty/range-v3/include/range/v3/view/replace.hpp
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_REPLACE_HPP
|
||||
#define RANGES_V3_VIEW_REPLACE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Val1, typename Val2>
|
||||
struct replacer_fn
|
||||
{
|
||||
private:
|
||||
Val1 old_value_;
|
||||
Val2 new_value_;
|
||||
|
||||
public:
|
||||
replacer_fn() = default;
|
||||
constexpr replacer_fn(Val1 old_value, Val2 new_value)
|
||||
: old_value_(std::move(old_value))
|
||||
, new_value_(std::move(new_value))
|
||||
{}
|
||||
|
||||
template<typename I>
|
||||
[[noreturn]] common_type_t<decay_t<unwrap_reference_t<Val2 const &>>,
|
||||
iter_value_t<I>> &
|
||||
operator()(copy_tag, I const &) const
|
||||
{
|
||||
RANGES_EXPECT(false);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
common_reference_t<unwrap_reference_t<Val2 const &>, iter_reference_t<I>>
|
||||
operator()(I const & i) const
|
||||
{
|
||||
auto && x = *i;
|
||||
if(x == unwrap_reference(old_value_))
|
||||
return unwrap_reference(new_value_);
|
||||
return ((decltype(x) &&)x);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
common_reference_t<unwrap_reference_t<Val2 const &>,
|
||||
iter_rvalue_reference_t<I>>
|
||||
operator()(move_tag, I const & i) const
|
||||
{
|
||||
auto && x = iter_move(i);
|
||||
if(x == unwrap_reference(old_value_))
|
||||
return unwrap_reference(new_value_);
|
||||
return ((decltype(x) &&)x);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
struct replace_base_fn
|
||||
{
|
||||
template(typename Rng, typename Val1, typename Val2)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
same_as<
|
||||
detail::decay_t<unwrap_reference_t<Val1>>,
|
||||
detail::decay_t<unwrap_reference_t<Val2>>> AND
|
||||
equality_comparable_with<
|
||||
detail::decay_t<unwrap_reference_t<Val1>>,
|
||||
range_value_t<Rng>> AND
|
||||
common_with<detail::decay_t<unwrap_reference_t<Val2 const &>>,
|
||||
range_value_t<Rng>> AND
|
||||
common_reference_with<unwrap_reference_t<Val2 const &>,
|
||||
range_reference_t<Rng>> AND
|
||||
common_reference_with<
|
||||
unwrap_reference_t<Val2 const &>,
|
||||
range_rvalue_reference_t<Rng>>)
|
||||
constexpr replace_view< //
|
||||
all_t<Rng>, //
|
||||
detail::decay_t<Val1>, //
|
||||
detail::decay_t<Val2>> //
|
||||
operator()(Rng && rng, Val1 && old_value,
|
||||
Val2 && new_value) const //
|
||||
{
|
||||
return {
|
||||
all(static_cast<Rng &&>(rng)),
|
||||
{static_cast<Val1 &&>(old_value), static_cast<Val2 &&>(new_value)}};
|
||||
}
|
||||
};
|
||||
|
||||
struct replace_fn : replace_base_fn
|
||||
{
|
||||
using replace_base_fn::operator();
|
||||
|
||||
template(typename Val1, typename Val2)(
|
||||
requires same_as<detail::decay_t<unwrap_reference_t<Val1>>,
|
||||
detail::decay_t<unwrap_reference_t<Val2>>>)
|
||||
constexpr auto operator()(Val1 old_value, Val2 new_value) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
replace_base_fn{}, std::move(old_value), std::move(new_value)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates replace_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(replace_fn, replace)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
157
Telegram/ThirdParty/range-v3/include/range/v3/view/replace_if.hpp
vendored
Normal file
157
Telegram/ThirdParty/range-v3/include/range/v3/view/replace_if.hpp
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_REPLACE_IF_HPP
|
||||
#define RANGES_V3_VIEW_REPLACE_IF_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/utility/compressed_pair.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/transform.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Pred, typename Val>
|
||||
struct replacer_if_fn : compressed_pair<semiregular_box_t<Pred>, Val>
|
||||
{
|
||||
private:
|
||||
using base_t = compressed_pair<semiregular_box_t<Pred>, Val>;
|
||||
using base_t::first;
|
||||
using base_t::second;
|
||||
|
||||
public:
|
||||
replacer_if_fn() = default;
|
||||
constexpr replacer_if_fn(Pred pred, Val new_value)
|
||||
: base_t{std::move(pred), std::move(new_value)}
|
||||
{}
|
||||
|
||||
template<typename I>
|
||||
[[noreturn]] common_type_t<decay_t<unwrap_reference_t<Val const &>>,
|
||||
iter_value_t<I>> &
|
||||
operator()(copy_tag, I const &) const
|
||||
{
|
||||
RANGES_EXPECT(false);
|
||||
}
|
||||
|
||||
template(typename I)(
|
||||
requires (!invocable<Pred const &, iter_reference_t<I>>))
|
||||
common_reference_t<unwrap_reference_t<Val const &>, iter_reference_t<I>> //
|
||||
operator()(I const & i)
|
||||
{
|
||||
auto && x = *i;
|
||||
if(invoke(first(), (decltype(x) &&)x)) //
|
||||
return unwrap_reference(second());
|
||||
return (decltype(x) &&)x;
|
||||
}
|
||||
template(typename I)(
|
||||
requires invocable<Pred const &, iter_reference_t<I>>)
|
||||
common_reference_t<unwrap_reference_t<Val const &>, iter_reference_t<I>> //
|
||||
operator()(I const & i) const
|
||||
{
|
||||
auto && x = *i;
|
||||
if(invoke(first(), (decltype(x) &&)x)) //
|
||||
return unwrap_reference(second());
|
||||
return (decltype(x) &&)x;
|
||||
}
|
||||
|
||||
template(typename I)(
|
||||
requires (!invocable<Pred const &, iter_rvalue_reference_t<I>>))
|
||||
common_reference_t<
|
||||
unwrap_reference_t<Val const &>, //
|
||||
iter_rvalue_reference_t<I>> //
|
||||
operator()(move_tag, I const & i)
|
||||
{
|
||||
auto && x = iter_move(i);
|
||||
if(invoke(first(), (decltype(x) &&)x)) //
|
||||
return unwrap_reference(second());
|
||||
return (decltype(x) &&)x;
|
||||
}
|
||||
template(typename I)(
|
||||
requires invocable<Pred const &, iter_rvalue_reference_t<I>>)
|
||||
common_reference_t< //
|
||||
unwrap_reference_t<Val const &>, //
|
||||
iter_rvalue_reference_t<I>> //
|
||||
operator()(move_tag, I const & i) const
|
||||
{
|
||||
auto && x = iter_move(i);
|
||||
if(invoke(first(), (decltype(x) &&)x)) //
|
||||
return unwrap_reference(second());
|
||||
return (decltype(x) &&)x;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
struct replace_if_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred, typename Val)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, iterator_t<Rng>> AND
|
||||
common_with<detail::decay_t<unwrap_reference_t<Val const &>>,
|
||||
range_value_t<Rng>> AND
|
||||
common_reference_with<unwrap_reference_t<Val const &>,
|
||||
range_reference_t<Rng>> AND
|
||||
common_reference_with<unwrap_reference_t<Val const &>,
|
||||
range_rvalue_reference_t<Rng>>)
|
||||
constexpr replace_if_view<all_t<Rng>, Pred, Val> //
|
||||
operator()(Rng && rng, Pred pred, Val new_value) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
{std::move(pred), std::move(new_value)}};
|
||||
}
|
||||
};
|
||||
|
||||
struct replace_if_fn : replace_if_base_fn
|
||||
{
|
||||
using replace_if_base_fn::operator();
|
||||
|
||||
template<typename Pred, typename Val>
|
||||
constexpr auto operator()(Pred pred, Val new_value) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
replace_if_base_fn{}, std::move(pred), std::move(new_value)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates replace_if_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(replace_if_fn, replace_if)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
186
Telegram/ThirdParty/range-v3/include/range/v3/view/reverse.hpp
vendored
Normal file
186
Telegram/ThirdParty/range-v3/include/range/v3/view/reverse.hpp
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_REVERSE_HPP
|
||||
#define RANGES_V3_VIEW_REVERSE_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/reverse_iterator.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/box.hpp>
|
||||
#include <range/v3/utility/get.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct RANGES_EMPTY_BASES reverse_view
|
||||
: view_interface<reverse_view<Rng>, range_cardinality<Rng>::value>
|
||||
, private detail::non_propagating_cache<iterator_t<Rng>, reverse_view<Rng>,
|
||||
!common_range<Rng>>
|
||||
{
|
||||
private:
|
||||
CPP_assert(bidirectional_range<Rng>);
|
||||
Rng rng_;
|
||||
constexpr reverse_iterator<iterator_t<Rng>> begin_(std::true_type)
|
||||
{
|
||||
return make_reverse_iterator(ranges::end(rng_));
|
||||
}
|
||||
constexpr reverse_iterator<iterator_t<Rng>> begin_(std::false_type)
|
||||
{
|
||||
using cache_t =
|
||||
detail::non_propagating_cache<iterator_t<Rng>, reverse_view<Rng>>;
|
||||
auto & end_ = static_cast<cache_t &>(*this);
|
||||
if(!end_)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
auto tmp = ranges::begin(rng_);
|
||||
auto e = ranges::end(rng_);
|
||||
while(tmp != e)
|
||||
++tmp;
|
||||
#else
|
||||
auto tmp = ranges::next(ranges::begin(rng_), ranges::end(rng_));
|
||||
#endif
|
||||
end_ = std::move(tmp);
|
||||
}
|
||||
return make_reverse_iterator(*end_);
|
||||
}
|
||||
|
||||
public:
|
||||
reverse_view() = default;
|
||||
constexpr explicit reverse_view(Rng rng)
|
||||
: rng_(detail::move(rng))
|
||||
{}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
constexpr reverse_iterator<iterator_t<Rng>> begin()
|
||||
{
|
||||
return begin_(meta::bool_<(bool)common_range<Rng>>{});
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND common_range<meta::const_if_c<Const, Rng>>)
|
||||
constexpr reverse_iterator<iterator_t<meta::const_if_c<Const, Rng>>> begin() const
|
||||
{
|
||||
return make_reverse_iterator(ranges::end(rng_));
|
||||
}
|
||||
constexpr reverse_iterator<iterator_t<Rng>> end()
|
||||
{
|
||||
return make_reverse_iterator(ranges::begin(rng_));
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND common_range<meta::const_if_c<Const, Rng>>)
|
||||
constexpr reverse_iterator<iterator_t<meta::const_if_c<Const, Rng>>> end() const
|
||||
{
|
||||
return make_reverse_iterator(ranges::begin(rng_));
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(rng_);
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(rng_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct reverse_view<reverse_view<Rng>> : Rng
|
||||
{
|
||||
CPP_assert(bidirectional_range<Rng>);
|
||||
CPP_assert(
|
||||
same_as<detail::decay_t<decltype(std::declval<reverse_view<Rng>>().base())>,
|
||||
Rng>);
|
||||
|
||||
reverse_view() = default;
|
||||
constexpr explicit reverse_view(reverse_view<Rng> rng)
|
||||
: Rng(rng.base())
|
||||
{}
|
||||
|
||||
constexpr reverse_view<Rng> base() const
|
||||
{
|
||||
return reverse_view<Rng>{*this};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<reverse_view<Rng>> =
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
reverse_view(Rng &&) //
|
||||
-> reverse_view<views::all_t<Rng>>;
|
||||
|
||||
template<typename Rng>
|
||||
reverse_view(reverse_view<Rng>)
|
||||
-> reverse_view<reverse_view<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct reverse_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND bidirectional_range<Rng>)
|
||||
constexpr reverse_view<all_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
return reverse_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates reverse_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<reverse_fn>, reverse)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::reverse;
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires view_<Rng> AND bidirectional_range<Rng>)
|
||||
using reverse_view = ranges::reverse_view<Rng>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::reverse_view)
|
||||
|
||||
#endif
|
||||
267
Telegram/ThirdParty/range-v3/include/range/v3/view/sample.hpp
vendored
Normal file
267
Telegram/ThirdParty/range-v3/include/range/v3/view/sample.hpp
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Casey Carter 2016
|
||||
//
|
||||
// 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_SAMPLE_HPP
|
||||
#define RANGES_V3_VIEW_SAMPLE_HPP
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/algorithm/shuffle.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Rng,
|
||||
bool = (bool)sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>>>
|
||||
class size_tracker
|
||||
{
|
||||
range_difference_t<Rng> size_;
|
||||
|
||||
public:
|
||||
CPP_assert(forward_range<Rng> || sized_range<Rng>);
|
||||
size_tracker() = default;
|
||||
size_tracker(Rng & rng)
|
||||
: size_(ranges::distance(rng))
|
||||
{}
|
||||
void decrement()
|
||||
{
|
||||
--size_;
|
||||
}
|
||||
range_difference_t<Rng> get(Rng &, iterator_t<Rng> &) const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
};
|
||||
|
||||
// Impl for sized_sentinel_for (no need to store anything)
|
||||
template<typename Rng>
|
||||
class size_tracker<Rng, true>
|
||||
{
|
||||
public:
|
||||
size_tracker() = default;
|
||||
size_tracker(Rng &)
|
||||
{}
|
||||
void decrement()
|
||||
{}
|
||||
range_difference_t<Rng> get(Rng & rng, iterator_t<Rng> const & it) const
|
||||
{
|
||||
return ranges::end(rng) - it;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
// Take a random sampling from another view
|
||||
template<typename Rng, typename URNG>
|
||||
class sample_view : public view_facade<sample_view<Rng, URNG>, finite>
|
||||
{
|
||||
friend range_access;
|
||||
using D = range_difference_t<Rng>;
|
||||
Rng rng_;
|
||||
// Mutable is OK here because sample_view is an Input view.
|
||||
mutable range_difference_t<Rng> size_;
|
||||
URNG * engine_;
|
||||
|
||||
template<bool IsConst>
|
||||
class cursor
|
||||
{
|
||||
friend cursor<!IsConst>;
|
||||
|
||||
using Base = meta::const_if_c<IsConst, Rng>;
|
||||
meta::const_if_c<IsConst, sample_view> * parent_;
|
||||
iterator_t<Base> current_;
|
||||
RANGES_NO_UNIQUE_ADDRESS detail::size_tracker<Base> size_;
|
||||
|
||||
D pop_size()
|
||||
{
|
||||
return size_.get(parent_->rng_, current_);
|
||||
}
|
||||
void advance()
|
||||
{
|
||||
if(parent_->size_ > 0)
|
||||
{
|
||||
using Dist = std::uniform_int_distribution<D>;
|
||||
Dist dist{};
|
||||
URNG & engine = *parent_->engine_;
|
||||
|
||||
for(;; ++current_, size_.decrement())
|
||||
{
|
||||
RANGES_ASSERT(current_ != ranges::end(parent_->rng_));
|
||||
auto n = pop_size();
|
||||
RANGES_EXPECT(n > 0);
|
||||
typename Dist::param_type const interval{0, n - 1};
|
||||
if(dist(engine, interval) < parent_->size_)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = range_value_t<Rng>;
|
||||
using difference_type = D;
|
||||
|
||||
cursor() = default;
|
||||
explicit cursor(meta::const_if_c<IsConst, sample_view> * rng)
|
||||
: parent_(rng)
|
||||
, current_(ranges::begin(rng->rng_))
|
||||
, size_{rng->rng_}
|
||||
{
|
||||
auto n = pop_size();
|
||||
if(rng->size_ > n)
|
||||
rng->size_ = n;
|
||||
advance();
|
||||
}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: parent_(that.parent_)
|
||||
, current_(std::move(that.current_))
|
||||
, size_(that.size_)
|
||||
{}
|
||||
range_reference_t<Rng> read() const
|
||||
{
|
||||
return *current_;
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
RANGES_EXPECT(parent_);
|
||||
return parent_->size_ <= 0;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
RANGES_EXPECT(parent_);
|
||||
RANGES_EXPECT(parent_->size_ > 0);
|
||||
--parent_->size_;
|
||||
RANGES_ASSERT(current_ != ranges::end(parent_->rng_));
|
||||
++current_;
|
||||
size_.decrement();
|
||||
advance();
|
||||
}
|
||||
};
|
||||
|
||||
cursor<false> begin_cursor()
|
||||
{
|
||||
return cursor<false>{this};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND
|
||||
(sized_range<meta::const_if_c<Const, Rng>> ||
|
||||
sized_sentinel_for<sentinel_t<meta::const_if_c<Const, Rng>>,
|
||||
iterator_t<meta::const_if_c<Const, Rng>>> ||
|
||||
forward_range<meta::const_if_c<Const, Rng>>)) //
|
||||
cursor<Const> begin_cursor() const
|
||||
{
|
||||
return cursor<true>{this};
|
||||
}
|
||||
|
||||
public:
|
||||
sample_view() = default;
|
||||
|
||||
explicit sample_view(Rng rng, D sample_size, URNG & generator)
|
||||
: rng_(std::move(rng))
|
||||
, size_(sample_size)
|
||||
, engine_(std::addressof(generator))
|
||||
{
|
||||
RANGES_EXPECT(sample_size >= 0);
|
||||
}
|
||||
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng, typename URNG>
|
||||
sample_view(Rng &&, range_difference_t<Rng>, URNG &)
|
||||
->sample_view<views::all_t<Rng>, URNG>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
/// Returns a random sample of a range of length `size(range)`.
|
||||
struct sample_base_fn
|
||||
{
|
||||
template(typename Rng, typename URNG = detail::default_random_engine)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
uniform_random_bit_generator<URNG> AND
|
||||
convertible_to<invoke_result_t<URNG &>, range_difference_t<Rng>> AND
|
||||
(sized_range<Rng> ||
|
||||
sized_sentinel_for<sentinel_t<Rng>, iterator_t<Rng>> ||
|
||||
forward_range<Rng>)) //
|
||||
sample_view<all_t<Rng>, URNG> operator()(
|
||||
Rng && rng,
|
||||
range_difference_t<Rng> sample_size,
|
||||
URNG & generator = detail::get_random_engine()) const
|
||||
{
|
||||
return sample_view<all_t<Rng>, URNG>{
|
||||
all(static_cast<Rng &&>(rng)), sample_size, generator};
|
||||
}
|
||||
|
||||
/// \cond
|
||||
template<typename Rng, typename URNG>
|
||||
invoke_result_t<sample_base_fn, Rng, range_difference_t<Rng>, URNG &> //
|
||||
operator()(
|
||||
Rng && rng,
|
||||
range_difference_t<Rng> sample_size,
|
||||
detail::reference_wrapper_<URNG> r) const
|
||||
{
|
||||
return (*this)(static_cast<Rng &&>(rng), sample_size, r.get());
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
struct sample_fn : sample_base_fn
|
||||
{
|
||||
using sample_base_fn::operator();
|
||||
|
||||
template(typename Size, typename URNG = detail::default_random_engine)(
|
||||
requires integral<Size> AND uniform_random_bit_generator<URNG>)
|
||||
constexpr auto operator()(
|
||||
Size n,
|
||||
URNG & urng = detail::get_random_engine()) const //
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
sample_base_fn{}, n, detail::reference_wrapper_<URNG>(urng)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates sample_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(sample_fn, sample)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::sample_view)
|
||||
|
||||
#endif
|
||||
890
Telegram/ThirdParty/range-v3/include/range/v3/view/set_algorithm.hpp
vendored
Normal file
890
Telegram/ThirdParty/range-v3/include/range/v3/view/set_algorithm.hpp
vendored
Normal file
@@ -0,0 +1,890 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
// Copyright Tomislav Ivek 2015-2016
|
||||
//
|
||||
// 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_SET_ALGORITHM_HPP
|
||||
#define RANGES_V3_VIEW_SET_ALGORITHM_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/comparisons.hpp>
|
||||
#include <range/v3/functional/identity.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/move.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Rng1, typename Rng2, typename C, typename P1, typename P2,
|
||||
template<bool, typename...> class Cursor, cardinality Cardinality>
|
||||
struct set_algorithm_view
|
||||
: view_facade<set_algorithm_view<Rng1, Rng2, C, P1, P2, Cursor, Cardinality>,
|
||||
Cardinality>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
semiregular_box_t<C> pred_;
|
||||
semiregular_box_t<P1> proj1_;
|
||||
semiregular_box_t<P2> proj2_;
|
||||
Rng1 rng1_;
|
||||
Rng2 rng2_;
|
||||
|
||||
template<bool IsConst>
|
||||
using cursor = Cursor<IsConst, Rng1, Rng2, C, P1, P2>;
|
||||
|
||||
cursor<simple_view<Rng1>() && simple_view<Rng2>()> begin_cursor()
|
||||
{
|
||||
return {pred_,
|
||||
proj1_,
|
||||
proj2_,
|
||||
ranges::begin(rng1_),
|
||||
ranges::end(rng1_),
|
||||
ranges::begin(rng2_),
|
||||
ranges::end(rng2_)};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_cursor() const //
|
||||
-> CPP_ret(cursor<true>)(
|
||||
requires range<Rng1 const> && range<Rng2 const>)
|
||||
{
|
||||
return {pred_,
|
||||
proj1_,
|
||||
proj2_,
|
||||
ranges::begin(rng1_),
|
||||
ranges::end(rng1_),
|
||||
ranges::begin(rng2_),
|
||||
ranges::end(rng2_)};
|
||||
}
|
||||
|
||||
public:
|
||||
set_algorithm_view() = default;
|
||||
set_algorithm_view(Rng1 rng1, Rng2 rng2, C pred, P1 proj1, P2 proj2)
|
||||
: pred_(std::move(pred))
|
||||
, proj1_(std::move(proj1))
|
||||
, proj2_(std::move(proj2))
|
||||
, rng1_(std::move(rng1))
|
||||
, rng2_(std::move(rng2))
|
||||
{}
|
||||
};
|
||||
|
||||
template<bool IsConst, typename Rng1, typename Rng2, typename C, typename P1,
|
||||
typename P2>
|
||||
struct set_difference_cursor
|
||||
{
|
||||
private:
|
||||
friend struct set_difference_cursor<!IsConst, Rng1, Rng2, C, P1, P2>;
|
||||
using pred_ref_ = semiregular_box_ref_or_val_t<C, IsConst>;
|
||||
using proj1_ref_ = semiregular_box_ref_or_val_t<P1, IsConst>;
|
||||
using proj2_ref_ = semiregular_box_ref_or_val_t<P2, IsConst>;
|
||||
pred_ref_ pred_;
|
||||
proj1_ref_ proj1_;
|
||||
proj2_ref_ proj2_;
|
||||
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst, T>;
|
||||
|
||||
using R1 = constify_if<Rng1>;
|
||||
using R2 = constify_if<Rng2>;
|
||||
|
||||
iterator_t<R1> it1_;
|
||||
sentinel_t<R1> end1_;
|
||||
|
||||
iterator_t<R2> it2_;
|
||||
sentinel_t<R2> end2_;
|
||||
|
||||
void satisfy()
|
||||
{
|
||||
while(it1_ != end1_)
|
||||
{
|
||||
if(it2_ == end2_)
|
||||
return;
|
||||
|
||||
if(invoke(pred_, invoke(proj1_, *it1_), invoke(proj2_, *it2_)))
|
||||
return;
|
||||
|
||||
if(!invoke(pred_, invoke(proj2_, *it2_), invoke(proj1_, *it1_)))
|
||||
++it1_;
|
||||
|
||||
++it2_;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = range_value_t<constify_if<Rng1>>;
|
||||
using single_pass = meta::or_c<single_pass_iterator_<iterator_t<R1>>,
|
||||
single_pass_iterator_<iterator_t<R2>>>;
|
||||
|
||||
set_difference_cursor() = default;
|
||||
set_difference_cursor(pred_ref_ pred, proj1_ref_ proj1, proj2_ref_ proj2,
|
||||
iterator_t<R1> it1, sentinel_t<R1> end1,
|
||||
iterator_t<R2> it2, sentinel_t<R2> end2)
|
||||
: pred_(std::move(pred))
|
||||
, proj1_(std::move(proj1))
|
||||
, proj2_(std::move(proj2))
|
||||
, it1_(std::move(it1))
|
||||
, end1_(std::move(end1))
|
||||
, it2_(std::move(it2))
|
||||
, end2_(std::move(end2))
|
||||
{
|
||||
satisfy();
|
||||
}
|
||||
template(bool Other)(
|
||||
requires IsConst && CPP_NOT(Other)) //
|
||||
set_difference_cursor(
|
||||
set_difference_cursor<Other, Rng1, Rng2, C, P1, P2> that)
|
||||
: pred_(std::move(that.pred_))
|
||||
, proj1_(std::move(that.proj1_))
|
||||
, proj2_(std::move(that.proj2_))
|
||||
, it1_(std::move(that.it1_))
|
||||
, end1_(std::move(that.end1_))
|
||||
, it2_(std::move(that.it2_))
|
||||
, end2_(std::move(that.end2_))
|
||||
{}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(read)()(const)
|
||||
(
|
||||
return *it1_
|
||||
)
|
||||
// clang-format on
|
||||
void next()
|
||||
{
|
||||
++it1_;
|
||||
satisfy();
|
||||
}
|
||||
CPP_member
|
||||
auto equal(set_difference_cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires forward_range<Rng1>)
|
||||
{
|
||||
// does not support comparing iterators from different ranges
|
||||
return it1_ == that.it1_;
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return it1_ == end1_;
|
||||
}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(move)()(const)
|
||||
(
|
||||
return iter_move(it1_)
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
constexpr cardinality set_difference_cardinality(cardinality c1, cardinality c2)
|
||||
{
|
||||
return (c1 == unknown)
|
||||
? unknown
|
||||
: (c1 >= 0) || (c1 == finite) ? finite : // else, c1 == infinite
|
||||
(c2 >= 0) || (c2 == finite) ? infinite : unknown;
|
||||
}
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename Rng1, typename Rng2, typename C, typename P1, typename P2>
|
||||
using set_difference_view =
|
||||
detail::set_algorithm_view<Rng1, Rng2, C, P1, P2, detail::set_difference_cursor,
|
||||
detail::set_difference_cardinality(
|
||||
range_cardinality<Rng1>::value,
|
||||
range_cardinality<Rng2>::value)>;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct set_difference_base_fn
|
||||
{
|
||||
template(typename Rng1, typename Rng2, typename C = less,
|
||||
typename P1 = identity, typename P2 = identity)(
|
||||
requires //
|
||||
viewable_range<Rng1> AND input_range<Rng1> AND
|
||||
viewable_range<Rng2> AND input_range<Rng2> AND
|
||||
indirect_relation<C,
|
||||
projected<iterator_t<Rng1>, P1>,
|
||||
projected<iterator_t<Rng2>, P2>>)
|
||||
set_difference_view<all_t<Rng1>, all_t<Rng2>, C, P1, P2> //
|
||||
operator()(Rng1 && rng1,
|
||||
Rng2 && rng2,
|
||||
C pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return {all(static_cast<Rng1 &&>(rng1)),
|
||||
all(static_cast<Rng2 &&>(rng2)),
|
||||
std::move(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)};
|
||||
}
|
||||
};
|
||||
|
||||
struct set_difference_fn : set_difference_base_fn
|
||||
{
|
||||
using set_difference_base_fn::operator();
|
||||
|
||||
template(typename Rng2, typename C = less, typename P1 = identity,
|
||||
typename P2 = identity)(
|
||||
requires viewable_range<Rng2> AND input_range<Rng2> AND (!range<C>))
|
||||
constexpr auto operator()(Rng2 && rng2,
|
||||
C && pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return make_view_closure(bind_back(set_difference_base_fn{},
|
||||
all(rng2),
|
||||
static_cast<C &&>(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates set_difference_fn
|
||||
RANGES_INLINE_VARIABLE(set_difference_fn, set_difference)
|
||||
} // namespace views
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<bool IsConst, typename Rng1, typename Rng2, typename C, typename P1,
|
||||
typename P2>
|
||||
struct set_intersection_cursor
|
||||
{
|
||||
private:
|
||||
friend struct set_intersection_cursor<!IsConst, Rng1, Rng2, C, P1, P2>;
|
||||
using pred_ref_ = semiregular_box_ref_or_val_t<C, IsConst>;
|
||||
using proj1_ref_ = semiregular_box_ref_or_val_t<P1, IsConst>;
|
||||
using proj2_ref_ = semiregular_box_ref_or_val_t<P2, IsConst>;
|
||||
pred_ref_ pred_;
|
||||
proj1_ref_ proj1_;
|
||||
proj2_ref_ proj2_;
|
||||
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst, T>;
|
||||
|
||||
using R1 = constify_if<Rng1>;
|
||||
using R2 = constify_if<Rng2>;
|
||||
|
||||
iterator_t<R1> it1_;
|
||||
sentinel_t<R1> end1_;
|
||||
|
||||
iterator_t<R2> it2_;
|
||||
sentinel_t<R2> end2_;
|
||||
|
||||
void satisfy()
|
||||
{
|
||||
while(it1_ != end1_ && it2_ != end2_)
|
||||
{
|
||||
if(invoke(pred_, invoke(proj1_, *it1_), invoke(proj2_, *it2_)))
|
||||
++it1_;
|
||||
else
|
||||
{
|
||||
if(!invoke(pred_, invoke(proj2_, *it2_), invoke(proj1_, *it1_)))
|
||||
return;
|
||||
++it2_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = range_value_t<R1>;
|
||||
using single_pass = meta::or_c<single_pass_iterator_<iterator_t<R1>>,
|
||||
single_pass_iterator_<iterator_t<R2>>>;
|
||||
|
||||
set_intersection_cursor() = default;
|
||||
set_intersection_cursor(pred_ref_ pred, proj1_ref_ proj1, proj2_ref_ proj2,
|
||||
iterator_t<R1> it1, sentinel_t<R1> end1,
|
||||
iterator_t<R2> it2, sentinel_t<R2> end2)
|
||||
: pred_(std::move(pred))
|
||||
, proj1_(std::move(proj1))
|
||||
, proj2_(std::move(proj2))
|
||||
, it1_(std::move(it1))
|
||||
, end1_(std::move(end1))
|
||||
, it2_(std::move(it2))
|
||||
, end2_(std::move(end2))
|
||||
{
|
||||
satisfy();
|
||||
}
|
||||
template(bool Other)(
|
||||
requires IsConst && CPP_NOT(Other)) //
|
||||
set_intersection_cursor(
|
||||
set_intersection_cursor<Other, Rng1, Rng2, C, P1, P2> that)
|
||||
: pred_(std::move(that.pred_))
|
||||
, proj1_(std::move(that.proj1_))
|
||||
, proj2_(std::move(that.proj2_))
|
||||
, it1_(std::move(that.it1_))
|
||||
, end1_(std::move(that.end1_))
|
||||
, it2_(std::move(that.it2_))
|
||||
, end2_(std::move(that.end2_))
|
||||
{}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(read)()(const)
|
||||
(
|
||||
return *it1_
|
||||
)
|
||||
// clang-format on
|
||||
void next()
|
||||
{
|
||||
++it1_;
|
||||
++it2_;
|
||||
satisfy();
|
||||
}
|
||||
CPP_member
|
||||
auto equal(set_intersection_cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires forward_range<Rng1>)
|
||||
{
|
||||
// does not support comparing iterators from different ranges
|
||||
return it1_ == that.it1_;
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return (it1_ == end1_) || (it2_ == end2_);
|
||||
}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(move)()(const)
|
||||
(
|
||||
return iter_move(it1_)
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
constexpr cardinality set_intersection_cardinality(cardinality c1, cardinality c2)
|
||||
{
|
||||
return (c1 == unknown) || (c2 == unknown)
|
||||
? unknown
|
||||
: (c1 >= 0 || c1 == finite) || (c2 >= 0 || c2 == finite) ? finite
|
||||
: unknown;
|
||||
}
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename Rng1, typename Rng2, typename C, typename P1, typename P2>
|
||||
using set_intersection_view =
|
||||
detail::set_algorithm_view<Rng1, Rng2, C, P1, P2, detail::set_intersection_cursor,
|
||||
detail::set_intersection_cardinality(
|
||||
range_cardinality<Rng1>::value,
|
||||
range_cardinality<Rng2>::value)>;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct set_intersection_base_fn
|
||||
{
|
||||
template(typename Rng1, typename Rng2, typename C = less,
|
||||
typename P1 = identity, typename P2 = identity)(
|
||||
requires viewable_range<Rng1> AND input_range<Rng1> AND
|
||||
viewable_range<Rng2> AND input_range<Rng2> AND
|
||||
indirect_relation<
|
||||
C,
|
||||
projected<iterator_t<Rng1>, P1>,
|
||||
projected<iterator_t<Rng2>, P2>>)
|
||||
set_intersection_view<all_t<Rng1>, all_t<Rng2>, C, P1, P2>
|
||||
operator()(Rng1 && rng1,
|
||||
Rng2 && rng2,
|
||||
C pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return {all(static_cast<Rng1 &&>(rng1)),
|
||||
all(static_cast<Rng2 &&>(rng2)),
|
||||
std::move(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)};
|
||||
}
|
||||
};
|
||||
|
||||
struct set_intersection_fn : set_intersection_base_fn
|
||||
{
|
||||
using set_intersection_base_fn::operator();
|
||||
|
||||
template(typename Rng2, typename C = less, typename P1 = identity,
|
||||
typename P2 = identity)(
|
||||
requires viewable_range<Rng2> AND input_range<Rng2> AND (!range<C>))
|
||||
constexpr auto operator()(Rng2 && rng2,
|
||||
C && pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return make_view_closure(bind_back(set_intersection_base_fn{},
|
||||
all(rng2),
|
||||
static_cast<C &&>(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates set_intersection_fn
|
||||
RANGES_INLINE_VARIABLE(set_intersection_fn, set_intersection)
|
||||
} // namespace views
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<bool IsConst, typename Rng1, typename Rng2, typename C, typename P1,
|
||||
typename P2>
|
||||
struct set_union_cursor
|
||||
{
|
||||
private:
|
||||
friend struct set_union_cursor<!IsConst, Rng1, Rng2, C, P1, P2>;
|
||||
using pred_ref_ = semiregular_box_ref_or_val_t<C, IsConst>;
|
||||
using proj1_ref_ = semiregular_box_ref_or_val_t<P1, IsConst>;
|
||||
using proj2_ref_ = semiregular_box_ref_or_val_t<P2, IsConst>;
|
||||
pred_ref_ pred_;
|
||||
proj1_ref_ proj1_;
|
||||
proj2_ref_ proj2_;
|
||||
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst, T>;
|
||||
|
||||
using R1 = constify_if<Rng1>;
|
||||
using R2 = constify_if<Rng2>;
|
||||
|
||||
iterator_t<R1> it1_;
|
||||
sentinel_t<R1> end1_;
|
||||
|
||||
iterator_t<R2> it2_;
|
||||
sentinel_t<R2> end2_;
|
||||
|
||||
enum class state_t
|
||||
{
|
||||
FIRST,
|
||||
SECOND
|
||||
} state;
|
||||
|
||||
void satisfy()
|
||||
{
|
||||
if(it1_ == end1_)
|
||||
{
|
||||
state = state_t::SECOND;
|
||||
return;
|
||||
}
|
||||
|
||||
if(it2_ == end2_)
|
||||
{
|
||||
state = state_t::FIRST;
|
||||
return;
|
||||
}
|
||||
|
||||
if(invoke(pred_, invoke(proj2_, *it2_), invoke(proj1_, *it1_)))
|
||||
{
|
||||
state = state_t::SECOND;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!invoke(pred_, invoke(proj1_, *it1_), invoke(proj2_, *it2_)))
|
||||
++it2_;
|
||||
|
||||
state = state_t::FIRST;
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = common_type_t<range_value_t<R1>, range_value_t<R2>>;
|
||||
using reference_type =
|
||||
common_reference_t<range_reference_t<R1>, range_reference_t<R2>>;
|
||||
using rvalue_reference_type =
|
||||
common_reference_t<range_rvalue_reference_t<R1>,
|
||||
range_rvalue_reference_t<R2>>;
|
||||
using single_pass = meta::or_c<single_pass_iterator_<iterator_t<R1>>,
|
||||
single_pass_iterator_<iterator_t<R2>>>;
|
||||
|
||||
set_union_cursor() = default;
|
||||
set_union_cursor(pred_ref_ pred, proj1_ref_ proj1, proj2_ref_ proj2,
|
||||
iterator_t<R1> it1, sentinel_t<R1> end1, iterator_t<R2> it2,
|
||||
sentinel_t<R2> end2)
|
||||
: pred_(std::move(pred))
|
||||
, proj1_(std::move(proj1))
|
||||
, proj2_(std::move(proj2))
|
||||
, it1_(std::move(it1))
|
||||
, end1_(std::move(end1))
|
||||
, it2_(std::move(it2))
|
||||
, end2_(std::move(end2))
|
||||
{
|
||||
satisfy();
|
||||
}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other))
|
||||
set_union_cursor(set_union_cursor<Other, Rng1, Rng2, C, P1, P2> that)
|
||||
: pred_(std::move(that.pred_))
|
||||
, proj1_(std::move(that.proj1_))
|
||||
, proj2_(std::move(that.proj2_))
|
||||
, it1_(std::move(that.it1_))
|
||||
, end1_(std::move(that.end1_))
|
||||
, it2_(std::move(that.it2_))
|
||||
, end2_(std::move(that.end2_))
|
||||
{}
|
||||
reference_type read() const noexcept(noexcept(*it1_) && noexcept(*it2_))
|
||||
{
|
||||
if(state == state_t::SECOND)
|
||||
return *it2_;
|
||||
else
|
||||
return *it1_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
if(state == state_t::FIRST)
|
||||
++it1_;
|
||||
else
|
||||
++it2_;
|
||||
satisfy();
|
||||
}
|
||||
CPP_member
|
||||
auto equal(set_union_cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires forward_range<Rng1> && forward_range<Rng2>)
|
||||
{
|
||||
// does not support comparing iterators from different ranges
|
||||
return (it1_ == that.it1_) && (it2_ == that.it2_);
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return (it1_ == end1_) && (it2_ == end2_);
|
||||
}
|
||||
rvalue_reference_type move() const
|
||||
noexcept(noexcept(iter_move(it1_)) && noexcept(iter_move(it2_)))
|
||||
{
|
||||
if(state == state_t::SECOND)
|
||||
return iter_move(it2_);
|
||||
else
|
||||
return iter_move(it1_);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr cardinality set_union_cardinality(cardinality c1, cardinality c2)
|
||||
{
|
||||
return (c1 == infinite) || (c2 == infinite)
|
||||
? infinite
|
||||
: (c1 == unknown) || (c2 == unknown) ? unknown : finite;
|
||||
}
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename Rng1, typename Rng2, typename C, typename P1, typename P2>
|
||||
using set_union_view =
|
||||
detail::set_algorithm_view<Rng1, Rng2, C, P1, P2, detail::set_union_cursor,
|
||||
detail::set_union_cardinality(
|
||||
range_cardinality<Rng1>::value,
|
||||
range_cardinality<Rng2>::value)>;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct set_union_base_fn
|
||||
{
|
||||
public:
|
||||
template(typename Rng1, typename Rng2, typename C = less,
|
||||
typename P1 = identity, typename P2 = identity)(
|
||||
requires //
|
||||
viewable_range<Rng1> AND input_range<Rng1> AND
|
||||
viewable_range<Rng2> AND input_range<Rng2> AND
|
||||
common_with<range_value_t<Rng1>, range_value_t<Rng2>> AND
|
||||
common_reference_with<range_reference_t<Rng1>,
|
||||
range_reference_t<Rng2>> AND
|
||||
common_reference_with<range_rvalue_reference_t<Rng1>,
|
||||
range_rvalue_reference_t<Rng2>> AND
|
||||
indirect_relation<C,
|
||||
projected<iterator_t<Rng1>, P1>,
|
||||
projected<iterator_t<Rng2>, P2>>)
|
||||
set_union_view<all_t<Rng1>, all_t<Rng2>, C, P1, P2> //
|
||||
operator()(Rng1 && rng1,
|
||||
Rng2 && rng2,
|
||||
C pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return {all(static_cast<Rng1 &&>(rng1)),
|
||||
all(static_cast<Rng2 &&>(rng2)),
|
||||
std::move(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)};
|
||||
}
|
||||
};
|
||||
|
||||
struct set_union_fn : set_union_base_fn
|
||||
{
|
||||
using set_union_base_fn::operator();
|
||||
|
||||
template(typename Rng2, typename C = less, typename P1 = identity,
|
||||
typename P2 = identity)(
|
||||
requires viewable_range<Rng2> AND input_range<Rng2> AND (!range<C>))
|
||||
constexpr auto operator()(Rng2 && rng2,
|
||||
C && pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return make_view_closure(bind_back(set_union_base_fn{},
|
||||
all(rng2),
|
||||
static_cast<C &&>(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates set_union_fn
|
||||
RANGES_INLINE_VARIABLE(set_union_fn, set_union)
|
||||
} // namespace views
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<bool IsConst, typename Rng1, typename Rng2, typename C, typename P1,
|
||||
typename P2>
|
||||
struct set_symmetric_difference_cursor
|
||||
{
|
||||
private:
|
||||
friend struct set_symmetric_difference_cursor<!IsConst, Rng1, Rng2, C, P1,
|
||||
P2>;
|
||||
using pred_ref_ = semiregular_box_ref_or_val_t<C, IsConst>;
|
||||
using proj1_ref_ = semiregular_box_ref_or_val_t<P1, IsConst>;
|
||||
using proj2_ref_ = semiregular_box_ref_or_val_t<P2, IsConst>;
|
||||
pred_ref_ pred_;
|
||||
proj1_ref_ proj1_;
|
||||
proj2_ref_ proj2_;
|
||||
|
||||
template<typename T>
|
||||
using constify_if = meta::const_if_c<IsConst, T>;
|
||||
|
||||
using R1 = constify_if<Rng1>;
|
||||
using R2 = constify_if<Rng2>;
|
||||
|
||||
iterator_t<R1> it1_;
|
||||
sentinel_t<R1> end1_;
|
||||
|
||||
iterator_t<R2> it2_;
|
||||
sentinel_t<R2> end2_;
|
||||
|
||||
enum class state_t
|
||||
{
|
||||
FIRST,
|
||||
SECOND,
|
||||
ONLY_FIRST,
|
||||
ONLY_SECOND
|
||||
} state;
|
||||
|
||||
void satisfy()
|
||||
{
|
||||
while(it1_ != end1_)
|
||||
{
|
||||
if(it2_ == end2_)
|
||||
{
|
||||
state = state_t::ONLY_FIRST;
|
||||
return;
|
||||
}
|
||||
|
||||
if(invoke(pred_, invoke(proj1_, *it1_), invoke(proj2_, *it2_)))
|
||||
{
|
||||
state = state_t::FIRST;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(invoke(pred_, invoke(proj2_, *it2_), invoke(proj1_, *it1_)))
|
||||
{
|
||||
state = state_t::SECOND;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
++it1_;
|
||||
++it2_;
|
||||
}
|
||||
}
|
||||
}
|
||||
state = state_t::ONLY_SECOND;
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = common_type_t<range_value_t<R1>, range_value_t<R2>>;
|
||||
using reference_type =
|
||||
common_reference_t<range_reference_t<R1>, range_reference_t<R2>>;
|
||||
using rvalue_reference_type =
|
||||
common_reference_t<range_rvalue_reference_t<R1>,
|
||||
range_rvalue_reference_t<R2>>;
|
||||
using single_pass = meta::or_c<single_pass_iterator_<iterator_t<R1>>,
|
||||
single_pass_iterator_<iterator_t<R2>>>;
|
||||
|
||||
set_symmetric_difference_cursor() = default;
|
||||
set_symmetric_difference_cursor(pred_ref_ pred, proj1_ref_ proj1,
|
||||
proj2_ref_ proj2, iterator_t<R1> it1,
|
||||
sentinel_t<R1> end1, iterator_t<R2> it2,
|
||||
sentinel_t<R2> end2)
|
||||
: pred_(std::move(pred))
|
||||
, proj1_(std::move(proj1))
|
||||
, proj2_(std::move(proj2))
|
||||
, it1_(std::move(it1))
|
||||
, end1_(std::move(end1))
|
||||
, it2_(std::move(it2))
|
||||
, end2_(std::move(end2))
|
||||
, state()
|
||||
{
|
||||
satisfy();
|
||||
}
|
||||
template(bool Other)(
|
||||
requires IsConst && CPP_NOT(Other)) //
|
||||
set_symmetric_difference_cursor(
|
||||
set_symmetric_difference_cursor<Other, Rng1, Rng2, C, P1, P2> that)
|
||||
: pred_(std::move(that.pred_))
|
||||
, proj1_(std::move(that.proj1_))
|
||||
, proj2_(std::move(that.proj2_))
|
||||
, it1_(std::move(that.it1_))
|
||||
, end1_(std::move(that.end1_))
|
||||
, it2_(std::move(that.it2_))
|
||||
, end2_(std::move(that.end2_))
|
||||
, state(that.state)
|
||||
{}
|
||||
reference_type read() const noexcept(noexcept(*it1_) && noexcept(*it2_))
|
||||
{
|
||||
if(state == state_t::SECOND || state == state_t::ONLY_SECOND)
|
||||
return *it2_;
|
||||
else
|
||||
return *it1_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case state_t::FIRST:
|
||||
++it1_;
|
||||
satisfy();
|
||||
break;
|
||||
case state_t::ONLY_FIRST:
|
||||
++it1_;
|
||||
break;
|
||||
case state_t::SECOND:
|
||||
++it2_;
|
||||
satisfy();
|
||||
break;
|
||||
case state_t::ONLY_SECOND:
|
||||
++it2_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CPP_member
|
||||
auto equal(set_symmetric_difference_cursor const & that) const
|
||||
-> CPP_ret(bool)(
|
||||
requires forward_range<R1> && forward_range<R2>)
|
||||
{
|
||||
// does not support comparing iterators from different ranges:
|
||||
return (it1_ == that.it1_) && (it2_ == that.it2_);
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return (it1_ == end1_) && (it2_ == end2_);
|
||||
}
|
||||
rvalue_reference_type move() const
|
||||
noexcept(noexcept(iter_move(it1_)) && noexcept(iter_move(it2_)))
|
||||
{
|
||||
if(state == state_t::SECOND || state == state_t::ONLY_SECOND)
|
||||
return iter_move(it2_);
|
||||
else
|
||||
return iter_move(it1_);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr cardinality set_symmetric_difference_cardinality(cardinality c1,
|
||||
cardinality c2)
|
||||
{
|
||||
return (c1 == unknown) || (c2 == unknown)
|
||||
? unknown
|
||||
: (c1 == infinite) != (c2 == infinite)
|
||||
? infinite
|
||||
: (c1 == infinite) && (c2 == infinite) ? unknown : finite;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename Rng1, typename Rng2, typename C, typename P1, typename P2>
|
||||
using set_symmetric_difference_view = detail::set_algorithm_view<
|
||||
Rng1, Rng2, C, P1, P2, detail::set_symmetric_difference_cursor,
|
||||
detail::set_symmetric_difference_cardinality(range_cardinality<Rng1>::value,
|
||||
range_cardinality<Rng2>::value)>;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct set_symmetric_difference_base_fn
|
||||
{
|
||||
template(typename Rng1, typename Rng2, typename C = less,
|
||||
typename P1 = identity, typename P2 = identity)(
|
||||
requires //
|
||||
viewable_range<Rng1> AND input_range<Rng1> AND
|
||||
viewable_range<Rng2> AND input_range<Rng2> AND
|
||||
common_with<range_value_t<Rng1>, range_value_t<Rng2>> AND
|
||||
common_reference_with<range_reference_t<Rng1>,
|
||||
range_reference_t<Rng2>> AND
|
||||
common_reference_with<range_rvalue_reference_t<Rng1>,
|
||||
range_rvalue_reference_t<Rng2>> AND
|
||||
indirect_relation<C,
|
||||
projected<iterator_t<Rng1>, P1>,
|
||||
projected<iterator_t<Rng2>, P2>>)
|
||||
set_symmetric_difference_view<all_t<Rng1>, all_t<Rng2>, C, P1, P2>
|
||||
operator()(Rng1 && rng1,
|
||||
Rng2 && rng2,
|
||||
C pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return {all(static_cast<Rng1 &&>(rng1)),
|
||||
all(static_cast<Rng2 &&>(rng2)),
|
||||
std::move(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)};
|
||||
}
|
||||
};
|
||||
|
||||
struct set_symmetric_difference_fn : set_symmetric_difference_base_fn
|
||||
{
|
||||
using set_symmetric_difference_base_fn::operator();
|
||||
|
||||
template(typename Rng2, typename C = less, typename P1 = identity,
|
||||
typename P2 = identity)(
|
||||
requires viewable_range<Rng2> AND input_range<Rng2> AND (!range<C>))
|
||||
constexpr auto operator()(Rng2 && rng2,
|
||||
C && pred = C{},
|
||||
P1 proj1 = P1{},
|
||||
P2 proj2 = P2{}) const
|
||||
{
|
||||
return make_view_closure(bind_back(set_symmetric_difference_base_fn{},
|
||||
all(rng2),
|
||||
static_cast<C &&>(pred),
|
||||
std::move(proj1),
|
||||
std::move(proj2)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates set_symmetric_difference_fn
|
||||
RANGES_INLINE_VARIABLE(set_symmetric_difference_fn, set_symmetric_difference)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
141
Telegram/ThirdParty/range-v3/include/range/v3/view/single.hpp
vendored
Normal file
141
Telegram/ThirdParty/range-v3/include/range/v3/view/single.hpp
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_SINGLE_HPP
|
||||
#define RANGES_V3_VIEW_SINGLE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/traits.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/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename T>
|
||||
struct single_view : view_interface<single_view<T>, (cardinality)1>
|
||||
{
|
||||
private:
|
||||
CPP_assert(copy_constructible<T>);
|
||||
static_assert(std::is_object<T>::value,
|
||||
"The template parameter of single_view must be an object type");
|
||||
semiregular_box_t<T> value_;
|
||||
template<typename... Args>
|
||||
constexpr single_view(in_place_t, std::true_type, Args &&... args)
|
||||
: value_{static_cast<Args &&>(args)...}
|
||||
{}
|
||||
template<typename... Args>
|
||||
constexpr single_view(in_place_t, std::false_type, Args &&... args)
|
||||
: value_{in_place, static_cast<Args &&>(args)...}
|
||||
{}
|
||||
|
||||
public:
|
||||
single_view() = default;
|
||||
constexpr explicit single_view(T const & t)
|
||||
: value_(t)
|
||||
{}
|
||||
constexpr explicit single_view(T && t)
|
||||
: value_(std::move(t))
|
||||
{}
|
||||
template(class... Args)(
|
||||
requires constructible_from<T, Args...>)
|
||||
constexpr single_view(in_place_t, Args &&... args)
|
||||
: single_view{in_place,
|
||||
meta::bool_<(bool)semiregular<T>>{},
|
||||
static_cast<Args &&>(args)...}
|
||||
{}
|
||||
constexpr T * begin() noexcept
|
||||
{
|
||||
return data();
|
||||
}
|
||||
constexpr T const * begin() const noexcept
|
||||
{
|
||||
return data();
|
||||
}
|
||||
constexpr T * end() noexcept
|
||||
{
|
||||
return data() + 1;
|
||||
}
|
||||
constexpr T const * end() const noexcept
|
||||
{
|
||||
return data() + 1;
|
||||
}
|
||||
static constexpr std::size_t size() noexcept
|
||||
{
|
||||
return 1u;
|
||||
}
|
||||
constexpr T * data() noexcept
|
||||
{
|
||||
return detail::addressof(static_cast<T &>(value_));
|
||||
}
|
||||
constexpr T const * data() const noexcept
|
||||
{
|
||||
return detail::addressof(static_cast<T const &>(value_));
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<class T>
|
||||
explicit single_view(T &&) //
|
||||
-> single_view<detail::decay_t<T>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct single_fn
|
||||
{
|
||||
template(typename Val)(
|
||||
requires copy_constructible<Val>)
|
||||
single_view<Val> operator()(Val value) const
|
||||
{
|
||||
return single_view<Val>{std::move(value)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates single_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(single_fn, single)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::single;
|
||||
}
|
||||
template(typename T)(
|
||||
requires std::is_object<T>::value) //
|
||||
using single_view = ranges::single_view<T>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::single_view)
|
||||
|
||||
#endif
|
||||
341
Telegram/ThirdParty/range-v3/include/range/v3/view/slice.hpp
vendored
Normal file
341
Telegram/ThirdParty/range-v3/include/range/v3/view/slice.hpp
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_SLICE_HPP
|
||||
#define RANGES_V3_VIEW_SLICE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/counted_iterator.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/drop_exactly.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Rng, typename Int>
|
||||
iterator_t<Rng> pos_at_(Rng && rng, Int i, input_range_tag, std::true_type)
|
||||
{
|
||||
RANGES_EXPECT(0 <= i);
|
||||
return next(ranges::begin(rng), i);
|
||||
}
|
||||
|
||||
template<typename Rng, typename Int>
|
||||
iterator_t<Rng> pos_at_(Rng && rng, Int i, bidirectional_range_tag,
|
||||
std::false_type)
|
||||
{
|
||||
if(0 > i)
|
||||
{
|
||||
// If it's not common and we know the size, faster to count from the front
|
||||
if(RANGES_CONSTEXPR_IF(sized_range<Rng> && !common_range<Rng>))
|
||||
return next(ranges::begin(rng), distance(rng) + i);
|
||||
// Otherwise, probably faster to count from the back.
|
||||
return next(ranges::next(ranges::begin(rng), ranges::end(rng)), i);
|
||||
}
|
||||
return next(ranges::begin(rng), i);
|
||||
}
|
||||
|
||||
template<typename Rng, typename Int>
|
||||
iterator_t<Rng> pos_at_(Rng && rng, Int i, input_range_tag, std::false_type)
|
||||
{
|
||||
RANGES_EXPECT(i >= 0 || (bool)sized_range<Rng> || (bool)forward_range<Rng>);
|
||||
if(0 > i)
|
||||
return next(ranges::begin(rng), distance(rng) + i);
|
||||
return next(ranges::begin(rng), i);
|
||||
}
|
||||
|
||||
template<typename Rng, bool IsRandomAccess>
|
||||
struct slice_view_ : view_facade<slice_view<Rng>, finite>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
Rng rng_;
|
||||
range_difference_t<Rng> from_, count_;
|
||||
detail::non_propagating_cache<iterator_t<Rng>> begin_;
|
||||
|
||||
iterator_t<Rng> get_begin_()
|
||||
{
|
||||
if(!begin_)
|
||||
begin_ = detail::pos_at_(
|
||||
rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{});
|
||||
return *begin_;
|
||||
}
|
||||
|
||||
public:
|
||||
slice_view_() = default;
|
||||
constexpr slice_view_(Rng rng, range_difference_t<Rng> from,
|
||||
range_difference_t<Rng> count)
|
||||
: rng_(std::move(rng))
|
||||
, from_(from)
|
||||
, count_(count)
|
||||
{}
|
||||
counted_iterator<iterator_t<Rng>> begin()
|
||||
{
|
||||
return make_counted_iterator(get_begin_(), count_);
|
||||
}
|
||||
default_sentinel_t end()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
auto size() const
|
||||
{
|
||||
return static_cast<detail::iter_size_t<iterator_t<Rng>>>(count_);
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct slice_view_<Rng, true> : view_interface<slice_view<Rng>, finite>
|
||||
{
|
||||
private:
|
||||
Rng rng_;
|
||||
range_difference_t<Rng> from_, count_;
|
||||
|
||||
public:
|
||||
slice_view_() = default;
|
||||
constexpr slice_view_(Rng rng, range_difference_t<Rng> from,
|
||||
range_difference_t<Rng> count)
|
||||
: rng_(std::move(rng))
|
||||
, from_(from)
|
||||
, count_(count)
|
||||
{
|
||||
RANGES_EXPECT(0 <= count_);
|
||||
}
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
return detail::pos_at_(
|
||||
rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{});
|
||||
}
|
||||
iterator_t<Rng> end()
|
||||
{
|
||||
return detail::pos_at_(
|
||||
rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{}) +
|
||||
count_;
|
||||
}
|
||||
template(typename BaseRng = Rng)(
|
||||
requires range<BaseRng const>)
|
||||
iterator_t<BaseRng const> begin() const
|
||||
{
|
||||
return detail::pos_at_(
|
||||
rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{});
|
||||
}
|
||||
template(typename BaseRng = Rng)(
|
||||
requires range<BaseRng const>)
|
||||
iterator_t<BaseRng const> end() const
|
||||
{
|
||||
return detail::pos_at_(
|
||||
rng_, from_, range_tag_of<Rng>{}, is_infinite<Rng>{}) +
|
||||
count_;
|
||||
}
|
||||
auto size() const
|
||||
{
|
||||
return static_cast<detail::iter_size_t<iterator_t<Rng>>>(count_);
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct slice_view : detail::slice_view_<Rng, (bool)random_access_range<Rng>>
|
||||
{
|
||||
using detail::slice_view_<Rng, (bool)random_access_range<Rng>>::slice_view_;
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<slice_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
slice_view(Rng &&, range_difference_t<Rng>, range_difference_t<Rng>)
|
||||
->slice_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct slice_base_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
static constexpr slice_view<all_t<Rng>> impl_(Rng && rng,
|
||||
range_difference_t<Rng> from,
|
||||
range_difference_t<Rng> count,
|
||||
input_range_tag, range_tag = {})
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), from, count};
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires borrowed_range<Rng>)
|
||||
static subrange<iterator_t<Rng>> impl_(Rng && rng,
|
||||
range_difference_t<Rng> from,
|
||||
range_difference_t<Rng> count,
|
||||
random_access_range_tag,
|
||||
common_range_tag = {})
|
||||
{
|
||||
auto it =
|
||||
detail::pos_at_(rng, from, range_tag_of<Rng>{}, is_infinite<Rng>{});
|
||||
return {it, it + count};
|
||||
}
|
||||
|
||||
public:
|
||||
// slice(rng, 2, 4)
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
constexpr auto operator()(Rng && rng,
|
||||
range_difference_t<Rng> from,
|
||||
range_difference_t<Rng> to) const
|
||||
{
|
||||
RANGES_EXPECT(0 <= from && from <= to);
|
||||
return slice_base_fn::impl_(
|
||||
static_cast<Rng &&>(rng), from, to - from, range_tag_of<Rng>{});
|
||||
}
|
||||
// slice(rng, 4, end-2)
|
||||
// TODO Support Forward, non-Sized ranges by returning a range that
|
||||
// doesn't know it's size?
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND sized_range<Rng>)
|
||||
auto operator()(Rng && rng,
|
||||
range_difference_t<Rng> from,
|
||||
detail::from_end_of_t<Rng> to) const
|
||||
{
|
||||
static_assert(!is_infinite<Rng>::value,
|
||||
"Can't index from the end of an infinite range!");
|
||||
RANGES_EXPECT(0 <= from);
|
||||
RANGES_ASSERT(from <= distance(rng) + to.dist_);
|
||||
return slice_base_fn::impl_(static_cast<Rng &&>(rng),
|
||||
from,
|
||||
distance(rng) + to.dist_ - from,
|
||||
range_tag_of<Rng>{});
|
||||
}
|
||||
// slice(rng, end-4, end-2)
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND
|
||||
(forward_range<Rng> || (input_range<Rng> && sized_range<Rng>)))
|
||||
auto operator()(Rng && rng,
|
||||
detail::from_end_of_t<Rng> from,
|
||||
detail::from_end_of_t<Rng> to) const
|
||||
{
|
||||
static_assert(!is_infinite<Rng>::value,
|
||||
"Can't index from the end of an infinite range!");
|
||||
RANGES_EXPECT(from.dist_ <= to.dist_);
|
||||
return slice_base_fn::impl_(static_cast<Rng &&>(rng),
|
||||
from.dist_,
|
||||
to.dist_ - from.dist_,
|
||||
range_tag_of<Rng>{},
|
||||
common_range_tag_of<Rng>{});
|
||||
}
|
||||
// slice(rng, 4, end)
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
auto operator()(Rng && rng, range_difference_t<Rng> from, end_fn) const
|
||||
{
|
||||
RANGES_EXPECT(0 <= from);
|
||||
return ranges::views::drop_exactly(static_cast<Rng &&>(rng), from);
|
||||
}
|
||||
// slice(rng, end-4, end)
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND
|
||||
(forward_range<Rng> || (input_range<Rng> && sized_range<Rng>)))
|
||||
auto operator()(Rng && rng,
|
||||
detail::from_end_of_t<Rng> from,
|
||||
end_fn) const
|
||||
{
|
||||
static_assert(!is_infinite<Rng>::value,
|
||||
"Can't index from the end of an infinite range!");
|
||||
return slice_base_fn::impl_(static_cast<Rng &&>(rng),
|
||||
from.dist_,
|
||||
-from.dist_,
|
||||
range_tag_of<Rng>{},
|
||||
common_range_tag_of<Rng>{});
|
||||
}
|
||||
};
|
||||
|
||||
struct slice_fn : slice_base_fn
|
||||
{
|
||||
using slice_base_fn::operator();
|
||||
|
||||
// Overloads for the pipe syntax: rng | views::slice(from,to)
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int from, Int to) const
|
||||
{
|
||||
return make_view_closure(bind_back(slice_base_fn{}, from, to));
|
||||
}
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int from, detail::from_end_<Int> to) const
|
||||
{
|
||||
return make_view_closure(bind_back(slice_base_fn{}, from, to));
|
||||
}
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(detail::from_end_<Int> from,
|
||||
detail::from_end_<Int> to) const
|
||||
{
|
||||
return make_view_closure(bind_back(slice_base_fn{}, from, to));
|
||||
}
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int from, end_fn) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(ranges::views::drop_exactly_base_fn{}, from));
|
||||
}
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(detail::from_end_<Int> from, end_fn to) const
|
||||
{
|
||||
return make_view_closure(bind_back(slice_base_fn{}, from, to));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates _slice_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(slice_fn, slice)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::slice_view)
|
||||
|
||||
#endif
|
||||
407
Telegram/ThirdParty/range-v3/include/range/v3/view/sliding.hpp
vendored
Normal file
407
Telegram/ThirdParty/range-v3/include/range/v3/view/sliding.hpp
vendored
Normal file
@@ -0,0 +1,407 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
// Copyright Tobias Mayer 2016
|
||||
// Copyright Casey Carter 2016
|
||||
//
|
||||
// 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_SLIDING_HPP
|
||||
#define RANGES_V3_VIEW_SLIDING_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/counted.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace sliding_view_detail
|
||||
{
|
||||
enum class cache
|
||||
{
|
||||
none,
|
||||
first,
|
||||
last
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
using caching = std::integral_constant<
|
||||
cache, random_access_range<Rng> && sized_range<Rng>
|
||||
? cache::none
|
||||
: bidirectional_range<Rng> && common_range<Rng> ? cache::last
|
||||
: cache::first>;
|
||||
} // namespace sliding_view_detail
|
||||
/// \endcond
|
||||
|
||||
template<typename Rng,
|
||||
sliding_view_detail::cache = sliding_view_detail::caching<Rng>::value>
|
||||
struct sliding_view;
|
||||
|
||||
/// \cond
|
||||
namespace sliding_view_detail
|
||||
{
|
||||
template<typename Rng>
|
||||
using uncounted_t =
|
||||
decltype(ranges::uncounted(std::declval<iterator_t<Rng> &>()));
|
||||
|
||||
template<typename Rng, bool = (bool)random_access_range<Rng>>
|
||||
struct trailing
|
||||
{
|
||||
trailing() = default;
|
||||
constexpr trailing(Rng & rng)
|
||||
: it_{uncounted(ranges::begin(rng))}
|
||||
{}
|
||||
constexpr uncounted_t<Rng> get(iterator_t<Rng> const &,
|
||||
range_difference_t<Rng>) const
|
||||
{
|
||||
return it_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<Rng>)
|
||||
{
|
||||
--it_;
|
||||
}
|
||||
|
||||
private:
|
||||
uncounted_t<Rng> it_;
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct trailing<Rng, true>
|
||||
{
|
||||
trailing() = default;
|
||||
constexpr trailing(Rng &) noexcept
|
||||
{}
|
||||
constexpr uncounted_t<Rng> get(iterator_t<Rng> const & it,
|
||||
range_difference_t<Rng> n) const
|
||||
{
|
||||
return uncounted(it - (n - 1));
|
||||
}
|
||||
void next()
|
||||
{}
|
||||
void prev()
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct RANGES_EMPTY_BASES sv_base
|
||||
: view_adaptor<sliding_view<Rng>, Rng,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
, private detail::non_propagating_cache<iterator_t<Rng>, sv_base<Rng>,
|
||||
caching<Rng>::value != cache::none>
|
||||
{
|
||||
CPP_assert(forward_range<Rng>);
|
||||
sv_base() = default;
|
||||
sv_base(Rng rng, range_difference_t<Rng> n)
|
||||
: sv_base::view_adaptor(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_ASSERT(0 < n_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
auto const count = ranges::size(this->base());
|
||||
auto const n = static_cast<range_size_t<Rng const>>(n_);
|
||||
return count < n ? 0 : count - n + 1;
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
auto const count = ranges::size(this->base());
|
||||
auto const n = static_cast<range_size_t<Rng>>(n_);
|
||||
return count < n ? 0 : count - n + 1;
|
||||
}
|
||||
|
||||
protected:
|
||||
range_difference_t<Rng> n_;
|
||||
|
||||
optional<iterator_t<Rng>> & cache() &
|
||||
{
|
||||
return static_cast<cache_t &>(*this);
|
||||
}
|
||||
optional<iterator_t<Rng>> const & cache() const &
|
||||
{
|
||||
return static_cast<cache_t const &>(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
using cache_t = detail::non_propagating_cache<iterator_t<Rng>, sv_base<Rng>>;
|
||||
};
|
||||
} // namespace sliding_view_detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct sliding_view<Rng, sliding_view_detail::cache::first>
|
||||
: sliding_view_detail::sv_base<Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
iterator_t<Rng> get_first()
|
||||
{
|
||||
auto & first = this->cache();
|
||||
if(!first)
|
||||
{
|
||||
first = ranges::next(
|
||||
ranges::begin(this->base()), this->n_ - 1, ranges::end(this->base()));
|
||||
}
|
||||
return *first;
|
||||
}
|
||||
|
||||
struct RANGES_EMPTY_BASES adaptor
|
||||
: adaptor_base
|
||||
, sliding_view_detail::trailing<Rng>
|
||||
{
|
||||
private:
|
||||
using base_t = sliding_view_detail::trailing<Rng>;
|
||||
range_difference_t<Rng> n_ = {};
|
||||
|
||||
public:
|
||||
adaptor() = default;
|
||||
adaptor(sliding_view * v)
|
||||
: base_t{v->base()}
|
||||
, n_{v->n_}
|
||||
{}
|
||||
iterator_t<Rng> begin(sliding_view & v)
|
||||
{
|
||||
return v.get_first();
|
||||
}
|
||||
auto read(iterator_t<Rng> const & it) const
|
||||
-> decltype(views::counted(uncounted(it), n_))
|
||||
{
|
||||
return views::counted(base_t::get(it, n_), n_);
|
||||
}
|
||||
void next(iterator_t<Rng> & it)
|
||||
{
|
||||
++it;
|
||||
base_t::next();
|
||||
}
|
||||
CPP_member
|
||||
auto prev(iterator_t<Rng> & it) //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<Rng>)
|
||||
{
|
||||
base_t::prev();
|
||||
--it;
|
||||
}
|
||||
CPP_member
|
||||
auto advance(iterator_t<Rng> & it, range_difference_t<Rng> n)
|
||||
-> CPP_ret(void)(
|
||||
requires random_access_range<Rng>)
|
||||
{
|
||||
it += n;
|
||||
}
|
||||
};
|
||||
|
||||
adaptor begin_adaptor()
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
meta::if_c<common_range<Rng>, adaptor, adaptor_base> end_adaptor()
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
|
||||
public:
|
||||
using sliding_view::sv_base::sv_base;
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct sliding_view<Rng, sliding_view_detail::cache::last>
|
||||
: sliding_view_detail::sv_base<Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
iterator_t<Rng> get_last()
|
||||
{
|
||||
auto & last = this->cache();
|
||||
if(!last)
|
||||
{
|
||||
last = ranges::prev(
|
||||
ranges::end(this->base()), this->n_ - 1, ranges::begin(this->base()));
|
||||
}
|
||||
return *last;
|
||||
}
|
||||
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
range_difference_t<Rng> n_ = {};
|
||||
|
||||
public:
|
||||
adaptor() = default;
|
||||
adaptor(sliding_view * v)
|
||||
: n_{v->n_}
|
||||
{}
|
||||
iterator_t<Rng> end(sliding_view & v)
|
||||
{
|
||||
return v.get_last();
|
||||
}
|
||||
auto read(iterator_t<Rng> const & it) const
|
||||
-> decltype(views::counted(uncounted(it), n_))
|
||||
{
|
||||
return views::counted(uncounted(it), n_);
|
||||
}
|
||||
};
|
||||
|
||||
adaptor begin_adaptor()
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
adaptor end_adaptor()
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
|
||||
public:
|
||||
using sliding_view::sv_base::sv_base;
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct sliding_view<Rng, sliding_view_detail::cache::none>
|
||||
: sliding_view_detail::sv_base<Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
template<bool Const>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
friend adaptor<!Const>;
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
range_difference_t<Rng> n_ = 0;
|
||||
|
||||
public:
|
||||
adaptor() = default;
|
||||
adaptor(range_difference_t<Rng> n)
|
||||
: n_(n)
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
adaptor(adaptor<Other> that)
|
||||
: n_(that.n_)
|
||||
{}
|
||||
iterator_t<CRng> end(meta::const_if_c<Const, sliding_view> & v) const
|
||||
{
|
||||
auto const sz = ranges::distance(v.base());
|
||||
auto const offset = n_ - 1 < sz ? n_ - 1 : sz;
|
||||
return ranges::begin(v.base()) + (sz - offset);
|
||||
}
|
||||
auto read(iterator_t<CRng> const & it) const
|
||||
-> decltype(views::counted(uncounted(it), n_))
|
||||
{
|
||||
return views::counted(uncounted(it), n_);
|
||||
}
|
||||
};
|
||||
|
||||
adaptor<simple_view<Rng>()> begin_adaptor()
|
||||
{
|
||||
return {this->n_};
|
||||
}
|
||||
CPP_member
|
||||
auto begin_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return {this->n_};
|
||||
}
|
||||
adaptor<simple_view<Rng>()> end_adaptor()
|
||||
{
|
||||
return {this->n_};
|
||||
}
|
||||
CPP_member
|
||||
auto end_adaptor() const //
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return {this->n_};
|
||||
}
|
||||
|
||||
public:
|
||||
using sliding_view::sv_base::sv_base;
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<sliding_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
sliding_view(Rng &&, range_difference_t<Rng>)
|
||||
-> sliding_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
// In: range<T>
|
||||
// Out: range<range<T>>, where each inner range has $n$ elements.
|
||||
struct sliding_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng>)
|
||||
constexpr sliding_view<all_t<Rng>> //
|
||||
operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), n};
|
||||
}
|
||||
};
|
||||
|
||||
struct sliding_fn : sliding_base_fn
|
||||
{
|
||||
using sliding_base_fn::operator();
|
||||
|
||||
template<typename Int>
|
||||
constexpr auto CPP_fun(operator())(Int n)(const //
|
||||
requires detail::integer_like_<Int>)
|
||||
{
|
||||
return make_view_closure(bind_back(sliding_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates sliding_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(sliding_fn, sliding)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
426
Telegram/ThirdParty/range-v3/include/range/v3/view/span.hpp
vendored
Normal file
426
Telegram/ThirdParty/range-v3/include/range/v3/view/span.hpp
vendored
Normal file
@@ -0,0 +1,426 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Casey Carter 2016-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_SPAN_HPP
|
||||
#define RANGES_V3_VIEW_SPAN_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/equal.hpp>
|
||||
#include <range/v3/algorithm/lexicographical_compare.hpp>
|
||||
#include <range/v3/iterator/reverse_iterator.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
using span_index_t = std::ptrdiff_t;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
constexpr detail::span_index_t dynamic_extent = -1;
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template(typename To, typename From)(
|
||||
requires integral<To> AND integral<From>)
|
||||
constexpr To narrow_cast(From from) noexcept
|
||||
{
|
||||
using C = common_type_t<To, From>;
|
||||
return RANGES_EXPECT((from > 0) == (static_cast<To>(from) > 0)),
|
||||
RANGES_EXPECT(static_cast<C>(from) ==
|
||||
static_cast<C>(static_cast<To>(from))),
|
||||
static_cast<To>(from);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr span_index_t byte_size(span_index_t n) noexcept
|
||||
{
|
||||
return n == dynamic_extent ? dynamic_extent
|
||||
: (RANGES_EXPECT(n >= 0),
|
||||
RANGES_EXPECT(narrow_cast<std::size_t>(n) <=
|
||||
PTRDIFF_MAX / sizeof(T)),
|
||||
n * narrow_cast<span_index_t>(sizeof(T)));
|
||||
}
|
||||
|
||||
template<span_index_t N>
|
||||
struct span_extent
|
||||
{
|
||||
CPP_assert(N >= 0);
|
||||
|
||||
constexpr span_extent() noexcept = default;
|
||||
constexpr span_extent(span_index_t size) noexcept
|
||||
// this constructor does nothing, the delegation exists only
|
||||
// to provide a place for the contract check expression.
|
||||
: span_extent{(RANGES_EXPECT(size == N), tag{})}
|
||||
{}
|
||||
|
||||
constexpr span_index_t size() const noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
private:
|
||||
struct tag
|
||||
{};
|
||||
constexpr span_extent(tag) noexcept
|
||||
{}
|
||||
};
|
||||
template<>
|
||||
struct span_extent<dynamic_extent>
|
||||
{
|
||||
span_extent() = default;
|
||||
constexpr span_extent(span_index_t size) noexcept
|
||||
: size_{((void)RANGES_EXPECT(size >= 0), size)}
|
||||
{}
|
||||
constexpr span_index_t size() const noexcept
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
private:
|
||||
span_index_t size_ = 0;
|
||||
};
|
||||
|
||||
constexpr span_index_t subspan_extent(span_index_t Extent, span_index_t Offset,
|
||||
span_index_t Count) noexcept
|
||||
{
|
||||
return Count == dynamic_extent && Extent != dynamic_extent ? Extent - Offset
|
||||
: Count;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// clang-format off
|
||||
/// \concept span_compatible_range_
|
||||
/// \brief The \c span_compatible_range_ concept
|
||||
template(typename Rng, typename T)(
|
||||
concept (span_compatible_range_)(Rng, T),
|
||||
detail::is_convertible<detail::element_t<Rng>(*)[], T(*)[]>::value
|
||||
);
|
||||
/// \concept span_compatible_range
|
||||
/// \brief The \c span_compatible_range concept
|
||||
template<typename Rng, typename T>
|
||||
CPP_concept span_compatible_range =
|
||||
sized_range<Rng> && contiguous_range<Rng> &&
|
||||
CPP_concept_ref(ranges::span_compatible_range_, Rng, T);
|
||||
|
||||
/// \concept span_dynamic_conversion
|
||||
/// \brief The \c span_dynamic_conversion concept
|
||||
template<typename Rng, detail::span_index_t N>
|
||||
CPP_concept span_dynamic_conversion =
|
||||
N == dynamic_extent ||
|
||||
range_cardinality<Rng>::value < cardinality();
|
||||
|
||||
/// \concept span_static_conversion
|
||||
/// \brief The \c span_static_conversion concept
|
||||
template<typename Rng, detail::span_index_t N>
|
||||
CPP_concept span_static_conversion =
|
||||
N != dynamic_extent && range_cardinality<Rng>::value == N;
|
||||
// clang-format on
|
||||
/// \endcond
|
||||
|
||||
template<typename T, detail::span_index_t N = dynamic_extent>
|
||||
struct RANGES_EMPTY_BASES span
|
||||
: public view_interface<
|
||||
span<T, N>, (N == dynamic_extent ? finite : static_cast<cardinality>(N))>
|
||||
, public detail::span_extent<N>
|
||||
{
|
||||
CPP_assert(std::is_object<T>::value);
|
||||
|
||||
using element_type = T;
|
||||
using value_type = meta::_t<std::remove_cv<T>>;
|
||||
using index_type = detail::span_index_t;
|
||||
using difference_type = index_type;
|
||||
using pointer = T *;
|
||||
using reference = T &;
|
||||
using iterator = T *;
|
||||
using reverse_iterator = ranges::reverse_iterator<iterator>;
|
||||
|
||||
static constexpr index_type extent = N;
|
||||
|
||||
constexpr span() noexcept = default;
|
||||
constexpr span(pointer ptr, index_type cnt) noexcept
|
||||
: detail::span_extent<N>{(RANGES_EXPECT(cnt >= 0), cnt)}
|
||||
, data_{(RANGES_EXPECT(0 == cnt || ptr != nullptr), ptr)}
|
||||
{}
|
||||
template<typename = void> // Artificially templatize so that the other
|
||||
// constructor is preferred for {ptr, 0}
|
||||
constexpr span(pointer first, pointer last) noexcept
|
||||
: span{first, last - first}
|
||||
{}
|
||||
|
||||
template(typename Rng)(
|
||||
requires (!same_as<span, uncvref_t<Rng>>) AND
|
||||
span_compatible_range<Rng, T> AND
|
||||
span_dynamic_conversion<Rng, N>)
|
||||
constexpr span(Rng && rng) noexcept(noexcept(ranges::data(rng),
|
||||
ranges::size(rng)))
|
||||
: span{ranges::data(rng), detail::narrow_cast<index_type>(ranges::size(rng))}
|
||||
{}
|
||||
|
||||
template(typename Rng)(
|
||||
requires (!same_as<span, uncvref_t<Rng>>) AND
|
||||
span_compatible_range<Rng, T> AND
|
||||
span_static_conversion<Rng, N>)
|
||||
constexpr span(Rng && rng) noexcept(noexcept(ranges::data(rng)))
|
||||
: span{ranges::data(rng), N}
|
||||
{}
|
||||
|
||||
template<index_type Count>
|
||||
constexpr span<T, Count> first() const noexcept
|
||||
{
|
||||
static_assert(Count >= 0, "Count of elements to extract cannot be negative.");
|
||||
static_assert(
|
||||
N == dynamic_extent || Count <= N,
|
||||
"Count of elements to extract must be less than the static span extent.");
|
||||
return RANGES_EXPECT(Count <= size()),
|
||||
RANGES_EXPECT(Count == 0 || data_ != nullptr),
|
||||
span<T, Count>{data_, Count};
|
||||
}
|
||||
constexpr span<T> first(index_type cnt) const noexcept
|
||||
{
|
||||
return RANGES_EXPECT(cnt >= 0 && cnt <= size()),
|
||||
RANGES_EXPECT(cnt == 0 || data_ != nullptr), span<T>{data_, cnt};
|
||||
}
|
||||
|
||||
template<index_type Count>
|
||||
constexpr span<T, Count> last() const noexcept
|
||||
{
|
||||
static_assert(Count >= 0, "Count of elements to extract cannot be negative.");
|
||||
static_assert(
|
||||
N == dynamic_extent || Count <= N,
|
||||
"Count of elements to extract must be less than the static span extent.");
|
||||
return RANGES_EXPECT(Count <= size()),
|
||||
RANGES_EXPECT((Count == 0 && size() == 0) || data_ != nullptr),
|
||||
span<T, Count>{data_ + size() - Count, Count};
|
||||
}
|
||||
constexpr span<T> last(index_type cnt) const noexcept
|
||||
{
|
||||
return RANGES_EXPECT(cnt >= 0 && cnt <= size()),
|
||||
RANGES_EXPECT((cnt == 0 && size() == 0) || data_ != nullptr),
|
||||
span<T>{data_ + size() - cnt, cnt};
|
||||
}
|
||||
|
||||
template<index_type Offset, index_type Count>
|
||||
constexpr span<T, detail::subspan_extent(N, Offset, Count)> subspan() const
|
||||
noexcept
|
||||
{
|
||||
static_assert(Offset >= 0,
|
||||
"Offset of first element to extract cannot be negative.");
|
||||
static_assert(Count >= dynamic_extent,
|
||||
"Count of elements to extract cannot be negative.");
|
||||
static_assert(
|
||||
N == dynamic_extent ||
|
||||
N >= Offset + (Count == dynamic_extent ? 0 : Count),
|
||||
"Sequence of elements to extract must be within the static span extent.");
|
||||
return RANGES_EXPECT(size() >=
|
||||
Offset + (Count == dynamic_extent ? 0 : Count)),
|
||||
RANGES_EXPECT((Offset == 0 && Count <= 0) || data_ != nullptr),
|
||||
span<T, detail::subspan_extent(N, Offset, Count)>{
|
||||
data_ + Offset, Count == dynamic_extent ? size() - Offset : Count};
|
||||
}
|
||||
template<index_type Offset>
|
||||
constexpr span<T, (N >= Offset ? N - Offset : dynamic_extent)> subspan() const
|
||||
noexcept
|
||||
{
|
||||
static_assert(Offset >= 0,
|
||||
"Offset of first element to extract cannot be negative.");
|
||||
static_assert(N == dynamic_extent || N >= Offset,
|
||||
"Offset of first element to extract must be within the static "
|
||||
"span extent.");
|
||||
return RANGES_EXPECT(size() >= Offset),
|
||||
RANGES_EXPECT((Offset == 0 && size() == 0) || data_ != nullptr),
|
||||
span < T,
|
||||
N >= Offset ? N - Offset
|
||||
: dynamic_extent > {data_ + Offset, size() - Offset};
|
||||
}
|
||||
constexpr span<T, dynamic_extent> subspan(index_type offset) const noexcept
|
||||
{
|
||||
return RANGES_EXPECT(offset >= 0), RANGES_EXPECT(size() >= offset),
|
||||
RANGES_EXPECT((offset == 0 && size() == 0) || data_ != nullptr),
|
||||
span<T, dynamic_extent>{data_ + offset, size() - offset};
|
||||
}
|
||||
constexpr span<T, dynamic_extent> subspan(index_type offset, index_type cnt) const
|
||||
noexcept
|
||||
{
|
||||
return RANGES_EXPECT(offset >= 0), RANGES_EXPECT(cnt >= 0),
|
||||
RANGES_EXPECT(size() >= offset + cnt),
|
||||
RANGES_EXPECT((offset == 0 && cnt == 0) || data_ != nullptr),
|
||||
span<T, dynamic_extent>{data_ + offset, cnt};
|
||||
}
|
||||
|
||||
constexpr pointer data() const noexcept
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
using detail::span_extent<N>::size;
|
||||
constexpr index_type size_bytes() const noexcept
|
||||
{
|
||||
return detail::byte_size<T>(size());
|
||||
}
|
||||
constexpr bool empty() const noexcept
|
||||
{
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
constexpr reference operator[](index_type idx) const noexcept
|
||||
{
|
||||
return RANGES_EXPECT(idx >= 0), RANGES_EXPECT(idx < size()),
|
||||
RANGES_EXPECT(data_), data_[idx];
|
||||
}
|
||||
|
||||
constexpr iterator begin() const noexcept
|
||||
{
|
||||
return RANGES_EXPECT(!size() || data_), data_;
|
||||
}
|
||||
constexpr iterator end() const noexcept
|
||||
{
|
||||
return RANGES_EXPECT(!size() || data_), data_ + size();
|
||||
}
|
||||
constexpr reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return reverse_iterator{end()};
|
||||
}
|
||||
constexpr reverse_iterator rend() const noexcept
|
||||
{
|
||||
return reverse_iterator{begin()};
|
||||
}
|
||||
|
||||
template(typename U, index_type M)(
|
||||
requires equality_comparable_with<T, U>)
|
||||
bool operator==(span<U, M> const & that) const
|
||||
{
|
||||
RANGES_EXPECT(!size() || data());
|
||||
RANGES_EXPECT(!that.size() || that.data());
|
||||
return ranges::equal(*this, that);
|
||||
}
|
||||
template(typename U, index_type M)(
|
||||
requires equality_comparable_with<T, U>)
|
||||
bool operator!=(span<U, M> const & that) const
|
||||
{
|
||||
return !(*this == that);
|
||||
}
|
||||
|
||||
template(typename U, index_type M)(
|
||||
requires totally_ordered_with<T, U>)
|
||||
bool operator<(span<U, M> const & that) const
|
||||
{
|
||||
RANGES_EXPECT(!size() || data());
|
||||
RANGES_EXPECT(!that.size() || that.data());
|
||||
return ranges::lexicographical_compare(*this, that);
|
||||
}
|
||||
template(typename U, index_type M)(
|
||||
requires totally_ordered_with<T, U>)
|
||||
bool operator>(span<U, M> const & that) const
|
||||
{
|
||||
return that < *this;
|
||||
}
|
||||
template(typename U, index_type M)(
|
||||
requires totally_ordered_with<T, U>)
|
||||
bool operator<=(span<U, M> const & that) const
|
||||
{
|
||||
return !(that < *this);
|
||||
}
|
||||
template(typename U, index_type M)(
|
||||
requires totally_ordered_with<T, U>)
|
||||
bool operator>=(span<U, M> const & that) const
|
||||
{
|
||||
return !(*this < that);
|
||||
}
|
||||
|
||||
private:
|
||||
T * data_ = nullptr;
|
||||
};
|
||||
|
||||
template<typename T, detail::span_index_t N>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<span<T, N>> = true;
|
||||
|
||||
template<typename T, detail::span_index_t N>
|
||||
constexpr detail::span_index_t span<T, N>::extent;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng)(
|
||||
requires contiguous_range<Rng>)
|
||||
span(Rng && rng)
|
||||
->span<detail::element_t<Rng>, (range_cardinality<Rng>::value < cardinality()
|
||||
? dynamic_extent
|
||||
: static_cast<detail::span_index_t>(
|
||||
range_cardinality<Rng>::value))>;
|
||||
#endif
|
||||
|
||||
template<typename T, detail::span_index_t N>
|
||||
span<unsigned char const, detail::byte_size<T>(N)> as_bytes(span<T, N> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<unsigned char const *>(s.data()), s.size_bytes()};
|
||||
}
|
||||
template<typename T, detail::span_index_t N>
|
||||
span<unsigned char, detail::byte_size<T>(N)> as_writeable_bytes(span<T, N> s) noexcept
|
||||
{
|
||||
return {reinterpret_cast<unsigned char *>(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
template<typename ElementType>
|
||||
constexpr span<ElementType> make_span(ElementType * ptr,
|
||||
detail::span_index_t cnt) noexcept
|
||||
{
|
||||
return span<ElementType>{ptr, cnt};
|
||||
}
|
||||
template<typename ElementType>
|
||||
constexpr span<ElementType> make_span(ElementType * first,
|
||||
ElementType * last) noexcept
|
||||
{
|
||||
return span<ElementType>{first, last};
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires contiguous_range<Rng> AND
|
||||
(range_cardinality<Rng>::value < cardinality())) //
|
||||
constexpr span<detail::element_t<Rng>> make_span(Rng && rng) noexcept(
|
||||
noexcept(ranges::data(rng), ranges::size(rng)))
|
||||
{
|
||||
return {ranges::data(rng),
|
||||
detail::narrow_cast<detail::span_index_t>(ranges::size(rng))};
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires contiguous_range<Rng> AND
|
||||
(range_cardinality<Rng>::value >= cardinality())) //
|
||||
constexpr span<
|
||||
detail::element_t<Rng>,
|
||||
static_cast<detail::span_index_t>(
|
||||
range_cardinality<Rng>::
|
||||
value)> make_span(Rng && rng) noexcept(noexcept(ranges::data(rng)))
|
||||
{
|
||||
return {ranges::data(rng), range_cardinality<Rng>::value};
|
||||
}
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_VIEW_SPAN_HPP
|
||||
706
Telegram/ThirdParty/range-v3/include/range/v3/view/split.hpp
vendored
Normal file
706
Telegram/ThirdParty/range-v3/include/range/v3/view/split.hpp
vendored
Normal file
@@ -0,0 +1,706 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_SPLIT_HPP
|
||||
#define RANGES_V3_VIEW_SPLIT_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/mismatch.hpp>
|
||||
#include <range/v3/functional/bind_back.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/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/single.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// clang-format off
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && \
|
||||
RANGES_CXX_VER <= RANGES_CXX_STD_17
|
||||
template<typename R, std::size_t Sz = static_cast<std::size_t>(R::size())>
|
||||
constexpr bool _is_tiny_range_(R const *) noexcept
|
||||
{
|
||||
return R::size() <= 1u;
|
||||
}
|
||||
constexpr bool _is_tiny_range_(void const*) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/// \concept tiny_range
|
||||
/// \brief The \c tiny_range concept
|
||||
template<typename R>
|
||||
CPP_concept tiny_range =
|
||||
sized_range<R> &&
|
||||
detail::_is_tiny_range_(static_cast<std::add_pointer_t<R>>(nullptr));
|
||||
#else // ^^^^ workaround / no workaround vvvv
|
||||
/// \concept tiny_range_
|
||||
/// \brief The \c tiny_range_ concept
|
||||
template(typename R)(
|
||||
concept (tiny_range_)(R),
|
||||
ranges::type<
|
||||
std::integral_constant<decltype(R::size()), R::size()>> AND
|
||||
(R::size() <= 1)
|
||||
);
|
||||
/// \concept tiny_range
|
||||
/// \brief The \c tiny_range concept
|
||||
template<typename R>
|
||||
CPP_concept tiny_range =
|
||||
sized_range<R> &&
|
||||
CPP_concept_ref(detail::tiny_range_, std::remove_reference_t<R>);
|
||||
#endif
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
|
||||
template<typename V, typename Pattern>
|
||||
#if CPP_CXX_CONCEPTS
|
||||
requires input_range<V> && forward_range<Pattern> && view_<V> && view_<
|
||||
Pattern> && indirectly_comparable<iterator_t<V>, iterator_t<Pattern>,
|
||||
ranges::equal_to> &&
|
||||
(forward_range<V> || detail::tiny_range<Pattern>)
|
||||
#endif
|
||||
struct split_view;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct there
|
||||
{
|
||||
template<typename T>
|
||||
static decltype(auto) current_(T & t) noexcept
|
||||
{
|
||||
return (t.curr_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename It>
|
||||
struct here
|
||||
{
|
||||
It curr_ = It();
|
||||
It & current_(ignore_t) noexcept
|
||||
{
|
||||
return curr_;
|
||||
}
|
||||
It const & current_(ignore_t) const noexcept
|
||||
{
|
||||
return curr_;
|
||||
}
|
||||
};
|
||||
|
||||
template<bool>
|
||||
struct here_or_there_
|
||||
{
|
||||
template<typename>
|
||||
using invoke = there;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct here_or_there_<true>
|
||||
{
|
||||
template<typename It>
|
||||
using invoke = here<It>;
|
||||
};
|
||||
|
||||
template<typename It>
|
||||
using split_view_base = meta::invoke<here_or_there_<!forward_iterator<It>>, It>;
|
||||
|
||||
template<typename JoinView, bool Const>
|
||||
struct split_outer_iterator;
|
||||
|
||||
template<typename JoinView, bool Const>
|
||||
struct split_inner_iterator;
|
||||
|
||||
template<typename V, typename Pattern, bool Const>
|
||||
struct split_inner_iterator<split_view<V, Pattern>, Const>
|
||||
{
|
||||
private:
|
||||
using Outer = split_outer_iterator<split_view<V, Pattern>, Const>;
|
||||
using Base = meta::const_if_c<Const, V>;
|
||||
using BaseIterCategory =
|
||||
typename std::iterator_traits<iterator_t<Base>>::iterator_category;
|
||||
Outer i_ = Outer();
|
||||
bool incremented_ = false;
|
||||
constexpr decltype(auto) current_() noexcept
|
||||
{
|
||||
return i_.current_();
|
||||
}
|
||||
constexpr decltype(auto) current_() const noexcept
|
||||
{
|
||||
return i_.current_();
|
||||
}
|
||||
constexpr bool done_() const
|
||||
{
|
||||
auto cur = current_();
|
||||
auto last = ranges::end(i_.parent_->base_);
|
||||
if(cur == last)
|
||||
return true;
|
||||
auto pcur = ranges::begin(i_.parent_->pattern_);
|
||||
auto pend = ranges::end(i_.parent_->pattern_);
|
||||
if(pcur == pend)
|
||||
return incremented_;
|
||||
do
|
||||
{
|
||||
if(*cur != *pcur)
|
||||
return false;
|
||||
if(++pcur == pend)
|
||||
return true;
|
||||
} while(++cur != last);
|
||||
return false;
|
||||
}
|
||||
#if RANGES_CXX_IF_CONSTEXPR < RANGES_CXX_IF_CONSTEXPR_17
|
||||
constexpr void pre_inc(std::true_type) // Forward
|
||||
{
|
||||
++current_();
|
||||
}
|
||||
constexpr void pre_inc(std::false_type) // Input
|
||||
{
|
||||
if(Pattern::size() != 0)
|
||||
++current_();
|
||||
}
|
||||
constexpr split_inner_iterator post_inc(std::true_type) // Forward
|
||||
{
|
||||
auto tmp = *this;
|
||||
pre_inc(std::true_type{});
|
||||
return tmp;
|
||||
}
|
||||
constexpr void post_inc(std::false_type) // Input
|
||||
{
|
||||
pre_inc(std::false_type{});
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
using iterator_concept = typename Outer::iterator_concept;
|
||||
using iterator_category =
|
||||
meta::conditional_t<
|
||||
derived_from<BaseIterCategory, std::forward_iterator_tag>,
|
||||
std::forward_iterator_tag,
|
||||
std::input_iterator_tag>;
|
||||
using value_type = range_value_t<Base>;
|
||||
using difference_type = range_difference_t<Base>;
|
||||
using reference = range_reference_t<Base>; // Not to spec
|
||||
using pointer = iter_pointer_t<iterator_t<Base>>; // Not to spec
|
||||
|
||||
split_inner_iterator() = default;
|
||||
|
||||
constexpr explicit split_inner_iterator(Outer i)
|
||||
: i_(std::move(i))
|
||||
{}
|
||||
|
||||
constexpr decltype(auto) operator*() const
|
||||
{
|
||||
return *current_();
|
||||
}
|
||||
|
||||
constexpr split_inner_iterator & operator++()
|
||||
{
|
||||
incremented_ = true;
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(!forward_range<Base>)
|
||||
if constexpr(Pattern::size() == 0)
|
||||
return *this;
|
||||
++current_();
|
||||
#else
|
||||
pre_inc(meta::bool_<forward_range<Base>>{});
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr decltype(auto) operator++(int)
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(forward_range<V>)
|
||||
{
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
++*this;
|
||||
#else
|
||||
return post_inc(meta::bool_<forward_range<V>>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
CPP_broken_friend_member
|
||||
friend constexpr auto operator==(split_inner_iterator const & x,
|
||||
split_inner_iterator const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires forward_range<Base>)
|
||||
{
|
||||
return x.i_.curr_ == y.i_.curr_;
|
||||
}
|
||||
CPP_broken_friend_member
|
||||
friend constexpr auto operator!=(split_inner_iterator const & x,
|
||||
split_inner_iterator const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires forward_range<Base>)
|
||||
{
|
||||
return x.i_.curr_ != y.i_.curr_;
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator==(split_inner_iterator const & x,
|
||||
default_sentinel_t)
|
||||
{
|
||||
return x.done_();
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator==(default_sentinel_t,
|
||||
split_inner_iterator const & x)
|
||||
{
|
||||
return x.done_();
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator!=(split_inner_iterator const & x,
|
||||
default_sentinel_t)
|
||||
{
|
||||
return !x.done_();
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator!=(default_sentinel_t,
|
||||
split_inner_iterator const & x)
|
||||
{
|
||||
return !x.done_();
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr decltype(auto) iter_move(
|
||||
split_inner_iterator const &
|
||||
i) noexcept(noexcept(ranges::iter_move(i.current_())))
|
||||
{
|
||||
return ranges::iter_move(i.current_());
|
||||
}
|
||||
CPP_broken_friend_member
|
||||
friend constexpr auto iter_swap(
|
||||
split_inner_iterator const & x,
|
||||
split_inner_iterator const &
|
||||
y) noexcept(noexcept(ranges::iter_swap(x.current_(), y.current_())))
|
||||
-> CPP_broken_friend_ret(void)(
|
||||
requires indirectly_swappable<iterator_t<Base>>)
|
||||
{
|
||||
ranges::iter_swap(x.current_(), y.current_());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename It>
|
||||
using split_outer_iterator_base =
|
||||
meta::invoke<here_or_there_<forward_iterator<It>>, It>;
|
||||
|
||||
template<typename JoinView, bool Const>
|
||||
struct split_outer_iterator;
|
||||
|
||||
template<typename V, typename Pattern, bool Const>
|
||||
struct split_outer_iterator<split_view<V, Pattern>, Const>
|
||||
: split_outer_iterator_base<iterator_t<meta::const_if_c<Const, V>>>
|
||||
{
|
||||
private:
|
||||
friend struct split_inner_iterator<split_view<V, Pattern>, Const>;
|
||||
using Parent = meta::const_if_c<Const, split_view<V, Pattern>>;
|
||||
using Base = meta::const_if_c<Const, V>;
|
||||
using Current = split_outer_iterator_base<iterator_t<Base>>;
|
||||
|
||||
Parent * parent_ = nullptr;
|
||||
constexpr decltype(auto) current_() noexcept
|
||||
{
|
||||
return parent_->current_(*this);
|
||||
}
|
||||
constexpr decltype(auto) current_() const noexcept
|
||||
{
|
||||
return parent_->current_(*this);
|
||||
}
|
||||
constexpr decltype(auto) base_() const noexcept
|
||||
{
|
||||
return (parent_->base_);
|
||||
}
|
||||
#if RANGES_CXX_IF_CONSTEXPR < RANGES_CXX_IF_CONSTEXPR_17
|
||||
constexpr split_outer_iterator post_inc(std::true_type) // Forward
|
||||
{
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
constexpr void post_inc(std::false_type) // Input
|
||||
{
|
||||
++*this;
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
using iterator_concept =
|
||||
meta::conditional_t<forward_range<Base>, std::forward_iterator_tag,
|
||||
std::input_iterator_tag>;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
struct value_type : view_interface<value_type>
|
||||
{
|
||||
private:
|
||||
split_outer_iterator i_ = split_outer_iterator();
|
||||
|
||||
public:
|
||||
value_type() = default;
|
||||
constexpr explicit value_type(split_outer_iterator i)
|
||||
: i_(std::move(i))
|
||||
{}
|
||||
constexpr split_inner_iterator<split_view<V, Pattern>, Const> begin()
|
||||
const
|
||||
{
|
||||
return split_inner_iterator<split_view<V, Pattern>, Const>(i_);
|
||||
}
|
||||
constexpr default_sentinel_t end() const
|
||||
{
|
||||
return default_sentinel;
|
||||
}
|
||||
};
|
||||
using difference_type = range_difference_t<Base>;
|
||||
using reference = value_type; // Not to spec
|
||||
using pointer = value_type *; // Not to spec
|
||||
|
||||
split_outer_iterator() = default;
|
||||
|
||||
CPP_member
|
||||
constexpr explicit CPP_ctor(split_outer_iterator)(Parent * parent)(
|
||||
requires (!forward_range<Base>))
|
||||
: parent_(parent)
|
||||
{}
|
||||
|
||||
CPP_member
|
||||
constexpr CPP_ctor(split_outer_iterator)(Parent * parent,
|
||||
iterator_t<Base> current)(
|
||||
requires forward_range<Base>)
|
||||
: Current{std::move(current)}
|
||||
, parent_(parent)
|
||||
{}
|
||||
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other) AND
|
||||
convertible_to<iterator_t<V>, iterator_t<Base>>)
|
||||
constexpr split_outer_iterator(
|
||||
split_outer_iterator<split_view<V, Pattern>, Other> i)
|
||||
: Current{std::move(i.curr_)}
|
||||
, parent_(i.parent_)
|
||||
{}
|
||||
|
||||
constexpr value_type operator*() const
|
||||
{
|
||||
return value_type{*this};
|
||||
}
|
||||
|
||||
constexpr split_outer_iterator & operator++()
|
||||
{
|
||||
auto & current = current_();
|
||||
const auto last = ranges::end(base_());
|
||||
if(current == last)
|
||||
return *this;
|
||||
auto const pbegin = ranges::begin(parent_->pattern_);
|
||||
auto const pend = ranges::end(parent_->pattern_);
|
||||
if(pbegin == pend)
|
||||
++current;
|
||||
else
|
||||
do
|
||||
{
|
||||
const auto ret = ranges::mismatch(current, last, pbegin, pend);
|
||||
if(ret.in2 == pend)
|
||||
{
|
||||
current = ret.in1; // The pattern matched; skip it
|
||||
break;
|
||||
}
|
||||
} while(++current != last);
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr decltype(auto) operator++(int)
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(forward_range<Base>)
|
||||
{
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
++*this;
|
||||
#else
|
||||
return post_inc(meta::bool_<forward_range<Base>>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
CPP_broken_friend_member
|
||||
friend constexpr auto operator==(split_outer_iterator const & x,
|
||||
split_outer_iterator const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires forward_range<Base>)
|
||||
{
|
||||
return x.curr_ == y.curr_;
|
||||
}
|
||||
CPP_broken_friend_member
|
||||
friend constexpr auto operator!=(split_outer_iterator const & x,
|
||||
split_outer_iterator const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires forward_range<Base>)
|
||||
{
|
||||
return x.curr_ != y.curr_;
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator==(split_outer_iterator const & x,
|
||||
default_sentinel_t)
|
||||
{
|
||||
return x.current_() == ranges::end(x.base_());
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator==(default_sentinel_t,
|
||||
split_outer_iterator const & x)
|
||||
{
|
||||
return x.current_() == ranges::end(x.base_());
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator!=(split_outer_iterator const & x,
|
||||
default_sentinel_t)
|
||||
{
|
||||
return x.current_() != ranges::end(x.base_());
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator!=(default_sentinel_t,
|
||||
split_outer_iterator const & x)
|
||||
{
|
||||
return x.current_() != ranges::end(x.base_());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename V, typename Pattern>
|
||||
#if CPP_CXX_CONCEPTS
|
||||
requires input_range<V> && forward_range<Pattern> && view_<V> && view_<
|
||||
Pattern> && indirectly_comparable<iterator_t<V>, iterator_t<Pattern>,
|
||||
ranges::equal_to> &&
|
||||
(forward_range<V> || detail::tiny_range<Pattern>)
|
||||
#endif
|
||||
struct RANGES_EMPTY_BASES split_view
|
||||
: view_interface<split_view<V, Pattern>, is_finite<V>::value ? finite : unknown>
|
||||
, private detail::split_view_base<iterator_t<V>>
|
||||
{
|
||||
private:
|
||||
template<typename, bool>
|
||||
friend struct detail::split_outer_iterator;
|
||||
template<typename, bool>
|
||||
friend struct detail::split_inner_iterator;
|
||||
|
||||
V base_ = V();
|
||||
Pattern pattern_ = Pattern();
|
||||
template<bool Const>
|
||||
using outer_iterator = detail::split_outer_iterator<split_view, Const>;
|
||||
|
||||
#if RANGES_CXX_IF_CONSTEXPR < RANGES_CXX_IF_CONSTEXPR_17
|
||||
outer_iterator<simple_view<V>()> begin_(std::true_type)
|
||||
{
|
||||
return outer_iterator<simple_view<V>()>{this, ranges::begin(base_)};
|
||||
}
|
||||
outer_iterator<false> begin_(std::false_type)
|
||||
{
|
||||
this->curr_ = ranges::begin(base_);
|
||||
return outer_iterator<false>{this};
|
||||
}
|
||||
|
||||
outer_iterator<simple_view<V>()> end_(std::true_type) const
|
||||
{
|
||||
return outer_iterator<true>{this, ranges::end(base_)};
|
||||
}
|
||||
default_sentinel_t end_(std::false_type) const
|
||||
{
|
||||
return default_sentinel;
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
split_view() = default;
|
||||
|
||||
constexpr split_view(V base, Pattern pattern)
|
||||
: base_((V &&) base)
|
||||
, pattern_((Pattern &&) pattern)
|
||||
{}
|
||||
|
||||
CPP_member
|
||||
constexpr CPP_ctor(split_view)(V base, range_value_t<V> e)(
|
||||
requires constructible_from<Pattern, range_value_t<V>>)
|
||||
: base_(std::move(base))
|
||||
, pattern_(e)
|
||||
{}
|
||||
|
||||
constexpr V base() const
|
||||
{
|
||||
return base_;
|
||||
}
|
||||
|
||||
constexpr outer_iterator<forward_range<V> && simple_view<V>()> begin()
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(forward_range<V>)
|
||||
return outer_iterator<simple_view<V>()>{this, ranges::begin(base_)};
|
||||
else
|
||||
{
|
||||
this->curr_ = ranges::begin(base_);
|
||||
return outer_iterator<false>{this};
|
||||
}
|
||||
#else
|
||||
return begin_(meta::bool_<forward_range<V>>{});
|
||||
#endif
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto begin() const //
|
||||
-> CPP_ret(outer_iterator<true>)(
|
||||
requires forward_range<V> && forward_range<const V>)
|
||||
{
|
||||
return {this, ranges::begin(base_)};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end() //
|
||||
-> CPP_ret(outer_iterator<simple_view<V>()>)(
|
||||
requires forward_range<V> && common_range<V>)
|
||||
{
|
||||
return outer_iterator<simple_view<V>()>{this, ranges::end(base_)};
|
||||
}
|
||||
constexpr auto end() const
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(forward_range<V> && forward_range<const V> &&
|
||||
common_range<const V>)
|
||||
return outer_iterator<true>{this, ranges::end(base_)};
|
||||
else
|
||||
return default_sentinel;
|
||||
#else
|
||||
return end_(meta::bool_ < forward_range<V> && forward_range<const V> &&
|
||||
common_range<const V> > {});
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename R, typename P)(
|
||||
requires input_range<R> AND forward_range<P> AND viewable_range<R> AND
|
||||
viewable_range<P> AND
|
||||
indirectly_comparable<iterator_t<R>, iterator_t<P>, ranges::equal_to> AND
|
||||
(forward_range<R> || detail::tiny_range<P>)) //
|
||||
split_view(R &&, P &&)
|
||||
->split_view<views::all_t<R>, views::all_t<P>>;
|
||||
|
||||
template(typename R)(
|
||||
requires input_range<R>)
|
||||
split_view(R &&, range_value_t<R>)
|
||||
->split_view<views::all_t<R>, single_view<range_value_t<R>>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct split_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirectly_comparable<iterator_t<Rng>,
|
||||
range_value_t<Rng> const *,
|
||||
ranges::equal_to>)
|
||||
constexpr split_view<all_t<Rng>, single_view<range_value_t<Rng>>> //
|
||||
operator()(Rng && rng, range_value_t<Rng> val) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), single(std::move(val))};
|
||||
}
|
||||
|
||||
template(typename Rng, typename Pattern)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
viewable_range<Pattern> AND forward_range<Pattern> AND
|
||||
indirectly_comparable<
|
||||
iterator_t<Rng>,
|
||||
iterator_t<Pattern>,
|
||||
ranges::equal_to> AND
|
||||
(forward_range<Rng> || detail::tiny_range<Pattern>)) //
|
||||
constexpr split_view<all_t<Rng>, all_t<Pattern>> //
|
||||
operator()(Rng && rng, Pattern && pattern) const
|
||||
{
|
||||
return {all((Rng &&) rng), all((Pattern &&) pattern)};
|
||||
}
|
||||
};
|
||||
|
||||
struct split_fn : split_base_fn
|
||||
{
|
||||
using split_base_fn::operator();
|
||||
|
||||
template<typename T>
|
||||
constexpr auto operator()(T t) const
|
||||
{
|
||||
return make_view_closure(bind_back(split_base_fn{}, std::move(t)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates split_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(split_fn, split)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::split;
|
||||
}
|
||||
template(typename Rng, typename Pattern)(
|
||||
requires input_range<Rng> AND forward_range<Pattern> AND view_<Rng> AND
|
||||
view_<Pattern> AND
|
||||
indirectly_comparable<
|
||||
iterator_t<Rng>,
|
||||
iterator_t<Pattern>,
|
||||
ranges::equal_to> AND
|
||||
(forward_range<Rng> || ranges::detail::tiny_range<Pattern>)) //
|
||||
using split_view =
|
||||
ranges::split_view<Rng, Pattern>;
|
||||
} // namespace cpp20
|
||||
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::split_view)
|
||||
|
||||
#endif
|
||||
230
Telegram/ThirdParty/range-v3/include/range/v3/view/split_when.hpp
vendored
Normal file
230
Telegram/ThirdParty/range-v3/include/range/v3/view/split_when.hpp
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_SPLIT_WHEN_HPP
|
||||
#define RANGES_V3_VIEW_SPLIT_WHEN_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/find_if_not.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
#include <range/v3/view/indirect.hpp>
|
||||
#include <range/v3/view/iota.hpp>
|
||||
#include <range/v3/view/take_while.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
template<typename Rng, typename Fun>
|
||||
struct split_when_view
|
||||
: view_facade<split_when_view<Rng, Fun>,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
Rng rng_;
|
||||
semiregular_box_t<Fun> fun_;
|
||||
|
||||
template<bool IsConst>
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
friend split_when_view;
|
||||
friend struct cursor<!IsConst>;
|
||||
bool zero_;
|
||||
using CRng = meta::const_if_c<IsConst, Rng>;
|
||||
iterator_t<CRng> cur_;
|
||||
sentinel_t<CRng> last_;
|
||||
using fun_ref_t = semiregular_box_ref_or_val_t<Fun, IsConst>;
|
||||
fun_ref_t fun_;
|
||||
|
||||
struct search_pred
|
||||
{
|
||||
bool zero_;
|
||||
iterator_t<CRng> first_;
|
||||
sentinel_t<CRng> last_;
|
||||
fun_ref_t fun_;
|
||||
bool operator()(iterator_t<CRng> cur) const
|
||||
{
|
||||
return (zero_ && cur == first_) ||
|
||||
(cur != last_ && !invoke(fun_, cur, last_).first);
|
||||
}
|
||||
};
|
||||
using reference_ =
|
||||
indirect_view<take_while_view<iota_view<iterator_t<CRng>>, search_pred>>;
|
||||
reference_ read() const
|
||||
{
|
||||
return reference_{{views::iota(cur_), {zero_, cur_, last_, fun_}}};
|
||||
}
|
||||
void next()
|
||||
{
|
||||
RANGES_EXPECT(cur_ != last_);
|
||||
// If the last match consumed zero elements, bump the position.
|
||||
if(zero_)
|
||||
{
|
||||
zero_ = false;
|
||||
++cur_;
|
||||
}
|
||||
for(; cur_ != last_; ++cur_)
|
||||
{
|
||||
auto p = invoke(fun_, cur_, last_);
|
||||
if(p.first)
|
||||
{
|
||||
zero_ = (cur_ == p.second);
|
||||
cur_ = p.second;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool equal(default_sentinel_t) const
|
||||
{
|
||||
return cur_ == last_;
|
||||
}
|
||||
bool equal(cursor const & that) const
|
||||
{
|
||||
return cur_ == that.cur_;
|
||||
}
|
||||
cursor(fun_ref_t fun, iterator_t<CRng> first, sentinel_t<CRng> last)
|
||||
: cur_(first)
|
||||
, last_(last)
|
||||
, fun_(fun)
|
||||
{
|
||||
// For skipping an initial zero-length match
|
||||
auto p = invoke(fun, first, last);
|
||||
zero_ = p.first && first == p.second;
|
||||
}
|
||||
|
||||
public:
|
||||
cursor() = default;
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: cursor{std::move(that.cur_), std::move(that.last_), std::move(that.fun_)}
|
||||
{}
|
||||
};
|
||||
cursor<false> begin_cursor()
|
||||
{
|
||||
return {fun_, ranges::begin(rng_), ranges::end(rng_)};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>> AND
|
||||
invocable<Fun const &, iterator_t<meta::const_if_c<Const, Rng>>,
|
||||
sentinel_t<meta::const_if_c<Const, Rng>>>)
|
||||
cursor<Const> begin_cursor() const
|
||||
{
|
||||
return {fun_, ranges::begin(rng_), ranges::end(rng_)};
|
||||
}
|
||||
|
||||
public:
|
||||
split_when_view() = default;
|
||||
split_when_view(Rng rng, Fun fun)
|
||||
: rng_(std::move(rng))
|
||||
, fun_(std::move(fun))
|
||||
{}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Fun>)
|
||||
split_when_view(Rng &&, Fun)
|
||||
-> split_when_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct split_when_base_fn
|
||||
{
|
||||
private:
|
||||
template<typename Pred>
|
||||
struct predicate_pred_
|
||||
{
|
||||
semiregular_box_t<Pred> pred_;
|
||||
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
std::pair<bool, I> operator()(I cur, S last) const
|
||||
{
|
||||
auto where = ranges::find_if_not(cur, last, std::ref(pred_));
|
||||
return {cur != where, where};
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
template(typename Rng, typename Fun)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng> AND
|
||||
invocable<Fun &, iterator_t<Rng>, sentinel_t<Rng>> AND
|
||||
invocable<Fun &, iterator_t<Rng>, iterator_t<Rng>> AND
|
||||
copy_constructible<Fun> AND
|
||||
convertible_to<
|
||||
invoke_result_t<Fun &, iterator_t<Rng>, sentinel_t<Rng>>,
|
||||
std::pair<bool, iterator_t<Rng>>>)
|
||||
split_when_view<all_t<Rng>, Fun> operator()(Rng && rng, Fun fun) const //
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(fun)};
|
||||
}
|
||||
template(typename Rng, typename Fun)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng> AND
|
||||
predicate<Fun const &, range_reference_t<Rng>> AND
|
||||
copy_constructible<Fun>)
|
||||
split_when_view<all_t<Rng>, predicate_pred_<Fun>> //
|
||||
operator()(Rng && rng, Fun fun) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
predicate_pred_<Fun>{std::move(fun)}};
|
||||
}
|
||||
};
|
||||
|
||||
struct split_when_fn : split_when_base_fn
|
||||
{
|
||||
using split_when_base_fn::operator();
|
||||
|
||||
template<typename T>
|
||||
constexpr auto operator()(T && t) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(split_when_base_fn{}, static_cast<T &&>(t)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates split_when_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(split_when_fn, split_when)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::split_when_view)
|
||||
|
||||
#endif
|
||||
341
Telegram/ThirdParty/range-v3/include/range/v3/view/stride.hpp
vendored
Normal file
341
Telegram/ThirdParty/range-v3/include/range/v3/view/stride.hpp
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-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_STRIDE_HPP
|
||||
#define RANGES_V3_VIEW_STRIDE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
template<typename Rng>
|
||||
struct stride_view;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Rng>
|
||||
using stride_view_adaptor =
|
||||
view_adaptor<stride_view<Rng>, Rng,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>;
|
||||
|
||||
// Bidirectional stride views need to remember the distance between
|
||||
// the penultimate iterator and the last iterator - which may be less
|
||||
// than the stride - so that decrementing an last iterator properly
|
||||
// produces the penultimate iterator. stride_view_base specializes on
|
||||
// that distinction so that only Bidirectional stride views have the
|
||||
// data member "offset_".
|
||||
template<typename Rng, bool BidiRange>
|
||||
struct stride_view_base_;
|
||||
template<typename Rng>
|
||||
using stride_view_base = stride_view_base_<Rng, (bool)bidirectional_range<Rng>>;
|
||||
|
||||
template<typename Rng, bool /*= bidirectional_range<Rng>*/>
|
||||
struct stride_view_base_ : stride_view_adaptor<Rng>
|
||||
{
|
||||
stride_view_base_() = default;
|
||||
constexpr stride_view_base_(Rng && rng, range_difference_t<Rng> const stride)
|
||||
: stride_view_adaptor<Rng>{std::move(rng)}
|
||||
, stride_{(RANGES_EXPECT(0 < stride), stride)}
|
||||
, offset_{calc_offset(meta::bool_<sized_range<Rng>>{})}
|
||||
{}
|
||||
|
||||
protected:
|
||||
constexpr void set_offset(range_difference_t<Rng> const delta) noexcept
|
||||
{
|
||||
RANGES_EXPECT(0 <= delta && delta < stride_);
|
||||
if(0 > offset_)
|
||||
offset_ = delta;
|
||||
else
|
||||
RANGES_EXPECT(offset_ == delta);
|
||||
}
|
||||
constexpr void set_offset(range_difference_t<Rng> const) const noexcept
|
||||
{}
|
||||
constexpr range_difference_t<Rng> get_offset(bool check = true) const noexcept
|
||||
{
|
||||
RANGES_EXPECT(!check || 0 <= offset_);
|
||||
return offset_;
|
||||
}
|
||||
|
||||
range_difference_t<Rng> stride_;
|
||||
range_difference_t<Rng> offset_ = -1;
|
||||
|
||||
private:
|
||||
constexpr range_difference_t<Rng> calc_offset(std::true_type)
|
||||
{
|
||||
if(auto const rem = ranges::distance(this->base()) % stride_)
|
||||
return stride_ - rem;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
constexpr range_difference_t<Rng> calc_offset(std::false_type) const noexcept
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct stride_view_base_<Rng, false> : stride_view_adaptor<Rng>
|
||||
{
|
||||
stride_view_base_() = default;
|
||||
constexpr stride_view_base_(Rng && rng, range_difference_t<Rng> const stride)
|
||||
: stride_view_adaptor<Rng>{std::move(rng)}
|
||||
, stride_{(RANGES_EXPECT(0 < stride), stride)}
|
||||
{}
|
||||
|
||||
protected:
|
||||
constexpr void set_offset(range_difference_t<Rng> const) const noexcept
|
||||
{}
|
||||
constexpr range_difference_t<Rng> get_offset(bool = true) const noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
range_difference_t<Rng> stride_;
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct stride_view : detail::stride_view_base<Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
|
||||
// stride_view const models Range if Rng const models Range, and
|
||||
// either (1) Rng is sized, so we can pre-calculate offset_, or (2)
|
||||
// Rng is !Bidirectional, so it does not need offset_.
|
||||
static constexpr bool const_iterable() noexcept
|
||||
{
|
||||
return range<Rng const> &&
|
||||
(sized_range<Rng const> || !bidirectional_range<Rng const>);
|
||||
}
|
||||
|
||||
// If the underlying range doesn't model common_range, then we can't
|
||||
// decrement the last and there's no reason to adapt the sentinel. Strictly
|
||||
// speaking, we don't have to adapt the last iterator of input and forward
|
||||
// ranges, but in the interests of making the resulting stride view model
|
||||
// common_range, adapt it anyway.
|
||||
template<bool Const>
|
||||
static constexpr bool can_bound() noexcept
|
||||
{
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
return common_range<CRng> &&
|
||||
(sized_range<CRng> || !bidirectional_range<CRng>);
|
||||
}
|
||||
|
||||
template<bool Const>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
friend struct adaptor<!Const>;
|
||||
using CRng = meta::const_if_c<Const, Rng>;
|
||||
using stride_view_t = meta::const_if_c<Const, stride_view>;
|
||||
stride_view_t * rng_;
|
||||
|
||||
public:
|
||||
adaptor() = default;
|
||||
constexpr adaptor(stride_view_t * rng) noexcept
|
||||
: rng_(rng)
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
adaptor(adaptor<Other> that)
|
||||
: rng_(that.rng_)
|
||||
{}
|
||||
constexpr void next(iterator_t<CRng> & it)
|
||||
{
|
||||
auto const last = ranges::end(rng_->base());
|
||||
RANGES_EXPECT(it != last);
|
||||
auto const delta = ranges::advance(it, rng_->stride_, last);
|
||||
if(it == last)
|
||||
{
|
||||
rng_->set_offset(delta);
|
||||
}
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto prev(iterator_t<CRng> & it) //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<CRng>)
|
||||
{
|
||||
RANGES_EXPECT(it != ranges::begin(rng_->base()));
|
||||
auto delta = -rng_->stride_;
|
||||
if(it == ranges::end(rng_->base()))
|
||||
{
|
||||
RANGES_EXPECT(rng_->get_offset() >= 0);
|
||||
delta += rng_->get_offset();
|
||||
}
|
||||
ranges::advance(it, delta);
|
||||
}
|
||||
template(typename Other)(
|
||||
requires sized_sentinel_for<Other, iterator_t<CRng>>)
|
||||
constexpr range_difference_t<Rng> distance_to(iterator_t<CRng> const & here,
|
||||
Other const & there) const
|
||||
{
|
||||
range_difference_t<Rng> delta = there - here;
|
||||
if(delta < 0)
|
||||
delta -= rng_->stride_ - 1;
|
||||
else
|
||||
delta += rng_->stride_ - 1;
|
||||
return delta / rng_->stride_;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto advance(iterator_t<CRng> & it, range_difference_t<Rng> n) //
|
||||
-> CPP_ret(void)(
|
||||
requires random_access_range<CRng>)
|
||||
{
|
||||
if(0 == n)
|
||||
return;
|
||||
n *= rng_->stride_;
|
||||
auto const last = ranges::end(rng_->base());
|
||||
if(it == last)
|
||||
{
|
||||
RANGES_EXPECT(n < 0);
|
||||
RANGES_EXPECT(rng_->get_offset() >= 0);
|
||||
n += rng_->get_offset();
|
||||
}
|
||||
if(0 < n)
|
||||
{
|
||||
auto delta = ranges::advance(it, n, last);
|
||||
if(it == last)
|
||||
{
|
||||
// advance hit the last of the base range.
|
||||
rng_->set_offset(delta % rng_->stride_);
|
||||
}
|
||||
}
|
||||
else if(0 > n)
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
ranges::advance(it, n);
|
||||
#else
|
||||
auto const first = ranges::begin(rng_->base());
|
||||
auto const delta = ranges::advance(it, n, first);
|
||||
RANGES_EXPECT(delta == 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
constexpr adaptor<false> begin_adaptor() noexcept
|
||||
{
|
||||
return adaptor<false>{this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto begin_adaptor() const noexcept
|
||||
-> CPP_ret(adaptor<true>)(
|
||||
requires(const_iterable()))
|
||||
{
|
||||
return adaptor<true>{this};
|
||||
}
|
||||
|
||||
constexpr meta::if_c<can_bound<false>(), adaptor<false>, adaptor_base> //
|
||||
end_adaptor() noexcept
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto end_adaptor() const noexcept //
|
||||
-> CPP_ret(meta::if_c<can_bound<true>(), adaptor<true>, adaptor_base>)(
|
||||
requires (const_iterable()))
|
||||
{
|
||||
return {this};
|
||||
}
|
||||
|
||||
public:
|
||||
stride_view() = default;
|
||||
constexpr stride_view(Rng rng, range_difference_t<Rng> const stride)
|
||||
: detail::stride_view_base<Rng>{std::move(rng), stride}
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
using size_type = range_size_t<Rng>;
|
||||
auto const n = ranges::size(this->base());
|
||||
return (n + static_cast<size_type>(this->stride_) - 1) /
|
||||
static_cast<size_type>(this->stride_);
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
using size_type = range_size_t<Rng const>;
|
||||
auto const n = ranges::size(this->base());
|
||||
return (n + static_cast<size_type>(this->stride_) - 1) /
|
||||
static_cast<size_type>(this->stride_);
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
stride_view(Rng &&, range_difference_t<Rng>)
|
||||
-> stride_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct stride_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
constexpr stride_view<all_t<Rng>> //
|
||||
operator()(Rng && rng, range_difference_t<Rng> step) const
|
||||
{
|
||||
return stride_view<all_t<Rng>>{all(static_cast<Rng &&>(rng)), step};
|
||||
}
|
||||
};
|
||||
|
||||
struct stride_fn : stride_base_fn
|
||||
{
|
||||
using stride_base_fn::operator();
|
||||
|
||||
template(typename Difference)(
|
||||
requires detail::integer_like_<Difference>)
|
||||
constexpr auto operator()(Difference step) const
|
||||
{
|
||||
return make_view_closure(bind_back(stride_base_fn{}, step));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates stride_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(stride_fn, stride)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::stride_view)
|
||||
|
||||
#endif
|
||||
485
Telegram/ThirdParty/range-v3/include/range/v3/view/subrange.hpp
vendored
Normal file
485
Telegram/ThirdParty/range-v3/include/range/v3/view/subrange.hpp
vendored
Normal file
@@ -0,0 +1,485 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-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_SUBRANGE_HPP
|
||||
#define RANGES_V3_VIEW_SUBRANGE_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/dangling.hpp>
|
||||
#include <range/v3/utility/get.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
enum class subrange_kind : bool
|
||||
{
|
||||
unsized,
|
||||
sized
|
||||
};
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// clang-format off
|
||||
/// \concept convertible_to_not_slicing_
|
||||
/// \brief The \c convertible_to_not_slicing_ concept
|
||||
template<typename From, typename To>
|
||||
CPP_concept convertible_to_not_slicing_ =
|
||||
convertible_to<From, To> &&
|
||||
// A conversion is a slicing conversion if the source and the destination
|
||||
// are both pointers, and if the pointed-to types differ after removing
|
||||
// cv qualifiers.
|
||||
(!(std::is_pointer<decay_t<From>>::value &&
|
||||
std::is_pointer<decay_t<To>>::value &&
|
||||
not_same_as_<std::remove_pointer_t<decay_t<From>>,
|
||||
std::remove_pointer_t<decay_t<To>>>));
|
||||
|
||||
template<std::size_t N, typename T>
|
||||
using tuple_element_fun_t = void (*)(meta::_t<std::tuple_element<N, T>> const &);
|
||||
|
||||
/// \concept pair_like_impl_
|
||||
/// \brief The \c pair_like_impl_ concept
|
||||
template<typename T>
|
||||
CPP_requires(pair_like_impl_, //
|
||||
requires(T t, tuple_element_fun_t<0, T> p0, tuple_element_fun_t<1, T> p1) //
|
||||
(
|
||||
p0( get<0>(t) ),
|
||||
p1( get<1>(t) )
|
||||
));
|
||||
/// \concept pair_like_impl_
|
||||
/// \brief The \c pair_like_impl_ concept
|
||||
template<typename T>
|
||||
CPP_concept pair_like_impl_ = CPP_requires_ref(detail::pair_like_impl_, T);
|
||||
|
||||
/// \concept is_complete_
|
||||
/// \brief The \c is_complete_ concept
|
||||
template(typename T)(
|
||||
concept (is_complete_)(T),
|
||||
0 != sizeof(T));
|
||||
|
||||
/// \concept is_complete_
|
||||
/// \brief The \c is_complete_ concept
|
||||
template<typename T>
|
||||
CPP_concept is_complete_ = //
|
||||
CPP_concept_ref(is_complete_, T);
|
||||
|
||||
template(typename T)( //
|
||||
concept (pair_like_)(T), //
|
||||
is_complete_<std::tuple_size<T>> AND
|
||||
derived_from<std::tuple_size<T>, meta::size_t<2>> AND
|
||||
detail::pair_like_impl_<T>);
|
||||
|
||||
/// \concept pair_like
|
||||
/// \brief The \c pair_like concept
|
||||
template<typename T>
|
||||
CPP_concept pair_like = //
|
||||
CPP_concept_ref(detail::pair_like_, T);
|
||||
|
||||
// clang-format off
|
||||
template(typename T, typename U, typename V)( //
|
||||
concept (pair_like_convertible_from_helper_)(T, U, V), //
|
||||
convertible_to_not_slicing_<U, meta::_t<std::tuple_element<0, T>>> AND
|
||||
convertible_to<V, meta::_t<std::tuple_element<1, T>>>);
|
||||
|
||||
/// \concept pair_like_convertible_from_helper_
|
||||
/// \brief The \c pair_like_convertible_from_helper_ concept
|
||||
template<typename T, typename U, typename V>
|
||||
CPP_concept pair_like_convertible_from_helper_ = //
|
||||
CPP_concept_ref(pair_like_convertible_from_helper_, T, U, V);
|
||||
|
||||
template(typename T, typename U, typename V)( //
|
||||
concept (pair_like_convertible_from_impl_)(T, U, V),
|
||||
(!range<T>) AND
|
||||
constructible_from<T, U, V> AND
|
||||
pair_like<uncvref_t<T>> AND
|
||||
pair_like_convertible_from_helper_<T, U, V>);
|
||||
|
||||
/// \concept pair_like_convertible_from_
|
||||
/// \brief The \c pair_like_convertible_from_ concept
|
||||
template<typename T, typename U, typename V>
|
||||
CPP_concept pair_like_convertible_from_ =
|
||||
CPP_concept_ref(detail::pair_like_convertible_from_impl_, T, U, V);
|
||||
|
||||
/// \concept range_convertible_to_impl_
|
||||
/// \brief The \c range_convertible_to_impl_ concept
|
||||
template(typename R, typename I, typename S)(
|
||||
concept (range_convertible_to_impl_)(R, I, S),
|
||||
convertible_to_not_slicing_<iterator_t<R>, I> AND
|
||||
convertible_to<sentinel_t<R>, S>);
|
||||
|
||||
/// \concept range_convertible_to_
|
||||
/// \brief The \c range_convertible_to_ concept
|
||||
template<typename R, typename I, typename S>
|
||||
CPP_concept range_convertible_to_ =
|
||||
borrowed_range<R> &&
|
||||
CPP_concept_ref(detail::range_convertible_to_impl_, R, I, S);
|
||||
// clang-format on
|
||||
|
||||
template(typename S, typename I)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr bool is_sized_sentinel_() noexcept
|
||||
{
|
||||
return (bool)sized_sentinel_for<S, I>;
|
||||
}
|
||||
|
||||
template<subrange_kind K, typename S, typename I>
|
||||
constexpr bool store_size_() noexcept
|
||||
{
|
||||
return K == subrange_kind::sized && !(bool)sized_sentinel_for<S, I>;
|
||||
}
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template< //
|
||||
typename I, //
|
||||
typename S = I, //
|
||||
subrange_kind K = static_cast<subrange_kind>(detail::is_sized_sentinel_<S, I>())>
|
||||
struct subrange;
|
||||
|
||||
template<typename I, typename S, subrange_kind K>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<subrange<I, S, K>> = true;
|
||||
|
||||
/// \cond
|
||||
namespace _subrange_
|
||||
{
|
||||
struct adl_hook
|
||||
{};
|
||||
|
||||
template(std::size_t N, typename I, typename S, subrange_kind K)(
|
||||
requires (N == 0)) //
|
||||
constexpr I get(subrange<I, S, K> const & r)
|
||||
{
|
||||
return r.begin();
|
||||
}
|
||||
template(std::size_t N, typename I, typename S, subrange_kind K)(
|
||||
requires (N == 1)) //
|
||||
constexpr S get(subrange<I, S, K> const & r)
|
||||
{
|
||||
return r.end();
|
||||
}
|
||||
} // namespace _subrange_
|
||||
/// \endcond
|
||||
|
||||
template<typename I, typename S, subrange_kind K>
|
||||
struct subrange
|
||||
: view_interface<subrange<I, S, K>,
|
||||
same_as<S, unreachable_sentinel_t>
|
||||
? infinite
|
||||
: K == subrange_kind::sized ? finite : unknown>
|
||||
, private _subrange_::adl_hook
|
||||
{
|
||||
CPP_assert(input_or_output_iterator<I>);
|
||||
CPP_assert(sentinel_for<S, I>);
|
||||
CPP_assert(K == subrange_kind::sized || !sized_sentinel_for<S, I>);
|
||||
CPP_assert(K != subrange_kind::sized || !same_as<S, unreachable_sentinel_t>);
|
||||
|
||||
using size_type = detail::iter_size_t<I>;
|
||||
using iterator = I;
|
||||
using sentinel = S;
|
||||
|
||||
subrange() = default;
|
||||
|
||||
template(typename I2)(
|
||||
requires detail::convertible_to_not_slicing_<I2, I> AND
|
||||
(!detail::store_size_<K, S, I>())) //
|
||||
constexpr subrange(I2 && i, S s)
|
||||
: data_{static_cast<I2 &&>(i), std::move(s)}
|
||||
{}
|
||||
|
||||
template(typename I2)(
|
||||
requires detail::convertible_to_not_slicing_<I2, I> AND
|
||||
(detail::store_size_<K, S, I>())) //
|
||||
constexpr subrange(I2 && i, S s, size_type n)
|
||||
: data_{static_cast<I2 &&>(i), std::move(s), n}
|
||||
{
|
||||
if(RANGES_CONSTEXPR_IF((bool)random_access_iterator<I>))
|
||||
{
|
||||
using D = iter_difference_t<I>;
|
||||
RANGES_EXPECT(n <= (size_type)std::numeric_limits<D>::max());
|
||||
RANGES_EXPECT(ranges::next(first_(), (D)n) == last_());
|
||||
}
|
||||
}
|
||||
template(typename I2)(
|
||||
requires detail::convertible_to_not_slicing_<I2, I> AND
|
||||
sized_sentinel_for<S, I>)
|
||||
constexpr subrange(I2 && i, S s, size_type n)
|
||||
: data_{static_cast<I2 &&>(i), std::move(s)}
|
||||
{
|
||||
RANGES_EXPECT(static_cast<size_type>(last_() - first_()) == n);
|
||||
}
|
||||
|
||||
template(typename R)(
|
||||
requires (!same_as<detail::decay_t<R>, subrange>) AND
|
||||
detail::range_convertible_to_<R, I, S> AND
|
||||
(!detail::store_size_<K, S, I>()))
|
||||
constexpr subrange(R && r)
|
||||
: subrange{ranges::begin(r), ranges::end(r)}
|
||||
{}
|
||||
|
||||
template(typename R)(
|
||||
requires (!same_as<detail::decay_t<R>, subrange>) AND
|
||||
detail::range_convertible_to_<R, I, S> AND
|
||||
(detail::store_size_<K, S, I>()) AND
|
||||
sized_range<R>)
|
||||
constexpr subrange(R && r)
|
||||
: subrange{ranges::begin(r), ranges::end(r), ranges::size(r)}
|
||||
{}
|
||||
|
||||
template(typename R)(
|
||||
requires (K == subrange_kind::sized) AND
|
||||
detail::range_convertible_to_<R, I, S>)
|
||||
constexpr subrange(R && r, size_type n) //
|
||||
: subrange{ranges::begin(r), ranges::end(r), n}
|
||||
{
|
||||
if(RANGES_CONSTEXPR_IF((bool)sized_range<R>))
|
||||
{
|
||||
RANGES_EXPECT(n == ranges::size(r));
|
||||
}
|
||||
}
|
||||
|
||||
template(typename PairLike)(
|
||||
requires (!same_as<PairLike, subrange>) AND
|
||||
detail::pair_like_convertible_from_<PairLike, I const &, S const &>)
|
||||
constexpr operator PairLike() const
|
||||
{
|
||||
return PairLike(first_(), last_());
|
||||
}
|
||||
|
||||
constexpr I begin() const noexcept(std::is_nothrow_copy_constructible<I>::value)
|
||||
{
|
||||
return first_();
|
||||
}
|
||||
constexpr S end() const noexcept(std::is_nothrow_copy_constructible<S>::value)
|
||||
{
|
||||
return last_();
|
||||
}
|
||||
constexpr bool empty() const
|
||||
{
|
||||
return first_() == last_();
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto size() const //
|
||||
-> CPP_ret(size_type)(
|
||||
requires (K == subrange_kind::sized))
|
||||
{
|
||||
return get_size_();
|
||||
}
|
||||
|
||||
RANGES_NODISCARD
|
||||
constexpr subrange next(iter_difference_t<I> n = 1) const
|
||||
{
|
||||
auto tmp = *this;
|
||||
tmp.advance(n);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
RANGES_NODISCARD constexpr auto prev(iter_difference_t<I> n = 1) const
|
||||
-> CPP_ret(subrange)(
|
||||
requires bidirectional_iterator<I>)
|
||||
{
|
||||
auto tmp = *this;
|
||||
tmp.advance(-n);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
constexpr subrange & advance(iter_difference_t<I> n)
|
||||
{
|
||||
set_size_(get_size_() -
|
||||
static_cast<size_type>(n - ranges::advance(first_(), n, last_())));
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
using data_t =
|
||||
meta::conditional_t< //
|
||||
detail::store_size_<K, S, I>(), //
|
||||
std::tuple<I, S, size_type>, //
|
||||
std::tuple<I, S>>;
|
||||
data_t data_;
|
||||
|
||||
constexpr I & first_() noexcept
|
||||
{
|
||||
return std::get<0>(data_);
|
||||
}
|
||||
constexpr const I & first_() const noexcept
|
||||
{
|
||||
return std::get<0>(data_);
|
||||
}
|
||||
constexpr S & last_() noexcept
|
||||
{
|
||||
return std::get<1>(data_);
|
||||
}
|
||||
constexpr const S & last_() const noexcept
|
||||
{
|
||||
return std::get<1>(data_);
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto get_size_() const //
|
||||
-> CPP_ret(size_type)(
|
||||
requires sized_sentinel_for<S, I>)
|
||||
{
|
||||
return static_cast<size_type>(last_() - first_());
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto get_size_() const noexcept //
|
||||
-> CPP_ret(size_type)(
|
||||
requires (detail::store_size_<K, S, I>()))
|
||||
{
|
||||
return std::get<2>(data_);
|
||||
}
|
||||
static constexpr void set_size_(...) noexcept
|
||||
{}
|
||||
CPP_member
|
||||
constexpr auto set_size_(size_type n) noexcept //
|
||||
-> CPP_ret(void)(
|
||||
requires (detail::store_size_<K, S, I>()))
|
||||
{
|
||||
std::get<2>(data_) = n;
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename I, typename S>
|
||||
subrange(I, S) //
|
||||
-> subrange<I, S>;
|
||||
|
||||
template(typename I, typename S)(
|
||||
requires input_or_output_iterator<I> AND sentinel_for<S, I>)
|
||||
subrange(I, S, detail::iter_size_t<I>)
|
||||
-> subrange<I, S, subrange_kind::sized>;
|
||||
|
||||
template(typename R)(
|
||||
requires borrowed_range<R>)
|
||||
subrange(R &&) //
|
||||
-> subrange<iterator_t<R>, sentinel_t<R>,
|
||||
(sized_range<R> ||
|
||||
sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
|
||||
? subrange_kind::sized
|
||||
: subrange_kind::unsized>;
|
||||
|
||||
template(typename R)(
|
||||
requires borrowed_range<R>)
|
||||
subrange(R &&, detail::iter_size_t<iterator_t<R>>)
|
||||
-> subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized>;
|
||||
#endif
|
||||
|
||||
// in lieu of deduction guides, use make_subrange
|
||||
struct make_subrange_fn
|
||||
{
|
||||
template<typename I, typename S>
|
||||
constexpr subrange<I, S> operator()(I i, S s) const
|
||||
{
|
||||
return {i, s};
|
||||
}
|
||||
template(typename I, typename S)(
|
||||
requires input_or_output_iterator<I> AND sentinel_for<S, I>)
|
||||
constexpr subrange<I, S, subrange_kind::sized> //
|
||||
operator()(I i, S s, detail::iter_size_t<I> n) const
|
||||
{
|
||||
return {i, s, n};
|
||||
}
|
||||
template(typename R)(
|
||||
requires borrowed_range<R>)
|
||||
constexpr auto operator()(R && r) const
|
||||
-> subrange<iterator_t<R>, sentinel_t<R>,
|
||||
(sized_range<R> || sized_sentinel_for<sentinel_t<R>, iterator_t<R>>)
|
||||
? subrange_kind::sized
|
||||
: subrange_kind::unsized>
|
||||
{
|
||||
return {(R &&) r};
|
||||
}
|
||||
template(typename R)(
|
||||
requires borrowed_range<R>)
|
||||
constexpr subrange<iterator_t<R>, sentinel_t<R>, subrange_kind::sized> //
|
||||
operator()(R && r, detail::iter_size_t<iterator_t<R>> n) const
|
||||
{
|
||||
return {(R &&) r, n};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates make_subrange_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(make_subrange_fn, make_subrange)
|
||||
|
||||
template<typename R>
|
||||
using borrowed_subrange_t = detail::maybe_dangling_<R, subrange<iterator_t<R>>>;
|
||||
|
||||
template<typename R>
|
||||
using safe_subrange_t RANGES_DEPRECATED("Use borrowed_subrange_t instead.") =
|
||||
borrowed_subrange_t<R>;
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::subrange_kind;
|
||||
|
||||
template(typename I, //
|
||||
typename S = I, //
|
||||
subrange_kind K = //
|
||||
static_cast<subrange_kind>( //
|
||||
detail::is_sized_sentinel_<S, I>()))(
|
||||
requires input_or_output_iterator<I> AND sentinel_for<S, I> AND
|
||||
(K == subrange_kind::sized || !sized_sentinel_for<S, I>)) //
|
||||
using subrange = ranges::subrange<I, S, K>;
|
||||
|
||||
using ranges::borrowed_subrange_t;
|
||||
|
||||
template<typename R>
|
||||
using safe_subrange_t RANGES_DEPRECATED("Use borrowed_subrange_t instead.") =
|
||||
borrowed_subrange_t<R>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename I, typename S, ::ranges::subrange_kind K>
|
||||
struct tuple_size<::ranges::subrange<I, S, K>> : std::integral_constant<size_t, 2>
|
||||
{};
|
||||
template<typename I, typename S, ::ranges::subrange_kind K>
|
||||
struct tuple_element<0, ::ranges::subrange<I, S, K>>
|
||||
{
|
||||
using type = I;
|
||||
};
|
||||
template<typename I, typename S, ::ranges::subrange_kind K>
|
||||
struct tuple_element<1, ::ranges::subrange<I, S, K>>
|
||||
{
|
||||
using type = S;
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
146
Telegram/ThirdParty/range-v3/include/range/v3/view/tail.hpp
vendored
Normal file
146
Telegram/ThirdParty/range-v3/include/range/v3/view/tail.hpp
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_TAIL_HPP
|
||||
#define RANGES_V3_VIEW_TAIL_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
constexpr T prev_or_zero_(T n)
|
||||
{
|
||||
return n == 0 ? T(0) : T(n - 1);
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
struct tail_view
|
||||
: view_interface<tail_view<Rng>,
|
||||
(range_cardinality<Rng>::value >= 0)
|
||||
? detail::prev_or_zero_(range_cardinality<Rng>::value)
|
||||
: range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
Rng rng_;
|
||||
|
||||
public:
|
||||
tail_view() = default;
|
||||
tail_view(Rng rng)
|
||||
: rng_(static_cast<Rng &&>(rng))
|
||||
{
|
||||
CPP_assert(input_range<Rng>);
|
||||
}
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
return next(ranges::begin(rng_), 1, ranges::end(rng_));
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>>)
|
||||
iterator_t<meta::const_if_c<Const, Rng>> begin() const
|
||||
{
|
||||
return next(ranges::begin(rng_), 1, ranges::end(rng_));
|
||||
}
|
||||
sentinel_t<Rng> end()
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>>)
|
||||
sentinel_t<meta::const_if_c<Const, Rng>> end() const
|
||||
{
|
||||
return ranges::end(rng_);
|
||||
}
|
||||
// Strange cast to bool in the requires clause is to work around gcc bug.
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires(bool(sized_range<Rng>)))
|
||||
{
|
||||
using size_type = range_size_t<Rng>;
|
||||
return range_cardinality<Rng>::value >= 0
|
||||
? detail::prev_or_zero_((size_type)range_cardinality<Rng>::value)
|
||||
: detail::prev_or_zero_(ranges::size(rng_));
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires(bool(sized_range<Rng const>)))
|
||||
{
|
||||
using size_type = range_size_t<Rng>;
|
||||
return range_cardinality<Rng>::value >= 0
|
||||
? detail::prev_or_zero_((size_type)range_cardinality<Rng>::value)
|
||||
: detail::prev_or_zero_(ranges::size(rng_));
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<tail_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng>)
|
||||
tail_view(Rng &&)
|
||||
->tail_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct tail_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
meta::if_c<range_cardinality<Rng>::value == 0,
|
||||
all_t<Rng>,
|
||||
tail_view<all_t<Rng>>> //
|
||||
operator()(Rng && rng) const
|
||||
{
|
||||
return all(static_cast<Rng &&>(rng));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates tail_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<tail_fn>, tail)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::tail_view)
|
||||
|
||||
#endif
|
||||
327
Telegram/ThirdParty/range-v3/include/range/v3/view/take.hpp
vendored
Normal file
327
Telegram/ThirdParty/range-v3/include/range/v3/view/take.hpp
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_TAKE_HPP
|
||||
#define RANGES_V3_VIEW_TAKE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/min.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/counted_iterator.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
template<typename Rng>
|
||||
struct take_view : view_interface<take_view<Rng>, finite>
|
||||
{
|
||||
private:
|
||||
CPP_assert(view_<Rng>);
|
||||
Rng base_ = Rng();
|
||||
range_difference_t<Rng> count_ = 0;
|
||||
template<bool Const>
|
||||
struct sentinel
|
||||
{
|
||||
private:
|
||||
using Base = meta::conditional_t<Const, Rng const, Rng>;
|
||||
using CI = counted_iterator<iterator_t<Base>>;
|
||||
sentinel_t<Base> end_ = sentinel_t<Base>();
|
||||
|
||||
public:
|
||||
sentinel() = default;
|
||||
constexpr explicit sentinel(sentinel_t<Base> last)
|
||||
: end_(std::move(last))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other) AND
|
||||
convertible_to<sentinel_t<Rng>,
|
||||
sentinel_t<Base>>)
|
||||
constexpr sentinel(sentinel<Other> that)
|
||||
: end_(std::move(that.end_))
|
||||
{}
|
||||
constexpr sentinel_t<Base> base() const
|
||||
{
|
||||
return end_;
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator==(sentinel const & x, CI const & y)
|
||||
{
|
||||
return y.count() == 0 || y.base() == x.end_;
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator==(CI const & y, sentinel const & x)
|
||||
{
|
||||
return y.count() == 0 || y.base() == x.end_;
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator!=(sentinel const & x, CI const & y)
|
||||
{
|
||||
return y.count() != 0 && y.base() != x.end_;
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_756601
|
||||
template<typename = void>
|
||||
#endif // RANGES_WORKAROUND_MSVC_756601
|
||||
friend constexpr bool operator!=(CI const & y, sentinel const & x)
|
||||
{
|
||||
return y.count() != 0 && y.base() != x.end_;
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_IF_CONSTEXPR < RANGES_CXX_IF_CONSTEXPR_17
|
||||
template<typename Take>
|
||||
static auto begin_random_access_(Take & take, std::true_type)
|
||||
{
|
||||
return ranges::begin(take.base_);
|
||||
}
|
||||
template<typename Take>
|
||||
static auto begin_random_access_(Take & take, std::false_type)
|
||||
{
|
||||
auto s = static_cast<range_difference_t<Rng>>(take.size());
|
||||
return make_counted_iterator(ranges::begin(take.base_), s);
|
||||
}
|
||||
template<typename Take>
|
||||
static auto begin_sized_(Take & take, std::true_type)
|
||||
{
|
||||
return begin_random_access_(
|
||||
take, meta::bool_<random_access_range<decltype((take.base_))>>{});
|
||||
}
|
||||
template<typename Take>
|
||||
static auto begin_sized_(Take & take, std::false_type)
|
||||
{
|
||||
return make_counted_iterator(ranges::begin(take.base_), take.count_);
|
||||
}
|
||||
|
||||
template<typename Take>
|
||||
static auto end_random_access_(Take & take, std::true_type)
|
||||
{
|
||||
return ranges::begin(take.base_) +
|
||||
static_cast<range_difference_t<Rng>>(take.size());
|
||||
}
|
||||
static auto end_random_access_(detail::ignore_t, std::false_type)
|
||||
{
|
||||
return default_sentinel;
|
||||
}
|
||||
template<typename Take>
|
||||
static auto end_sized_(Take & take, std::true_type, std::false_type) // sized
|
||||
{
|
||||
return end_random_access_(
|
||||
take, meta::bool_<random_access_range<decltype((take.base_))>>{});
|
||||
}
|
||||
static auto end_sized_(detail::ignore_t, std::false_type,
|
||||
std::true_type) // infinite
|
||||
{
|
||||
return default_sentinel;
|
||||
}
|
||||
static auto end_sized_(take_view & take, std::false_type, std::false_type)
|
||||
{
|
||||
return sentinel<false>{ranges::end(take.base_)};
|
||||
}
|
||||
static auto end_sized_(take_view const & take, std::false_type, std::false_type)
|
||||
{
|
||||
return sentinel<true>{ranges::end(take.base_)};
|
||||
}
|
||||
#endif
|
||||
public:
|
||||
take_view() = default;
|
||||
|
||||
constexpr take_view(Rng base, range_difference_t<Rng> cnt)
|
||||
: base_(std::move(base))
|
||||
, count_(cnt)
|
||||
{}
|
||||
|
||||
constexpr Rng base() const
|
||||
{
|
||||
return base_;
|
||||
}
|
||||
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(begin)()(
|
||||
requires(!simple_view<Rng>()))
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(sized_range<Rng>)
|
||||
if constexpr(random_access_range<Rng>)
|
||||
return ranges::begin(base_);
|
||||
else
|
||||
{
|
||||
// cannot always delegate to size() member on GCC with ConceptsTS
|
||||
#if defined(__cpp_concepts) && __cpp_concepts <= 201507
|
||||
auto s = ranges::min(
|
||||
static_cast<range_difference_t<Rng>>(count_),
|
||||
static_cast<range_difference_t<Rng>>(ranges::size(base_)));
|
||||
#else
|
||||
auto s = static_cast<range_difference_t<Rng>>(size());
|
||||
#endif
|
||||
return make_counted_iterator(ranges::begin(base_), s);
|
||||
}
|
||||
else
|
||||
return make_counted_iterator(ranges::begin(base_), count_);
|
||||
#else
|
||||
return begin_sized_(*this, meta::bool_<sized_range<Rng>>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(begin)()(const //
|
||||
requires range<Rng const>)
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(sized_range<Rng const>)
|
||||
if constexpr(random_access_range<Rng const>)
|
||||
return ranges::begin(base_);
|
||||
else
|
||||
{
|
||||
auto s = static_cast<range_difference_t<Rng>>(size());
|
||||
return make_counted_iterator(ranges::begin(base_), s);
|
||||
}
|
||||
else
|
||||
return make_counted_iterator(ranges::begin(base_), count_);
|
||||
#else
|
||||
return begin_sized_(*this, meta::bool_<sized_range<Rng const>>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(end)()(
|
||||
requires(!simple_view<Rng>()))
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(sized_range<Rng>)
|
||||
if constexpr(random_access_range<Rng>)
|
||||
return ranges::begin(base_) +
|
||||
static_cast<range_difference_t<Rng>>(size());
|
||||
else
|
||||
return default_sentinel;
|
||||
// Not to spec: Infinite ranges:
|
||||
else if constexpr(is_infinite<Rng>::value)
|
||||
return default_sentinel;
|
||||
else
|
||||
return sentinel<false>{ranges::end(base_)};
|
||||
#else
|
||||
return end_sized_(*this, meta::bool_<sized_range<Rng>>{}, is_infinite<Rng>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(end)()(const //
|
||||
requires range<Rng const>)
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
if constexpr(sized_range<Rng const>)
|
||||
if constexpr(random_access_range<Rng const>)
|
||||
return ranges::begin(base_) +
|
||||
static_cast<range_difference_t<Rng>>(size());
|
||||
else
|
||||
return default_sentinel;
|
||||
// Not to spec: Infinite ranges:
|
||||
else if constexpr(is_infinite<Rng const>::value)
|
||||
return default_sentinel;
|
||||
else
|
||||
return sentinel<true>{ranges::end(base_)};
|
||||
#else
|
||||
return end_sized_(
|
||||
*this, meta::bool_<sized_range<Rng const>>{}, is_infinite<Rng const>{});
|
||||
#endif
|
||||
}
|
||||
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
auto n = ranges::size(base_);
|
||||
return ranges::min(n, static_cast<decltype(n)>(count_));
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
auto n = ranges::size(base_);
|
||||
return ranges::min(n, static_cast<decltype(n)>(count_));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<take_view<Rng>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng>
|
||||
take_view(Rng &&, range_difference_t<Rng>)
|
||||
-> take_view<views::all_t<Rng>>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct take_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng>)
|
||||
take_view<all_t<Rng>> operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), n};
|
||||
}
|
||||
};
|
||||
|
||||
struct take_fn : take_base_fn
|
||||
{
|
||||
using take_base_fn::operator();
|
||||
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int n) const
|
||||
{
|
||||
return make_view_closure(bind_back(take_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates take_fn
|
||||
RANGES_INLINE_VARIABLE(take_fn, take)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::take;
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires view_<Rng>)
|
||||
using take_view = ranges::take_view<Rng>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::take_view)
|
||||
|
||||
#endif
|
||||
203
Telegram/ThirdParty/range-v3/include/range/v3/view/take_exactly.hpp
vendored
Normal file
203
Telegram/ThirdParty/range-v3/include/range/v3/view/take_exactly.hpp
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_TAKE_EXACTLY_HPP
|
||||
#define RANGES_V3_VIEW_TAKE_EXACTLY_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/iterator/counted_iterator.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/counted.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename Rng>
|
||||
struct is_random_access_common_
|
||||
: meta::bool_<(bool)random_access_range<Rng> && (bool)common_range<Rng>>
|
||||
{};
|
||||
|
||||
// BUGBUG Per the discussion in https://github.com/ericniebler/stl2/issues/63,
|
||||
// it's unclear if we can infer anything from random_access_range<Rng> &&
|
||||
// common_range<Rng>
|
||||
template<typename Rng,
|
||||
bool IsRandomAccessCommon /*= is_random_access_common_<Rng>::value*/>
|
||||
struct take_exactly_view_
|
||||
: view_interface<take_exactly_view_<Rng, IsRandomAccessCommon>, finite>
|
||||
{
|
||||
private:
|
||||
Rng rng_;
|
||||
range_difference_t<Rng> n_;
|
||||
|
||||
public:
|
||||
take_exactly_view_() = default;
|
||||
take_exactly_view_(Rng rng, range_difference_t<Rng> n)
|
||||
: rng_(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
}
|
||||
counted_iterator<iterator_t<Rng>> begin()
|
||||
{
|
||||
return {ranges::begin(rng_), n_};
|
||||
}
|
||||
template(typename BaseRng = Rng)(
|
||||
requires range<BaseRng const>)
|
||||
counted_iterator<iterator_t<BaseRng const>> begin() const
|
||||
{
|
||||
return {ranges::begin(rng_), n_};
|
||||
}
|
||||
default_sentinel_t end() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
auto size() const
|
||||
{
|
||||
return static_cast<detail::iter_size_t<iterator_t<Rng>>>(n_);
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng>
|
||||
struct take_exactly_view_<Rng, true>
|
||||
: view_interface<take_exactly_view_<Rng, true>, finite>
|
||||
{
|
||||
private:
|
||||
Rng rng_;
|
||||
range_difference_t<Rng> n_;
|
||||
|
||||
public:
|
||||
take_exactly_view_() = default;
|
||||
take_exactly_view_(Rng rng, range_difference_t<Rng> n)
|
||||
: rng_(std::move(rng))
|
||||
, n_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
RANGES_EXPECT(!(bool)sized_range<Rng> || n <= ranges::distance(rng_));
|
||||
}
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
return ranges::begin(rng_);
|
||||
}
|
||||
iterator_t<Rng> end()
|
||||
{
|
||||
return ranges::begin(rng_) + n_;
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(begin)()(const //
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return ranges::begin(rng_);
|
||||
}
|
||||
CPP_auto_member
|
||||
auto CPP_fun(end)()(const //
|
||||
requires range<Rng const>)
|
||||
{
|
||||
return ranges::begin(rng_) + n_;
|
||||
}
|
||||
detail::iter_size_t<iterator_t<Rng>> size() const
|
||||
{
|
||||
return static_cast<detail::iter_size_t<iterator_t<Rng>>>(n_);
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng>
|
||||
using take_exactly_view = detail::take_exactly_view_<Rng>;
|
||||
|
||||
template<typename Rng, bool B>
|
||||
RANGES_INLINE_VAR constexpr bool //
|
||||
enable_borrowed_range<detail::take_exactly_view_<Rng, B>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct take_exactly_base_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
static constexpr take_exactly_view<all_t<Rng>> impl_(
|
||||
Rng && rng, range_difference_t<Rng> n, input_range_tag)
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), n};
|
||||
}
|
||||
template(typename Rng)(
|
||||
requires borrowed_range<Rng>)
|
||||
static constexpr subrange<iterator_t<Rng>> impl_(Rng && rng,
|
||||
range_difference_t<Rng> n,
|
||||
random_access_range_tag)
|
||||
{
|
||||
return {begin(rng), next(begin(rng), n)};
|
||||
}
|
||||
|
||||
public:
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND input_range<Rng>)
|
||||
constexpr auto operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
return take_exactly_base_fn::impl_(
|
||||
static_cast<Rng &&>(rng), n, range_tag_of<Rng>{});
|
||||
}
|
||||
};
|
||||
|
||||
struct take_exactly_fn : take_exactly_base_fn
|
||||
{
|
||||
using take_exactly_base_fn::operator();
|
||||
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int n) const
|
||||
{
|
||||
return make_view_closure(bind_back(take_exactly_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates take_exactly_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(take_exactly_fn, take_exactly)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::detail::take_exactly_view_)
|
||||
|
||||
#endif
|
||||
66
Telegram/ThirdParty/range-v3/include/range/v3/view/take_last.hpp
vendored
Normal file
66
Telegram/ThirdParty/range-v3/include/range/v3/view/take_last.hpp
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Barry Revzin 2019-present
|
||||
//
|
||||
// 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_TAKE_LAST_HPP
|
||||
#define RANGES_V3_VIEW_TAKE_LAST_HPP
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/operations.hpp>
|
||||
#include <range/v3/view/drop_exactly.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct take_last_base_fn
|
||||
{
|
||||
template(typename Rng)(
|
||||
requires viewable_range<Rng> AND sized_range<Rng>)
|
||||
auto operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
auto sz = ranges::distance(rng);
|
||||
return drop_exactly(static_cast<Rng &&>(rng), sz > n ? sz - n : 0);
|
||||
}
|
||||
};
|
||||
|
||||
struct take_last_fn : take_last_base_fn
|
||||
{
|
||||
using take_last_base_fn::operator();
|
||||
|
||||
template(typename Int)(
|
||||
requires detail::integer_like_<Int>)
|
||||
constexpr auto operator()(Int n) const
|
||||
{
|
||||
return make_view_closure(bind_back(take_last_base_fn{}, n));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates take_last_fn
|
||||
RANGES_INLINE_VARIABLE(take_last_fn, take_last)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
210
Telegram/ThirdParty/range-v3/include/range/v3/view/take_while.hpp
vendored
Normal file
210
Telegram/ThirdParty/range-v3/include/range/v3/view/take_while.hpp
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_TAKE_WHILE_HPP
|
||||
#define RANGES_V3_VIEW_TAKE_WHILE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/compose.hpp>
|
||||
#include <range/v3/functional/indirect.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Pred>
|
||||
struct iter_take_while_view
|
||||
: view_adaptor<iter_take_while_view<Rng, Pred>, Rng,
|
||||
is_finite<Rng>::value ? finite : unknown>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Pred> pred_;
|
||||
|
||||
template<bool IsConst>
|
||||
struct sentinel_adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
friend struct sentinel_adaptor<!IsConst>;
|
||||
using CRng = meta::const_if_c<IsConst, Rng>;
|
||||
RANGES_NO_UNIQUE_ADDRESS semiregular_box_ref_or_val_t<Pred, IsConst> pred_;
|
||||
|
||||
public:
|
||||
sentinel_adaptor() = default;
|
||||
sentinel_adaptor(semiregular_box_ref_or_val_t<Pred, IsConst> pred)
|
||||
: pred_(std::move(pred))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
sentinel_adaptor(sentinel_adaptor<Other> that)
|
||||
: pred_(std::move(that.pred_))
|
||||
{}
|
||||
bool empty(iterator_t<CRng> const & it, sentinel_t<CRng> const & last) const
|
||||
{
|
||||
return it == last || !invoke(pred_, it);
|
||||
}
|
||||
};
|
||||
sentinel_adaptor<false> end_adaptor()
|
||||
{
|
||||
return {pred_};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>> AND
|
||||
invocable<Pred const &, iterator_t<meta::const_if_c<Const, Rng>>>)
|
||||
sentinel_adaptor<Const> end_adaptor() const
|
||||
{
|
||||
return {pred_};
|
||||
}
|
||||
|
||||
public:
|
||||
iter_take_while_view() = default;
|
||||
constexpr iter_take_while_view(Rng rng, Pred pred)
|
||||
: iter_take_while_view::view_adaptor{std::move(rng)}
|
||||
, pred_(std::move(pred))
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Rng, typename Pred>
|
||||
struct take_while_view : iter_take_while_view<Rng, indirected<Pred>>
|
||||
{
|
||||
take_while_view() = default;
|
||||
constexpr take_while_view(Rng rng, Pred pred)
|
||||
: iter_take_while_view<Rng, indirected<Pred>>{std::move(rng),
|
||||
indirect(std::move(pred))}
|
||||
{}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Fun>)
|
||||
take_while_view(Rng &&, Fun)
|
||||
-> take_while_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct iter_take_while_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
predicate<Pred &, iterator_t<Rng>> AND copy_constructible<Pred>)
|
||||
constexpr iter_take_while_view<all_t<Rng>, Pred> //
|
||||
operator()(Rng && rng, Pred pred) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(pred)};
|
||||
}
|
||||
};
|
||||
|
||||
struct iter_take_while_fn : iter_take_while_base_fn
|
||||
{
|
||||
using iter_take_while_base_fn::operator();
|
||||
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(iter_take_while_base_fn{}, std::move(pred)));
|
||||
}
|
||||
};
|
||||
|
||||
struct take_while_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<Pred &, iterator_t<Rng>>)
|
||||
constexpr take_while_view<all_t<Rng>, Pred> //
|
||||
operator()(Rng && rng, Pred pred) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(pred)};
|
||||
}
|
||||
template(typename Rng, typename Pred, typename Proj)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
indirect_unary_predicate<composed<Pred, Proj> &, iterator_t<Rng>>)
|
||||
constexpr take_while_view<all_t<Rng>, composed<Pred, Proj>> //
|
||||
operator()(Rng && rng, Pred pred, Proj proj) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
compose(std::move(pred), std::move(proj))};
|
||||
}
|
||||
};
|
||||
|
||||
struct take_while_bind_fn
|
||||
{
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const // TODO: underconstrained
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(take_while_base_fn{}, std::move(pred)));
|
||||
}
|
||||
template(typename Pred, typename Proj)(
|
||||
requires (!range<Pred>)) // TODO: underconstrained
|
||||
constexpr auto operator()(Pred && pred, Proj proj) const
|
||||
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
take_while_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
|
||||
}
|
||||
};
|
||||
|
||||
struct RANGES_EMPTY_BASES take_while_fn
|
||||
: take_while_base_fn, take_while_bind_fn
|
||||
{
|
||||
using take_while_base_fn::operator();
|
||||
using take_while_bind_fn::operator();
|
||||
};
|
||||
|
||||
/// \relates iter_take_while_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(iter_take_while_fn, iter_take_while)
|
||||
|
||||
/// \relates take_while_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(take_while_fn, take_while)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::take_while;
|
||||
}
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
predicate<Pred &, iterator_t<Rng>> AND copy_constructible<Pred>)
|
||||
using take_while_view = ranges::take_while_view<Rng, Pred>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::iter_take_while_view)
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::take_while_view)
|
||||
|
||||
#endif
|
||||
207
Telegram/ThirdParty/range-v3/include/range/v3/view/tokenize.hpp
vendored
Normal file
207
Telegram/ThirdParty/range-v3/include/range/v3/view/tokenize.hpp
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_TOKENIZE_HPP
|
||||
#define RANGES_V3_VIEW_TOKENIZE_HPP
|
||||
|
||||
#include <initializer_list>
|
||||
#include <regex>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Regex, typename SubMatchRange>
|
||||
struct tokenize_view
|
||||
: view_interface<tokenize_view<Rng, Regex, SubMatchRange>,
|
||||
is_finite<Rng>::value ? finite : range_cardinality<Rng>::value>
|
||||
{
|
||||
private:
|
||||
CPP_assert(bidirectional_range<Rng> && view_<Rng> && common_range<Rng>);
|
||||
CPP_assert(semiregular<Regex>);
|
||||
CPP_assert(semiregular<SubMatchRange>);
|
||||
|
||||
Rng rng_;
|
||||
Regex rex_;
|
||||
SubMatchRange subs_;
|
||||
std::regex_constants::match_flag_type flags_;
|
||||
template<bool Const>
|
||||
using iterator_t =
|
||||
std::regex_token_iterator<iterator_t<meta::const_if_c<Const, Rng>>>;
|
||||
|
||||
public:
|
||||
tokenize_view() = default;
|
||||
tokenize_view(Rng rng, Regex rex, SubMatchRange subs,
|
||||
std::regex_constants::match_flag_type flags)
|
||||
: rng_(std::move(rng))
|
||||
, rex_(std::move(rex))
|
||||
, subs_(std::move(subs))
|
||||
, flags_(flags)
|
||||
{}
|
||||
iterator_t<simple_view<Rng>()> begin()
|
||||
{
|
||||
meta::const_if_c<simple_view<Rng>(), Rng> & rng = rng_;
|
||||
return {ranges::begin(rng), ranges::end(rng), rex_, subs_, flags_};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires range<Rng const>)
|
||||
iterator_t<Const> begin() const
|
||||
{
|
||||
return {ranges::begin(rng_), ranges::end(rng_), rex_, subs_, flags_};
|
||||
}
|
||||
iterator_t<simple_view<Rng>()> end()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires range<Rng const>)
|
||||
iterator_t<Const> end() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Regex, typename SubMatchRange)(
|
||||
requires copy_constructible<Regex> AND copy_constructible<SubMatchRange>)
|
||||
tokenize_view(Rng &&, Regex, SubMatchRange)
|
||||
->tokenize_view<views::all_t<Rng>, Regex, SubMatchRange>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct tokenize_base_fn
|
||||
{
|
||||
template(typename Rng, typename Regex)(
|
||||
requires bidirectional_range<Rng> AND common_range<Rng> AND
|
||||
same_as< //
|
||||
range_value_t<Rng>, //
|
||||
typename detail::decay_t<Regex>::value_type>)
|
||||
tokenize_view<all_t<Rng>, detail::decay_t<Regex>, int> //
|
||||
operator()(Rng && rng,
|
||||
Regex && rex,
|
||||
int sub = 0,
|
||||
std::regex_constants::match_flag_type flags =
|
||||
std::regex_constants::match_default) const //
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
static_cast<Regex &&>(rex),
|
||||
sub,
|
||||
flags};
|
||||
}
|
||||
|
||||
template(typename Rng, typename Regex)(
|
||||
requires bidirectional_range<Rng> AND common_range<Rng> AND
|
||||
same_as<range_value_t<Rng>,
|
||||
typename detail::decay_t<Regex>::value_type>)
|
||||
tokenize_view<all_t<Rng>, detail::decay_t<Regex>, std::vector<int>> //
|
||||
operator()(Rng && rng,
|
||||
Regex && rex,
|
||||
std::vector<int> subs,
|
||||
std::regex_constants::match_flag_type flags =
|
||||
std::regex_constants::match_default) const //
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
static_cast<Regex &&>(rex),
|
||||
std::move(subs),
|
||||
flags};
|
||||
}
|
||||
|
||||
template(typename Rng, typename Regex)(
|
||||
requires bidirectional_range<Rng> AND common_range<Rng> AND
|
||||
same_as<range_value_t<Rng>,
|
||||
typename detail::decay_t<Regex>::value_type>)
|
||||
tokenize_view<all_t<Rng>,
|
||||
detail::decay_t<Regex>,
|
||||
std::initializer_list<int>> //
|
||||
operator()(Rng && rng,
|
||||
Regex && rex,
|
||||
std::initializer_list<int> subs,
|
||||
std::regex_constants::match_flag_type flags =
|
||||
std::regex_constants::match_default) const //
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
static_cast<Regex &&>(rex),
|
||||
std::move(subs),
|
||||
flags};
|
||||
}
|
||||
};
|
||||
|
||||
struct tokenize_fn : tokenize_base_fn
|
||||
{
|
||||
using tokenize_base_fn::operator();
|
||||
|
||||
template<typename Regex>
|
||||
constexpr auto operator()(Regex && rex,
|
||||
int sub = 0,
|
||||
std::regex_constants::match_flag_type flags =
|
||||
std::regex_constants::match_default) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
tokenize_base_fn{}, static_cast<Regex &&>(rex), sub, flags));
|
||||
}
|
||||
|
||||
template<typename Regex>
|
||||
auto operator()(Regex && rex,
|
||||
std::vector<int> subs,
|
||||
std::regex_constants::match_flag_type flags =
|
||||
std::regex_constants::match_default) const
|
||||
{
|
||||
return bind_back(tokenize_base_fn{},
|
||||
static_cast<Regex &&>(rex),
|
||||
std::move(subs),
|
||||
flags);
|
||||
}
|
||||
|
||||
template<typename Regex>
|
||||
constexpr auto operator()(Regex && rex,
|
||||
std::initializer_list<int> subs,
|
||||
std::regex_constants::match_flag_type flags =
|
||||
std::regex_constants::match_default) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
tokenize_base_fn{}, static_cast<Regex &&>(rex), subs, flags));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates tokenize_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(tokenize_fn, tokenize)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::tokenize_view)
|
||||
|
||||
#endif
|
||||
618
Telegram/ThirdParty/range-v3/include/range/v3/view/transform.hpp
vendored
Normal file
618
Telegram/ThirdParty/range-v3/include/range/v3/view/transform.hpp
vendored
Normal file
@@ -0,0 +1,618 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_TRANSFORM_HPP
|
||||
#define RANGES_V3_VIEW_TRANSFORM_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/algorithm/max.hpp>
|
||||
#include <range/v3/algorithm/min.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/indirect.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/move.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adaptor.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
constexpr cardinality transform2_cardinality(cardinality c1, cardinality c2)
|
||||
{
|
||||
return c1 >= 0 || c2 >= 0
|
||||
? (c1 >= 0 && c2 >= 0 ? (c1 < c2 ? c1 : c2) : finite)
|
||||
: c1 == finite || c2 == finite
|
||||
? finite
|
||||
: c1 == unknown || c2 == unknown ? unknown : infinite;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
/// \concept iter_transform_1_readable_
|
||||
/// \brief The \c iter_transform_1_readable_ concept
|
||||
template(typename Fun, typename Rng)(
|
||||
concept (iter_transform_1_readable_)(Fun, Rng),
|
||||
regular_invocable<Fun &, iterator_t<Rng>> AND
|
||||
regular_invocable<Fun &, copy_tag, iterator_t<Rng>> AND
|
||||
regular_invocable<Fun &, move_tag, iterator_t<Rng>> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<Fun &, iterator_t<Rng>> &&,
|
||||
invoke_result_t<Fun &, copy_tag, iterator_t<Rng>> &> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<Fun &, iterator_t<Rng>> &&,
|
||||
invoke_result_t<Fun &, move_tag, iterator_t<Rng>> &&> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<Fun &, move_tag, iterator_t<Rng>> &&,
|
||||
invoke_result_t<Fun &, copy_tag, iterator_t<Rng>> const &>
|
||||
);
|
||||
/// \concept iter_transform_1_readable
|
||||
/// \brief The \c iter_transform_1_readable concept
|
||||
template<typename Fun, typename Rng>
|
||||
CPP_concept iter_transform_1_readable =
|
||||
CPP_concept_ref(detail::iter_transform_1_readable_, Fun, Rng);
|
||||
|
||||
/// \concept iter_transform_2_readable_
|
||||
/// \brief The \c iter_transform_2_readable_ concept
|
||||
template(typename Fun, typename Rng1, typename Rng2)(
|
||||
concept (iter_transform_2_readable_)(Fun, Rng1, Rng2),
|
||||
regular_invocable<Fun &, iterator_t<Rng1>, iterator_t<Rng2>> AND
|
||||
regular_invocable<Fun &, copy_tag, iterator_t<Rng1>, iterator_t<Rng2>> AND
|
||||
regular_invocable<Fun &, move_tag, iterator_t<Rng1>, iterator_t<Rng2>> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<Fun &, iterator_t<Rng1>, iterator_t<Rng2>> &&,
|
||||
invoke_result_t<Fun &, copy_tag, iterator_t<Rng1>, iterator_t<Rng2>> &> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<Fun &, iterator_t<Rng1>, iterator_t<Rng2>> &&,
|
||||
invoke_result_t<Fun &, move_tag, iterator_t<Rng1>, iterator_t<Rng2>> &&> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<Fun &, move_tag, iterator_t<Rng1>, iterator_t<Rng2>> &&,
|
||||
invoke_result_t<Fun &, copy_tag, iterator_t<Rng1>, iterator_t<Rng2>> const &>
|
||||
);
|
||||
/// \concept iter_transform_2_readable
|
||||
/// \brief The \c iter_transform_2_readable concept
|
||||
template<typename Fun, typename Rng1, typename Rng2>
|
||||
CPP_concept iter_transform_2_readable =
|
||||
CPP_concept_ref(detail::iter_transform_2_readable_, Fun, Rng1, Rng2);
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Fun>
|
||||
struct iter_transform_view : view_adaptor<iter_transform_view<Rng, Fun>, Rng>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Fun> fun_;
|
||||
template<bool Const>
|
||||
using use_sentinel_t =
|
||||
meta::bool_<!common_range<meta::const_if_c<Const, Rng>> ||
|
||||
single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng>>>>;
|
||||
|
||||
template<bool IsConst>
|
||||
struct adaptor : adaptor_base
|
||||
{
|
||||
private:
|
||||
friend struct adaptor<!IsConst>;
|
||||
using CRng = meta::const_if_c<IsConst, Rng>;
|
||||
using fun_ref_ = semiregular_box_ref_or_val_t<Fun, IsConst>;
|
||||
RANGES_NO_UNIQUE_ADDRESS fun_ref_ fun_;
|
||||
|
||||
public:
|
||||
using value_type =
|
||||
detail::decay_t<invoke_result_t<Fun &, copy_tag, iterator_t<CRng>>>;
|
||||
adaptor() = default;
|
||||
adaptor(fun_ref_ fun)
|
||||
: fun_(std::move(fun))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires IsConst AND CPP_NOT(Other)) //
|
||||
adaptor(adaptor<Other> that)
|
||||
: fun_(std::move(that.fun_))
|
||||
{}
|
||||
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(read)(iterator_t<CRng> it)(const)
|
||||
(
|
||||
return invoke(fun_, it)
|
||||
)
|
||||
auto CPP_auto_fun(iter_move)(iterator_t<CRng> it)(const)
|
||||
(
|
||||
return invoke(fun_, move_tag{}, it)
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
adaptor<false> begin_adaptor()
|
||||
{
|
||||
return {fun_};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>> AND
|
||||
detail::iter_transform_1_readable<Fun const,
|
||||
meta::const_if_c<Const, Rng>>)
|
||||
adaptor<Const> begin_adaptor() const
|
||||
{
|
||||
return {fun_};
|
||||
}
|
||||
meta::if_<use_sentinel_t<false>, adaptor_base, adaptor<false>> end_adaptor()
|
||||
{
|
||||
return {fun_};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng>> AND
|
||||
detail::iter_transform_1_readable<Fun const,
|
||||
meta::const_if_c<Const, Rng>>)
|
||||
meta::if_<use_sentinel_t<Const>, adaptor_base, adaptor<Const>> end_adaptor() const
|
||||
{
|
||||
return {fun_};
|
||||
}
|
||||
|
||||
public:
|
||||
iter_transform_view() = default;
|
||||
iter_transform_view(Rng rng, Fun fun)
|
||||
: iter_transform_view::view_adaptor{std::move(rng)}
|
||||
, fun_(std::move(fun))
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(
|
||||
requires sized_range<Rng>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires sized_range<Rng const>)
|
||||
{
|
||||
return ranges::size(this->base());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng, typename Fun>
|
||||
struct transform_view : iter_transform_view<Rng, indirected<Fun>>
|
||||
{
|
||||
transform_view() = default;
|
||||
transform_view(Rng rng, Fun fun)
|
||||
: iter_transform_view<Rng, indirected<Fun>>{std::move(rng),
|
||||
indirect(std::move(fun))}
|
||||
{}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Rng, typename Fun)(
|
||||
requires copy_constructible<Fun>)
|
||||
transform_view(Rng &&, Fun)
|
||||
-> transform_view<views::all_t<Rng>, Fun>;
|
||||
#endif
|
||||
|
||||
template<typename Rng1, typename Rng2, typename Fun>
|
||||
struct iter_transform2_view
|
||||
: view_facade<iter_transform2_view<Rng1, Rng2, Fun>,
|
||||
detail::transform2_cardinality(range_cardinality<Rng1>::value,
|
||||
range_cardinality<Rng2>::value)>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
RANGES_NO_UNIQUE_ADDRESS semiregular_box_t<Fun> fun_;
|
||||
Rng1 rng1_;
|
||||
Rng2 rng2_;
|
||||
using difference_type_ =
|
||||
common_type_t<range_difference_t<Rng1>, range_difference_t<Rng2>>;
|
||||
|
||||
static constexpr cardinality my_cardinality = detail::transform2_cardinality(
|
||||
range_cardinality<Rng1>::value, range_cardinality<Rng2>::value);
|
||||
|
||||
template<bool>
|
||||
struct cursor;
|
||||
|
||||
template<bool Const>
|
||||
struct sentinel
|
||||
{
|
||||
private:
|
||||
friend struct cursor<Const>;
|
||||
sentinel_t<meta::const_if_c<Const, Rng1>> end1_;
|
||||
sentinel_t<meta::const_if_c<Const, Rng2>> end2_;
|
||||
|
||||
public:
|
||||
sentinel() = default;
|
||||
sentinel(meta::const_if_c<Const, iter_transform2_view> * parent,
|
||||
decltype(ranges::end))
|
||||
: end1_(end(parent->rng1_))
|
||||
, end2_(end(parent->rng2_))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
sentinel(sentinel<Other> that)
|
||||
: end1_(std::move(that.end1_))
|
||||
, end2_(std::move(that.end2_))
|
||||
{}
|
||||
};
|
||||
|
||||
template<bool Const>
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
using fun_ref_ = semiregular_box_ref_or_val_t<Fun, Const>;
|
||||
using R1 = meta::const_if_c<Const, Rng1>;
|
||||
using R2 = meta::const_if_c<Const, Rng2>;
|
||||
fun_ref_ fun_;
|
||||
iterator_t<R1> it1_;
|
||||
iterator_t<R2> it2_;
|
||||
|
||||
public:
|
||||
using difference_type = difference_type_;
|
||||
using single_pass = meta::or_c<(bool)single_pass_iterator_<iterator_t<R1>>,
|
||||
(bool)single_pass_iterator_<iterator_t<R2>>>;
|
||||
using value_type =
|
||||
detail::decay_t<invoke_result_t<meta::const_if_c<Const, Fun> &, copy_tag,
|
||||
iterator_t<R1>, iterator_t<R2>>>;
|
||||
|
||||
cursor() = default;
|
||||
template<typename BeginEndFn>
|
||||
cursor(meta::const_if_c<Const, iter_transform2_view> * parent,
|
||||
BeginEndFn begin_end)
|
||||
: fun_(parent->fun_)
|
||||
, it1_(begin_end(parent->rng1_))
|
||||
, it2_(begin_end(parent->rng2_))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: fun_(std::move(that.fun_))
|
||||
, it1_(std::move(that.end1_))
|
||||
, it2_(std::move(that.end2_))
|
||||
{}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(read)()(const)
|
||||
(
|
||||
return invoke(fun_, it1_, it2_)
|
||||
)
|
||||
// clang-format on
|
||||
void next()
|
||||
{
|
||||
++it1_;
|
||||
++it2_;
|
||||
}
|
||||
CPP_member
|
||||
auto equal(cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires forward_range<Rng1> && forward_range<Rng2>)
|
||||
{
|
||||
// By returning true if *any* of the iterators are equal, we allow
|
||||
// transformed ranges to be of different lengths, stopping when the first
|
||||
// one reaches the last.
|
||||
return it1_ == that.it1_ || it2_ == that.it2_;
|
||||
}
|
||||
bool equal(sentinel<Const> const & s) const
|
||||
{
|
||||
// By returning true if *any* of the iterators are equal, we allow
|
||||
// transformed ranges to be of different lengths, stopping when the first
|
||||
// one reaches the last.
|
||||
return it1_ == s.end1_ || it2_ == s.end2_;
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_range<R1> && bidirectional_range<R2>)
|
||||
{
|
||||
--it1_;
|
||||
--it2_;
|
||||
}
|
||||
CPP_member
|
||||
auto advance(difference_type n) -> CPP_ret(void)(
|
||||
requires random_access_range<R1> && random_access_range<R2>)
|
||||
{
|
||||
ranges::advance(it1_, n);
|
||||
ranges::advance(it2_, n);
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(cursor const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires sized_sentinel_for<iterator_t<R1>, iterator_t<R1>> &&
|
||||
sized_sentinel_for<iterator_t<R2>, iterator_t<R2>>)
|
||||
{
|
||||
// Return the smallest distance (in magnitude) of any of the iterator
|
||||
// pairs. This is to accommodate zippers of sequences of different length.
|
||||
difference_type d1 = that.it1_ - it1_, d2 = that.it2_ - it2_;
|
||||
return 0 < d1 ? ranges::min(d1, d2) : ranges::max(d1, d2);
|
||||
}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(move)()(const)
|
||||
(
|
||||
return invoke(fun_, move_tag{}, it1_, it2_)
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
template<bool Const>
|
||||
using end_cursor_t = meta::if_c<
|
||||
common_range<meta::const_if_c<Const, Rng1>> &&
|
||||
common_range<meta::const_if_c<Const, Rng2>> &&
|
||||
!single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng1>>> &&
|
||||
!single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rng2>>>,
|
||||
cursor<Const>, sentinel<Const>>;
|
||||
|
||||
cursor<simple_view<Rng1>() && simple_view<Rng2>()> begin_cursor()
|
||||
{
|
||||
return {this, ranges::begin};
|
||||
}
|
||||
end_cursor_t<simple_view<Rng1>() && simple_view<Rng2>()> end_cursor()
|
||||
{
|
||||
return {this, ranges::end};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng1>> AND
|
||||
range<meta::const_if_c<Const, Rng2>> AND
|
||||
detail::iter_transform_2_readable< //
|
||||
Fun const, //
|
||||
meta::const_if_c<Const, Rng1>, //
|
||||
meta::const_if_c<Const, Rng2>>)
|
||||
cursor<true> begin_cursor() const
|
||||
{
|
||||
return {this, ranges::begin};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND range<meta::const_if_c<Const, Rng1>> AND
|
||||
range<meta::const_if_c<Const, Rng2>> AND
|
||||
detail::iter_transform_2_readable< //
|
||||
Fun const, //
|
||||
meta::const_if_c<Const, Rng1>, //
|
||||
meta::const_if_c<Const, Rng2>>)
|
||||
end_cursor_t<Const> end_cursor() const
|
||||
{
|
||||
return {this, ranges::end};
|
||||
}
|
||||
template<typename Self>
|
||||
static constexpr auto size_(Self & self)
|
||||
{
|
||||
using size_type = common_type_t<range_size_t<Rng1>, range_size_t<Rng2>>;
|
||||
return ranges::min(static_cast<size_type>(ranges::size(self.rng1_)),
|
||||
static_cast<size_type>(ranges::size(self.rng2_)));
|
||||
}
|
||||
|
||||
template<bool B>
|
||||
using R1 = meta::invoke<detail::dependent_<B>, Rng1>;
|
||||
template<bool B>
|
||||
using R2 = meta::invoke<detail::dependent_<B>, Rng2>;
|
||||
|
||||
public:
|
||||
iter_transform2_view() = default;
|
||||
constexpr iter_transform2_view(Rng1 rng1, Rng2 rng2, Fun fun)
|
||||
: fun_(std::move(fun))
|
||||
, rng1_(std::move(rng1))
|
||||
, rng2_(std::move(rng2))
|
||||
{}
|
||||
CPP_member
|
||||
static constexpr auto size() //
|
||||
-> CPP_ret(std::size_t)(
|
||||
requires (my_cardinality >= 0))
|
||||
{
|
||||
return static_cast<std::size_t>(my_cardinality);
|
||||
}
|
||||
template(bool True = true)(
|
||||
requires (my_cardinality < 0) AND sized_range<Rng1 const> AND
|
||||
sized_range<Rng2 const> AND
|
||||
common_with<range_size_t<R1<True>>, range_size_t<R2<True>>>)
|
||||
constexpr auto size() const
|
||||
{
|
||||
return size_(*this);
|
||||
}
|
||||
template(bool True = true)(
|
||||
requires (my_cardinality < 0) AND sized_range<Rng1> AND sized_range<Rng2> AND
|
||||
common_with<range_size_t<R1<True>>, range_size_t<R2<True>>>)
|
||||
constexpr auto size()
|
||||
{
|
||||
return size_(*this);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng1, typename Rng2, typename Fun>
|
||||
struct transform2_view : iter_transform2_view<Rng1, Rng2, indirected<Fun>>
|
||||
{
|
||||
transform2_view() = default;
|
||||
constexpr transform2_view(Rng1 rng1, Rng2 rng2, Fun fun)
|
||||
: iter_transform2_view<Rng1, Rng2, indirected<Fun>>{std::move(rng1),
|
||||
std::move(rng2),
|
||||
indirect(std::move(fun))}
|
||||
{}
|
||||
};
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct iter_transform_base_fn
|
||||
{
|
||||
template(typename Rng, typename Fun)(
|
||||
requires viewable_range<Rng> AND input_range<Rng> AND
|
||||
copy_constructible<Fun> AND
|
||||
detail::iter_transform_1_readable<Fun, Rng>)
|
||||
constexpr iter_transform_view<all_t<Rng>, Fun> //
|
||||
operator()(Rng && rng, Fun fun) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(fun)};
|
||||
}
|
||||
|
||||
template(typename Rng1, typename Rng2, typename Fun)(
|
||||
requires viewable_range<Rng1> AND input_range<Rng1> AND
|
||||
viewable_range<Rng2> AND input_range<Rng2> AND
|
||||
copy_constructible<Fun> AND
|
||||
common_with<range_difference_t<Rng1>, range_difference_t<Rng1>> AND
|
||||
detail::iter_transform_2_readable<Fun, Rng1, Rng2>)
|
||||
constexpr iter_transform2_view<all_t<Rng1>, all_t<Rng2>, Fun> //
|
||||
operator()(Rng1 && rng1, Rng2 && rng2, Fun fun) const
|
||||
{
|
||||
return {all(static_cast<Rng1 &&>(rng1)),
|
||||
all(static_cast<Rng2 &&>(rng2)),
|
||||
std::move(fun)};
|
||||
}
|
||||
};
|
||||
|
||||
struct iter_transform_fn : iter_transform_base_fn
|
||||
{
|
||||
using iter_transform_base_fn::operator();
|
||||
|
||||
template<typename Fun>
|
||||
constexpr auto operator()(Fun fun) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(iter_transform_base_fn{}, std::move(fun)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates iter_transform_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(iter_transform_fn, iter_transform)
|
||||
|
||||
// Don't forget to update views::for_each whenever this set
|
||||
// of concepts changes
|
||||
// clang-format off
|
||||
/// \concept transformable_range_
|
||||
/// \brief The \c transformable_range_ concept
|
||||
template(typename Rng, typename Fun)(
|
||||
concept (transformable_range_)(Rng, Fun),
|
||||
regular_invocable<Fun &, range_reference_t<Rng>> AND
|
||||
(!std::is_void<indirect_result_t<Fun &, iterator_t<Rng>>>::value)
|
||||
);
|
||||
/// \concept transformable_range
|
||||
/// \brief The \c transformable_range concept
|
||||
template<typename Rng, typename Fun>
|
||||
CPP_concept transformable_range =
|
||||
viewable_range<Rng> && input_range<Rng> &&
|
||||
copy_constructible<Fun> &&
|
||||
CPP_concept_ref(views::transformable_range_, Rng, Fun);
|
||||
|
||||
/// \concept transformable_ranges_
|
||||
/// \brief The \c transformable_ranges_ concept
|
||||
template(typename Rng1, typename Rng2, typename Fun)(
|
||||
concept (transformable_ranges_)(Rng1, Rng2, Fun),
|
||||
regular_invocable<Fun &, range_reference_t<Rng1>, range_reference_t<Rng2>> AND
|
||||
(!std::is_void<
|
||||
indirect_result_t<Fun &, iterator_t<Rng1>, iterator_t<Rng2>>>::value)
|
||||
);
|
||||
/// \concept transformable_ranges
|
||||
/// \brief The \c transformable_ranges concept
|
||||
template<typename Rng1, typename Rng2, typename Fun>
|
||||
CPP_concept transformable_ranges =
|
||||
viewable_range<Rng1> && input_range<Rng1> &&
|
||||
viewable_range<Rng2> && input_range<Rng2> &&
|
||||
copy_constructible<Fun> &&
|
||||
CPP_concept_ref(views::transformable_ranges_, Rng1, Rng2, Fun);
|
||||
// clang-format on
|
||||
|
||||
struct transform_base_fn
|
||||
{
|
||||
template(typename Rng, typename Fun)(
|
||||
requires transformable_range<Rng, Fun>)
|
||||
constexpr transform_view<all_t<Rng>, Fun> operator()(Rng && rng, Fun fun)
|
||||
const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(fun)};
|
||||
}
|
||||
|
||||
template(typename Rng1, typename Rng2, typename Fun)(
|
||||
requires transformable_ranges<Rng1, Rng2, Fun>)
|
||||
constexpr transform2_view<all_t<Rng1>, all_t<Rng2>, Fun> //
|
||||
operator()(Rng1 && rng1, Rng2 && rng2, Fun fun) const
|
||||
{
|
||||
return {all(static_cast<Rng1 &&>(rng1)),
|
||||
all(static_cast<Rng2 &&>(rng2)),
|
||||
std::move(fun)};
|
||||
}
|
||||
};
|
||||
|
||||
/// # ranges::views::transform
|
||||
/// The transform view takes in a function `T -> U` and converts an input
|
||||
/// range of `T` into an output range of `U` by calling the function on every
|
||||
/// element of the input range.
|
||||
///
|
||||
/// ## Example
|
||||
/// \snippet example/view/transform.cpp transform example
|
||||
///
|
||||
/// ### Output
|
||||
/// \include example/view/transform_golden.txt
|
||||
///
|
||||
/// ## Syntax
|
||||
/// ```cpp
|
||||
/// auto output_range = input_range | ranges::views::transform(transform_func);
|
||||
/// ```
|
||||
///
|
||||
/// ## Parameters
|
||||
/// <pre><b>transform_func</b></pre>
|
||||
/// - Maps an input value to an output value (`transform_func(T) -> U`)
|
||||
///
|
||||
/// <pre><b>input_range</b></pre>
|
||||
/// - The range of elements to transform
|
||||
/// - Reference type: `T`
|
||||
///
|
||||
/// <pre><b>output_range</b></pre>
|
||||
/// - The range of output values
|
||||
/// - Reference type: `U`
|
||||
/// - Value type: `decay_t<U>`
|
||||
/// - This range will have the same category as the input range (excluding
|
||||
/// contiguous ranges). Contiguous ranges are reduced to random access ranges.
|
||||
///
|
||||
struct transform_fn : transform_base_fn
|
||||
{
|
||||
using transform_base_fn::operator();
|
||||
|
||||
template<typename Fun>
|
||||
constexpr auto operator()(Fun fun) const
|
||||
{
|
||||
return make_view_closure(bind_back(transform_base_fn{}, std::move(fun)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates transform_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(transform_fn, transform)
|
||||
} // namespace views
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
namespace views
|
||||
{
|
||||
using ranges::views::transform;
|
||||
}
|
||||
template(typename Rng, typename F)(
|
||||
requires input_range<Rng> AND copy_constructible<F> AND view_<Rng> AND
|
||||
std::is_object<F>::value AND
|
||||
regular_invocable<F &, iter_reference_t<iterator_t<Rng>>>)
|
||||
using transform_view = ranges::transform_view<Rng, F>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::iter_transform_view)
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::transform_view)
|
||||
|
||||
#endif
|
||||
162
Telegram/ThirdParty/range-v3/include/range/v3/view/trim.hpp
vendored
Normal file
162
Telegram/ThirdParty/range-v3/include/range/v3/view/trim.hpp
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Johel Guerrero 2019
|
||||
//
|
||||
// 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_TRIM_HPP
|
||||
#define RANGES_V3_VIEW_TRIM_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/algorithm/find_if_not.hpp>
|
||||
#include <range/v3/detail/config.hpp>
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/compose.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/primitives.hpp>
|
||||
#include <range/v3/utility/optional.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Rng, typename Pred>
|
||||
struct trim_view : view_interface<trim_view<Rng, Pred>>
|
||||
{
|
||||
private:
|
||||
Rng rng_;
|
||||
semiregular_box_t<Pred> pred_;
|
||||
detail::non_propagating_cache<iterator_t<Rng>> begin_;
|
||||
detail::non_propagating_cache<iterator_t<Rng>> end_;
|
||||
|
||||
public:
|
||||
CPP_assert(bidirectional_range<Rng> && view_<Rng> && indirect_unary_predicate<
|
||||
Pred, iterator_t<Rng>> && common_range<Rng>);
|
||||
|
||||
trim_view() = default;
|
||||
constexpr trim_view(Rng rng, Pred pred)
|
||||
: rng_(std::move(rng))
|
||||
, pred_(std::move(pred))
|
||||
{}
|
||||
|
||||
iterator_t<Rng> begin()
|
||||
{
|
||||
if(!begin_)
|
||||
begin_ = find_if_not(rng_, std::ref(pred_));
|
||||
return *begin_;
|
||||
}
|
||||
iterator_t<Rng> end()
|
||||
{
|
||||
if(!end_)
|
||||
{
|
||||
const auto first = begin();
|
||||
auto last = ranges::end(rng_);
|
||||
while(last != first)
|
||||
if(!invoke(pred_, *--last))
|
||||
{
|
||||
++last;
|
||||
break;
|
||||
}
|
||||
end_ = std::move(last);
|
||||
}
|
||||
return *end_;
|
||||
}
|
||||
|
||||
Rng base() const
|
||||
{
|
||||
return rng_;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Rng, typename Pred>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<trim_view<Rng, Pred>> = //
|
||||
enable_borrowed_range<Rng>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename Rng, typename Pred>
|
||||
trim_view(Rng &&, Pred) //
|
||||
-> trim_view<views::all_t<Rng>, Pred>;
|
||||
#endif
|
||||
|
||||
template<typename Rng, typename Pred>
|
||||
RANGES_INLINE_VAR constexpr bool disable_sized_range<trim_view<Rng, Pred>> = true;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct trim_base_fn
|
||||
{
|
||||
template(typename Rng, typename Pred)(
|
||||
requires viewable_range<Rng> AND bidirectional_range<Rng> AND
|
||||
indirect_unary_predicate<Pred, iterator_t<Rng>> AND
|
||||
common_range<Rng>)
|
||||
constexpr trim_view<all_t<Rng>, Pred> //
|
||||
operator()(Rng && rng, Pred pred) const //
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), std::move(pred)};
|
||||
}
|
||||
template(typename Rng, typename Pred, typename Proj)(
|
||||
requires viewable_range<Rng> AND bidirectional_range<Rng> AND
|
||||
indirect_unary_predicate<composed<Pred, Proj>, iterator_t<Rng>> AND
|
||||
common_range<Rng>)
|
||||
constexpr trim_view<all_t<Rng>, composed<Pred, Proj>> //
|
||||
operator()(Rng && rng, Pred pred, Proj proj) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)),
|
||||
compose(std::move(pred), std::move(proj))};
|
||||
}
|
||||
};
|
||||
|
||||
struct trim_bind_fn
|
||||
{
|
||||
template<typename Pred>
|
||||
constexpr auto operator()(Pred pred) const // TODO: underconstrained
|
||||
{
|
||||
return make_view_closure(bind_back(trim_base_fn{}, std::move(pred)));
|
||||
}
|
||||
template(typename Pred, typename Proj)(
|
||||
requires (!range<Pred>)) // TODO: underconstrained
|
||||
constexpr auto operator()(Pred && pred, Proj proj) const
|
||||
{
|
||||
return make_view_closure(bind_back(
|
||||
trim_base_fn{}, static_cast<Pred &&>(pred), std::move(proj)));
|
||||
}
|
||||
};
|
||||
|
||||
struct RANGES_EMPTY_BASES trim_fn
|
||||
: trim_base_fn, trim_bind_fn
|
||||
{
|
||||
using trim_base_fn::operator();
|
||||
using trim_bind_fn::operator();
|
||||
};
|
||||
|
||||
/// \relates trim_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(trim_fn, trim)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::trim_view)
|
||||
|
||||
#endif // RANGES_V3_VIEW_TRIM_HPP
|
||||
74
Telegram/ThirdParty/range-v3/include/range/v3/view/unbounded.hpp
vendored
Normal file
74
Telegram/ThirdParty/range-v3/include/range/v3/view/unbounded.hpp
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_UNBOUNDED_HPP
|
||||
#define RANGES_V3_VIEW_UNBOUNDED_HPP
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/unreachable_sentinel.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/interface.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename I>
|
||||
struct unbounded_view : view_interface<unbounded_view<I>, infinite>
|
||||
{
|
||||
private:
|
||||
I it_;
|
||||
|
||||
public:
|
||||
unbounded_view() = default;
|
||||
constexpr explicit unbounded_view(I it)
|
||||
: it_(detail::move(it))
|
||||
{}
|
||||
constexpr I begin() const
|
||||
{
|
||||
return it_;
|
||||
}
|
||||
constexpr unreachable_sentinel_t end() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<unbounded_view<I>> = true;
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct unbounded_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires input_iterator<I>)
|
||||
constexpr unbounded_view<I> operator()(I it) const
|
||||
{
|
||||
return unbounded_view<I>{detail::move(it)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates unbounded_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(unbounded_fn, unbounded)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::unbounded_view)
|
||||
|
||||
#endif
|
||||
72
Telegram/ThirdParty/range-v3/include/range/v3/view/unique.hpp
vendored
Normal file
72
Telegram/ThirdParty/range-v3/include/range/v3/view/unique.hpp
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_UNIQUE_HPP
|
||||
#define RANGES_V3_VIEW_UNIQUE_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/not_fn.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/view/adjacent_filter.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/view.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
namespace views
|
||||
{
|
||||
struct unique_base_fn
|
||||
{
|
||||
template(typename Rng, typename C = equal_to)(
|
||||
requires viewable_range<Rng> AND forward_range<Rng> AND
|
||||
indirect_relation<C, iterator_t<Rng>>)
|
||||
constexpr adjacent_filter_view<all_t<Rng>, logical_negate<C>> //
|
||||
operator()(Rng && rng, C pred = {}) const
|
||||
{
|
||||
return {all(static_cast<Rng &&>(rng)), not_fn(pred)};
|
||||
}
|
||||
};
|
||||
|
||||
struct unique_fn : unique_base_fn
|
||||
{
|
||||
using unique_base_fn::operator();
|
||||
|
||||
template(typename C)(
|
||||
requires (!range<C>))
|
||||
constexpr auto operator()(C && pred) const
|
||||
{
|
||||
return make_view_closure(
|
||||
bind_back(unique_base_fn{}, static_cast<C &&>(pred)));
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates unique_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(view_closure<unique_fn>, unique)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
289
Telegram/ThirdParty/range-v3/include/range/v3/view/view.hpp
vendored
Normal file
289
Telegram/ThirdParty/range-v3/include/range/v3/view/view.hpp
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
//
|
||||
// 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_VIEW_HPP
|
||||
#define RANGES_V3_VIEW_VIEW_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/compose.hpp>
|
||||
#include <range/v3/functional/concepts.hpp>
|
||||
#include <range/v3/functional/pipeable.hpp>
|
||||
#include <range/v3/functional/reference_wrapper.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
struct dereference_fn
|
||||
{
|
||||
// clang-format off
|
||||
template<typename I>
|
||||
constexpr auto CPP_auto_fun(operator())(I &&i) (const)
|
||||
(
|
||||
return *(I &&) i
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
struct view_closure_base_
|
||||
{};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
// clang-format off
|
||||
/// \concept simple_view_impl_
|
||||
/// \brief The \c simple_view_impl_ concept
|
||||
template(typename Rng)(
|
||||
concept (simple_view_impl_)(Rng),
|
||||
same_as<iterator_t<Rng>, iterator_t<Rng const>> AND
|
||||
same_as<sentinel_t<Rng>, sentinel_t<Rng const>>);
|
||||
|
||||
/// \concept simple_view_
|
||||
/// \brief The \c simple_view_ concept
|
||||
template<typename Rng>
|
||||
CPP_concept simple_view_ =
|
||||
view_<Rng> &&
|
||||
range<Rng const> &&
|
||||
CPP_concept_ref(ranges::simple_view_impl_, Rng);
|
||||
|
||||
/// \concept invocable_view_closure_
|
||||
/// \brief The \c invocable_view_closure_ concept
|
||||
template(typename ViewFn, typename Rng)(
|
||||
concept (invocable_view_closure_)(ViewFn, Rng),
|
||||
!derived_from<invoke_result_t<ViewFn, Rng>, detail::view_closure_base_>);
|
||||
|
||||
/// \concept invocable_view_closure
|
||||
/// \brief The \c invocable_view_closure concept
|
||||
template<typename ViewFn, typename Rng>
|
||||
CPP_concept invocable_view_closure =
|
||||
invocable<ViewFn, Rng> &&
|
||||
CPP_concept_ref(ranges::invocable_view_closure_, ViewFn, Rng);
|
||||
// clang-format on
|
||||
|
||||
template<typename Rng>
|
||||
constexpr bool simple_view() noexcept
|
||||
{
|
||||
return (bool)simple_view_<Rng>;
|
||||
}
|
||||
|
||||
struct make_view_closure_fn
|
||||
{
|
||||
template<typename Fun>
|
||||
constexpr views::view_closure<Fun> operator()(Fun fun) const
|
||||
{
|
||||
return views::view_closure<Fun>{static_cast<Fun &&>(fun)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \ingroup group-views
|
||||
/// \sa make_view_closure_fn
|
||||
RANGES_INLINE_VARIABLE(make_view_closure_fn, make_view_closure)
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct RANGES_STRUCT_WITH_ADL_BARRIER(view_closure_base)
|
||||
: detail::view_closure_base_
|
||||
{
|
||||
// Piping requires viewable_ranges. Pipeing a value into a closure
|
||||
// should not yield another closure.
|
||||
template(typename Rng, typename ViewFn)(
|
||||
requires viewable_range<Rng> AND
|
||||
invocable_view_closure<ViewFn, Rng>)
|
||||
friend constexpr auto operator|(Rng && rng, view_closure<ViewFn> vw)
|
||||
{
|
||||
return static_cast<ViewFn &&>(vw)(static_cast<Rng &&>(rng));
|
||||
}
|
||||
|
||||
#ifndef RANGES_WORKAROUND_CLANG_43400
|
||||
// This overload is deleted because when piping a range into an
|
||||
// view, it must be moved in.
|
||||
template<typename Rng, typename ViewFn> // **************************
|
||||
friend constexpr auto // **************************
|
||||
operator|(Rng &&, view_closure<ViewFn> const &) // ******* READ THIS ********
|
||||
// **** IF YOUR COMPILE *****
|
||||
-> CPP_broken_friend_ret(Rng)( // ****** BREAKS HERE *******
|
||||
requires range<Rng> && // **************************
|
||||
(!viewable_range<Rng>)) = delete; // **************************
|
||||
// **************************************************************************
|
||||
// * When piping a range into an adaptor, the range must satisfy the *
|
||||
// * "viewable_range" concept. A range is viewable when either or both *
|
||||
// * of these things are true: *
|
||||
// * - The range is an lvalue (not a temporary object), OR *
|
||||
// * - The range is a view (not a container). *
|
||||
// **************************************************************************
|
||||
#endif
|
||||
|
||||
template<typename ViewFn, typename Pipeable>
|
||||
friend constexpr auto operator|(view_closure<ViewFn> vw, Pipeable pipe)
|
||||
-> CPP_broken_friend_ret(view_closure<composed<Pipeable, ViewFn>>)(
|
||||
requires (is_pipeable_v<Pipeable>))
|
||||
{
|
||||
return make_view_closure(
|
||||
compose(static_cast<Pipeable &&>(pipe), static_cast<ViewFn &&>(vw)));
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef RANGES_WORKAROUND_CLANG_43400
|
||||
namespace RANGES_ADL_BARRIER_FOR(view_closure_base)
|
||||
{
|
||||
// This overload is deleted because when piping a range into an
|
||||
// view, it must be moved in.
|
||||
template(typename Rng, typename ViewFn)( // ************************
|
||||
requires range<Rng> AND (!viewable_range<Rng>))// ************************
|
||||
constexpr Rng // ************************
|
||||
operator|(Rng &&, view_closure<ViewFn> const &) // ****** READ THIS *******
|
||||
= delete; // *** IF YOUR COMPILE ****
|
||||
// ***** BREAKS HERE ******
|
||||
// ************************
|
||||
// ************************
|
||||
// ***************************************************************************
|
||||
// * When piping a range into an adaptor, the range must satisfy the *
|
||||
// * "viewable_range" concept. A range is viewable when either or both *
|
||||
// * of these things are true: *
|
||||
// * - The range is an lvalue (not a temporary object), OR *
|
||||
// * - The range is a view (not a container). *
|
||||
// ***************************************************************************
|
||||
} // namespace )
|
||||
#endif // RANGES_WORKAROUND_CLANG_43400
|
||||
|
||||
template<typename ViewFn>
|
||||
struct RANGES_EMPTY_BASES view_closure
|
||||
: view_closure_base
|
||||
, ViewFn
|
||||
{
|
||||
view_closure() = default;
|
||||
|
||||
constexpr explicit view_closure(ViewFn fn)
|
||||
: ViewFn(static_cast<ViewFn &&>(fn))
|
||||
{}
|
||||
};
|
||||
|
||||
/// \cond
|
||||
/// DEPRECATED STUFF
|
||||
struct view_access_
|
||||
{
|
||||
template<typename ViewFn>
|
||||
struct impl
|
||||
{
|
||||
// clang-format off
|
||||
template<typename... Ts, typename V = ViewFn>
|
||||
static constexpr auto CPP_auto_fun(bind)(Ts &&... ts)
|
||||
(
|
||||
return V::bind(static_cast<Ts &&>(ts)...)
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
};
|
||||
|
||||
using view_access RANGES_DEPRECATED(
|
||||
"view_access and views::view<> are deprecated. Please "
|
||||
"replace view<> with view_closure<> and discontinue use of view_access.") =
|
||||
view_access_;
|
||||
|
||||
template<typename>
|
||||
struct old_view_;
|
||||
|
||||
struct make_view_fn_
|
||||
{
|
||||
template<typename Fun>
|
||||
constexpr old_view_<Fun> operator()(Fun fun) const
|
||||
{
|
||||
return old_view_<Fun>{static_cast<Fun &&>(fun)};
|
||||
}
|
||||
};
|
||||
using make_view_fn RANGES_DEPRECATED(
|
||||
"make_view_fn is deprecated. Please use "
|
||||
"make_view_closure instead.") = make_view_fn_;
|
||||
|
||||
namespace
|
||||
{
|
||||
RANGES_DEPRECATED(
|
||||
"make_view and views::view<> has been deprecated. Please switch to "
|
||||
"make_view_closure and views::view_closure.")
|
||||
RANGES_INLINE_VAR constexpr auto & make_view =
|
||||
static_const<make_view_fn_>::value;
|
||||
} // namespace
|
||||
|
||||
template<typename ViewFn>
|
||||
struct old_view_ : pipeable_base
|
||||
{
|
||||
private:
|
||||
ViewFn vw_;
|
||||
friend pipeable_access;
|
||||
|
||||
// Piping requires range arguments or lvalue containers.
|
||||
template(typename Rng, typename Vw)(
|
||||
requires viewable_range<Rng> AND invocable<ViewFn &, Rng>)
|
||||
static constexpr auto pipe(Rng && rng, Vw && v)
|
||||
{
|
||||
return v.vw_(static_cast<Rng &&>(rng));
|
||||
}
|
||||
|
||||
public:
|
||||
old_view_() = default;
|
||||
|
||||
constexpr explicit old_view_(ViewFn a) noexcept(
|
||||
std::is_nothrow_move_constructible<ViewFn>::value)
|
||||
: vw_(std::move(a))
|
||||
{}
|
||||
|
||||
// Calling directly requires a viewable_range.
|
||||
template(typename Rng, typename... Rest)(
|
||||
requires viewable_range<Rng> AND invocable<ViewFn const &, Rng, Rest...>)
|
||||
constexpr invoke_result_t<ViewFn const &, Rng, Rest...> //
|
||||
operator()(Rng && rng, Rest &&... rest) const
|
||||
{
|
||||
return vw_(static_cast<Rng &&>(rng), static_cast<Rest &&>(rest)...);
|
||||
}
|
||||
|
||||
// Currying overload.
|
||||
// clang-format off
|
||||
template<typename... Ts, typename V = ViewFn>
|
||||
constexpr auto CPP_auto_fun(operator())(Ts &&... ts)(const)
|
||||
(
|
||||
return make_view_fn_{}(
|
||||
view_access_::impl<V>::bind(vw_, static_cast<Ts &&>(ts)...))
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
template<typename ViewFn>
|
||||
using view RANGES_DEPRECATED(
|
||||
"The views::view<> template is deprecated. Please switch to view_closure") =
|
||||
old_view_<ViewFn>;
|
||||
/// \endcond
|
||||
} // namespace views
|
||||
|
||||
template<typename ViewFn>
|
||||
RANGES_INLINE_VAR constexpr bool is_pipeable_v<views::view_closure<ViewFn>> = true;
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
189
Telegram/ThirdParty/range-v3/include/range/v3/view/zip.hpp
vendored
Normal file
189
Telegram/ThirdParty/range-v3/include/range/v3/view/zip.hpp
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_ZIP_HPP
|
||||
#define RANGES_V3_VIEW_ZIP_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
#include <range/v3/utility/common_tuple.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/empty.hpp>
|
||||
#include <range/v3/view/zip_with.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
struct indirect_zip_fn_
|
||||
{
|
||||
// tuple value
|
||||
template(typename... Its)(
|
||||
requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
|
||||
std::tuple<iter_value_t<Its>...> operator()(copy_tag, Its...) const
|
||||
{
|
||||
RANGES_EXPECT(false);
|
||||
}
|
||||
|
||||
// tuple reference
|
||||
template(typename... Its)(
|
||||
requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
|
||||
common_tuple<iter_reference_t<Its>...>
|
||||
operator()(Its const &... its) const //
|
||||
noexcept(meta::and_c<noexcept(iter_reference_t<Its>(*its))...>::value)
|
||||
{
|
||||
return common_tuple<iter_reference_t<Its>...>{*its...};
|
||||
}
|
||||
|
||||
// tuple rvalue reference
|
||||
template(typename... Its)(
|
||||
requires (sizeof...(Its) != 2) AND and_v<indirectly_readable<Its>...>)
|
||||
common_tuple<iter_rvalue_reference_t<Its>...> //
|
||||
operator()(move_tag, Its const &... its) const //
|
||||
noexcept(meta::and_c<noexcept(
|
||||
iter_rvalue_reference_t<Its>(iter_move(its)))...>::value)
|
||||
{
|
||||
return common_tuple<iter_rvalue_reference_t<Its>...>{iter_move(its)...};
|
||||
}
|
||||
|
||||
// pair value
|
||||
template(typename It1, typename It2)(
|
||||
requires indirectly_readable<It1> AND indirectly_readable<It2>)
|
||||
std::pair<iter_value_t<It1>, iter_value_t<It2>> //
|
||||
operator()(copy_tag, It1, It2) const
|
||||
{
|
||||
RANGES_EXPECT(false);
|
||||
}
|
||||
|
||||
// pair reference
|
||||
template(typename It1, typename It2)(
|
||||
requires indirectly_readable<It1> AND indirectly_readable<It2>)
|
||||
common_pair<iter_reference_t<It1>, iter_reference_t<It2>>
|
||||
operator()(It1 const & it1, It2 const & it2) const //
|
||||
noexcept( //
|
||||
noexcept(iter_reference_t<It1>(*it1)) && //
|
||||
noexcept(iter_reference_t<It2>(*it2)))
|
||||
{
|
||||
return {*it1, *it2};
|
||||
}
|
||||
|
||||
// pair rvalue reference
|
||||
template(typename It1, typename It2)(
|
||||
requires indirectly_readable<It1> AND indirectly_readable<It2>)
|
||||
common_pair<iter_rvalue_reference_t<It1>, iter_rvalue_reference_t<It2>>
|
||||
operator()(move_tag, It1 const & it1, It2 const & it2) const
|
||||
noexcept(noexcept(iter_rvalue_reference_t<It1>(iter_move(it1))) &&
|
||||
noexcept(iter_rvalue_reference_t<It2>(iter_move(it2))))
|
||||
{
|
||||
return {iter_move(it1), iter_move(it2)};
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename... Rngs>
|
||||
struct zip_view : iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>
|
||||
{
|
||||
CPP_assert(sizeof...(Rngs) != 0);
|
||||
|
||||
zip_view() = default;
|
||||
explicit zip_view(Rngs... rngs)
|
||||
: iter_zip_with_view<detail::indirect_zip_fn_, Rngs...>{
|
||||
detail::indirect_zip_fn_{},
|
||||
std::move(rngs)...}
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename... Rng>
|
||||
RANGES_INLINE_VAR constexpr bool enable_borrowed_range<zip_view<Rng...>> =
|
||||
and_v<enable_borrowed_range<Rng>...>;
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template<typename... Rng>
|
||||
zip_view(Rng &&...) //
|
||||
-> zip_view<views::all_t<Rng>...>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct zip_fn
|
||||
{
|
||||
constexpr empty_view<std::tuple<>> operator()() const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
template(typename... Rngs)(
|
||||
requires and_v<viewable_range<Rngs>...> AND
|
||||
and_v<input_range<Rngs>...> AND
|
||||
(sizeof...(Rngs) != 0)) //
|
||||
zip_view<all_t<Rngs>...> operator()(Rngs &&... rngs) const
|
||||
{
|
||||
return zip_view<all_t<Rngs>...>{all(static_cast<Rngs &&>(rngs))...};
|
||||
}
|
||||
#if defined(_MSC_VER)
|
||||
template(typename Rng0)(
|
||||
requires input_range<Rng0> AND viewable_range<Rng0>)
|
||||
constexpr zip_view<all_t<Rng0>> operator()(Rng0 && rng0) const
|
||||
{
|
||||
return zip_view<all_t<Rng0>>{all(static_cast<Rng0 &&>(rng0))};
|
||||
}
|
||||
template(typename Rng0, typename Rng1)(
|
||||
requires input_range<Rng0> AND viewable_range<Rng0> AND
|
||||
input_range<Rng1> AND viewable_range<Rng1>)
|
||||
constexpr zip_view<all_t<Rng0>, all_t<Rng1>> //
|
||||
operator()(Rng0 && rng0, Rng1 && rng1) const
|
||||
{
|
||||
return zip_view<all_t<Rng0>, all_t<Rng1>>{ //
|
||||
all(static_cast<Rng0 &&>(rng0)), //
|
||||
all(static_cast<Rng1 &&>(rng1))};
|
||||
}
|
||||
template(typename Rng0, typename Rng1, typename Rng2)(
|
||||
requires input_range<Rng0> AND viewable_range<Rng0> AND
|
||||
input_range<Rng1> AND viewable_range<Rng1> AND
|
||||
input_range<Rng2> AND viewable_range<Rng2>)
|
||||
constexpr zip_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>> //
|
||||
operator()(Rng0 && rng0, Rng1 && rng1, Rng2 && rng2) const
|
||||
{
|
||||
return zip_view<all_t<Rng0>, all_t<Rng1>, all_t<Rng2>>{ //
|
||||
all(static_cast<Rng0 &&>(rng0)), //
|
||||
all(static_cast<Rng1 &&>(rng1)), //
|
||||
all(static_cast<Rng2 &&>(rng2))};
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/// \relates zip_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(zip_fn, zip)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::zip_view)
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
452
Telegram/ThirdParty/range-v3/include/range/v3/view/zip_with.hpp
vendored
Normal file
452
Telegram/ThirdParty/range-v3/include/range/v3/view/zip_with.hpp
vendored
Normal file
@@ -0,0 +1,452 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
//
|
||||
// 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_ZIP_WITH_HPP
|
||||
#define RANGES_V3_VIEW_ZIP_WITH_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/bind_back.hpp>
|
||||
#include <range/v3/functional/indirect.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/range/access.hpp>
|
||||
#include <range/v3/range/concepts.hpp>
|
||||
#include <range/v3/range/traits.hpp>
|
||||
#include <range/v3/utility/common_type.hpp>
|
||||
#include <range/v3/utility/semiregular_box.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/utility/tuple_algorithm.hpp>
|
||||
#include <range/v3/view/all.hpp>
|
||||
#include <range/v3/view/empty.hpp>
|
||||
#include <range/v3/view/facade.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
struct equal_to_
|
||||
{
|
||||
template<typename T, typename U>
|
||||
bool operator()(T const & t, U const & u) const
|
||||
{
|
||||
return static_cast<bool>(t == u);
|
||||
}
|
||||
};
|
||||
RANGES_INLINE_VARIABLE(equal_to_, equal_to)
|
||||
|
||||
struct dec_
|
||||
{
|
||||
template<typename T>
|
||||
void operator()(T & t) const
|
||||
{
|
||||
--t;
|
||||
}
|
||||
};
|
||||
RANGES_INLINE_VARIABLE(dec_, dec)
|
||||
|
||||
struct inc_
|
||||
{
|
||||
template<typename T>
|
||||
void operator()(T & t) const
|
||||
{
|
||||
++t;
|
||||
}
|
||||
};
|
||||
RANGES_INLINE_VARIABLE(inc_, inc)
|
||||
|
||||
struct _advance_
|
||||
{
|
||||
template(typename I, typename Diff)(
|
||||
requires input_or_output_iterator<I> AND integer_like_<Diff>)
|
||||
void operator()(I & i, Diff n) const
|
||||
{
|
||||
advance(i, static_cast<iter_difference_t<I>>(n));
|
||||
}
|
||||
};
|
||||
RANGES_INLINE_VARIABLE(_advance_, advance_)
|
||||
|
||||
struct distance_to_
|
||||
{
|
||||
template<typename T>
|
||||
constexpr auto operator()(T const & t, T const & u) const -> decltype(u - t)
|
||||
{
|
||||
return u - t;
|
||||
}
|
||||
};
|
||||
RANGES_INLINE_VARIABLE(distance_to_, distance_to)
|
||||
|
||||
struct _min_
|
||||
{
|
||||
template<typename T, typename U>
|
||||
constexpr auto operator()(T const & t, U const & u) const
|
||||
-> decltype(true ? t : u)
|
||||
{
|
||||
return u < t ? u : t;
|
||||
}
|
||||
};
|
||||
RANGES_INLINE_VARIABLE(_min_, min_)
|
||||
|
||||
struct _max_
|
||||
{
|
||||
template<typename T, typename U>
|
||||
constexpr auto operator()(T const & t, U const & u) const
|
||||
-> decltype(true ? u : t)
|
||||
{
|
||||
return u < t ? t : u;
|
||||
}
|
||||
};
|
||||
RANGES_INLINE_VARIABLE(_max_, max_)
|
||||
|
||||
template<typename State, typename Value>
|
||||
using zip_cardinality = std::integral_constant<
|
||||
cardinality,
|
||||
State::value >= 0 && Value::value >= 0
|
||||
? min_(State::value, Value::value)
|
||||
: State::value >=0 && Value::value == infinite
|
||||
? State::value
|
||||
: State::value == infinite && Value::value >= 0
|
||||
? Value::value
|
||||
: State::value == finite || Value::value == finite
|
||||
? finite
|
||||
: State::value == unknown || Value::value == unknown
|
||||
? unknown
|
||||
: infinite>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
namespace views
|
||||
{
|
||||
// clang-format off
|
||||
/// \concept zippable_with_
|
||||
/// \brief The \c zippable_with_ concept
|
||||
template(typename Fun, typename... Rngs)(
|
||||
concept (zippable_with_)(Fun, Rngs...),
|
||||
invocable<Fun&, iterator_t<Rngs>...> AND
|
||||
invocable<Fun&, copy_tag, iterator_t<Rngs>...> AND
|
||||
invocable<Fun&, move_tag, iterator_t<Rngs>...>
|
||||
);
|
||||
/// \concept zippable_with
|
||||
/// \brief The \c zippable_with concept
|
||||
template<typename Fun, typename ...Rngs>
|
||||
CPP_concept zippable_with =
|
||||
and_v<input_range<Rngs>...> &&
|
||||
copy_constructible<Fun> &&
|
||||
CPP_concept_ref(views::zippable_with_, Fun, Rngs...);
|
||||
// clang-format on
|
||||
} // namespace views
|
||||
|
||||
/// \addtogroup group-views
|
||||
/// @{
|
||||
template<typename Fun, typename... Rngs>
|
||||
struct iter_zip_with_view
|
||||
: view_facade<iter_zip_with_view<Fun, Rngs...>,
|
||||
meta::fold<meta::list<range_cardinality<Rngs>...>,
|
||||
std::integral_constant<cardinality, cardinality::infinite>,
|
||||
meta::quote<detail::zip_cardinality>>::value>
|
||||
{
|
||||
private:
|
||||
CPP_assert(sizeof...(Rngs) != 0);
|
||||
friend range_access;
|
||||
|
||||
semiregular_box_t<Fun> fun_;
|
||||
std::tuple<Rngs...> rngs_;
|
||||
using difference_type_ = common_type_t<range_difference_t<Rngs>...>;
|
||||
|
||||
template<bool Const>
|
||||
struct cursor;
|
||||
|
||||
template<bool Const>
|
||||
struct sentinel
|
||||
{
|
||||
private:
|
||||
friend struct cursor<Const>;
|
||||
friend struct sentinel<!Const>;
|
||||
std::tuple<sentinel_t<meta::const_if_c<Const, Rngs>>...> ends_;
|
||||
|
||||
public:
|
||||
sentinel() = default;
|
||||
sentinel(detail::ignore_t,
|
||||
std::tuple<sentinel_t<meta::const_if_c<Const, Rngs>>...> ends)
|
||||
: ends_(std::move(ends))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
sentinel(sentinel<Other> that)
|
||||
: ends_(std::move(that.ends_))
|
||||
{}
|
||||
};
|
||||
|
||||
template<bool Const>
|
||||
struct cursor
|
||||
{
|
||||
private:
|
||||
friend struct cursor<!Const>;
|
||||
using fun_ref_ = semiregular_box_ref_or_val_t<Fun, Const>;
|
||||
fun_ref_ fun_;
|
||||
std::tuple<iterator_t<meta::const_if_c<Const, Rngs>>...> its_;
|
||||
|
||||
public:
|
||||
using difference_type =
|
||||
common_type_t<range_difference_t<meta::const_if_c<Const, Rngs>>...>;
|
||||
using single_pass = meta::or_c<(
|
||||
bool)single_pass_iterator_<iterator_t<meta::const_if_c<Const, Rngs>>>...>;
|
||||
using value_type = detail::decay_t<invoke_result_t<
|
||||
fun_ref_ &, copy_tag, iterator_t<meta::const_if_c<Const, Rngs>>...>>;
|
||||
|
||||
cursor() = default;
|
||||
cursor(fun_ref_ fun,
|
||||
std::tuple<iterator_t<meta::const_if_c<Const, Rngs>>...> its)
|
||||
: fun_(std::move(fun))
|
||||
, its_(std::move(its))
|
||||
{}
|
||||
template(bool Other)(
|
||||
requires Const AND CPP_NOT(Other)) //
|
||||
cursor(cursor<Other> that)
|
||||
: fun_(std::move(that.fun_))
|
||||
, its_(std::move(that.its_))
|
||||
{}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(read)()(const)
|
||||
(
|
||||
return tuple_apply(fun_, its_)
|
||||
)
|
||||
// clang-format on
|
||||
void next()
|
||||
{
|
||||
tuple_for_each(its_, detail::inc);
|
||||
}
|
||||
CPP_member
|
||||
auto equal(cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires and_v<
|
||||
sentinel_for<iterator_t<meta::const_if_c<Const, Rngs>>,
|
||||
iterator_t<meta::const_if_c<Const, Rngs>>>...>)
|
||||
{
|
||||
// By returning true if *any* of the iterators are equal, we allow
|
||||
// zipped ranges to be of different lengths, stopping when the first
|
||||
// one reaches the last.
|
||||
return tuple_foldl(tuple_transform(its_, that.its_, detail::equal_to),
|
||||
false,
|
||||
[](bool a, bool b) { return a || b; });
|
||||
}
|
||||
bool equal(sentinel<Const> const & s) const
|
||||
{
|
||||
// By returning true if *any* of the iterators are equal, we allow
|
||||
// zipped ranges to be of different lengths, stopping when the first
|
||||
// one reaches the last.
|
||||
return tuple_foldl(tuple_transform(its_, s.ends_, detail::equal_to),
|
||||
false,
|
||||
[](bool a, bool b) { return a || b; });
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires and_v<bidirectional_range<meta::const_if_c<Const, Rngs>>...>)
|
||||
{
|
||||
tuple_for_each(its_, detail::dec);
|
||||
}
|
||||
CPP_member
|
||||
auto advance(difference_type n) //
|
||||
-> CPP_ret(void)(
|
||||
requires and_v<random_access_range<meta::const_if_c<Const, Rngs>>...>)
|
||||
{
|
||||
tuple_for_each(its_, bind_back(detail::advance_, n));
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(cursor const & that) const //
|
||||
-> CPP_ret(difference_type)(
|
||||
requires and_v<
|
||||
sized_sentinel_for<iterator_t<meta::const_if_c<Const, Rngs>>,
|
||||
iterator_t<meta::const_if_c<Const, Rngs>>>...>)
|
||||
{
|
||||
// Return the smallest distance (in magnitude) of any of the iterator
|
||||
// pairs. This is to accommodate zippers of sequences of different length.
|
||||
if(0 < std::get<0>(that.its_) - std::get<0>(its_))
|
||||
return tuple_foldl(
|
||||
tuple_transform(its_, that.its_, detail::distance_to),
|
||||
(std::numeric_limits<difference_type>::max)(),
|
||||
detail::min_);
|
||||
else
|
||||
return tuple_foldl(
|
||||
tuple_transform(its_, that.its_, detail::distance_to),
|
||||
(std::numeric_limits<difference_type>::min)(),
|
||||
detail::max_);
|
||||
}
|
||||
// clang-format off
|
||||
template<std::size_t... Is>
|
||||
auto CPP_auto_fun(move_)(meta::index_sequence<Is...>)(const)
|
||||
(
|
||||
return invoke(fun_, move_tag{}, std::get<Is>(its_)...)
|
||||
)
|
||||
// clang-format on
|
||||
auto move() const noexcept(noexcept(std::declval<cursor const &>().move_(
|
||||
meta::make_index_sequence<sizeof...(Rngs)>{})))
|
||||
-> decltype(std::declval<cursor const &>().move_(
|
||||
meta::make_index_sequence<sizeof...(Rngs)>{}))
|
||||
{
|
||||
return move_(meta::make_index_sequence<sizeof...(Rngs)>{});
|
||||
}
|
||||
};
|
||||
|
||||
template<bool Const>
|
||||
using end_cursor_t =
|
||||
meta::if_c<concepts::and_v<(bool)common_range<Rngs>...,
|
||||
!(bool)single_pass_iterator_<iterator_t<Rngs>>...>,
|
||||
cursor<Const>, sentinel<Const>>;
|
||||
|
||||
cursor<false> begin_cursor()
|
||||
{
|
||||
return {fun_, tuple_transform(rngs_, ranges::begin)};
|
||||
}
|
||||
end_cursor_t<false> end_cursor()
|
||||
{
|
||||
return {fun_, tuple_transform(rngs_, ranges::end)};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND and_v<range<Rngs const>...> AND
|
||||
views::zippable_with<Fun, meta::if_c<Const, Rngs const>...>)
|
||||
cursor<Const> begin_cursor() const
|
||||
{
|
||||
return {fun_, tuple_transform(rngs_, ranges::begin)};
|
||||
}
|
||||
template(bool Const = true)(
|
||||
requires Const AND and_v<range<Rngs const>...> AND
|
||||
views::zippable_with<Fun, meta::if_c<Const, Rngs const>...>)
|
||||
end_cursor_t<Const> end_cursor() const
|
||||
{
|
||||
return {fun_, tuple_transform(rngs_, ranges::end)};
|
||||
}
|
||||
|
||||
public:
|
||||
iter_zip_with_view() = default;
|
||||
explicit iter_zip_with_view(Rngs... rngs)
|
||||
: fun_(Fun{})
|
||||
, rngs_{std::move(rngs)...}
|
||||
{}
|
||||
explicit iter_zip_with_view(Fun fun, Rngs... rngs)
|
||||
: fun_(std::move(fun))
|
||||
, rngs_{std::move(rngs)...}
|
||||
{}
|
||||
CPP_auto_member
|
||||
constexpr auto CPP_fun(size)()(const //
|
||||
requires and_v<sized_range<Rngs const>...>)
|
||||
{
|
||||
using size_type = common_type_t<range_size_t<Rngs const>...>;
|
||||
return range_cardinality<iter_zip_with_view>::value >= 0
|
||||
? size_type{(
|
||||
std::size_t)range_cardinality<iter_zip_with_view>::value}
|
||||
: tuple_foldl(tuple_transform(rngs_,
|
||||
[](auto && r) -> size_type {
|
||||
return ranges::size(r);
|
||||
}),
|
||||
(std::numeric_limits<size_type>::max)(),
|
||||
detail::min_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Fun, typename... Rngs>
|
||||
struct zip_with_view : iter_zip_with_view<indirected<Fun>, Rngs...>
|
||||
{
|
||||
CPP_assert(sizeof...(Rngs) != 0);
|
||||
|
||||
zip_with_view() = default;
|
||||
explicit zip_with_view(Rngs... rngs)
|
||||
: iter_zip_with_view<indirected<Fun>, Rngs...>{{Fun{}}, std::move(rngs)...}
|
||||
{}
|
||||
explicit zip_with_view(Fun fun, Rngs... rngs)
|
||||
: iter_zip_with_view<indirected<Fun>, Rngs...>{{std::move(fun)},
|
||||
std::move(rngs)...}
|
||||
{}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
|
||||
template(typename Fun, typename... Rng)(
|
||||
requires copy_constructible<Fun>)
|
||||
zip_with_view(Fun, Rng &&...)
|
||||
-> zip_with_view<Fun, views::all_t<Rng>...>;
|
||||
#endif
|
||||
|
||||
namespace views
|
||||
{
|
||||
struct iter_zip_with_fn
|
||||
{
|
||||
template(typename... Rngs, typename Fun)(
|
||||
requires and_v<viewable_range<Rngs>...> AND
|
||||
zippable_with<Fun, Rngs...> AND (sizeof...(Rngs) != 0)) //
|
||||
iter_zip_with_view<Fun, all_t<Rngs>...> //
|
||||
operator()(Fun fun, Rngs &&... rngs) const
|
||||
{
|
||||
return iter_zip_with_view<Fun, all_t<Rngs>...>{
|
||||
std::move(fun), all(static_cast<Rngs &&>(rngs))...};
|
||||
}
|
||||
|
||||
template(typename Fun)(
|
||||
requires zippable_with<Fun>) //
|
||||
constexpr empty_view<detail::decay_t<invoke_result_t<Fun &>>>
|
||||
operator()(Fun) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates iter_zip_with_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(iter_zip_with_fn, iter_zip_with)
|
||||
|
||||
struct zip_with_fn
|
||||
{
|
||||
template(typename... Rngs, typename Fun)(
|
||||
requires and_v<viewable_range<Rngs>...> AND
|
||||
and_v<input_range<Rngs>...> AND copy_constructible<Fun> AND
|
||||
invocable<Fun &, range_reference_t<Rngs>...> AND
|
||||
(sizeof...(Rngs) != 0)) //
|
||||
zip_with_view<Fun, all_t<Rngs>...> operator()(Fun fun, Rngs &&... rngs) const
|
||||
{
|
||||
return zip_with_view<Fun, all_t<Rngs>...>{
|
||||
std::move(fun), all(static_cast<Rngs &&>(rngs))...};
|
||||
}
|
||||
|
||||
template(typename Fun)(
|
||||
requires copy_constructible<Fun> AND invocable<Fun &>) //
|
||||
constexpr empty_view<detail::decay_t<invoke_result_t<Fun &>>>
|
||||
operator()(Fun) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
/// \relates zip_with_fn
|
||||
/// \ingroup group-views
|
||||
RANGES_INLINE_VARIABLE(zip_with_fn, zip_with)
|
||||
} // namespace views
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#include <range/v3/detail/satisfy_boost_range.hpp>
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::iter_zip_with_view)
|
||||
RANGES_SATISFY_BOOST_RANGE(::ranges::zip_with_view)
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user