FastLED 3.9.15
Loading...
Searching...
No Matches
slice.h
Go to the documentation of this file.
1#pragma once
2
3
4#include "fl/stdint.h"
5#include "fl/clamp.h"
6#include "fl/geometry.h"
7#include "fl/allocator.h"
8
9namespace fl {
10
11template <typename T, fl::size INLINED_SIZE> class FixedVector;
12
13template <typename T, typename Allocator> class HeapVector;
14
15template <typename T, fl::size INLINED_SIZE> class InlinedVector;
16
17template <typename T, fl::size N> class array;
18
19// Slice<int> is equivalent to int* with a length. It is used to pass around
20// arrays of integers with a length, without needing to pass around a separate
21// length parameter.
22// It works just like an array of objects, but it also knows its length.
23template <typename T> class Slice {
24 public:
25 Slice() : mData(nullptr), mSize(0) {}
26 Slice(T *data, fl::size size) : mData(data), mSize(size) {}
27
28 // ======= CONTAINER CONSTRUCTORS =======
29 // Simple constructors that work for all cases
30 template<typename Alloc>
33
34 template <fl::size INLINED_SIZE>
37
38 template <fl::size INLINED_SIZE>
41
42 // Additional constructors for const conversion (U -> const U)
43 template<typename U, typename Alloc>
46
47 template<typename U, fl::size INLINED_SIZE>
50
51 template<typename U, fl::size INLINED_SIZE>
54
55 // ======= NON-CONST CONTAINER CONVERSIONS =======
56 // Non-const versions for mutable spans
57 template<typename Alloc>
60
61 template <fl::size INLINED_SIZE>
64
65 template <fl::size INLINED_SIZE>
68
69
70
71 // ======= FL::ARRAY CONVERSIONS =======
72 // fl::array<T> -> Slice<T>
73 template <fl::size N>
74 Slice(const array<T, N> &arr)
75 : mData(arr.data()), mSize(N) {}
76
77 template <fl::size N>
79 : mData(arr.data()), mSize(N) {}
80
81 // fl::array<U> -> Slice<T> (for type conversions like U -> const U)
82 template <typename U, fl::size N>
83 Slice(const array<U, N> &arr)
84 : mData(arr.data()), mSize(N) {}
85
86 template <typename U, fl::size N>
88 : mData(arr.data()), mSize(N) {}
89
90 // ======= C-STYLE ARRAY CONVERSIONS =======
91 // T[] -> Slice<T>
92 template <fl::size ARRAYSIZE>
93 Slice(T (&array)[ARRAYSIZE])
94 : mData(array), mSize(ARRAYSIZE) {}
95
96 // U[] -> Slice<T> (for type conversions like U -> const U)
97 template <typename U, fl::size ARRAYSIZE>
98 Slice(U (&array)[ARRAYSIZE])
99 : mData(array), mSize(ARRAYSIZE) {}
100
101 // const U[] -> Slice<T> (for const arrays)
102 template <typename U, fl::size ARRAYSIZE>
103 Slice(const U (&array)[ARRAYSIZE])
104 : mData(array), mSize(ARRAYSIZE) {}
105
106 // ======= ITERATOR CONVERSIONS =======
107 template <typename Iterator>
108 Slice(Iterator begin, Iterator end)
109 : mData(&(*begin)), mSize(end - begin) {}
110
111 Slice(const Slice &other) : mData(other.mData), mSize(other.mSize) {}
112
113 Slice &operator=(const Slice &other) {
114 mData = other.mData;
115 mSize = other.mSize;
116 return *this;
117 }
118
119 // Automatic promotion to const Slice<const T>
120 operator Slice<const T>() const { return Slice<const T>(mData, mSize); }
121
122 T &operator[](fl::size index) {
123 // No bounds checking in embedded environment
124 return mData[index];
125 }
126
127 const T &operator[](fl::size index) const {
128 // No bounds checking in embedded environment
129 return mData[index];
130 }
131
132 T *begin() const { return mData; }
133
134 T *end() const { return mData + mSize; }
135
136 fl::size length() const { return mSize; }
137
138 const T *data() const { return mData; }
139
140 T *data() { return mData; }
141
142 fl::size size() const { return mSize; }
143
144 Slice<T> slice(fl::size start, fl::size end) const {
145 // No bounds checking in embedded environment
146 return Slice<T>(mData + start, end - start);
147 }
148
149 Slice<T> slice(fl::size start) const {
150 // No bounds checking in embedded environment
151 return Slice<T>(mData + start, mSize - start);
152 }
153
154 // Find the first occurrence of a value in the slice
155 // Returns the index of the first occurrence if found, or fl::size(-1) if not
156 // found
157 fl::size find(const T &value) const {
158 for (fl::size i = 0; i < mSize; ++i) {
159 if (mData[i] == value) {
160 return i;
161 }
162 }
163 return fl::size(-1);
164 }
165
166 bool pop_front() {
167 if (mSize == 0) {
168 return false;
169 }
170 ++mData;
171 --mSize;
172 return true;
173 }
174
175 bool pop_back() {
176 if (mSize == 0) {
177 return false;
178 }
179 --mSize;
180 return true;
181 }
182
183 T &front() { return *mData; }
184
185 const T &front() const { return *mData; }
186
187 T &back() { return *(mData + mSize - 1); }
188
189 const T &back() const { return *(mData + mSize - 1); }
190
191 bool empty() { return mSize == 0; }
192
193 private:
195 fl::size mSize;
196};
197template <typename T> class MatrixSlice {
198 public:
199 // represents a window into a matrix
200 // bottom-left and top-right corners are passed as plain ints
201 MatrixSlice() = default;
202 MatrixSlice(T *data, i32 dataWidth, i32 dataHeight,
203 i32 bottomLeftX, i32 bottomLeftY, i32 topRightX,
204 i32 topRightY)
205 : mData(data), mDataWidth(dataWidth), mDataHeight(dataHeight),
206 mBottomLeft{bottomLeftX, bottomLeftY},
207 mTopRight{topRightX, topRightY} {}
208
209 MatrixSlice(const MatrixSlice &other) = default;
210 MatrixSlice &operator=(const MatrixSlice &other) = default;
211
212 // outputs a vec2 but takes x,y as inputs
213 vec2<i32> getParentCoord(i32 x_local, i32 y_local) const {
214 return {x_local + mBottomLeft.x, y_local + mBottomLeft.y};
215 }
216
217 vec2<i32> getLocalCoord(i32 x_world, i32 y_world) const {
218 // clamp to [mBottomLeft, mTopRight]
219 i32 x_clamped = fl::clamp(x_world, mBottomLeft.x, mTopRight.x);
220 i32 y_clamped = fl::clamp(y_world, mBottomLeft.y, mTopRight.y);
221 // convert to local
222 return {x_clamped - mBottomLeft.x, y_clamped - mBottomLeft.y};
223 }
224
225 // element access via (x,y)
226 T &operator()(i32 x, i32 y) { return at(x, y); }
227
228 // Add access like slice[y][x]
229 T *operator[](i32 row) {
230 i32 parentRow = row + mBottomLeft.y;
231 return mData + parentRow * mDataWidth + mBottomLeft.x;
232 }
233
234 T &at(i32 x, i32 y) {
235 auto parent = getParentCoord(x, y);
236 return mData[parent.x + parent.y * mDataWidth];
237 }
238
239 const T &at(i32 x, i32 y) const {
240 auto parent = getParentCoord(x, y);
241 return mData[parent.x + parent.y * mDataWidth];
242 }
243
244 private:
245 T *mData = nullptr;
246 i32 mDataWidth = 0;
247 i32 mDataHeight = 0;
250};
251
252} // namespace fl
int y
Definition simple.h:93
int x
Definition simple.h:92
vec2< i32 > getLocalCoord(i32 x_world, i32 y_world) const
Definition slice.h:217
const T & at(i32 x, i32 y) const
Definition slice.h:239
T & at(i32 x, i32 y)
Definition slice.h:234
MatrixSlice & operator=(const MatrixSlice &other)=default
MatrixSlice()=default
MatrixSlice(const MatrixSlice &other)=default
vec2< i32 > mBottomLeft
Definition slice.h:248
vec2< i32 > mTopRight
Definition slice.h:249
i32 mDataHeight
Definition slice.h:247
vec2< i32 > getParentCoord(i32 x_local, i32 y_local) const
Definition slice.h:213
T * operator[](i32 row)
Definition slice.h:229
T & operator()(i32 x, i32 y)
Definition slice.h:226
MatrixSlice(T *data, i32 dataWidth, i32 dataHeight, i32 bottomLeftX, i32 bottomLeftY, i32 topRightX, i32 topRightY)
Definition slice.h:202
Slice(const Slice &other)
Definition slice.h:111
Slice(Iterator begin, Iterator end)
Definition slice.h:108
const T & back() const
Definition slice.h:189
Slice(const HeapVector< U, Alloc > &vector)
Definition slice.h:44
T * data()
Definition slice.h:140
Slice(const InlinedVector< T, INLINED_SIZE > &vector)
Definition slice.h:39
fl::size length() const
Definition slice.h:136
bool pop_back()
Definition slice.h:175
Slice(const array< U, N > &arr)
Definition slice.h:83
Slice(FixedVector< T, INLINED_SIZE > &vector)
Definition slice.h:62
Slice(HeapVector< T, Alloc > &vector)
Definition slice.h:58
Slice(array< T, N > &arr)
Definition slice.h:78
fl::size find(const T &value) const
Definition slice.h:157
const T & operator[](fl::size index) const
Definition slice.h:127
T * begin() const
Definition slice.h:132
Slice(InlinedVector< T, INLINED_SIZE > &vector)
Definition slice.h:66
Slice(const HeapVector< T, Alloc > &vector)
Definition slice.h:31
Slice(U(&array)[ARRAYSIZE])
Definition slice.h:98
Slice(array< U, N > &arr)
Definition slice.h:87
T * mData
Definition slice.h:194
bool pop_front()
Definition slice.h:166
Slice< T > slice(fl::size start, fl::size end) const
Definition slice.h:144
Slice(const FixedVector< U, INLINED_SIZE > &vector)
Definition slice.h:48
T & operator[](fl::size index)
Definition slice.h:122
Slice(const FixedVector< T, INLINED_SIZE > &vector)
Definition slice.h:35
T & back()
Definition slice.h:187
Slice(const U(&array)[ARRAYSIZE])
Definition slice.h:103
Slice()
Definition slice.h:25
const T & front() const
Definition slice.h:185
bool empty()
Definition slice.h:191
const T * data() const
Definition slice.h:138
Slice & operator=(const Slice &other)
Definition slice.h:113
fl::size size() const
Definition slice.h:142
fl::size mSize
Definition slice.h:195
Slice(const array< T, N > &arr)
Definition slice.h:74
T * end() const
Definition slice.h:134
Slice< T > slice(fl::size start) const
Definition slice.h:149
T & front()
Definition slice.h:183
Slice(T(&array)[ARRAYSIZE])
Definition slice.h:93
Slice(T *data, fl::size size)
Definition slice.h:26
Slice(const InlinedVector< U, INLINED_SIZE > &vector)
Definition slice.h:52
A fixed-size array implementation similar to std::array.
Definition array.h:27
FASTLED_FORCE_INLINE T clamp(T value, T min, T max)
Definition clamp.h:10
HeapVector< T, Allocator > vector
Definition vector.h:1214
IMPORTANT!
Definition crgb.h:20