Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qiteratorfacade_p.h
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QITERATORFACADE_P_H
5#define QITERATORFACADE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qtconfigmacros.h>
19#include <QtCore/qxptype_traits.h>
20
21#include <iterator>
22#include <type_traits>
23
24QT_BEGIN_NAMESPACE
25
26namespace QtMultimediaPrivate {
27
28namespace impl {
29
30#if defined(__cpp_concepts)
31
32template <typename T>
33concept has_increment = requires(T & t)
34{
35 t.increment();
36};
37
38template <typename T>
39concept has_decrement = requires(T & t)
40{
41 t.decrement();
42};
43
44template <typename T>
45concept has_equals = requires(const T &t1, const T &t2)
46{
47 t1.equals(t2);
48};
49
50#else
51
52template <typename T>
53using increment_expr = decltype(std::declval<T &>().increment());
54
55template <typename T>
56using decrement_expr = decltype(std::declval<T &>().decrement());
57
58template <typename T>
59using equals_expr = decltype(std::declval<const T &>().equals(std::declval<const T &>()));
60
61template <typename T>
62constexpr bool has_increment = qxp::is_detected<increment_expr, T>::value;
63
64template <typename T>
65constexpr bool has_decrement = qxp::is_detected<decrement_expr, T>::value;
66
67template <typename T>
68constexpr bool has_equals = qxp::is_detected<equals_expr, T>::value;
69
70#endif
71
72} // namespace impl
73
74// CRTP helper that turns a minimal iterator implementation into a full one.
75//
76// Derived must always implement:
77// <value> dereference() const - access the current element
78//
79// and, for single-pass/forward/bidirectional iteration:
80// void increment() - move one step forward
81// bool equals(const Derived &o) const - compare iterator positions
82// void decrement() - move one step backward (optional; enables operator--)
83//
84// For random access iteration, Derived may instead (or additionally) implement:
85// void advance_by(difference_type n) - move n steps forward (n may be negative)
86// difference_type distance_to(const Derived &o) const
87// - signed number of steps from *this to o
88template <typename Derived, typename ValueType, typename IteratorCategory = std::input_iterator_tag,
89 typename Reference = ValueType &, typename DifferenceType = std::ptrdiff_t>
91{
92public:
93 using iterator_category = IteratorCategory;
94 using value_type = ValueType;
95 using reference = Reference;
96 using difference_type = DifferenceType;
99
100 constexpr decltype(auto) operator*() const { return derived().dereference(); }
101
102 constexpr Derived &operator++()
103 {
104 stepForward();
105 return derived();
106 }
107
108 constexpr Derived operator++(int)
109 {
110 Derived result = derived();
111 stepForward();
112 return result;
113 }
114
115 constexpr Derived &operator--()
116 {
117 stepBackward();
118 return derived();
119 }
120
121 constexpr Derived operator--(int)
122 {
123 Derived result = derived();
124 stepBackward();
125 return result;
126 }
127
128 template <typename N>
129#if defined(__cpp_concepts)
131 {
132 d.advance_by(n);
133 }
134#endif
135 constexpr Derived &operator+=(N n)
136 {
137 derived().advance_by(n);
138 return derived();
139 }
140
141 template <typename N>
142#if defined(__cpp_concepts)
144 {
145 d.advance_by(n);
146 }
147#endif
148 constexpr Derived &operator-=(N n)
149 {
150 derived().advance_by(-n);
151 return derived();
152 }
153
154 template <typename N>
155#if defined(__cpp_concepts)
157 {
158 d.advance_by(n);
159 }
160#endif
161 friend constexpr Derived operator+(Derived it, N n)
162 {
163 it.advance_by(n);
164 return it;
165 }
166
167 template <typename N>
168#if defined(__cpp_concepts)
170 {
171 d.advance_by(n);
172 }
173#endif
174 friend constexpr Derived operator+(N n, Derived it)
175 {
176 it.advance_by(n);
177 return it;
178 }
179
180 template <typename N>
181#if defined(__cpp_concepts)
183 {
184 d.advance_by(n);
185 }
186#endif
187 friend constexpr Derived operator-(Derived it, N n)
188 {
189 it.advance_by(-n);
190 return it;
191 }
192
193 template <typename N>
194#if defined(__cpp_concepts)
196 {
197 d.advance_by(n);
198 }
199#endif
200 friend constexpr Derived operator-(N n, Derived it)
201 {
202 it.advance_by(-n);
203 return it;
204 }
205
206 template <typename N>
207#if defined(__cpp_concepts)
209 {
210 d.advance_by(n);
211 }
212#endif
213 constexpr decltype(auto) operator[](N n) const
214 {
215 Derived tmp = derived();
216 tmp.advance_by(n);
217 return tmp.dereference();
218 }
219
220 friend constexpr auto operator-(const Derived &lhs, const Derived &rhs)
221#if defined(__cpp_concepts)
222 requires requires(const Derived &d)
223 {
224 d.distance_to(d);
225 }
226#endif
227 {
228 return rhs.distance_to(lhs);
229 }
230
231 friend constexpr bool operator<(const Derived &lhs, const Derived &rhs)
232#if defined(__cpp_concepts)
233 requires requires(const Derived &d)
234 {
235 d.distance_to(d);
236 }
237#endif
238 {
239 return lhs.distance_to(rhs) > 0;
240 }
241
242 friend constexpr bool operator<=(const Derived &lhs, const Derived &rhs)
243#if defined(__cpp_concepts)
244 requires requires(const Derived &d)
245 {
246 d.distance_to(d);
247 }
248#endif
249 {
250 return lhs.distance_to(rhs) >= 0;
251 }
252
253 friend constexpr bool operator>(const Derived &lhs, const Derived &rhs)
254#if defined(__cpp_concepts)
255 requires requires(const Derived &d)
256 {
257 d.distance_to(d);
258 }
259#endif
260 {
261 return lhs.distance_to(rhs) < 0;
262 }
263
264 friend constexpr bool operator>=(const Derived &lhs, const Derived &rhs)
265#if defined(__cpp_concepts)
266 requires requires(const Derived &d)
267 {
268 d.distance_to(d);
269 }
270#endif
271 {
272 return lhs.distance_to(rhs) <= 0;
273 }
274
275 friend constexpr bool operator==(const Derived &lhs, const Derived &rhs)
276 {
277 return lhs.equalsImpl(rhs);
278 }
279
280 friend constexpr bool operator!=(const Derived &lhs, const Derived &rhs)
281 {
282 return !lhs.equalsImpl(rhs);
283 }
284
285private:
286 constexpr Derived &derived() { return static_cast<Derived &>(*this); }
287 constexpr const Derived &derived() const { return static_cast<const Derived &>(*this); }
288
289 constexpr void stepForward() { stepForwardDispatch<impl::has_increment<Derived>>(); }
290
291 template <bool HasIncrement>
292 constexpr void stepForwardDispatch()
293 {
294 if constexpr (HasIncrement)
295 derived().increment();
296 else
297 derived().advance_by(1);
298 }
299
300 constexpr void stepBackward() { stepBackwardDispatch<impl::has_decrement<Derived>>(); }
301
302 template <bool HasDecrement>
303 constexpr void stepBackwardDispatch()
304 {
305 if constexpr (HasDecrement)
306 derived().decrement();
307 else
308 derived().advance_by(-1);
309 }
310
311 constexpr bool equalsImpl(const Derived &other) const
312 {
313 return equalsDispatch<impl::has_equals<Derived>>(other);
314 }
315
316 template <bool HasEquals>
317 constexpr bool equalsDispatch(const Derived &other) const
318 {
319 if constexpr (HasEquals)
320 return derived().equals(other);
321 else
322 return derived().distance_to(other) == 0;
323 }
324};
325
326} // namespace QtMultimediaPrivate
327
328QT_END_NAMESPACE
329
330#endif // QITERATORFACADE_P_H
friend constexpr bool operator==(const Derived &lhs, const Derived &rhs)
friend constexpr bool operator!=(const Derived &lhs, const Derived &rhs)
friend constexpr Derived operator-(Derived it, N n)
friend constexpr Derived operator+(N n, Derived it)
constexpr decltype(auto) operator*() const
friend constexpr Derived operator-(N n, Derived it)
friend constexpr Derived operator+(Derived it, N n)
friend constexpr auto operator-(const Derived &lhs, const Derived &rhs)
constexpr decltype(auto) operator[](N n) const
friend constexpr bool operator<=(const Derived &lhs, const Derived &rhs)
friend constexpr bool operator<(const Derived &lhs, const Derived &rhs)
friend constexpr bool operator>=(const Derived &lhs, const Derived &rhs)
friend constexpr bool operator>(const Derived &lhs, const Derived &rhs)
decltype(std::declval< const T & >().equals(std::declval< const T & >())) equals_expr
decltype(std::declval< T & >().decrement()) decrement_expr
decltype(std::declval< T & >().increment()) increment_expr