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