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 "../macros.hpp"
12#include <iterator>
13#include <bit>
14#include <optional>
15#include <string>
16#include <stdexcept>
17#include <array>
18
19hi_export_module(hikogui.parser.lookahead_iterator);
20
21hi_export namespace hi {
22inline namespace v1 {
23
30template<size_t LookaheadCount, typename It, std::sentinel_for<It> ItEnd = std::default_sentinel_t>
32public:
33 static_assert(std::has_single_bit(LookaheadCount), "LookaheadCount must be a power of two.");
34
35 constexpr static size_t max_size = LookaheadCount;
36
37 using value_type = std::iterator_traits<It>::value_type;
38 using reference = value_type const &;
39 using pointer = value_type const *;
40 using difference_type = std::ptrdiff_t;
41 using iterator_category = std::forward_iterator_tag;
42
43 class proxy {
44 public:
45 using value_type = value_type;
46 using reference = reference;
47 using pointer = pointer;
48
49 constexpr proxy(proxy const &) noexcept = default;
50 constexpr proxy(proxy &&) noexcept = default;
51 constexpr proxy &operator=(proxy const &) noexcept = default;
52 constexpr proxy &operator=(proxy &&) noexcept = default;
53 constexpr proxy(value_type other) noexcept : _v(std::move(other)) {}
54
55 constexpr reference operator*() const noexcept
56 {
57 return _v;
58 }
59
60 constexpr pointer operator->() const noexcept
61 {
62 return std::addressof(_v);
63 }
64
65 private:
66 value_type _v;
67 };
68
69 constexpr lookahead_iterator() noexcept = default;
70 constexpr lookahead_iterator(lookahead_iterator const &) noexcept = delete;
71 constexpr lookahead_iterator(lookahead_iterator &&) noexcept = default;
72 constexpr lookahead_iterator&operator=(lookahead_iterator const &) noexcept = delete;
73 constexpr lookahead_iterator&operator=(lookahead_iterator &&) noexcept = default;
74
75 constexpr explicit lookahead_iterator(It first, ItEnd last) noexcept : _it(first), _last(last), _size(0)
76 {
77 while (_size != max_size and _it != last) {
78 add_one_to_lookahead();
79 }
80 }
81
86 [[nodiscard]] constexpr size_t size() const noexcept
87 {
88 return _size;
89 }
90
95 [[nodiscard]] constexpr bool empty() const noexcept
96 {
97 return _size == 0;
98 }
99
100 constexpr explicit operator bool() const noexcept
101 {
102 return not empty();
103 }
104
105 [[nodiscard]] constexpr bool operator==(std::default_sentinel_t) const noexcept
106 {
107 return empty();
108 }
109
115 [[nodiscard]] constexpr reference operator[](size_t i) const noexcept
116 {
117 hi_axiom(i < _size);
118 return _lookahead[(_tail + i) % max_size];
119 }
120
127 [[nodiscard]] constexpr reference at(size_t i) const
128 {
129 if (i < _size) {
130 return (*this)[i];
131 } else {
132 throw std::out_of_range("lookahead_iterator::at()");
133 }
134 }
135
142 [[nodiscard]] constexpr std::optional<value_type> next(size_t i = 1) const noexcept
143 {
144 if (i < _size) {
145 return (*this)[i];
146 } else {
147 return std::nullopt;
148 }
149 }
150
153 constexpr reference operator*() const noexcept
154 {
155 hi_axiom(_size != 0);
156 return (*this)[0];
157 }
158
161 constexpr pointer operator->() const noexcept
162 {
163 hi_axiom(_size != 0);
164 return std::addressof((*this)[0]);
165 }
166
169 constexpr lookahead_iterator &operator++() noexcept
170 {
171 hi_axiom(_size != 0);
172 --_size;
173 ++_tail;
174 add_one_to_lookahead();
175
176 return *this;
177 }
178
179 constexpr lookahead_iterator &operator+=(size_t n) noexcept
180 {
181 for (auto i = 0_uz; i != n; ++i) {
182 ++(*this);
183 }
184 return *this;
185 }
186
187 constexpr proxy operator++(int) noexcept
188 {
189 auto r = proxy{**this};
190 ++(*this);
191 return r;
192 }
193
194private:
195 It _it;
196 ItEnd _last;
197 size_t _size = 0;
198 size_t _tail = 0;
199
200 std::array<value_type, max_size> _lookahead = {};
201
202 constexpr void add_one_to_lookahead() noexcept
203 {
204 hi_axiom(_size < max_size);
205
206 if (_it != _last) {
207 _lookahead[(_tail + _size) % max_size] = *_it;
208 ++_it;
209 ++_size;
210 }
211 }
212};
213
214static_assert(std::movable<lookahead_iterator<2, std::string::iterator, std::string::iterator>>);
215static_assert(std::is_same_v<std::iterator_traits<lookahead_iterator<2, std::string::iterator, std::string::iterator>>::value_type, char>);
216static_assert(std::input_or_output_iterator<lookahead_iterator<2, std::string::iterator, std::string::iterator>>);
217static_assert(std::weakly_incrementable<lookahead_iterator<2, std::string::iterator, std::string::iterator>>);
218
226template<size_t LookaheadCount, typename It, std::sentinel_for<It> ItEnd = std::default_sentinel_t>
227auto make_lookahead_iterator(It first, ItEnd last = std::default_sentinel) noexcept
228{
230}
231
239template<size_t LookaheadCount, std::ranges::range Range>
240auto make_lookahead_iterator(Range const &range) noexcept
241{
242 return make_lookahead_iterator<LookaheadCount>(std::ranges::begin(range), std::ranges::end(range));
243}
244
245}}
246
@ other
The gui_event does not have associated data.
The HikoGUI namespace.
Definition array_generic.hpp:20
auto make_lookahead_iterator(It first, ItEnd last=std::default_sentinel) noexcept
Create a lookahead_iterator from a forward iterator.
Definition lookahead_iterator.hpp:227
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Lookahead iterator.
Definition lookahead_iterator.hpp:31
constexpr lookahead_iterator & operator++() noexcept
Increment the iterator.
Definition lookahead_iterator.hpp:169
constexpr size_t size() const noexcept
The number of entries can be looked ahead.
Definition lookahead_iterator.hpp:86
constexpr pointer operator->() const noexcept
Get a pointer to the value at the iterator.
Definition lookahead_iterator.hpp:161
constexpr reference at(size_t i) const
Get a reference to an item at or beyond the iterator.
Definition lookahead_iterator.hpp:127
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:142
constexpr reference operator[](size_t i) const noexcept
Get a reference to an item at or beyond the iterator.
Definition lookahead_iterator.hpp:115
constexpr reference operator*() const noexcept
Get a reference to the value at the iterator.
Definition lookahead_iterator.hpp:153
constexpr bool empty() const noexcept
Check if the iterator is at end.
Definition lookahead_iterator.hpp:95
Definition lookahead_iterator.hpp:43
T addressof(T... args)
T move(T... args)