summaryrefslogtreecommitdiff
path: root/src/ranges.hh
diff options
context:
space:
mode:
authorFrank LENORMAND <lenormf@gmail.com>2021-10-21 10:52:08 +0200
committerFrank LENORMAND <lenormf@gmail.com>2021-10-21 10:58:46 +0200
commit0af234a3293c632479ed708388fd73547851a9fd (patch)
treeb70a942f5dcd26c6747b22aa1d49e746c1911025 /src/ranges.hh
parent689553c2e9b953a9d3822528d4ad858af95fb6a2 (diff)
src: Implement the `enumerate()` range filter
Diffstat (limited to 'src/ranges.hh')
-rw-r--r--src/ranges.hh48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/ranges.hh b/src/ranges.hh
index bd3edd9b..3480cab9 100644
--- a/src/ranges.hh
+++ b/src/ranges.hh
@@ -5,6 +5,7 @@
#include <utility>
#include <iterator>
#include <numeric>
+#include <tuple>
#include "constexpr_utils.hh"
@@ -155,6 +156,53 @@ inline auto filter(Filter f)
});
}
+template<typename Range>
+struct EnumerateView
+{
+ using RangeIt = IteratorOf<Range>;
+
+ struct Iterator : std::iterator<std::forward_iterator_tag,
+ typename std::iterator_traits<RangeIt>::value_type>
+ {
+ Iterator(size_t index, RangeIt it, RangeIt end)
+ : m_index{index}, m_it{std::move(it)}, m_end{std::move(end)} {}
+
+ decltype(auto) operator*() { return std::make_tuple(m_index, *m_it); }
+ Iterator& operator++() { ++m_index; ++m_it; return *this; }
+ Iterator operator++(int) { auto copy = *this; ++(*this); return copy; }
+
+ friend bool operator==(const Iterator& lhs, const Iterator& rhs)
+ {
+ return lhs.m_index == rhs.m_index and lhs.m_it == rhs.m_it;
+ }
+
+ friend bool operator!=(const Iterator& lhs, const Iterator& rhs)
+ {
+ return not (lhs == rhs);
+ }
+
+ const RangeIt& base() const { return m_it; }
+
+ private:
+ size_t m_index;
+ RangeIt m_it;
+ RangeIt m_end;
+ };
+
+ Iterator begin() const { return {0, std::begin(m_range), std::end(m_range)}; }
+ Iterator end() const { return {std::size(m_range), std::end(m_range), std::end(m_range)}; }
+
+ Range m_range;
+};
+
+inline auto enumerate()
+{
+ return make_view_factory([](auto&& range) {
+ using Range = decltype(range);
+ return EnumerateView<decay_range<Range>>{std::forward<Range>(range)};
+ });
+}
+
template<typename Range, typename Transform>
struct TransformView
{