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:
304
Telegram/ThirdParty/range-v3/include/range/v3/iterator/access.hpp
vendored
Normal file
304
Telegram/ThirdParty/range-v3/include/range/v3/iterator/access.hpp
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2013-present
|
||||
// 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_ITERATOR_ACCESS_HPP
|
||||
#define RANGES_V3_ITERATOR_ACCESS_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <std/detail/associated_types.hpp>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/utility/move.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
#include <range/v3/utility/swap.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I,
|
||||
#ifdef RANGES_WORKAROUND_MSVC_683388
|
||||
typename R = meta::conditional_t<
|
||||
std::is_pointer<uncvref_t<I>>::value &&
|
||||
std::is_array<std::remove_pointer_t<uncvref_t<I>>>::value,
|
||||
std::add_lvalue_reference_t<std::remove_pointer_t<uncvref_t<I>>>,
|
||||
decltype(*std::declval<I &>())>,
|
||||
#else
|
||||
typename R = decltype(*std::declval<I &>()),
|
||||
#endif
|
||||
typename = R &>
|
||||
using iter_reference_t_ = R;
|
||||
|
||||
#if defined(RANGES_DEEP_STL_INTEGRATION) && RANGES_DEEP_STL_INTEGRATION && \
|
||||
!defined(RANGES_DOXYGEN_INVOKED)
|
||||
template<typename T>
|
||||
using iter_value_t_ =
|
||||
typename meta::conditional_t<
|
||||
is_std_iterator_traits_specialized_v<T>,
|
||||
std::iterator_traits<T>,
|
||||
indirectly_readable_traits<T>>::value_type;
|
||||
#else
|
||||
template<typename T>
|
||||
using iter_value_t_ = typename indirectly_readable_traits<T>::value_type;
|
||||
#endif
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename R>
|
||||
using iter_reference_t = detail::iter_reference_t_<R>;
|
||||
|
||||
template<typename R>
|
||||
using iter_value_t = detail::iter_value_t_<uncvref_t<R>>;
|
||||
|
||||
/// \cond
|
||||
namespace _iter_move_
|
||||
{
|
||||
#if RANGES_BROKEN_CPO_LOOKUP
|
||||
void iter_move(); // unqualified name lookup block
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
decltype(iter_move(std::declval<T>())) try_adl_iter_move_(int);
|
||||
|
||||
template<typename T>
|
||||
void try_adl_iter_move_(long);
|
||||
|
||||
template<typename T>
|
||||
RANGES_INLINE_VAR constexpr bool is_adl_indirectly_movable_v =
|
||||
!RANGES_IS_SAME(void, decltype(_iter_move_::try_adl_iter_move_<T>(42)));
|
||||
|
||||
struct fn
|
||||
{
|
||||
// clang-format off
|
||||
template<typename I,
|
||||
typename = detail::enable_if_t<is_adl_indirectly_movable_v<I &>>>
|
||||
#ifndef RANGES_WORKAROUND_CLANG_23135
|
||||
constexpr
|
||||
#endif // RANGES_WORKAROUND_CLANG_23135
|
||||
auto CPP_auto_fun(operator())(I &&i)(const)
|
||||
(
|
||||
return iter_move(i)
|
||||
)
|
||||
|
||||
template<
|
||||
typename I,
|
||||
typename = detail::enable_if_t<!is_adl_indirectly_movable_v<I &>>,
|
||||
typename R = iter_reference_t<I>>
|
||||
#ifndef RANGES_WORKAROUND_CLANG_23135
|
||||
constexpr
|
||||
#endif // RANGES_WORKAROUND_CLANG_23135
|
||||
auto CPP_auto_fun(operator())(I &&i)(const)
|
||||
(
|
||||
return static_cast<aux::move_t<R>>(aux::move(*i))
|
||||
)
|
||||
// clang-format on
|
||||
};
|
||||
} // namespace _iter_move_
|
||||
/// \endcond
|
||||
|
||||
RANGES_DEFINE_CPO(_iter_move_::fn, iter_move)
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I, typename O>
|
||||
auto is_indirectly_movable_(I & (*i)(), O & (*o)(), iter_value_t<I> * v = nullptr)
|
||||
-> always_<std::true_type,
|
||||
decltype(iter_value_t<I>(iter_move(i()))),
|
||||
decltype(*v = iter_move(i())),
|
||||
decltype(*o() = (iter_value_t<I> &&) * v),
|
||||
decltype(*o() = iter_move(i()))>;
|
||||
template<typename I, typename O>
|
||||
auto is_indirectly_movable_(...) -> std::false_type;
|
||||
|
||||
template<typename I, typename O>
|
||||
auto is_nothrow_indirectly_movable_(iter_value_t<I> * v) -> meta::bool_<
|
||||
noexcept(iter_value_t<I>(iter_move(std::declval<I &>()))) &&
|
||||
noexcept(*v = iter_move(std::declval<I &>())) &&
|
||||
noexcept(*std::declval<O &>() = (iter_value_t<I> &&) * v) &&
|
||||
noexcept(*std::declval<O &>() = iter_move(std::declval<I &>()))>;
|
||||
template<typename I, typename O>
|
||||
auto is_nothrow_indirectly_movable_(...) -> std::false_type;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename I, typename O>
|
||||
RANGES_INLINE_VAR constexpr bool is_indirectly_movable_v =
|
||||
decltype(detail::is_indirectly_movable_<I, O>(nullptr, nullptr))::value;
|
||||
|
||||
template<typename I, typename O>
|
||||
RANGES_INLINE_VAR constexpr bool is_nothrow_indirectly_movable_v =
|
||||
decltype(detail::is_nothrow_indirectly_movable_<I, O>(nullptr))::value;
|
||||
|
||||
template<typename I, typename O>
|
||||
struct is_indirectly_movable : meta::bool_<is_indirectly_movable_v<I, O>>
|
||||
{};
|
||||
|
||||
template<typename I, typename O>
|
||||
struct is_nothrow_indirectly_movable
|
||||
: meta::bool_<is_nothrow_indirectly_movable_v<I, O>>
|
||||
{};
|
||||
|
||||
/// \cond
|
||||
namespace _iter_swap_
|
||||
{
|
||||
struct nope
|
||||
{};
|
||||
|
||||
// Q: Should std::reference_wrapper be considered a proxy wrt swapping rvalues?
|
||||
// A: No. Its operator= is currently defined to reseat the references, so
|
||||
// std::swap(ra, rb) already means something when ra and rb are (lvalue)
|
||||
// reference_wrappers. That reseats the reference wrappers but leaves the
|
||||
// referents unmodified. Treating rvalue reference_wrappers differently would
|
||||
// be confusing.
|
||||
|
||||
// Q: Then why is it OK to "re"-define swap for pairs and tuples of references?
|
||||
// A: Because as defined above, swapping an rvalue tuple of references has the
|
||||
// same semantics as swapping an lvalue tuple of references. Rather than
|
||||
// reseat the references, assignment happens *through* the references.
|
||||
|
||||
// Q: But I have an iterator whose operator* returns an rvalue
|
||||
// std::reference_wrapper<T>. How do I make it model indirectly_swappable?
|
||||
// A: With an overload of iter_swap.
|
||||
|
||||
// Intentionally create an ambiguity with std::iter_swap, which is
|
||||
// unconstrained.
|
||||
template<typename T, typename U>
|
||||
nope iter_swap(T, U) = delete;
|
||||
|
||||
#ifdef RANGES_WORKAROUND_MSVC_895622
|
||||
nope iter_swap();
|
||||
#endif
|
||||
|
||||
template<typename T, typename U>
|
||||
decltype(iter_swap(std::declval<T>(), std::declval<U>())) try_adl_iter_swap_(int);
|
||||
|
||||
template<typename T, typename U>
|
||||
nope try_adl_iter_swap_(long);
|
||||
|
||||
// Test whether an overload of iter_swap for a T and a U can be found
|
||||
// via ADL with the iter_swap overload above participating in the
|
||||
// overload set. This depends on user-defined iter_swap overloads
|
||||
// being a better match than the overload in namespace std.
|
||||
template<typename T, typename U>
|
||||
RANGES_INLINE_VAR constexpr bool is_adl_indirectly_swappable_v =
|
||||
!RANGES_IS_SAME(nope, decltype(_iter_swap_::try_adl_iter_swap_<T, U>(42)));
|
||||
|
||||
struct fn
|
||||
{
|
||||
// *If* a user-defined iter_swap is found via ADL, call that:
|
||||
template<typename T, typename U>
|
||||
constexpr detail::enable_if_t<is_adl_indirectly_swappable_v<T, U>> operator()(
|
||||
T && t, U && u) const noexcept(noexcept(iter_swap((T &&) t, (U &&) u)))
|
||||
{
|
||||
(void)iter_swap((T &&) t, (U &&) u);
|
||||
}
|
||||
|
||||
// *Otherwise*, for readable types with swappable reference
|
||||
// types, call ranges::swap(*a, *b)
|
||||
template<typename I0, typename I1>
|
||||
constexpr detail::enable_if_t<
|
||||
!is_adl_indirectly_swappable_v<I0, I1> &&
|
||||
is_swappable_with<iter_reference_t<I0>, iter_reference_t<I1>>::value>
|
||||
operator()(I0 && a, I1 && b) const noexcept(noexcept(ranges::swap(*a, *b)))
|
||||
{
|
||||
ranges::swap(*a, *b);
|
||||
}
|
||||
|
||||
// *Otherwise*, for readable types that are mutually
|
||||
// indirectly_movable_storable, implement as:
|
||||
// iter_value_t<T0> tmp = iter_move(a);
|
||||
// *a = iter_move(b);
|
||||
// *b = std::move(tmp);
|
||||
template<typename I0, typename I1>
|
||||
constexpr detail::enable_if_t<
|
||||
!is_adl_indirectly_swappable_v<I0, I1> &&
|
||||
!is_swappable_with<iter_reference_t<I0>, iter_reference_t<I1>>::value &&
|
||||
is_indirectly_movable_v<I0, I1> && is_indirectly_movable_v<I1, I0>>
|
||||
operator()(I0 && a, I1 && b) const
|
||||
noexcept(is_nothrow_indirectly_movable_v<I0, I1> &&
|
||||
is_nothrow_indirectly_movable_v<I1, I0>)
|
||||
{
|
||||
iter_value_t<I0> v0 = iter_move(a);
|
||||
*a = iter_move(b);
|
||||
*b = detail::move(v0);
|
||||
}
|
||||
};
|
||||
} // namespace _iter_swap_
|
||||
/// \endcond
|
||||
|
||||
/// \relates _iter_swap_::fn
|
||||
RANGES_DEFINE_CPO(_iter_swap_::fn, iter_swap)
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, typename U>
|
||||
auto is_indirectly_swappable_(T & (*t)(), U & (*u)())
|
||||
-> detail::always_<std::true_type, decltype(iter_swap(t(), u()))>;
|
||||
template<typename T, typename U>
|
||||
auto is_indirectly_swappable_(...) -> std::false_type;
|
||||
|
||||
template<typename T, typename U>
|
||||
auto is_nothrow_indirectly_swappable_(int)
|
||||
-> meta::bool_<noexcept(iter_swap(std::declval<T &>(), std::declval<U &>()))>;
|
||||
template<typename T, typename U>
|
||||
auto is_nothrow_indirectly_swappable_(long) -> std::false_type;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename T, typename U>
|
||||
RANGES_INLINE_VAR constexpr bool is_indirectly_swappable_v =
|
||||
decltype(detail::is_indirectly_swappable_<T, U>(nullptr, nullptr))::value;
|
||||
|
||||
template<typename T, typename U>
|
||||
RANGES_INLINE_VAR constexpr bool is_nothrow_indirectly_swappable_v =
|
||||
decltype(detail::is_nothrow_indirectly_swappable_<T, U>(0))::value;
|
||||
|
||||
template<typename T, typename U>
|
||||
struct is_indirectly_swappable : meta::bool_<is_indirectly_swappable_v<T, U>>
|
||||
{};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct is_nothrow_indirectly_swappable
|
||||
: meta::bool_<is_nothrow_indirectly_swappable_v<T, U>>
|
||||
{};
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::iter_move;
|
||||
using ranges::iter_reference_t;
|
||||
using ranges::iter_swap;
|
||||
using ranges::iter_value_t;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_ACCESS_HPP
|
||||
1038
Telegram/ThirdParty/range-v3/include/range/v3/iterator/basic_iterator.hpp
vendored
Normal file
1038
Telegram/ThirdParty/range-v3/include/range/v3/iterator/basic_iterator.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
462
Telegram/ThirdParty/range-v3/include/range/v3/iterator/common_iterator.hpp
vendored
Normal file
462
Telegram/ThirdParty/range-v3/include/range/v3/iterator/common_iterator.hpp
vendored
Normal file
@@ -0,0 +1,462 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
// 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_ITERATOR_COMMON_ITERATOR_HPP
|
||||
#define RANGES_V3_ITERATOR_COMMON_ITERATOR_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/detail/variant.hpp>
|
||||
#include <range/v3/iterator/basic_iterator.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/utility/common_tuple.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I, typename S>
|
||||
variant<I, S> & cidata(common_iterator<I, S> & that)
|
||||
{
|
||||
return that.data_;
|
||||
}
|
||||
|
||||
template<typename I, typename S>
|
||||
variant<I, S> const & cidata(common_iterator<I, S> const & that)
|
||||
{
|
||||
return that.data_;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
#if RANGES_BROKEN_CPO_LOOKUP
|
||||
namespace _common_iterator_
|
||||
{
|
||||
struct adl_hook
|
||||
{};
|
||||
} // namespace _common_iterator_
|
||||
#endif
|
||||
/// \endcond
|
||||
|
||||
template<typename I, typename S>
|
||||
struct common_iterator
|
||||
#if RANGES_BROKEN_CPO_LOOKUP
|
||||
: private _common_iterator_::adl_hook
|
||||
#endif
|
||||
{
|
||||
private:
|
||||
CPP_assert(input_or_output_iterator<I>);
|
||||
CPP_assert(sentinel_for<S, I>);
|
||||
CPP_assert(!same_as<I, S>);
|
||||
variant<I, S> data_;
|
||||
|
||||
friend variant<I, S> & detail::cidata<>(common_iterator<I, S> &);
|
||||
friend variant<I, S> const & detail::cidata<>(common_iterator<I, S> const &);
|
||||
struct emplace_fn
|
||||
{
|
||||
variant<I, S> * data_;
|
||||
template<typename T, std::size_t N>
|
||||
void operator()(indexed_element<T, N> t) const
|
||||
{
|
||||
ranges::emplace<N>(*data_, t.get());
|
||||
}
|
||||
};
|
||||
struct arrow_proxy_
|
||||
{
|
||||
private:
|
||||
friend common_iterator;
|
||||
iter_value_t<I> keep_;
|
||||
arrow_proxy_(iter_reference_t<I> && x)
|
||||
: keep_(std::move(x))
|
||||
{}
|
||||
|
||||
public:
|
||||
const iter_value_t<I> * operator->() const noexcept
|
||||
{
|
||||
return std::addressof(keep_);
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
static T * operator_arrow_(T * p, int) noexcept
|
||||
{
|
||||
return p;
|
||||
}
|
||||
template<typename J, typename = detail::iter_arrow_t<J const>>
|
||||
static J operator_arrow_(J const & j, int) noexcept(noexcept(J(j)))
|
||||
{
|
||||
return j;
|
||||
}
|
||||
template(typename J, typename R = iter_reference_t<J>)(
|
||||
requires std::is_reference<R>::value) //
|
||||
static meta::_t<std::add_pointer<R>> operator_arrow_(J const & j, long) noexcept
|
||||
{
|
||||
auto && r = *j;
|
||||
return std::addressof(r);
|
||||
}
|
||||
template(typename J, typename V = iter_value_t<J>)(
|
||||
requires constructible_from<V, iter_reference_t<J>>)
|
||||
static arrow_proxy_ operator_arrow_(J const & j, ...) noexcept(noexcept(V(V(*j))))
|
||||
{
|
||||
return arrow_proxy_(*j);
|
||||
}
|
||||
|
||||
public:
|
||||
using difference_type = iter_difference_t<I>;
|
||||
|
||||
common_iterator() = default;
|
||||
common_iterator(I i)
|
||||
: data_(emplaced_index<0>, std::move(i))
|
||||
{}
|
||||
common_iterator(S s)
|
||||
: data_(emplaced_index<1>, std::move(s))
|
||||
{}
|
||||
template(typename I2, typename S2)(
|
||||
requires convertible_to<I2, I> AND convertible_to<S2, S>)
|
||||
common_iterator(common_iterator<I2, S2> const & that)
|
||||
: data_(detail::variant_core_access::make_empty<I, S>())
|
||||
{
|
||||
detail::cidata(that).visit_i(emplace_fn{&data_});
|
||||
}
|
||||
template(typename I2, typename S2)(
|
||||
requires convertible_to<I2, I> AND convertible_to<S2, S>)
|
||||
common_iterator & operator=(common_iterator<I2, S2> const & that)
|
||||
{
|
||||
detail::cidata(that).visit_i(emplace_fn{&data_});
|
||||
return *this;
|
||||
}
|
||||
iter_reference_t<I> operator*() //
|
||||
noexcept(noexcept(iter_reference_t<I>(*std::declval<I &>())))
|
||||
{
|
||||
return *ranges::get<0>(data_);
|
||||
}
|
||||
CPP_member
|
||||
auto operator*() const //
|
||||
noexcept(noexcept(iter_reference_t<I>(*std::declval<I const &>())))
|
||||
-> CPP_ret(iter_reference_t<I>)(
|
||||
requires indirectly_readable<I const>)
|
||||
{
|
||||
return *ranges::get<0>(data_);
|
||||
}
|
||||
template(typename J = I)(
|
||||
requires indirectly_readable<J>)
|
||||
auto operator->() const //
|
||||
noexcept(
|
||||
noexcept(common_iterator::operator_arrow_(std::declval<I const &>(), 42)))
|
||||
-> decltype(common_iterator::operator_arrow_(std::declval<J const &>(), 42))
|
||||
{
|
||||
return common_iterator::operator_arrow_(ranges::get<0>(data_), 42);
|
||||
}
|
||||
common_iterator & operator++()
|
||||
{
|
||||
++ranges::get<0>(data_);
|
||||
return *this;
|
||||
}
|
||||
#ifdef RANGES_WORKAROUND_MSVC_677925
|
||||
template(typename I2 = I)(
|
||||
requires (!forward_iterator<I2>)) //
|
||||
auto operator++(int) //
|
||||
-> decltype(std::declval<I2 &>()++)
|
||||
{
|
||||
return ranges::get<0>(data_)++;
|
||||
}
|
||||
#else // ^^^ workaround ^^^ / vvv no workaround vvv
|
||||
CPP_member
|
||||
auto operator++(int) //
|
||||
-> CPP_ret(decltype(std::declval<I &>()++))(
|
||||
requires (!forward_iterator<I>))
|
||||
{
|
||||
return ranges::get<0>(data_)++;
|
||||
}
|
||||
#endif // RANGES_WORKAROUND_MSVC_677925
|
||||
CPP_member
|
||||
auto operator++(int) //
|
||||
-> CPP_ret(common_iterator)(
|
||||
requires forward_iterator<I>)
|
||||
{
|
||||
return common_iterator(ranges::get<0>(data_)++);
|
||||
}
|
||||
|
||||
#if !RANGES_BROKEN_CPO_LOOKUP
|
||||
template<typename I_ = I>
|
||||
friend constexpr auto iter_move(common_iterator const & i) //
|
||||
noexcept(detail::has_nothrow_iter_move_v<I>)
|
||||
-> CPP_broken_friend_ret(iter_rvalue_reference_t<I>)(
|
||||
requires input_iterator<I_>)
|
||||
{
|
||||
return ranges::iter_move(ranges::get<0>(detail::cidata(i)));
|
||||
}
|
||||
template<typename I2, typename S2>
|
||||
friend auto iter_swap(
|
||||
common_iterator const & x,
|
||||
common_iterator<I2, S2> const &
|
||||
y) noexcept(is_nothrow_indirectly_swappable<I, I2>::value)
|
||||
-> CPP_broken_friend_ret(void)(
|
||||
requires indirectly_swappable<I2, I>)
|
||||
{
|
||||
return ranges::iter_swap(ranges::get<0>(detail::cidata(x)),
|
||||
ranges::get<0>(detail::cidata(y)));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/// \cond
|
||||
#if RANGES_BROKEN_CPO_LOOKUP
|
||||
namespace _common_iterator_
|
||||
{
|
||||
template<typename I, typename S>
|
||||
constexpr auto iter_move(common_iterator<I, S> const & i) noexcept(
|
||||
detail::has_nothrow_iter_move_v<I>)
|
||||
-> CPP_broken_friend_ret(iter_rvalue_reference_t<I>)(
|
||||
requires input_iterator<I>)
|
||||
{
|
||||
return ranges::iter_move(ranges::get<0>(detail::cidata(i)));
|
||||
}
|
||||
template<typename I1, typename S1, typename I2, typename S2>
|
||||
auto iter_swap(common_iterator<I1, S1> const & x,
|
||||
common_iterator<I2, S2> const & y) //
|
||||
noexcept(is_nothrow_indirectly_swappable<I1, I2>::value)
|
||||
-> CPP_broken_friend_ret(void)(
|
||||
requires indirectly_swappable<I1, I2>)
|
||||
{
|
||||
return ranges::iter_swap(ranges::get<0>(detail::cidata(x)),
|
||||
ranges::get<0>(detail::cidata(y)));
|
||||
}
|
||||
} // namespace _common_iterator_
|
||||
#endif
|
||||
/// \endcond
|
||||
|
||||
template(typename I1, typename I2, typename S1, typename S2)(
|
||||
requires sentinel_for<S1, I2> AND sentinel_for<S2, I1> AND
|
||||
(!equality_comparable_with<I1, I2>)) //
|
||||
bool operator==(common_iterator<I1, S1> const & x, common_iterator<I2, S2> const & y)
|
||||
{
|
||||
return detail::cidata(x).index() == 1u ? (detail::cidata(y).index() == 1u ||
|
||||
ranges::get<0>(detail::cidata(y)) ==
|
||||
ranges::get<1>(detail::cidata(x)))
|
||||
: (detail::cidata(y).index() != 1u ||
|
||||
ranges::get<0>(detail::cidata(x)) ==
|
||||
ranges::get<1>(detail::cidata(y)));
|
||||
}
|
||||
|
||||
template(typename I1, typename I2, typename S1, typename S2)(
|
||||
requires sentinel_for<S1, I2> AND sentinel_for<S2, I1> AND
|
||||
equality_comparable_with<I1, I2>)
|
||||
bool operator==(common_iterator<I1, S1> const & x, common_iterator<I2, S2> const & y)
|
||||
{
|
||||
return detail::cidata(x).index() == 1u
|
||||
? (detail::cidata(y).index() == 1u ||
|
||||
ranges::get<0>(detail::cidata(y)) ==
|
||||
ranges::get<1>(detail::cidata(x)))
|
||||
: (detail::cidata(y).index() == 1u
|
||||
? ranges::get<0>(detail::cidata(x)) ==
|
||||
ranges::get<1>(detail::cidata(y))
|
||||
: ranges::get<0>(detail::cidata(x)) ==
|
||||
ranges::get<0>(detail::cidata(y)));
|
||||
}
|
||||
|
||||
template(typename I1, typename I2, typename S1, typename S2)(
|
||||
requires sentinel_for<S1, I2> AND sentinel_for<S2, I1>)
|
||||
bool operator!=(common_iterator<I1, S1> const & x, common_iterator<I2, S2> const & y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template(typename I1, typename I2, typename S1, typename S2)(
|
||||
requires sized_sentinel_for<I1, I2> AND sized_sentinel_for<S1, I2> AND
|
||||
sized_sentinel_for<S2, I1>)
|
||||
iter_difference_t<I2> operator-(common_iterator<I1, S1> const & x,
|
||||
common_iterator<I2, S2> const & y)
|
||||
{
|
||||
return detail::cidata(x).index() == 1u
|
||||
? (detail::cidata(y).index() == 1u
|
||||
? 0
|
||||
: ranges::get<1>(detail::cidata(x)) -
|
||||
ranges::get<0>(detail::cidata(y)))
|
||||
: (detail::cidata(y).index() == 1u
|
||||
? ranges::get<0>(detail::cidata(x)) -
|
||||
ranges::get<1>(detail::cidata(y))
|
||||
: ranges::get<0>(detail::cidata(x)) -
|
||||
ranges::get<0>(detail::cidata(y)));
|
||||
}
|
||||
|
||||
template<typename I, typename S>
|
||||
struct indirectly_readable_traits<common_iterator<I, S>>
|
||||
: meta::if_c<
|
||||
(bool)indirectly_readable<I>,
|
||||
indirectly_readable_traits<I>,
|
||||
meta::nil_>
|
||||
{};
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I>
|
||||
auto demote_common_iter_cat(...) -> nil_;
|
||||
template<typename I>
|
||||
auto demote_common_iter_cat(long)
|
||||
-> with_iterator_category<std::input_iterator_tag>;
|
||||
template(typename I)(
|
||||
requires derived_from<typename std::iterator_traits<I>::iterator_category,
|
||||
std::forward_iterator_tag>)
|
||||
auto demote_common_iter_cat(int)
|
||||
-> with_iterator_category<std::forward_iterator_tag>;
|
||||
|
||||
template<typename I, bool = (bool)input_iterator<I>>
|
||||
struct common_iterator_std_traits : decltype(detail::demote_common_iter_cat<I>(0))
|
||||
{
|
||||
using difference_type = iter_difference_t<I>;
|
||||
using value_type = iter_value_t<I>;
|
||||
using reference = iter_reference_t<I>;
|
||||
using pointer = detail::iter_pointer_t<I>;
|
||||
using iterator_concept =
|
||||
meta::conditional_t<(bool)forward_iterator<I>, std::forward_iterator_tag,
|
||||
std::input_iterator_tag>;
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
struct common_iterator_std_traits<I, false>
|
||||
{
|
||||
using difference_type = iter_difference_t<I>;
|
||||
using value_type = void;
|
||||
using reference = void;
|
||||
using pointer = void;
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
};
|
||||
|
||||
// An iterator adaptor that demotes a user-defined difference_type to
|
||||
// std::intmax_t, for use when constructing containers from such
|
||||
// iterators.
|
||||
template<typename I>
|
||||
struct cpp17_iterator_cursor
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
I it_;
|
||||
struct mixin : basic_mixin<cpp17_iterator_cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
#ifndef _MSC_VER
|
||||
using basic_mixin<cpp17_iterator_cursor>::basic_mixin;
|
||||
#else
|
||||
constexpr explicit mixin(cpp17_iterator_cursor && cur)
|
||||
: basic_mixin<cpp17_iterator_cursor>(
|
||||
static_cast<cpp17_iterator_cursor &&>(cur))
|
||||
{}
|
||||
constexpr explicit mixin(cpp17_iterator_cursor const & cur)
|
||||
: basic_mixin<cpp17_iterator_cursor>(cur)
|
||||
{}
|
||||
#endif
|
||||
explicit mixin(I it)
|
||||
: mixin{cpp17_iterator_cursor{std::move(it)}}
|
||||
{}
|
||||
I base() const
|
||||
{
|
||||
return this->get().it_;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
using single_pass = meta::bool_<!forward_iterator<I>>;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = iter_value_t<I>;
|
||||
|
||||
cpp17_iterator_cursor() = default;
|
||||
constexpr explicit cpp17_iterator_cursor(I i)
|
||||
: it_(static_cast<I &&>(i))
|
||||
{}
|
||||
|
||||
I arrow() const
|
||||
{
|
||||
return it_;
|
||||
}
|
||||
decltype(auto) read()
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
decltype(auto) read() const
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
bool equal(cpp17_iterator_cursor const & that) const
|
||||
{
|
||||
return it_ == that.it_;
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_iterator<I>)
|
||||
{
|
||||
--it_;
|
||||
}
|
||||
CPP_member
|
||||
auto advance(std::ptrdiff_t n) //
|
||||
-> CPP_ret(void)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
it_ += static_cast<iter_difference_t<I>>(n);
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(cpp17_iterator_cursor const & that) //
|
||||
-> CPP_ret(std::ptrdiff_t)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
auto d = that.it_ - it_;
|
||||
RANGES_EXPECT(d <= PTRDIFF_MAX);
|
||||
return static_cast<std::ptrdiff_t>(d);
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::common_iterator;
|
||||
}
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
/// \cond
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename I, typename S>
|
||||
struct iterator_traits<::ranges::common_iterator<I, S>>
|
||||
: ::ranges::detail::common_iterator_std_traits<I>
|
||||
{};
|
||||
} // namespace std
|
||||
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
/// \endcond
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
990
Telegram/ThirdParty/range-v3/include/range/v3/iterator/concepts.hpp
vendored
Normal file
990
Telegram/ThirdParty/range-v3/include/range/v3/iterator/concepts.hpp
vendored
Normal file
@@ -0,0 +1,990 @@
|
||||
/// \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_ITERATOR_CONCEPTS_HPP
|
||||
#define RANGES_V3_ITERATOR_CONCEPTS_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/functional/comparisons.hpp>
|
||||
#include <range/v3/functional/concepts.hpp>
|
||||
#include <range/v3/functional/identity.hpp>
|
||||
#include <range/v3/functional/invoke.hpp>
|
||||
#include <range/v3/iterator/access.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
|
||||
#ifdef _GLIBCXX_DEBUG
|
||||
#include <debug/safe_iterator.h>
|
||||
#endif
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator-concepts
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I>
|
||||
using iter_traits_t = meta::conditional_t<is_std_iterator_traits_specialized_v<I>,
|
||||
std::iterator_traits<I>, I>;
|
||||
|
||||
#if defined(_GLIBCXX_DEBUG)
|
||||
template(typename I, typename T, typename Seq)(
|
||||
requires same_as<I, __gnu_debug::_Safe_iterator<T *, Seq>>)
|
||||
auto iter_concept_(__gnu_debug::_Safe_iterator<T *, Seq>, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
#endif
|
||||
#if defined(__GLIBCXX__)
|
||||
template(typename I, typename T, typename Seq)(
|
||||
requires same_as<I, __gnu_cxx::__normal_iterator<T *, Seq>>)
|
||||
auto iter_concept_(__gnu_cxx::__normal_iterator<T *, Seq>, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
#endif
|
||||
#if defined(_LIBCPP_VERSION)
|
||||
template(typename I, typename T)(
|
||||
requires same_as<I, std::__wrap_iter<T *>>)
|
||||
auto iter_concept_(std::__wrap_iter<T *>, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
#endif
|
||||
#if defined(_MSVC_STL_VERSION) || defined(_IS_WRS)
|
||||
template(typename I)(
|
||||
requires same_as<I, class I::_Array_iterator>)
|
||||
auto iter_concept_(I, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
template(typename I)(
|
||||
requires same_as<I, class I::_Array_const_iterator>)
|
||||
auto iter_concept_(I, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
template(typename I)(
|
||||
requires same_as<I, class I::_Vector_iterator>)
|
||||
auto iter_concept_(I, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
template(typename I)(
|
||||
requires same_as<I, class I::_Vector_const_iterator>)
|
||||
auto iter_concept_(I, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
template(typename I)(
|
||||
requires same_as<I, class I::_String_iterator>)
|
||||
auto iter_concept_(I, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
template(typename I)(
|
||||
requires same_as<I, class I::_String_const_iterator>)
|
||||
auto iter_concept_(I, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
template(typename I)(
|
||||
requires same_as<I, class I::_String_view_iterator>)
|
||||
auto iter_concept_(I, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
#endif
|
||||
template(typename I, typename T)(
|
||||
requires same_as<I, T *>)
|
||||
auto iter_concept_(T *, priority_tag<3>)
|
||||
-> ranges::contiguous_iterator_tag;
|
||||
template<typename I>
|
||||
auto iter_concept_(I, priority_tag<2>) ->
|
||||
typename iter_traits_t<I>::iterator_concept;
|
||||
template<typename I>
|
||||
auto iter_concept_(I, priority_tag<1>) ->
|
||||
typename iter_traits_t<I>::iterator_category;
|
||||
template<typename I>
|
||||
auto iter_concept_(I, priority_tag<0>)
|
||||
-> enable_if_t<!is_std_iterator_traits_specialized_v<I>,
|
||||
std::random_access_iterator_tag>;
|
||||
|
||||
template<typename I>
|
||||
using iter_concept_t =
|
||||
decltype(iter_concept_<I>(std::declval<I>(), priority_tag<3>{}));
|
||||
|
||||
using ::concepts::detail::weakly_equality_comparable_with_;
|
||||
|
||||
template<typename I>
|
||||
using readable_types_t =
|
||||
meta::list<iter_value_t<I>, iter_reference_t<I>, iter_rvalue_reference_t<I>>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
// clang-format off
|
||||
/// \concept readable_
|
||||
/// \brief The \c readable_ concept
|
||||
template(typename I)(
|
||||
concept (readable_)(I),
|
||||
// requires (I const i)
|
||||
// (
|
||||
// { *i } -> same_as<iter_reference_t<I>>;
|
||||
// { iter_move(i) } -> same_as<iter_rvalue_reference_t<I>>;
|
||||
// ) &&
|
||||
same_as<iter_reference_t<I const>, iter_reference_t<I>> AND
|
||||
same_as<iter_rvalue_reference_t<I const>, iter_rvalue_reference_t<I>> AND
|
||||
common_reference_with<iter_reference_t<I> &&, iter_value_t<I> &> AND
|
||||
common_reference_with<iter_reference_t<I> &&,
|
||||
iter_rvalue_reference_t<I> &&> AND
|
||||
common_reference_with<iter_rvalue_reference_t<I> &&, iter_value_t<I> const &>
|
||||
);
|
||||
|
||||
/// \concept indirectly_readable
|
||||
/// \brief The \c indirectly_readable concept
|
||||
template<typename I>
|
||||
CPP_concept indirectly_readable = //
|
||||
CPP_concept_ref(ranges::readable_, uncvref_t<I>);
|
||||
|
||||
template<typename I>
|
||||
RANGES_DEPRECATED("Please use ranges::indirectly_readable instead")
|
||||
RANGES_INLINE_VAR constexpr bool readable = //
|
||||
indirectly_readable<I>;
|
||||
|
||||
/// \concept writable_
|
||||
/// \brief The \c writable_ concept
|
||||
template<typename O, typename T>
|
||||
CPP_requires(writable_,
|
||||
requires(O && o, T && t) //
|
||||
(
|
||||
*o = (T &&) t,
|
||||
*(O &&) o = (T &&) t,
|
||||
const_cast<iter_reference_t<O> const &&>(*o) = (T &&) t,
|
||||
const_cast<iter_reference_t<O> const &&>(*(O &&) o) = (T &&) t
|
||||
));
|
||||
/// \concept indirectly_writable
|
||||
/// \brief The \c indirectly_writable concept
|
||||
template<typename O, typename T>
|
||||
CPP_concept indirectly_writable = //
|
||||
CPP_requires_ref(ranges::writable_, O, T);
|
||||
|
||||
template<typename O, typename T>
|
||||
RANGES_DEPRECATED("Please use ranges::indirectly_writable instead")
|
||||
RANGES_INLINE_VAR constexpr bool writable = //
|
||||
indirectly_writable<O, T>;
|
||||
// clang-format on
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
#if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
|
||||
template<typename D>
|
||||
inline constexpr bool _is_integer_like_ = std::is_integral<D>::value;
|
||||
#else
|
||||
template<typename D, typename = void>
|
||||
constexpr bool _is_integer_like_ = std::is_integral<D>::value;
|
||||
#endif
|
||||
|
||||
// gcc10 uses for std::ranges::range_difference_t<
|
||||
// std::ranges::iota_view<size_t, size_t>> == __int128
|
||||
#if __SIZEOF_INT128__
|
||||
__extension__ typedef __int128 int128_t;
|
||||
#if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
|
||||
template<>
|
||||
inline constexpr bool _is_integer_like_<int128_t> = true;
|
||||
#else
|
||||
template<typename Enable>
|
||||
constexpr bool _is_integer_like_<int128_t, Enable> = true;
|
||||
#endif
|
||||
#endif // __SIZEOF_INT128__
|
||||
|
||||
// clang-format off
|
||||
/// \concept integer_like_
|
||||
/// \brief The \c integer_like_ concept
|
||||
template<typename D>
|
||||
CPP_concept integer_like_ = _is_integer_like_<D>;
|
||||
// TODO additional syntactic and semantic requirements
|
||||
|
||||
#ifdef RANGES_WORKAROUND_MSVC_792338
|
||||
template<typename D, bool Signed = (D(-1) < D(0))>
|
||||
constexpr bool _is_signed_(D *)
|
||||
{
|
||||
return Signed;
|
||||
}
|
||||
constexpr bool _is_signed_(void *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \concept signed_integer_like_
|
||||
/// \brief The \c signed_integer_like_ concept
|
||||
template<typename D>
|
||||
CPP_concept signed_integer_like_ =
|
||||
integer_like_<D> && detail::_is_signed_((D*) nullptr);
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
/// \concept signed_integer_like_impl_
|
||||
/// \brief The \c signed_integer_like_impl_ concept
|
||||
template(typename D)(
|
||||
concept (signed_integer_like_impl_)(D),
|
||||
integer_like_<D> AND
|
||||
concepts::type<std::integral_constant<bool, (D(-1) < D(0))>> AND
|
||||
std::integral_constant<bool, (D(-1) < D(0))>::value
|
||||
);
|
||||
|
||||
/// \concept signed_integer_like_
|
||||
/// \brief The \c signed_integer_like_ concept
|
||||
template<typename D>
|
||||
CPP_concept signed_integer_like_ =
|
||||
integer_like_<D> &&
|
||||
CPP_concept_ref(detail::signed_integer_like_impl_, D);
|
||||
#endif // RANGES_WORKAROUND_MSVC_792338
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
// clang-format off
|
||||
/// \concept weakly_incrementable_
|
||||
/// \brief The \c weakly_incrementable_ concept
|
||||
template<typename I>
|
||||
CPP_requires(weakly_incrementable_,
|
||||
requires(I i) //
|
||||
(
|
||||
++i,
|
||||
i++,
|
||||
concepts::requires_<same_as<I&, decltype(++i)>>
|
||||
));
|
||||
|
||||
/// \concept weakly_incrementable_
|
||||
/// \brief The \c weakly_incrementable_ concept
|
||||
template(typename I)(
|
||||
concept (weakly_incrementable_)(I),
|
||||
concepts::type<iter_difference_t<I>> AND
|
||||
detail::signed_integer_like_<iter_difference_t<I>>);
|
||||
|
||||
/// \concept weakly_incrementable
|
||||
/// \brief The \c weakly_incrementable concept
|
||||
template<typename I>
|
||||
CPP_concept weakly_incrementable =
|
||||
copyable<I> &&
|
||||
CPP_requires_ref(ranges::weakly_incrementable_, I) &&
|
||||
CPP_concept_ref(ranges::weakly_incrementable_, I);
|
||||
|
||||
/// \concept incrementable_
|
||||
/// \brief The \c incrementable_ concept
|
||||
template<typename I>
|
||||
CPP_requires(incrementable_,
|
||||
requires(I i) //
|
||||
(
|
||||
concepts::requires_<same_as<I, decltype(i++)>>
|
||||
));
|
||||
/// \concept incrementable
|
||||
/// \brief The \c incrementable concept
|
||||
template<typename I>
|
||||
CPP_concept incrementable =
|
||||
regular<I> &&
|
||||
weakly_incrementable<I> &&
|
||||
CPP_requires_ref(ranges::incrementable_, I);
|
||||
|
||||
/// \concept input_or_output_iterator_
|
||||
/// \brief The \c input_or_output_iterator_ concept
|
||||
template(typename I)(
|
||||
concept (input_or_output_iterator_)(I),
|
||||
detail::dereferenceable_<I&>
|
||||
);
|
||||
|
||||
/// \concept input_or_output_iterator
|
||||
/// \brief The \c input_or_output_iterator concept
|
||||
template<typename I>
|
||||
CPP_concept input_or_output_iterator =
|
||||
weakly_incrementable<I> &&
|
||||
CPP_concept_ref(ranges::input_or_output_iterator_, I);
|
||||
|
||||
/// \concept sentinel_for
|
||||
/// \brief The \c sentinel_for concept
|
||||
template<typename S, typename I>
|
||||
CPP_concept sentinel_for =
|
||||
semiregular<S> &&
|
||||
input_or_output_iterator<I> &&
|
||||
detail::weakly_equality_comparable_with_<S, I>;
|
||||
|
||||
/// \concept sized_sentinel_for_
|
||||
/// \brief The \c sized_sentinel_for_ concept
|
||||
template<typename S, typename I>
|
||||
CPP_requires(sized_sentinel_for_,
|
||||
requires(S const & s, I const & i) //
|
||||
(
|
||||
s - i,
|
||||
i - s,
|
||||
concepts::requires_<same_as<iter_difference_t<I>, decltype(s - i)>>,
|
||||
concepts::requires_<same_as<iter_difference_t<I>, decltype(i - s)>>
|
||||
));
|
||||
/// \concept sized_sentinel_for_
|
||||
/// \brief The \c sized_sentinel_for_ concept
|
||||
template(typename S, typename I)(
|
||||
concept (sized_sentinel_for_)(S, I),
|
||||
(!disable_sized_sentinel<std::remove_cv_t<S>, std::remove_cv_t<I>>) AND
|
||||
sentinel_for<S, I>);
|
||||
|
||||
/// \concept sized_sentinel_for
|
||||
/// \brief The \c sized_sentinel_for concept
|
||||
template<typename S, typename I>
|
||||
CPP_concept sized_sentinel_for =
|
||||
CPP_concept_ref(sized_sentinel_for_, S, I) &&
|
||||
CPP_requires_ref(ranges::sized_sentinel_for_, S, I);
|
||||
|
||||
/// \concept output_iterator_
|
||||
/// \brief The \c output_iterator_ concept
|
||||
template<typename Out, typename T>
|
||||
CPP_requires(output_iterator_,
|
||||
requires(Out o, T && t) //
|
||||
(
|
||||
*o++ = (T &&) t
|
||||
));
|
||||
/// \concept output_iterator
|
||||
/// \brief The \c output_iterator concept
|
||||
template<typename Out, typename T>
|
||||
CPP_concept output_iterator =
|
||||
input_or_output_iterator<Out> &&
|
||||
indirectly_writable<Out, T> &&
|
||||
CPP_requires_ref(ranges::output_iterator_, Out, T);
|
||||
|
||||
/// \concept with_category_
|
||||
/// \brief The \c with_category_ concept
|
||||
template(typename I, typename Tag)(
|
||||
concept (with_category_)(I, Tag),
|
||||
derived_from<detail::iter_concept_t<I>, Tag>
|
||||
);
|
||||
|
||||
/// \concept input_iterator
|
||||
/// \brief The \c input_iterator concept
|
||||
template<typename I>
|
||||
CPP_concept input_iterator =
|
||||
input_or_output_iterator<I> &&
|
||||
indirectly_readable<I> &&
|
||||
CPP_concept_ref(ranges::with_category_, I, std::input_iterator_tag);
|
||||
|
||||
/// \concept forward_iterator
|
||||
/// \brief The \c forward_iterator concept
|
||||
template<typename I>
|
||||
CPP_concept forward_iterator =
|
||||
input_iterator<I> &&
|
||||
incrementable<I> &&
|
||||
sentinel_for<I, I> &&
|
||||
CPP_concept_ref(ranges::with_category_, I, std::forward_iterator_tag);
|
||||
|
||||
/// \concept bidirectional_iterator_
|
||||
/// \brief The \c bidirectional_iterator_ concept
|
||||
template<typename I>
|
||||
CPP_requires(bidirectional_iterator_,
|
||||
requires(I i) //
|
||||
(
|
||||
--i,
|
||||
i--,
|
||||
concepts::requires_<same_as<I&, decltype(--i)>>,
|
||||
concepts::requires_<same_as<I, decltype(i--)>>
|
||||
));
|
||||
/// \concept bidirectional_iterator
|
||||
/// \brief The \c bidirectional_iterator concept
|
||||
template<typename I>
|
||||
CPP_concept bidirectional_iterator =
|
||||
forward_iterator<I> &&
|
||||
CPP_requires_ref(ranges::bidirectional_iterator_, I) &&
|
||||
CPP_concept_ref(ranges::with_category_, I, std::bidirectional_iterator_tag);
|
||||
|
||||
/// \concept random_access_iterator_
|
||||
/// \brief The \c random_access_iterator_ concept
|
||||
template<typename I>
|
||||
CPP_requires(random_access_iterator_,
|
||||
requires(I i, iter_difference_t<I> n)
|
||||
(
|
||||
i + n,
|
||||
n + i,
|
||||
i - n,
|
||||
i += n,
|
||||
i -= n,
|
||||
concepts::requires_<same_as<decltype(i + n), I>>,
|
||||
concepts::requires_<same_as<decltype(n + i), I>>,
|
||||
concepts::requires_<same_as<decltype(i - n), I>>,
|
||||
concepts::requires_<same_as<decltype(i += n), I&>>,
|
||||
concepts::requires_<same_as<decltype(i -= n), I&>>,
|
||||
concepts::requires_<same_as<decltype(i[n]), iter_reference_t<I>>>
|
||||
));
|
||||
/// \concept random_access_iterator
|
||||
/// \brief The \c random_access_iterator concept
|
||||
template<typename I>
|
||||
CPP_concept random_access_iterator =
|
||||
bidirectional_iterator<I> &&
|
||||
totally_ordered<I> &&
|
||||
sized_sentinel_for<I, I> &&
|
||||
CPP_requires_ref(ranges::random_access_iterator_, I) &&
|
||||
CPP_concept_ref(ranges::with_category_, I, std::random_access_iterator_tag);
|
||||
|
||||
/// \concept contiguous_iterator_
|
||||
/// \brief The \c contiguous_iterator_ concept
|
||||
template(typename I)(
|
||||
concept (contiguous_iterator_)(I),
|
||||
std::is_lvalue_reference<iter_reference_t<I>>::value AND
|
||||
same_as<iter_value_t<I>, uncvref_t<iter_reference_t<I>>> AND
|
||||
derived_from<detail::iter_concept_t<I>, ranges::contiguous_iterator_tag>
|
||||
);
|
||||
|
||||
/// \concept contiguous_iterator
|
||||
/// \brief The \c contiguous_iterator concept
|
||||
template<typename I>
|
||||
CPP_concept contiguous_iterator =
|
||||
random_access_iterator<I> &&
|
||||
CPP_concept_ref(ranges::contiguous_iterator_, I);
|
||||
// clang-format on
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
// iterator_tag_of
|
||||
template<typename Rng>
|
||||
using iterator_tag_of = //
|
||||
std::enable_if_t< //
|
||||
input_iterator<Rng>, //
|
||||
meta::conditional_t< //
|
||||
contiguous_iterator<Rng>, //
|
||||
ranges::contiguous_iterator_tag, //
|
||||
meta::conditional_t< //
|
||||
random_access_iterator<Rng>, //
|
||||
std::random_access_iterator_tag, //
|
||||
meta::conditional_t< //
|
||||
bidirectional_iterator<Rng>, //
|
||||
std::bidirectional_iterator_tag, //
|
||||
meta::conditional_t< //
|
||||
forward_iterator<Rng>, //
|
||||
std::forward_iterator_tag, //
|
||||
std::input_iterator_tag>>>>>;
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename, bool>
|
||||
struct iterator_category_
|
||||
{};
|
||||
|
||||
template<typename I>
|
||||
struct iterator_category_<I, true>
|
||||
{
|
||||
using type = iterator_tag_of<I>;
|
||||
};
|
||||
|
||||
template<typename T, typename U = meta::_t<std::remove_const<T>>>
|
||||
using iterator_category = iterator_category_<U, (bool)input_iterator<U>>;
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
/// \cond
|
||||
// Generally useful to know if an iterator is single-pass or not:
|
||||
// clang-format off
|
||||
/// \concept single_pass_iterator_
|
||||
/// \brief The \c single_pass_iterator_ concept
|
||||
template<typename I>
|
||||
CPP_concept single_pass_iterator_ =
|
||||
input_or_output_iterator<I> && !forward_iterator<I>;
|
||||
// clang-format on
|
||||
/// \endcond
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// indirect_result_t
|
||||
template<typename Fun, typename... Is>
|
||||
using indirect_result_t =
|
||||
detail::enable_if_t<(bool)and_v<(bool)indirectly_readable<Is>...>,
|
||||
invoke_result_t<Fun, iter_reference_t<Is>...>>;
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
// clang-format off
|
||||
/// \concept common_reference_with_4_impl_
|
||||
/// \brief The \c common_reference_with_4_impl_ concept
|
||||
template(typename T1, typename T2, typename T3, typename T4)(
|
||||
concept (common_reference_with_4_impl_)(T1, T2, T3, T4),
|
||||
concepts::type<common_reference_t<T1, T2, T3, T4>> AND
|
||||
convertible_to<T1, common_reference_t<T1, T2, T3, T4>> AND
|
||||
convertible_to<T2, common_reference_t<T1, T2, T3, T4>> AND
|
||||
convertible_to<T3, common_reference_t<T1, T2, T3, T4>> AND
|
||||
convertible_to<T4, common_reference_t<T1, T2, T3, T4>>
|
||||
);
|
||||
|
||||
/// \concept common_reference_with_4_
|
||||
/// \brief The \c common_reference_with_4_ concept
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
CPP_concept common_reference_with_4_ =
|
||||
CPP_concept_ref(detail::common_reference_with_4_impl_, T1, T2, T3, T4);
|
||||
// axiom: all permutations of T1,T2,T3,T4 have the same
|
||||
// common reference type.
|
||||
|
||||
/// \concept indirectly_unary_invocable_impl_
|
||||
/// \brief The \c indirectly_unary_invocable_impl_ concept
|
||||
template(typename F, typename I)(
|
||||
concept (indirectly_unary_invocable_impl_)(F, I),
|
||||
invocable<F &, iter_value_t<I> &> AND
|
||||
invocable<F &, iter_reference_t<I>> AND
|
||||
invocable<F &, iter_common_reference_t<I>> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<F &, iter_value_t<I> &>,
|
||||
invoke_result_t<F &, iter_reference_t<I>>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_unary_invocable_
|
||||
/// \brief The \c indirectly_unary_invocable_ concept
|
||||
template<typename F, typename I>
|
||||
CPP_concept indirectly_unary_invocable_ =
|
||||
indirectly_readable<I> &&
|
||||
CPP_concept_ref(detail::indirectly_unary_invocable_impl_, F, I);
|
||||
// clang-format on
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
// clang-format off
|
||||
/// \concept indirectly_unary_invocable
|
||||
/// \brief The \c indirectly_unary_invocable concept
|
||||
template<typename F, typename I>
|
||||
CPP_concept indirectly_unary_invocable =
|
||||
detail::indirectly_unary_invocable_<F, I> &&
|
||||
copy_constructible<F>;
|
||||
|
||||
/// \concept indirectly_regular_unary_invocable_
|
||||
/// \brief The \c indirectly_regular_unary_invocable_ concept
|
||||
template(typename F, typename I)(
|
||||
concept (indirectly_regular_unary_invocable_)(F, I),
|
||||
regular_invocable<F &, iter_value_t<I> &> AND
|
||||
regular_invocable<F &, iter_reference_t<I>> AND
|
||||
regular_invocable<F &, iter_common_reference_t<I>> AND
|
||||
common_reference_with<
|
||||
invoke_result_t<F &, iter_value_t<I> &>,
|
||||
invoke_result_t<F &, iter_reference_t<I>>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_regular_unary_invocable
|
||||
/// \brief The \c indirectly_regular_unary_invocable concept
|
||||
template<typename F, typename I>
|
||||
CPP_concept indirectly_regular_unary_invocable =
|
||||
indirectly_readable<I> &&
|
||||
copy_constructible<F> &&
|
||||
CPP_concept_ref(ranges::indirectly_regular_unary_invocable_, F, I);
|
||||
|
||||
/// \cond
|
||||
// Non-standard indirect invocable concepts
|
||||
/// \concept indirectly_binary_invocable_impl_
|
||||
/// \brief The \c indirectly_binary_invocable_impl_ concept
|
||||
template(typename F, typename I1, typename I2)(
|
||||
concept (indirectly_binary_invocable_impl_)(F, I1, I2),
|
||||
invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
|
||||
invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
|
||||
invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
|
||||
invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
|
||||
invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
|
||||
detail::common_reference_with_4_<
|
||||
invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
|
||||
invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
|
||||
invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
|
||||
invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_binary_invocable_
|
||||
/// \brief The \c indirectly_binary_invocable_ concept
|
||||
template<typename F, typename I1, typename I2>
|
||||
CPP_concept indirectly_binary_invocable_ =
|
||||
indirectly_readable<I1> && indirectly_readable<I2> &&
|
||||
copy_constructible<F> &&
|
||||
CPP_concept_ref(ranges::indirectly_binary_invocable_impl_, F, I1, I2);
|
||||
|
||||
/// \concept indirectly_regular_binary_invocable_impl_
|
||||
/// \brief The \c indirectly_regular_binary_invocable_impl_ concept
|
||||
template(typename F, typename I1, typename I2)(
|
||||
concept (indirectly_regular_binary_invocable_impl_)(F, I1, I2),
|
||||
regular_invocable<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
|
||||
regular_invocable<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
|
||||
regular_invocable<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
|
||||
regular_invocable<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
|
||||
regular_invocable<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>> AND
|
||||
detail::common_reference_with_4_<
|
||||
invoke_result_t<F &, iter_value_t<I1> &, iter_value_t<I2> &>,
|
||||
invoke_result_t<F &, iter_value_t<I1> &, iter_reference_t<I2>>,
|
||||
invoke_result_t<F &, iter_reference_t<I1>, iter_value_t<I2> &>,
|
||||
invoke_result_t<F &, iter_reference_t<I1>, iter_reference_t<I2>>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_regular_binary_invocable_
|
||||
/// \brief The \c indirectly_regular_binary_invocable_ concept
|
||||
template<typename F, typename I1, typename I2>
|
||||
CPP_concept indirectly_regular_binary_invocable_ =
|
||||
indirectly_readable<I1> && indirectly_readable<I2> &&
|
||||
copy_constructible<F> &&
|
||||
CPP_concept_ref(ranges::indirectly_regular_binary_invocable_impl_, F, I1, I2);
|
||||
/// \endcond
|
||||
|
||||
/// \concept indirect_unary_predicate_
|
||||
/// \brief The \c indirect_unary_predicate_ concept
|
||||
template(typename F, typename I)(
|
||||
concept (indirect_unary_predicate_)(F, I),
|
||||
predicate<F &, iter_value_t<I> &> AND
|
||||
predicate<F &, iter_reference_t<I>> AND
|
||||
predicate<F &, iter_common_reference_t<I>>
|
||||
);
|
||||
|
||||
/// \concept indirect_unary_predicate
|
||||
/// \brief The \c indirect_unary_predicate concept
|
||||
template<typename F, typename I>
|
||||
CPP_concept indirect_unary_predicate =
|
||||
indirectly_readable<I> &&
|
||||
copy_constructible<F> &&
|
||||
CPP_concept_ref(ranges::indirect_unary_predicate_, F, I);
|
||||
|
||||
/// \concept indirect_binary_predicate_impl_
|
||||
/// \brief The \c indirect_binary_predicate_impl_ concept
|
||||
template(typename F, typename I1, typename I2)(
|
||||
concept (indirect_binary_predicate_impl_)(F, I1, I2),
|
||||
predicate<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
|
||||
predicate<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
|
||||
predicate<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
|
||||
predicate<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
|
||||
predicate<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
|
||||
);
|
||||
|
||||
/// \concept indirect_binary_predicate_
|
||||
/// \brief The \c indirect_binary_predicate_ concept
|
||||
template<typename F, typename I1, typename I2>
|
||||
CPP_concept indirect_binary_predicate_ =
|
||||
indirectly_readable<I1> && indirectly_readable<I2> &&
|
||||
copy_constructible<F> &&
|
||||
CPP_concept_ref(ranges::indirect_binary_predicate_impl_, F, I1, I2);
|
||||
|
||||
/// \concept indirect_relation_
|
||||
/// \brief The \c indirect_relation_ concept
|
||||
template(typename F, typename I1, typename I2)(
|
||||
concept (indirect_relation_)(F, I1, I2),
|
||||
relation<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
|
||||
relation<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
|
||||
relation<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
|
||||
relation<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
|
||||
relation<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
|
||||
);
|
||||
|
||||
/// \concept indirect_relation
|
||||
/// \brief The \c indirect_relation concept
|
||||
template<typename F, typename I1, typename I2 = I1>
|
||||
CPP_concept indirect_relation =
|
||||
indirectly_readable<I1> && indirectly_readable<I2> &&
|
||||
copy_constructible<F> &&
|
||||
CPP_concept_ref(ranges::indirect_relation_, F, I1, I2);
|
||||
|
||||
/// \concept indirect_strict_weak_order_
|
||||
/// \brief The \c indirect_strict_weak_order_ concept
|
||||
template(typename F, typename I1, typename I2)(
|
||||
concept (indirect_strict_weak_order_)(F, I1, I2),
|
||||
strict_weak_order<F &, iter_value_t<I1> &, iter_value_t<I2> &> AND
|
||||
strict_weak_order<F &, iter_value_t<I1> &, iter_reference_t<I2>> AND
|
||||
strict_weak_order<F &, iter_reference_t<I1>, iter_value_t<I2> &> AND
|
||||
strict_weak_order<F &, iter_reference_t<I1>, iter_reference_t<I2>> AND
|
||||
strict_weak_order<F &, iter_common_reference_t<I1>, iter_common_reference_t<I2>>
|
||||
);
|
||||
|
||||
/// \concept indirect_strict_weak_order
|
||||
/// \brief The \c indirect_strict_weak_order concept
|
||||
template<typename F, typename I1, typename I2 = I1>
|
||||
CPP_concept indirect_strict_weak_order =
|
||||
indirectly_readable<I1> && indirectly_readable<I2> &&
|
||||
copy_constructible<F> &&
|
||||
CPP_concept_ref(ranges::indirect_strict_weak_order_, F, I1, I2);
|
||||
// clang-format on
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// projected struct, for "projecting" a readable with a unary callable
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_UNDEFINED_INTERNAL
|
||||
template<typename I, typename Proj>
|
||||
struct projected_
|
||||
{
|
||||
struct type
|
||||
{
|
||||
using reference = indirect_result_t<Proj &, I>;
|
||||
using value_type = uncvref_t<reference>;
|
||||
reference operator*() const;
|
||||
};
|
||||
};
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
|
||||
template<typename Proj>
|
||||
struct select_projected_
|
||||
{
|
||||
template<typename I>
|
||||
using apply =
|
||||
meta::_t<
|
||||
detail::enable_if_t<
|
||||
(bool)indirectly_regular_unary_invocable<Proj, I>,
|
||||
detail::projected_<I, Proj>>>;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct select_projected_<identity>
|
||||
{
|
||||
template<typename I>
|
||||
using apply = detail::enable_if_t<(bool)indirectly_readable<I>, I>;
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename I, typename Proj>
|
||||
using projected = typename detail::select_projected_<Proj>::template apply<I>;
|
||||
|
||||
template<typename I, typename Proj>
|
||||
struct incrementable_traits<detail::projected_<I, Proj>> : incrementable_traits<I>
|
||||
{};
|
||||
|
||||
// clang-format off
|
||||
/// \concept indirectly_movable_
|
||||
/// \brief The \c indirectly_movable_ concept
|
||||
template(typename I, typename O)(
|
||||
concept (indirectly_movable_)(I, O),
|
||||
indirectly_writable<O, iter_rvalue_reference_t<I>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_movable
|
||||
/// \brief The \c indirectly_movable concept
|
||||
template<typename I, typename O>
|
||||
CPP_concept indirectly_movable =
|
||||
indirectly_readable<I> && CPP_concept_ref(ranges::indirectly_movable_, I, O);
|
||||
|
||||
/// \concept indirectly_movable_storable_
|
||||
/// \brief The \c indirectly_movable_storable_ concept
|
||||
template(typename I, typename O)(
|
||||
concept (indirectly_movable_storable_)(I, O),
|
||||
indirectly_writable<O, iter_value_t<I>> AND
|
||||
movable<iter_value_t<I>> AND
|
||||
constructible_from<iter_value_t<I>, iter_rvalue_reference_t<I>> AND
|
||||
assignable_from<iter_value_t<I> &, iter_rvalue_reference_t<I>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_movable_storable
|
||||
/// \brief The \c indirectly_movable_storable concept
|
||||
template<typename I, typename O>
|
||||
CPP_concept indirectly_movable_storable =
|
||||
indirectly_movable<I, O> &&
|
||||
CPP_concept_ref(ranges::indirectly_movable_storable_, I, O);
|
||||
|
||||
/// \concept indirectly_copyable_
|
||||
/// \brief The \c indirectly_copyable_ concept
|
||||
template(typename I, typename O)(
|
||||
concept (indirectly_copyable_)(I, O),
|
||||
indirectly_writable<O, iter_reference_t<I>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_copyable
|
||||
/// \brief The \c indirectly_copyable concept
|
||||
template<typename I, typename O>
|
||||
CPP_concept indirectly_copyable =
|
||||
indirectly_readable<I> && CPP_concept_ref(ranges::indirectly_copyable_, I, O);
|
||||
|
||||
/// \concept indirectly_copyable_storable_
|
||||
/// \brief The \c indirectly_copyable_storable_ concept
|
||||
template(typename I, typename O)(
|
||||
concept (indirectly_copyable_storable_)(I, O),
|
||||
indirectly_writable<O, iter_value_t<I> const &> AND
|
||||
copyable<iter_value_t<I>> AND
|
||||
constructible_from<iter_value_t<I>, iter_reference_t<I>> AND
|
||||
assignable_from<iter_value_t<I> &, iter_reference_t<I>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_copyable_storable
|
||||
/// \brief The \c indirectly_copyable_storable concept
|
||||
template<typename I, typename O>
|
||||
CPP_concept indirectly_copyable_storable =
|
||||
indirectly_copyable<I, O> &&
|
||||
CPP_concept_ref(ranges::indirectly_copyable_storable_, I, O);
|
||||
|
||||
/// \concept indirectly_swappable_
|
||||
/// \brief The \c indirectly_swappable_ concept
|
||||
template<typename I1, typename I2>
|
||||
CPP_requires(indirectly_swappable_,
|
||||
requires(I1 const i1, I2 const i2) //
|
||||
(
|
||||
ranges::iter_swap(i1, i2),
|
||||
ranges::iter_swap(i1, i1),
|
||||
ranges::iter_swap(i2, i2),
|
||||
ranges::iter_swap(i2, i1)
|
||||
));
|
||||
/// \concept indirectly_swappable
|
||||
/// \brief The \c indirectly_swappable concept
|
||||
template<typename I1, typename I2 = I1>
|
||||
CPP_concept indirectly_swappable =
|
||||
indirectly_readable<I1> && //
|
||||
indirectly_readable<I2> && //
|
||||
CPP_requires_ref(ranges::indirectly_swappable_, I1, I2);
|
||||
|
||||
/// \concept projected_indirect_relation_
|
||||
/// \brief The \c projected_indirect_relation_ concept
|
||||
template(typename C, typename I1, typename P1, typename I2, typename P2)(
|
||||
concept (projected_indirect_relation_)(C, I1, P1, I2, P2),
|
||||
indirect_relation<C, projected<I1, P1>, projected<I2, P2>>
|
||||
);
|
||||
|
||||
/// \concept indirectly_comparable
|
||||
/// \brief The \c indirectly_comparable concept
|
||||
template<typename I1, typename I2, typename C, typename P1 = identity,
|
||||
typename P2 = identity>
|
||||
CPP_concept indirectly_comparable =
|
||||
CPP_concept_ref(ranges::projected_indirect_relation_, C, I1, P1, I2, P2);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Composite concepts for use defining algorithms:
|
||||
/// \concept permutable
|
||||
/// \brief The \c permutable concept
|
||||
template<typename I>
|
||||
CPP_concept permutable =
|
||||
forward_iterator<I> &&
|
||||
indirectly_swappable<I, I> &&
|
||||
indirectly_movable_storable<I, I>;
|
||||
|
||||
/// \concept projected_indirect_strict_weak_order_
|
||||
/// \brief The \c projected_indirect_strict_weak_order_ concept
|
||||
template(typename C, typename I1, typename P1, typename I2, typename P2)(
|
||||
concept (projected_indirect_strict_weak_order_)(C, I1, P1, I2, P2),
|
||||
indirect_strict_weak_order<C, projected<I1, P1>, projected<I2, P2>>
|
||||
);
|
||||
|
||||
template<typename I1, typename I2, typename Out, typename C = less,
|
||||
typename P1 = identity, typename P2 = identity>
|
||||
CPP_concept mergeable =
|
||||
input_iterator<I1> &&
|
||||
input_iterator<I2> &&
|
||||
weakly_incrementable<Out> &&
|
||||
indirectly_copyable<I1, Out> &&
|
||||
indirectly_copyable<I2, Out> &&
|
||||
CPP_concept_ref(ranges::projected_indirect_strict_weak_order_, C, I1, P1, I2, P2);
|
||||
|
||||
/// \concept sortable
|
||||
/// \brief The \c sortable concept
|
||||
template<typename I, typename C = less, typename P = identity>
|
||||
CPP_concept sortable =
|
||||
permutable<I> &&
|
||||
CPP_concept_ref(ranges::projected_indirect_strict_weak_order_, C, I, P, I, P);
|
||||
// clang-format on
|
||||
|
||||
struct sentinel_tag
|
||||
{};
|
||||
struct sized_sentinel_tag : sentinel_tag
|
||||
{};
|
||||
|
||||
template<typename S, typename I>
|
||||
using sentinel_tag_of = //
|
||||
std::enable_if_t< //
|
||||
sentinel_for<S, I>, //
|
||||
meta::conditional_t< //
|
||||
sized_sentinel_for<S, I>, //
|
||||
sized_sentinel_tag, //
|
||||
sentinel_tag>>;
|
||||
|
||||
// Deprecated things:
|
||||
/// \cond
|
||||
template<typename I>
|
||||
using iterator_category RANGES_DEPRECATED(
|
||||
"iterator_category is deprecated. Use the iterator concepts instead") =
|
||||
detail::iterator_category<I>;
|
||||
|
||||
template<typename I>
|
||||
using iterator_category_t RANGES_DEPRECATED(
|
||||
"iterator_category_t is deprecated. Use the iterator concepts instead") =
|
||||
meta::_t<detail::iterator_category<I>>;
|
||||
|
||||
template<typename Fun, typename... Is>
|
||||
using indirect_invoke_result_t RANGES_DEPRECATED(
|
||||
"Please switch to indirect_result_t") = indirect_result_t<Fun, Is...>;
|
||||
|
||||
template<typename Fun, typename... Is>
|
||||
struct RANGES_DEPRECATED("Please switch to indirect_result_t") indirect_invoke_result
|
||||
: meta::defer<indirect_result_t, Fun, Is...>
|
||||
{};
|
||||
|
||||
template<typename Sig>
|
||||
struct indirect_result_of
|
||||
{};
|
||||
|
||||
template<typename Fun, typename... Is>
|
||||
struct RANGES_DEPRECATED("Please switch to indirect_result_t")
|
||||
indirect_result_of<Fun(Is...)> : meta::defer<indirect_result_t, Fun, Is...>
|
||||
{};
|
||||
|
||||
template<typename Sig>
|
||||
using indirect_result_of_t RANGES_DEPRECATED("Please switch to indirect_result_t") =
|
||||
meta::_t<indirect_result_of<Sig>>;
|
||||
/// \endcond
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::bidirectional_iterator;
|
||||
using ranges::contiguous_iterator;
|
||||
using ranges::forward_iterator;
|
||||
using ranges::incrementable;
|
||||
using ranges::indirect_relation;
|
||||
using ranges::indirect_result_t;
|
||||
using ranges::indirect_strict_weak_order;
|
||||
using ranges::indirect_unary_predicate;
|
||||
using ranges::indirectly_comparable;
|
||||
using ranges::indirectly_copyable;
|
||||
using ranges::indirectly_copyable_storable;
|
||||
using ranges::indirectly_movable;
|
||||
using ranges::indirectly_movable_storable;
|
||||
using ranges::indirectly_readable;
|
||||
using ranges::indirectly_regular_unary_invocable;
|
||||
using ranges::indirectly_swappable;
|
||||
using ranges::indirectly_unary_invocable;
|
||||
using ranges::indirectly_writable;
|
||||
using ranges::input_iterator;
|
||||
using ranges::input_or_output_iterator;
|
||||
using ranges::mergeable;
|
||||
using ranges::output_iterator;
|
||||
using ranges::permutable;
|
||||
using ranges::projected;
|
||||
using ranges::random_access_iterator;
|
||||
using ranges::sentinel_for;
|
||||
using ranges::sized_sentinel_for;
|
||||
using ranges::sortable;
|
||||
using ranges::weakly_incrementable;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#ifdef _GLIBCXX_DEBUG
|
||||
// HACKHACK: workaround underconstrained operator- for libstdc++ debug iterator wrapper
|
||||
// by intentionally creating an ambiguity when the wrapped types don't support the
|
||||
// necessary operation.
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template(typename I1, typename I2, typename Seq)(
|
||||
requires (!::ranges::sized_sentinel_for<I1, I2>)) //
|
||||
void operator-(_Safe_iterator<I1, Seq> const &, _Safe_iterator<I2, Seq> const &) =
|
||||
delete;
|
||||
|
||||
template(typename I1, typename Seq)(
|
||||
requires (!::ranges::sized_sentinel_for<I1, I1>)) //
|
||||
void operator-(_Safe_iterator<I1, Seq> const &, _Safe_iterator<I1, Seq> const &) =
|
||||
delete;
|
||||
} // namespace __gnu_debug
|
||||
#endif
|
||||
|
||||
#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 3900)
|
||||
// HACKHACK: workaround libc++ (https://llvm.org/bugs/show_bug.cgi?id=28421)
|
||||
// and libstdc++ (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71771)
|
||||
// underconstrained operator- for reverse_iterator by disabling sized_sentinel_for
|
||||
// when the base iterators do not model sized_sentinel_for.
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
template<typename S, typename I>
|
||||
/*inline*/ constexpr bool
|
||||
disable_sized_sentinel<std::reverse_iterator<S>, std::reverse_iterator<I>> =
|
||||
!static_cast<bool>(sized_sentinel_for<I, S>);
|
||||
} // namespace ranges
|
||||
|
||||
#endif // defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 3900)
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_CONCEPTS_HPP
|
||||
472
Telegram/ThirdParty/range-v3/include/range/v3/iterator/counted_iterator.hpp
vendored
Normal file
472
Telegram/ThirdParty/range-v3/include/range/v3/iterator/counted_iterator.hpp
vendored
Normal file
@@ -0,0 +1,472 @@
|
||||
/// \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_ITERATOR_COUNTED_ITERATOR_HPP
|
||||
#define RANGES_V3_ITERATOR_COUNTED_ITERATOR_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/default_sentinel.hpp>
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace _counted_iterator_
|
||||
{
|
||||
struct access
|
||||
{
|
||||
template<typename I>
|
||||
static constexpr iter_difference_t<counted_iterator<I>> & count(
|
||||
counted_iterator<I> & ci) noexcept
|
||||
{
|
||||
return ci.cnt_;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
static constexpr I & current(counted_iterator<I> & ci) noexcept
|
||||
{
|
||||
return ci.current_;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
static constexpr I const & current(counted_iterator<I> const & ci) noexcept
|
||||
{
|
||||
return ci.current_;
|
||||
}
|
||||
};
|
||||
|
||||
template<bool>
|
||||
struct contiguous_iterator_concept_base
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct contiguous_iterator_concept_base<true>
|
||||
{
|
||||
using iterator_concept = ranges::contiguous_iterator_tag;
|
||||
};
|
||||
} // namespace _counted_iterator_
|
||||
/// \endcond
|
||||
|
||||
template<typename I>
|
||||
// requires input_or_output_iterator<I>
|
||||
struct counted_iterator
|
||||
: _counted_iterator_::contiguous_iterator_concept_base<(bool)contiguous_iterator<I>>
|
||||
{
|
||||
private:
|
||||
friend advance_fn;
|
||||
CPP_assert(input_or_output_iterator<I>);
|
||||
friend _counted_iterator_::access;
|
||||
|
||||
I current_{};
|
||||
iter_difference_t<I> cnt_{0};
|
||||
|
||||
constexpr void post_increment_(std::true_type)
|
||||
{
|
||||
CPP_assert(std::is_void<decltype(current_++)>());
|
||||
++current_;
|
||||
--cnt_;
|
||||
}
|
||||
constexpr auto post_increment_(std::false_type) -> decltype(current_++)
|
||||
{
|
||||
CPP_assert(!std::is_void<decltype(current_++)>());
|
||||
auto && tmp = current_++;
|
||||
--cnt_;
|
||||
return static_cast<decltype(tmp) &&>(tmp);
|
||||
}
|
||||
|
||||
public:
|
||||
using iterator_type = I;
|
||||
using difference_type = iter_difference_t<I>;
|
||||
|
||||
counted_iterator() = default;
|
||||
|
||||
constexpr counted_iterator(I x, iter_difference_t<I> n)
|
||||
: current_(std::move(x))
|
||||
, cnt_(n)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
}
|
||||
|
||||
template(typename I2)(
|
||||
requires convertible_to<I2, I>)
|
||||
constexpr counted_iterator(counted_iterator<I2> const & i)
|
||||
: current_(_counted_iterator_::access::current(i))
|
||||
, cnt_(i.count())
|
||||
{}
|
||||
|
||||
template(typename I2)(
|
||||
requires convertible_to<I2, I>)
|
||||
constexpr counted_iterator & operator=(counted_iterator<I2> const & i)
|
||||
{
|
||||
current_ = _counted_iterator_::access::current(i);
|
||||
cnt_ = i.count();
|
||||
}
|
||||
|
||||
constexpr I base() const
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
|
||||
constexpr iter_difference_t<I> count() const
|
||||
{
|
||||
return cnt_;
|
||||
}
|
||||
|
||||
constexpr iter_reference_t<I> operator*() noexcept(
|
||||
noexcept(iter_reference_t<I>(*current_)))
|
||||
{
|
||||
RANGES_EXPECT(cnt_ > 0);
|
||||
return *current_;
|
||||
}
|
||||
template(typename I2 = I)(
|
||||
requires indirectly_readable<I2 const>)
|
||||
constexpr iter_reference_t<I2> operator*() const //
|
||||
noexcept(noexcept(iter_reference_t<I>(*current_)))
|
||||
{
|
||||
RANGES_EXPECT(cnt_ > 0);
|
||||
return *current_;
|
||||
}
|
||||
|
||||
constexpr counted_iterator & operator++()
|
||||
{
|
||||
RANGES_EXPECT(cnt_ > 0);
|
||||
++current_;
|
||||
--cnt_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef RANGES_WORKAROUND_MSVC_677925
|
||||
template(typename I2 = I)(
|
||||
requires (!forward_iterator<I2>)) //
|
||||
constexpr auto operator++(int) -> decltype(std::declval<I2 &>()++)
|
||||
#else // ^^^ workaround ^^^ / vvv no workaround vvv
|
||||
CPP_member
|
||||
constexpr auto operator++(int) //
|
||||
-> CPP_ret(decltype(std::declval<I &>()++))(
|
||||
requires (!forward_iterator<I>))
|
||||
#endif // RANGES_WORKAROUND_MSVC_677925
|
||||
{
|
||||
RANGES_EXPECT(cnt_ > 0);
|
||||
return post_increment_(std::is_void<decltype(current_++)>());
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator++(int) //
|
||||
-> CPP_ret(counted_iterator)(
|
||||
requires forward_iterator<I>)
|
||||
{
|
||||
auto tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator--() //
|
||||
-> CPP_ret(counted_iterator &)(
|
||||
requires bidirectional_iterator<I>)
|
||||
{
|
||||
--current_;
|
||||
++cnt_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator--(int) //
|
||||
-> CPP_ret(counted_iterator)(
|
||||
requires bidirectional_iterator<I>)
|
||||
{
|
||||
auto tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator+=(difference_type n) //
|
||||
-> CPP_ret(counted_iterator &)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
RANGES_EXPECT(cnt_ >= n);
|
||||
current_ += n;
|
||||
cnt_ -= n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator+(difference_type n) const //
|
||||
-> CPP_ret(counted_iterator)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
auto tmp(*this);
|
||||
tmp += n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator-=(difference_type n) //
|
||||
-> CPP_ret(counted_iterator &)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
RANGES_EXPECT(cnt_ >= -n);
|
||||
current_ -= n;
|
||||
cnt_ += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator-(difference_type n) const //
|
||||
-> CPP_ret(counted_iterator)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
auto tmp(*this);
|
||||
tmp -= n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPP_member
|
||||
constexpr auto operator[](difference_type n) const //
|
||||
-> CPP_ret(iter_reference_t<I>)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
RANGES_EXPECT(cnt_ >= n);
|
||||
return current_[n];
|
||||
}
|
||||
|
||||
#if !RANGES_BROKEN_CPO_LOOKUP
|
||||
CPP_broken_friend_member
|
||||
friend constexpr auto iter_move(counted_iterator const & i) //
|
||||
noexcept(detail::has_nothrow_iter_move_v<I>)
|
||||
-> CPP_broken_friend_ret(iter_rvalue_reference_t<I>)(
|
||||
requires input_iterator<I>)
|
||||
{
|
||||
return ranges::iter_move(i.current_);
|
||||
}
|
||||
template<typename I2, typename S2>
|
||||
friend constexpr auto iter_swap(counted_iterator const & x,
|
||||
counted_iterator<I2> const & y) //
|
||||
noexcept(is_nothrow_indirectly_swappable<I, I2>::value)
|
||||
-> CPP_broken_friend_ret(void)(
|
||||
requires indirectly_swappable<I2, I>)
|
||||
{
|
||||
return ranges::iter_swap(x.current_, _counted_iterator_::access::current(y));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/// \cond
|
||||
#if RANGES_BROKEN_CPO_LOOKUP
|
||||
namespace _counted_iterator_
|
||||
{
|
||||
template<typename I>
|
||||
constexpr auto iter_move(counted_iterator<I> const & i) noexcept(
|
||||
detail::has_nothrow_iter_move_v<I>)
|
||||
-> CPP_broken_friend_ret(iter_rvalue_reference_t<I>)(
|
||||
requires input_iterator<I>)
|
||||
{
|
||||
return ranges::iter_move(_counted_iterator_::access::current(i));
|
||||
}
|
||||
template<typename I1, typename I2>
|
||||
constexpr auto iter_swap(
|
||||
counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const &
|
||||
y) noexcept(is_nothrow_indirectly_swappable<I1, I2>::value)
|
||||
-> CPP_broken_friend_ret(void)(
|
||||
requires indirectly_swappable<I2, I1>)
|
||||
{
|
||||
return ranges::iter_swap(_counted_iterator_::access::current(x),
|
||||
_counted_iterator_::access::current(y));
|
||||
}
|
||||
} // namespace _counted_iterator_
|
||||
#endif
|
||||
/// endcond
|
||||
|
||||
template(typename I1, typename I2)(
|
||||
requires common_with<I1, I2>)
|
||||
constexpr bool operator==(counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const & y)
|
||||
{
|
||||
return x.count() == y.count();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr bool operator==(counted_iterator<I> const & x, default_sentinel_t)
|
||||
{
|
||||
return x.count() == 0;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr bool operator==(default_sentinel_t, counted_iterator<I> const & x)
|
||||
{
|
||||
return x.count() == 0;
|
||||
}
|
||||
|
||||
template(typename I1, typename I2)(
|
||||
requires common_with<I1, I2>)
|
||||
constexpr bool operator!=(counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const & y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr bool operator!=(counted_iterator<I> const & x, default_sentinel_t y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr bool operator!=(default_sentinel_t x, counted_iterator<I> const & y)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template(typename I1, typename I2)(
|
||||
requires common_with<I1, I2>)
|
||||
constexpr bool operator<(counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const & y)
|
||||
{
|
||||
return y.count() < x.count();
|
||||
}
|
||||
|
||||
template(typename I1, typename I2)(
|
||||
requires common_with<I1, I2>)
|
||||
constexpr bool operator<=(counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const & y)
|
||||
{
|
||||
return !(y < x);
|
||||
}
|
||||
|
||||
template(typename I1, typename I2)(
|
||||
requires common_with<I1, I2>)
|
||||
constexpr bool operator>(counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const & y)
|
||||
{
|
||||
return y < x;
|
||||
}
|
||||
|
||||
template(typename I1, typename I2)(
|
||||
requires common_with<I1, I2>)
|
||||
constexpr bool operator>=(counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const & y)
|
||||
{
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
template(typename I1, typename I2)(
|
||||
requires common_with<I1, I2>)
|
||||
constexpr iter_difference_t<I2> operator-(counted_iterator<I1> const & x,
|
||||
counted_iterator<I2> const & y)
|
||||
{
|
||||
return y.count() - x.count();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr iter_difference_t<I> operator-(counted_iterator<I> const & x,
|
||||
default_sentinel_t)
|
||||
{
|
||||
return -x.count();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr iter_difference_t<I> operator-(default_sentinel_t,
|
||||
counted_iterator<I> const & y)
|
||||
{
|
||||
return y.count();
|
||||
}
|
||||
|
||||
template(typename I)(
|
||||
requires random_access_iterator<I>)
|
||||
constexpr counted_iterator<I> operator+(iter_difference_t<I> n,
|
||||
counted_iterator<I> const & x)
|
||||
{
|
||||
return x + n;
|
||||
}
|
||||
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
constexpr counted_iterator<I> make_counted_iterator(I i, iter_difference_t<I> n)
|
||||
{
|
||||
return {std::move(i), n};
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
struct indirectly_readable_traits<counted_iterator<I>>
|
||||
: meta::conditional_t<
|
||||
(bool)indirectly_readable<I>,
|
||||
indirectly_readable_traits<I>,
|
||||
meta::nil_>
|
||||
{};
|
||||
|
||||
CPP_template_def(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
constexpr void advance_fn::operator()(counted_iterator<I> & i,
|
||||
iter_difference_t<I> n) const
|
||||
{
|
||||
RANGES_EXPECT(n <= i.cnt_);
|
||||
advance(i.current_, n);
|
||||
i.cnt_ -= n;
|
||||
}
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::counted_iterator;
|
||||
}
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
/// \cond
|
||||
namespace ranges
|
||||
{
|
||||
namespace _counted_iterator_
|
||||
{
|
||||
template<typename I, typename = void>
|
||||
struct iterator_traits_
|
||||
{
|
||||
using difference_type = iter_difference_t<I>;
|
||||
using value_type = void;
|
||||
using reference = void;
|
||||
using pointer = void;
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
struct iterator_traits_<I, meta::if_c<input_iterator<I>>>
|
||||
: std::iterator_traits<I>
|
||||
{
|
||||
using pointer = void;
|
||||
};
|
||||
} // namespace _counted_iterator_
|
||||
} // namespace ranges
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename I>
|
||||
struct iterator_traits<::ranges::counted_iterator<I>>
|
||||
: ::ranges::_counted_iterator_::iterator_traits_<I>
|
||||
{};
|
||||
} // namespace std
|
||||
/// \endcond
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
41
Telegram/ThirdParty/range-v3/include/range/v3/iterator/default_sentinel.hpp
vendored
Normal file
41
Telegram/ThirdParty/range-v3/include/range/v3/iterator/default_sentinel.hpp
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/// \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_ITERATOR_DEFAULT_SENTINEL_HPP
|
||||
#define RANGES_V3_ITERATOR_DEFAULT_SENTINEL_HPP
|
||||
|
||||
#include <range/v3/detail/config.hpp>
|
||||
#include <range/v3/utility/static_const.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
struct default_sentinel_t
|
||||
{};
|
||||
|
||||
// Default sentinel
|
||||
RANGES_INLINE_VARIABLE(default_sentinel_t, default_sentinel)
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::default_sentinel;
|
||||
using ranges::default_sentinel_t;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
470
Telegram/ThirdParty/range-v3/include/range/v3/iterator/diffmax_t.hpp
vendored
Normal file
470
Telegram/ThirdParty/range-v3/include/range/v3/iterator/diffmax_t.hpp
vendored
Normal file
@@ -0,0 +1,470 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 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_ITERATOR_DIFFMAX_T_HPP
|
||||
#define RANGES_V3_ITERATOR_DIFFMAX_T_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <iosfwd>
|
||||
#include <limits>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_UNSIGNED_MATH
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
struct diffmax_t
|
||||
{
|
||||
private:
|
||||
bool neg_;
|
||||
std::uintmax_t val_;
|
||||
struct tag
|
||||
{};
|
||||
|
||||
constexpr diffmax_t(tag, bool neg, std::uintmax_t val)
|
||||
: neg_(val && neg)
|
||||
, val_(val)
|
||||
{}
|
||||
|
||||
/// \cond
|
||||
constexpr void _check()
|
||||
{
|
||||
RANGES_ENSURE(!neg_ || val_);
|
||||
}
|
||||
static constexpr diffmax_t _normalize(bool neg, std::uintmax_t val)
|
||||
{
|
||||
return diffmax_t{tag{}, val && neg, val};
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
public:
|
||||
diffmax_t() = default;
|
||||
|
||||
template(typename T)(
|
||||
requires integral<T>)
|
||||
constexpr diffmax_t(T val) noexcept
|
||||
: neg_(0 > val)
|
||||
, val_(0 > val ? static_cast<std::uintmax_t>(-val)
|
||||
: static_cast<std::uintmax_t>(val))
|
||||
{}
|
||||
|
||||
friend constexpr bool operator<(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
a._check();
|
||||
b._check();
|
||||
return a.neg_ ? (b.neg_ ? a.val_ > b.val_ : true)
|
||||
: (b.neg_ ? false : a.val_ < b.val_);
|
||||
}
|
||||
friend constexpr bool operator>(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return b < a;
|
||||
}
|
||||
friend constexpr bool operator<=(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return !(b < a);
|
||||
}
|
||||
friend constexpr bool operator>=(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return !(a < b);
|
||||
}
|
||||
friend constexpr bool operator==(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
a._check();
|
||||
b._check();
|
||||
return a.val_ == b.val_ && a.neg_ == b.neg_;
|
||||
}
|
||||
friend constexpr bool operator!=(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
friend constexpr diffmax_t operator+(diffmax_t a) noexcept
|
||||
{
|
||||
return a;
|
||||
}
|
||||
friend constexpr diffmax_t operator-(diffmax_t a) noexcept
|
||||
{
|
||||
return _normalize(!a.neg_, a.val_);
|
||||
}
|
||||
|
||||
friend constexpr diffmax_t operator+(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return a.neg_ == b.neg_
|
||||
? diffmax_t{tag{}, a.neg_, a.val_ + b.val_}
|
||||
: (a.neg_ ? (a.val_ > b.val_
|
||||
? diffmax_t{tag{}, true, a.val_ - b.val_}
|
||||
: diffmax_t{tag{}, false, b.val_ - a.val_})
|
||||
: (b.val_ > a.val_
|
||||
? diffmax_t{tag{}, true, b.val_ - a.val_}
|
||||
: diffmax_t{tag{}, false, a.val_ - b.val_}));
|
||||
}
|
||||
friend constexpr diffmax_t operator-(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return a + -b;
|
||||
}
|
||||
friend constexpr diffmax_t operator*(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return _normalize(a.neg_ ^ b.neg_, a.val_ * b.val_);
|
||||
}
|
||||
friend constexpr diffmax_t operator/(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return _normalize(a.neg_ ^ b.neg_, a.val_ / b.val_);
|
||||
}
|
||||
friend constexpr diffmax_t operator%(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return _normalize(a.neg_, a.val_ % b.val_);
|
||||
}
|
||||
static constexpr std::uintmax_t compl_if(bool neg,
|
||||
std::uintmax_t val) noexcept
|
||||
{
|
||||
return neg ? ~val + 1 : val;
|
||||
}
|
||||
friend constexpr diffmax_t operator&(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return _normalize(
|
||||
a.neg_ && b.neg_,
|
||||
compl_if(a.neg_ && b.neg_,
|
||||
compl_if(a.neg_, a.val_) & compl_if(b.neg_, b.val_)));
|
||||
}
|
||||
friend constexpr diffmax_t operator|(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return _normalize(
|
||||
a.neg_ || b.neg_,
|
||||
compl_if(a.neg_ || b.neg_,
|
||||
compl_if(a.neg_, a.val_) | compl_if(b.neg_, b.val_)));
|
||||
}
|
||||
friend constexpr diffmax_t operator^(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return _normalize(
|
||||
bool(a.neg_ ^ b.neg_),
|
||||
compl_if(bool(a.neg_ ^ b.neg_),
|
||||
compl_if(a.neg_, a.val_) ^ compl_if(b.neg_, b.val_)));
|
||||
}
|
||||
|
||||
friend constexpr diffmax_t operator<<(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
RANGES_ENSURE(!a.neg_);
|
||||
return b.neg_ ? diffmax_t{tag{}, false, a.val_ >> b.val_}
|
||||
: diffmax_t{tag{}, false, a.val_ << b.val_};
|
||||
}
|
||||
friend constexpr diffmax_t operator>>(diffmax_t a, diffmax_t b) noexcept
|
||||
{
|
||||
return b.neg_ ? diffmax_t{tag{}, a.neg_, a.val_ << b.val_}
|
||||
: diffmax_t{tag{}, a.neg_, a.val_ >> b.val_};
|
||||
}
|
||||
|
||||
friend constexpr diffmax_t & operator+=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a + b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator-=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a - b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator*=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a * b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator/=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a / b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator%=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a % b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator&=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a & b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator|=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a | b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator^=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
return (a = a ^ b);
|
||||
}
|
||||
friend constexpr diffmax_t & operator<<=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
a = (a << b);
|
||||
return a;
|
||||
}
|
||||
friend constexpr diffmax_t & operator>>=(diffmax_t & a, diffmax_t b) noexcept
|
||||
{
|
||||
a = (a >> b);
|
||||
return a;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
friend constexpr auto operator+=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} + b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator-=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} - b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator*=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} * b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator/=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} / b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator%=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} % b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator&=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} & b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator|=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} | b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator^=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
return (a = static_cast<T>(diffmax_t{a} ^ b));
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator<<=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
a = static_cast<T>(diffmax_t{a} << b);
|
||||
return a;
|
||||
}
|
||||
template<typename T>
|
||||
friend constexpr auto operator>>=(T & a, diffmax_t b) noexcept
|
||||
-> CPP_broken_friend_ret(T &)(
|
||||
requires integral<T>)
|
||||
{
|
||||
a = static_cast<T>(diffmax_t{a} >> b);
|
||||
return a;
|
||||
}
|
||||
|
||||
friend constexpr diffmax_t & operator++(diffmax_t & a) noexcept
|
||||
{
|
||||
a.neg_ = (a.neg_ ? --a.val_ : ++a.val_) && a.neg_;
|
||||
return a;
|
||||
}
|
||||
friend constexpr diffmax_t & operator--(diffmax_t & a) noexcept
|
||||
{
|
||||
a.neg_ = (a.neg_ ? ++a.val_ : --a.val_) && a.neg_;
|
||||
return a;
|
||||
}
|
||||
friend constexpr diffmax_t operator++(diffmax_t & a, int) noexcept
|
||||
{
|
||||
auto tmp = a;
|
||||
++a;
|
||||
return tmp;
|
||||
}
|
||||
friend constexpr diffmax_t operator--(diffmax_t & a, int) noexcept
|
||||
{
|
||||
auto tmp = a;
|
||||
--a;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template(typename T)(
|
||||
requires integral<T>)
|
||||
constexpr explicit
|
||||
operator T() const noexcept
|
||||
{
|
||||
return neg_ ? -static_cast<T>(val_) : static_cast<T>(val_);
|
||||
}
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return val_ != 0;
|
||||
}
|
||||
constexpr bool operator!() const noexcept
|
||||
{
|
||||
return val_ == 0;
|
||||
}
|
||||
|
||||
template<typename Ostream>
|
||||
friend auto operator<<(Ostream & sout, diffmax_t a)
|
||||
-> CPP_broken_friend_ret(std::ostream &)(
|
||||
requires derived_from<
|
||||
Ostream, std::basic_ostream<typename Ostream::char_type,
|
||||
typename Ostream::traits_type>>)
|
||||
{
|
||||
return sout << (&"-"[!a.neg_]) << a.val_;
|
||||
}
|
||||
};
|
||||
|
||||
#if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
|
||||
template<>
|
||||
inline constexpr bool _is_integer_like_<diffmax_t> = true;
|
||||
#else
|
||||
template<typename Enable>
|
||||
constexpr bool _is_integer_like_<diffmax_t, Enable> = true;
|
||||
#endif
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
} // namespace ranges
|
||||
|
||||
/// \cond
|
||||
RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct numeric_limits<::ranges::detail::diffmax_t>
|
||||
{
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool has_infinity = false;
|
||||
static constexpr bool has_quiet_NaN = false;
|
||||
static constexpr bool has_signaling_NaN = false;
|
||||
static constexpr bool has_denorm = false;
|
||||
static constexpr bool has_denorm_loss = false;
|
||||
static constexpr std::float_round_style round_style = std::round_toward_zero;
|
||||
static constexpr bool is_iec559 = false;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = false;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(std::uintmax_t) + 1;
|
||||
static constexpr int digits10 =
|
||||
static_cast<int>(digits * 0.301029996); // digits * std::log10(2)
|
||||
static constexpr int max_digits10 = 0;
|
||||
static constexpr int radix = 2;
|
||||
static constexpr int min_exponent = 0;
|
||||
static constexpr int min_exponent10 = 0;
|
||||
static constexpr int max_exponent = 0;
|
||||
static constexpr int max_exponent10 = 0;
|
||||
static constexpr bool traps = true;
|
||||
static constexpr bool tinyness_before = false;
|
||||
|
||||
static constexpr ::ranges::detail::diffmax_t max() noexcept
|
||||
{
|
||||
return std::uintmax_t(-1);
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t min() noexcept
|
||||
{
|
||||
return -max();
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t lowest() noexcept
|
||||
{
|
||||
return min();
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t epsilon() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t round_error() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t infinity() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t quiet_NaN() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t signaling_NaN() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static constexpr ::ranges::detail::diffmax_t denorm_min() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct numeric_limits<::ranges::detail::diffmax_t const>
|
||||
: numeric_limits<::ranges::detail::diffmax_t>
|
||||
{};
|
||||
template<>
|
||||
struct numeric_limits<::ranges::detail::diffmax_t volatile>
|
||||
: numeric_limits<::ranges::detail::diffmax_t>
|
||||
{};
|
||||
template<>
|
||||
struct numeric_limits<::ranges::detail::diffmax_t const volatile>
|
||||
: numeric_limits<::ranges::detail::diffmax_t>
|
||||
{};
|
||||
|
||||
#if RANGES_CXX_INLINE_VARIABLES >= RANGES_CXX_INLINE_VARIABLES_17
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_specialized;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_signed;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_integer;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_exact;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_infinity;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_quiet_NaN;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_signaling_NaN;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_denorm;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::has_denorm_loss;
|
||||
inline constexpr std::float_round_style
|
||||
numeric_limits<::ranges::detail::diffmax_t>::round_style;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_iec559;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_bounded;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_modulo;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::digits;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::digits10;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::max_digits10;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::radix;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::min_exponent;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::min_exponent10;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::max_exponent;
|
||||
inline constexpr int numeric_limits<::ranges::detail::diffmax_t>::max_exponent10;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::traps;
|
||||
inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::tinyness_before;
|
||||
#endif
|
||||
} // namespace std
|
||||
/// \endcond
|
||||
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif
|
||||
219
Telegram/ThirdParty/range-v3/include/range/v3/iterator/insert_iterators.hpp
vendored
Normal file
219
Telegram/ThirdParty/range-v3/include/range/v3/iterator/insert_iterators.hpp
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
/// \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_ITERATOR_INSERT_ITERATORS_HPP
|
||||
#define RANGES_V3_ITERATOR_INSERT_ITERATORS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/operations.hpp>
|
||||
#include <range/v3/utility/addressof.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
template<typename Container>
|
||||
struct back_insert_iterator
|
||||
{
|
||||
using container_type = Container;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
constexpr back_insert_iterator() = default;
|
||||
constexpr explicit back_insert_iterator(Container & x)
|
||||
: container_(detail::addressof(x))
|
||||
{}
|
||||
back_insert_iterator & operator=(typename Container::value_type const & value)
|
||||
{
|
||||
container_->push_back(value);
|
||||
return *this;
|
||||
}
|
||||
back_insert_iterator & operator=(typename Container::value_type && value)
|
||||
{
|
||||
container_->push_back(std::move(value));
|
||||
return *this;
|
||||
}
|
||||
back_insert_iterator & operator*()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
back_insert_iterator & operator++()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
back_insert_iterator operator++(int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Container * container_ = nullptr;
|
||||
};
|
||||
|
||||
struct back_inserter_fn
|
||||
{
|
||||
template<typename Container>
|
||||
constexpr back_insert_iterator<Container> operator()(Container & x) const
|
||||
{
|
||||
return back_insert_iterator<Container>{x};
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `back_inserter_fn`
|
||||
RANGES_INLINE_VARIABLE(back_inserter_fn, back_inserter)
|
||||
|
||||
template<typename Container>
|
||||
struct front_insert_iterator
|
||||
{
|
||||
using container_type = Container;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
constexpr front_insert_iterator() = default;
|
||||
constexpr explicit front_insert_iterator(Container & x)
|
||||
: container_(detail::addressof(x))
|
||||
{}
|
||||
front_insert_iterator & operator=(typename Container::value_type const & value)
|
||||
{
|
||||
container_->push_front(value);
|
||||
return *this;
|
||||
}
|
||||
front_insert_iterator & operator=(typename Container::value_type && value)
|
||||
{
|
||||
container_->push_front(std::move(value));
|
||||
return *this;
|
||||
}
|
||||
front_insert_iterator & operator*()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
front_insert_iterator & operator++()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
front_insert_iterator operator++(int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Container * container_ = nullptr;
|
||||
};
|
||||
|
||||
struct front_inserter_fn
|
||||
{
|
||||
template<typename Cont>
|
||||
constexpr front_insert_iterator<Cont> operator()(Cont & cont) const
|
||||
{
|
||||
return front_insert_iterator<Cont>{cont};
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `front_inserter_fn`
|
||||
RANGES_INLINE_VARIABLE(front_inserter_fn, front_inserter)
|
||||
|
||||
template<typename Container>
|
||||
struct insert_iterator
|
||||
{
|
||||
using container_type = Container;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
constexpr insert_iterator() = default;
|
||||
constexpr explicit insert_iterator(Container & x, typename Container::iterator w)
|
||||
: container_(detail::addressof(x))
|
||||
, where_(w)
|
||||
{}
|
||||
insert_iterator & operator=(typename Container::value_type const & value)
|
||||
{
|
||||
where_ = ranges::next(container_->insert(where_, value));
|
||||
return *this;
|
||||
}
|
||||
insert_iterator & operator=(typename Container::value_type && value)
|
||||
{
|
||||
where_ = ranges::next(container_->insert(where_, std::move(value)));
|
||||
return *this;
|
||||
}
|
||||
insert_iterator & operator*()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
insert_iterator & operator++()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
insert_iterator & operator++(int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Container * container_ = nullptr;
|
||||
typename Container::iterator where_ = typename Container::iterator();
|
||||
};
|
||||
|
||||
struct inserter_fn
|
||||
{
|
||||
template<typename Cont>
|
||||
constexpr insert_iterator<Cont> operator()(Cont & cont,
|
||||
typename Cont::iterator where) const
|
||||
{
|
||||
return insert_iterator<Cont>{cont, std::move(where)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `inserter_fn`
|
||||
RANGES_INLINE_VARIABLE(inserter_fn, inserter)
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::back_insert_iterator;
|
||||
using ranges::back_inserter;
|
||||
using ranges::front_insert_iterator;
|
||||
using ranges::front_inserter;
|
||||
using ranges::insert_iterator;
|
||||
using ranges::inserter;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
/// \cond
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename Container>
|
||||
struct iterator_traits<::ranges::back_insert_iterator<Container>>
|
||||
: ::ranges::detail::std_output_iterator_traits<>
|
||||
{};
|
||||
|
||||
template<typename Container>
|
||||
struct iterator_traits<::ranges::front_insert_iterator<Container>>
|
||||
: ::ranges::detail::std_output_iterator_traits<>
|
||||
{};
|
||||
|
||||
template<typename Container>
|
||||
struct iterator_traits<::ranges::insert_iterator<Container>>
|
||||
: ::ranges::detail::std_output_iterator_traits<>
|
||||
{};
|
||||
} // namespace std
|
||||
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
/// \endcond
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_INSERT_ITERATORS_HPP
|
||||
453
Telegram/ThirdParty/range-v3/include/range/v3/iterator/move_iterators.hpp
vendored
Normal file
453
Telegram/ThirdParty/range-v3/include/range/v3/iterator/move_iterators.hpp
vendored
Normal file
@@ -0,0 +1,453 @@
|
||||
/// \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_ITERATOR_MOVE_ITERATORS_HPP
|
||||
#define RANGES_V3_ITERATOR_MOVE_ITERATORS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/basic_iterator.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
#include <range/v3/iterator/traits.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
template<typename I>
|
||||
struct move_iterator
|
||||
{
|
||||
private:
|
||||
CPP_assert(input_iterator<I>);
|
||||
I current_ = I{};
|
||||
|
||||
public:
|
||||
using iterator_type = I;
|
||||
using difference_type = iter_difference_t<I>;
|
||||
using value_type = iter_value_t<I>;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using reference = iter_rvalue_reference_t<I>;
|
||||
|
||||
constexpr move_iterator() = default;
|
||||
explicit move_iterator(I i)
|
||||
: current_(i)
|
||||
{}
|
||||
template(typename O)(
|
||||
requires convertible_to<O, I>)
|
||||
move_iterator(move_iterator<O> const & i)
|
||||
: current_(i.base())
|
||||
{}
|
||||
template(typename O)(
|
||||
requires convertible_to<O, I>)
|
||||
move_iterator & operator=(move_iterator<O> const & i)
|
||||
{
|
||||
current_ = i.base();
|
||||
return *this;
|
||||
}
|
||||
I base() const
|
||||
{
|
||||
return current_;
|
||||
}
|
||||
// clang-format off
|
||||
auto CPP_auto_fun(operator*)()(const)
|
||||
(
|
||||
return iter_move(current_)
|
||||
)
|
||||
// clang-format on
|
||||
move_iterator &
|
||||
operator++()
|
||||
{
|
||||
++current_;
|
||||
return *this;
|
||||
}
|
||||
CPP_member
|
||||
auto operator++(int) //
|
||||
-> CPP_ret(void)(
|
||||
requires (!forward_iterator<I>))
|
||||
{
|
||||
++current_;
|
||||
}
|
||||
CPP_member
|
||||
auto operator++(int) //
|
||||
-> CPP_ret(move_iterator)(
|
||||
requires forward_iterator<I>)
|
||||
{
|
||||
return move_iterator(current_++);
|
||||
}
|
||||
CPP_member
|
||||
auto operator--() //
|
||||
-> CPP_ret(move_iterator &)(
|
||||
requires forward_iterator<I>)
|
||||
{
|
||||
--current_;
|
||||
return *this;
|
||||
}
|
||||
CPP_member
|
||||
auto operator--(int) //
|
||||
-> CPP_ret(move_iterator)(
|
||||
requires bidirectional_iterator<I>)
|
||||
{
|
||||
return move_iterator(current_--);
|
||||
}
|
||||
CPP_member
|
||||
auto operator+(difference_type n) const //
|
||||
-> CPP_ret(move_iterator)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
return move_iterator(current_ + n);
|
||||
}
|
||||
CPP_member
|
||||
auto operator+=(difference_type n)
|
||||
-> CPP_ret(move_iterator &)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
current_ += n;
|
||||
return *this;
|
||||
}
|
||||
CPP_member
|
||||
auto operator-(difference_type n) const //
|
||||
-> CPP_ret(move_iterator)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
return move_iterator(current_ - n);
|
||||
}
|
||||
CPP_member
|
||||
auto operator-=(difference_type n) //
|
||||
-> CPP_ret(move_iterator &)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
current_ -= n;
|
||||
return *this;
|
||||
}
|
||||
CPP_member
|
||||
auto operator[](difference_type n) const //
|
||||
-> CPP_ret(reference)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
return iter_move(current_ + n);
|
||||
}
|
||||
|
||||
template<typename I2>
|
||||
friend auto operator==(move_iterator const & x, move_iterator<I2> const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires equality_comparable_with<I, I2>)
|
||||
{
|
||||
return x.base() == y.base();
|
||||
}
|
||||
template<typename I2>
|
||||
friend auto operator!=(move_iterator const & x, move_iterator<I2> const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires equality_comparable_with<I, I2>)
|
||||
{
|
||||
return !(x == y);
|
||||
}
|
||||
template<typename I2>
|
||||
friend auto operator<(move_iterator const & x, move_iterator<I2> const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires totally_ordered_with<I, I2>)
|
||||
{
|
||||
return x.base() < y.base();
|
||||
}
|
||||
template<typename I2>
|
||||
friend auto operator<=(move_iterator const & x, move_iterator<I2> const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires totally_ordered_with<I, I2>)
|
||||
{
|
||||
return !(y < x);
|
||||
}
|
||||
template<typename I2>
|
||||
friend auto operator>(move_iterator const & x, move_iterator<I2> const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires totally_ordered_with<I, I2>)
|
||||
{
|
||||
return y < x;
|
||||
}
|
||||
template<typename I2>
|
||||
friend auto operator>=(move_iterator const & x, move_iterator<I2> const & y)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires totally_ordered_with<I, I2>)
|
||||
{
|
||||
return !(x < y);
|
||||
}
|
||||
|
||||
template<typename I2>
|
||||
friend auto operator-(move_iterator const & x, move_iterator<I2> const & y)
|
||||
-> CPP_broken_friend_ret(iter_difference_t<I2>)(
|
||||
requires sized_sentinel_for<I, I2>)
|
||||
{
|
||||
return x.base() - y.base();
|
||||
}
|
||||
CPP_broken_friend_member
|
||||
friend auto operator+(iter_difference_t<I> n,
|
||||
move_iterator const & x)
|
||||
-> CPP_broken_friend_ret(move_iterator)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
return x + n;
|
||||
}
|
||||
};
|
||||
|
||||
struct make_move_iterator_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires input_iterator<I>)
|
||||
constexpr move_iterator<I> operator()(I it) const
|
||||
{
|
||||
return move_iterator<I>{detail::move(it)};
|
||||
}
|
||||
};
|
||||
|
||||
RANGES_INLINE_VARIABLE(make_move_iterator_fn, make_move_iterator)
|
||||
|
||||
template<typename S>
|
||||
struct move_sentinel
|
||||
{
|
||||
private:
|
||||
S sent_;
|
||||
|
||||
public:
|
||||
constexpr move_sentinel()
|
||||
: sent_{}
|
||||
{}
|
||||
constexpr explicit move_sentinel(S s)
|
||||
: sent_(detail::move(s))
|
||||
{}
|
||||
template(typename OS)(
|
||||
requires convertible_to<OS, S>)
|
||||
constexpr explicit move_sentinel(move_sentinel<OS> const & that)
|
||||
: sent_(that.base())
|
||||
{}
|
||||
template(typename OS)(
|
||||
requires convertible_to<OS, S>)
|
||||
move_sentinel & operator=(move_sentinel<OS> const & that)
|
||||
{
|
||||
sent_ = that.base();
|
||||
return *this;
|
||||
}
|
||||
S base() const
|
||||
{
|
||||
return sent_;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
friend auto operator==(move_iterator<I> const & i, move_sentinel const & s)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires sentinel_for<S, I>)
|
||||
{
|
||||
return i.base() == s.base();
|
||||
}
|
||||
template<typename I>
|
||||
friend auto operator==(move_sentinel const & s, move_iterator<I> const & i)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires sentinel_for<S, I>)
|
||||
{
|
||||
return s.base() == i.base();
|
||||
}
|
||||
template<typename I>
|
||||
friend auto operator!=(move_iterator<I> const & i, move_sentinel const & s)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires sentinel_for<S, I>)
|
||||
{
|
||||
return i.base() != s.base();
|
||||
}
|
||||
template<typename I>
|
||||
friend auto operator!=(move_sentinel const & s, move_iterator<I> const & i)
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires sentinel_for<S, I>)
|
||||
{
|
||||
return s.base() != i.base();
|
||||
}
|
||||
};
|
||||
|
||||
struct make_move_sentinel_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires input_iterator<I>)
|
||||
constexpr move_iterator<I> operator()(I i) const
|
||||
{
|
||||
return move_iterator<I>{detail::move(i)};
|
||||
}
|
||||
|
||||
template(typename S)(
|
||||
requires semiregular<S> AND (!input_iterator<S>)) //
|
||||
constexpr move_sentinel<S> operator()(S s) const
|
||||
{
|
||||
return move_sentinel<S>{detail::move(s)};
|
||||
}
|
||||
};
|
||||
|
||||
RANGES_INLINE_VARIABLE(make_move_sentinel_fn, make_move_sentinel)
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I, bool IsReadable>
|
||||
struct move_into_cursor_types_
|
||||
{};
|
||||
|
||||
template<typename I>
|
||||
struct move_into_cursor_types_<I, true>
|
||||
{
|
||||
using value_type = iter_value_t<I>;
|
||||
using single_pass = meta::bool_<(bool)single_pass_iterator_<I>>;
|
||||
};
|
||||
|
||||
template<typename I>
|
||||
using move_into_cursor_types =
|
||||
move_into_cursor_types_<I, (bool)indirectly_readable<I>>;
|
||||
|
||||
template<typename I>
|
||||
struct move_into_cursor : move_into_cursor_types<I>
|
||||
{
|
||||
private:
|
||||
friend range_access;
|
||||
struct mixin : basic_mixin<move_into_cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
#ifndef _MSC_VER
|
||||
using basic_mixin<move_into_cursor>::basic_mixin;
|
||||
#else
|
||||
constexpr explicit mixin(move_into_cursor && cur)
|
||||
: basic_mixin<move_into_cursor>(static_cast<move_into_cursor &&>(cur))
|
||||
{}
|
||||
constexpr explicit mixin(move_into_cursor const & cur)
|
||||
: basic_mixin<move_into_cursor>(cur)
|
||||
{}
|
||||
#endif
|
||||
explicit mixin(I it)
|
||||
: mixin{move_into_cursor{std::move(it)}}
|
||||
{}
|
||||
I base() const
|
||||
{
|
||||
return this->get().it_;
|
||||
}
|
||||
};
|
||||
|
||||
I it_ = I();
|
||||
|
||||
explicit move_into_cursor(I it)
|
||||
: it_(std::move(it))
|
||||
{}
|
||||
void next()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
template(typename T)(
|
||||
requires indirectly_writable<I, aux::move_t<T>>)
|
||||
void write(T && t) noexcept(noexcept(*it_ = std::move(t)))
|
||||
{
|
||||
*it_ = std::move(t);
|
||||
}
|
||||
template(typename T)(
|
||||
requires indirectly_writable<I, aux::move_t<T>>)
|
||||
void write(T && t) const noexcept(noexcept(*it_ = std::move(t)))
|
||||
{
|
||||
*it_ = std::move(t);
|
||||
}
|
||||
CPP_member
|
||||
auto read() const noexcept(noexcept(*std::declval<I const &>()))
|
||||
-> CPP_ret(iter_reference_t<I>)(
|
||||
requires indirectly_readable<I>)
|
||||
{
|
||||
return *it_;
|
||||
}
|
||||
CPP_member
|
||||
auto equal(move_into_cursor const & that) const //
|
||||
-> CPP_ret(bool)(
|
||||
requires input_iterator<I>)
|
||||
{
|
||||
return it_ == that.it_;
|
||||
}
|
||||
CPP_member
|
||||
auto prev() //
|
||||
-> CPP_ret(void)(
|
||||
requires bidirectional_iterator<I>)
|
||||
{
|
||||
--it_;
|
||||
}
|
||||
CPP_member
|
||||
auto advance(iter_difference_t<I> n) //
|
||||
-> CPP_ret(void)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
it_ += n;
|
||||
}
|
||||
CPP_member
|
||||
auto distance_to(move_into_cursor const & that) const //
|
||||
-> CPP_ret(iter_difference_t<I>)(
|
||||
requires sized_sentinel_for<I, I>)
|
||||
{
|
||||
return that.it_ - it_;
|
||||
}
|
||||
template(typename II = I const)(
|
||||
requires same_as<I const, II> AND indirectly_readable<II>)
|
||||
constexpr iter_rvalue_reference_t<II> move() const //
|
||||
noexcept(has_nothrow_iter_move_v<II>)
|
||||
{
|
||||
return iter_move(it_);
|
||||
}
|
||||
|
||||
public:
|
||||
constexpr move_into_cursor() = default;
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
struct move_into_fn
|
||||
{
|
||||
template<typename I>
|
||||
constexpr move_into_iterator<I> operator()(I it) const
|
||||
{
|
||||
return move_into_iterator<I>{std::move(it)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `move_into_fn`
|
||||
RANGES_INLINE_VARIABLE(move_into_fn, move_into)
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::make_move_iterator;
|
||||
using ranges::move_iterator;
|
||||
using ranges::move_sentinel;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
/// \cond
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename I>
|
||||
struct iterator_traits<::ranges::move_iterator<I>>
|
||||
{
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using difference_type = typename ::ranges::move_iterator<I>::difference_type;
|
||||
using value_type = typename ::ranges::move_iterator<I>::value_type;
|
||||
using reference = typename ::ranges::move_iterator<I>::reference;
|
||||
using pointer = meta::_t<std::add_pointer<reference>>;
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
/// \endcond
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_MOVE_ITERATORS_HPP
|
||||
650
Telegram/ThirdParty/range-v3/include/range/v3/iterator/operations.hpp
vendored
Normal file
650
Telegram/ThirdParty/range-v3/include/range/v3/iterator/operations.hpp
vendored
Normal file
@@ -0,0 +1,650 @@
|
||||
/// \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_ITERATOR_OPERATIONS_HPP
|
||||
#define RANGES_V3_ITERATOR_OPERATIONS_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/concepts.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
template<typename I>
|
||||
// requires input_or_output_iterator<I>
|
||||
struct counted_iterator;
|
||||
/// \endcond
|
||||
|
||||
struct advance_fn
|
||||
{
|
||||
#if RANGES_CXX_IF_CONSTEXPR >= RANGES_CXX_IF_CONSTEXPR_17
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
constexpr void operator()(I & i, iter_difference_t<I> n) const
|
||||
// [[expects: n >= 0 || bidirectional_iterator<I>]]
|
||||
{
|
||||
if constexpr(random_access_iterator<I>)
|
||||
{
|
||||
i += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr(bidirectional_iterator<I>)
|
||||
for(; 0 > n; ++n)
|
||||
--i;
|
||||
RANGES_EXPECT(0 <= n);
|
||||
for(; 0 < n; --n)
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr void operator()(I & i, S bound) const
|
||||
// [[expects axiom: reachable(i, bound)]]
|
||||
{
|
||||
if constexpr(assignable_from<I &, S>)
|
||||
{
|
||||
i = std::move(bound);
|
||||
}
|
||||
else if constexpr(sized_sentinel_for<S, I>)
|
||||
{
|
||||
iter_difference_t<I> d = bound - i;
|
||||
RANGES_EXPECT(0 <= d);
|
||||
(*this)(i, d);
|
||||
}
|
||||
else
|
||||
while(i != bound)
|
||||
++i;
|
||||
}
|
||||
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr iter_difference_t<I> //
|
||||
operator()(I & i, iter_difference_t<I> n, S bound) const
|
||||
// [[expects axiom: 0 == n ||
|
||||
// (0 < n && reachable(i, bound)) ||
|
||||
// (0 > n && same_as<I, S> && bidirectional_iterator<I> && reachable(bound,
|
||||
// i))]]
|
||||
{
|
||||
if constexpr(sized_sentinel_for<S, I>)
|
||||
{
|
||||
if(0 == n)
|
||||
return 0;
|
||||
const auto d = bound - i;
|
||||
if constexpr(bidirectional_iterator<I> && same_as<I, S>)
|
||||
{
|
||||
RANGES_EXPECT(0 <= n ? 0 <= d : 0 >= d);
|
||||
if(0 <= n ? d <= n : d >= n)
|
||||
{
|
||||
i = std::move(bound);
|
||||
return n - d;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RANGES_EXPECT(0 <= n && 0 <= d);
|
||||
if(d <= n)
|
||||
{
|
||||
(*this)(i, std::move(bound));
|
||||
return n - d;
|
||||
}
|
||||
}
|
||||
(*this)(i, n);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if constexpr(bidirectional_iterator<I> && same_as<I, S>)
|
||||
{
|
||||
if(0 > n)
|
||||
{
|
||||
do
|
||||
{
|
||||
--i;
|
||||
++n;
|
||||
} while(0 != n && i != bound);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
RANGES_EXPECT(0 <= n);
|
||||
while(0 != n && i != bound)
|
||||
{
|
||||
++i;
|
||||
--n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#else
|
||||
private:
|
||||
template<typename I>
|
||||
static constexpr void n_(I & i, iter_difference_t<I> n, std::input_iterator_tag);
|
||||
template<typename I>
|
||||
static constexpr void n_(I & i, iter_difference_t<I> n,
|
||||
std::bidirectional_iterator_tag);
|
||||
template<typename I>
|
||||
static constexpr void n_(I & i, iter_difference_t<I> n,
|
||||
std::random_access_iterator_tag);
|
||||
template<typename I, typename S>
|
||||
static constexpr void to_impl_(I & i, S s, sentinel_tag);
|
||||
template<typename I, typename S>
|
||||
static constexpr void to_impl_(I & i, S s, sized_sentinel_tag);
|
||||
template<typename I, typename S>
|
||||
static constexpr void to_(I & i, S s, std::true_type); // assignable
|
||||
template<typename I, typename S>
|
||||
static constexpr void to_(I & i, S s, std::false_type); // !assignable
|
||||
template<typename I, typename S>
|
||||
static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
|
||||
S bound, sentinel_tag,
|
||||
std::input_iterator_tag);
|
||||
template<typename I>
|
||||
static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
|
||||
I bound, sentinel_tag,
|
||||
std::bidirectional_iterator_tag);
|
||||
template<typename I, typename S, typename Concept>
|
||||
static constexpr iter_difference_t<I> bounded_(I & it, iter_difference_t<I> n,
|
||||
S bound, sized_sentinel_tag,
|
||||
Concept);
|
||||
|
||||
public:
|
||||
// Advance a certain number of steps:
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
constexpr void operator()(I & i, iter_difference_t<I> n) const
|
||||
{
|
||||
advance_fn::n_(i, n, iterator_tag_of<I>{});
|
||||
}
|
||||
// Advance to a certain position:
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr void operator()(I & i, S s) const
|
||||
{
|
||||
advance_fn::to_(
|
||||
i, static_cast<S &&>(s), meta::bool_<assignable_from<I &, S>>());
|
||||
}
|
||||
// Advance a certain number of times, with a bound:
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr iter_difference_t<I> //
|
||||
operator()(I & it, iter_difference_t<I> n, S bound) const
|
||||
{
|
||||
return advance_fn::bounded_(it,
|
||||
n,
|
||||
static_cast<S &&>(bound),
|
||||
sentinel_tag_of<S, I>(),
|
||||
iterator_tag_of<I>());
|
||||
}
|
||||
#endif
|
||||
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
constexpr void operator()(counted_iterator<I> & i, iter_difference_t<I> n) const;
|
||||
};
|
||||
|
||||
/// \sa `advance_fn`
|
||||
RANGES_INLINE_VARIABLE(advance_fn, advance)
|
||||
|
||||
#if RANGES_CXX_IF_CONSTEXPR < RANGES_CXX_IF_CONSTEXPR_17
|
||||
template<typename I>
|
||||
constexpr void advance_fn::n_(I & i, iter_difference_t<I> n, std::input_iterator_tag)
|
||||
{
|
||||
RANGES_EXPECT(n >= 0);
|
||||
for(; n > 0; --n)
|
||||
++i;
|
||||
}
|
||||
template<typename I>
|
||||
constexpr void advance_fn::n_(I & i, iter_difference_t<I> n,
|
||||
std::bidirectional_iterator_tag)
|
||||
{
|
||||
if(n > 0)
|
||||
for(; n > 0; --n)
|
||||
++i;
|
||||
else
|
||||
for(; n < 0; ++n)
|
||||
--i;
|
||||
}
|
||||
template<typename I>
|
||||
constexpr void advance_fn::n_(I & i, iter_difference_t<I> n,
|
||||
std::random_access_iterator_tag)
|
||||
{
|
||||
i += n;
|
||||
}
|
||||
template<typename I, typename S>
|
||||
constexpr void advance_fn::to_impl_(I & i, S s, sentinel_tag)
|
||||
{
|
||||
while(i != s)
|
||||
++i;
|
||||
}
|
||||
template<typename I, typename S>
|
||||
constexpr void advance_fn::to_impl_(I & i, S s, sized_sentinel_tag)
|
||||
{
|
||||
iter_difference_t<I> d = s - i;
|
||||
RANGES_EXPECT(0 <= d);
|
||||
advance(i, d);
|
||||
}
|
||||
// Advance to a certain position:
|
||||
template<typename I, typename S>
|
||||
constexpr void advance_fn::to_(I & i, S s, std::true_type)
|
||||
{
|
||||
i = static_cast<S &&>(s);
|
||||
}
|
||||
template<typename I, typename S>
|
||||
constexpr void advance_fn::to_(I & i, S s, std::false_type)
|
||||
{
|
||||
advance_fn::to_impl_(i, static_cast<S &&>(s), sentinel_tag_of<S, I>());
|
||||
}
|
||||
template<typename I, typename S>
|
||||
constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
|
||||
S bound, sentinel_tag,
|
||||
std::input_iterator_tag)
|
||||
{
|
||||
RANGES_EXPECT(0 <= n);
|
||||
for(; 0 != n && it != bound; --n)
|
||||
++it;
|
||||
return n;
|
||||
}
|
||||
template<typename I>
|
||||
constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
|
||||
I bound, sentinel_tag,
|
||||
std::bidirectional_iterator_tag)
|
||||
{
|
||||
if(0 <= n)
|
||||
for(; 0 != n && it != bound; --n)
|
||||
++it;
|
||||
else
|
||||
for(; 0 != n && it != bound; ++n)
|
||||
--it;
|
||||
return n;
|
||||
}
|
||||
template<typename I, typename S, typename Concept>
|
||||
constexpr iter_difference_t<I> advance_fn::bounded_(I & it, iter_difference_t<I> n,
|
||||
S bound, sized_sentinel_tag,
|
||||
Concept)
|
||||
{
|
||||
RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
|
||||
if(n == 0)
|
||||
return 0;
|
||||
iter_difference_t<I> d = bound - it;
|
||||
RANGES_EXPECT(0 <= n ? 0 <= d : 0 >= d);
|
||||
if(0 <= n ? n >= d : n <= d)
|
||||
{
|
||||
advance(it, static_cast<S &&>(bound));
|
||||
return n - d;
|
||||
}
|
||||
advance(it, n);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct next_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
constexpr I operator()(I it) const
|
||||
{
|
||||
return ++it;
|
||||
}
|
||||
template(typename I)(
|
||||
requires input_or_output_iterator<I>)
|
||||
constexpr I operator()(I it, iter_difference_t<I> n) const
|
||||
{
|
||||
advance(it, n);
|
||||
return it;
|
||||
}
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr I operator()(I it, S s) const
|
||||
{
|
||||
advance(it, static_cast<S &&>(s));
|
||||
return it;
|
||||
}
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr I operator()(I it, iter_difference_t<I> n, S bound) const
|
||||
{
|
||||
advance(it, n, static_cast<S &&>(bound));
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `next_fn`
|
||||
RANGES_INLINE_VARIABLE(next_fn, next)
|
||||
|
||||
struct prev_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires bidirectional_iterator<I>)
|
||||
constexpr I operator()(I it) const
|
||||
{
|
||||
return --it;
|
||||
}
|
||||
template(typename I)(
|
||||
requires bidirectional_iterator<I>)
|
||||
constexpr I operator()(I it, iter_difference_t<I> n) const
|
||||
{
|
||||
advance(it, -n);
|
||||
return it;
|
||||
}
|
||||
template(typename I)(
|
||||
requires bidirectional_iterator<I>)
|
||||
constexpr I operator()(I it, iter_difference_t<I> n, I bound) const
|
||||
{
|
||||
advance(it, -n, static_cast<I &&>(bound));
|
||||
return it;
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `prev_fn`
|
||||
RANGES_INLINE_VARIABLE(prev_fn, prev)
|
||||
|
||||
struct iter_enumerate_fn
|
||||
{
|
||||
private:
|
||||
template(typename I, typename S)(
|
||||
requires (!sized_sentinel_for<I, I>)) //
|
||||
static constexpr std::pair<iter_difference_t<I>, I> //
|
||||
impl_i(I first, S last, sentinel_tag)
|
||||
{
|
||||
iter_difference_t<I> d = 0;
|
||||
for(; first != last; ++first)
|
||||
++d;
|
||||
return {d, first};
|
||||
}
|
||||
template(typename I, typename S)(
|
||||
requires sized_sentinel_for<I, I>)
|
||||
static constexpr std::pair<iter_difference_t<I>, I> //
|
||||
impl_i(I first, S end_, sentinel_tag)
|
||||
{
|
||||
I last = ranges::next(first, end_);
|
||||
auto n = static_cast<iter_difference_t<I>>(last - first);
|
||||
RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
|
||||
return {n, last};
|
||||
}
|
||||
template<typename I, typename S>
|
||||
static constexpr std::pair<iter_difference_t<I>, I> //
|
||||
impl_i(I first, S last, sized_sentinel_tag)
|
||||
{
|
||||
auto n = static_cast<iter_difference_t<I>>(last - first);
|
||||
RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
|
||||
return {n, ranges::next(first, last)};
|
||||
}
|
||||
|
||||
public:
|
||||
template(typename I, typename S)(
|
||||
requires sentinel_for<S, I>)
|
||||
constexpr std::pair<iter_difference_t<I>, I> operator()(I first, S last) const
|
||||
{
|
||||
return iter_enumerate_fn::impl_i(static_cast<I &&>(first),
|
||||
static_cast<S &&>(last),
|
||||
sentinel_tag_of<S, I>());
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `iter_enumerate_fn`
|
||||
RANGES_INLINE_VARIABLE(iter_enumerate_fn, iter_enumerate)
|
||||
|
||||
struct iter_distance_fn
|
||||
{
|
||||
private:
|
||||
template<typename I, typename S>
|
||||
static constexpr iter_difference_t<I> impl_i(I first, S last, sentinel_tag)
|
||||
{
|
||||
return iter_enumerate(static_cast<I &&>(first), static_cast<S &&>(last))
|
||||
.first;
|
||||
}
|
||||
template<typename I, typename S>
|
||||
static constexpr iter_difference_t<I> impl_i(I first, S last, sized_sentinel_tag)
|
||||
{
|
||||
auto n = static_cast<iter_difference_t<I>>(last - first);
|
||||
RANGES_EXPECT(((bool)same_as<I, S> || 0 <= n));
|
||||
return n;
|
||||
}
|
||||
|
||||
public:
|
||||
template(typename I, typename S)(
|
||||
requires input_or_output_iterator<I> AND sentinel_for<S, I>)
|
||||
constexpr iter_difference_t<I> operator()(I first, S last) const
|
||||
{
|
||||
return iter_distance_fn::impl_i(static_cast<I &&>(first),
|
||||
static_cast<S &&>(last),
|
||||
sentinel_tag_of<S, I>());
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `iter_distance_fn`
|
||||
RANGES_INLINE_VARIABLE(iter_distance_fn, iter_distance)
|
||||
|
||||
struct iter_distance_compare_fn
|
||||
{
|
||||
private:
|
||||
template<typename I, typename S>
|
||||
static constexpr int impl_i(I first, S last, iter_difference_t<I> n, sentinel_tag)
|
||||
{
|
||||
if(n < 0)
|
||||
return 1;
|
||||
for(; n > 0; --n, ++first)
|
||||
{
|
||||
if(first == last)
|
||||
return -1;
|
||||
}
|
||||
return first == last ? 0 : 1;
|
||||
}
|
||||
template<typename I, typename S>
|
||||
static constexpr int impl_i(I first, S last, iter_difference_t<I> n,
|
||||
sized_sentinel_tag)
|
||||
{
|
||||
iter_difference_t<I> dist = last - first;
|
||||
if(n < dist)
|
||||
return 1;
|
||||
if(dist < n)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
template(typename I, typename S)(
|
||||
requires input_iterator<I> AND sentinel_for<S, I>)
|
||||
constexpr int operator()(I first, S last, iter_difference_t<I> n) const
|
||||
{
|
||||
return iter_distance_compare_fn::impl_i(static_cast<I &&>(first),
|
||||
static_cast<S &&>(last),
|
||||
n,
|
||||
sentinel_tag_of<S, I>());
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `iter_distance_compare_fn`
|
||||
RANGES_INLINE_VARIABLE(iter_distance_compare_fn, iter_distance_compare)
|
||||
|
||||
// Like distance(b,e), but guaranteed to be O(1)
|
||||
struct iter_size_fn
|
||||
{
|
||||
template(typename I, typename S)(
|
||||
requires sized_sentinel_for<S, I>)
|
||||
constexpr meta::_t<std::make_unsigned<iter_difference_t<I>>> //
|
||||
operator()(I const & first, S last) const
|
||||
{
|
||||
using size_type = meta::_t<std::make_unsigned<iter_difference_t<I>>>;
|
||||
iter_difference_t<I> n = last - first;
|
||||
RANGES_EXPECT(0 <= n);
|
||||
return static_cast<size_type>(n);
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `iter_size_fn`
|
||||
RANGES_INLINE_VARIABLE(iter_size_fn, iter_size)
|
||||
|
||||
/// \cond
|
||||
namespace adl_uncounted_recounted_detail
|
||||
{
|
||||
template<typename I>
|
||||
constexpr I uncounted(I i)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
constexpr I recounted(I const &, I i, iter_difference_t<I>)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
struct uncounted_fn
|
||||
{
|
||||
template<typename I>
|
||||
constexpr auto operator()(I i) const -> decltype(uncounted((I &&) i))
|
||||
{
|
||||
return uncounted((I &&) i);
|
||||
}
|
||||
};
|
||||
|
||||
struct recounted_fn
|
||||
{
|
||||
template<typename I, typename J>
|
||||
constexpr auto operator()(I i, J j, iter_difference_t<J> n) const
|
||||
-> decltype(recounted((I &&) i, (J &&) j, n))
|
||||
{
|
||||
return recounted((I &&) i, (J &&) j, n);
|
||||
}
|
||||
};
|
||||
} // namespace adl_uncounted_recounted_detail
|
||||
/// \endcond
|
||||
|
||||
RANGES_INLINE_VARIABLE(adl_uncounted_recounted_detail::uncounted_fn, uncounted)
|
||||
RANGES_INLINE_VARIABLE(adl_uncounted_recounted_detail::recounted_fn, recounted)
|
||||
|
||||
struct enumerate_fn : iter_enumerate_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
static constexpr std::pair<range_difference_t<Rng>, iterator_t<Rng>> impl_r(
|
||||
Rng & rng, range_tag, range_tag)
|
||||
{
|
||||
return iter_enumerate(begin(rng), end(rng));
|
||||
}
|
||||
template<typename Rng>
|
||||
static constexpr std::pair<range_difference_t<Rng>, iterator_t<Rng>> impl_r(
|
||||
Rng & rng, common_range_tag, sized_range_tag)
|
||||
{
|
||||
return {static_cast<range_difference_t<Rng>>(size(rng)), end(rng)};
|
||||
}
|
||||
|
||||
public:
|
||||
using iter_enumerate_fn::operator();
|
||||
|
||||
template(typename Rng)(
|
||||
requires range<Rng>)
|
||||
constexpr std::pair<range_difference_t<Rng>, iterator_t<Rng>> operator()(Rng && rng) const
|
||||
{
|
||||
// Better not be trying to compute the distance of an infinite range:
|
||||
RANGES_EXPECT(!is_infinite<Rng>::value);
|
||||
return enumerate_fn::impl_r(
|
||||
rng, common_range_tag_of<Rng>(), sized_range_tag_of<Rng>());
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `enumerate_fn`
|
||||
RANGES_INLINE_VARIABLE(enumerate_fn, enumerate)
|
||||
|
||||
struct distance_fn : iter_distance_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
static range_difference_t<Rng> impl_r(Rng & rng, range_tag)
|
||||
{
|
||||
return enumerate(rng).first;
|
||||
}
|
||||
template<typename Rng>
|
||||
static constexpr range_difference_t<Rng> impl_r(Rng & rng, sized_range_tag)
|
||||
{
|
||||
return static_cast<range_difference_t<Rng>>(size(rng));
|
||||
}
|
||||
|
||||
public:
|
||||
using iter_distance_fn::operator();
|
||||
|
||||
template(typename Rng)(
|
||||
requires range<Rng>)
|
||||
constexpr range_difference_t<Rng> operator()(Rng && rng) const
|
||||
{
|
||||
// Better not be trying to compute the distance of an infinite range:
|
||||
RANGES_EXPECT(!is_infinite<Rng>::value);
|
||||
return distance_fn::impl_r(rng, sized_range_tag_of<Rng>());
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `distance_fn`
|
||||
RANGES_INLINE_VARIABLE(distance_fn, distance)
|
||||
|
||||
// The interface of distance_compare is taken from Util.listLengthCmp in the GHC API.
|
||||
struct distance_compare_fn : iter_distance_compare_fn
|
||||
{
|
||||
private:
|
||||
template<typename Rng>
|
||||
static constexpr int impl_r(Rng & rng, range_difference_t<Rng> n, range_tag)
|
||||
{
|
||||
// Infinite ranges are always compared to be larger than a finite number.
|
||||
return is_infinite<Rng>::value
|
||||
? 1
|
||||
: iter_distance_compare(begin(rng), end(rng), n);
|
||||
}
|
||||
template<typename Rng>
|
||||
static constexpr int impl_r(Rng & rng, range_difference_t<Rng> n, sized_range_tag)
|
||||
{
|
||||
auto dist = distance(rng); // O(1) since rng is a sized_range
|
||||
if(dist > n)
|
||||
return 1;
|
||||
else if(dist < n)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
using iter_distance_compare_fn::operator();
|
||||
|
||||
template(typename Rng)(
|
||||
requires range<Rng>)
|
||||
constexpr int operator()(Rng && rng, range_difference_t<Rng> n) const
|
||||
{
|
||||
return distance_compare_fn::impl_r(rng, n, sized_range_tag_of<Rng>());
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `distance_compare_fn`
|
||||
RANGES_INLINE_VARIABLE(distance_compare_fn, distance_compare)
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::advance;
|
||||
using ranges::distance;
|
||||
using ranges::next;
|
||||
using ranges::prev;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_OPERATIONS_HPP
|
||||
155
Telegram/ThirdParty/range-v3/include/range/v3/iterator/reverse_iterator.hpp
vendored
Normal file
155
Telegram/ThirdParty/range-v3/include/range/v3/iterator/reverse_iterator.hpp
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
/// \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_ITERATOR_REVERSE_ITERATOR_HPP
|
||||
#define RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/basic_iterator.hpp>
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I>
|
||||
struct reverse_cursor
|
||||
{
|
||||
private:
|
||||
CPP_assert(bidirectional_iterator<I>);
|
||||
friend range_access;
|
||||
|
||||
using value_type = iter_value_t<I>;
|
||||
|
||||
template<typename OtherI>
|
||||
friend struct reverse_cursor;
|
||||
struct mixin : basic_mixin<reverse_cursor>
|
||||
{
|
||||
mixin() = default;
|
||||
#ifndef _MSC_VER
|
||||
using basic_mixin<reverse_cursor>::basic_mixin;
|
||||
#else
|
||||
constexpr explicit mixin(reverse_cursor && cur)
|
||||
: basic_mixin<reverse_cursor>(static_cast<reverse_cursor &&>(cur))
|
||||
{}
|
||||
constexpr explicit mixin(reverse_cursor const & cur)
|
||||
: basic_mixin<reverse_cursor>(cur)
|
||||
{}
|
||||
#endif
|
||||
constexpr mixin(I it)
|
||||
: mixin{reverse_cursor{it}}
|
||||
{}
|
||||
constexpr I base() const
|
||||
{
|
||||
return this->get().base();
|
||||
}
|
||||
};
|
||||
|
||||
I it_;
|
||||
|
||||
constexpr reverse_cursor(I it)
|
||||
: it_(std::move(it))
|
||||
{}
|
||||
constexpr iter_reference_t<I> read() const
|
||||
{
|
||||
return *arrow();
|
||||
}
|
||||
constexpr I arrow() const
|
||||
{
|
||||
auto tmp = it_;
|
||||
--tmp;
|
||||
return tmp;
|
||||
}
|
||||
constexpr I base() const
|
||||
{
|
||||
return it_;
|
||||
}
|
||||
template(typename J)(
|
||||
requires sentinel_for<J, I>)
|
||||
constexpr bool equal(reverse_cursor<J> const & that) const
|
||||
{
|
||||
return it_ == that.it_;
|
||||
}
|
||||
constexpr void next()
|
||||
{
|
||||
--it_;
|
||||
}
|
||||
constexpr void prev()
|
||||
{
|
||||
++it_;
|
||||
}
|
||||
CPP_member
|
||||
constexpr auto advance(iter_difference_t<I> n) //
|
||||
-> CPP_ret(void)(
|
||||
requires random_access_iterator<I>)
|
||||
{
|
||||
it_ -= n;
|
||||
}
|
||||
template(typename J)(
|
||||
requires sized_sentinel_for<J, I>)
|
||||
constexpr iter_difference_t<I> distance_to(reverse_cursor<J> const & that) //
|
||||
const
|
||||
{
|
||||
return it_ - that.base();
|
||||
}
|
||||
constexpr iter_rvalue_reference_t<I> move() const
|
||||
noexcept(noexcept((void)I(I(it_)), (void)--const_cast<I &>(it_),
|
||||
iter_move(it_)))
|
||||
{
|
||||
auto tmp = it_;
|
||||
--tmp;
|
||||
return iter_move(tmp);
|
||||
}
|
||||
|
||||
public:
|
||||
reverse_cursor() = default;
|
||||
template(typename U)(
|
||||
requires convertible_to<U, I>)
|
||||
constexpr reverse_cursor(reverse_cursor<U> const & u)
|
||||
: it_(u.base())
|
||||
{}
|
||||
};
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
struct make_reverse_iterator_fn
|
||||
{
|
||||
template(typename I)(
|
||||
requires bidirectional_iterator<I>)
|
||||
constexpr reverse_iterator<I> operator()(I i) const
|
||||
{
|
||||
return reverse_iterator<I>(i);
|
||||
}
|
||||
};
|
||||
|
||||
RANGES_INLINE_VARIABLE(make_reverse_iterator_fn, make_reverse_iterator)
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::make_reverse_iterator;
|
||||
using ranges::reverse_iterator;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP
|
||||
272
Telegram/ThirdParty/range-v3/include/range/v3/iterator/stream_iterators.hpp
vendored
Normal file
272
Telegram/ThirdParty/range-v3/include/range/v3/iterator/stream_iterators.hpp
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
/// \file
|
||||
// Range v3 library
|
||||
//
|
||||
// Copyright Eric Niebler 2014-present
|
||||
// Copyright Google LLC 2020-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_ITERATOR_STREAM_ITERATORS_HPP
|
||||
#define RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
template<typename T = void, typename Char = char,
|
||||
typename Traits = std::char_traits<Char>>
|
||||
struct ostream_iterator
|
||||
{
|
||||
private:
|
||||
template<class U>
|
||||
using value_t = meta::if_<std::is_void<T>, U, T>;
|
||||
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using char_type = Char;
|
||||
using traits_type = Traits;
|
||||
using ostream_type = std::basic_ostream<Char, Traits>;
|
||||
|
||||
constexpr ostream_iterator() = default;
|
||||
ostream_iterator(ostream_type & s, Char const * d = nullptr) noexcept
|
||||
: sout_(&s)
|
||||
, delim_(d)
|
||||
{}
|
||||
template(typename U)(
|
||||
requires convertible_to<U, value_t<U> const &>)
|
||||
ostream_iterator & operator=(U && value)
|
||||
{
|
||||
RANGES_EXPECT(sout_);
|
||||
*sout_ << static_cast<value_t<U> const &>(static_cast<U &&>(value));
|
||||
if(delim_)
|
||||
*sout_ << delim_;
|
||||
return *this;
|
||||
}
|
||||
ostream_iterator & operator*()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
ostream_iterator & operator++()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
ostream_iterator & operator++(int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_type * sout_;
|
||||
Char const * delim_;
|
||||
};
|
||||
|
||||
template<typename Delim, typename Char = char,
|
||||
typename Traits = std::char_traits<Char>>
|
||||
struct ostream_joiner
|
||||
{
|
||||
CPP_assert(semiregular<Delim>);
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using char_type = Char;
|
||||
using traits_type = Traits;
|
||||
using ostream_type = std::basic_ostream<Char, Traits>;
|
||||
|
||||
constexpr ostream_joiner() = default;
|
||||
ostream_joiner(ostream_type & s, Delim const & d)
|
||||
: delim_(d)
|
||||
, sout_(std::addressof(s))
|
||||
, first_(true)
|
||||
{}
|
||||
ostream_joiner(ostream_type & s, Delim && d)
|
||||
: delim_(std::move(d))
|
||||
, sout_(std::addressof(s))
|
||||
, first_(true)
|
||||
{}
|
||||
template<typename T>
|
||||
ostream_joiner & operator=(T const & value)
|
||||
{
|
||||
RANGES_EXPECT(sout_);
|
||||
if(!first_)
|
||||
*sout_ << delim_;
|
||||
first_ = false;
|
||||
*sout_ << value;
|
||||
return *this;
|
||||
}
|
||||
ostream_joiner & operator*() noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
ostream_joiner & operator++() noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
ostream_joiner & operator++(int) noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
Delim delim_;
|
||||
ostream_type * sout_;
|
||||
bool first_;
|
||||
};
|
||||
|
||||
struct make_ostream_joiner_fn
|
||||
{
|
||||
template(typename Delim, typename Char, typename Traits)(
|
||||
requires semiregular<detail::decay_t<Delim>>)
|
||||
ostream_joiner<detail::decay_t<Delim>, Char, Traits> //
|
||||
operator()(std::basic_ostream<Char, Traits> & s, Delim && d) const
|
||||
{
|
||||
return {s, std::forward<Delim>(d)};
|
||||
}
|
||||
};
|
||||
|
||||
/// \sa `make_ostream_joiner_fn`
|
||||
RANGES_INLINE_VARIABLE(make_ostream_joiner_fn, make_ostream_joiner)
|
||||
|
||||
template<typename Char, typename Traits = std::char_traits<Char>>
|
||||
struct ostreambuf_iterator
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef Char char_type;
|
||||
typedef Traits traits_type;
|
||||
typedef std::basic_streambuf<Char, Traits> streambuf_type;
|
||||
typedef std::basic_ostream<Char, Traits> ostream_type;
|
||||
|
||||
constexpr ostreambuf_iterator() = default;
|
||||
ostreambuf_iterator(ostream_type & s) noexcept
|
||||
: ostreambuf_iterator(s.rdbuf())
|
||||
{}
|
||||
ostreambuf_iterator(streambuf_type * s) noexcept
|
||||
: sbuf_(s)
|
||||
{
|
||||
RANGES_ASSERT(s != nullptr);
|
||||
}
|
||||
ostreambuf_iterator & operator=(Char c)
|
||||
{
|
||||
RANGES_ASSERT(sbuf_ != nullptr);
|
||||
if(!failed_)
|
||||
failed_ = (sbuf_->sputc(c) == Traits::eof());
|
||||
return *this;
|
||||
}
|
||||
ostreambuf_iterator & operator*()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
ostreambuf_iterator & operator++()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
ostreambuf_iterator & operator++(int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
bool failed() const noexcept
|
||||
{
|
||||
return failed_;
|
||||
}
|
||||
|
||||
private:
|
||||
streambuf_type * sbuf_ = nullptr;
|
||||
bool failed_ = false;
|
||||
};
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
template<typename T, typename Char = char,
|
||||
typename Traits = std::char_traits<Char>>
|
||||
using ostream_iterator = ranges::ostream_iterator<T, Char, Traits>;
|
||||
|
||||
using ranges::ostreambuf_iterator;
|
||||
} // namespace cpp20
|
||||
|
||||
/// \brief Writes to an ostream object using the unformatted
|
||||
/// `std::basic_ostream::write` operation. This means that `32` will be encoded as
|
||||
/// `100000` as opposed to the string "32".
|
||||
///
|
||||
template<typename CharT = char, typename Traits = std::char_traits<CharT>>
|
||||
class unformatted_ostream_iterator final
|
||||
{
|
||||
public:
|
||||
using iterator_category = std::output_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using char_type = CharT;
|
||||
using traits_type = Traits;
|
||||
using ostream_type = std::basic_ostream<CharT, Traits>;
|
||||
|
||||
unformatted_ostream_iterator() = default;
|
||||
|
||||
explicit unformatted_ostream_iterator(ostream_type & out) noexcept
|
||||
: out_(&out)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
// requires stream_insertible<T, ostream_type>
|
||||
unformatted_ostream_iterator & operator=(T const & t)
|
||||
{
|
||||
RANGES_EXPECT(out_);
|
||||
out_->write(reinterpret_cast<char const *>(std::addressof(t)), sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
unformatted_ostream_iterator & operator*() noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
unformatted_ostream_iterator & operator++() noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
unformatted_ostream_iterator & operator++(int) noexcept
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_type * out_ = nullptr;
|
||||
};
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
/// \cond
|
||||
RANGES_DIAGNOSTIC_PUSH
|
||||
RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T, typename Char, typename Traits>
|
||||
struct iterator_traits<::ranges::ostream_iterator<T, Char, Traits>>
|
||||
: ::ranges::detail::std_output_iterator_traits<>
|
||||
{};
|
||||
|
||||
template<typename Char, typename Traits>
|
||||
struct iterator_traits<::ranges::ostreambuf_iterator<Char, Traits>>
|
||||
: ::ranges::detail::std_output_iterator_traits<>
|
||||
{};
|
||||
} // namespace std
|
||||
|
||||
RANGES_DIAGNOSTIC_POP
|
||||
/// \endcond
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_STREAM_ITERATORS_HPP
|
||||
178
Telegram/ThirdParty/range-v3/include/range/v3/iterator/traits.hpp
vendored
Normal file
178
Telegram/ThirdParty/range-v3/include/range/v3/iterator/traits.hpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/// \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_ITERATOR_TRAITS_HPP
|
||||
#define RANGES_V3_ITERATOR_TRAITS_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
#include <meta/meta.hpp>
|
||||
|
||||
#include <concepts/concepts.hpp>
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/access.hpp> // for iter_move, iter_swap
|
||||
#include <range/v3/utility/common_type.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
|
||||
/// \cond
|
||||
using input_iterator_tag RANGES_DEPRECATED(
|
||||
"Please switch to the standard iterator tags") = std::input_iterator_tag;
|
||||
using forward_iterator_tag RANGES_DEPRECATED(
|
||||
"Please switch to the standard iterator tags") = std::forward_iterator_tag;
|
||||
using bidirectional_iterator_tag RANGES_DEPRECATED(
|
||||
"Please switch to the standard iterator tags") = std::bidirectional_iterator_tag;
|
||||
using random_access_iterator_tag RANGES_DEPRECATED(
|
||||
"Please switch to the standard iterator tags") = std::random_access_iterator_tag;
|
||||
/// \endcond
|
||||
|
||||
struct contiguous_iterator_tag : std::random_access_iterator_tag
|
||||
{};
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I, typename = iter_reference_t<I>,
|
||||
typename R = decltype(iter_move(std::declval<I &>())), typename = R &>
|
||||
using iter_rvalue_reference_t = R;
|
||||
|
||||
template<typename I>
|
||||
RANGES_INLINE_VAR constexpr bool has_nothrow_iter_move_v =
|
||||
noexcept(iter_rvalue_reference_t<I>(ranges::iter_move(std::declval<I &>())));
|
||||
} // namespace detail
|
||||
/// \endcond
|
||||
|
||||
template<typename I>
|
||||
using iter_rvalue_reference_t = detail::iter_rvalue_reference_t<I>;
|
||||
|
||||
template<typename I>
|
||||
using iter_common_reference_t =
|
||||
common_reference_t<iter_reference_t<I>, iter_value_t<I> &>;
|
||||
|
||||
#if defined(RANGES_DEEP_STL_INTEGRATION) && RANGES_DEEP_STL_INTEGRATION && \
|
||||
!defined(RANGES_DOXYGEN_INVOKED)
|
||||
template<typename T>
|
||||
using iter_difference_t =
|
||||
typename meta::conditional_t<detail::is_std_iterator_traits_specialized_v<T>,
|
||||
std::iterator_traits<uncvref_t<T>>,
|
||||
incrementable_traits<uncvref_t<T>>>::difference_type;
|
||||
#else
|
||||
template<typename T>
|
||||
using iter_difference_t =
|
||||
typename incrementable_traits<uncvref_t<T>>::difference_type;
|
||||
#endif
|
||||
|
||||
// Defined in <range/v3/iterator/access.hpp>
|
||||
// template<typename T>
|
||||
// using iter_value_t = ...
|
||||
|
||||
// Defined in <range/v3/iterator/access.hpp>
|
||||
// template<typename R>
|
||||
// using iter_reference_t = detail::iter_reference_t_<R>;
|
||||
|
||||
// Defined in <range/v3/range_fwd.hpp>:
|
||||
// template<typename S, typename I>
|
||||
// inline constexpr bool disable_sized_sentinel = false;
|
||||
|
||||
/// \cond
|
||||
namespace detail
|
||||
{
|
||||
template<typename I>
|
||||
using iter_size_t =
|
||||
meta::_t<meta::conditional_t<std::is_integral<iter_difference_t<I>>::value,
|
||||
std::make_unsigned<iter_difference_t<I>>,
|
||||
meta::id<iter_difference_t<I>>>>;
|
||||
|
||||
template<typename I>
|
||||
using iter_arrow_t = decltype(std::declval<I &>().operator->());
|
||||
|
||||
template<typename I>
|
||||
using iter_pointer_t =
|
||||
meta::_t<meta::conditional_t<
|
||||
meta::is_trait<meta::defer<iter_arrow_t, I>>::value,
|
||||
meta::defer<iter_arrow_t, I>,
|
||||
std::add_pointer<iter_reference_t<I>>>>;
|
||||
|
||||
template<typename T>
|
||||
struct difference_type_ : meta::defer<iter_difference_t, T>
|
||||
{};
|
||||
|
||||
template<typename T>
|
||||
struct value_type_ : meta::defer<iter_value_t, T>
|
||||
{};
|
||||
|
||||
template<typename T>
|
||||
struct size_type_ : meta::defer<iter_size_t, T>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
using difference_type_t RANGES_DEPRECATED(
|
||||
"ranges::difference_type_t is deprecated. Please use "
|
||||
"ranges::iter_difference_t instead.") = iter_difference_t<T>;
|
||||
|
||||
template<typename T>
|
||||
using value_type_t RANGES_DEPRECATED(
|
||||
"ranges::value_type_t is deprecated. Please use "
|
||||
"ranges::iter_value_t instead.") = iter_value_t<T>;
|
||||
|
||||
template<typename R>
|
||||
using reference_t RANGES_DEPRECATED(
|
||||
"ranges::reference_t is deprecated. Use ranges::iter_reference_t "
|
||||
"instead.") = iter_reference_t<R>;
|
||||
|
||||
template<typename I>
|
||||
using rvalue_reference_t RANGES_DEPRECATED(
|
||||
"rvalue_reference_t is deprecated; "
|
||||
"use iter_rvalue_reference_t instead") = iter_rvalue_reference_t<I>;
|
||||
|
||||
template<typename T>
|
||||
struct RANGES_DEPRECATED(
|
||||
"ranges::size_type is deprecated. Iterators do not have an associated "
|
||||
"size_type.") size_type : detail::size_type_<T>
|
||||
{};
|
||||
|
||||
template<typename I>
|
||||
using size_type_t RANGES_DEPRECATED("size_type_t is deprecated.") =
|
||||
detail::iter_size_t<I>;
|
||||
/// \endcond
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::iter_common_reference_t;
|
||||
using ranges::iter_difference_t;
|
||||
using ranges::iter_reference_t;
|
||||
using ranges::iter_rvalue_reference_t;
|
||||
using ranges::iter_value_t;
|
||||
|
||||
// Specialize these in the ranges:: namespace
|
||||
using ranges::disable_sized_sentinel;
|
||||
template<typename T>
|
||||
using incrementable_traits = ranges::incrementable_traits<T>;
|
||||
template<typename T>
|
||||
using indirectly_readable_traits = ranges::indirectly_readable_traits<T>;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_TRAITS_HPP
|
||||
70
Telegram/ThirdParty/range-v3/include/range/v3/iterator/unreachable_sentinel.hpp
vendored
Normal file
70
Telegram/ThirdParty/range-v3/include/range/v3/iterator/unreachable_sentinel.hpp
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/// \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_ITERATOR_UNREACHABLE_SENTINEL_HPP
|
||||
#define RANGES_V3_ITERATOR_UNREACHABLE_SENTINEL_HPP
|
||||
|
||||
#include <range/v3/range_fwd.hpp>
|
||||
|
||||
#include <range/v3/iterator/concepts.hpp>
|
||||
|
||||
#include <range/v3/detail/prologue.hpp>
|
||||
|
||||
namespace ranges
|
||||
{
|
||||
/// \addtogroup group-iterator
|
||||
/// @{
|
||||
struct unreachable_sentinel_t
|
||||
{
|
||||
template<typename I>
|
||||
friend constexpr auto operator==(I const &, unreachable_sentinel_t) noexcept
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires weakly_incrementable<I>)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
template<typename I>
|
||||
friend constexpr auto operator==(unreachable_sentinel_t, I const &) noexcept
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires weakly_incrementable<I>)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
template<typename I>
|
||||
friend constexpr auto operator!=(I const &, unreachable_sentinel_t) noexcept
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires weakly_incrementable<I>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
template<typename I>
|
||||
friend constexpr auto operator!=(unreachable_sentinel_t, I const &) noexcept
|
||||
-> CPP_broken_friend_ret(bool)(
|
||||
requires weakly_incrementable<I>)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
RANGES_INLINE_VARIABLE(unreachable_sentinel_t, unreachable)
|
||||
|
||||
namespace cpp20
|
||||
{
|
||||
using ranges::unreachable;
|
||||
using ranges::unreachable_sentinel_t;
|
||||
} // namespace cpp20
|
||||
/// @}
|
||||
} // namespace ranges
|
||||
|
||||
#include <range/v3/detail/epilogue.hpp>
|
||||
|
||||
#endif // RANGES_V3_ITERATOR_UNREACHABLE_SENTINEL_HPP
|
||||
Reference in New Issue
Block a user