HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
lookahead_iterator.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2023.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
8#pragma once
9
10#include "../utility/utility.hpp"
11#include <iterator>
12#include <bit>
13#include <optional>
14#include <string>
15
16namespace hi {
17inline namespace v1 {
18
25template<size_t LookaheadCount, typename It, std::sentinel_for<It> ItEnd = std::default_sentinel_t>
26class lookahead_iterator {
27public:
28 static_assert(std::has_single_bit(LookaheadCount), "LookaheadCount must be a power of two.");
29
30 constexpr static size_t max_size = LookaheadCount;
31
32 using value_type = std::iterator_traits<It>::value_type;
33 using reference = value_type const &;
34 using pointer = value_type const *;
35 using difference_type = std::ptrdiff_t;
36 using iterator_category = std::forward_iterator_tag;
37
38 class proxy {
39 public:
40 using value_type = value_type;
41 using reference = reference;
42 using pointer = pointer;
43
44 constexpr proxy(proxy const &) noexcept = default;
45 constexpr proxy(proxy &&) noexcept = default;
46 constexpr proxy &operator=(proxy const &) noexcept = default;
47 constexpr proxy &operator=(proxy &&) noexcept = default;
48 constexpr proxy(value_type other) noexcept : _v(std::move(other)) {}
49
50 constexpr reference operator*() const noexcept
51 {
52 return _v;
53 }
54
55 constexpr pointer operator->() const noexcept
56 {
57 return std::addressof(_v);
58 }
59
60 private:
61 value_type _v;
62 };
63
69
70 constexpr explicit lookahead_iterator(It first, ItEnd last) noexcept : _it(first), _last(last), _size(0)
71 {
72 while (_size != max_size and _it != last) {
73 add_one_to_lookahead();
74 }
75 }
76
81 [[nodiscard]] constexpr size_t size() const noexcept
82 {
83 return _size;
84 }
85
90 [[nodiscard]] constexpr bool empty() const noexcept
91 {
92 return _size == 0;
93 }
94
95 constexpr explicit operator bool() const noexcept
96 {
97 return not empty();
98 }
99
100 [[nodiscard]] constexpr bool operator==(std::default_sentinel_t) const noexcept
101 {
102 return empty();
103 }
104
110 [[nodiscard]] constexpr reference operator[](size_t i) const noexcept
111 {
112 hi_axiom(i < _size);
113 return _lookahead[(_tail + i) % max_size];
114 }
115
122 [[nodiscard]] constexpr reference at(size_t i) const
123 {
124 if (i < _size) {
125 return (*this)[i];
126 } else {
127 throw std::out_of_range("lookahead_iterator::at()");
128 }
129 }
130
137 [[nodiscard]] constexpr std::optional<value_type> next(size_t i = 1) const noexcept
138 {
139 if (i < _size) {
140 return (*this)[i];
141 } else {
142 return std::nullopt;
143 }
144 }
145
149 {
150 hi_axiom(_size != 0);
151 return (*this)[0];
152 }
153
157 {
158 hi_axiom(_size != 0);
159 return std::addressof((*this)[0]);
160 }
161
165 {
166 hi_axiom(_size != 0);
167 --_size;
168 ++_tail;
169 add_one_to_lookahead();
170
171 return *this;
172 }
173
174 constexpr lookahead_iterator &operator+=(size_t n) noexcept
175 {
176 for (auto i = 0_uz; i != n; ++i) {
177 ++(*this);
178 }
179 return *this;
180 }
181
182 constexpr proxy operator++(int) noexcept
183 {
184 auto r = proxy{**this};
185 ++(*this);
186 return r;
187 }
188
189private:
190 It _it;
191 ItEnd _last;
192 size_t _size = 0;
193 size_t _tail = 0;
194
195 std::array<value_type, max_size> _lookahead = {};
196
197 constexpr void add_one_to_lookahead() noexcept
198 {
199 hi_axiom(_size < max_size);
200
201 if (_it != _last) {
202 _lookahead[(_tail + _size) % max_size] = *_it;
203 ++_it;
204 ++_size;
205 }
206 }
207};
208
209static_assert(std::movable<lookahead_iterator<2, std::string::iterator, std::string::iterator>>);
210static_assert(std::is_same_v<std::iterator_traits<lookahead_iterator<2, std::string::iterator, std::string::iterator>>::value_type, char>);
211static_assert(std::input_or_output_iterator<lookahead_iterator<2, std::string::iterator, std::string::iterator>>);
212static_assert(std::weakly_incrementable<lookahead_iterator<2, std::string::iterator, std::string::iterator>>);
213
221template<size_t LookaheadCount, typename It, std::sentinel_for<It> ItEnd = std::default_sentinel_t>
222auto make_lookahead_iterator(It first, ItEnd last = std::default_sentinel) noexcept
223{
225}
226
234template<size_t LookaheadCount, std::ranges::range Range>
235auto make_lookahead_iterator(Range const &range) noexcept
236{
237 return make_lookahead_iterator<LookaheadCount>(std::ranges::begin(range), std::ranges::end(range));
238}
239
240}}
241
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Lookahead iterator.
Definition lookahead_iterator.hpp:15
constexpr reference operator*() const noexcept
Get a reference to the value at the iterator.
Definition lookahead_iterator.hpp:148
constexpr lookahead_iterator & operator++() noexcept
Increment the iterator.
Definition lookahead_iterator.hpp:164
constexpr reference at(size_t i) const
Get a reference to an item at or beyond the iterator.
Definition lookahead_iterator.hpp:122
constexpr size_t size() const noexcept
The number of entries can be looked ahead.
Definition lookahead_iterator.hpp:81
lookahead_iterator & operator++() noexcept
Increment the iterator.
Definition lookahead_iterator.hpp:127
constexpr bool empty() const noexcept
Check if the iterator is at end.
Definition lookahead_iterator.hpp:90
constexpr std::optional< value_type > next(size_t i=1) const noexcept
Get a reference to an item at or beyond the iterator.
Definition lookahead_iterator.hpp:137
constexpr reference operator[](size_t i) const noexcept
Get a reference to an item at or beyond the iterator.
Definition lookahead_iterator.hpp:110
constexpr pointer operator->() const noexcept
Get a pointer to the value at the iterator.
Definition lookahead_iterator.hpp:156
Definition lookahead_iterator.hpp:38
Definition concepts.hpp:39
Definition concepts.hpp:42
T addressof(T... args)
T move(T... args)