Monado OpenXR Runtime
Loading...
Searching...
No Matches
u_template_historybuf_const_iterator.inl
Go to the documentation of this file.
1// Copyright 2021-2022, Collabora, Ltd.
2//
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief const_iterator details for ring buffer
7 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
8 * @ingroup aux_util
9 */
10#pragma once
11
12// IWYU pragma: private, include "util/u_template_historybuf.hpp"
13
14#include <stddef.h>
15#include <type_traits>
16
17namespace xrt::auxiliary::util {
18template <typename T, size_t MaxSize> class HistoryBuffer;
19
20namespace detail {
21 /**
22 * @brief Class template for const_iterator for HistoryBuffer
23 *
24 * @tparam T Container element type - must match HistoryBuffer
25 * @tparam MaxSize Maximum number of elements - must match HistoryBuffer
26 */
27 template <typename T, size_t MaxSize>
28 class HistoryBufConstIterator : public RandomAccessIteratorBase<const RingBufferHelper>
29 {
31 friend class HistoryBuffer<T, MaxSize>;
32 friend class HistoryBufIterator<T, MaxSize>;
33
34 public:
37 using typename base::difference_type;
38 using typename base::iterator_category;
39 using value_type = const T;
40 using pointer = const T *;
41 using reference = const T &;
42
43 //! Default-construct an (invalid) iterator.
45
46 // copy and move as you wish
50 operator=(HistoryBufConstIterator const &) = default;
52 operator=(HistoryBufConstIterator &&) noexcept = default;
53
54 //! Implicit conversion from a non-const iterator
55 HistoryBufConstIterator(const HistoryBufIterator<T, MaxSize> &other);
56
57 //! Is this iterator valid?
58 bool
59 valid() const noexcept
60 {
61 return container_ != nullptr && base::valid();
62 }
63
64 //! Is this iterator valid?
65 explicit operator bool() const noexcept
66 {
67 return valid();
68 }
69
70 //! Get the inner container: for internal use
71 container_type *
72 container() const noexcept
73 {
74 return container_;
75 }
76
77 //! Dereference operator: throws std::out_of_range if invalid
78 reference
79 operator*() const;
80
81 //! Smart pointer operator: returns nullptr if invalid
82 pointer
83 operator->() const noexcept;
84
85 //! Pre-increment: Advance, then return self.
86 Self &
87 operator++();
88
89 //! Post-increment: return a copy of initial state after incrementing self
90 // NOLINTNEXTLINE(cert-dcl21-cpp)
91 Self
92 operator++(int) &
93 {
94 Self tmp = *this;
95 this->increment_n(1);
96 return tmp;
97 }
98
99 //! Pre-decrement: Subtract, then return self.
100 Self &
101 operator--();
102
103 //! Post-decrement: return a copy of initial state after decrementing self
104 // NOLINTNEXTLINE(cert-dcl21-cpp)
105 Self
107 {
108 Self tmp = *this;
109 this->decrement_n(1);
110 return tmp;
111 }
112
113 // Use the base class implementation of subtracting one iterator from another
114 using base::operator-;
115
116 //! Increment by an arbitrary amount.
117 Self &
118 operator+=(std::ptrdiff_t n) noexcept;
119
120 //! Decrement by an arbitrary amount.
121 Self &
122 operator-=(std::ptrdiff_t n) noexcept;
123
124 //! Increment a copy of the iterator by an arbitrary amount.
125 Self
126 operator+(std::ptrdiff_t n) const noexcept;
127
128 //! Decrement a copy of the iterator by an arbitrary amount.
129 Self
130 operator-(std::ptrdiff_t n) const noexcept;
131
132 private:
133 //! Factory for a "begin" iterator from a container and its helper: mostly for internal use.
134 static Self
135 begin(container_type &container, const RingBufferHelper &helper)
136 {
137 return {&container, base::begin(helper)};
138 }
139
140 //! Construct the "past the end" iterator that can be decremented safely
141 static Self
142 end(container_type &container, const RingBufferHelper &helper)
143 {
144 return {&container, base::end(helper)};
145 }
146
147 // for use internally
148 HistoryBufConstIterator(container_type *container, base &&iter_base)
149 : base(iter_base), container_(container)
150 {}
151 container_type *container_{nullptr};
152 };
153
154 template <typename T, size_t MaxSize>
155 inline typename HistoryBufConstIterator<T, MaxSize>::reference
157 {
158 auto *ptr = container_->get_at_index(base::index());
159 if (ptr == nullptr) {
160 throw std::out_of_range("Iterator index out of range");
161 }
162 return *ptr;
163 }
164
165 template <typename T, size_t MaxSize>
166 inline typename HistoryBufConstIterator<T, MaxSize>::pointer
168 {
169 return container_->get_at_index(base::index());
170 }
171
172 template <typename T, size_t MaxSize>
175 {
176 this->increment_n(1);
177 return *this;
178 }
179
180 template <typename T, size_t MaxSize>
183 {
184 this->decrement_n(1);
185 return *this;
186 }
187
188 template <typename T, size_t MaxSize>
191 {
192 static_cast<base &>(*this) += n;
193 return *this;
194 }
195
196 template <typename T, size_t MaxSize>
199 {
200 static_cast<base &>(*this) -= n;
201 return *this;
202 }
203
204 template <typename T, size_t MaxSize>
206 HistoryBufConstIterator<T, MaxSize>::operator+(std::ptrdiff_t n) const noexcept
207 {
208 Self ret(*this);
209 ret += n;
210 return ret;
211 }
212
213 template <typename T, size_t MaxSize>
215 HistoryBufConstIterator<T, MaxSize>::operator-(std::ptrdiff_t n) const noexcept
216 {
217 Self ret(*this);
218 ret -= n;
219 return ret;
220 }
221} // namespace detail
222
223// HistoryBuffer method implementations that depend on const_iterator availability
224
225template <typename T, size_t MaxSize>
228{
229 static_assert(std::is_same<typename std::iterator_traits<const_iterator>::iterator_category,
230 std::random_access_iterator_tag>::value,
231 "Iterator should be random access");
232 return const_iterator::begin(*this, helper_);
233}
234
235template <typename T, size_t MaxSize>
238{
239 return const_iterator::end(*this, helper_);
240}
241
242template <typename T, size_t MaxSize>
245{
246 return cbegin();
247}
248
249template <typename T, size_t MaxSize>
252{
253 return cend();
254}
255
256} // namespace xrt::auxiliary::util
Stores some number of values in a ring buffer, overwriting the earliest-pushed-remaining element if o...
Definition u_template_historybuf.hpp:38
const_iterator end() const noexcept
Get a "past the end" (past the newest) const iterator.
Definition u_template_historybuf_const_iterator.inl:251
const_iterator cbegin() const noexcept
Get a const iterator for the oldest element.
Definition u_template_historybuf_const_iterator.inl:227
const_iterator cend() const noexcept
Get a "past the end" (past the newest) const iterator.
Definition u_template_historybuf_const_iterator.inl:237
const_iterator begin() const noexcept
Get a const iterator for the oldest element.
Definition u_template_historybuf_const_iterator.inl:244
Template for base class used by "random-access" iterators and const_iterators, providing all the func...
Definition u_iterator_base.hpp:37
void increment_n(std::size_t n)
Increment an arbitrary amount.
Definition u_iterator_base.hpp:310
static RandomAccessIteratorBase end(const RingBufferHelper &container)
Factory function: construct the "past the end" iterator that can be decremented safely.
Definition u_iterator_base.hpp:124
void decrement_n(std::size_t n)
Decrement an arbitrary amount.
Definition u_iterator_base.hpp:320
bool valid() const noexcept
Is this iterator valid?
Definition u_iterator_base.hpp:279
static RandomAccessIteratorBase begin(const RingBufferHelper &container)
Factory function: construct the "begin" iterator.
Definition u_iterator_base.hpp:117
Class template for const_iterator for HistoryBuffer.
Definition u_template_historybuf_const_iterator.inl:29
Self operator-(std::ptrdiff_t n) const noexcept
Decrement a copy of the iterator by an arbitrary amount.
Definition u_template_historybuf_const_iterator.inl:215
Self operator+(std::ptrdiff_t n) const noexcept
Increment a copy of the iterator by an arbitrary amount.
Definition u_template_historybuf_const_iterator.inl:206
Self & operator-=(std::ptrdiff_t n) noexcept
Decrement by an arbitrary amount.
Definition u_template_historybuf_const_iterator.inl:198
HistoryBufConstIterator()=default
Default-construct an (invalid) iterator.
Self & operator++()
Pre-increment: Advance, then return self.
Definition u_template_historybuf_const_iterator.inl:174
container_type * container() const noexcept
Get the inner container: for internal use.
Definition u_template_historybuf_const_iterator.inl:72
pointer operator->() const noexcept
Smart pointer operator: returns nullptr if invalid.
Definition u_template_historybuf_const_iterator.inl:167
Self & operator+=(std::ptrdiff_t n) noexcept
Increment by an arbitrary amount.
Definition u_template_historybuf_const_iterator.inl:190
reference operator*() const
Dereference operator: throws std::out_of_range if invalid.
Definition u_template_historybuf_const_iterator.inl:156
Self & operator--()
Pre-decrement: Subtract, then return self.
Definition u_template_historybuf_const_iterator.inl:182
bool valid() const noexcept
Is this iterator valid?
Definition u_template_historybuf_const_iterator.inl:59
Self operator--(int) &
Post-decrement: return a copy of initial state after decrementing self.
Definition u_template_historybuf_const_iterator.inl:106
Class template for iterator for HistoryBuffer.
Definition u_template_historybuf_iterator.inl:29
All the bookkeeping for adapting a fixed-size array to a ring buffer.
Definition u_template_historybuf_impl_helpers.hpp:46
Definition comp_scratch.c:130