Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
reverse_iterator.hpp
Go to the documentation of this file.
1// Copyright 2026, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5///
6/// @file reverse_iterator.hpp
7/// @brief Provides a backport of the constexpr implementation of @c std::reverse_iterator .
8///
9#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_ITERATOR_REVERSE_ITERATOR_HPP_
10#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_ITERATOR_REVERSE_ITERATOR_HPP_
11
12// IWYU pragma: private, include "arene/base/iterator.hpp"
13// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
14
15// parasoft-begin-suppress AUTOSAR-A7_1_5-a-2 "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
16
17// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
18#include "arene/base/compare/compare_three_way.hpp"
19#include "arene/base/compare/operators.hpp"
20#include "arene/base/compare/strong_ordering.hpp"
21#include "arene/base/compiler_support/attributes.hpp"
22#include "arene/base/compiler_support/platform_queries.hpp"
23#include "arene/base/compiler_support/preprocessor.hpp"
24#include "arene/base/constraints/constraints.hpp"
25#include "arene/base/iterator/distance.hpp"
26#include "arene/base/iterator/next.hpp"
27#include "arene/base/iterator/prev.hpp"
28#include "arene/base/stdlib_choice/declval.hpp"
29#include "arene/base/stdlib_choice/enable_if.hpp"
30#include "arene/base/stdlib_choice/forward.hpp"
31#include "arene/base/stdlib_choice/is_constructible.hpp"
32#include "arene/base/stdlib_choice/is_convertible.hpp"
33#include "arene/base/stdlib_choice/is_copy_constructible.hpp"
34#include "arene/base/stdlib_choice/is_pointer.hpp"
35#include "arene/base/stdlib_choice/is_same.hpp"
36#include "arene/base/stdlib_choice/iterator_traits.hpp"
37#include "arene/base/type_traits/arithmetic_traits.hpp"
38#include "arene/base/type_traits/comparison_traits.hpp"
39#include "arene/base/type_traits/iterator_category_traits.hpp"
40
41#if ARENE_IS_OFF(ARENE_STDLIB_LIBARENECXX)
42#include "arene/base/iterator/detail/std_reverse_iterator_enabled.hpp"
43#else
44#include "arene/base/iterator/detail/std_reverse_iterator_disabled.hpp"
45#endif
46
47// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
48
49// parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
50
51namespace arene {
52namespace base {
53
54namespace reverse_iterator_detail {
55
56// parasoft-begin-suppress AUTOSAR-A5_0_3-a "This abstraction is generic and
57// does not restrict the value type of the base iterator"
58
59/// @brief Base class for @c reverse_iterator providing operations that do not depend on pointer-ness of underlying
60/// iterator.
61template <typename Itr>
62class reverse_iterator_base {
63 public:
64 static_assert(is_bidirectional_iterator_v<Itr>, "Must be at least a bidirectional iterator to be reversed.");
65
66 /// @brief Equivalent to @c value_type for the underlying iterator.
67 using value_type = typename std::iterator_traits<Itr>::value_type;
68 /// @brief Equivalent to @c reference for the underlying iterator.
69 using reference = typename std::iterator_traits<Itr>::reference;
70 /// @brief Equivalent to @c pointer for the underlying iterator.
71 using pointer = typename std::iterator_traits<Itr>::pointer;
72 /// @brief Equivalent to @c difference_type for the underlying iterator.
73 using difference_type = typename std::iterator_traits<Itr>::difference_type;
74 /// @brief Equivalent to @c iterator_category for the underlying iterator.
75 using iterator_category = typename std::iterator_traits<Itr>::iterator_category;
76 /// @brief The type of the wrapped iterator
77 using iterator_type = Itr;
78
79 protected:
80 // This weird declaration order is needed due to a bug in noexcept evaluation in GCC<10, where it incorrectly requires
81 // named referenced in noexcept(noexcept()) specifiers to have been declared before being referenced if they do not
82 // depend on a template parameter.
83
84 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "Protected data members permitted by M11-0-1 Permit #1 v1.0.0"
85 /// @brief The underlying forward iterator
86 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes) detemplitized base class with no invariants.
87 Itr itr_;
88 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
89
90 // parasoft-begin-suppress AUTOSAR-M9_3_3-a-2 "False positive: Uses this"
91 // parasoft-begin-suppress CERT_CPP-MSC52-a-2 "False positive: does return a value"
92 // parasoft-begin-suppress CERT_C-MSC37-a-2 "False positive: does return a value"
93 // parasoft-begin-suppress AUTOSAR-A8_4_2-a-2 "False positive: does return a value"
94 /// @brief Gets the iterator needed for dereferencing in a reversed view based on forward iterators.
95 ///
96 /// @return Itr Iterator to the position _before_ the current position.
97 ARENE_NODISCARD constexpr auto itr_for_access() const noexcept(noexcept(::arene::base::prev(itr_))) -> iterator_type {
98 return ::arene::base::prev(itr_);
99 }
100 // parasoft-end-suppress AUTOSAR-A8_4_2-a-2
101 // parasoft-end-suppress CERT_C-MSC37-a-2
102 // parasoft-end-suppress CERT_CPP-MSC52-a-2
103 // parasoft-end-suppress AUTOSAR-M9_3_3-a-2
104
105 /// @brief Default ctor
106 ///
107 /// @post The iterator is constructed as if via @c Itr{}
108 constexpr reverse_iterator_base() noexcept = default;
109
110 /// @brief Copy ctor
111 /// @param other The iterator being copied
112 constexpr reverse_iterator_base(reverse_iterator_base const& other) noexcept = default;
113
114 /// @brief Move ctor
115 /// @param other The iterator being moved
116 constexpr reverse_iterator_base(reverse_iterator_base&& other) noexcept = default;
117
118 /// @brief Copy assignment
119 /// @param other The iterator being copied
120 /// @return *this
121 constexpr auto operator=(reverse_iterator_base const& other) noexcept -> reverse_iterator_base& = default;
122
123 /// @brief Move assignment
124 /// @param other The iterator being moved
125 /// @return *this
126 constexpr auto operator=(reverse_iterator_base&& other) noexcept -> reverse_iterator_base& = default;
127
128 /// @brief default destructor
129 ~reverse_iterator_base() = default;
130
131 /// @brief Construct from a non-reversed iterator
132 ///
133 /// @param iter The iterator to construct the reversed iterator from
134 /// @post The iterator points to the location of @c iter in a reversed view.
135 constexpr explicit reverse_iterator_base(Itr iter) noexcept(std::is_nothrow_copy_constructible<Itr>::value)
136 : itr_(iter) {}
137
138 public:
139 // parasoft-begin-suppress CERT_CPP-MSC52-a-2 "False positive: does return a value"
140 // parasoft-begin-suppress CERT_C-MSC37-a-2 "False positive: does return a value"
141 // parasoft-begin-suppress AUTOSAR-A8_4_2-a-2 "False positive: does return a value"
142 /// @brief Dereferences the iterator
143 ///
144 /// @return reference A reference to the element at the position of the iterator
145 ARENE_NODISCARD constexpr auto operator*() const noexcept(noexcept(
146 // weird noexcept style is needed due to a bug in GCC8 for evaluation of noexcept in constexpr.
147 *std::declval<reverse_iterator_base const&>().itr_for_access()
148 )) -> reference {
149 return *itr_for_access();
150 }
151 // parasoft-end-suppress AUTOSAR-A8_4_2-a-2
152 // parasoft-end-suppress CERT_C-MSC37-a-2
153 // parasoft-end-suppress CERT_CPP-MSC52-a-2
154
155 /// @brief Unwraps the iterator
156 ///
157 /// @return Itr A copy of the underlying iterator.
158 ARENE_NODISCARD constexpr auto base() const noexcept(std::is_nothrow_copy_constructible<Itr>::value)
159 -> iterator_type {
160 return itr_;
161 }
162};
163
164// parasoft-end-suppress AUTOSAR-A5_0_3-a
165
166} // namespace reverse_iterator_detail
167
168// parasoft-begin-suppress AUTOSAR-A5_0_3-a "This abstraction is generic and
169// does not restrict the value type of the base iterator"
170
171// parasoft-begin-suppress AUTOSAR-A10_1_1-a-2 "False positive: the ordering base class is empty"
172// parasoft-begin-suppress AUTOSAR-A13_5_1-a-2 "False positive: only const overload provided"
173/// @brief A backport of the @c constexpr @c std::reverse_iterator from C++17
174///
175/// @tparam Itr The type of the wrapped_iterator to wrap. Must satisfy @c is_bidirectional_iterator_v .
176///
177/// Specialization for when the iterator is a non-pointer type.
178template <typename Itr, bool = std::is_pointer<Itr>::value>
182 /// @brief Internal type alias for the implementation base class
184
185 /// @brief Internal type alias for the implementation base class
187
188 public:
189 // alias in typedefs
190 using typename reviter_base::difference_type;
191 using typename reviter_base::iterator_category;
192 using typename reviter_base::pointer;
193 using typename reviter_base::reference;
194 using typename reviter_base::value_type;
195
196 /// @brief Default construct
197 constexpr reverse_iterator() = default;
198
199 /// @brief Copy ctor
200 /// @param other The iterator being copied
201 constexpr reverse_iterator(reverse_iterator const& other) noexcept = default;
202
203 /// @brief Move ctor
204 /// @param other The iterator being moved
205 constexpr reverse_iterator(reverse_iterator&& other) noexcept = default;
206
207 /// @brief Copy assignment
208 /// @param other The iterator being copied
209 /// @return *this
210 constexpr auto operator=(reverse_iterator const& other) noexcept -> reverse_iterator& = default;
211
212 /// @brief Move assignment
213 /// @param other The iterator being moved
214 /// @return *this
215 constexpr auto operator=(reverse_iterator&& other) noexcept -> reverse_iterator& = default;
216
217 /// @brief default destructor
218 ~reverse_iterator() = default;
219
220 // parasoft-begin-suppress AUTOSAR-A0_1_4-a-2 "False positive: 'iter' is used"
221 /// @brief Construct from a non-reversed iterator
222 ///
223 /// @param iter The iterator to construct the reversed iterator from
224 /// @post The iterator points to the location of @c iter in a reversed view.
228 // parasoft-end-suppress AUTOSAR-A0_1_4-a-2
229
230 /// @brief Conversion-construct from a reversed iterator of compatible type
231 ///
232 /// @tparam U The type of the iterator to convert from. Must satisfy <c>std::is_convertible<const U&, Itr></c>.
233 /// @param iter The iterator to construct the reversed iterator from
234 /// @post The iterator points to the location of @c iter in a reversed view.
235 template <
236 typename U,
239 std::enable_if_t<std::is_convertible<U const&, Itr>::value>> = nullptr>
240 constexpr explicit reverse_iterator(reverse_iterator<U> const& iter
241 ) noexcept(std::is_nothrow_constructible<Itr, U const&>::value&& noexcept(iter.base()))
243 ordering_base{} {}
244
245 // parasoft-begin-suppress AUTOSAR-A0_1_4-a-2 "False positive: 'iter' is used"
246 /// @brief Conversion-construct from a std::reverse_iterator
247 ///
248 /// @param iter The iterator to construct the reversed iterator from
249 /// @post The iterator points to the location of @c iter in a reversed view.
250 // NOLINTNEXTLINE(hicpp-explicit-conversions) Need implicit conversion for drop-in with std::reverse_iterator
255 // parasoft-end-suppress AUTOSAR-A0_1_4-a-2
256
257 // parasoft-begin-suppress AUTOSAR-A13_2_3-a "False positive: Not a relational operator"
258 // parasoft-begin-suppress AUTOSAR-A8_4_2-a "False positive: A value is always returned"
259 // parasoft-begin-suppress CERT_C-MSC37-a "False positive: A value is always returned"
260 // parasoft-begin-suppress CERT_CPP-MSC52-a "False positive: A value is always returned"
261 // parasoft-begin-suppress AUTOSAR-A13_5_2-a "Implicit conversion is needed for interoperability between types"
262 /// @brief Conversion operator to a std::reverse_iterator
263 ///
264 /// @return std::reverse_itr<Itr> An instance of @c std::reverse_iterator<Itr> as if constructed from @c base() .
265 // NOLINTNEXTLINE(hicpp-explicit-conversions) Need implicit conversion for drop-in with std::reverse_iterator
272 // parasoft-end-suppress AUTOSAR-A13_5_2-a
273 // parasoft-end-suppress CERT_C-MSC37-a
274 // parasoft-end-suppress CERT_CPP-MSC52-a
275 // parasoft-end-suppress AUTOSAR-A8_4_2-a
276 // parasoft-end-suppress AUTOSAR-A13_5_2-a
277
278 // parasoft-begin-suppress CERT_CPP-MSC52-a-2 "False positive: does return a value"
279 // parasoft-begin-suppress CERT_C-MSC37-a-2 "False positive: does return a value"
280 // parasoft-begin-suppress AUTOSAR-A8_4_2-a-2 "False positive: does return a value"
281 /// @brief Dereferences the iterator
282 ///
283 /// @return pointer A pointer to the element at the position of the iterator
284 ARENE_NODISCARD constexpr auto operator->() const
285 noexcept(noexcept(std::declval<reverse_iterator const&>().itr_for_access().operator->())) -> pointer {
286 return this->itr_for_access().operator->();
287 }
288 // parasoft-end-suppress AUTOSAR-A8_4_2-a-2
289 // parasoft-end-suppress CERT_C-MSC37-a-2
290 // parasoft-end-suppress CERT_CPP-MSC52-a-2
291
292 // parasoft-begin-suppress AUTOSAR-A0_1_4-a-2 "False positive: 'delta' is used"
293 // parasoft-begin-suppress CERT_CPP-MSC52-a-2 "False positive: does return a value"
294 // parasoft-begin-suppress CERT_C-MSC37-a-2 "False positive: does return a value"
295 // parasoft-begin-suppress AUTOSAR-A8_4_2-a-2 "False positive: does return a value"
296 /// @brief Index-and-dereference the iterator
297 /// @param delta The offest of the element to access
298 ///
299 /// @pre @c *this+delta is within the underlying range
300 /// @return reference A reference to the element at the position equivalent to @c *this+delta .
301 ARENE_NODISCARD constexpr auto operator[](difference_type const delta) const noexcept -> reference {
302 return *(*this + delta);
303 }
304 // parasoft-end-suppress AUTOSAR-A8_4_2-a-2
305 // parasoft-end-suppress CERT_C-MSC37-a-2
306 // parasoft-end-suppress CERT_CPP-MSC52-a-2
307 // parasoft-end-suppress AUTOSAR-A0_1_4-a-2
308
309 /// @brief Increments the iterator
310 ///
311 /// @return reverse_iterator& The iterator post-modification
312 /// @post The iterator is advanced by one position
313 constexpr auto operator++() noexcept(noexcept(--std::declval<Itr&>())) -> reverse_iterator& {
314 --(this->itr_);
315 return *this;
316 }
317
318 // parasoft-begin-suppress AUTOSAR-A3_9_1-b-2 "False positive: postincrement requires an int parameter"
319 /// @brief Increments the iterator
320 ///
321 /// @return reverse_iterator A copy of the iterator pre-modification
322 /// @post The iterator is advanced by one position
323 constexpr auto operator++(int
325 ) -> reverse_iterator {
326 auto tmp = *this;
327 ++(*this);
328 return tmp;
329 }
330 // parasoft-end-suppress AUTOSAR-A3_9_1-b-2
331
332 /// @brief Decremented the iterator
333 ///
334 /// @return reverse_iterator& The iterator post-modification
335 /// @post The iterator is decremented by one position
336 constexpr auto operator--() noexcept(noexcept(++std::declval<Itr&>())) -> reverse_iterator& {
337 ++(this->itr_);
338 return *this;
339 }
340
341 // parasoft-begin-suppress AUTOSAR-A3_9_1-b-2 "False positive: postincrement requires an int parameter"
342 /// @brief Decrements the iterator
343 ///
344 /// @return reverse_iterator A copy of the iterator pre-modification
345 /// @post The iterator is decremented by one position
346 constexpr auto operator--(int
348 ) -> reverse_iterator {
349 auto tmp = *this;
350 --(*this);
351 return tmp;
352 }
353 // parasoft-end-suppress AUTOSAR-A3_9_1-b-2
354
355 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
356 // translation units"
357 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
358 /// @brief Add an offset to the iterator
359 ///
360 /// @param iter The iterator to add the offset to.
361 /// @param delta The offset to add.
362 /// @return reverse_iterator The iterator equivalent to advancing @c iter by @c delta positions.
363 ARENE_NODISCARD friend constexpr auto operator+(
364 reverse_iterator const& iter,
369 }
370 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
371 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
372
373 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
374 // translation units"
375 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
376 /// @brief Add an offset to the iterator
377 ///
378 /// @param iter The iterator to add the offset to.
379 /// @param delta The offset to add.
380 /// @return reverse_iterator The iterator equivalent to advancing @c iter by @c delta positions.
381 ARENE_NODISCARD friend constexpr auto operator+(
386 return iter + delta;
387 }
388 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
389 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
390
391 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
392 // translation units"
393 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
394 /// @brief Subtract an offset from the iterator
395 ///
396 /// @param iter The iterator to subtract the offset from.
397 /// @param delta The offset to subtract.
398 /// @return reverse_iterator The iterator equivalent to decrementing @c iter by @c delta positions.
399 ARENE_NODISCARD friend constexpr auto operator-(
400 reverse_iterator const& iter,
405 }
406 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
407 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
408
409 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
410 // translation units"
411 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
412 /// @brief Compute the difference between two iterators
413 ///
414 /// @param lhs The left-hand iterator operand.
415 /// @param rhs The right-hand iterator operand.
416 /// @return difference_type The number of positions between the two iterators.
417 ARENE_NODISCARD friend constexpr auto operator-(
418 reverse_iterator const lhs,
420 ) noexcept(is_nothrow_subtractable_v<Itr const&>) -> difference_type {
421 return rhs.itr_ - lhs.itr_;
422 }
423 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
424 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
425
426 /// @brief Increments the iterator by an offset
427 ///
428 /// @param delta The offset to add.
429 /// @return reverse_iterator The iterator post-modification
430 /// @post The iterator is incremented by @c delta positions.
431 constexpr auto operator+=(difference_type const delta) noexcept(noexcept(std::declval<Itr&>() -= delta))
432 -> reverse_iterator& {
433 this->itr_ -= delta;
434 return *this;
435 }
436
437 /// @brief Increments the iterator by an offset
438 ///
439 /// @param delta The offset to subtract.
440 /// @return reverse_iterator The iterator post-modification
441 /// @post The iterator is decremented by @c delta positions.
442 constexpr auto operator-=(difference_type const delta) noexcept(noexcept(std::declval<Itr&>() += delta))
443 -> reverse_iterator& {
444 this->itr_ += delta;
445 return *this;
446 }
447
448 /// @brief Compare two random access iterators for relative ordering
449 ///
450 /// @tparam U The type of the iterator to compare against. Must satisfy @c compare_three_way_supported_v<U,Itr>
451 /// @param lhs The first iterator.
452 /// @param rhs The second iterator.
453 ///
454 /// @return strong_ordering::less If @c lhs is an iterator to a position before @c rhs in the sequence.
455 /// @return strong_ordering::equal If @c lhs is an iterator to a position equivalent to @c rhs in the sequence.
456 /// @return strong_ordering::greater If @c lhs is an iterator to a position after @c rhs in the sequence.
457 template <typename U, constraints<std::enable_if_t<compare_three_way_supported_v<U, Itr>>> = nullptr>
458 ARENE_NODISCARD static constexpr auto
462
463 /// @brief Compare two random access iterators for relative ordering
464 ///
465 /// @tparam U The type of the iterator to compare against. Must satisfy @c compare_three_way_supported_v<U,Itr>
466 /// @param lhs The first iterator.
467 /// @param rhs The second iterator.
468 ///
469 /// @return strong_ordering::less If @c lhs is an iterator to a position before @c rhs in the sequence.
470 /// @return strong_ordering::equal If @c lhs is an iterator to a position equivalent to @c rhs in the sequence.
471 /// @return strong_ordering::greater If @c lhs is an iterator to a position after @c rhs in the sequence.
472 template <typename U, constraints<std::enable_if_t<compare_three_way_supported_v<U, Itr>>> = nullptr>
473 ARENE_NODISCARD static constexpr auto
478
479 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "False positive: comparison operators are permitted"
480 // parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Mixed comparisons permitted by A13-5-5 Permit #1"
481 // parasoft-begin-suppress AUTOSAR-M3_3_2-a-2 "False positive: cannot apply static here"
482 /// @brief Compare two bidirectional iterators for equality
483 ///
484 /// @tparam U The type of the iterator to compare against. Must satisfy @c is_equality_comparable<Itr,U>
485 /// @param lhs The first iterator.
486 /// @param rhs The second iterator.
487 /// @return true if the iterators point to the same position.
488 /// @return false if the iterators point to different positions.
489 template <
490 typename U,
494 ARENE_NODISCARD friend constexpr auto operator==(reverse_iterator const& lhs, reverse_iterator<U> const& rhs) noexcept
495 -> bool {
496 return lhs.itr_ == rhs.itr_;
497 }
498 // parasoft-end-suppress AUTOSAR-M3_3_2-a-2
499 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
500 // parasoft-end-suppress AUTOSAR-A13_5_5-b-2
501
502 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "False positive: comparison operators are permitted"
503 // parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Mixed comparisons permitted by A13-5-5 Permit #1"
504 /// @brief Compare two bidirectional iterators for equality
505 ///
506 /// @tparam U The type of the iterator to compare against. Must satisfy @c is_equality_comparable<Itr,U>
507 /// @param lhs The first iterator.
508 /// @param rhs The second iterator.
509 /// @return true if the iterators point to the same position.
510 /// @return false if the iterators point to different positions.
511 template <
512 typename U,
516 ARENE_NODISCARD friend constexpr auto operator==(
517 reverse_iterator const& lhs,
519 ) noexcept(noexcept(std::declval<Itr>() == std::declval<U>()) && noexcept(rhs.base())) -> bool {
520 return lhs.itr_ == rhs.base();
521 }
522 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
523 // parasoft-end-suppress AUTOSAR-A13_5_5-b-2
524
525 // parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Mixed comparisons permitted by A13-5-5 Permit #1"
526 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "False positive: comparison operators are permitted"
527 /// @brief Compare two bidirectional iterators for inequality
528 ///
529 /// @tparam U The type of the iterator to compare against. Must satisfy @c is_equality_comparable<Itr,U>
530 /// @param lhs The first iterator.
531 /// @param rhs The second iterator.
532 /// @return true if the iterators point to the different positions.
533 /// @return false if the iterators point to the same position.
534 template <
535 typename U,
539 ARENE_NODISCARD friend constexpr auto operator!=(reverse_iterator const& lhs, reverse_iterator<U> const& rhs) noexcept
540 -> bool {
541 return lhs.itr_ != rhs.itr_;
542 }
543 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
544 // parasoft-end-suppress AUTOSAR-A13_5_5-b-2
545
546 // parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Mixed comparisons permitted by A13-5-5 Permit #1"
547 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "False positive: comparison operators are permitted"
548 /// @brief Compare two bidirectional iterators for inequality
549 ///
550 /// @tparam U The type of the iterator to compare against. Must satisfy @c is_equality_comparable<Itr,U>
551 /// @param lhs The first iterator.
552 /// @param rhs The second iterator.
553 /// @return true if the iterators point to the different positions.
554 /// @return false if the iterators point to the same position.
555 template <
556 typename U,
560 ARENE_NODISCARD friend constexpr auto
562 -> bool {
563 return lhs.itr_ != rhs.base();
564 }
565 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
566 // parasoft-end-suppress AUTOSAR-A13_5_5-b-2
567};
568// parasoft-end-suppress AUTOSAR-A13_5_1-a-2
569// parasoft-end-suppress AUTOSAR-A10_1_1-a-2
570
571// parasoft-begin-suppress AUTOSAR-A10_1_1-a-2 "False positive: the ordering base class is empty"
572// parasoft-begin-suppress AUTOSAR-A13_5_1-a-2 "False positive: only const overload provided"
573/// @brief A backport of the @c constexpr @c std::reverse_iterator from C++17
574///
575/// @tparam Itr The type of the wrapped_iterator to wrap. Must satisfy @c is_bidirectional_iterator_v .
576///
577/// Specialization for when the iterator is a pointer type.
578template <typename Itr>
579class reverse_iterator<Itr, true> final
580 : public reverse_iterator_detail::reverse_iterator_base<Itr>
581 , generic_ordering_from_three_way_compare<reverse_iterator<Itr>> {
582 /// @brief Internal type alias for the implementation base class
583 using reviter_base = reverse_iterator_detail::reverse_iterator_base<Itr>;
584 /// @brief Internal type alias for the implementation base class
585 using ordering_base = generic_ordering_from_three_way_compare<reverse_iterator<Itr>>;
586
587 public:
588 // alias in typedefs
589 using typename reviter_base::difference_type;
590 using typename reviter_base::iterator_category;
591 using typename reviter_base::pointer;
592 using typename reviter_base::reference;
593 using typename reviter_base::value_type;
594
595 /// @brief Default construct
596 constexpr reverse_iterator() = default;
597
598 /// @brief Copy ctor
599 /// @param other The iterator being copied
600 constexpr reverse_iterator(reverse_iterator const& other) noexcept = default;
601
602 /// @brief Move ctor
603 /// @param other The iterator being moved
604 constexpr reverse_iterator(reverse_iterator&& other) noexcept = default;
605
606 /// @brief Copy assignment
607 /// @param other The iterator being copied
608 /// @return *this
609 constexpr auto operator=(reverse_iterator const& other) noexcept -> reverse_iterator& = default;
610
611 /// @brief Move assignment
612 /// @param other The iterator being moved
613 /// @return *this
614 constexpr auto operator=(reverse_iterator&& other) noexcept -> reverse_iterator& = default;
615
616 /// @brief default destructor
617 ~reverse_iterator() = default;
618
619 /// @brief Construct from a non-reversed iterator
620 ///
621 /// @param iter The iterator to construct the reversed iterator from
622 /// @post The iterator points to the location of @c iter in a reversed view.
623 constexpr explicit reverse_iterator(Itr iter) noexcept(std::is_nothrow_copy_constructible<Itr>::value)
624 : reviter_base(iter),
625 ordering_base{} {}
626
627 /// @brief Conversion-construct from a reversed iterator of compatible type
628 ///
629 /// @tparam U The type of the iterator to convert from. Must satisfy <c>std::is_convertible<const U&, Itr></c>.
630 /// @param iter The iterator to construct the reversed iterator from
631 /// @post The iterator points to the location of @c iter in a reversed view.
632 template <
633 typename U,
634 constraints<
635 std::enable_if_t<!std::is_same<U, Itr>::value>,
636 std::enable_if_t<std::is_convertible<U const&, Itr>::value>> = nullptr>
637 constexpr explicit reverse_iterator(reverse_iterator<U> const& iter
638 ) noexcept(std::is_nothrow_constructible<Itr, U const&>::value&& noexcept(iter.base()))
639 : reviter_base(iter.base()),
640 ordering_base{} {}
641
642 /// @brief Conversion-construct from a std::reverse_iterator
643 ///
644 /// @param iter The iterator to construct the reversed iterator from
645 /// @post The iterator points to the location of @c iter in a reversed view.
646 // NOLINTNEXTLINE(hicpp-explicit-conversions) Need implicit conversion for drop-in with std::reverse_iterator
647 constexpr reverse_iterator(reverse_iterator_detail::std_reverse_iterator<Itr> const& iter
648 ) noexcept(std::is_nothrow_constructible<reviter_base, Itr>::value&& noexcept(iter.base()))
649 : reviter_base(iter.base()),
650 ordering_base{} {}
651
652 // parasoft-begin-suppress AUTOSAR-A13_2_3-a "False positive: Not a relational operator"
653 // parasoft-begin-suppress AUTOSAR-A13_5_2-a "Implicit conversion is needed for interoperability between types"
654 /// @brief Conversion operator to a std::reverse_iterator
655 ///
656 /// @return std::reverse_itr<Itr> An instance of @c std::reverse_iterator<Itr> as if constructed from @c base() .
657 // NOLINTNEXTLINE(hicpp-explicit-conversions) Need implicit conversion for drop-in with std::reverse_iterator
658 constexpr operator reverse_iterator_detail::std_reverse_iterator<Itr>() const
659 noexcept(std::is_nothrow_constructible<reverse_iterator_detail::std_reverse_iterator<Itr>, Itr>::value&& noexcept(
660 std::declval<reverse_iterator>().base()
661 )) {
662 return reverse_iterator_detail::std_reverse_iterator<Itr>{this->base()};
663 }
664 // parasoft-end-suppress AUTOSAR-A13_2_3-a
665 // parasoft-end-suppress AUTOSAR-A13_5_2-a
666
667 /// @brief Dereferences the iterator
668 ///
669 /// @return pointer A pointer to the element at the position of the iterator
670 ARENE_NODISCARD constexpr auto operator->() const noexcept -> pointer { return this->itr_for_access(); }
671
672 /// @brief Index-and-dereference the iterator
673 ///
674 /// @param delta The index at which to dereference the iterator
675 ///
676 /// @return reference A reference to the element at the position equivalent to @c *this+delta .
677
678 ARENE_NODISCARD constexpr auto operator[](difference_type const delta) const noexcept -> reference {
679 return *(*this + delta);
680 }
681
682 /// @brief Increments the iterator
683 ///
684 /// @return reverse_iterator& The iterator post-modification
685 /// @post The iterator is advanced by one position
686 constexpr auto operator++() noexcept -> reverse_iterator& {
687 *this += 1;
688 return *this;
689 }
690
691 // parasoft-begin-suppress AUTOSAR-A3_9_1-b-2 "False positive: postincrement requires an int parameter"
692 /// @brief Increments the iterator
693 ///
694 /// @return reverse_iterator A copy of the iterator pre-modification
695 /// @post The iterator is advanced by one position
696 constexpr auto operator++(int) noexcept -> reverse_iterator {
697 auto tmp = *this;
698 ++(*this);
699 return tmp;
700 }
701 // parasoft-end-suppress AUTOSAR-A3_9_1-b-2
702
703 /// @brief Decremented the iterator
704 ///
705 /// @return reverse_iterator& The iterator post-modification
706 /// @post The iterator is decremented by one position
707 constexpr auto operator--() noexcept -> reverse_iterator& {
708 *this -= 1;
709 return *this;
710 }
711
712 // parasoft-begin-suppress AUTOSAR-A3_9_1-b-2 "False positive: postincrement requires an int parameter"
713 /// @brief Decrements the iterator
714 ///
715 /// @return reverse_iterator A copy of the iterator pre-modification
716 /// @post The iterator is decremented by one position
717 constexpr auto operator--(int) noexcept -> reverse_iterator {
718 auto tmp = *this;
719 --(*this);
720 return tmp;
721 }
722 // parasoft-end-suppress AUTOSAR-A3_9_1-b-2
723
724 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
725 // translation units"
726 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
727 // parasoft-begin-suppress AUTOSAR-A7_1_1-a-2 "False positive: iter is modified"
728 /// @brief Add an offset to the iterator
729 ///
730 /// @param iter The iterator to add the offset to.
731 /// @param delta The offset to add.
732 /// @return reverse_iterator The iterator equivalent to advancing @c iter by @c delta positions.
733 ARENE_NODISCARD friend constexpr auto operator+(reverse_iterator iter, difference_type const delta) noexcept
734 -> reverse_iterator {
735 iter += delta;
736 return iter;
737 }
738 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
739 // parasoft-end-suppress AUTOSAR-A7_1_1-a-2
740 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
741
742 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
743 // translation units"
744 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
745 /// @brief Add an offset to the iterator
746 ///
747 /// @param iter The iterator to add the offset to.
748 /// @param delta The offset to add.
749 /// @return reverse_iterator The iterator equivalent to advancing @c iter by @c delta positions.
750 ARENE_NODISCARD friend constexpr auto operator+(difference_type const delta, reverse_iterator const& iter) noexcept
751 -> reverse_iterator {
752 return iter + delta;
753 }
754 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
755 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
756
757 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
758 // translation units"
759 // parasoft-begin-suppress AUTOSAR-A7_1_1-a-2 "False positive: iter is modified"
760 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
761 /// @brief Subtract an offset from the iterator
762 ///
763 /// @param iter The iterator to subtract the offset from.
764 /// @param delta The offset to subtract.
765 /// @return reverse_iterator The iterator equivalent to decrementing @c iter by @c delta positions.
766 ARENE_NODISCARD friend constexpr auto operator-(reverse_iterator iter, difference_type const delta) noexcept
767 -> reverse_iterator {
768 iter -= delta;
769 return iter;
770 }
771 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
772 // parasoft-end-suppress AUTOSAR-A7_1_1-a-2
773 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
774
775 // parasoft-begin-suppress AUTOSAR-A0_1_3-a-2 "False positive: Function is namespace scope and used in other
776 // translation units"
777 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Hidden friends permitted by A11-3-1 Permit #2"
778 /// @brief Compute the difference between two iterators
779 ///
780 /// @param lhs The left-hand iterator operand.
781 /// @param rhs The right-hand iterator operand.
782 /// @return difference_type The number of positions between the two iterators.
783 ARENE_NODISCARD friend constexpr auto operator-(reverse_iterator const lhs, reverse_iterator const rhs) noexcept
784 -> difference_type {
785 return ::arene::base::distance(lhs.itr_, rhs.itr_);
786 }
787 // parasoft-end-suppress AUTOSAR-A0_1_3-a-2
788
789 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
790 /// @brief Increments the iterator by an offset
791 ///
792 /// @param delta The offset to add.
793 /// @return reverse_iterator The iterator post-modification
794 /// @post The iterator is incremented by @c delta positions.
795 constexpr auto operator+=(difference_type const delta) noexcept -> reverse_iterator& {
796 this->itr_ = ::arene::base::prev(this->itr_, delta);
797 return *this;
798 }
799
800 /// @brief Increments the iterator by an offset
801 ///
802 /// @param delta The offset to subtract.
803 /// @return reverse_iterator The iterator post-modification
804 /// @post The iterator is decremented by @c delta positions.
805 constexpr auto operator-=(difference_type const delta) noexcept -> reverse_iterator& {
806 this->itr_ = ::arene::base::next(this->itr_, delta);
807 return *this;
808 }
809
810 /// @brief Compare two random access iterators for relative ordering
811 ///
812 /// @tparam U The type of the iterator to compare against. Must satisfy @c compare_three_way_supported_v<U,Itr>
813 /// @param lhs The first iterator.
814 /// @param rhs The second iterator.
815 ///
816 /// @return strong_ordering::less If @c lhs is an iterator to a position before @c rhs in the sequence.
817 /// @return strong_ordering::equal If @c lhs is an iterator to a position equivalent to @c rhs in the sequence.
818 /// @return strong_ordering::greater If @c lhs is an iterator to a position after @c rhs in the sequence.
819 template <typename U, constraints<std::enable_if_t<compare_three_way_supported_v<U, Itr>>> = nullptr>
820 ARENE_NODISCARD static constexpr auto
821 three_way_compare(reverse_iterator const& lhs, reverse_iterator<U> const& rhs) noexcept -> strong_ordering {
822 return compare_three_way{}(rhs.itr_, lhs.itr_);
823 }
824
825 /// @brief Compare two random access iterators for relative ordering
826 ///
827 /// @tparam U The type of the iterator to compare against. Must satisfy @c compare_three_way_supported_v<U,Itr>
828 /// @param lhs The first iterator.
829 /// @param rhs The second iterator.
830 ///
831 /// @return strong_ordering::less If @c lhs is an iterator to a position before @c rhs in the sequence.
832 /// @return strong_ordering::equal If @c lhs is an iterator to a position equivalent to @c rhs in the sequence.
833 /// @return strong_ordering::greater If @c lhs is an iterator to a position after @c rhs in the sequence.
834 template <typename U, constraints<std::enable_if_t<compare_three_way_supported_v<U, Itr>>> = nullptr>
835 ARENE_NODISCARD static constexpr auto
836 three_way_compare(reverse_iterator const& lhs, reverse_iterator_detail::std_reverse_iterator<U> const& rhs) noexcept
837 -> strong_ordering {
838 return compare_three_way{}(rhs.base(), lhs.itr_);
839 }
840};
841// parasoft-end-suppress AUTOSAR-A13_5_1-a-2
842// parasoft-end-suppress AUTOSAR-A10_1_1-a-2
843
844// parasoft-end-suppress AUTOSAR-A5_0_3-a
845
846/// @brief Factory function for creating a @c reverse_iterator with deduced template arguments pre C++17.
847///
848/// @tparam Itr The type of the wrapped_iterator to wrap. Must satisfy @c is_bidirectional_iterator_v .
849/// @param iter The iterator to construct from.
850/// @return reverse_iterator<Itr> Equivalent to @c reverse_iterator<Itr>{std::forward<Itr>(iter)} .
851template <typename Itr, constraints<std::enable_if_t<is_bidirectional_iterator_v<Itr>>> = nullptr>
855}
856
857} // namespace base
858} // namespace arene
859
860#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_ITERATOR_REVERSE_ITERATOR_HPP_
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10