Distributed Ranges
Loading...
Searching...
No Matches
iterator_adaptor.hpp
1// SPDX-FileCopyrightText: Intel Corporation
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#pragma once
6
7#include <iterator>
8#include <type_traits>
9
10#include <dr/detail/ranges_shim.hpp>
11
12namespace dr {
13
14namespace {
15
16template <typename R>
17concept has_segments_method = requires(R r) {
18 { r.segments() };
19};
20
21} // namespace
22
23template <typename Accessor> class iterator_adaptor {
24public:
25 using accessor_type = Accessor;
26 using const_accessor_type = typename Accessor::const_iterator_accessor;
27 using nonconst_accessor_type = typename Accessor::nonconst_iterator_accessor;
28
29 using difference_type = typename Accessor::difference_type;
30 using value_type = typename Accessor::value_type;
33 using reference = typename Accessor::reference;
34 using iterator_category = typename Accessor::iterator_category;
35
37
38 static_assert(std::is_same_v<iterator, iterator_adaptor<Accessor>>);
39
40 iterator_adaptor() = default;
41 ~iterator_adaptor() = default;
42 iterator_adaptor(const iterator_adaptor &) = default;
43 iterator_adaptor &operator=(const iterator_adaptor &) = default;
44
45 template <typename... Args>
46 requires(
47 sizeof...(Args) >= 1 &&
48 !((sizeof...(Args) == 1 &&
49 (std::is_same_v<nonconst_iterator, std::decay_t<Args>> || ...)) ||
50 (std::is_same_v<const_iterator, std::decay_t<Args>> || ...) ||
51 (std::is_same_v<nonconst_accessor_type, std::decay_t<Args>> || ...) ||
52 (std::is_same_v<const_accessor_type, std::decay_t<Args>> || ...)) &&
53 std::is_constructible_v<accessor_type, Args...>)
54 iterator_adaptor(Args &&...args) : accessor_(std::forward<Args>(args)...) {}
55
56 iterator_adaptor(const accessor_type &accessor) : accessor_(accessor) {}
57 iterator_adaptor(const const_accessor_type &accessor)
58 requires(!std::is_same_v<accessor_type, const_accessor_type>)
59 : accessor_(accessor) {}
60
61 operator const_iterator() const
62 requires(!std::is_same_v<iterator, const_iterator>)
63 {
64 return const_iterator(accessor_);
65 }
66
67 bool operator==(const_iterator other) const {
68 return accessor_ == other.accessor_;
69 }
70
71 bool operator!=(const_iterator other) const { return !(*this == other); }
72
73 bool operator<(const_iterator other) const
74 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
75 {
76 return accessor_ < other.accessor_;
77 }
78
79 bool operator<=(const_iterator other) const
80 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
81 {
82 return *this < other || *this == other;
83 }
84
85 bool operator>(const_iterator other) const
86 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
87 {
88 return !(*this <= other);
89 }
90
91 bool operator>=(const_iterator other) const
92 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
93 {
94 return !(*this < other);
95 }
96
97 reference operator*() const { return *accessor_; }
98
99 reference operator[](difference_type offset) const
100 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
101 {
102 return *(*this + offset);
103 }
104
105 iterator &operator+=(difference_type offset) noexcept
106 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
107 {
108 accessor_ += offset;
109 return *this;
110 }
111
112 iterator &operator-=(difference_type offset) noexcept
113 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
114 {
115 accessor_ += -offset;
116 return *this;
117 }
118
119 iterator operator+(difference_type offset) const
120 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
121 {
122 iterator other = *this;
123 other += offset;
124 return other;
125 }
126
127 iterator operator-(difference_type offset) const
128 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
129 {
130 iterator other = *this;
131 other += -offset;
132 return other;
133 }
134
135 difference_type operator-(const_iterator other) const
136 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
137 {
138 return accessor_ - other.accessor_;
139 }
140
141 iterator &operator++() noexcept
142 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
143 {
144 *this += 1;
145 return *this;
146 }
147
148 iterator &operator++() noexcept
149 requires(
150 !std::is_same_v<iterator_category, std::random_access_iterator_tag>)
151 {
152 ++accessor_;
153 return *this;
154 }
155
156 iterator operator++(int) noexcept {
157 iterator other = *this;
158 ++(*this);
159 return other;
160 }
161
162 iterator &operator--() noexcept
163 requires(
164 std::is_same_v<iterator_category, std::random_access_iterator_tag> ||
165 std::is_same_v<iterator_category, std::bidirectional_iterator_tag>)
166 {
167 *this += -1;
168 return *this;
169 }
170
171 iterator operator--(int) noexcept
172 requires(
173 std::is_same_v<iterator_category, std::random_access_iterator_tag> ||
174 std::is_same_v<iterator_category, std::bidirectional_iterator_tag>)
175 {
176 iterator other = *this;
177 --(*this);
178 return other;
179 }
180
181 auto segments() const noexcept
182 requires(has_segments_method<accessor_type>)
183 {
184 return accessor_.segments();
185 }
186
187 friend iterator operator+(difference_type n, iterator iter)
188 requires(std::is_same_v<iterator_category, std::random_access_iterator_tag>)
189 {
190 return iter + n;
191 }
192
193private:
194 friend const_iterator;
195 friend nonconst_iterator;
196
197 accessor_type accessor_;
198};
199
200} // namespace dr
Definition: iterator_adaptor.hpp:23
Definition: iterator_adaptor.hpp:17