vecmem 1.18.0
Loading...
Searching...
No Matches
static_vector.ipp
1/* VecMem project, part of the ACTS project (R&D line)
2 *
3 * (c) 2021-2025 CERN for the benefit of the ACTS project
4 *
5 * Mozilla Public License Version 2.0
6 */
7#pragma once
8
9// Local include(s).
10#include "vecmem/utils/memmove.hpp"
11
12// System include(s).
13#include <cassert>
14
15namespace vecmem {
16
17template <typename TYPE, std::size_t MAX_SIZE>
19 : m_size(0), m_elements() {}
20
21template <typename TYPE, std::size_t MAX_SIZE>
23 size_type size, const_reference value)
24 : m_size(size), m_elements() {
25
26 assign(size, value);
27}
28
29template <typename TYPE, std::size_t MAX_SIZE>
30VECMEM_HOST_AND_DEVICE typename static_vector<TYPE, MAX_SIZE>::reference
32
33 // Make sure that the element exists.
34 assert(pos < m_size);
35
36 // Return the element.
37 return *(reinterpret_cast<pointer>(m_elements) + pos);
38}
39
40template <typename TYPE, std::size_t MAX_SIZE>
41VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::at(
42 size_type pos) const -> const_reference {
43
44 // Make sure that the element exists.
45 assert(pos < m_size);
46
47 // Return the element.
48 return *(reinterpret_cast<const_pointer>(m_elements) + pos);
49}
50
51template <typename TYPE, std::size_t MAX_SIZE>
54
55 // Return the element.
56 return *(reinterpret_cast<pointer>(m_elements) + pos);
57}
58
59template <typename TYPE, std::size_t MAX_SIZE>
61 size_type pos) const -> const_reference {
62
63 // Return the element.
64 return *(reinterpret_cast<const_pointer>(m_elements) + pos);
65}
66
67template <typename TYPE, std::size_t MAX_SIZE>
68VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::front()
69 -> reference {
70
71 // Make sure that the element exists.
72 assert(m_size > 0);
73
74 // Return the element.
75 return *(reinterpret_cast<pointer>(m_elements));
76}
77
78template <typename TYPE, std::size_t MAX_SIZE>
79VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::front() const
81
82 // Make sure that the element exists.
83 assert(m_size > 0);
84
85 // Return the element.
86 return *(reinterpret_cast<const_pointer>(m_elements));
87}
88
89template <typename TYPE, std::size_t MAX_SIZE>
90VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::back() -> reference {
91
92 // Make sure that the element exists.
93 assert(m_size > 0);
94
95 // Return the element.
96 return *(reinterpret_cast<pointer>(m_elements) + m_size - 1);
97}
98
99template <typename TYPE, std::size_t MAX_SIZE>
100VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::back() const
101 -> const_reference {
102
103 // Make sure that the element exists.
104 assert(m_size > 0);
105
106 // Return the element.
107 return *(reinterpret_cast<const_pointer>(m_elements) + m_size - 1);
108}
109
110template <typename TYPE, std::size_t MAX_SIZE>
111VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::data() -> pointer {
112
113 return reinterpret_cast<pointer>(m_elements);
114}
115
116template <typename TYPE, std::size_t MAX_SIZE>
117VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::data() const
118 -> const_pointer {
119
120 return reinterpret_cast<const_pointer>(m_elements);
121}
122
123template <typename TYPE, std::size_t MAX_SIZE>
124VECMEM_HOST_AND_DEVICE void static_vector<TYPE, MAX_SIZE>::assign(
125 size_type count, const_reference value) {
126
127 // Make sure that the sizes are compatible.
128 assert(array_max_size >= count);
129
130 // Remove all previous elements.
131 clear();
132
133 // Create the required number of identical elements.
134 for (size_type i = 0; i < count; ++i) {
135 construct(i, value);
136 }
137
138 // Set the assigned size of the vector.
139 m_size = count;
140}
141
142template <typename TYPE, std::size_t MAX_SIZE>
143VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::insert(
145
146 // Make sure that one more position is available.
147 assert(m_size < array_max_size);
148
149 // Find the index of this iterator inside of the vector.
150 auto id = element_id(pos);
151
152 // Move the payload of the existing elements after "pos".
153 details::memmove(static_cast<void*>(id.m_ptr + 1),
154 static_cast<const void*>(id.m_ptr),
155 (m_size - id.m_index) * value_size);
156
157 // Instantiate the new value.
158 construct(id.m_index, value);
159
160 // Increment the size.
161 ++m_size;
162
163 // Return an iterator to the inserted element.
164 return id.m_ptr;
165}
166
167template <typename TYPE, std::size_t MAX_SIZE>
168VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::insert(
170
171 // Make sure that the requested number of positions are still available.
172 assert(m_size + count <= array_max_size);
173
174 // Find the index of this iterator inside of the vector.
175 auto id = element_id(pos);
176
177 // Move the payload of the existing elements after "pos".
178 details::memmove(static_cast<void*>(id.m_ptr + count),
179 static_cast<const void*>(id.m_ptr),
180 (m_size - id.m_index) * value_size);
181
182 // Instantiate all the new values.
183 for (size_type i = 0; i < count; ++i) {
184 construct(id.m_index + i, value);
185 }
186
187 // Increment the size.
188 m_size += count;
189
190 // Return an iterator to the first inserted element.
191 return id.m_ptr;
192}
193
194template <typename TYPE, std::size_t MAX_SIZE>
195template <typename... Args>
196VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::emplace(
197 const_iterator pos, Args&&... args) -> iterator {
198
199 // Make sure that one more position is available.
200 assert(m_size < array_max_size);
201
202 // Find the index of this iterator inside of the vector.
203 auto id = element_id(pos);
204
205 // Move the payload of the existing elements after "pos".
206 details::memmove(static_cast<void*>(id.m_ptr + 1),
207 static_cast<const void*>(id.m_ptr),
208 (m_size - id.m_index) * value_size);
209
210 // Instantiate the new value.
211 new (id.m_ptr) value_type(std::forward<Args>(args)...);
212
213 // Increment the size.
214 ++m_size;
215
216 // Return an iterator to the inserted element.
217 return id.m_ptr;
218}
219
220template <typename TYPE, std::size_t MAX_SIZE>
221template <typename... Args>
222VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::emplace_back(
223 Args&&... args) -> reference {
224
225 return *(emplace(end(), std::forward<Args>(args)...));
226}
227
228template <typename TYPE, std::size_t MAX_SIZE>
230 const_reference value) {
231
232 insert(end(), value);
233}
234
235template <typename TYPE, std::size_t MAX_SIZE>
236VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::erase(
238
239 // Find the index of this iterator inside of the vector.
240 auto id = element_id(pos);
241
242 // Move up the payload of the elements from after the removed one.
243 details::memmove(static_cast<void*>(id.m_ptr),
244 static_cast<const void*>(id.m_ptr + 1),
245 (m_size - id.m_index - 1) * value_size);
246
247 // Decrement the size.
248 --m_size;
249
250 // Return an iterator to after the removed element.
251 return id.m_ptr;
252}
253
254template <typename TYPE, std::size_t MAX_SIZE>
255VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::erase(
257
258 // Find the indices and pointers of the iterators.
259 auto first_id = element_id(first);
260 auto last_id = element_id(last);
261 assert(first_id.m_index <= last_id.m_index);
262
263 // Move up the payload of the elements from after the removed range.
264 details::memmove(static_cast<void*>(first_id.m_ptr),
265 static_cast<const void*>(last_id.m_ptr),
266 (m_size - last_id.m_index) * value_size);
267
268 // Decrease the size.
269 m_size -= (last_id.m_index - first_id.m_index);
270
271 // Return an iterator to after the removed elements.
272 return first_id.m_ptr;
273}
274
275template <typename TYPE, std::size_t MAX_SIZE>
276VECMEM_HOST_AND_DEVICE void static_vector<TYPE, MAX_SIZE>::pop_back() {
277
278 erase(end() - 1);
279}
280
281template <typename TYPE, std::size_t MAX_SIZE>
282VECMEM_HOST_AND_DEVICE void static_vector<TYPE, MAX_SIZE>::clear() {
283
284 m_size = 0;
285}
286
287template <typename TYPE, std::size_t MAX_SIZE>
288VECMEM_HOST_AND_DEVICE void static_vector<TYPE, MAX_SIZE>::resize(
289 std::size_t new_size) {
290
291 resize(new_size, value_type());
292}
293
294template <typename TYPE, std::size_t MAX_SIZE>
295VECMEM_HOST_AND_DEVICE void static_vector<TYPE, MAX_SIZE>::resize(
296 std::size_t new_size, const_reference value) {
297
298 // Make sure that the request can be done.
299 assert(new_size <= array_max_size);
300
301 // Check if anything even needs to be done.
302 if (new_size == m_size) {
303 return;
304 }
305
306 // If the new size is smaller than the current size, remove the unwanted
307 // elements.
308 if (new_size < m_size) {
309 erase(begin() + new_size, end());
310 }
311 // If the new size is larger than the current size, insert extra elements.
312 else {
313 insert(end(), new_size - m_size, value);
314 }
315}
316
317template <typename TYPE, std::size_t MAX_SIZE>
318VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::begin() -> iterator {
319
320 return reinterpret_cast<iterator>(m_elements);
321}
322
323template <typename TYPE, std::size_t MAX_SIZE>
324VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::begin() const
325 -> const_iterator {
326
327 return reinterpret_cast<const_iterator>(m_elements);
328}
329
330template <typename TYPE, std::size_t MAX_SIZE>
331VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::cbegin() const
332 -> const_iterator {
333
334 return begin();
335}
336
337template <typename TYPE, std::size_t MAX_SIZE>
338VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::end() -> iterator {
339
340 return (reinterpret_cast<iterator>(m_elements) + m_size);
341}
342
343template <typename TYPE, std::size_t MAX_SIZE>
344VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::end() const
345 -> const_iterator {
346
347 return (reinterpret_cast<const_iterator>(m_elements) + m_size);
348}
349
350template <typename TYPE, std::size_t MAX_SIZE>
351VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::cend() const
352 -> const_iterator {
353
354 return end();
355}
356
357template <typename TYPE, std::size_t MAX_SIZE>
358VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::rbegin()
360
361 return reverse_iterator(end());
362}
363
364template <typename TYPE, std::size_t MAX_SIZE>
365VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::rbegin() const
367
368 return const_reverse_iterator(end());
369}
370
371template <typename TYPE, std::size_t MAX_SIZE>
374
375 return rbegin();
376}
377
378template <typename TYPE, std::size_t MAX_SIZE>
379VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::rend()
381
382 return reverse_iterator(begin());
383}
384
385template <typename TYPE, std::size_t MAX_SIZE>
386VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::rend() const
388
389 return const_reverse_iterator(begin());
390}
391
392template <typename TYPE, std::size_t MAX_SIZE>
393VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::crend() const
395
396 return rend();
397}
398
399template <typename TYPE, std::size_t MAX_SIZE>
400VECMEM_HOST_AND_DEVICE bool static_vector<TYPE, MAX_SIZE>::empty() const {
401
402 return m_size == 0;
403}
404
405template <typename TYPE, std::size_t MAX_SIZE>
406VECMEM_HOST_AND_DEVICE auto static_vector<TYPE, MAX_SIZE>::size() const
407 -> size_type {
408
409 return m_size;
410}
411
412template <typename TYPE, std::size_t MAX_SIZE>
414 -> size_type {
415
416 return array_max_size;
417}
418
419template <typename TYPE, std::size_t MAX_SIZE>
421 -> size_type {
422
423 return array_max_size;
424}
425
426template <typename TYPE, std::size_t MAX_SIZE>
427VECMEM_HOST_AND_DEVICE void static_vector<TYPE, MAX_SIZE>::reserve(
429
430 // Make sure that the user didn't ask for too much.
431 assert(new_cap <= array_max_size);
432 (void)new_cap;
433}
434
435template <typename TYPE, std::size_t MAX_SIZE>
436VECMEM_HOST_AND_DEVICE void static_vector<TYPE, MAX_SIZE>::construct(
437 size_type pos, const_reference value) {
438
439 // Make sure that the position is available.
440 assert(pos < array_max_size);
441
442 // Use the constructor of the type.
443 pointer ptr = reinterpret_cast<pointer>(m_elements) + pos;
444 new (ptr) value_type(value);
445}
446
447template <typename TYPE, std::size_t MAX_SIZE>
448VECMEM_HOST_AND_DEVICE typename static_vector<TYPE, MAX_SIZE>::ElementId
449static_vector<TYPE, MAX_SIZE>::element_id(const_iterator pos) {
450
451 size_type const index = static_cast<size_type>(pos - begin());
452 assert(index <= m_size);
453 pointer const ptr = reinterpret_cast<pointer>(m_elements) + index;
454 return {index, ptr};
455}
456
457} // namespace vecmem
An allocator class that wraps a memory resource.
Definition allocator.hpp:37
Type mimicking std::reverse_iterator.
Definition reverse_iterator.hpp:25
Class mimicking std::vector on top of a fixed sized array.
Definition static_vector.hpp:30
VECMEM_HOST_AND_DEVICE size_type capacity() const
Return the current (fixed) capacity of the vector.
Definition static_vector.ipp:420
VECMEM_HOST_AND_DEVICE void assign(size_type count, const_reference value)
Assign new values to the vector.
Definition static_vector.ipp:124
VECMEM_HOST_AND_DEVICE const_iterator cend() const
Return a constant forward iterator pointing at the end of the vector.
Definition static_vector.ipp:351
std::add_lvalue_reference_t< value_type > reference
Value reference type.
Definition static_vector.hpp:67
VECMEM_HOST_AND_DEVICE reference at(size_type pos)
Return a specific element of the vector in a "safe way" (non-const)
Definition static_vector.ipp:31
VECMEM_HOST_AND_DEVICE void resize(std::size_t new_size)
Resize the vector.
Definition static_vector.ipp:288
VECMEM_HOST_AND_DEVICE bool empty() const
Check whether the vector is empty.
Definition static_vector.ipp:400
std::size_t size_type
Size type for the array.
Definition static_vector.hpp:53
std::add_pointer_t< value_type > pointer
Value pointer type.
Definition static_vector.hpp:72
VECMEM_HOST_AND_DEVICE size_type size() const
Return the number of elements in the vector.
Definition static_vector.ipp:406
VECMEM_HOST_AND_DEVICE iterator erase(const_iterator pos)
Remove one element from the vector.
Definition static_vector.ipp:236
VECMEM_HOST_AND_DEVICE static_vector()
Default constructor.
Definition static_vector.ipp:18
VECMEM_HOST_AND_DEVICE iterator begin()
Return a forward iterator pointing at the beginning of the vector.
Definition static_vector.ipp:318
VECMEM_HOST_AND_DEVICE reference operator[](size_type pos)
Return a specific element of the vector (non-const)
Definition static_vector.ipp:52
VECMEM_HOST_AND_DEVICE void clear()
Clear the vector.
Definition static_vector.ipp:282
VECMEM_HOST_AND_DEVICE const_reverse_iterator crend() const
Return a constant reverse iterator pointing at the beginning of the vector.
Definition static_vector.ipp:393
VECMEM_HOST_AND_DEVICE pointer data()
Access the underlying memory array (non-const)
Definition static_vector.ipp:111
VECMEM_HOST_AND_DEVICE reference emplace_back(Args &&... args)
Add a new element at the end of the vector.
VECMEM_HOST_AND_DEVICE void push_back(const_reference value)
Add a new element at the end of the vector.
Definition static_vector.ipp:229
VECMEM_HOST_AND_DEVICE iterator emplace(const_iterator pos, Args &&... args)
Insert a new element into the vector.
VECMEM_HOST_AND_DEVICE iterator end()
Return a forward iterator pointing at the end of the vector.
Definition static_vector.ipp:338
std::add_lvalue_reference_t< std::add_const_t< value_type > > const_reference
Constant value reference type.
Definition static_vector.hpp:70
VECMEM_HOST_AND_DEVICE const_reverse_iterator crbegin() const
Return a constant reverse iterator pointing at the end of the vector.
Definition static_vector.ipp:372
VECMEM_HOST_AND_DEVICE reference back()
Return the last element of the vector (non-const)
Definition static_vector.ipp:90
VECMEM_HOST_AND_DEVICE reverse_iterator rend()
Return a reverse iterator pointing at the beginning of the vector.
Definition static_vector.ipp:379
pointer iterator
Forward iterator type.
Definition static_vector.hpp:77
VECMEM_HOST_AND_DEVICE void reserve(size_type new_cap)
Reserve additional storage for the vector.
Definition static_vector.ipp:427
VECMEM_HOST_AND_DEVICE const_iterator cbegin() const
Return a constant forward iterator pointing at the beginning of the vector.
Definition static_vector.ipp:331
const_pointer const_iterator
Constant forward iterator type.
Definition static_vector.hpp:79
VECMEM_HOST_AND_DEVICE iterator insert(const_iterator pos, const_reference value)
Insert a new element into the vector.
Definition static_vector.ipp:143
VECMEM_HOST_AND_DEVICE reverse_iterator rbegin()
Return a reverse iterator pointing at the end of the vector.
Definition static_vector.ipp:358
VECMEM_HOST_AND_DEVICE size_type max_size() const
Return the maximum (fixed) number of elements in the vector.
Definition static_vector.ipp:413
std::add_pointer_t< std::add_const_t< value_type > > const_pointer
Constant value pointer type.
Definition static_vector.hpp:74
VECMEM_HOST_AND_DEVICE reference front()
Return the first element of the vector (non-const)
Definition static_vector.ipp:68
VECMEM_HOST_AND_DEVICE void pop_back()
Remove the last element of the vector.
Definition static_vector.ipp:276
VECMEM_HOST_AND_DEVICE void memmove(void *dest, const void *src, std::size_t bytes)
Hand-written implementation of a memmove function.
Definition memmove.ipp:13
Main namespace for the vecmem classes/functions.
Definition atomic_ref.hpp:16