72 Visitor v{
this,
nullptr};
92 return c_str()[index];
96 static char dummy =
'\0';
105 static char dummy =
'\0';
114 static char dummy =
'\0';
123 if (
empty())
return '\0';
128 if (
empty())
return '\0';
133 if (index >=
mLength)
return '\0';
134 return c_str()[index];
189 fl::size len = view.
length;
235 fl::size existingLen =
mLength;
237 if (existingLen > 0 && existingData) {
246 if (existingLen > 0 && existingData) {
247 fl::memcpy(newData->data(), existingData, existingLen);
249 fl::memcpy(newData->data() + existingLen, str, n);
250 newData->data()[newLen] =
'\0';
257 if (hasHeapData() && heapData().
get().use_count() <= 1) {
259 if (!heap->hasCapacity(newLen)) {
262 const char* bufStart = heap->data();
263 fl::size grow_length =
fl::max(3, newLen * 3 / 2);
264 if (str >= bufStart && str < bufStart + mLength + 1) {
265 fl::size
offset =
static_cast<fl::size
>(str - bufStart);
266 heap->grow(grow_length);
267 str = heap->data() +
offset;
269 heap->grow(grow_length);
274 heap->data()[mLength] =
'\0';
276 }
else if (hasHeapData()) {
281 fl::memcpy(newData->data(), heap->data(), mLength);
282 fl::memcpy(newData->data() + mLength, str, n);
283 newData->data()[newLen] =
'\0';
289 if (newLen + 1 <= mInlineCapacity) {
292 fl::memcpy(inlineBufferPtr() + mLength, str, n);
295 inlineBufferPtr()[mLength] =
'\0';
301 fl::memcpy(newData->data(), inlineBufferPtr(), mLength);
302 fl::memcpy(newData->data() + mLength, str, n);
303 newData->data()[newLen] =
'\0';
312 int len =
fl::utoa32(
static_cast<fl::u32
>(n), buf, 10);
313 return write(buf, len);
319 return write(buf, len);
324#if FL_PLATFORM_HAS_LARGE_MEMORY
331 :
static_cast<fl::u32
>(val),
339#if FL_PLATFORM_HAS_LARGE_MEMORY
346 fl::i32 narrow = val > 2147483647LL ? 2147483647
347 : val < -2147483648LL ? -2147483648
348 :
static_cast<fl::i32
>(val);
349 int len =
fl::itoa(narrow, buf, 10);
351 return write(buf, len);
362 int len =
fl::itoa(
static_cast<fl::i32
>(val), buf, 10);
403 fl::size len = other.size();
404 if (other.hasHeapData()) {
412 const char* src = other.c_str();
424 fl::size actualCount = count;
428 if (actualCount > 0) {
455 if (
pos >= str.size()) {
459 fl::size actualCount = count;
460 if (actualCount ==
npos ||
pos + actualCount > str.size()) {
461 actualCount = str.size() -
pos;
463 copy(str.c_str() +
pos, actualCount);
477 for (fl::size i = 0; i < count; ++i) {
484 for (fl::size i = 0; i < count; ++i) {
487 ptr->data()[count] =
'\0';
500 if (newCapacity <=
mLength)
return;
504 if (heap.
get().
use_count() <= 1 && heap->hasCapacity(newCapacity)) {
510 newData->data()[
mLength] =
'\0';
528 if (heap->capacity() <=
mLength + 1)
return;
543 for (fl::size i = 0; i <
mLength; ++i) {
550 if (!substr)
return npos;
551 auto begin_ptr =
c_str();
552 const char* found =
fl::strstr(begin_ptr, substr);
553 if (found)
return found - begin_ptr;
559 for (fl::size i = start_pos; i <
mLength; ++i) {
567 auto begin_ptr =
c_str() + start_pos;
568 const char* found =
fl::strstr(begin_ptr, substr);
569 if (found)
return found -
c_str();
581 const char* str =
c_str();
582 for (fl::size i = searchPos + 1; i > 0; --i) {
583 if (str[i - 1] == c)
return i - 1;
589 if (!s || count == 0) {
594 fl::size maxStart =
mLength - count;
596 if (searchStart + count >
mLength) searchStart = maxStart;
597 const char* str =
c_str();
598 for (fl::size i = searchStart + 1; i > 0; --i) {
599 fl::size idx = i - 1;
600 if (idx + count >
mLength)
continue;
602 for (fl::size j = 0; j < count; ++j) {
603 if (str[idx + j] != s[j]) { match =
false;
break; }
605 if (match)
return idx;
620 if (!s || count == 0)
return npos;
622 const char* str =
c_str();
624 for (fl::size j = 0; j < count; ++j) {
625 if (str[i] == s[j])
return i;
642 if (!s || count == 0)
return npos;
645 const char* str =
c_str();
646 for (fl::size i = searchPos + 1; i > 0; --i) {
647 for (fl::size j = 0; j < count; ++j) {
648 if (str[i - 1] == s[j])
return i - 1;
666 const char* str =
c_str();
668 if (str[i] != c)
return i;
676 const char* str =
c_str();
678 bool found_in_set =
false;
679 for (fl::size j = 0; j < count; ++j) {
680 if (str[i] == s[j]) { found_in_set =
true;
break; }
682 if (!found_in_set)
return i;
699 const char* str =
c_str();
700 for (fl::size i = searchPos + 1; i > 0; --i) {
701 if (str[i - 1] != c)
return i - 1;
707 if (!s || count == 0) {
714 const char* str =
c_str();
715 for (fl::size i = searchPos + 1; i > 0; --i) {
716 bool found_in_set =
false;
717 for (fl::size j = 0; j < count; ++j) {
718 if (str[i - 1] == s[j]) { found_in_set =
true;
break; }
720 if (!found_in_set)
return i - 1;
745 if (!prefix)
return true;
747 if (prefix_len >
mLength)
return false;
752 if (!suffix)
return true;
754 if (suffix_len >
mLength)
return false;
781 if (count == 0)
return *
this;
788 fl::size newLen =
mLength + count;
795 for (fl::size i = 0; i < count; ++i) newData->data()[
pos + i] = ch;
797 newData->data()[newLen] =
'\0';
816 if (canInsertInPlace) {
818 canInsertInPlace = heap.
get().
use_count() <= 1 && heap->hasCapacity(newLen);
819 if (canInsertInPlace) {
820 char*
data = heap->data();
822 for (fl::size i = 0; i < count; ++i)
data[
pos + i] = ch;
827 if (!canInsertInPlace) {
829 const char* src =
c_str();
831 for (fl::size i = 0; i < count; ++i) newData->data()[
pos + i] = ch;
833 newData->data()[newLen] =
'\0';
841 if (!s)
return *
this;
846 return insert(
pos, str.c_str(), str.size());
850 if (pos2 >= str.size())
return *
this;
851 fl::size actualCount = count;
852 if (actualCount ==
npos || pos2 + actualCount > str.size()) {
853 actualCount = str.size() - pos2;
855 return insert(
pos, str.c_str() + pos2, actualCount);
860 if (!s || count == 0)
return *
this;
867 fl::size newLen =
mLength + count;
876 newData->data()[newLen] =
'\0';
895 if (canInsertInPlace) {
897 canInsertInPlace = heap.
get().
use_count() <= 1 && heap->hasCapacity(newLen);
898 if (canInsertInPlace) {
899 char*
data = heap->data();
906 if (!canInsertInPlace) {
908 const char* src =
c_str();
912 newData->data()[newLen] =
'\0';
924 fl::size actualCount = count;
928 if (actualCount == 0)
return *
this;
935 fl::size remainingLen =
mLength -
pos - actualCount;
936 if (remainingLen > 0) {
937 fl::memcpy(newData->data() +
pos, heap->data() +
pos + actualCount, remainingLen);
940 newData->data()[
mLength] =
'\0';
945 fl::size remainingLen =
mLength -
pos - actualCount;
946 if (remainingLen > 0) {
958 return replace(
pos, count, str.c_str(), str.size());
963 if (pos2 >= str.size())
return erase(
pos, count);
964 fl::size actualCount2 = count2;
965 if (actualCount2 ==
npos || pos2 + actualCount2 > str.size()) {
966 actualCount2 = str.size() - pos2;
968 return replace(
pos, count, str.c_str() + pos2, actualCount2);
980 fl::size actualCount = count;
984 fl::size newLen =
mLength - actualCount + count2;
992 fl::size remainingLen =
mLength -
pos - actualCount;
993 if (remainingLen > 0) {
994 fl::memcpy(newData->data() +
pos + count2, heap->data() +
pos + actualCount, remainingLen);
996 newData->data()[newLen] =
'\0';
1004 if (count2 != actualCount) {
1005 fl::size remainingLen =
mLength -
pos - actualCount;
1006 if (remainingLen > 0) {
1018 if (canReplaceInPlace) {
1020 canReplaceInPlace = heap.
get().
use_count() <= 1 && heap->hasCapacity(newLen);
1021 if (canReplaceInPlace) {
1022 char*
data = heap->data();
1023 if (count2 != actualCount) {
1024 fl::size remainingLen =
mLength -
pos - actualCount;
1025 if (remainingLen > 0) {
1034 if (!canReplaceInPlace) {
1036 const char* src =
c_str();
1039 fl::size remainingLen =
mLength -
pos - actualCount;
1040 if (remainingLen > 0) {
1041 fl::memcpy(newData->data() +
pos + count2, src +
pos + actualCount, remainingLen);
1043 newData->data()[newLen] =
'\0';
1063 fl::size actualCount = count;
1067 fl::size newLen =
mLength - actualCount + count2;
1074 for (fl::size i = 0; i < count2; ++i) newData->data()[
pos + i] = ch;
1075 fl::size remainingLen =
mLength -
pos - actualCount;
1076 if (remainingLen > 0) {
1077 fl::memcpy(newData->data() +
pos + count2, heap->data() +
pos + actualCount, remainingLen);
1079 newData->data()[newLen] =
'\0';
1087 if (count2 != actualCount) {
1088 fl::size remainingLen =
mLength -
pos - actualCount;
1089 if (remainingLen > 0) {
1101 if (canReplaceInPlace) {
1103 canReplaceInPlace = heap.
get().
use_count() <= 1 && heap->hasCapacity(newLen);
1104 if (canReplaceInPlace) {
1105 char*
data = heap->data();
1106 if (count2 != actualCount) {
1107 fl::size remainingLen =
mLength -
pos - actualCount;
1108 if (remainingLen > 0) {
1112 for (fl::size i = 0; i < count2; ++i)
data[
pos + i] = ch;
1117 if (!canReplaceInPlace) {
1119 const char* src =
c_str();
1121 for (fl::size i = 0; i < count2; ++i) newData->data()[
pos + i] = ch;
1122 fl::size remainingLen =
mLength -
pos - actualCount;
1123 if (remainingLen > 0) {
1124 fl::memcpy(newData->data() +
pos + count2, src +
pos + actualCount, remainingLen);
1126 newData->data()[newLen] =
'\0';
1139 return str.empty() ? 0 : -1;
1141 fl::size actualCount1 = count1;
1142 if (actualCount1 ==
npos || pos1 + actualCount1 >
mLength) {
1143 actualCount1 =
mLength - pos1;
1145 fl::size minLen = (actualCount1 < str.size()) ? actualCount1 : str.size();
1148 if (actualCount1 < str.size())
return -1;
1149 if (actualCount1 > str.size())
return 1;
1155 if (pos1 >
mLength || pos2 >= str.size()) {
1156 if (pos1 >
mLength && pos2 >= str.size())
return 0;
1157 if (pos1 >
mLength)
return -1;
1160 fl::size actualCount1 = count1;
1161 if (actualCount1 ==
npos || pos1 + actualCount1 >
mLength) {
1162 actualCount1 =
mLength - pos1;
1164 fl::size actualCount2 = count2;
1165 if (actualCount2 ==
npos || pos2 + actualCount2 > str.size()) {
1166 actualCount2 = str.size() - pos2;
1168 fl::size minLen = (actualCount1 < actualCount2) ? actualCount1 : actualCount2;
1171 if (actualCount1 < actualCount2)
return -1;
1172 if (actualCount1 > actualCount2)
return 1;
1177 if (!s)
return mLength > 0 ? 1 : 0;
1183 if (pos1 >=
mLength)
return 0;
1184 fl::size actualCount1 = count1;
1185 if (actualCount1 ==
npos || pos1 + actualCount1 >
mLength) {
1186 actualCount1 =
mLength - pos1;
1188 return (actualCount1 > 0) ? 1 : 0;
1190 if (pos1 >
mLength)
return (s[0] ==
'\0') ? 0 : -1;
1191 fl::size actualCount1 = count1;
1192 if (actualCount1 ==
npos || pos1 + actualCount1 >
mLength) {
1193 actualCount1 =
mLength - pos1;
1196 fl::size minLen = (actualCount1 < sLen) ? actualCount1 : sLen;
1199 if (actualCount1 < sLen)
return -1;
1200 if (actualCount1 > sLen)
return 1;
1206 if (pos1 >=
mLength)
return (count2 == 0) ? 0 : -1;
1207 fl::size actualCount1 = count1;
1208 if (actualCount1 ==
npos || pos1 + actualCount1 >
mLength) {
1209 actualCount1 =
mLength - pos1;
1211 return (actualCount1 > 0) ? 1 : ((count2 == 0) ? 0 : -1);
1213 if (pos1 >
mLength)
return (count2 == 0) ? 0 : -1;
1214 fl::size actualCount1 = count1;
1215 if (actualCount1 ==
npos || pos1 + actualCount1 >
mLength) {
1216 actualCount1 =
mLength - pos1;
1218 fl::size minLen = (actualCount1 < count2) ? actualCount1 : count2;
1221 if (actualCount1 < count2)
return -1;
1222 if (actualCount1 > count2)
return 1;
1229 if (other.isInline()) {
1238 other.mStorage.reset();
1239 other.inlineBufferPtr()[0] =
'\0';
1243 if (
this == &other)
return;
1244 if (other.isInline()) {
1253 other.mStorage.reset();
1254 other.inlineBufferPtr()[0] =
'\0';
1258 if (
this == &other)
return;
1261 bool otherInline = other.isInline();
1263 if (!thisInline && !otherInline) {
1267 }
else if (thisInline && otherInline) {
1270 bool otherFits =
mLength + 1 <= other.mInlineCapacity;
1271 if (thisFits && otherFits) {
1274 for (fl::size i = 0; i <= maxLen; ++i) {
1277 other.inlineBufferPtr()[i] = tmp;
1287 fl::size otherLen = other.mLength;
1296 other.mStorage.reset();
1297 fl::memcpy(other.inlineBufferPtr(), thisData->data(), thisLen + 1);
1299 other.mStorage = thisData;
1301 other.mLength = thisLen;
1303 }
else if (thisInline) {
1310 other.mStorage.reset();
1311 if (thisLen + 1 <= other.mInlineCapacity) {
1317 other.mLength = thisLen;
1320 other.swapWith(*
this);
1332 if (
data && len > 0) {
1339 if (!holder || holder->length() == 0)
return;
1367 write(
static_cast<fl::u16
>(val));
1381 write(
static_cast<fl::i32
>(val));
1425 return append(
static_cast<float>(val));
1429 write(str.c_str(), str.size());
1466 fl::size additional_chars = count -
mLength;
1469 for (fl::size i = 0; i < additional_chars; ++i) {
Concrete type-erased string class operating on a caller- provided buffer (or fl::span<char>).
A fixed-size array implementation similar to std::array.
int compare(const basic_string &str) const FL_NO_EXCEPT
const char * constData() const FL_NO_EXCEPT
char & at(fl::size pos) FL_NO_EXCEPT
bool isNonOwning() const FL_NO_EXCEPT
void materialize() FL_NO_EXCEPT
fl::size find_first_not_of(char c, fl::size pos=0) const FL_NO_EXCEPT
void setSharedHolder(const fl::shared_ptr< StringHolder > &holder) FL_NO_EXCEPT
void clear(bool freeMemory=false) FL_NO_EXCEPT
char * c_str_mutable() FL_NO_EXCEPT
void swapWith(basic_string &other) FL_NO_EXCEPT
bool starts_with(const char *prefix) const FL_NO_EXCEPT
bool operator<=(const basic_string &other) const FL_NO_EXCEPT
void moveFrom(basic_string &&other) FL_NO_EXCEPT
NotNullStringHolderPtr & heapData() FL_NO_EXCEPT
bool operator>=(const basic_string &other) const FL_NO_EXCEPT
char back() const FL_NO_EXCEPT
basic_string & replace(fl::size pos, fl::size count, const basic_string &str) FL_NO_EXCEPT
bool hasHeapData() const FL_NO_EXCEPT
void pop_back() FL_NO_EXCEPT
bool ends_with(const char *suffix) const FL_NO_EXCEPT
basic_string & appendHex(i32 val) FL_NO_EXCEPT
basic_string & appendOct(i32 val) FL_NO_EXCEPT
float toFloat() const FL_NO_EXCEPT
static constexpr fl::size npos
fl::size find(const char &value) const FL_NO_EXCEPT
bool operator==(const basic_string &other) const FL_NO_EXCEPT
void push_back(char c) FL_NO_EXCEPT
void reserve(fl::size newCapacity) FL_NO_EXCEPT
basic_string(char *inlineBuffer, fl::size inlineCapacity) FL_NO_EXCEPT
fl::size rfind(char c, fl::size pos=npos) const FL_NO_EXCEPT
char operator[](fl::size index) const FL_NO_EXCEPT
char * inlineBufferPtr() FL_NO_EXCEPT
char charAt(fl::size index) const FL_NO_EXCEPT
void setView(const char *data, fl::size len) FL_NO_EXCEPT
fl::size find_first_of(char c, fl::size pos=0) const FL_NO_EXCEPT
bool isInline() const FL_NO_EXCEPT
fl::variant< NotNullStringHolderPtr, ConstLiteral, ConstView > mStorage
fl::size find_last_of(char c, fl::size pos=npos) const FL_NO_EXCEPT
bool operator!=(const basic_string &other) const FL_NO_EXCEPT
void setLiteral(const char *literal) FL_NO_EXCEPT
void push_ascii(char c) FL_NO_EXCEPT
bool empty() const FL_NO_EXCEPT
const char * c_str() const FL_NO_EXCEPT
bool operator>(const basic_string &other) const FL_NO_EXCEPT
const char * data() const FL_NO_EXCEPT
char front() const FL_NO_EXCEPT
bool operator<(const basic_string &other) 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 shrink_to_fit() FL_NO_EXCEPT
fl::size find_last_not_of(char c, fl::size pos=npos) const FL_NO_EXCEPT
void moveAssign(basic_string &&other) FL_NO_EXCEPT
~basic_string() FL_DTOR_NOEXCEPT
basic_string & insert(fl::size pos, fl::size count, char ch) FL_NO_EXCEPT
void copy(const char *str) FL_NO_EXCEPT
bool contains(const char *substr) const FL_NO_EXCEPT
void assign(const char *str, fl::size len) FL_NO_EXCEPT
fl::size capacity() const FL_NO_EXCEPT
basic_string & erase(fl::size pos=0, fl::size count=npos) FL_NO_EXCEPT
basic_string & append(const char *str) FL_NO_EXCEPT
Concrete type-erased string class.
constexpr const T & get() const FL_NO_EXCEPT
long use_count() const FL_NO_EXCEPT
constexpr string_view() FL_NO_EXCEPT
#define FL_DISABLE_WARNING(warning)
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
fl::UISlider offset("Offset", 0.0f, 0.0f, 1.0f, 0.01f)
void replace(Iterator first, Iterator last, const T &old_value, const T &new_value) FL_NO_EXCEPT
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Iterator find(Iterator first, Iterator last, const T &value) FL_NO_EXCEPT
constexpr common_type_t< T, U > max(T a, U b) FL_NO_EXCEPT
void swap(array< T, N > &lhs, array< T, N > &rhs) FL_NO_EXCEPT
int utoa32(u32 value, char *sp, int radix) FL_NO_EXCEPT
Convert unsigned 32-bit integer to string buffer in given radix.
u8 u8 fract8 blur_amount FL_NO_EXCEPT
constexpr int type_rank< T >::value
fl::not_null< StringHolderPtr > NotNullStringHolderPtr
FASTLED_FORCE_INLINE int strcmp(const char *s1, const char *s2) FL_NO_EXCEPT
void clear(CRGB(&arr)[N]) FL_NO_EXCEPT
FASTLED_FORCE_INLINE void * memmove(void *dest, const void *src, size_t n) FL_NO_EXCEPT
int itoa64(i64 value, char *sp, int radix) FL_NO_EXCEPT
Convert signed 64-bit integer to string buffer in given radix.
FASTLED_FORCE_INLINE void * memcpy(void *dest, const void *src, size_t n) FL_NO_EXCEPT
int itoa(i32 value, char *sp, int radix) FL_NO_EXCEPT
Convert signed 32-bit integer to string buffer in given radix.
FASTLED_FORCE_INLINE const char * strstr(const char *haystack, const char *needle) FL_NO_EXCEPT
expected< T, E > result
Alias for expected (Rust-style naming)
int utoa64(u64 value, char *sp, int radix) FL_NO_EXCEPT
Convert unsigned 64-bit integer to string buffer in given radix.
pair_element< I, T1, T2 >::type & get(pair< T1, T2 > &p) FL_NO_EXCEPT
float parseFloat(const char *str, fl::size len) FL_NO_EXCEPT
Parse a floating point number from a character buffer.
void ftoa(float value, char *buffer, int precision) FL_NO_EXCEPT
Convert floating point number to string buffer.
To * bit_cast_ptr(void *storage) FL_NO_EXCEPT
FASTLED_FORCE_INLINE int strncmp(const char *s1, const char *s2, size_t n) FL_NO_EXCEPT
FASTLED_FORCE_INLINE size_t strlen(const char *s) FL_NO_EXCEPT
Base definition for an LED controller.