SlHelpers
Views.h
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #pragma once
4 
5 #include <ranges>
6 
7 namespace SlHelpers::Views {
8 
12 template<std::ranges::view V>
13 class PairwiseView : public std::ranges::view_interface<PairwiseView<V>> {
14 public:
15  PairwiseView() : m_base(V()) {}
17  explicit constexpr PairwiseView(V base) : m_base(std::move(base)) {}
18 
20  auto begin() { return Iterator{std::ranges::begin(m_base), std::ranges::end(m_base)}; }
22  auto end() { return Sentinel{std::ranges::end(m_base)}; }
23 
27  struct Sentinel {
29  std::ranges::iterator_t<V> m_end;
30  };
31 
35  struct Iterator {
36  private:
37  std::ranges::iterator_t<V> m_cur;
38  std::ranges::iterator_t<V> m_next;
39  std::ranges::iterator_t<V> m_end;
40  public:
42  using ValueType = std::pair<decltype(*m_cur), decltype(*m_cur)>;
43 
45  Iterator(std::ranges::iterator_t<V> begin, std::ranges::iterator_t<V> end)
46  : m_cur(begin), m_next(begin), m_end(end) {
47  if (m_next != m_end)
48  ++m_next;
49  }
50 
52  ValueType operator*() const { return { *m_cur, *m_next }; }
53 
56  ++m_cur;
57  ++m_next;
58  return *this;
59  }
60 
62  bool operator!=(Sentinel s) const { return m_cur != s.m_end && m_next != s.m_end; }
63 
64  };
65 private:
66  V m_base;
67 };
68 
69 template<class R>
70 PairwiseView(R&&) -> PairwiseView<std::views::all_t<R>>;
71 
75 struct PairwiseFn {
77  template<std::ranges::viewable_range R>
78  auto operator()(R &&r) const {
79  return PairwiseView(std::views::all(std::forward<R>(r)));
80  }
81 
83  template<std::ranges::viewable_range R>
84  friend auto operator|(R &&r, const PairwiseFn &fn) {
85  return fn(std::forward<R>(r));
86  }
87 };
88 
89 inline constexpr PairwiseFn pairwise{};
90 
91 } // namespace
Definition: Views.h:7
auto operator()(R &&r) const
Support for pairwise(view)
Definition: Views.h:78
ValueType operator*() const
Dereference this Iterator – obtain the pair.
Definition: Views.h:52
Support struct for PairwiseView.
Definition: Views.h:75
auto begin()
Get the beginning of the range.
Definition: Views.h:20
std::ranges::iterator_t< V > m_end
The actual end of the range.
Definition: Views.h:29
Iterator & operator++()
Pre-increment this Iterator.
Definition: Views.h:55
Mimic c++23&#39;s std::views::adjacent<2>
Definition: Views.h:13
std::pair< decltype(*m_cur), decltype(*m_cur)> ValueType
Type of the stored pair in this Iterator.
Definition: Views.h:42
Iterator(std::ranges::iterator_t< V > begin, std::ranges::iterator_t< V > end)
Construct a new Iterator.
Definition: Views.h:45
The Iterator for PairwiseView.
Definition: Views.h:35
bool operator!=(Sentinel s) const
Compare to Sentinel.
Definition: Views.h:62
friend auto operator|(R &&r, const PairwiseFn &fn)
Support for view | pairwise.
Definition: Views.h:84
constexpr PairwiseView(V base)
Construct a new PairwiseView containing base.
Definition: Views.h:17
auto end()
Get the end of the range.
Definition: Views.h:22
The Sentinel for PairwiseView&#39;s Iterator.
Definition: Views.h:27