guanaqo 1.0.0-alpha.27
Utilities for scientific software
Loading...
Searching...
No Matches
enumerate.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @ingroup ranges
5/// enumerate() range adapter.
6
7#include <ranges>
8#include <utility>
9
10namespace guanaqo {
11
12/// @ingroup ranges
13template <class Rng>
14struct enumerate_t : std::ranges::view_interface<enumerate_t<Rng>> {
15 Rng rng;
16
17 // P2325R3: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2325r3.html
18 enumerate_t() = default;
19 enumerate_t(Rng rng) : rng{std::forward<Rng>(rng)} {}
20
21 using begin_t = decltype(std::ranges::begin(std::as_const(rng)));
22 using end_t = decltype(std::ranges::end(std::as_const(rng)));
23
24 struct sentinel_t {
26 };
27
28 struct iter_t {
29 // P2325R3: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2325r3.html
30 iter_t() = default;
31 iter_t(begin_t &&it) : it{std::forward<begin_t>(it)} {}
32
33 using index_t = std::ranges::range_difference_t<Rng>;
36
37 using difference_type = std::ptrdiff_t;
38 using value_type = std::tuple<index_t, decltype(*it)>;
39
40 bool operator!=(sentinel_t s) const { return s.it != it; }
41 bool operator==(sentinel_t s) const { return s.it == it; }
42 // TODO: For Clang bug
43 friend bool operator!=(sentinel_t s, const iter_t &i) { return i != s; }
44 friend bool operator==(sentinel_t s, const iter_t &i) { return i == s; }
45
47 ++it;
48 ++index;
49 return *this;
50 }
51 iter_t operator++(int) const {
52 auto tmp = *this;
53 ++*this;
54 return tmp;
55 }
56
57 value_type operator*() const { return {index, *it}; }
58 };
59
60 auto begin() const -> std::input_or_output_iterator auto {
61 return iter_t{std::ranges::begin(rng)};
62 }
63 auto end() const
64 // -> std::sentinel_for<iter_t> auto
65 {
66 return sentinel_t{std::ranges::end(rng)};
67 }
68};
69
70/// @ingroup ranges
71template <class Rng>
72auto enumerate(Rng &&rng) {
73 return enumerate_t<std::views::all_t<Rng>>{std::forward<Rng>(rng)};
74}
75
76} // namespace guanaqo
auto enumerate(Rng &&rng)
Definition enumerate.hpp:72
std::ptrdiff_t difference_type
Definition enumerate.hpp:37
value_type operator*() const
Definition enumerate.hpp:57
bool operator!=(sentinel_t s) const
Definition enumerate.hpp:40
bool operator==(sentinel_t s) const
Definition enumerate.hpp:41
friend bool operator==(sentinel_t s, const iter_t &i)
Definition enumerate.hpp:44
friend bool operator!=(sentinel_t s, const iter_t &i)
Definition enumerate.hpp:43
iter_t operator++(int) const
Definition enumerate.hpp:51
std::ranges::range_difference_t< Rng > index_t
Definition enumerate.hpp:33
std::tuple< index_t, decltype(*it)> value_type
Definition enumerate.hpp:38
auto begin() const -> std::input_or_output_iterator auto
Definition enumerate.hpp:60
decltype(std::ranges::begin(std::as_const(rng))) begin_t
Definition enumerate.hpp:21
decltype(std::ranges::end(std::as_const(rng))) end_t
Definition enumerate.hpp:22