Files
klubhaus-doorbell/libraries/FastLED/src/fl/ostream.h
2026-02-12 00:45:31 -08:00

141 lines
3.0 KiB
C++

#pragma once
// allow-include-after-namespace
// Forward declaration to avoid pulling in fl/io.h and causing fl/io.cpp to be compiled
#ifndef FL_IO_H_INCLUDED
namespace fl {
void print(const char* str);
}
#endif
#include "fl/str.h"
#include "fl/int.h"
#include "fl/type_traits.h"
#include "crgb.h"
namespace fl {
class ostream {
public:
ostream() = default;
// Stream output operators that immediately print
ostream& operator<<(const char* str) {
if (str) {
print(str);
}
return *this;
}
ostream& operator<<(const string& str) {
print(str.c_str());
return *this;
}
ostream& operator<<(char c) {
char str[2] = {c, '\0'};
print(str);
return *this;
}
ostream& operator<<(fl::i8 n) {
string temp;
temp.append(fl::i16(n));
print(temp.c_str());
return *this;
}
ostream& operator<<(fl::u8 n) {
string temp;
temp.append(fl::u16(n));
print(temp.c_str());
return *this;
}
ostream& operator<<(fl::i16 n) {
string temp;
temp.append(n);
print(temp.c_str());
return *this;
}
ostream& operator<<(fl::i32 n) {
string temp;
temp.append(n);
print(temp.c_str());
return *this;
}
ostream& operator<<(fl::u32 n) {
string temp;
temp.append(n);
print(temp.c_str());
return *this;
}
ostream& operator<<(float f) {
string temp;
temp.append(f);
print(temp.c_str());
return *this;
}
ostream& operator<<(double d) {
string temp;
temp.append(d);
print(temp.c_str());
return *this;
}
ostream& operator<<(const CRGB& rgb) {
string temp;
temp.append(rgb);
print(temp.c_str());
return *this;
}
// Unified handler for fl:: namespace size-like unsigned integer types to avoid conflicts
// This handles fl::size and fl::u16 from the fl:: namespace only
template<typename T>
typename fl::enable_if<
fl::is_same<T, fl::size>::value ||
fl::is_same<T, fl::u16>::value,
ostream&
>::type operator<<(T n) {
string temp;
temp.append(fl::u32(n));
print(temp.c_str());
return *this;
}
// Generic template for other types that have string append support
// Note: This must come after the specific SFINAE template to avoid conflicts
template<typename T>
typename fl::enable_if<
!fl::is_same<T, fl::size>::value &&
!fl::is_same<T, fl::u16>::value,
ostream&
>::type operator<<(const T& value) {
string temp;
temp.append(value);
print(temp.c_str());
return *this;
}
};
// Global cout instance for immediate output
extern ostream cout;
// Line ending manipulator
struct endl_t {};
extern const endl_t endl;
// endl manipulator implementation
inline ostream& operator<<(ostream& os, const endl_t&) {
os << "\n";
return os;
}
} // namespace fl