Clingo
Loading...
Searching...
No Matches
enumerate.hh
1#pragma once
2
3#include <concepts>
4#include <iterator>
5
6namespace CppClingo::Util {
7
10
12template <typename T>
13concept iterable = requires(T x) {
14 x.begin();
15 x.end();
16};
17
19template <class T>
20 requires std::forward_iterator<T> || std::integral<T>
22
24template <std::forward_iterator T> class enumerate<T> {
25 public:
27 class iterator {
28 public:
30 using iterator_category = std::forward_iterator_tag;
32 using value_type = std::pair<size_t, typename T::reference>;
34 using difference_type = std::make_signed_t<size_t>;
35
37 iterator() = default;
38
40 iterator(size_t num, T cur) : num_{num}, cur_{cur} {}
41
43 auto operator*() const -> value_type { return {num_, *cur_}; }
44
46 auto operator++() -> iterator & {
47 ++cur_;
48 ++num_;
49 return *this;
50 }
51
53 auto operator++(int) -> iterator {
54 iterator tmp = *this;
55 ++(*this);
56 return tmp;
57 }
58
60 friend auto operator==(iterator const &a, iterator const &b) -> bool { return a.cur_ == b.cur_; }
61
62 private:
63 size_t num_ = 0;
64 T cur_;
65 };
66 static_assert(std::forward_iterator<iterator>);
67
69 template <iterable U>
70 requires std::is_lvalue_reference_v<U>
71 // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
72 enumerate(U &&x) : enumerate{x.begin(), x.end()} {}
74 enumerate(T begin, T end) : begin_{begin}, end_{end} {}
75
77 [[nodiscard]] auto begin() const -> iterator { return {0, begin_}; }
79 [[nodiscard]] auto end() const -> iterator { return {0, end_}; }
80
81 private:
82 T begin_;
83 T end_;
84};
85
87template <iterable U>
88 requires std::is_lvalue_reference_v<U>
89enumerate(U &&x) -> enumerate<decltype(x.begin())>;
90
92template <std::forward_iterator T> enumerate(T begin, T end) -> enumerate<T>;
93
95template <std::integral T> class enumerate<T> {
96 public:
98 enumerate(T begin, T end) : begin_{begin}, end_{end} {}
100 enumerate(T end) : begin_{}, end_{end} {}
101
102 class iterator {
103 public:
105 using iterator_category = std::forward_iterator_tag;
107 using value_type = T;
109 using difference_type = std::make_signed_t<value_type>;
110
112 iterator() = default;
113
115 iterator(value_type cur) : cur_{cur} {}
116
118 auto operator*() const -> value_type { return cur_; }
119
121 auto operator++() -> iterator & {
122 ++cur_;
123 return *this;
124 }
125
127 auto operator++(int) -> iterator {
128 iterator tmp = *this;
129 ++(*this);
130 return tmp;
131 }
132
134 friend auto operator==(iterator const &a, iterator const &b) -> bool = default;
135
136 private:
137 value_type cur_ = 0;
138 };
139 static_assert(std::forward_iterator<iterator>);
140
142 [[nodiscard]] auto begin() const -> iterator { return {begin_}; }
144 [[nodiscard]] auto end() const -> iterator { return {end_}; }
145
146 private:
147 T begin_;
148 T end_;
149};
150
152template <std::integral T> enumerate(T end) -> enumerate<T>;
153
155template <std::integral T> enumerate(T begin, T end) -> enumerate<T>;
156
158
159} // namespace CppClingo::Util
iterator(value_type cur)
Construct an iterator from an integer.
Definition enumerate.hh:115
auto operator*() const -> value_type
Get the reference.
Definition enumerate.hh:43
auto operator++(int) -> iterator
Advance the iterator.
Definition enumerate.hh:53
friend auto operator==(iterator const &a, iterator const &b) -> bool=default
Compare two iterators.
iterator()=default
Construct an invalid iterator.
auto operator++() -> iterator &
Advance the iterator.
Definition enumerate.hh:46
iterator(size_t num, T cur)
Construct an iterator from an index and a forward iterator.
Definition enumerate.hh:40
std::make_signed_t< size_t > difference_type
The difference type.
Definition enumerate.hh:34
friend auto operator==(iterator const &a, iterator const &b) -> bool
Compare two iterators.
Definition enumerate.hh:60
std::forward_iterator_tag iterator_category
The iterator category.
Definition enumerate.hh:30
std::pair< size_t, typename T::reference > value_type
The index and the reference the iterator is referring to.
Definition enumerate.hh:32
enumerate(T begin, T end)
Enumerate an iterator range.
Definition enumerate.hh:74
auto end() const -> iterator
Get the end iterator (sentinel).
Definition enumerate.hh:79
enumerate(U &&x)
Enumerate an iterable collection.
Definition enumerate.hh:72
auto begin() const -> iterator
Get the begin iterator.
Definition enumerate.hh:77
enumerate(T end)
Enumerate an integer range.
Definition enumerate.hh:100
A python style enumerate/range object.
Definition enumerate.hh:21
Concept ensuring a collection is iterable.
Definition enumerate.hh:13