Zen C++ Libraries
Zero-dependency re-usable components for C++
Loading...
Searching...
No Matches
mapped_iterator.hpp
1
2#pragma once
3
4#include <iterator>
5#include <type_traits>
6
7#include "zen/config.hpp"
8
9ZEN_NAMESPACE_START
10
11template<typename IterT, typename F>
12class mapped_iterator {
13
14 IterT iterator;
15 F func;
16
17 using traits = std::iterator_traits<IterT>;
18
19public:
20
21 using iterator_category = traits::iterator_category;
22
23 using value_type = typename std::invoke_result<F, typename IterT::value_type>::type;
24
30 using reference = value_type;
31
32 using difference_type = traits::difference_type;
33
34 using pointer = traits::pointer;
35
36 mapped_iterator(IterT iterator, F func):
37 iterator(iterator), func(func) {}
38
39 // TODO make this work with arbitrary F
40 bool operator==(const mapped_iterator& other) const {
41 return iterator == other.iterator;
42 }
43
44 // TODO make this work with arbitrary F
45 bool operator!=(const mapped_iterator& other) const {
46 return iterator != other.iterator;
47 }
48
49 mapped_iterator& operator++() requires(std::incrementable<IterT>) {
50 ++iterator;
51 return *this;
52 }
53
54 mapped_iterator& operator--() requires(std::bidirectional_iterator<IterT>) {
55 --iterator;
56 return *this;
57 }
58
59 mapped_iterator operator++(int) requires(std::incrementable<IterT>) {
60 return mapped_iterator { iterator++, func };
61 }
62
63 mapped_iterator operator--(int) requires(std::bidirectional_iterator<IterT>) {
64 return mapped_iterator { iterator--, func };
65 }
66
67 IterT& operator+(std::ptrdiff_t offset) requires(std::random_access_iterator<IterT>) {
68 iterator += offset;
69 return *this;
70 }
71
72 IterT& operator-(std::ptrdiff_t offset) requires(std::random_access_iterator<IterT>) {
73 iterator -= offset;
74 return *this;
75 }
76
77 reference operator*() requires(std::indirectly_readable<IterT>) {
78 return func(*iterator);
79 }
80
81 IterT& operator=(value_type&& value) requires(std::indirectly_writable<IterT, value_type>) {
82 iterator = value;
83 return *this;
84 }
85
86};
87
88template<std::input_iterator IterT, typename F>
89auto map(IterT iterator, F func) {
90 return mapped_iterator { iterator, func };
91}
92
93ZEN_NAMESPACE_END
94
95namespace std {
96
97template <typename IterT, typename F>
98struct iterator_traits<zen::mapped_iterator<IterT, F>>
99{
100 using difference_type = ZEN_NAMESPACE::mapped_iterator<IterT, F>::difference_type;
101 using value_type = ZEN_NAMESPACE::mapped_iterator<IterT, F>::value_type;
102 using pointer = ZEN_NAMESPACE::mapped_iterator<IterT, F>::pointer;
103 using reference = ZEN_NAMESPACE::mapped_iterator<IterT, F>::reference;
104 using iterator_category = ZEN_NAMESPACE::mapped_iterator<IterT, F>::iterator_category;
105};
106
107}
108
Definition mapped_iterator.hpp:12
value_type reference
Definition mapped_iterator.hpp:30
Definition concepts.hpp:45