UtilsLite
Utilities for C++ programming
Loading...
Searching...
No Matches
rang.hxx
Go to the documentation of this file.
1/*\
2
3 Taken from: https://github.com/agauniyal/rang/blob/master/include/rang.hpp
4
5
6
7\*/
8
9#include <algorithm>
10#include <atomic>
11#include <cstdlib>
12#include <cstring>
13#include <iostream>
14
15namespace rang {
16
17 #ifndef DOXYGEN_SHOULD_SKIP_THIS
18 using std::ostream;
19 #endif
20
21 /* For better compability with most of terminals do not use any style settings
22 * except of reset, bold and reversed.
23 * Note that on Windows terminals bold style is same as fgB color.
24 */
25 enum class style {
26 reset = 0,
27 bold = 1,
28 dim = 2,
29 italic = 3,
31 blink = 5,
32 rblink = 6,
36 };
37
38 enum class fg {
39 black = 30,
40 red = 31,
41 green = 32,
42 yellow = 33,
43 blue = 34,
44 magenta = 35,
45 cyan = 36,
46 gray = 37,
47 reset = 39
48 };
49
50 enum class bg {
51 black = 40,
52 red = 41,
53 green = 42,
54 yellow = 43,
55 blue = 44,
56 magenta = 45,
57 cyan = 46,
58 gray = 47,
59 reset = 49
60 };
61
62 enum class fgB {
63 black = 90,
64 red = 91,
65 green = 92,
66 yellow = 93,
67 blue = 94,
68 magenta = 95,
69 cyan = 96,
70 gray = 97
71 };
72
73 enum class bgB {
74 black = 100,
75 red = 101,
76 green = 102,
77 yellow = 103,
78 blue = 104,
79 magenta = 105,
80 cyan = 106,
81 gray = 107
82 };
83
84 enum class control { // Behaviour of rang function calls
85 Off = 0, // toggle off rang style/color calls
86 Auto = 1, // (Default) autodect terminal and colorize if needed
87 Force = 2 // force ansi color output to non terminal streams
88 };
89 // Use rang::setControlMode to set rang control mode
90
91 enum class winTerm { // Windows Terminal Mode
92 Auto = 0, // (Default) automatically detects wheter Ansi or Native API
93 Ansi = 1, // Force use Ansi API
94 Native = 2 // Force use Native API
95 };
96 // Use rang::setWinTermMode to explicitly set terminal API for Windows
97 // Calling rang::setWinTermMode have no effect on other OS
98
99 #ifndef DOXYGEN_SHOULD_SKIP_THIS
100
101 namespace rang_implementation {
102
103 using std::atomic;
104 using std::enable_if;
105 using std::is_same;
106 using std::ostream;
107 using std::streambuf;
108
109 inline
110 std::atomic<control> &
111 controlMode() noexcept {
112 static std::atomic<control> value(control::Auto);
113 return value;
114 }
115
116 inline
117 std::atomic<winTerm> &
118 winTermMode() noexcept {
119 static std::atomic<winTerm> termMode(winTerm::Auto);
120 return termMode;
121 }
122
123 template <typename T>
124 using enableStd = typename enable_if<
125 is_same<T, rang::style>::value ||
126 is_same<T, rang::fg>::value ||
127 is_same<T, rang::bg>::value ||
128 is_same<T, rang::fgB>::value ||
129 is_same<T, rang::bgB>::value,
130 ostream &
131 >::type;
132
133 extern bool isTerminal( streambuf const * ) noexcept;
134 extern bool supportsAnsi( streambuf const * ) noexcept;
135 extern bool supportsColor() noexcept;
136
137 #ifdef UTILS_OS_WINDOWS
138 template <typename T>
139 inline
140 void
141 setWinColorAnsi( ostream &os, T const value ) {
142 os << "\033[" << static_cast<int>(value) << "m";
143 }
144
145 void setWinColorNative( ostream &os, enum rang::style value );
146 void setWinColorNative( ostream &os, enum rang::bg value );
147 void setWinColorNative( ostream &os, enum rang::fg value );
148 void setWinColorNative( ostream &os, enum rang::bgB value );
149 void setWinColorNative( ostream &os, enum rang::fgB value );
150
151 template <typename T>
152 inline
153 enableStd<T>
154 setColor( ostream &os, T const value ) {
155 if (winTermMode() == winTerm::Auto) {
156 if (supportsAnsi(os.rdbuf())) {
157 setWinColorAnsi(os, value);
158 } else {
159 setWinColorNative(os, value);
160 }
161 } else if (winTermMode() == winTerm::Ansi) {
162 setWinColorAnsi(os, value);
163 } else {
164 setWinColorNative(os, value);
165 }
166 return os;
167 }
168 #else
169 template <typename T>
170 inline
171 enableStd<T>
172 setColor( ostream &os, T const value ) {
173 return os << "\033[" << static_cast<int>(value) << "m";
174 }
175 #endif
176
177 } // namespace rang_implementation
178
179 template <typename T>
180 inline
181 rang_implementation::enableStd<T>
182 operator << ( ostream &os, T const value ) {
183 control const option = rang_implementation::controlMode();
184 switch (option) {
185 case control::Auto:
186 return rang_implementation::supportsColor()
187 && rang_implementation::isTerminal(os.rdbuf())
188 ? rang_implementation::setColor(os, value)
189 : os;
190 case control::Force:
191 return rang_implementation::setColor(os, value);
192 default:
193 return os;
194 }
195 }
196
197 inline
198 void
199 setWinTermMode( rang::winTerm const value ) noexcept {
200 rang_implementation::winTermMode() = value;
201 }
202
203 inline
204 void
205 setControlMode( control const value ) noexcept {
206 rang_implementation::controlMode() = value;
207 }
208 #endif
209
210} // namespace rang
211
212//
213// eof: rang.hxx
214//
Utils::ostream_type & operator<<(Utils::ostream_type &stream, Utils::Table::Row const &row)
Stream insertion operator for rendering a table row to an output stream.
Definition Table.hxx:379
Definition rang.hxx:15
fgB
Definition rang.hxx:62
fg
Definition rang.hxx:38
@ black
Definition rang.hxx:39
@ blue
Definition rang.hxx:43
@ magenta
Definition rang.hxx:44
@ cyan
Definition rang.hxx:45
@ green
Definition rang.hxx:41
@ red
Definition rang.hxx:40
@ gray
Definition rang.hxx:46
@ yellow
Definition rang.hxx:42
bgB
Definition rang.hxx:73
control
Definition rang.hxx:84
@ Auto
Definition rang.hxx:86
@ Force
Definition rang.hxx:87
@ Off
Definition rang.hxx:85
bg
Definition rang.hxx:50
style
Definition rang.hxx:25
@ italic
Definition rang.hxx:29
@ rblink
Definition rang.hxx:32
@ blink
Definition rang.hxx:31
@ dim
Definition rang.hxx:28
@ bold
Definition rang.hxx:27
@ underline
Definition rang.hxx:30
@ reset
Definition rang.hxx:26
@ reversed
Definition rang.hxx:33
@ conceal
Definition rang.hxx:34
@ crossed
Definition rang.hxx:35
winTerm
Definition rang.hxx:91
@ Ansi
Definition rang.hxx:93
@ Native
Definition rang.hxx:94