SlHelpers
Loading...
Searching...
No Matches
Color.h
1// SPDX-License-Identifier: GPL-2.0-only
2
3#pragma once
4
5#include <iostream>
6#include <unistd.h>
7
8namespace SlHelpers {
18class Color {
19public:
21 enum C : unsigned {
22 BLACK = 30,
23 RED = 31,
24 GREEN = 32,
25 YELLOW = 33,
26 BLUE = 34,
27 MAGENTA = 35,
28 CYAN = 36,
29 WHITE = 37,
30 COL256 = 38,
31 DEFAULT = 39,
32 };
33
35 enum Ctrl {
36 NoNL,
37 NL,
38 };
39
44 explicit Color(enum C c = DEFAULT) noexcept : Color(std::cout, c) {}
45
51 explicit Color(std::ostream &os, enum C c = DEFAULT) noexcept : m_NL(true), m_os(os) {
52 if (doColor(os))
53 m_os << seqBegin << c << 'm';
54 }
55
62 Color(unsigned char r, unsigned char g, unsigned char b) noexcept
63 : Color(std::cout, r, g, b) {}
64
72 Color(std::ostream &os, unsigned char r, unsigned char g, unsigned char b) noexcept
73 : m_NL(true), m_os(os) {
74 if (!doColor(os))
75 return;
76 m_os << seqBegin << COL256 << ";2;" <<
77 toUnsigned(r) << ';' <<
78 toUnsigned(g) << ';' <<
79 toUnsigned(b) << 'm';
80 }
81
82 ~Color() {
83 if (doColor(m_os))
84 m_os << seqEnd;
85 if (m_NL)
86 m_os << '\n';
87 }
88
93 static void forceColor(bool force) { m_forceColor = force; }
98 static void forceColorValue(bool value) { m_forceColorValue = value; }
99
104 std::ostream &os() { return m_os; }
105
110 void ctrl(Ctrl ctrl) {
111 switch (ctrl) {
112 case NL:
113 case NoNL:
114 m_NL = ctrl == NL;
115 break;
116 }
117 }
118
119private:
120 template<typename T>
121 static unsigned toUnsigned(const T &val) { return val; }
122 static unsigned outIndex(const std::ostream &os) {
123 if (os.rdbuf() == std::cout.rdbuf())
124 return 0U;
125 if (os.rdbuf() == std::cerr.rdbuf())
126 return 1U;
127 return 2U;
128 }
129 static bool doColor(const std::ostream &os) {
130 if (m_forceColor)
131 return m_forceColorValue;
132 auto idx = outIndex(os);
133 if (m_doColor[idx] < 0)
134 m_doColor[idx] = isatty(idx + 1);
135 return m_doColor[idx];
136 }
137
138 friend void testColor();
139 inline static std::string_view seqBegin = "\033[01;";
140 inline static std::string_view seqEnd = "\033[0m";
141 inline static signed char m_doColor[] = { -1, -1, 1 };
142 inline static bool m_forceColor = false;
143 inline static bool m_forceColorValue = false;
144 bool m_NL;
145 std::ostream &m_os;
146};
147
148inline Color &&operator<<(Color &&os, const Color::Ctrl &ctrl)
149{
150 os.ctrl(ctrl);
151 return std::move(os);
152}
153
154template<typename T>
155Color &&operator<<(Color &&os, const T &x)
156{
157 os.os() << x;
158 return std::move(os);
159}
160
161}
Colorized output.
Definition Color.h:18
Color(std::ostream &os, enum C c=DEFAULT) noexcept
New Color stream (into os) using color c.
Definition Color.h:51
Color(enum C c=DEFAULT) noexcept
New Color stream (stdout) using color c.
Definition Color.h:44
Ctrl
Controls for Color.
Definition Color.h:35
static void forceColor(bool force)
Force color value (see forceColorValue()).
Definition Color.h:93
void ctrl(Ctrl ctrl)
Controls the stream behavior.
Definition Color.h:110
Color(unsigned char r, unsigned char g, unsigned char b) noexcept
New Color stream (stdout) using an RGB color.
Definition Color.h:62
static void forceColorValue(bool value)
If forceColor(true) was called, use of colors is bound to value.
Definition Color.h:98
C
Predefined colors.
Definition Color.h:21
std::ostream & os()
Return current output stream.
Definition Color.h:104
Color(std::ostream &os, unsigned char r, unsigned char g, unsigned char b) noexcept
New Color stream (into os) using an RGB color.
Definition Color.h:72