FastLED 3.10.6
Loading...
Searching...
No Matches
string.h
Go to the documentation of this file.
1#pragma once
2
4// fl::string has inlined memory and copy on write semantics.
5
6
8#include "fl/stl/int.h"
9#include "fl/stl/cstring.h"
11#include "platforms/is_platform.h" // IWYU pragma: keep (for FL_IS_WASM)
12
13#ifdef FL_IS_WASM
14// IWYU pragma: begin_keep
15#include <string>
16// IWYU pragma: end_keep
17#endif
18
19#include "fl/stl/shared_ptr.h"
20#include "fl/stl/optional.h"
21#include "fl/stl/type_traits.h"
22#include "fl/stl/span.h"
23#include "fl/stl/vector.h" // IWYU pragma: keep
24#include "fl/stl/variant.h"
25#include "fl/stl/string_view.h"
27#include "fl/stl/bitset.h"
28#include "fl/stl/move.h"
29#include "fl/stl/noexcept.h"
30
31// Inline (SSO) buffer size for fl::string, in bytes. Every fl::string
32// object carries this buffer, and — because fl::json_value's variant is
33// sized to its largest alternative (fl::string) — EVERY json value (even
34// an int or bool) pays for it too. At the old default of 64 a single
35// JSON-RPC response with a few hundred values consumed tens of KB and
36// exhausted the heap on classic ESP32 once WiFi was up (FastLED#3588).
37// 32 still keeps typical keys/short values inline while roughly halving
38// the per-string and per-json-value footprint. Override by defining
39// FASTLED_STR_INLINED_SIZE before including FastLED.
40#ifndef FASTLED_STR_INLINED_SIZE
41#define FASTLED_STR_INLINED_SIZE 32
42#endif
43
44
45// Test for Arduino String class (must be after includes)
46#if defined(String_class_h)
47#define FL_STRING_NEEDS_ARDUINO_CONVERSION 1
48#else
49#define FL_STRING_NEEDS_ARDUINO_CONVERSION 0
50#endif
51
52#if FL_STRING_NEEDS_ARDUINO_CONVERSION
53class String; // Arduino String class
54#endif
55
56namespace fl {
57
58class Tile2x2_u8_wrap;
59class JsonUiInternal;
60
61struct json_value;
62class json;
63
64template <typename T> struct rect;
65template <typename T> struct vec2;
66template <typename T> struct vec3;
67
68template <typename T> class WeakPtr;
69
70template <typename Key, typename Hash, typename KeyEqual> class HashSet;
71
72class XYMap;
73
74namespace audio { namespace fft { class Bins; } }
75struct CRGB;
76
77} // namespace fl
78
79namespace fl {
80
81// `fl::string_n<N>` is the templated inline-buffer storage policy
82// over `fl::basic_string`. It co-locates a `char[N]` buffer with
83// the basic_string state and passes that buffer to the base ctor.
84// Every operation (write, append, find, replace, …) lives in
85// `basic_string` and is compiled exactly once; per-N instantiations
86// of `string_n<N>` are thin constructor stubs that only differ in
87// the literal `N` they hand to the base. The compiler / linker
88// folds identical instantiations under COMDAT, and the non-shared
89// bytes are tiny (each ctor is `: basic_string(mBuf, N) {}` plus a
90// short body that calls `copy()`/`setLiteral()`/etc.).
91//
92// Convenience aliases:
93// - `fl::string_small` — 32-byte inline buffer (constrained MCUs)
94// - `fl::string` — `FASTLED_STR_INLINED_SIZE` (default 64)
95// - `fl::string_large` — 256-byte inline buffer (text-heavy paths)
96//
97// All three are layout-compatible; copy/move between sizes works
98// because the underlying `basic_string` storage policy is uniform.
99//
100// See `agents/docs/string-architecture.md`.
101template <fl::size N>
102class string_n : public basic_string {
103 protected:
104 char mInlineBuffer[N] = {0};
105
106 public:
107 // Default + content-population constructors. All delegate to
108 // `basic_string(mInlineBuffer, N)` and then call the
109 // non-template population helpers on the base.
111
113 if (str) copy(str);
114 }
115
116 string_n(const char* str, fl::size len) FL_NO_EXCEPT : basic_string(mInlineBuffer, N) {
117 copy(str, len);
118 }
119
120 string_n(fl::size len, char c) FL_NO_EXCEPT : basic_string(mInlineBuffer, N) {
121 resize(len, c);
122 }
123
125 copy(static_cast<const basic_string&>(other));
126 }
127
128 template <fl::size M>
130 copy(static_cast<const basic_string&>(other));
131 }
132
136
138 copy(other);
139 }
140
142 if (!sv.empty()) {
143 copy(sv.data(), sv.size());
144 }
145 }
146
148 copy(s.data(), s.size());
149 }
150
152 copy(s.data(), s.size());
153 }
154
158
159 template <typename InputIt>
160 string_n(InputIt first, InputIt last) FL_NO_EXCEPT : basic_string(mInlineBuffer, N) {
161 assign(first, last);
162 }
163
164 template <int M>
165 string_n(const char (&str)[M]) FL_NO_EXCEPT : basic_string(mInlineBuffer, N) {
166 copy(str, M - 1);
167 }
168
170 copy(static_cast<const basic_string&>(other));
171 return *this;
172 }
173
174 template <fl::size M>
176 copy(static_cast<const basic_string&>(other));
177 return *this;
178 }
179
181 moveAssign(fl::move(other));
182 return *this;
183 }
184};
185
186// Convenience aliases. `fl::string` is the default; `string_small`
187// trades inline capacity for object size on constrained targets,
188// `string_large` trades the other way for text-heavy paths.
191
192// `fl::string` extends `string_n<FASTLED_STR_INLINED_SIZE>` with
193// the composite-type formatter overloads (CRGB, vec2, span,
194// vector, optional, …), the `substring()` / `trim()` family
195// (returning `string` so callers chain naturally), and the static
196// factory + comparison methods. The trampoline pattern is:
197//
198// fl::string -> fl::string_n<N> -> fl::basic_string
199//
200// where only `basic_string` carries the real bytes; the upper
201// layers are thin wrappers that get folded out by the optimizer.
202class string : public string_n<FASTLED_STR_INLINED_SIZE> {
203 public:
204 static constexpr fl::size npos = static_cast<fl::size>(-1);
205
206 using basic_string::copy;
211
212 // ======= STATIC FACTORY METHODS =======
213 static string from_literal(const char* literal) FL_NO_EXCEPT;
214 static string from_view(const char* data, fl::size len) FL_NO_EXCEPT;
215 static string from_view(const string_view& sv) FL_NO_EXCEPT;
216 static string interned(const char* str, fl::size len) FL_NO_EXCEPT;
217 static string interned(const char* str) FL_NO_EXCEPT;
218 static string interned(const string_view& sv) FL_NO_EXCEPT;
219 static string copy_no_view(const string& str) FL_NO_EXCEPT;
220 static int strcmp(const string& a, const string& b) FL_NO_EXCEPT;
221
222 // ======= CONSTRUCTORS =======
223 // All non-template ctors delegate to string_n<N>'s ctors —
224 // defined in string.cpp.hpp as one-line forwarders for header
225 // hygiene. Template ctors stay inline (they're parameterised
226 // on caller types and can't be split out).
228 string(const char* str) FL_NO_EXCEPT;
229 string(const char* str, fl::size len) FL_NO_EXCEPT;
230 string(fl::size len, char c) FL_NO_EXCEPT;
231 string(const string& other) FL_NO_EXCEPT;
232 string(string&& other) FL_NO_EXCEPT;
233 string(const basic_string& other) FL_NO_EXCEPT;
234 string(const string_view& sv) FL_NO_EXCEPT;
235 string(const fl::span<const char>& s) FL_NO_EXCEPT;
236 string(const fl::span<char>& s) FL_NO_EXCEPT;
237 string(const fl::shared_ptr<StringHolder>& holder) FL_NO_EXCEPT;
238 template <typename InputIt>
239 string(InputIt first, InputIt last) FL_NO_EXCEPT
240 : string_n<FASTLED_STR_INLINED_SIZE>(first, last) {}
241 template <int N>
242 string(const char (&str)[N]) FL_NO_EXCEPT
244
245 // ======= ASSIGNMENT =======
246 string& operator=(const string& other) FL_NO_EXCEPT;
247 string& operator=(string&& other) FL_NO_EXCEPT;
248 string& operator=(const char* str) FL_NO_EXCEPT;
249 template <int N> string& operator=(const char (&str)[N]) FL_NO_EXCEPT {
250 assign(str, N - 1);
251 return *this;
252 }
253
254 string& assign(string_view sv) FL_NO_EXCEPT;
255
256 // ======= SUBSTRING (returns string, so must live here) =======
257 string substring(fl::size start, fl::size end) const FL_NO_EXCEPT;
258 string substr(fl::size start, fl::size length) const FL_NO_EXCEPT;
259 string substr(fl::size start) const FL_NO_EXCEPT;
260 string trim() const FL_NO_EXCEPT;
261
262#ifdef FL_IS_WASM
263 string(const std::string& str); // okay std namespace; defined in string.cpp.hpp
264 string& operator=(const std::string& str) FL_NO_EXCEPT; // okay std namespace
265 string& append(const std::string& str); // okay std namespace
266#endif
267
268#if FL_STRING_NEEDS_ARDUINO_CONVERSION
269 string(const ::String& str);
270 string& operator=(const ::String& str) FL_NO_EXCEPT;
271 string& append(const ::String& str);
272#endif
273
274
275
276 bool operator>(const string &other) const FL_NO_EXCEPT;
277 bool operator>=(const string &other) const FL_NO_EXCEPT;
278 bool operator<(const string &other) const FL_NO_EXCEPT;
279 bool operator<=(const string &other) const FL_NO_EXCEPT;
280 bool operator==(const string &other) const FL_NO_EXCEPT;
281 bool operator!=(const string &other) const FL_NO_EXCEPT;
282
283 // ======= CONCATENATION =======
284 string& operator+=(const string& other) FL_NO_EXCEPT;
285
286 template <typename T> string& operator+=(const T& val) FL_NO_EXCEPT {
287 append(val);
288 return *this;
289 }
290
291 // ======= APPEND OVERLOADS =======
292 template <fl::u32 N>
294 bs.to_string(this);
295 return *this;
296 }
297
298 string& append(const bitset_dynamic& bs) FL_NO_EXCEPT {
299 bs.to_string(this);
300 return *this;
301 }
302
303 template <fl::u32 N>
305 bs.to_string(this);
306 return *this;
307 }
308
309 template <typename T> string& append(const fl::span<T>& slice) FL_NO_EXCEPT {
310 append("[");
311 for (fl::size i = 0; i < slice.size(); ++i) {
312 if (i > 0) append(", ");
313 append(slice[i]);
314 }
315 append("]");
316 return *this;
317 }
318
319 template <typename T> string& append(const fl::vector<T>& vec) FL_NO_EXCEPT {
320 fl::span<const T> slice(vec.data(), vec.size());
321 append(slice);
322 return *this;
323 }
324
325 template <typename T, fl::size N>
327 fl::span<const T> slice(vec.data(), vec.size());
328 append(slice);
329 return *this;
330 }
331
332 template <typename T>
333 string& append(const rect<T>& rect) FL_NO_EXCEPT {
334 append("rect(");
335 append(rect.mMin.x);
336 append(",");
337 append(rect.mMin.y);
338 append(",");
339 append(rect.mMax.x);
340 append(",");
341 append(rect.mMax.y);
342 append(")");
343 return *this;
344 }
345
346 template <typename T>
347 string& append(const vec2<T>& pt) FL_NO_EXCEPT {
348 append("vec2(");
349 append(pt.x);
350 append(",");
351 append(pt.y);
352 append(")");
353 return *this;
354 }
355
356 template <typename T>
357 string& append(const vec3<T>& pt) FL_NO_EXCEPT {
358 append("vec3(");
359 append(pt.x);
360 append(",");
361 append(pt.y);
362 append(",");
363 append(pt.z);
364 append(")");
365 return *this;
366 }
367
368 template <typename T>
369 string& append(const WeakPtr<T>& val) FL_NO_EXCEPT {
370 write("WeakPtr(use_count=", 18);
371 write(static_cast<fl::u32>(val.use_count()));
372 write(")", 1);
373 return *this;
374 }
375
376 template <typename T>
378 if (!val) {
379 write("nullptr", 7);
380 } else {
381 write("shared_ptr(use_count=", 21);
382 write(static_cast<fl::u32>(val.use_count()));
383 write(")", 1);
384 }
385 return *this;
386 }
387
388 string& append(const JsonUiInternal& val) FL_NO_EXCEPT;
389 string& append(const json_value& val) FL_NO_EXCEPT;
390 string& append(const json& val) FL_NO_EXCEPT;
391
392 template <typename T, fl::size N>
394 append("[");
395 for (fl::size i = 0; i < vec.size(); ++i) {
396 if (i > 0) append(",");
397 append(vec[i]);
398 }
399 append("]");
400 return *this;
401 }
402
403 string& append(const CRGB& c) FL_NO_EXCEPT;
404 string& appendCRGB(const CRGB& c) FL_NO_EXCEPT;
405
406 // Any type with a to_float() method (e.g., fixed_point types)
407 template <typename T>
408 typename fl::enable_if<
409 fl::is_same<decltype(static_cast<const T*>(nullptr)->to_float()), float>::value
411 string&>::type
412 append(const T& val) FL_NO_EXCEPT {
413 basic_string::append(val.to_float());
414 return *this;
415 }
416
417 string& append(const audio::fft::Bins& str) FL_NO_EXCEPT;
418 string& append(const XYMap& map) FL_NO_EXCEPT;
419 string& append(const Tile2x2_u8_wrap& tile) FL_NO_EXCEPT;
420
421 template <typename Key, typename Hash, typename KeyEqual>
423 append("{");
424 fl::size i = 0;
425 for (auto it = set.begin(); it != set.end(); ++it) {
426 if (i > 0) append(",");
427 append(*it);
428 ++i;
429 }
430 append("}");
431 return *this;
432 }
433
434 template <typename T>
435 string& append(const fl::optional<T>& opt) FL_NO_EXCEPT {
436 if (opt.has_value()) {
437 append(opt.value());
438 } else {
439 write("nullopt", 7);
440 }
441 return *this;
442 }
443
444 void swap(string& other) FL_NO_EXCEPT;
445
446 string& intern() FL_NO_EXCEPT;
447
448 private:
449 enum {
451 };
452
454};
455
456// ======= FREE FUNCTIONS =======
457
458template<typename T>
459inline string to_string(T value) FL_NO_EXCEPT {
460 string result;
461 result.append(value);
462 return result;
463}
464
465inline string to_string(float value, int precision) FL_NO_EXCEPT {
466 string result;
467 result.append(value, precision);
468 return result;
469}
470
471inline string operator+(const char* lhs, const string& rhs) FL_NO_EXCEPT {
472 string result(lhs);
473 result += rhs;
474 return result;
475}
476
477inline string operator+(const string& lhs, const char* rhs) FL_NO_EXCEPT {
478 string result(lhs);
479 result += rhs;
480 return result;
481}
482
483inline string operator+(const string& lhs, const string& rhs) FL_NO_EXCEPT {
484 string result(lhs);
485 result += rhs;
486 return result;
487}
488
489template<typename T>
490inline typename fl::enable_if<!fl::is_arithmetic<T>::value, string>::type
491operator+(const char* lhs, const T& rhs) FL_NO_EXCEPT {
492 string result(lhs);
493 result += rhs;
494 return result;
495}
496
497template<typename T>
498inline typename fl::enable_if<!fl::is_arithmetic<T>::value, string>::type
499operator+(const T& lhs, const char* rhs) FL_NO_EXCEPT {
500 string result;
501 result.append(lhs);
502 result += rhs;
503 return result;
504}
505
506template<typename T>
507inline string operator+(const string& lhs, const T& rhs) FL_NO_EXCEPT {
508 string result(lhs);
509 result += rhs;
510 return result;
511}
512
513template<typename T>
514inline string operator+(const T& lhs, const string& rhs) FL_NO_EXCEPT {
515 string result;
516 result.append(lhs);
517 result += rhs;
518 return result;
519}
520
522// Template Implementation for charconv.h
524
525template<typename T>
526fl::string to_hex(T value, bool uppercase, bool pad_to_width) FL_NO_EXCEPT {
528 bool is_negative = false;
529 u64 unsigned_value;
530 if (static_cast<i64>(value) < 0 && sizeof(T) <= 8) {
531 is_negative = true;
532 unsigned_value = static_cast<u64>(-static_cast<i64>(value));
533 } else {
534 unsigned_value = static_cast<u64>(value);
535 }
536 return detail::hex(unsigned_value, width, is_negative, uppercase, pad_to_width);
537}
538
539// Comparator that orders strings by size first, then by content.
540// Not lexicographic — use only for associative containers (flat_map, etc.)
541// where you need fast lookup and don't care about alphabetical order.
543 bool operator()(const string &a, const string &b) const FL_NO_EXCEPT {
544 fl::size al = a.size(), bl = b.size();
545 if (al != bl) {
546 return al < bl;
547 }
548 return fl::memcmp(a.c_str(), b.c_str(), al) < 0;
549 }
550};
551
552} // namespace fl
AudioAnalyzeFFT1024 fft
Concrete type-erased string class operating on a caller- provided buffer (or fl::span<char>).
void setSharedHolder(const fl::shared_ptr< StringHolder > &holder) FL_NO_EXCEPT
void moveFrom(basic_string &&other) FL_NO_EXCEPT
basic_string & appendHex(i32 val) FL_NO_EXCEPT
basic_string & appendOct(i32 val) FL_NO_EXCEPT
basic_string(char *inlineBuffer, fl::size inlineCapacity) FL_NO_EXCEPT
const char * data() const FL_NO_EXCEPT
fl::size write(const fl::u8 *data, fl::size n) FL_NO_EXCEPT
void resize(fl::size count) FL_NO_EXCEPT
void moveAssign(basic_string &&other) FL_NO_EXCEPT
void copy(const char *str) FL_NO_EXCEPT
void assign(const char *str, fl::size len) FL_NO_EXCEPT
fl::size size() const FL_NO_EXCEPT
basic_string & append(const char *str) FL_NO_EXCEPT
Concrete type-erased string class.
A dynamic bitset implementation that can be resized at runtime.
const_iterator begin() const
Definition set.h:415
const_iterator end() const
Definition set.h:416
Definition set.h:367
string_n & operator=(string_n &&other) FL_NO_EXCEPT
Definition string.h:180
string_n(InputIt first, InputIt last) FL_NO_EXCEPT
Definition string.h:160
string_n & operator=(const string_n< M > &other) FL_NO_EXCEPT
Definition string.h:175
string_n(const fl::shared_ptr< StringHolder > &holder) FL_NO_EXCEPT
Definition string.h:155
string_n & operator=(const string_n &other) FL_NO_EXCEPT
Definition string.h:169
string_n() FL_NO_EXCEPT
Definition string.h:110
string_n(const basic_string &other) FL_NO_EXCEPT
Definition string.h:137
string_n(const char *str, fl::size len) FL_NO_EXCEPT
Definition string.h:116
string_n(const string_n< M > &other) FL_NO_EXCEPT
Definition string.h:129
string_n(const char *str) FL_NO_EXCEPT
Definition string.h:112
string_n(const fl::span< char > &s) FL_NO_EXCEPT
Definition string.h:151
string_n(const fl::span< const char > &s) FL_NO_EXCEPT
Definition string.h:147
string_n(const string_view &sv) FL_NO_EXCEPT
Definition string.h:141
string_n(string_n &&other) FL_NO_EXCEPT
Definition string.h:133
string_n(const string_n &other) FL_NO_EXCEPT
Definition string.h:124
string_n(const char(&str)[M]) FL_NO_EXCEPT
Definition string.h:165
string_n(fl::size len, char c) FL_NO_EXCEPT
Definition string.h:120
char mInlineBuffer[N]
Definition string.h:104
static int strcmp(const string &a, const string &b) FL_NO_EXCEPT
bool operator!=(const string &other) const FL_NO_EXCEPT
string & operator+=(const string &other) FL_NO_EXCEPT
string & operator+=(const T &val) FL_NO_EXCEPT
Definition string.h:286
string & append(const fl::vector< T > &vec) FL_NO_EXCEPT
Definition string.h:319
bool operator>(const string &other) const FL_NO_EXCEPT
string & operator=(const string &other) FL_NO_EXCEPT
static string from_view(const char *data, fl::size len) FL_NO_EXCEPT
bool operator==(const string &other) const FL_NO_EXCEPT
string & operator=(const char(&str)[N]) FL_NO_EXCEPT
Definition string.h:249
string & intern() FL_NO_EXCEPT
string & append(const fl::span< T > &slice) FL_NO_EXCEPT
Definition string.h:309
string & append(const fl::optional< T > &opt) FL_NO_EXCEPT
Definition string.h:435
string & appendCRGB(const CRGB &c) FL_NO_EXCEPT
string(const char(&str)[N]) FL_NO_EXCEPT
Definition string.h:242
string & append(const vec2< T > &pt) FL_NO_EXCEPT
Definition string.h:347
void swap(string &other) FL_NO_EXCEPT
string & append(const bitset_dynamic &bs) FL_NO_EXCEPT
Definition string.h:298
bool operator>=(const string &other) const FL_NO_EXCEPT
string & append(const HashSet< Key, Hash, KeyEqual > &set) FL_NO_EXCEPT
Definition string.h:422
string & assign(string_view sv) FL_NO_EXCEPT
string & append(const vec3< T > &pt) FL_NO_EXCEPT
Definition string.h:357
string substring(fl::size start, fl::size end) const FL_NO_EXCEPT
@ kStrInlineSize
Definition string.h:450
fl::enable_if< fl::is_same< decltype(static_cast< constT * >(nullptr) ->to_float()), float >::value &&!fl::is_floating_point< T >::value, string & >::type append(const T &val) FL_NO_EXCEPT
Definition string.h:412
string & append(const bitset_fixed< N > &bs) FL_NO_EXCEPT
Definition string.h:293
string & append(const WeakPtr< T > &val) FL_NO_EXCEPT
Definition string.h:369
static string interned(const char *str, fl::size len) FL_NO_EXCEPT
string & append(const fl::FixedVector< T, N > &vec) FL_NO_EXCEPT
Definition string.h:393
string substr(fl::size start, fl::size length) const FL_NO_EXCEPT
string & append(const rect< T > &rect) FL_NO_EXCEPT
Definition string.h:333
static void compileTimeAssertions() FL_NO_EXCEPT
string & append(const bitset_inlined< N > &bs) FL_NO_EXCEPT
Definition string.h:304
static constexpr fl::size npos
Definition string.h:204
string() FL_NO_EXCEPT
bool operator<(const string &other) const FL_NO_EXCEPT
string & append(const fl::InlinedVector< T, N > &vec) FL_NO_EXCEPT
Definition string.h:326
static string copy_no_view(const string &str) FL_NO_EXCEPT
string & append(const fl::shared_ptr< T > &val) FL_NO_EXCEPT
Definition string.h:377
string trim() const FL_NO_EXCEPT
static string from_literal(const char *literal) FL_NO_EXCEPT
bool operator<=(const string &other) const FL_NO_EXCEPT
fl::UISlider length("Length", 1.0f, 0.0f, 1.0f, 0.01f)
fl::CRGB CRGB
Definition crgb.h:25
fl::string hex(u64 value, HexIntWidth width, bool is_negative, bool uppercase, bool pad_to_width)
Internal hex conversion function (implementation in charconv.cpp)
constexpr HexIntWidth get_hex_int_width() FL_NO_EXCEPT
Compile-time integer width determination (default - triggers error)
Definition charconv.h:60
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:28
constexpr int type_rank< T >::value
VectorN< T, INLINED_SIZE > InlinedVector
Definition span.h:25
MapRedBlackTree< Key, T, Compare, fl::allocator_slab< char > > map
Definition map.h:283
FASTLED_FORCE_INLINE CRGB operator+(const CRGB &p1, const CRGB &p2) FL_NO_EXCEPT
Add one CRGB to another, saturating at 0xFF for each channel.
Definition crgb.hpp:182
Optional< T > optional
Definition optional.h:16
fl::string to_hex(T value, bool uppercase=false, bool pad_to_width=false) FL_NO_EXCEPT
Convert an integer value to hexadecimal string representation.
Definition string.h:526
u8 width
Definition blur.h:186
int memcmp(const void *s1, const void *s2, size_t n) FL_NO_EXCEPT
string_n< 256 > string_large
Definition string.h:190
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
string_n< 32 > string_small
Definition string.h:189
InputGamut g FL_NO_EXCEPT
Definition rgbw.h:121
constexpr T * end(T(&array)[N]) FL_NO_EXCEPT
string to_string(T value) FL_NO_EXCEPT
Definition string.h:459
Base definition for an LED controller.
Definition crgb.hpp:179
fl::u64 u64
Definition stdint.h:220
fl::i64 i64
Definition stdint.h:221
#define FASTLED_STR_INLINED_SIZE
std::string compatible string class.
Definition string.h:41
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Definition crgb.h:38
bool operator()(const string &a, const string &b) const FL_NO_EXCEPT
Definition string.h:543
vec2< T > mMax
Definition geometry.h:438
vec2< T > mMin
Definition geometry.h:437