open62541pp 0.17.0
C++ wrapper of open62541
Loading...
Searching...
No Matches
iterator.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <functional> // invoke
4#include <iterator>
5#include <type_traits>
6#include <utility> // move
7
8namespace opcua::detail {
9
10template <typename Iter, typename F>
11class TransformIterator {
12public:
13 using iterator_type = Iter;
14 using iterator_category = typename std::iterator_traits<Iter>::iterator_category;
15 using value_type =
16 typename std::invoke_result_t<F, typename std::iterator_traits<Iter>::value_type>;
17 using difference_type = typename std::iterator_traits<Iter>::difference_type;
18 using pointer = value_type*;
19 using reference = value_type&;
20
21 constexpr TransformIterator(Iter it, F func)
22 : it_(std::move(it)),
23 func_(std::move(func)) {}
24
25 constexpr const Iter& base() const& noexcept {
26 return it_;
27 }
28
29 constexpr Iter base() && {
30 return it_;
31 }
32
33 constexpr value_type operator*() const {
34 return std::invoke(func_, *it_);
35 }
36
37 constexpr value_type operator[](difference_type n) const {
38 return *(*this + n);
39 }
40
41 constexpr TransformIterator& operator++() {
42 ++it_;
43 return *this;
44 }
45
46 constexpr TransformIterator operator++(int) { // NOLINT(cert-dcl21-cpp)
47 auto temp = *this;
48 ++(*this);
49 return temp;
50 }
51
52 constexpr TransformIterator operator+(difference_type n) const {
53 return {it_ + n, func_};
54 }
55
56 constexpr TransformIterator& operator+=(difference_type n) {
57 it_ += n;
58 return *this;
59 }
60
61 constexpr TransformIterator& operator--() {
62 --it_;
63 return *this;
64 }
65
66 constexpr TransformIterator operator--(int) { // NOLINT(cert-dcl21-cpp)
67 auto temp = *this;
68 --(*this);
69 return temp;
70 }
71
72 constexpr TransformIterator operator-(difference_type n) const {
73 return {it_ - n, func_};
74 }
75
76 constexpr TransformIterator& operator-=(difference_type n) {
77 it_ -= n;
78 return *this;
79 }
80
81private:
82 Iter it_;
83 std::decay_t<F> func_;
84};
85
86template <typename Iter1, typename F1, typename Iter2, typename F2>
87constexpr auto operator==(
88 const TransformIterator<Iter1, F1>& lhs, const TransformIterator<Iter2, F2>& rhs
89) {
90 return lhs.base() == rhs.base();
91}
92
93template <typename Iter1, typename F1, typename Iter2, typename F2>
94constexpr auto operator!=(
95 const TransformIterator<Iter1, F1>& lhs, const TransformIterator<Iter2, F2>& rhs
96) {
97 return lhs.base() != rhs.base();
98}
99
100template <typename Iter1, typename F1, typename Iter2, typename F2>
101constexpr auto operator<(
102 const TransformIterator<Iter1, F1>& lhs, const TransformIterator<Iter2, F2>& rhs
103) {
104 return lhs.base() < rhs.base();
105}
106
107template <typename Iter1, typename F1, typename Iter2, typename F2>
108constexpr auto operator<=(
109 const TransformIterator<Iter1, F1>& lhs, const TransformIterator<Iter2, F2>& rhs
110) {
111 return lhs.base() <= rhs.base();
112}
113
114template <typename Iter1, typename F1, typename Iter2, typename F2>
115constexpr auto operator>(
116 const TransformIterator<Iter1, F1>& lhs, const TransformIterator<Iter2, F2>& rhs
117) {
118 return lhs.base() > rhs.base();
119}
120
121template <typename Iter1, typename F1, typename Iter2, typename F2>
122constexpr auto operator>=(
123 const TransformIterator<Iter1, F1>& lhs, const TransformIterator<Iter2, F2>& rhs
124) {
125 return lhs.base() >= rhs.base();
126}
127
128template <typename Iter, typename F>
129constexpr TransformIterator<Iter, F> operator+(
130 const TransformIterator<Iter, F>& it, typename TransformIterator<Iter, F>::difference_type n
131) {
132 return {it.base() + n, it.func_};
133}
134
135template <typename Iter1, typename F1, typename Iter2, typename F2>
136constexpr auto operator-(
137 const TransformIterator<Iter1, F1>& lhs, const TransformIterator<Iter2, F2>& rhs
138) {
139 return lhs.base() - rhs.base();
140}
141
142} // namespace opcua::detail