tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
inplace_vector.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2024 Tobias Hienzsch
3
4#ifndef TETL_INPLACE_VECTOR_INPLACE_VECTOR_HPP
5#define TETL_INPLACE_VECTOR_INPLACE_VECTOR_HPP
6
7#include <etl/_config/all.hpp>
8
9#include <etl/_array/uninitialized_array.hpp>
10#include <etl/_contracts/check.hpp>
11#include <etl/_cstddef/ptrdiff_t.hpp>
12#include <etl/_cstddef/size_t.hpp>
13#include <etl/_iterator/next.hpp>
14#include <etl/_iterator/prev.hpp>
15#include <etl/_iterator/reverse_iterator.hpp>
16#include <etl/_memory/ranges_construct_at.hpp>
17#include <etl/_memory/ranges_destroy.hpp>
18#include <etl/_memory/ranges_destroy_at.hpp>
19#include <etl/_memory/uninitialized_copy.hpp>
20#include <etl/_memory/uninitialized_move.hpp>
21#include <etl/_type_traits/conditional.hpp>
22#include <etl/_type_traits/is_nothrow_copy_constructible.hpp>
23#include <etl/_type_traits/is_nothrow_move_constructible.hpp>
24#include <etl/_type_traits/is_trivially_copy_constructible.hpp>
25#include <etl/_type_traits/is_trivially_destructible.hpp>
26#include <etl/_type_traits/is_trivially_move_constructible.hpp>
27#include <etl/_type_traits/smallest_size_t.hpp>
28#include <etl/_utility/exchange.hpp>
29#include <etl/_utility/forward.hpp>
30#include <etl/_utility/move.hpp>
31#include <etl/_utility/unreachable.hpp>
32
33namespace etl {
34
35/// \headerfile etl/inplace_vector.hpp
36/// \ingroup inplace_vector
37template <typename T, etl::size_t Capacity>
39 using value_type = T;
40 using size_type = etl::size_t;
41 using difference_type = etl::ptrdiff_t;
42 using reference = value_type&;
43 using const_reference = value_type const&;
44 using pointer = T*;
45 using const_pointer = T const*;
46 using iterator = T*;
47 using const_iterator = T const*;
48 using reverse_iterator = etl::reverse_iterator<iterator>;
49 using const_reverse_iterator = etl::reverse_iterator<const_iterator>;
50
51 constexpr inplace_vector() = default;
52
54 requires etl::is_trivially_copy_constructible_v<T>
55 = default;
56
58 {
59 etl::uninitialized_copy(other.begin(), other.end(), begin());
60 _size = other._size; // NOLINT(cppcoreguidelines-prefer-member-initializer)
61 }
62
64 requires etl::is_trivially_move_constructible_v<T>
65 = default;
66
68 {
69 etl::uninitialized_move(other.begin(), other.end(), begin());
70 _size = etl::exchange(other._size, internal_size_t{}); // NOLINT(cppcoreguidelines-prefer-member-initializer)
71 }
72
73 ~inplace_vector()
74 requires etl::is_trivially_destructible_v<T>
75 = default;
76
77 constexpr ~inplace_vector()
78 {
79 etl::ranges::destroy(*this);
80 }
81
82 [[nodiscard]] constexpr auto begin() const noexcept -> T const*
83 {
84 return data();
85 }
86
87 [[nodiscard]] constexpr auto begin() noexcept -> T*
88 {
89 return data();
90 }
91
92 [[nodiscard]] constexpr auto end() const noexcept -> T const*
93 {
94 return etl::next(begin(), static_cast<etl::ptrdiff_t>(size()));
95 }
96
97 [[nodiscard]] constexpr auto end() noexcept -> T*
98 {
99 return etl::next(begin(), static_cast<etl::ptrdiff_t>(size()));
100 }
101
102 [[nodiscard]] constexpr auto data() const noexcept -> T const*
103 {
104 return _storage.data();
105 }
106
107 [[nodiscard]] constexpr auto data() noexcept -> T*
108 {
109 return _storage.data();
110 }
111
112 [[nodiscard]] constexpr auto empty() const noexcept -> bool
113 {
114 return size() == 0;
115 }
116
117 [[nodiscard]] constexpr auto size() const noexcept -> etl::size_t
118 {
119 return static_cast<etl::size_t>(_size);
120 }
121
122 [[nodiscard]] static constexpr auto capacity() noexcept -> etl::size_t
123 {
124 return Capacity;
125 }
126
127 [[nodiscard]] static constexpr auto max_size() noexcept -> etl::size_t
128 {
129 return Capacity;
130 }
131
132 [[nodiscard]] constexpr auto front() -> reference
133 {
134 TETL_PRECONDITION(not empty());
135 return *begin();
136 }
137
138 [[nodiscard]] constexpr auto front() const -> const_reference
139 {
140 TETL_PRECONDITION(not empty());
141 return *begin();
142 }
143
144 [[nodiscard]] constexpr auto back() -> reference
145 {
146 TETL_PRECONDITION(not empty());
147 return *etl::prev(end());
148 }
149
150 [[nodiscard]] constexpr auto back() const -> const_reference
151 {
152 TETL_PRECONDITION(not empty());
153 return *etl::prev(end());
154 }
155
156 [[nodiscard]] constexpr auto operator[](size_type n) -> reference
157 {
158 TETL_PRECONDITION(n < size());
159 return *etl::next(data(), static_cast<etl::ptrdiff_t>(n));
160 }
161
162 [[nodiscard]] constexpr auto operator[](size_type n) const -> const_reference
163 {
164 TETL_PRECONDITION(n < size());
165 return *etl::next(data(), static_cast<etl::ptrdiff_t>(n));
166 }
167
168 template <typename... Args>
169 constexpr auto try_emplace_back(Args&&... args) -> T*
170 {
171 if (size() == capacity()) {
172 return nullptr;
173 }
174 return etl::addressof(unchecked_emplace_back(etl::forward<Args>(args)...));
175 }
176
177 constexpr auto try_push_back(T const& val) -> T*
178 {
179 if (size() == capacity()) {
180 return nullptr;
181 }
182
183 return etl::addressof(unchecked_push_back(val));
184 }
185
186 constexpr auto try_push_back(T&& val) -> T*
187 {
188 if (size() == capacity()) {
189 return nullptr;
190 }
191
192 return etl::addressof(unchecked_push_back(etl::move(val)));
193 }
194
195 template <typename... Args>
196 constexpr auto unchecked_emplace_back(Args&&... args) -> T&
197 {
198 TETL_PRECONDITION(size() != max_size());
199 etl::ranges::construct_at(end(), etl::forward<Args>(args)...);
200 unsafe_set_size(size() + 1U);
201 return back();
202 }
203
204 constexpr auto unchecked_push_back(T const& val) -> T&
205 {
206 TETL_PRECONDITION(size() != max_size());
207 etl::ranges::construct_at(end(), val);
208 unsafe_set_size(size() + 1U);
209 return back();
210 }
211
212 constexpr auto unchecked_push_back(T&& val) -> T&
213 {
214 TETL_PRECONDITION(size() != max_size());
215 etl::ranges::construct_at(end(), etl::move(val));
216 unsafe_set_size(size() + 1U);
217 return back();
218 }
219
220 constexpr auto pop_back() -> void
221 {
222 TETL_PRECONDITION(not empty());
223 etl::ranges::destroy_at(etl::addressof(back()));
224 unsafe_set_size(size() - 1U);
225 }
226
227 constexpr auto clear() noexcept -> void
228 {
229 etl::ranges::destroy(*this);
230 unsafe_set_size(0);
231 }
232
233private:
234 constexpr auto unsafe_set_size(size_type newSize) noexcept -> void
235 {
236 TETL_PRECONDITION(newSize <= max_size());
237 _size = static_cast<internal_size_t>(newSize);
238 }
239
240 using internal_size_t = etl::smallest_size_t<Capacity>;
241 TETL_NO_UNIQUE_ADDRESS etl::uninitialized_array<T, Capacity> _storage;
242 TETL_NO_UNIQUE_ADDRESS internal_size_t _size;
243};
244
245template <typename T>
246struct inplace_vector<T, 0> {
247 using value_type = T;
248 using size_type = etl::size_t;
249 using difference_type = etl::ptrdiff_t;
250 using reference = value_type&;
251 using const_reference = value_type const&;
252 using pointer = T*;
253 using const_pointer = T const*;
254 using iterator = T*;
255 using const_iterator = T const*;
256 using reverse_iterator = etl::reverse_iterator<iterator>;
257 using const_reverse_iterator = etl::reverse_iterator<const_iterator>;
258
259 constexpr inplace_vector() = default;
260
261 [[nodiscard]] constexpr auto begin() const noexcept -> T const*
262 {
263 return data();
264 }
265
266 [[nodiscard]] constexpr auto begin() noexcept -> T*
267 {
268 return data();
269 }
270
271 [[nodiscard]] constexpr auto end() const noexcept -> T const*
272 {
273 return nullptr;
274 }
275
276 [[nodiscard]] constexpr auto end() noexcept -> T*
277 {
278 return nullptr;
279 }
280
281 [[nodiscard]] constexpr auto data() const noexcept -> T const*
282 {
283 return nullptr;
284 }
285
286 [[nodiscard]] constexpr auto data() noexcept -> T*
287 {
288 return nullptr;
289 }
290
291 [[nodiscard]] constexpr auto empty() const noexcept -> bool
292 {
293 return size() == 0;
294 }
295
296 [[nodiscard]] constexpr auto size() const noexcept -> etl::size_t
297 {
298 return 0;
299 }
300
301 [[nodiscard]] static constexpr auto capacity() noexcept -> etl::size_t
302 {
303 return 0;
304 }
305
306 [[nodiscard]] static constexpr auto max_size() noexcept -> etl::size_t
307 {
308 return 0;
309 }
310
311 [[nodiscard]] constexpr auto front() -> reference
312 {
314 }
315
316 [[nodiscard]] constexpr auto front() const -> const_reference
317 {
319 }
320
321 [[nodiscard]] constexpr auto back() -> reference
322 {
324 }
325
326 [[nodiscard]] constexpr auto back() const -> const_reference
327 {
329 }
330
331 [[nodiscard]] constexpr auto operator[](size_type /*n*/) -> reference
332 {
334 }
335
336 [[nodiscard]] constexpr auto operator[](size_type /*n*/) const -> const_reference
337 {
339 }
340
341 constexpr auto try_push_back(T const& /*val*/) -> T*
342 {
343 return nullptr;
344 }
345
346 constexpr auto try_push_back(T&& /*val*/) -> T*
347 {
348 return nullptr;
349 }
350
351 template <typename... Args>
352 constexpr auto try_emplace_back(Args&&... /*args*/) -> T*
353 {
354 return nullptr;
355 }
356
357 constexpr auto unchecked_push_back(T const& /*val*/) -> T&
358 {
360 }
361
362 constexpr auto unchecked_push_back(T&& /*val*/) -> T&
363 {
365 }
366
367 template <typename... Args>
368 constexpr auto unchecked_emplace_back(Args&&... /*args*/) -> T&
369 {
371 }
372
373 constexpr auto pop_back() -> void
374 {
376 }
377
378 constexpr auto clear() noexcept -> void { }
379};
380
381} // namespace etl
382
383#endif // TETL_INPLACE_VECTOR_INPLACE_VECTOR_HPP
Definition ranges_in_fun_result.hpp:12
Definition adjacent_find.hpp:9
auto unreachable() -> void
Definition unreachable.hpp:11
constexpr auto try_push_back(T &&) -> T *
Definition inplace_vector.hpp:346
constexpr auto data() const noexcept -> T const *
Definition inplace_vector.hpp:281
constexpr auto unchecked_push_back(T &&) -> T &
Definition inplace_vector.hpp:362
constexpr auto try_emplace_back(Args &&...) -> T *
Definition inplace_vector.hpp:352
constexpr auto back() const -> const_reference
Definition inplace_vector.hpp:326
constexpr auto unchecked_push_back(T const &) -> T &
Definition inplace_vector.hpp:357
constexpr auto pop_back() -> void
Definition inplace_vector.hpp:373
constexpr auto operator[](size_type) -> reference
Definition inplace_vector.hpp:331
constexpr auto unchecked_emplace_back(Args &&...) -> T &
Definition inplace_vector.hpp:368
constexpr auto front() -> reference
Definition inplace_vector.hpp:311
static constexpr auto capacity() noexcept -> etl::size_t
Definition inplace_vector.hpp:301
constexpr inplace_vector()=default
constexpr auto begin() noexcept -> T *
Definition inplace_vector.hpp:266
constexpr auto data() noexcept -> T *
Definition inplace_vector.hpp:286
constexpr auto begin() const noexcept -> T const *
Definition inplace_vector.hpp:261
constexpr auto front() const -> const_reference
Definition inplace_vector.hpp:316
constexpr auto empty() const noexcept -> bool
Definition inplace_vector.hpp:291
constexpr auto clear() noexcept -> void
Definition inplace_vector.hpp:378
constexpr auto try_push_back(T const &) -> T *
Definition inplace_vector.hpp:341
constexpr auto end() const noexcept -> T const *
Definition inplace_vector.hpp:271
constexpr auto back() -> reference
Definition inplace_vector.hpp:321
static constexpr auto max_size() noexcept -> etl::size_t
Definition inplace_vector.hpp:306
constexpr auto size() const noexcept -> etl::size_t
Definition inplace_vector.hpp:296
constexpr auto end() noexcept -> T *
Definition inplace_vector.hpp:276
constexpr auto operator[](size_type) const -> const_reference
Definition inplace_vector.hpp:336
Definition inplace_vector.hpp:38
constexpr auto data() const noexcept -> T const *
Definition inplace_vector.hpp:102
constexpr auto back() const -> const_reference
Definition inplace_vector.hpp:150
constexpr auto pop_back() -> void
Definition inplace_vector.hpp:220
constexpr auto front() -> reference
Definition inplace_vector.hpp:132
constexpr auto unchecked_emplace_back(Args &&... args) -> T &
Definition inplace_vector.hpp:196
static constexpr auto capacity() noexcept -> etl::size_t
Definition inplace_vector.hpp:122
constexpr auto try_push_back(T &&val) -> T *
Definition inplace_vector.hpp:186
constexpr inplace_vector()=default
constexpr ~inplace_vector()
Definition inplace_vector.hpp:77
constexpr auto operator[](size_type n) -> reference
Definition inplace_vector.hpp:156
inplace_vector(inplace_vector const &other)=default
constexpr auto unchecked_push_back(T const &val) -> T &
Definition inplace_vector.hpp:204
constexpr auto begin() noexcept -> T *
Definition inplace_vector.hpp:87
constexpr auto data() noexcept -> T *
Definition inplace_vector.hpp:107
constexpr auto begin() const noexcept -> T const *
Definition inplace_vector.hpp:82
constexpr auto front() const -> const_reference
Definition inplace_vector.hpp:138
constexpr auto empty() const noexcept -> bool
Definition inplace_vector.hpp:112
inplace_vector(inplace_vector &&other)=default
constexpr auto clear() noexcept -> void
Definition inplace_vector.hpp:227
constexpr auto unchecked_push_back(T &&val) -> T &
Definition inplace_vector.hpp:212
constexpr auto end() const noexcept -> T const *
Definition inplace_vector.hpp:92
constexpr auto back() -> reference
Definition inplace_vector.hpp:144
constexpr auto try_emplace_back(Args &&... args) -> T *
Definition inplace_vector.hpp:169
constexpr auto try_push_back(T const &val) -> T *
Definition inplace_vector.hpp:177
static constexpr auto max_size() noexcept -> etl::size_t
Definition inplace_vector.hpp:127
constexpr auto size() const noexcept -> etl::size_t
Definition inplace_vector.hpp:117
constexpr auto end() noexcept -> T *
Definition inplace_vector.hpp:97
constexpr auto operator[](size_type n) const -> const_reference
Definition inplace_vector.hpp:162
Definition uninitialized_array.hpp:26