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 {
58 typename std::iterator_traits<Iterator>::iterator_category());
61 [[nodiscard]]
constexpr auto end()
const {
71template<
typename Range>
76 : range(
std::forward<Range>(range_))
81 [[nodiscard]]
constexpr auto begin()
const {
85 [[nodiscard]]
constexpr auto end()
const {
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>
338 constexpr Filter(Range&& range_, Predicate pred_)
339 : range(
std::forward<Range>(range_)), pred(pred_)
356 [[no_unique_address]] Predicate pred;
359template<
typename... Ts>
360std::tuple<decltype(std::begin(std::declval<Ts>()))...>
363template<
typename... Ts>
364std::tuple<decltype(*std::begin(std::declval<Ts>()))...>
367template<
bool CHECK_ALL,
typename RangesTuple,
size_t... Is>
377 using iterator_category = std::input_iterator_tag;
378 using value_type = IteratorDerefTuple;
379 using difference_type = ptrdiff_t;
380 using pointer = value_type*;
381 using reference = value_type&;
383 Iterator(IteratorsTuple&& iterators_) : iterators(std::move(iterators_)) {}
385 Iterator& operator++() {
386 (++std::get<Is>(iterators), ...);
390 Iterator operator++(
int) {
396 [[nodiscard]]
bool operator==(
const Iterator& other)
const {
398 return (... || (std::get<Is>(iterators) == std::get<Is>(other.iterators)));
400 return std::get<0>(iterators) == std::get<0>(other.iterators);
405 return value_type((*std::get<Is>(iterators))...);
409 IteratorsTuple iterators;
416 [[nodiscard]] Iterator
begin()
const {
419 [[nodiscard]] Iterator
end()
const {
424template<
typename RangesTuple,
size_t ...Is>
425[[nodiscard]]
Zip<
true, RangesTuple, Is...>
zip(RangesTuple&&
ranges, std::index_sequence<Is...>){
426 return {std::forward<RangesTuple>(
ranges)};
429template<
typename RangesTuple,
size_t ...Is>
430[[nodiscard]]
Zip<
false, RangesTuple, Is...>
zip_equal(RangesTuple&&
ranges, std::index_sequence<Is...>)
434 return {std::forward<RangesTuple>(
ranges)};
439template<
typename Range>
440[[nodiscard]]
constexpr auto drop(Range&& range,
size_t n)
445template<
typename Range>
446[[nodiscard]]
constexpr auto drop_back(Range&& range,
size_t n)
451template<
typename Range>
452[[nodiscard]]
constexpr auto reverse(Range&& range)
457template<
typename Range,
typename UnaryOp>
458[[nodiscard]]
constexpr auto transform(Range&& range, UnaryOp op)
463template<
typename Map> [[nodiscard]]
constexpr auto keys(Map&& map)
466 [](
const auto&
t) ->
auto& {
return std::get<0>(
t); });
469template<
typename Map> [[nodiscard]]
constexpr auto values(Map&& map)
472 [](
const auto&
t) ->
auto& {
return std::get<1>(
t); });
475template<
typename ForwardRange,
typename Predicate>
476[[nodiscard]]
auto filter(ForwardRange&& range, Predicate pred)
482template<
typename ...Ranges>
486 std::index_sequence_for<Ranges...>());
490template<
typename ...Ranges>
494 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_)
Zip(Zip &&) noexcept=default
bool operator==(const Event &x, const Event &y)
auto copy(InputRange &&range, OutputIter out)
size_t size(std::string_view utf8)
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 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)
constexpr auto begin(const zstring_view &x)
constexpr auto end(const zstring_view &x)