guanaqo main
Utilities for scientific software
Loading...
Searching...
No Matches
iter-adapter.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @ingroup ranges
5/// Adapter turning iterator pairs into a view.
6
7#include <concepts>
8#include <iterator>
9#include <ranges>
10#include <type_traits>
11#include <utility>
12
13namespace guanaqo {
14
15/// @ingroup ranges
16template <class It>
18 // P2325R3: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2325r3.html
19 iter_range_adapter() = default;
20 iter_range_adapter(It it) : it{std::forward<It>(it)} {}
21 It it;
22
23 struct sentinel_t {};
24
25 struct iter_t : std::remove_cvref_t<It> {
26 // P2325R3: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2325r3.html
27 iter_t() = default;
28 iter_t(It it) : std::remove_cvref_t<It>{std::forward<It>(it)} {}
29
30 bool operator!=(sentinel_t) const { return static_cast<bool>(*this); }
31 bool operator==(sentinel_t) const { return !static_cast<bool>(*this); }
32 // TODO: For Clang bug
33 friend bool operator!=(sentinel_t s, const iter_t &i) { return i != s; }
34 friend bool operator==(sentinel_t s, const iter_t &i) { return i == s; }
35
37 this->std::remove_cvref_t<It>::operator++();
38 return *this;
39 }
40 iter_t operator++(int i) const {
41 this->std::remove_cvref_t<It>::operator++(i);
42 return *this;
43 }
44 const iter_t &operator*() const { return *this; }
46 using pointer = iter_t *;
47 using reference = iter_t &;
48 using difference_type = std::ptrdiff_t;
49 };
50
51 auto begin() const & -> std::input_or_output_iterator auto {
52 return iter_t{it};
53 }
54 auto begin() && -> std::input_or_output_iterator auto {
55 return iter_t{std::forward<It>(it)};
56 }
57 auto end() const /* -> std::sentinel_for<iter_t> auto */ {
58 return sentinel_t{};
59 }
60};
61
62} // namespace guanaqo
63
64// Make iter_range_adapter available as an std::ranges view.
65// Iterators remain valid even if the range is destroyed.
66// Assume that the user takes care of lifetime, similar to std::span.
67#ifndef DOXYGEN
68template <class It>
69inline constexpr bool ::std::ranges::enable_borrowed_range<
71#endif
bool operator==(sentinel_t) const
friend bool operator==(sentinel_t s, const iter_t &i)
friend bool operator!=(sentinel_t s, const iter_t &i)
bool operator!=(sentinel_t) const
auto begin() &&-> std::input_or_output_iterator auto
auto begin() const &-> std::input_or_output_iterator auto