/* color.hpp */ #pragma once #include //#include // for std::move #include namespace xo { enum color_encoding { CE_None, CE_Ansi, CE_Xterm, }; enum color_flags { CF_None = 0x0, CF_ColorOn = 0x01, CF_Contents = 0x02, CF_ColorOff = 0x04, CF_All = 0x07 }; template class color_impl { public: color_impl(color_flags flags, color_encoding encoding, std::uint32_t color, Contents && contents) : flags_{flags}, encoding_{encoding}, color_{color}, contents_{std::move(contents)} {} std::uint32_t color() const { return color_; } Contents const & contents() const { return contents_; } void print(std::ostream & os) const { if ((flags_ & CF_ColorOn) && (color_ > 0)) { switch(encoding_) { case CE_Ansi: os << "\033[" << color_ << "m"; break; case CE_Xterm: os << "\033[38;5;" << color_ << "m"; break; } } if (flags_ & CF_Contents) os << contents_; if ((flags_ & CF_ColorOff) && (color_ > 0)) os << "\033[0m"; } /*print*/ private: color_flags flags_ = CF_None; color_encoding encoding_ = CE_Ansi; /* .encoding = CE_Ansi: * 0 = no color * 30 = black * 31 = red * 32 = green * 33 = yellow * 34 = blue * 35 = magenta * 36 = cyan * * .encoding = CE_Xterm: * see [[https://i.stack.imgur.com/KTSQa.png]] * 0..7 standard colors (muted: grey, red, green, yellow, blue, pink, cyan, white) * 8..15 high-intensity colors (grey, red, green, yellow, blue, pink, cyan, white) * 16..51 chooses hue * 16..51 + (0..5)x36 increases whiteness */ std::uint32_t color_ = 0; Contents contents_; }; /*color_impl*/ template color_impl with_ansi_color(std::uint32_t color, Contents && contents) { return color_impl(CF_All, CE_Ansi, color, std::move(contents)); } /*with_ansi_color*/ template color_impl with_xterm_color(std::uint32_t color, Contents && contents) { return color_impl(CF_All, CE_Xterm, color, std::move(contents)); } /*with_ansi_color*/ template color_impl with_color(color_encoding encoding, std::uint32_t color, Contents && contents) { return color_impl(CF_All, encoding, color, std::move(contents)); } /*with_color*/ inline color_impl color_on_ansi(std::uint32_t color) { return color_impl(CF_ColorOn, CE_Ansi, color, 0); } /*color_on_ansi*/ inline color_impl color_on_xterm(std::uint32_t color) { return color_impl(CF_ColorOn, CE_Xterm, color, 0); } /*color_on_xterm*/ inline color_impl color_on(color_encoding encoding, std::uint32_t color) { return color_impl(CF_ColorOn, encoding, color, 0); } /*color_on*/ inline color_impl color_off() { /* any non-zero value works here for color */ return color_impl(CF_ColorOff, CE_None, 1 /*color*/, 0); } /*color_off*/ template inline std::ostream & operator<<(std::ostream & os, color_impl const & x) { x.print(os); return os; } /*operator<<*/ } /*namespace xo*/ /* end color.hpp */