HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
vector_span.hpp
1// Copyright Take Vos 2020-2022.
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
5#pragma once
6
7#include "utility/module.hpp"
8#include <span>
9#include <iterator>
10#include <memory>
11#include <new>
12
13namespace hi::inline v1 {
14
15template<typename T>
17public:
18 using value_type = T;
19 using difference_type = ssize_t;
20
21private:
22 value_type *ptr;
23
24public:
25 vector_span_iterator() noexcept : ptr(nullptr) {}
26 vector_span_iterator(vector_span_iterator const &other) noexcept = default;
27 vector_span_iterator(vector_span_iterator &&other) noexcept = default;
28 vector_span_iterator &operator=(vector_span_iterator const &other) noexcept = default;
29 vector_span_iterator &operator=(vector_span_iterator &&other) noexcept = default;
30 ~vector_span_iterator() = default;
31
32 vector_span_iterator(value_type *ptr) noexcept : ptr(ptr)
33 {
35 }
36
37 vector_span_iterator &operator=(value_type *ptr) noexcept
38 {
40 this->ptr = ptr;
41 return *this;
42 }
43
44 [[nodiscard]] value_type &operator*() noexcept
45 {
46 return *std::launder(ptr);
47 }
48 [[nodiscard]] value_type const &operator*() const noexcept
49 {
50 return *std::launder(ptr);
51 }
52 [[nodiscard]] value_type *operator->() noexcept
53 {
54 return std::launder(ptr);
55 }
56 [[nodiscard]] value_type const *operator->() const noexcept
57 {
58 return std::launder(ptr);
59 }
60 [[nodiscard]] value_type &operator[](std::size_t i) noexcept
61 {
62 return *std::launder(ptr + i);
63 }
64 [[nodiscard]] value_type const &operator[](std::size_t i) const noexcept
65 {
66 return *std::launder(ptr + i);
67 }
68
69 vector_span_iterator &operator++() noexcept
70 {
71 ++ptr;
72 return *this;
73 }
74 vector_span_iterator operator++(int) noexcept
75 {
76 auto tmp = *this;
77 ++ptr;
78 return tmp;
79 }
80 vector_span_iterator &operator--() noexcept
81 {
82 --ptr;
83 return *this;
84 }
85 vector_span_iterator operator--(int) noexcept
86 {
87 auto tmp = *this;
88 --ptr;
89 return tmp;
90 }
91
92 vector_span_iterator &operator+=(ssize_t rhs) noexcept
93 {
94 ptr += rhs;
95 return *this;
96 }
97 vector_span_iterator &operator-=(ssize_t rhs) noexcept
98 {
99 ptr -= rhs;
100 return *this;
101 }
102
103 [[nodiscard]] friend bool operator==(vector_span_iterator const &lhs, vector_span_iterator const &rhs) noexcept
104 {
105 return lhs.ptr == rhs.ptr;
106 }
107
108 [[nodiscard]] friend auto operator<=>(vector_span_iterator const &lhs, vector_span_iterator const &rhs) noexcept
109 {
110 return lhs.ptr <=> rhs.ptr;
111 }
112
113 [[nodiscard]] friend vector_span_iterator operator+(vector_span_iterator const &lhs, ssize_t rhs) noexcept
114 {
115 return vector_span_iterator{lhs.ptr + rhs};
116 }
117 [[nodiscard]] friend vector_span_iterator operator-(vector_span_iterator const &lhs, ssize_t rhs) noexcept
118 {
119 return vector_span_iterator{lhs.ptr - rhs};
120 }
121 [[nodiscard]] friend vector_span_iterator operator+(ssize_t lhs, vector_span_iterator const &rhs) noexcept
122 {
123 return vector_span_iterator{lhs + rhs.ptr};
124 }
125
126 [[nodiscard]] friend difference_type operator-(vector_span_iterator const &lhs, vector_span_iterator const &rhs) noexcept
127 {
128 return lhs.ptr - rhs.ptr;
129 }
130};
131
132template<typename T>
134public:
135 using value_type = T;
138
139private:
140 value_type *_begin;
141 value_type *_end;
142 value_type *_max;
143
144public:
145 constexpr vector_span() noexcept : _begin(nullptr), _end(nullptr), _max(nullptr) {}
146
147 constexpr vector_span(value_type *buffer, ssize_t nr_elements) noexcept :
148 _begin(buffer), _end(buffer), _max(buffer + nr_elements)
149 {
150 hi_axiom(nr_elements >= 0);
151 }
152
153 constexpr vector_span(std::span<value_type> span) noexcept :
154 _begin(span.data()), _end(span.data()), _max(span.data() + span.size())
155 {
156 }
157
158 constexpr vector_span(vector_span const& other) = default;
159 constexpr vector_span(vector_span&& other) = default;
160 constexpr vector_span& operator=(vector_span const& other) = default;
161 constexpr vector_span& operator=(vector_span&& other) = default;
162 ~vector_span() = default;
163
164 [[nodiscard]] constexpr iterator begin() noexcept
165 {
166 return _begin;
167 }
168
169 [[nodiscard]] constexpr const_iterator begin() const noexcept
170 {
171 return _begin;
172 }
173
174 [[nodiscard]] constexpr const_iterator cbegin() const noexcept
175 {
176 return _begin;
177 }
178
179 [[nodiscard]] constexpr iterator end() noexcept
180 {
181 return _end;
182 }
183
184 [[nodiscard]] constexpr const_iterator end() const noexcept
185 {
186 return _end;
187 }
188
189 [[nodiscard]] constexpr const_iterator cend() const noexcept
190 {
191 return _end;
192 }
193
194 [[nodiscard]] constexpr std::size_t size() const noexcept
195 {
196 return std::distance(_begin, _end);
197 }
198
199 [[nodiscard]] constexpr value_type& operator[](std::size_t i) noexcept
200 {
201 hi_axiom_bounds(i, *this);
202 return _begin[i];
203 }
204 [[nodiscard]] constexpr value_type const& operator[](std::size_t i) const noexcept
205 {
206 hi_axiom_bounds(i, *this);
207 return _begin[i];
208 }
209
210 constexpr value_type& front() noexcept
211 {
212 hi_axiom(_end != _begin);
213 return *_begin;
214 }
215
216 constexpr value_type const& front() const noexcept
217 {
218 hi_axiom(_end != _begin);
219 return *_begin;
220 }
221
222 constexpr value_type& back() noexcept
223 {
224 hi_axiom(_end != _begin);
225 return *(_end - 1);
226 }
227
228 constexpr value_type const& back() const noexcept
229 {
230 hi_axiom(_end != _begin);
231 return *(_end - 1);
232 }
233
234 [[nodiscard]] constexpr bool empty() const noexcept
235 {
236 return _begin == _end;
237 }
238
239 [[nodiscard]] constexpr bool full() const noexcept
240 {
241 return _end == _max;
242 }
243
244 constexpr void clear() noexcept
245 {
246 for (auto ptr = _begin; ptr != _end; ++ptr) {
247 std::destroy_at(ptr);
248 }
249 _end = _begin;
250 }
251
252 constexpr void push_back(value_type const& rhs) noexcept
253 {
254 hi_axiom(_end != _max);
255 std::construct_at(_end++, rhs);
256 }
257
258 constexpr void push_back(value_type&& rhs) noexcept
259 {
260 hi_axiom(_end != _max);
261 std::construct_at(_end++, std::move(rhs));
262 }
263
264 template<typename... Args>
265 constexpr void emplace_back(Args&&...args) noexcept
266 {
267 hi_axiom(_end != _max);
268 std::construct_at(_end++, std::forward<Args>(args)...);
269 }
270
271 constexpr void pop_back() noexcept
272 {
273 hi_axiom(_end != _begin);
274 std::destroy_at(--_end);
275 }
276};
277
278} // namespace hi::inline v1
#define hi_axiom_bounds(x,...)
Specify an axiom that the value is within bounds.
Definition assert.hpp:264
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hi_assert_not_null(x,...)
Assert if an expression is not nullptr.
Definition assert.hpp:238
DOXYGEN BUG.
Definition algorithm.hpp:13
Definition vector_span.hpp:16
Definition vector_span.hpp:133
T distance(T... args)
T move(T... args)