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);
422template<
typename Range>
423[[nodiscard]]
constexpr auto drop(Range&& range,
size_t n)
428template<
typename Range>
429[[nodiscard]]
constexpr auto drop_back(Range&& range,
size_t n)
434template<
typename Range>
435[[nodiscard]]
constexpr auto reverse(Range&& range)
440template<
typename Range,
typename UnaryOp>
441[[nodiscard]]
constexpr auto transform(Range&& range, UnaryOp op)
446template<
typename Map> [[nodiscard]]
constexpr auto keys(Map&& map)
449 [](
const auto&
t) ->
auto& {
return std::get<0>(
t); });
452template<
typename Map> [[nodiscard]]
constexpr auto values(Map&& map)
455 [](
const auto&
t) ->
auto& {
return std::get<1>(
t); });
458template<
typename ForwardRange,
typename Predicate>
459[[nodiscard]]
auto filter(ForwardRange&& range, Predicate pred)
464template<
typename ForwardRange>
465[[nodiscard]]
constexpr auto take(ForwardRange&& range,
size_t n)
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
constexpr Iterator safe_next(Iterator first, Iterator last, size_t n, std::input_iterator_tag)
constexpr Iterator safe_prev(Iterator first, Iterator last, size_t n, std::bidirectional_iterator_tag)
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)
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