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:
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
|
||||
Reference in New Issue
Block a user