Monado OpenXR Runtime
Loading...
Searching...
No Matches
u_template_historybuf_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 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 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 HistoryBufIterator : public RandomAccessIteratorBase<const RingBufferHelper>
29 {
31 friend class HistoryBuffer<T, MaxSize>;
32
33 public:
36 using typename base::difference_type;
37 using typename base::iterator_category;
38 using value_type = T;
39 using pointer = T *;
40 using reference = T &;
41
42 //! Default-construct an (invalid) iterator.
43 HistoryBufIterator() = default;
44
45 // copy and move as you wish
46 HistoryBufIterator(HistoryBufIterator const &) = default;
47 HistoryBufIterator(HistoryBufIterator &&) noexcept = default;
49 operator=(HistoryBufIterator const &) = default;
51 operator=(HistoryBufIterator &&) noexcept = default;
52
53 //! Is this iterator valid?
54 bool
55 valid() const noexcept
56 {
57 return container_ != nullptr && base::valid();
58 }
59
60 //! Is this iterator valid?
61 explicit operator bool() const noexcept
62 {
63 return valid();
64 }
65
66 //! Get the associated container: for internal use
67 container_type *
68 container() const noexcept
69 {
70 return container_;
71 }
72
73 //! Dereference operator: throws std::out_of_range if invalid
74 reference
75 operator*() const;
76
77 //! Smart pointer operator: returns nullptr if invalid
78 pointer
79 operator->() const noexcept;
80
81 //! Pre-increment: Advance, then return self.
82 Self &
83 operator++();
84
85 //! Post-increment: return a copy of initial state after incrementing self
86 // NOLINTNEXTLINE(cert-dcl21-cpp)
87 Self
88 operator++(int)
89 {
90 Self tmp = *this;
91 this->increment_n(1);
92 return tmp;
93 }
94
95 //! Pre-decrement: Subtract, then return self.
96 Self &
97 operator--();
98
99 //! Post-decrement: return a copy of initial state after decrementing self
100 // NOLINTNEXTLINE(cert-dcl21-cpp)
101 Self
103 {
104 Self tmp = *this;
105 this->decrement_n(1);
106 return tmp;
107 }
108
109 // Use the base class implementation of subtracting one iterator from another
110 using base::operator-;
111
112 //! Increment by an arbitrary amount.
113 Self &
114 operator+=(std::ptrdiff_t n) noexcept;
115
116 //! Decrement by an arbitrary amount.
117 Self &
118 operator-=(std::ptrdiff_t n) noexcept;
119
120 //! Increment a copy of the iterator by an arbitrary amount.
121 Self
122 operator+(std::ptrdiff_t n) const noexcept;
123
124 //! Decrement a copy of the iterator by an arbitrary amount.
125 Self
126 operator-(std::ptrdiff_t n) const noexcept;
127
128 private:
129 //! Factory for a "begin" iterator from a container and its helper: mostly for internal use.
130 static Self
131 begin(container_type &container, const RingBufferHelper &helper)
132 {
133 return {&container, base::begin(helper)};
134 }
135
136 //! Construct the "past the end" iterator that can be decremented safely
137 static Self
138 end(container_type &container, const RingBufferHelper &helper)
139 {
140 return {&container, base::end(helper)};
141 }
142
143 // for use internally
144 HistoryBufIterator(container_type *container, base &&iter_base) : base(iter_base), container_(container)
145 {}
146 container_type *container_{nullptr};
147 };
148
149 template <typename T, size_t MaxSize>
150 inline typename HistoryBufIterator<T, MaxSize>::reference
152 {
153 auto *ptr = container_->get_at_index(base::index());
154 if (ptr == nullptr) {
155 throw std::out_of_range("Iterator index out of range");
157 return *ptr;
158 }
159
160 template <typename T, size_t MaxSize>
161 inline typename HistoryBufIterator<T, MaxSize>::pointer
163 {
164 return container_->get_at_index(base::index());
165 }
166
167 template <typename T, size_t MaxSize>
170 {
171 this->increment_n(1);
172 return *this;
173 }
174
175 template <typename T, size_t MaxSize>
178 {
179 this->decrement_n(1);
180 return *this;
181 }
182
183 template <typename T, size_t MaxSize>
186 {
187 static_cast<base &>(*this) += n;
188 return *this;
189 }
190
191 template <typename T, size_t MaxSize>
194 {
195 static_cast<base &>(*this) -= n;
196 return *this;
197 }
198
199 template <typename T, size_t MaxSize>
201 HistoryBufIterator<T, MaxSize>::operator+(std::ptrdiff_t n) const noexcept
202 {
203 Self ret(*this);
204 ret += n;
205 return ret;
206 }
207
208 template <typename T, size_t MaxSize>
210 HistoryBufIterator<T, MaxSize>::operator-(std::ptrdiff_t n) const noexcept
211 {
212 Self ret(*this);
213 ret -= n;
214 return ret;
215 }
216
217 // Conversion constructor for const iterator
218 template <typename T, size_t MaxSize>
222} // namespace detail
223
224// HistoryBuffer method implementations that depend on iterator availability
225
226template <typename T, size_t MaxSize>
229{
230 static_assert(std::is_same<typename std::iterator_traits<iterator>::iterator_category,
231 std::random_access_iterator_tag>::value,
232 "Iterator should be random access");
233 return iterator::begin(*this, helper_);
234}
235
236template <typename T, size_t MaxSize>
239{
240 return iterator::end(*this, helper_);
241}
242
243} // 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 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
HistoryBufConstIterator()=default
Default-construct an (invalid) iterator.
Class template for iterator for HistoryBuffer.
Definition u_template_historybuf_iterator.inl:29
bool valid() const noexcept
Is this iterator valid?
Definition u_template_historybuf_iterator.inl:55
Self operator-(std::ptrdiff_t n) const noexcept
Decrement a copy of the iterator by an arbitrary amount.
Definition u_template_historybuf_iterator.inl:210
reference operator*() const
Dereference operator: throws std::out_of_range if invalid.
Definition u_template_historybuf_iterator.inl:151
Self operator--(int)
Post-decrement: return a copy of initial state after decrementing self.
Definition u_template_historybuf_iterator.inl:102
Self & operator+=(std::ptrdiff_t n) noexcept
Increment by an arbitrary amount.
Definition u_template_historybuf_iterator.inl:185
container_type * container() const noexcept
Get the associated container: for internal use.
Definition u_template_historybuf_iterator.inl:68
pointer operator->() const noexcept
Smart pointer operator: returns nullptr if invalid.
Definition u_template_historybuf_iterator.inl:162
Self & operator--()
Pre-decrement: Subtract, then return self.
Definition u_template_historybuf_iterator.inl:177
Self & operator-=(std::ptrdiff_t n) noexcept
Decrement by an arbitrary amount.
Definition u_template_historybuf_iterator.inl:193
Self operator+(std::ptrdiff_t n) const noexcept
Increment a copy of the iterator by an arbitrary amount.
Definition u_template_historybuf_iterator.inl:201
HistoryBufIterator()=default
Default-construct an (invalid) iterator.
Self & operator++()
Pre-increment: Advance, then return self.
Definition u_template_historybuf_iterator.inl:169
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