18template<
typename Iterator>
19[[nodiscard]]
constexpr Iterator
safe_next(Iterator first, Iterator last,
size_t n, std::input_iterator_tag)
21 while (n-- && (first != last)) ++first;
25template<
typename Iterator>
26[[nodiscard]]
constexpr Iterator
safe_next(Iterator first, Iterator last,
size_t n, std::random_access_iterator_tag)
28 return first + std::min<size_t>(n, last - first);
31template<
typename Iterator>
32[[nodiscard]]
constexpr Iterator
safe_prev(Iterator first, Iterator last,
size_t n, std::bidirectional_iterator_tag)
34 while (n-- && (first != last)) --last;
38template<
typename Iterator>
39[[nodiscard]]
constexpr Iterator
safe_prev(Iterator first, Iterator last,
size_t n, std::random_access_iterator_tag)
41 return last - std::min<size_t>(n, last - first);
45template<
typename Range>
49 constexpr Drop(Range&& range_,
size_t n_)
50 : range(
std::forward<Range>(range_))
55 [[nodiscard]]
constexpr auto begin()
const {
56 using Iterator =
decltype(std::begin(range));
57 return safe_next(std::begin(range), std::end(range), n,
58 typename std::iterator_traits<Iterator>::iterator_category());
61 [[nodiscard]]
constexpr auto end()
const {
62 return std::end(range);
71template<
typename Range>
76 : range(
std::forward<Range>(range_))
81 [[nodiscard]]
constexpr auto begin()
const {
82 return std::begin(range);
85 [[nodiscard]]
constexpr auto end()
const {
86 using Iterator =
decltype(std::begin(range));
87 return safe_prev(std::begin(range), std::end(range), n,
88 typename std::iterator_traits<Iterator>::iterator_category());
97template<
typename Range>
102 : range(
std::forward<Range>(range_))
106 [[nodiscard]]
constexpr auto begin()
const {
return range.rbegin(); }
107 [[nodiscard]]
constexpr auto begin() {
return range.rbegin(); }
108 [[nodiscard]]
constexpr auto end()
const {
return range.rend(); }
109 [[nodiscard]]
constexpr auto end() {
return range.rend(); }
110 [[nodiscard]]
constexpr auto rbegin()
const {
return range.begin(); }
111 [[nodiscard]]
constexpr auto rbegin() {
return range.begin(); }
112 [[nodiscard]]
constexpr auto rend()
const {
return range.end(); }
113 [[nodiscard]]
constexpr auto rend() {
return range.end(); }
123 using return_type = std::invoke_result_t<UnaryOp, decltype(*std::declval<Iterator>())>;
220 return it <=> other.it;
236 [[no_unique_address]] UO op;
239template<
typename Range,
typename UnaryOp>
class Transform
243 : range(
std::forward<Range>(range_)), op(op_)
247 [[nodiscard]]
constexpr auto begin()
const
251 [[nodiscard]]
constexpr auto end()
const
255 [[nodiscard]]
constexpr auto rbegin()
const
259 [[nodiscard]]
constexpr auto rend()
const
264 [[nodiscard]]
constexpr auto size()
const {
return range.size(); }
265 [[nodiscard]]
constexpr auto empty()
const {
return range.empty(); }
267 [[nodiscard]]
constexpr auto front()
const {
return op(range.front()); }
268 [[nodiscard]]
constexpr auto back()
const {
return op(range.back()); }
271 return std::invoke(op, range[idx]);
276 [[no_unique_address]] UnaryOp op;
280template<
typename Iterator,
typename Sentinel,
typename Predicate>
284 using value_type =
typename std::iterator_traits<Iterator>::value_type;
285 using reference =
typename std::iterator_traits<Iterator>::reference;
286 using pointer =
typename std::iterator_traits<Iterator>::pointer;
291 : it(it_), last(last_), pred(pred_)
293 while (isFiltered()) ++it;
308 }
while (isFiltered());
319 [[nodiscard]]
constexpr bool isFiltered()
321 return (it != last) && !std::invoke(pred, *it);
327 [[no_unique_address]] Predicate pred;
330template<
typename Range,
typename Predicate>
334 using Iterator =
decltype(std::begin(std::declval<Range>()));
335 using Sentinel =
decltype(std::end (std::declval<Range>()));
338 constexpr Filter(Range&& range_, Predicate pred_)
339 : range(
std::forward<Range>(range_)), pred(pred_)
345 return {std::begin(range), std::end(range), pred};
351 return {std::end(range), std::end(range), pred};
356 [[no_unique_address]] Predicate pred;
363 using value_type =
typename std::iterator_traits<Iterator>::value_type;
370 [[nodiscard]]
constexpr auto operator*()
const {
return *it; }
386 return (x.it == y.it) || (x.n == 0 && y.n == 0);
389 return (x.it == y) || (x.n == 0);
397template<
typename Range>
401 using Iterator =
decltype(std::begin(std::declval<Range>()));
402 using Sentinel =
decltype(std::end (std::declval<Range>()));
405 constexpr Take(Range&& range_,
size_t n_)
406 : range(
std::forward<Range>(range_)), n(n_) {}
409 return {std::begin(range), n};
412 return std::end(range);
421template<
typename... Ts>
422std::tuple<decltype(std::begin(std::declval<Ts>()))...>
425template<
typename... Ts>
426std::tuple<decltype(*std::begin(std::declval<Ts>()))...>
429template<
bool CHECK_ALL,
typename RangesTuple,
size_t... Is>
439 using iterator_category = std::input_iterator_tag;
440 using value_type = IteratorDerefTuple;
441 using difference_type = ptrdiff_t;
442 using pointer = value_type*;
443 using reference = value_type&;
445 explicit Iterator(IteratorsTuple&& iterators_) : iterators(std::move(iterators_)) {}
447 Iterator& operator++() {
448 (++std::get<Is>(iterators), ...);
452 Iterator operator++(
int) {
458 [[nodiscard]]
bool operator==(
const Iterator& other)
const {
460 return (... || (std::get<Is>(iterators) == std::get<Is>(other.iterators)));
462 return std::get<0>(iterators) == std::get<0>(other.iterators);
467 return value_type((*std::get<Is>(iterators))...);
471 IteratorsTuple iterators;
479 return Iterator{IteratorsTuple(std::begin(std::get<Is>(
ranges))...)};
481 [[nodiscard]]
auto end()
const {
482 return Iterator{IteratorsTuple(std::end(std::get<Is>(
ranges))...)};
486template<
typename RangesTuple,
size_t ...Is>
487[[nodiscard]]
Zip<
true, RangesTuple, Is...>
zip(RangesTuple&&
ranges, std::index_sequence<Is...>){
488 return {std::forward<RangesTuple>(
ranges)};
491template<
typename RangesTuple,
size_t ...Is>
492[[nodiscard]]
Zip<
false, RangesTuple, Is...>
zip_equal(RangesTuple&&
ranges, std::index_sequence<Is...>)
494 auto size0 = std::size(std::get<0>(
ranges)); (void)size0;
495 assert((... && (std::size(std::get<Is>(
ranges)) == size0)));
496 return {std::forward<RangesTuple>(
ranges)};
501template<
typename Range>
502[[nodiscard]]
constexpr auto drop(Range&& range,
size_t n)
507template<
typename Range>
508[[nodiscard]]
constexpr auto drop_back(Range&& range,
size_t n)
513template<
typename Range>
514[[nodiscard]]
constexpr auto reverse(Range&& range)
519template<
typename Range,
typename UnaryOp>
520[[nodiscard]]
constexpr auto transform(Range&& range, UnaryOp op)
525template<
typename Map> [[nodiscard]]
constexpr auto keys(Map&& map)
528 [](
const auto&
t) ->
auto& {
return std::get<0>(
t); });
531template<
typename Map> [[nodiscard]]
constexpr auto values(Map&& map)
534 [](
const auto&
t) ->
auto& {
return std::get<1>(
t); });
537template<
typename ForwardRange,
typename Predicate>
538[[nodiscard]]
auto filter(ForwardRange&& range, Predicate pred)
543template<
typename ForwardRange>
544[[nodiscard]]
constexpr auto take(ForwardRange&& range,
size_t n)
550template<
typename ...Ranges>
554 std::index_sequence_for<Ranges...>());
558template<
typename ...Ranges>
562 std::index_sequence_for<Ranges...>());
constexpr DropBack(Range &&range_, size_t n_)
constexpr auto begin() const
constexpr auto end() const
constexpr Drop(Range &&range_, size_t n_)
constexpr auto begin() const
constexpr auto end() const
constexpr F_Iterator end() const
decltype(std::end(std::declval< Range >())) Sentinel
constexpr Filter(Range &&range_, Predicate pred_)
constexpr F_Iterator begin() const
decltype(std::begin(std::declval< Range >())) Iterator
constexpr pointer operator->() const
typename std::iterator_traits< Iterator >::value_type value_type
typename std::iterator_traits< Iterator >::difference_type difference_type
constexpr reference operator*() const
constexpr FilteredIterator operator++(int)
typename std::iterator_traits< Iterator >::pointer pointer
constexpr FilteredIterator & operator++()
typename std::iterator_traits< Iterator >::reference reference
constexpr friend bool operator==(const FilteredIterator &x, const FilteredIterator &y)
constexpr FilteredIterator(Iterator it_, Sentinel last_, Predicate pred_)
std::forward_iterator_tag iterator_category
constexpr auto rend() const
constexpr auto end() const
constexpr auto begin() const
constexpr auto rbegin() const
constexpr Reverse(Range &&range_)
constexpr TakeIterator operator++(int)
constexpr friend bool operator==(const TakeIterator &x, const Sentinel &y)
typename std::iterator_traits< Iterator >::difference_type difference_type
constexpr TakeIterator(Iterator it_, size_t n_)
constexpr TakeIterator & operator++()
typename std::iterator_traits< Iterator >::value_type value_type
constexpr auto operator*() const
constexpr friend bool operator==(const TakeIterator &x, const TakeIterator &y)
decltype(std::begin(std::declval< Range >())) Iterator
constexpr Take_Iterator begin() const
constexpr Take(Range &&range_, size_t n_)
constexpr Sentinel end() const
decltype(std::end(std::declval< Range >())) Sentinel
Zip(Zip &&) noexcept=default
constexpr Iterator safe_next(Iterator first, Iterator last, size_t n, std::input_iterator_tag)
std::tuple< decltype(std::begin(std::declval< Ts >()))... > iterators_tuple_helper(const std::tuple< Ts... > &)
Zip< true, RangesTuple, Is... > zip(RangesTuple &&ranges, std::index_sequence< Is... >)
Zip< false, RangesTuple, Is... > zip_equal(RangesTuple &&ranges, std::index_sequence< Is... >)
constexpr Iterator safe_prev(Iterator first, Iterator last, size_t n, std::bidirectional_iterator_tag)
std::tuple< decltype(*std::begin(std::declval< Ts >()))... > iterators_deref_tuple_helper(const std::tuple< Ts... > &)
auto zip_equal(Ranges &&... ranges)
auto filter(ForwardRange &&range, Predicate pred)
constexpr auto transform(Range &&range, UnaryOp op)
constexpr auto take(ForwardRange &&range, size_t n)
constexpr auto reverse(Range &&range)
constexpr auto drop(Range &&range, size_t n)
constexpr auto drop_back(Range &&range, size_t n)
auto zip(Ranges &&... ranges)
constexpr auto keys(Map &&map)
constexpr auto values(Map &&map)
std::conditional_t< std::is_default_constructible_v< T > &&std::is_copy_assignable_v< T >, T, sreg_impl::semiregular< T > > semiregular_t
constexpr uint128 operator*(const uint128 &a, const uint128 &b)