FastLED 3.9.15
Loading...
Searching...
No Matches
slice.h
Go to the documentation of this file.
1#pragma once
2
3#include <stddef.h>
4#include <stdint.h>
5
6#include "fl/clamp.h"
7#include "fl/geometry.h"
8
9namespace fl {
10
11template <typename T, size_t INLINED_SIZE> class FixedVector;
12
13template <typename T> class HeapVector;
14
15template <typename T, size_t INLINED_SIZE> class InlinedVector;
16
17// Slice<int> is equivalent to int* with a length. It is used to pass around
18// arrays of integers with a length, without needing to pass around a separate
19// length parameter.
20// It works just like an array of objects, but it also knows its length.
21template <typename T> class Slice {
22 public:
23 Slice() : mData(nullptr), mSize(0) {}
24 Slice(T *data, size_t size) : mData(data), mSize(size) {}
25
28
29 template <size_t INLINED_SIZE>
32
33 template <size_t INLINED_SIZE>
36
37 template <typename U>
40
41 template <typename U, size_t INLINED_SIZE>
44
45 template <typename U, size_t INLINED_SIZE>
48
49 template <size_t ARRAYSIZE>
50 Slice(T (&array)[ARRAYSIZE]) : mData(array), mSize(ARRAYSIZE) {}
51
52 template <typename U, size_t ARRAYSIZE>
53 Slice(T (&array)[ARRAYSIZE]) : mData(array), mSize(ARRAYSIZE) {}
54
55 template <typename Iterator>
56 Slice(Iterator begin, Iterator end)
57 : mData(&(*begin)), mSize(end - begin) {}
58
59 Slice(const Slice &other) : mData(other.mData), mSize(other.mSize) {}
60
61 Slice &operator=(const Slice &other) {
62 mData = other.mData;
63 mSize = other.mSize;
64 return *this;
65 }
66
67 // Automatic promotion to const Slice<const T>
68 operator Slice<const T>() const { return Slice<const T>(mData, mSize); }
69
70 T &operator[](size_t index) {
71 // No bounds checking in embedded environment
72 return mData[index];
73 }
74
75 const T &operator[](size_t index) const {
76 // No bounds checking in embedded environment
77 return mData[index];
78 }
79
80 T *begin() const { return mData; }
81
82 T *end() const { return mData + mSize; }
83
84 size_t length() const { return mSize; }
85
86 const T *data() const { return mData; }
87
88 T *data() { return mData; }
89
90 size_t size() const { return mSize; }
91
92 Slice<T> slice(size_t start, size_t end) const {
93 // No bounds checking in embedded environment
94 return Slice<T>(mData + start, end - start);
95 }
96
97 Slice<T> slice(size_t start) const {
98 // No bounds checking in embedded environment
99 return Slice<T>(mData + start, mSize - start);
100 }
101
102 // Find the first occurrence of a value in the slice
103 // Returns the index of the first occurrence if found, or size_t(-1) if not
104 // found
105 size_t find(const T &value) const {
106 for (size_t i = 0; i < mSize; ++i) {
107 if (mData[i] == value) {
108 return i;
109 }
110 }
111 return size_t(-1);
112 }
113
114 bool pop_front() {
115 if (mSize == 0) {
116 return false;
117 }
118 ++mData;
119 --mSize;
120 return true;
121 }
122
123 bool pop_back() {
124 if (mSize == 0) {
125 return false;
126 }
127 --mSize;
128 return true;
129 }
130
131 T &front() { return *mData; }
132
133 const T &front() const { return *mData; }
134
135 T &back() { return *(mData + mSize - 1); }
136
137 const T &back() const { return *(mData + mSize - 1); }
138
139 bool empty() { return mSize == 0; }
140
141 private:
143 size_t mSize;
144};
145template <typename T> class MatrixSlice {
146 public:
147 // represents a window into a matrix
148 // bottom-left and top-right corners are passed as plain ints
149 MatrixSlice() = default;
150 MatrixSlice(T *data, int32_t dataWidth, int32_t dataHeight,
151 int32_t bottomLeftX, int32_t bottomLeftY, int32_t topRightX,
152 int32_t topRightY)
153 : mData(data), mDataWidth(dataWidth), mDataHeight(dataHeight),
154 mBottomLeft{bottomLeftX, bottomLeftY},
155 mTopRight{topRightX, topRightY} {}
156
157 MatrixSlice(const MatrixSlice &other) = default;
158 MatrixSlice &operator=(const MatrixSlice &other) = default;
159
160 // outputs a vec2 but takes x,y as inputs
161 vec2<int32_t> getParentCoord(int32_t x_local, int32_t y_local) const {
162 return {x_local + mBottomLeft.x, y_local + mBottomLeft.y};
163 }
164
165 vec2<int32_t> getLocalCoord(int32_t x_world, int32_t y_world) const {
166 // clamp to [mBottomLeft, mTopRight]
167 int32_t x_clamped = fl::clamp(x_world, mBottomLeft.x, mTopRight.x);
168 int32_t y_clamped = fl::clamp(y_world, mBottomLeft.y, mTopRight.y);
169 // convert to local
170 return {x_clamped - mBottomLeft.x, y_clamped - mBottomLeft.y};
171 }
172
173 // element access via (x,y)
174 T &operator()(int32_t x, int32_t y) { return at(x, y); }
175
176 // Add access like slice[y][x]
177 T *operator[](int32_t row) {
178 int32_t parentRow = row + mBottomLeft.y;
179 return mData + parentRow * mDataWidth + mBottomLeft.x;
180 }
181
182 T &at(int32_t x, int32_t y) {
183 auto parent = getParentCoord(x, y);
184 return mData[parent.x + parent.y * mDataWidth];
185 }
186
187 const T &at(int32_t x, int32_t y) const {
188 auto parent = getParentCoord(x, y);
189 return mData[parent.x + parent.y * mDataWidth];
190 }
191
192 private:
193 T *mData = nullptr;
194 int32_t mDataWidth = 0;
195 int32_t mDataHeight = 0;
198};
199
200} // namespace fl
int y
Definition Audio.ino:72
int x
Definition Audio.ino:71
T * operator[](int32_t row)
Definition slice.h:177
int32_t mDataHeight
Definition slice.h:195
MatrixSlice(T *data, int32_t dataWidth, int32_t dataHeight, int32_t bottomLeftX, int32_t bottomLeftY, int32_t topRightX, int32_t topRightY)
Definition slice.h:150
vec2< int32_t > getLocalCoord(int32_t x_world, int32_t y_world) const
Definition slice.h:165
T & operator()(int32_t x, int32_t y)
Definition slice.h:174
const T & at(int32_t x, int32_t y) const
Definition slice.h:187
MatrixSlice & operator=(const MatrixSlice &other)=default
MatrixSlice()=default
vec2< int32_t > mBottomLeft
Definition slice.h:196
T & at(int32_t x, int32_t y)
Definition slice.h:182
MatrixSlice(const MatrixSlice &other)=default
int32_t mDataWidth
Definition slice.h:194
vec2< int32_t > getParentCoord(int32_t x_local, int32_t y_local) const
Definition slice.h:161
vec2< int32_t > mTopRight
Definition slice.h:197
Slice(const Slice &other)
Definition slice.h:59
Slice(Iterator begin, Iterator end)
Definition slice.h:56
const T & back() const
Definition slice.h:137
T * data()
Definition slice.h:88
Slice(const InlinedVector< T, INLINED_SIZE > &vector)
Definition slice.h:34
Slice< T > slice(size_t start) const
Definition slice.h:97
bool pop_back()
Definition slice.h:123
Slice< T > slice(size_t start, size_t end) const
Definition slice.h:92
Slice(T(&array)[ARRAYSIZE])
Definition slice.h:53
T * begin() const
Definition slice.h:80
T & operator[](size_t index)
Definition slice.h:70
Slice(const HeapVector< T > &vector)
Definition slice.h:26
T * mData
Definition slice.h:142
size_t length() const
Definition slice.h:84
bool pop_front()
Definition slice.h:114
Slice(const FixedVector< U, INLINED_SIZE > &vector)
Definition slice.h:42
Slice(const FixedVector< T, INLINED_SIZE > &vector)
Definition slice.h:30
T & back()
Definition slice.h:135
Slice()
Definition slice.h:23
const T & front() const
Definition slice.h:133
bool empty()
Definition slice.h:139
const T * data() const
Definition slice.h:86
Slice(const HeapVector< U > &vector)
Definition slice.h:38
Slice & operator=(const Slice &other)
Definition slice.h:61
const T & operator[](size_t index) const
Definition slice.h:75
size_t size() const
Definition slice.h:90
T * end() const
Definition slice.h:82
T & front()
Definition slice.h:131
Slice(T(&array)[ARRAYSIZE])
Definition slice.h:50
size_t find(const T &value) const
Definition slice.h:105
Slice(T *data, size_t size)
Definition slice.h:24
Slice(const InlinedVector< U, INLINED_SIZE > &vector)
Definition slice.h:46
size_t mSize
Definition slice.h:143
A fixed-size array implementation similar to std::array.
Definition array.h:19
FASTLED_FORCE_INLINE T clamp(T value, T min, T max)
Definition clamp.h:10
HeapVector< T > vector
Definition vector.h:1028
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16