FastLED 3.9.3
Loading...
Searching...
No Matches
fixed_vector.h
1#pragma once
2
3#include <stdint.h>
4#include <stddef.h>
5
6#include "inplacenew.h"
7#include "namespace.h"
8
9FASTLED_NAMESPACE_BEGIN
10
11
12// A fixed sized vector. The user is responsible for making sure that the
13// inserts do not exceed the capacity of the vector, otherwise they will fail.
14// Because of this limitation, this vector is not a drop in replacement for
15// std::vector.
16template<typename T, size_t N>
18private:
19 union {
20 char raw[N * sizeof(T)];
21 T data[N];
22 };
23 size_t current_size = 0;
24
25public:
26 typedef T* iterator;
27 typedef const T* const_iterator;
28 // Constructor
29 constexpr FixedVector() : current_size(0) {}
30
31 // Destructor
32 ~FixedVector() {
33 clear();
34 }
35
36 // Array subscript operator
37 T& operator[](size_t index) {
38 return data[index];
39 }
40
41 // Const array subscript operator
42 const T& operator[](size_t index) const {
43 return data[index];
44 }
45
46 // Get the current size of the vector
47 constexpr size_t size() const {
48 return current_size;
49 }
50
51 constexpr bool empty() const {
52 return current_size == 0;
53 }
54
55 // Get the capacity of the vector
56 constexpr size_t capacity() const {
57 return N;
58 }
59
60 // Add an element to the end of the vector
61 void push_back(const T& value) {
62 if (current_size < N) {
63 void* mem = &data[current_size];
64 new (mem) T(value);
65 ++current_size;
66 }
67 }
68
69 // Remove the last element from the vector
70 void pop_back() {
71 if (current_size > 0) {
72 --current_size;
73 data[current_size].~T();
74 }
75 }
76
77 // Clear the vector
78 void clear() {
79 while (current_size > 0) {
80 pop_back();
81 }
82 }
83
84 // Erase the element at the given iterator position
85 iterator erase(iterator pos) {
86 if (pos != end()) {
87 pos->~T();
88 // shift all elements to the left
89 for (iterator p = pos; p != end() - 1; ++p) {
90 new (p) T(*(p + 1)); // Use copy constructor instead of std::move
91 (p + 1)->~T();
92 }
93 --current_size;
94 }
95 return pos;
96 }
97
98 iterator erase(const T& value) {
99 iterator it = find(value);
100 if (it != end()) {
101 erase(it);
102 }
103 return it;
104 }
105
106 iterator find(const T& value) {
107 for (iterator it = begin(); it != end(); ++it) {
108 if (*it == value) {
109 return it;
110 }
111 }
112 return end();
113 }
114
115 template<typename Predicate>
116 iterator find_if(Predicate pred) {
117 for (iterator it = begin(); it != end(); ++it) {
118 if (pred(*it)) {
119 return it;
120 }
121 }
122 return end();
123 }
124
125 bool insert(iterator pos, const T& value) {
126 if (current_size < N) {
127 // shift all elements to the right
128 for (iterator p = end(); p != pos; --p) {
129 new (p) T(*(p - 1)); // Use copy constructor instead of std::move
130 (p - 1)->~T();
131 }
132 new (pos) T(value);
133 ++current_size;
134 return true;
135 }
136 return false;
137 }
138
139 const_iterator find(const T& value) const {
140 for (const_iterator it = begin(); it != end(); ++it) {
141 if (*it == value) {
142 return it;
143 }
144 }
145 return end();
146 }
147
148 bool has(const T& value) const {
149 return find(value) != end();
150 }
151
152 // Access to first and last elements
153 T& front() {
154 return data[0];
155 }
156
157 const T& front() const {
158 return data[0];
159 }
160
161 T& back() {
162 return data[current_size - 1];
163 }
164
165 const T& back() const {
166 return data[current_size - 1];
167 }
168
169 // Iterator support
170 iterator begin() { return &data[0]; }
171 const_iterator begin() const { return &data[0]; }
172 iterator end() { return &data[current_size]; }
173 const_iterator end() const { return &data[current_size]; }
174};
175
176FASTLED_NAMESPACE_END