92 lines
2.3 KiB
C++
92 lines
2.3 KiB
C++
#pragma once
|
|
#ifndef _NB_SMARTSTREAM
|
|
#define _NB_SMARTSTREAM
|
|
|
|
#include <array>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <unordered_map>
|
|
|
|
namespace nb {
|
|
|
|
using RGB = std::array<unsigned char, 3>;
|
|
|
|
std::string toANSI(const RGB& color) {
|
|
return "\x1b[38;2;"+std::to_string(color[0])+";"+std::to_string(color[1])+
|
|
";"+std::to_string(color[2])+"m";
|
|
}
|
|
|
|
std::string toANSI(const unsigned int& color) {
|
|
return "\x1b[38;5;"+std::to_string(color)+"m";
|
|
}
|
|
|
|
template <typename U, typename Derived=void>
|
|
struct SmartText {
|
|
SmartText(const U& val) : msg(val) {}
|
|
|
|
const U msg;
|
|
|
|
template<typename C, typename T>
|
|
void process(std::basic_ostream<C,T>& stream) const;
|
|
};
|
|
|
|
template <typename Derived>
|
|
struct SmartText<std::string, Derived> {
|
|
template <std::size_t N>
|
|
SmartText(char const(&val) [N]) : msg(val) {}
|
|
SmartText(const std::string& val) : msg(val) {}
|
|
SmartText(const char* val) : msg(val) {}
|
|
|
|
const std::string msg;
|
|
|
|
template<typename C, typename T>
|
|
void process(std::basic_ostream<C,T>& stream) const;
|
|
};
|
|
|
|
template <typename U, typename Derived>
|
|
template <typename C, typename T>
|
|
void SmartText<U,Derived>::process(std::basic_ostream<C,T>& stream) const {
|
|
if (std::is_void<Derived>::value) {
|
|
stream << msg;
|
|
} else {
|
|
static_cast<Derived*>(this)->process(stream);
|
|
}
|
|
}
|
|
|
|
template<typename C, typename T, typename U, typename D>
|
|
std::basic_ostream<C, T>& operator<<(std::basic_ostream<C, T>& stream, const SmartText<U,D>& smt) {
|
|
if (std::is_void<D>::value) {
|
|
stream << smt.msg;
|
|
} else {
|
|
static_cast<const D*>(&smt)->process(stream);
|
|
}
|
|
return stream;
|
|
}
|
|
|
|
template <typename U>
|
|
struct TerminalColor : public SmartText<U, TerminalColor<U>> {
|
|
typedef SmartText<U, TerminalColor<U>> Base;
|
|
using Base::msg;
|
|
|
|
explicit TerminalColor(unsigned int color, const U& val)
|
|
: Base(val), colorSequence(toANSI(color)) { }
|
|
explicit TerminalColor(const RGB& color, const U& val)
|
|
: Base(val), colorSequence(toANSI(color)) { }
|
|
|
|
const std::string colorSequence;
|
|
|
|
template <typename C, typename T>
|
|
void process(std::basic_ostream<C, T>& stream) const {
|
|
if (&stream == &std::cout) {
|
|
stream << colorSequence << msg << "\x1b[0m";
|
|
} else {
|
|
stream << msg;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
}
|
|
|
|
#endif // _NB_SMARTSTREAM
|