FastLED 3.9.15
Loading...
Searching...
No Matches
vector.h
Go to the documentation of this file.
1#pragma once
2
3#include <stdint.h>
4#include <stddef.h>
5
6#include "inplacenew.h"
7#include "fl/namespace.h"
8#include "fl/scoped_ptr.h"
9#include "fl/insert_result.h"
10
11namespace fl {
12
13
14// A fixed sized vector. The user is responsible for making sure that the
15// inserts do not exceed the capacity of the vector, otherwise they will fail.
16// Because of this limitation, this vector is not a drop in replacement for
17// std::vector.
18template<typename T, size_t N>
20private:
21 union {
22 char mRaw[N * sizeof(T)];
23 T mData[N];
24 };
25 size_t current_size = 0;
26
27public:
28 typedef T* iterator;
29 typedef const T* const_iterator;
30 // Constructor
31 constexpr FixedVector() : current_size(0) {}
32
33 FixedVector(const T (&values)[N]) : current_size(N) {
34 assign(values, N);
35 }
36
37 template<size_t M>
38 FixedVector(const T (&values)[M]) : current_size(M) {
39 static_assert(M <= N, "Too many elements for FixedVector");
40 assign(values, M);
41 }
42
43 // Destructor
45 clear();
46 }
47
48 // Array subscript operator
49 T& operator[](size_t index) {
50 return mData[index];
51 }
52
53 // Const array subscript operator
54 const T& operator[](size_t index) const {
55 if (index >= current_size) {
56 const T* out = nullptr;
57 return *out; // Cause a nullptr dereference
58 }
59 return mData[index];
60 }
61
62 // Get the current size of the vector
63 constexpr size_t size() const {
64 return current_size;
65 }
66
67 constexpr bool empty() const {
68 return current_size == 0;
69 }
70
71 // Get the capacity of the vector
72 constexpr size_t capacity() const {
73 return N;
74 }
75
76 // Add an element to the end of the vector
77 void push_back(const T& value) {
78 if (current_size < N) {
79 void* mem = &mData[current_size];
80 new (mem) T(value);
82 }
83 }
84
85 void assign(const T* values, size_t count) {
86 clear();
87 for (size_t i = 0; i < count; ++i) {
88 push_back(values[i]);
89 }
90 }
91
93 clear();
94 for (const_iterator it = begin; it != end; ++it) {
95 push_back(*it);
96 }
97 }
98
99 // Remove the last element from the vector
100 void pop_back() {
101 if (current_size > 0) {
102 --current_size;
103 mData[current_size].~T();
104 }
105 }
106
107 // Clear the vector
108 void clear() {
109 while (current_size > 0) {
110 pop_back();
111 }
112 }
113
114 // Erase the element at the given iterator position
116 if (pos != end()) {
117 pos->~T();
118 // shift all elements to the left
119 for (iterator p = pos; p != end() - 1; ++p) {
120 new (p) T(*(p + 1)); // Use copy constructor instead of std::move
121 (p + 1)->~T();
122 }
123 --current_size;
124 }
125 return pos;
126 }
127
128 iterator erase(const T& value) {
129 iterator it = find(value);
130 if (it != end()) {
131 erase(it);
132 }
133 return it;
134 }
135
136 iterator find(const T& value) {
137 for (iterator it = begin(); it != end(); ++it) {
138 if (*it == value) {
139 return it;
140 }
141 }
142 return end();
143 }
144
145 template<typename Predicate>
146 iterator find_if(Predicate pred) {
147 for (iterator it = begin(); it != end(); ++it) {
148 if (pred(*it)) {
149 return it;
150 }
151 }
152 return end();
153 }
154
155 bool insert(iterator pos, const T& value) {
156 if (current_size < N) {
157 // shift all elements to the right
158 for (iterator p = end(); p != pos; --p) {
159 new (p) T(*(p - 1)); // Use copy constructor instead of std::move
160 (p - 1)->~T();
161 }
162 new (pos) T(value);
163 ++current_size;
164 return true;
165 }
166 return false;
167 }
168
169 const_iterator find(const T& value) const {
170 for (const_iterator it = begin(); it != end(); ++it) {
171 if (*it == value) {
172 return it;
173 }
174 }
175 return end();
176 }
177
179 return begin();
180 }
181
183 return begin();
184 }
185
186 bool has(const T& value) const {
187 return find(value) != end();
188 }
189
190 // Access to first and last elements
191 T& front() {
192 return mData[0];
193 }
194
195 const T& front() const {
196 return mData[0];
197 }
198
199 T& back() {
200 return mData[current_size - 1];
201 }
202
203 const T& back() const {
204 return mData[current_size - 1];
205 }
206
207 // Iterator support
208 iterator begin() { return &mData[0]; }
209 const_iterator begin() const { return &mData[0]; }
210 iterator end() { return &mData[current_size]; }
211 const_iterator end() const { return &mData[current_size]; }
212};
213
214
215template<typename T>
217private:
219
220 size_t mCapacity = 0;
221 size_t mSize = 0;
222
223 public:
224 typedef T* iterator;
225 typedef const T* const_iterator;
226
230 T& operator*() { return *(it - 1); }
231 reverse_iterator& operator++() { --it; return *this; }
232 bool operator!=(const reverse_iterator& other) const { return it != other.it; }
233 };
234
235 // Constructor
236 HeapVector(size_t size = 0, const T& value = T()): mCapacity(size) {
237 mArray.reset(new T[mCapacity]);
238 for (size_t i = 0; i < size; ++i) {
239 mArray[i] = value;
240 }
241 mSize = size;
242 }
243 HeapVector(const HeapVector<T>& other): mSize(other.size()) {
244 assign(other.begin(), other.end());
245 }
246 HeapVector& operator=(const HeapVector<T>& other) { // cppcheck-suppress operatorEqVarError
247 if (this != &other) {
248 assign(other.begin(), other.end());
249 }
250 return *this;
251 }
252
253 // Destructor
255 clear();
256 }
257
258 void ensure_size(size_t n) {
259 if (n > mCapacity) {
260 size_t new_capacity = (3*mCapacity) / 2;
261 if (new_capacity < n) {
262 new_capacity = n;
263 }
264 fl::scoped_array<T> new_array(new T[new_capacity]);
265 for (size_t i = 0; i < mSize; ++i) {
266 new_array[i] = mArray[i];
267 }
268 // mArray = std::move(new_array);
269 mArray.reset();
270 mArray.reset(new_array.release());
271 mCapacity = new_capacity;
272 }
273 }
274
275 void reserve(size_t n) {
276 if (n > mCapacity) {
277 ensure_size(n);
278 }
279 }
280
281 void resize(size_t n) {
282 if (mSize == n) {
283 return;
284 }
285 HeapVector<T> temp(n);
286 for (size_t i = 0; i < n && i < mSize; ++i) {
287 temp.mArray[i] = mArray[i];
288 }
289 swap(temp);
290 }
291
292 void resize(size_t n, const T& value) {
293 mArray.reset();
294 mArray.reset(new T[n]);
295 for (size_t i = 0; i < n; ++i) {
296 mArray[i] = value;
297 }
298 mCapacity = n;
299 }
300
301 // Array access operators
302 T& operator[](size_t index) {
303 return mArray[index];
304 }
305
306 const T& operator[](size_t index) const {
307 return mArray[index];
308 }
309
310 // Capacity and size methods
311 size_t size() const {
312 return mSize;
313 }
314
315 bool empty() const {
316 return mSize == 0;
317 }
318
319 size_t capacity() const {
320 return mCapacity;
321 }
322
323 // Element addition/removal
324 void push_back(const T& value) {
325 ensure_size(mSize + 1);
326 if (mSize < mCapacity) {
327 mArray[mSize] = value;
328 ++mSize;
329 }
330 }
331
332 void pop_back() {
333 if (mSize > 0) {
334 --mSize;
335 mArray[mSize] = T();
336 }
337 }
338
339 void clear() {
340 while (mSize > 0) {
341 pop_back();
342 }
343 }
344
345 // Iterator methods
346 iterator begin() { return &mArray[0]; }
347 const_iterator begin() const { return &mArray[0]; }
348 iterator end() { return &mArray[mSize]; }
349 const_iterator end() const { return &mArray[mSize]; }
350
351
352 reverse_iterator rbegin() {
353 return reverse_iterator(end());
354 }
355
356 reverse_iterator rend() {
357 return reverse_iterator(begin());
358 }
359
360 // Element access
361 T& front() {
362 return mArray[0];
363 }
364
365 const T& front() const {
366 return mArray[0];
367 }
368
369 T& back() {
370 return mArray[mSize - 1];
371 }
372
373 const T& back() const {
374 return mArray[mSize - 1];
375 }
376
377 // Search and modification
378 iterator find(const T& value) {
379 for (iterator it = begin(); it != end(); ++it) {
380 if (*it == value) {
381 return it;
382 }
383 }
384 return end();
385 }
386
387 const_iterator find(const T& value) const {
388 for (const_iterator it = begin(); it != end(); ++it) {
389 if (*it == value) {
390 return it;
391 }
392 }
393 return end();
394 }
395
396 template<typename Predicate>
397 iterator find_if(Predicate pred) {
398 for (iterator it = begin(); it != end(); ++it) {
399 if (pred(*it)) {
400 return it;
401 }
402 }
403 return end();
404 }
405
406 bool has(const T& value) const {
407 return find(value) != end();
408 }
409
410 bool erase(iterator pos, T* out_value = nullptr) {
411 if (pos == end() || empty()) {
412 return false;
413 }
414 if (out_value) {
415 *out_value = *pos;
416 }
417 while (pos != end() - 1) {
418 *pos = *(pos + 1);
419 ++pos;
420 }
421 back() = T();
422 --mSize;
423 return true;
424 }
425
426 void erase(const T& value) {
427 iterator it = find(value);
428 if (it != end()) {
429 erase(it);
430 }
431 }
432
433 void swap(HeapVector<T>& other) {
434 T* temp = mArray.release();
435 size_t temp_size = mSize;
436 size_t temp_capacity = mCapacity;
437 T* temp2 = other.mArray.release();
438 mArray.reset(temp2);
439 other.mArray.reset(temp);
440 mSize = other.mSize;
441 mCapacity = other.mCapacity;
442 other.mSize = temp_size;
443 other.mCapacity = temp_capacity;
444 }
445
446 void swap(iterator a, iterator b) {
447 T temp = *a;
448 *a = *b;
449 *b = temp;
450 }
451
452 bool full() const {
453 return mSize >= mCapacity;
454 }
455
456 bool insert(iterator pos, const T& value) {
457 // TODO: Introduce mMaxSize (and move it from SortedVector to here)
458 // push back and swap into place.
459 size_t target_idx = pos - begin();
460 push_back(value);
461 auto last = end() - 1;
462 for (size_t curr_idx = last - begin(); curr_idx > target_idx; --curr_idx) {
463 auto first = begin() + curr_idx - 1;
464 auto second = begin() + curr_idx;
465 swap(first, second);
466 }
467 return true;
468 }
469
470 void assign(const T* values, size_t count) {
471 assign(values, values + count);
472 }
473
475 clear();
476 reserve(end - begin);
477 for (const_iterator it = begin; it != end; ++it) {
478 push_back(*it);
479 }
480 }
481
482 T* data() {
483 return mArray.get();
484 }
485
486 const T* data() const {
487 return mArray.get();
488 }
489
490 bool operator==(const HeapVector<T>& other) const {
491 if (size() != other.size()) {
492 return false;
493 }
494 for (size_t i = 0; i < size(); ++i) {
495 if (mArray[i] != other.mArray[i]) {
496 return false;
497 }
498 }
499 return true;
500 }
501
502 bool operator!=(const HeapVector<T>& other) const {
503 return !(*this == other);
504 }
505};
506
507
508template <typename T, typename LessThan>
510private:
512 LessThan mLess;
513 size_t mMaxSize = size_t(-1);
514
515public:
518
519 SortedHeapVector(LessThan less=LessThan()): mLess(less) {}
520
521 void setMaxSize(size_t n) {
522 if (mMaxSize == n) {
523 return;
524 }
525 mMaxSize = n;
526 const bool needs_adjustment = mArray.size() > mMaxSize;
527 if (needs_adjustment) {
528 mArray.resize(n);
529 } else {
530 mArray.reserve(n);
531 }
532 }
533
535 mArray.clear();
536 }
537
538 void reserve(size_t n) {
539 mArray.reserve(n);
540 }
541
542 // Insert while maintaining sort order
543 bool insert(const T& value, InsertResult* result = nullptr) {
544 // Find insertion point using binary search
545 iterator pos = lower_bound(value);
546 if (pos != end() && !mLess(value, *pos) && !mLess(*pos, value)) {
547 // return false; // Already inserted.
548 if (result) {
549 // *result = kExists;
550 *result = InsertResult::kExists;
551 }
552
553 return false;
554 }
555 if (mArray.size() >= mMaxSize) {
556 // return false; // Too full
557 if (result) {
558 *result = InsertResult::kMaxSize;
559 }
560 return false;
561 }
562 mArray.insert(pos, value);
563 if (result) {
564 *result = kInserted;
565 }
566
567 return true;
568 }
569
570 // Find the first position where we should insert value to maintain sort order
571 iterator lower_bound(const T& value) {
572 iterator first = mArray.begin();
573 iterator last = mArray.end();
574
575 while (first != last) {
576 iterator mid = first + (last - first) / 2;
577
578 if (mLess(*mid, value)) {
579 first = mid + 1;
580 } else {
581 last = mid;
582 }
583 }
584 return first;
585 }
586
587 const_iterator lower_bound(const T& value) const {
588 return const_cast<SortedHeapVector*>(this)->lower_bound(value);
589 }
590
591 // Lookup operations
592 iterator find(const T& value) {
593 iterator pos = lower_bound(value);
594 if (pos != end() && !mLess(value, *pos) && !mLess(*pos, value)) {
595 return pos;
596 }
597 return end();
598 }
599
600 void swap(SortedHeapVector& other) {
601 mArray.swap(other.mArray);
602 }
603
604 const_iterator find(const T& value) const {
605 return const_cast<SortedHeapVector*>(this)->find(value);
606 }
607
608 bool has(const T& value) const {
609 return find(value) != end();
610 }
611
612 // Removal operations
613 bool erase(const T& value) {
614 iterator it = find(value);
615 if (it != end()) {
616 return mArray.erase(it);
617 }
618 return false;
619 }
620
622 return mArray.erase(pos);
623 }
624
625 // Basic container operations
626 size_t size() const { return mArray.size(); }
627 bool empty() const { return mArray.empty(); }
628 size_t capacity() const { return mArray.capacity(); }
629 void clear() { mArray.clear(); }
630 bool full() const {
631 if (mArray.size() >= mMaxSize) {
632 return true;
633 }
634 return mArray.full();
635 }
636
637 // Element access
638 T& operator[](size_t index) { return mArray[index]; }
639 const T& operator[](size_t index) const { return mArray[index]; }
640
641 T& front() { return mArray.front(); }
642 const T& front() const { return mArray.front(); }
643
644 T& back() { return mArray.back(); }
645 const T& back() const { return mArray.back(); }
646
647 // Iterators
648 iterator begin() { return mArray.begin(); }
649 const_iterator begin() const { return mArray.begin(); }
650 iterator end() { return mArray.end(); }
651 const_iterator end() const { return mArray.end(); }
652
653 // Raw data access
654 T* data() { return mArray.data(); }
655 const T* data() const { return mArray.data(); }
656};
657
658
659} // namespace fl
uint8_t pos
Definition Blur.ino:11
const PairKV * const_iterator
Definition vector.h:29
constexpr size_t size() const
Definition vector.h:63
iterator find_if(Predicate pred)
Definition vector.h:146
iterator data()
Definition vector.h:178
constexpr FixedVector()
Definition vector.h:31
void clear()
Definition vector.h:108
const T & back() const
Definition vector.h:203
void assign(const_iterator begin, const_iterator end)
Definition vector.h:92
T & operator[](size_t index)
Definition vector.h:49
const_iterator find(const T &value) const
Definition vector.h:169
bool has(const T &value) const
Definition vector.h:186
void pop_back()
Definition vector.h:100
iterator erase(const T &value)
Definition vector.h:128
const_iterator data() const
Definition vector.h:182
constexpr bool empty() const
Definition vector.h:67
const T & operator[](size_t index) const
Definition vector.h:54
const_iterator end() const
Definition vector.h:211
const_iterator begin() const
Definition vector.h:209
const T & front() const
Definition vector.h:195
FixedVector(const T(&values)[M])
Definition vector.h:38
void push_back(const T &value)
Definition vector.h:77
FixedVector(const T(&values)[N])
Definition vector.h:33
iterator erase(iterator pos)
Definition vector.h:115
constexpr size_t capacity() const
Definition vector.h:72
bool insert(iterator pos, const T &value)
Definition vector.h:155
iterator find(const T &value)
Definition vector.h:136
void assign(const T *values, size_t count)
Definition vector.h:85
size_t capacity() const
Definition vector.h:319
bool operator==(const HeapVector< T > &other) const
Definition vector.h:490
const_iterator end() const
Definition vector.h:349
const_iterator find(const T &value) const
Definition vector.h:387
const T & back() const
Definition vector.h:373
void reserve(size_t n)
Definition vector.h:275
const_iterator begin() const
Definition vector.h:347
void resize(size_t n, const T &value)
Definition vector.h:292
void assign(const T *values, size_t count)
Definition vector.h:470
size_t size() const
Definition vector.h:311
bool insert(iterator pos, const T &value)
Definition vector.h:456
HeapVector(size_t size=0, const T &value=T())
Definition vector.h:236
T & operator[](size_t index)
Definition vector.h:302
void clear()
Definition vector.h:339
void pop_back()
Definition vector.h:332
void push_back(const T &value)
Definition vector.h:324
HeapVector & operator=(const HeapVector< T > &other)
Definition vector.h:246
bool empty() const
Definition vector.h:315
bool erase(iterator pos, T *out_value=nullptr)
Definition vector.h:410
const T * data() const
Definition vector.h:486
const T & operator[](size_t index) const
Definition vector.h:306
iterator find_if(Predicate pred)
Definition vector.h:397
iterator end()
Definition vector.h:348
void ensure_size(size_t n)
Definition vector.h:258
void swap(iterator a, iterator b)
Definition vector.h:446
bool operator!=(const HeapVector< T > &other) const
Definition vector.h:502
const T & front() const
Definition vector.h:365
void resize(size_t n)
Definition vector.h:281
reverse_iterator rend()
Definition vector.h:356
iterator begin()
Definition vector.h:346
const DrawItem * const_iterator
Definition vector.h:225
iterator find(const T &value)
Definition vector.h:378
void swap(HeapVector< T > &other)
Definition vector.h:433
void erase(const T &value)
Definition vector.h:426
reverse_iterator rbegin()
Definition vector.h:352
fl::scoped_array< DrawItem > mArray
Definition vector.h:218
bool full() const
Definition vector.h:452
bool has(const T &value) const
Definition vector.h:406
HeapVector(const HeapVector< T > &other)
Definition vector.h:243
void assign(const_iterator begin, const_iterator end)
Definition vector.h:474
T & front()
Definition vector.h:361
size_t mMaxSize
Definition vector.h:513
SortedHeapVector(LessThan less=LessThan())
Definition vector.h:519
bool erase(iterator pos)
Definition vector.h:621
iterator lower_bound(const T &value)
Definition vector.h:571
HeapVector< Pair > mArray
Definition vector.h:511
bool erase(const T &value)
Definition vector.h:613
size_t size() const
Definition vector.h:626
iterator end()
Definition vector.h:650
bool has(const T &value) const
Definition vector.h:608
const T * data() const
Definition vector.h:655
iterator begin()
Definition vector.h:648
void swap(SortedHeapVector &other)
Definition vector.h:600
bool full() const
Definition vector.h:630
const T & back() const
Definition vector.h:645
const_iterator end() const
Definition vector.h:651
void setMaxSize(size_t n)
Definition vector.h:521
size_t capacity() const
Definition vector.h:628
HeapVector< Pair >::const_iterator const_iterator
Definition vector.h:517
const_iterator begin() const
Definition vector.h:649
PairLess mLess
Definition vector.h:512
T & operator[](size_t index)
Definition vector.h:638
bool insert(const T &value, InsertResult *result=nullptr)
Definition vector.h:543
const_iterator lower_bound(const T &value) const
Definition vector.h:587
HeapVector< Pair >::iterator iterator
Definition vector.h:516
bool empty() const
Definition vector.h:627
void reserve(size_t n)
Definition vector.h:538
const T & front() const
Definition vector.h:642
const T & operator[](size_t index) const
Definition vector.h:639
const_iterator find(const T &value) const
Definition vector.h:604
iterator find(const T &value)
Definition vector.h:592
Implements the FastLED namespace macros.
InsertResult
@ kMaxSize
@ kExists
@ kInserted
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
static FASTLED_NAMESPACE_BEGIN uint8_t const p[]
Definition noise.cpp:56
bool operator!=(const reverse_iterator &other) const
Definition vector.h:232
reverse_iterator & operator++()
Definition vector.h:231