|
auto | operator+ (iterator_type left, difference_type_arg< iterator_type > auto const off) |
|
auto | operator+= (iterator_type &self, difference_type_arg< iterator_type > auto const offset) -> auto & |
|
auto | operator+ (difference_type_arg< iterator_type > auto const offset, iterator_type right) |
|
auto | operator- (iterator_type left, difference_type_arg< iterator_type > auto off) |
|
auto | operator-= (iterator_type &left, difference_type_arg< iterator_type > auto off) -> auto & |
|
auto | operator-= (iterator_type &left, iter_sentinel_arg< iterator_type > auto sentinel) -> auto & |
|
auto | operator- (iterator_type const &left, iterator_type const &right) |
|
auto | operator- (iterator_type const &left, iter_sentinel_arg< iterator_type > auto const right) |
|
auto | operator- (iter_sentinel_arg< iterator_type > auto const right, iterator_type const &left) |
|
auto | operator<=> (iterator_type const &left, iterator_type const &right) |
|
auto | operator== (iterator_type const &left, iterator_type const &right) |
|
auto | operator!= (iterator_type const &left, iterator_type const &right) |
|
auto | operator== (iterator_type const &iter, iter_sentinel_arg< iterator_type > auto const) -> bool |
|
auto | operator!= (iterator_type const &iter, iter_sentinel_arg< iterator_type > auto const) -> bool |
|
auto | operator== (iter_sentinel_arg< iterator_type > auto const, iterator_type const &iter) -> bool |
|
auto | operator!= (iter_sentinel_arg< iterator_type > auto const, iterator_type const &iter) -> bool |
|
template<typename Iter>
class tatooine::iterator_facade< Iter >
C++20 implementation of an iterator facade.
Code originally taken from here: https://vector-of-bool.github.io/2020/06/13/cpp20-iter-facade.html
iterator_facade uses CRTP for inheritance.
It automatically infers value_type
(see infer_value_type), difference_type
(see infer_difference_type), iterator_category
, reference
and pointer
in the std::iterator_traits. Alternatively value_type
can be explicitely specified in the iterator implementation. difference_type
can be implicitely specified by implementing a distance_to
method.
The implementation needs at least the methods dereference
, increment
, equal
and a default constructor.
One can also use sentinels by specifying the type sentinel_type
in the iterator implementation. With this your iterator implementation needs to specify an equal
method.
This is an example of how to implement an iterator class with help of iterator_facade:
#include <algorithm>
#include <iostream>
#include <ranges>
#include <vector>
struct my_range {
struct sentinel_type {};
std::size_t m_vh{};
constexpr iterator() =
default;
constexpr explicit iterator(std::size_t const vh) : m_vh{vh} {}
constexpr iterator(iterator const&) = default;
constexpr iterator(iterator&&) noexcept = default;
constexpr auto operator=(iterator const&) -> iterator& = default;
constexpr auto operator=(iterator&&) noexcept -> iterator& = default;
~iterator() = default;
constexpr auto increment() { ++m_vh; }
constexpr auto decrement() { --m_vh; }
[[nodiscard]] constexpr auto dereference() const { return m_vh; }
[[nodiscard]] constexpr auto equal(iterator other) const {
return m_vh == other.m_vh;
}
[[nodiscard]] constexpr auto at_end() const { return m_vh == 10; }
};
static constexpr auto begin() {
return iterator{std::size_t{0}}; }
static constexpr auto end() {
return typename iterator::sentinel_type{}; }
};
template <>
inline constexpr const bool std::ranges::enable_borrowed_range<my_range> = true;
auto main() -> int {
auto v = std::vector<std::size_t>{};
auto r = my_range{};
for (auto i : r) {
std::cout << i << '\n';
}
auto square = [](
auto const x) {
return x * x; };
using namespace std::ranges;
copy(my_range{} | views::transform(square), std::back_inserter(v));
copy(r | views::transform(square), std::back_inserter(v));
for (auto i : v) {
std::cout << i << '\n';
}
using it_traits = std::iterator_traits<my_range::iterator>;
std::cout << "iterator_category: "
<< type_name<it_traits::iterator_category>() << '\n';
std::cout << "reference: " << type_name<it_traits::reference>()
<< '\n';
std::cout << "pointer: " << type_name<it_traits::pointer>() << '\n';
std::cout << "value_type: " << type_name<it_traits::value_type>()
<< '\n';
std::cout << "difference_type: " << type_name<it_traits::difference_type>()
<< '\n';
}
C++20 implementation of an iterator facade.
Definition: iterator_facade.h:154
Definition: algorithm.h:6
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322