FastLED 3.9.15
Loading...
Searching...
No Matches
strstream.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/stl/stdint.h" // IWYU pragma: keep
4#include "fl/stl/string.h"
5#include "crgb.h" // IWYU pragma: keep
6#include "fl/stl/ios.h" // IWYU pragma: keep
8#include "fl/stl/noexcept.h"
9
10
11namespace fl {
12
13class Tile2x2_u8;
14class Tile2x2_u8_wrap; // Forward declaration to support operator<< overload
15template <typename T> struct vec2; // Forward declaration from fl/math/geometry.h
16template <typename T> struct rect; // Forward declaration from fl/math/geometry.h
17template <typename T> class vector; // Forward declaration from fl/vector.h // IWYU pragma: keep
18template <typename T> class Optional; // Forward declaration from fl/stl/optional.h
19template <typename Key, typename Hash, typename KeyEqual> class unordered_set; // Forward declaration from fl/stl/unordered_set.h
20template <typename Key, typename T, typename Hash, typename KeyEqual, int INLINED_COUNT> class unordered_map; // Forward declaration from fl/stl/unordered_map.h
21template <typename Key, typename Value, fl::size N> class unsorted_map_fixed; // Forward declaration from fl/stl/map.h
22template <typename Key, typename Value, typename Less> class flat_map; // Forward declaration from fl/stl/flat_map.h
23template <typename T, fl::size Extent> class span; // Forward declaration from fl/stl/span.h (no default arg to avoid redefinition) // IWYU pragma: keep
24template <typename T1, typename T2> struct pair; // Forward declaration from fl/stl/pair.h
25namespace audio { namespace fft { class Bins; } } // Forward declaration
26template <fl::u32 N> class bitset_fixed;
27class bitset_dynamic; // IWYU pragma: keep
28template <fl::u32 N> class bitset_inlined; // IWYU pragma: keep
29
30// Note: int_cast_detail::cast_target is now defined in fl/stl/type_traits.h
31// and shared between sstream and basic_string for consistent integer formatting
32
33
34class sstream {
35 public:
36 sstream() FL_NOEXCEPT = default;
37 sstream(const string &str) FL_NOEXCEPT : mStr(str) {}
38
39 void setTreatCharAsInt(bool treatCharAsInt) FL_NOEXCEPT {
40 mTreatCharAsInt = treatCharAsInt;
41 }
42
43 string str() const FL_NOEXCEPT { return mStr; }
44 const char *c_str() const FL_NOEXCEPT { return mStr.c_str(); }
45
47 mStr.append(rgb);
48 return *this;
49 }
51 mStr.append(strStream.str());
52 return *this;
53 }
54
55 sstream &operator<<(const Tile2x2_u8 &subpixel) FL_NOEXCEPT;
56 sstream &operator<<(const Tile2x2_u8_wrap &tile) FL_NOEXCEPT; // New overload for wrapped tiles
57
58 // Bins support - implemented in strstream.cpp.hpp
60
61 // vec2<T> support - format as (x,y)
62 template<typename T>
64 mStr.append("(");
65 mStr.append(v.x);
66 mStr.append(",");
67 mStr.append(v.y);
68 mStr.append(")");
69 return *this;
70 }
71
72 // rect<T> support - format as rect((minx,miny), (maxx,maxy))
73 template<typename T>
75 mStr.append("rect(");
76 (*this) << r.mMin;
77 mStr.append(", ");
78 (*this) << r.mMax;
79 mStr.append(")");
80 return *this;
81 }
82
83 // Optional<T> support - format as nullopt or optional(value)
84 template<typename T>
86 if (!opt.has_value()) {
87 mStr.append("nullopt");
88 } else {
89 mStr.append("optional(");
90 (*this) << *opt;
91 mStr.append(")");
92 }
93 return *this;
94 }
95
96 // vector<T> support - format as [item1, item2, ...]
97 template<typename T>
99 mStr.append("[");
100 for (fl::size i = 0; i < vec.size(); ++i) {
101 if (i > 0) {
102 mStr.append(", ");
103 }
104 (*this) << vec[i];
105 }
106 mStr.append("]");
107 return *this;
108 }
109
110 // unordered_set<Key, Hash, KeyEqual> support - format as {item1, item2, ...}
111 template<typename Key, typename Hash, typename KeyEqual>
113 mStr.append("{");
114 bool first = true;
115 for (auto it = set.begin(); it != set.end(); ++it) {
116 if (!first) {
117 mStr.append(", ");
118 }
119 first = false;
120 (*this) << *it;
121 }
122 mStr.append("}");
123 return *this;
124 }
125
126 // unordered_map<Key, T, Hash, KeyEqual, INLINED_COUNT> support - format as {key1: value1, key2: value2, ...}
127 template<typename Key, typename T, typename Hash, typename KeyEqual, int INLINED_COUNT>
129 mStr.append("{");
130 bool first = true;
131 for (auto it = map.begin(); it != map.end(); ++it) {
132 if (!first) {
133 mStr.append(", ");
134 }
135 first = false;
136 (*this) << it->first;
137 mStr.append(": ");
138 (*this) << it->second;
139 }
140 mStr.append("}");
141 return *this;
142 }
143
144 // unsorted_map_fixed<Key, Value, N> support - format as {key1: value1, key2: value2, ...}
145 template<typename Key, typename Value, fl::size N>
147 mStr.append("{");
148 bool first = true;
149 for (auto it = map.begin(); it != map.end(); ++it) {
150 if (!first) {
151 mStr.append(", ");
152 }
153 first = false;
154 (*this) << it->first;
155 mStr.append(": ");
156 (*this) << it->second;
157 }
158 mStr.append("}");
159 return *this;
160 }
161
162 // flat_map<Key, Value, Less> support - format as {key1: value1, key2: value2, ...}
163 template<typename Key, typename Value, typename Less>
165 mStr.append("{");
166 bool first = true;
167 for (auto it = map.begin(); it != map.end(); ++it) {
168 if (!first) {
169 mStr.append(", ");
170 }
171 first = false;
172 (*this) << it->first;
173 mStr.append(": ");
174 (*this) << it->second;
175 }
176 mStr.append("}");
177 return *this;
178 }
179
180 // span<T, Extent> support - format as span[item1, item2, ...]
181 // Uses same format as vector but with "span" prefix for clarity
182 template<typename T, fl::size Extent>
184 mStr.append("span[");
185 for (fl::size i = 0; i < s.size(); ++i) {
186 if (i > 0) {
187 mStr.append(", ");
188 }
189 (*this) << s[i];
190 }
191 mStr.append("]");
192 return *this;
193 }
194
195 // pair<T1, T2> support - format as (first, second)
196 template<typename T1, typename T2>
198 mStr.append("(");
199 (*this) << p.first;
200 mStr.append(", ");
201 (*this) << p.second;
202 mStr.append(")");
203 return *this;
204 }
205
206 sstream &operator=(const fl::u16 &n) FL_NOEXCEPT {
207 mStr.clear();
208 (*this) << n;
209 return *this;
210 }
211
213 mStr.clear();
214 (*this) << n;
215 return *this;
216 }
217
219 mStr.clear();
220 (*this) << c;
221 return *this;
222 }
223
224 // << operator section
226 mStr.append(str);
227 return *this;
228 }
229
231 if (str) {
232 mStr.append(str);
233 }
234 return *this;
235 }
236
237 sstream &operator<<(const float &f) FL_NOEXCEPT {
238 // multiply by 100 and round to get 2 decimal places
239 mStr.append(f);
240 return *this;
241 }
242
243 sstream &operator<<(const double &f) FL_NOEXCEPT {
244 // multiply by 100 and round to get 2 decimal places
245 mStr.append(f);
246 return *this;
247 }
248
249 // Non-template overload for char - takes by value to ensure priority over templates
251 if (mTreatCharAsInt) {
252 mStr.append(fl::i32(c));
253 } else {
254 mStr.append(c);
255 }
256 return *this;
257 }
258
259 // Non-template overloads for signed/unsigned char to avoid template resolution issues
261 using target_t = typename int_cast_detail::cast_target<signed char>::type;
262 appendFormatted(static_cast<target_t>(n));
263 return *this;
264 }
265
266 sstream &operator<<(unsigned char n) FL_NOEXCEPT {
268 appendFormatted(static_cast<target_t>(n));
269 return *this;
270 }
271
272 template<fl::size N>
273 sstream &operator<<(const char (&str)[N]) FL_NOEXCEPT {
274 mStr.append(str);
275 return *this;
276 }
277
278 template<fl::u32 N>
280 // mStr.append(bs);
281 bs.to_string(&mStr);
282 return *this;
283 }
284
286 bs.to_string(&mStr);
287 return *this;
288 }
289
290 template<fl::u32 N>
292 bs.to_string(&mStr);
293 return *this;
294 }
295
296 // bool support - output as "true"/"false" for readability
298 mStr.append(b ? "true" : "false");
299 return *this;
300 }
301
302 //-------------------------------------------------------------------------
303 // Enum support - converts enum class and regular enums to their underlying integer type
304 //-------------------------------------------------------------------------
305 template<typename T>
308 using underlying_t = typename fl::underlying_type<T>::type;
309 return (*this) << static_cast<underlying_t>(e);
310 }
311
312 //-------------------------------------------------------------------------
313 // Generic integer type overload using SFINAE
314 //-------------------------------------------------------------------------
315 // Handles all multi-byte integer types (excludes char types which are handled separately)
316 // Uses is_multi_byte_integer trait to select only non-char integer types
317 template<typename T>
319 operator<<(T val) FL_NOEXCEPT {
320 using target_t = typename int_cast_detail::cast_target<T>::type;
321 appendFormatted(static_cast<target_t>(val));
322 return *this;
323 }
324
325 //-------------------------------------------------------------------------
326 // Types with to_float() method (e.g., fixed_point types)
327 //-------------------------------------------------------------------------
328 template<typename T>
329 typename fl::enable_if<
330 fl::is_same<decltype(static_cast<const T*>(nullptr)->to_float()), float>::value
333 operator<<(const T &val) FL_NOEXCEPT {
334 mStr.append(val.to_float());
335 return *this;
336 }
337
338 // assignment operator completely replaces the current string
340 mStr = str;
341 return *this;
342 }
343
345 mStr.clear();
346 mStr.append(str);
347 return *this;
348 }
349
350
351 // crgb
353 mStr.clear();
354 (*this) << rgb;
355 return *this;
356 }
357
358 void clear() FL_NOEXCEPT { mStr.clear(); }
359
360 // Get current formatting base (10=decimal, 16=hex, 8=octal)
361 int getBase() const FL_NOEXCEPT { return mBase; }
362
363 // Friend operators for manipulators
364 friend sstream& operator<<(sstream&, const hex_t&) FL_NOEXCEPT;
365 friend sstream& operator<<(sstream&, const dec_t&) FL_NOEXCEPT;
366 friend sstream& operator<<(sstream&, const oct_t&) FL_NOEXCEPT;
367
368 private:
369 string mStr;
370 bool mTreatCharAsInt = false; // Default to ASCII mode for readable text output
371 int mBase = 10; // Default to decimal
372
373 // Helper methods to format integers based on current base
375 void appendFormatted(fl::i16 val) FL_NOEXCEPT;
376 void appendFormatted(fl::i32 val) FL_NOEXCEPT;
378 void appendFormatted(fl::u16 val) FL_NOEXCEPT;
379 void appendFormatted(fl::u32 val) FL_NOEXCEPT;
381};
382
384 public:
385 sstream_noop &operator<<(const char *) FL_NOEXCEPT { return *this; }
386
387 template<fl::size N>
388 sstream_noop &operator<<(const char (&)[N]) FL_NOEXCEPT { return *this; }
389
390 template <typename T> sstream_noop &operator=(const T &) FL_NOEXCEPT { return *this; }
391
392 sstream_noop &operator<<(const CRGB &) FL_NOEXCEPT { return *this; }
393 sstream_noop &operator<<(const string &) FL_NOEXCEPT { return *this; }
394 sstream_noop &operator<<(char) FL_NOEXCEPT { return *this; }
395 sstream_noop &operator<<(signed char) FL_NOEXCEPT { return *this; }
396 sstream_noop &operator<<(unsigned char) FL_NOEXCEPT { return *this; }
397 sstream_noop &operator<<(short) FL_NOEXCEPT { return *this; }
398 sstream_noop &operator<<(unsigned short) FL_NOEXCEPT { return *this; }
399
400 // bool support to match sstream interface
401 sstream_noop &operator<<(bool) FL_NOEXCEPT { return *this; }
402
403 // Enum support to match sstream interface
404 template<typename T>
407
408 sstream_noop &operator<<(float) FL_NOEXCEPT { return *this; }
409 sstream_noop &operator<<(double) FL_NOEXCEPT { return *this; }
410
411 //-------------------------------------------------------------------------
412 // Generic integer type overload using SFINAE
413 //-------------------------------------------------------------------------
414 // Mirror sstream's integer handling for API compatibility
415 // Handles all multi-byte integer types (excludes char types which are handled separately)
416 template<typename T>
419
420 // Generic pointer and other type support for compatibility
421 sstream_noop &operator<<(const void*) FL_NOEXCEPT { return *this; }
422
423 // Support for strings/characters in arrays
424 template<fl::size N>
425 sstream_noop &operator<<(const sstream (&)[N]) FL_NOEXCEPT { return *this; }
426
427 sstream_noop &operator<<(const sstream &) FL_NOEXCEPT { return *this; }
428 sstream_noop &operator<<(const Tile2x2_u8 &) FL_NOEXCEPT { return *this; }
431
432 // Vector support
433 template<typename T>
434 sstream_noop &operator<<(const vec2<T> &) FL_NOEXCEPT { return *this; }
435
436 // rect support
437 template<typename T>
438 sstream_noop &operator<<(const rect<T> &) FL_NOEXCEPT { return *this; }
439
440 // Optional support
441 template<typename T>
442 sstream_noop &operator<<(const Optional<T> &) FL_NOEXCEPT { return *this; }
443
444 // vector support
445 template<typename T>
447
448 // unordered_set support
449 template<typename Key, typename Hash, typename KeyEqual>
451
452 // unordered_map support
453 template<typename Key, typename T, typename Hash, typename KeyEqual, int INLINED_COUNT>
455
456 // unsorted_map_fixed support
457 template<typename Key, typename Value, fl::size N>
459
460 // flat_map support
461 template<typename Key, typename Value, typename Less>
463
464 // span support
465 template<typename T, fl::size Extent>
467
468 // pair support
469 template<typename T1, typename T2>
471
472 // Bitset support
473 template<fl::u32 N>
475
477
478 template<fl::u32 N>
480
481 // Support for hex and dec formatters
482 sstream_noop &operator<<(const hex_t &) FL_NOEXCEPT { return *this; }
483 sstream_noop &operator<<(const dec_t &) FL_NOEXCEPT { return *this; }
484 sstream_noop &operator<<(const oct_t &) FL_NOEXCEPT { return *this; }
485
486 sstream_noop &operator=(const string &) FL_NOEXCEPT { return *this; }
487 sstream_noop &operator=(const CRGB &) FL_NOEXCEPT { return *this; }
488 sstream_noop &operator=(char) FL_NOEXCEPT { return *this; }
489};
490
491
492} // namespace fl
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
sstream_noop & operator<<(const audio::fft::Bins &) FL_NOEXCEPT
Definition strstream.h:430
sstream_noop & operator<<(const char(&)[N]) FL_NOEXCEPT
Definition strstream.h:388
sstream_noop & operator<<(const bitset_inlined< N > &) FL_NOEXCEPT
Definition strstream.h:479
sstream_noop & operator<<(double) FL_NOEXCEPT
Definition strstream.h:409
sstream_noop & operator<<(const oct_t &) FL_NOEXCEPT
Definition strstream.h:484
sstream_noop & operator<<(const fl::vector< T > &) FL_NOEXCEPT
Definition strstream.h:446
sstream_noop & operator<<(const bitset_fixed< N > &) FL_NOEXCEPT
Definition strstream.h:474
sstream_noop & operator<<(const vec2< T > &) FL_NOEXCEPT
Definition strstream.h:434
sstream_noop & operator=(const string &) FL_NOEXCEPT
Definition strstream.h:486
sstream_noop & operator<<(signed char) FL_NOEXCEPT
Definition strstream.h:395
sstream_noop & operator<<(const sstream &) FL_NOEXCEPT
Definition strstream.h:427
sstream_noop & operator<<(const fl::pair< T1, T2 > &) FL_NOEXCEPT
Definition strstream.h:470
sstream_noop & operator<<(const string &) FL_NOEXCEPT
Definition strstream.h:393
sstream_noop & operator=(char) FL_NOEXCEPT
Definition strstream.h:488
sstream_noop & operator=(const T &) FL_NOEXCEPT
Definition strstream.h:390
sstream_noop & operator<<(unsigned char) FL_NOEXCEPT
Definition strstream.h:396
sstream_noop & operator<<(const fl::flat_map< Key, Value, Less > &) FL_NOEXCEPT
Definition strstream.h:462
sstream_noop & operator<<(const Tile2x2_u8_wrap &) FL_NOEXCEPT
Definition strstream.h:429
sstream_noop & operator<<(const void *) FL_NOEXCEPT
Definition strstream.h:421
sstream_noop & operator<<(bool) FL_NOEXCEPT
Definition strstream.h:401
sstream_noop & operator<<(const rect< T > &) FL_NOEXCEPT
Definition strstream.h:438
sstream_noop & operator<<(short) FL_NOEXCEPT
Definition strstream.h:397
sstream_noop & operator<<(const Optional< T > &) FL_NOEXCEPT
Definition strstream.h:442
sstream_noop & operator<<(const bitset_dynamic &) FL_NOEXCEPT
Definition strstream.h:476
sstream_noop & operator<<(float) FL_NOEXCEPT
Definition strstream.h:408
sstream_noop & operator<<(const fl::unsorted_map_fixed< Key, Value, N > &) FL_NOEXCEPT
Definition strstream.h:458
sstream_noop & operator<<(const char *) FL_NOEXCEPT
Definition strstream.h:385
sstream_noop & operator<<(const fl::span< T, Extent > &) FL_NOEXCEPT
Definition strstream.h:466
sstream_noop & operator<<(const hex_t &) FL_NOEXCEPT
Definition strstream.h:482
sstream_noop & operator<<(const fl::unordered_set< Key, Hash, KeyEqual > &) FL_NOEXCEPT
Definition strstream.h:450
sstream_noop & operator<<(const fl::unordered_map< Key, T, Hash, KeyEqual, INLINED_COUNT > &) FL_NOEXCEPT
Definition strstream.h:454
sstream_noop & operator<<(const dec_t &) FL_NOEXCEPT
Definition strstream.h:483
sstream_noop & operator<<(char) FL_NOEXCEPT
Definition strstream.h:394
sstream_noop & operator<<(const Tile2x2_u8 &) FL_NOEXCEPT
Definition strstream.h:428
sstream_noop & operator<<(const sstream(&)[N]) FL_NOEXCEPT
Definition strstream.h:425
sstream_noop & operator=(const CRGB &) FL_NOEXCEPT
Definition strstream.h:487
sstream_noop & operator<<(unsigned short) FL_NOEXCEPT
Definition strstream.h:398
sstream_noop & operator<<(const CRGB &) FL_NOEXCEPT
Definition strstream.h:392
sstream & operator<<(const rect< T > &r) FL_NOEXCEPT
Definition strstream.h:74
sstream & operator<<(const fl::pair< T1, T2 > &p) FL_NOEXCEPT
Definition strstream.h:197
sstream & operator<<(signed char n) FL_NOEXCEPT
Definition strstream.h:260
string str() const FL_NOEXCEPT
Definition strstream.h:43
sstream & operator<<(const fl::flat_map< Key, Value, Less > &map) FL_NOEXCEPT
Definition strstream.h:164
sstream & operator<<(const char *str) FL_NOEXCEPT
Definition strstream.h:230
string mStr
Definition strstream.h:369
void appendFormatted(fl::i8 val) FL_NOEXCEPT
void clear() FL_NOEXCEPT
Definition strstream.h:358
sstream & operator<<(const Optional< T > &opt) FL_NOEXCEPT
Definition strstream.h:85
sstream & operator<<(const CRGB &rgb) FL_NOEXCEPT
Definition strstream.h:46
sstream & operator=(const fl::u8 &n) FL_NOEXCEPT
Definition strstream.h:212
sstream & operator<<(const fl::vector< T > &vec) FL_NOEXCEPT
Definition strstream.h:98
sstream & operator<<(unsigned char n) FL_NOEXCEPT
Definition strstream.h:266
sstream & operator<<(bool b) FL_NOEXCEPT
Definition strstream.h:297
void setTreatCharAsInt(bool treatCharAsInt) FL_NOEXCEPT
Definition strstream.h:39
sstream & operator<<(const bitset_fixed< N > &bs) FL_NOEXCEPT
Definition strstream.h:279
sstream & operator<<(const double &f) FL_NOEXCEPT
Definition strstream.h:243
sstream & operator<<(const vec2< T > &v) FL_NOEXCEPT
Definition strstream.h:63
sstream & operator=(const CRGB &rgb) FL_NOEXCEPT
Definition strstream.h:352
sstream & operator<<(const sstream &strStream) FL_NOEXCEPT
Definition strstream.h:50
sstream & operator<<(const float &f) FL_NOEXCEPT
Definition strstream.h:237
sstream & operator=(const char *str) FL_NOEXCEPT
Definition strstream.h:344
sstream & operator<<(const char(&str)[N]) FL_NOEXCEPT
Definition strstream.h:273
sstream & operator<<(char c) FL_NOEXCEPT
Definition strstream.h:250
sstream & operator=(char c) FL_NOEXCEPT
Definition strstream.h:218
sstream & operator<<(const fl::span< T, Extent > &s) FL_NOEXCEPT
Definition strstream.h:183
sstream & operator<<(const fl::unordered_map< Key, T, Hash, KeyEqual, INLINED_COUNT > &map) FL_NOEXCEPT
Definition strstream.h:128
sstream & operator<<(const fl::unordered_set< Key, Hash, KeyEqual > &set) FL_NOEXCEPT
Definition strstream.h:112
const char * c_str() const FL_NOEXCEPT
Definition strstream.h:44
sstream & operator=(const string &str) FL_NOEXCEPT
Definition strstream.h:339
sstream & operator<<(const string &str) FL_NOEXCEPT
Definition strstream.h:225
int getBase() const FL_NOEXCEPT
Definition strstream.h:361
sstream() FL_NOEXCEPT=default
sstream & operator<<(const bitset_dynamic &bs) FL_NOEXCEPT
Definition strstream.h:285
bool mTreatCharAsInt
Definition strstream.h:370
sstream & operator=(const fl::u16 &n) FL_NOEXCEPT
Definition strstream.h:206
sstream & operator<<(const fl::unsorted_map_fixed< Key, Value, N > &map) FL_NOEXCEPT
Definition strstream.h:146
sstream & operator<<(const bitset_inlined< N > &bs) FL_NOEXCEPT
Definition strstream.h:291
unsigned char u8
Definition s16x16x4.h:132
signed char i8
Definition s16x16x4.h:131
typename fl::conditional< IsSigned, typename fl::conditional< Size==1, fl::i8, typename fl::conditional< Size==2, fl::i16, typename fl::conditional< Size==4, fl::i32, typename fl::conditional< Size==8, fl::i64, fl::i64 >::type >::type >::type >::type, typename fl::conditional< Size==1, fl::u16, typename fl::conditional< Size==2, fl::u16, typename fl::conditional< Size==4, fl::u32, typename fl::conditional< Size==8, fl::u64, fl::u64 >::type >::type >::type >::type >::type type
constexpr int type_rank< T >::value
MapRedBlackTree< Key, T, Compare, fl::allocator_slab< char > > map
Definition map.h:283
fl::i64 i64
Definition s16x16x4.h:222
fl::u64 u64
Definition s16x16x4.h:221
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT
Representation of an 8-bit RGB pixel (Red, Green, Blue)
Definition crgb.h:38