1 // Formatting library for C++ - color support
3 // Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
4 // All rights reserved.
6 // For the license information refer to format.h.
15 #ifdef FMT_DEPRECATED_COLORS
17 // color and (v)print_colored are deprecated.
18 enum FMT_DEPRECATED color
{
28 FMT_DEPRECATED FMT_API
void vprint_colored(color c
, string_view format
,
30 FMT_DEPRECATED FMT_API
void vprint_colored(color c
, wstring_view format
,
32 template <typename
... Args
>
33 FMT_DEPRECATED
inline void print_colored(color c
, string_view format_str
,
34 const Args
&... args
) {
35 vprint_colored(c
, format_str
, make_format_args(args
...));
37 template <typename
... Args
>
38 FMT_DEPRECATED
inline void print_colored(color c
, wstring_view format_str
,
39 const Args
&... args
) {
40 vprint_colored(c
, format_str
, make_format_args
<wformat_context
>(args
...));
43 FMT_DEPRECATED
inline void vprint_colored(color c
, string_view format
,
45 char escape
[] = "\x1b[30m";
46 escape
[3] = static_cast<char>('0' + c
);
47 std::fputs(escape
, stdout
);
49 std::fputs(internal::data::RESET_COLOR
, stdout
);
52 FMT_DEPRECATED
inline void vprint_colored(color c
, wstring_view format
,
54 wchar_t escape
[] = L
"\x1b[30m";
55 escape
[3] = static_cast<wchar_t>('0' + c
);
56 std::fputws(escape
, stdout
);
58 std::fputws(internal::data::WRESET_COLOR
, stdout
);
63 enum class color
: uint32_t {
64 alice_blue
= 0xF0F8FF, // rgb(240,248,255)
65 antique_white
= 0xFAEBD7, // rgb(250,235,215)
66 aqua
= 0x00FFFF, // rgb(0,255,255)
67 aquamarine
= 0x7FFFD4, // rgb(127,255,212)
68 azure
= 0xF0FFFF, // rgb(240,255,255)
69 beige
= 0xF5F5DC, // rgb(245,245,220)
70 bisque
= 0xFFE4C4, // rgb(255,228,196)
71 black
= 0x000000, // rgb(0,0,0)
72 blanched_almond
= 0xFFEBCD, // rgb(255,235,205)
73 blue
= 0x0000FF, // rgb(0,0,255)
74 blue_violet
= 0x8A2BE2, // rgb(138,43,226)
75 brown
= 0xA52A2A, // rgb(165,42,42)
76 burly_wood
= 0xDEB887, // rgb(222,184,135)
77 cadet_blue
= 0x5F9EA0, // rgb(95,158,160)
78 chartreuse
= 0x7FFF00, // rgb(127,255,0)
79 chocolate
= 0xD2691E, // rgb(210,105,30)
80 coral
= 0xFF7F50, // rgb(255,127,80)
81 cornflower_blue
= 0x6495ED, // rgb(100,149,237)
82 cornsilk
= 0xFFF8DC, // rgb(255,248,220)
83 crimson
= 0xDC143C, // rgb(220,20,60)
84 cyan
= 0x00FFFF, // rgb(0,255,255)
85 dark_blue
= 0x00008B, // rgb(0,0,139)
86 dark_cyan
= 0x008B8B, // rgb(0,139,139)
87 dark_golden_rod
= 0xB8860B, // rgb(184,134,11)
88 dark_gray
= 0xA9A9A9, // rgb(169,169,169)
89 dark_green
= 0x006400, // rgb(0,100,0)
90 dark_khaki
= 0xBDB76B, // rgb(189,183,107)
91 dark_magenta
= 0x8B008B, // rgb(139,0,139)
92 dark_olive_green
= 0x556B2F, // rgb(85,107,47)
93 dark_orange
= 0xFF8C00, // rgb(255,140,0)
94 dark_orchid
= 0x9932CC, // rgb(153,50,204)
95 dark_red
= 0x8B0000, // rgb(139,0,0)
96 dark_salmon
= 0xE9967A, // rgb(233,150,122)
97 dark_sea_green
= 0x8FBC8F, // rgb(143,188,143)
98 dark_slate_blue
= 0x483D8B, // rgb(72,61,139)
99 dark_slate_gray
= 0x2F4F4F, // rgb(47,79,79)
100 dark_turquoise
= 0x00CED1, // rgb(0,206,209)
101 dark_violet
= 0x9400D3, // rgb(148,0,211)
102 deep_pink
= 0xFF1493, // rgb(255,20,147)
103 deep_sky_blue
= 0x00BFFF, // rgb(0,191,255)
104 dim_gray
= 0x696969, // rgb(105,105,105)
105 dodger_blue
= 0x1E90FF, // rgb(30,144,255)
106 fire_brick
= 0xB22222, // rgb(178,34,34)
107 floral_white
= 0xFFFAF0, // rgb(255,250,240)
108 forest_green
= 0x228B22, // rgb(34,139,34)
109 fuchsia
= 0xFF00FF, // rgb(255,0,255)
110 gainsboro
= 0xDCDCDC, // rgb(220,220,220)
111 ghost_white
= 0xF8F8FF, // rgb(248,248,255)
112 gold
= 0xFFD700, // rgb(255,215,0)
113 golden_rod
= 0xDAA520, // rgb(218,165,32)
114 gray
= 0x808080, // rgb(128,128,128)
115 green
= 0x008000, // rgb(0,128,0)
116 green_yellow
= 0xADFF2F, // rgb(173,255,47)
117 honey_dew
= 0xF0FFF0, // rgb(240,255,240)
118 hot_pink
= 0xFF69B4, // rgb(255,105,180)
119 indian_red
= 0xCD5C5C, // rgb(205,92,92)
120 indigo
= 0x4B0082, // rgb(75,0,130)
121 ivory
= 0xFFFFF0, // rgb(255,255,240)
122 khaki
= 0xF0E68C, // rgb(240,230,140)
123 lavender
= 0xE6E6FA, // rgb(230,230,250)
124 lavender_blush
= 0xFFF0F5, // rgb(255,240,245)
125 lawn_green
= 0x7CFC00, // rgb(124,252,0)
126 lemon_chiffon
= 0xFFFACD, // rgb(255,250,205)
127 light_blue
= 0xADD8E6, // rgb(173,216,230)
128 light_coral
= 0xF08080, // rgb(240,128,128)
129 light_cyan
= 0xE0FFFF, // rgb(224,255,255)
130 light_golden_rod_yellow
= 0xFAFAD2, // rgb(250,250,210)
131 light_gray
= 0xD3D3D3, // rgb(211,211,211)
132 light_green
= 0x90EE90, // rgb(144,238,144)
133 light_pink
= 0xFFB6C1, // rgb(255,182,193)
134 light_salmon
= 0xFFA07A, // rgb(255,160,122)
135 light_sea_green
= 0x20B2AA, // rgb(32,178,170)
136 light_sky_blue
= 0x87CEFA, // rgb(135,206,250)
137 light_slate_gray
= 0x778899, // rgb(119,136,153)
138 light_steel_blue
= 0xB0C4DE, // rgb(176,196,222)
139 light_yellow
= 0xFFFFE0, // rgb(255,255,224)
140 lime
= 0x00FF00, // rgb(0,255,0)
141 lime_green
= 0x32CD32, // rgb(50,205,50)
142 linen
= 0xFAF0E6, // rgb(250,240,230)
143 magenta
= 0xFF00FF, // rgb(255,0,255)
144 maroon
= 0x800000, // rgb(128,0,0)
145 medium_aquamarine
= 0x66CDAA, // rgb(102,205,170)
146 medium_blue
= 0x0000CD, // rgb(0,0,205)
147 medium_orchid
= 0xBA55D3, // rgb(186,85,211)
148 medium_purple
= 0x9370DB, // rgb(147,112,219)
149 medium_sea_green
= 0x3CB371, // rgb(60,179,113)
150 medium_slate_blue
= 0x7B68EE, // rgb(123,104,238)
151 medium_spring_green
= 0x00FA9A, // rgb(0,250,154)
152 medium_turquoise
= 0x48D1CC, // rgb(72,209,204)
153 medium_violet_red
= 0xC71585, // rgb(199,21,133)
154 midnight_blue
= 0x191970, // rgb(25,25,112)
155 mint_cream
= 0xF5FFFA, // rgb(245,255,250)
156 misty_rose
= 0xFFE4E1, // rgb(255,228,225)
157 moccasin
= 0xFFE4B5, // rgb(255,228,181)
158 navajo_white
= 0xFFDEAD, // rgb(255,222,173)
159 navy
= 0x000080, // rgb(0,0,128)
160 old_lace
= 0xFDF5E6, // rgb(253,245,230)
161 olive
= 0x808000, // rgb(128,128,0)
162 olive_drab
= 0x6B8E23, // rgb(107,142,35)
163 orange
= 0xFFA500, // rgb(255,165,0)
164 orange_red
= 0xFF4500, // rgb(255,69,0)
165 orchid
= 0xDA70D6, // rgb(218,112,214)
166 pale_golden_rod
= 0xEEE8AA, // rgb(238,232,170)
167 pale_green
= 0x98FB98, // rgb(152,251,152)
168 pale_turquoise
= 0xAFEEEE, // rgb(175,238,238)
169 pale_violet_red
= 0xDB7093, // rgb(219,112,147)
170 papaya_whip
= 0xFFEFD5, // rgb(255,239,213)
171 peach_puff
= 0xFFDAB9, // rgb(255,218,185)
172 peru
= 0xCD853F, // rgb(205,133,63)
173 pink
= 0xFFC0CB, // rgb(255,192,203)
174 plum
= 0xDDA0DD, // rgb(221,160,221)
175 powder_blue
= 0xB0E0E6, // rgb(176,224,230)
176 purple
= 0x800080, // rgb(128,0,128)
177 rebecca_purple
= 0x663399, // rgb(102,51,153)
178 red
= 0xFF0000, // rgb(255,0,0)
179 rosy_brown
= 0xBC8F8F, // rgb(188,143,143)
180 royal_blue
= 0x4169E1, // rgb(65,105,225)
181 saddle_brown
= 0x8B4513, // rgb(139,69,19)
182 salmon
= 0xFA8072, // rgb(250,128,114)
183 sandy_brown
= 0xF4A460, // rgb(244,164,96)
184 sea_green
= 0x2E8B57, // rgb(46,139,87)
185 sea_shell
= 0xFFF5EE, // rgb(255,245,238)
186 sienna
= 0xA0522D, // rgb(160,82,45)
187 silver
= 0xC0C0C0, // rgb(192,192,192)
188 sky_blue
= 0x87CEEB, // rgb(135,206,235)
189 slate_blue
= 0x6A5ACD, // rgb(106,90,205)
190 slate_gray
= 0x708090, // rgb(112,128,144)
191 snow
= 0xFFFAFA, // rgb(255,250,250)
192 spring_green
= 0x00FF7F, // rgb(0,255,127)
193 steel_blue
= 0x4682B4, // rgb(70,130,180)
194 tan
= 0xD2B48C, // rgb(210,180,140)
195 teal
= 0x008080, // rgb(0,128,128)
196 thistle
= 0xD8BFD8, // rgb(216,191,216)
197 tomato
= 0xFF6347, // rgb(255,99,71)
198 turquoise
= 0x40E0D0, // rgb(64,224,208)
199 violet
= 0xEE82EE, // rgb(238,130,238)
200 wheat
= 0xF5DEB3, // rgb(245,222,179)
201 white
= 0xFFFFFF, // rgb(255,255,255)
202 white_smoke
= 0xF5F5F5, // rgb(245,245,245)
203 yellow
= 0xFFFF00, // rgb(255,255,0)
204 yellow_green
= 0x9ACD32 // rgb(154,205,50)
205 }; // enum class color
207 enum class terminal_color
: uint8_t {
224 }; // enum class terminal_color
226 enum class emphasis
: uint8_t {
230 strikethrough
= 1 << 3
231 }; // enum class emphasis
233 // rgb is a struct for red, green and blue colors.
234 // We use rgb as name because some editors will show it as color direct in the
237 FMT_CONSTEXPR
rgb() : r(0), g(0), b(0) {}
238 FMT_CONSTEXPR
rgb(uint8_t r_
, uint8_t g_
, uint8_t b_
) : r(r_
), g(g_
), b(b_
) {}
239 FMT_CONSTEXPR
rgb(uint32_t hex
)
240 : r((hex
>> 16) & 0xFF), g((hex
>> 8) & 0xFF), b(hex
& 0xFF) {}
241 FMT_CONSTEXPR
rgb(color hex
)
242 : r((uint32_t(hex
) >> 16) & 0xFF),
243 g((uint32_t(hex
) >> 8) & 0xFF),
244 b(uint32_t(hex
) & 0xFF) {}
252 // color is a struct of either a rgb color or a terminal color.
254 FMT_CONSTEXPR
color_type() FMT_NOEXCEPT
: is_rgb(), value
{} {}
255 FMT_CONSTEXPR
color_type(color rgb_color
) FMT_NOEXCEPT
: is_rgb(true),
257 value
.rgb_color
= static_cast<uint32_t>(rgb_color
);
259 FMT_CONSTEXPR
color_type(rgb rgb_color
) FMT_NOEXCEPT
: is_rgb(true), value
{} {
260 value
.rgb_color
= (static_cast<uint32_t>(rgb_color
.r
) << 16) |
261 (static_cast<uint32_t>(rgb_color
.g
) << 8) | rgb_color
.b
;
263 FMT_CONSTEXPR
color_type(terminal_color term_color
) FMT_NOEXCEPT
: is_rgb(),
265 value
.term_color
= static_cast<uint8_t>(term_color
);
273 } // namespace internal
275 // Experimental text formatting support.
278 FMT_CONSTEXPR
text_style(emphasis em
= emphasis()) FMT_NOEXCEPT
279 : set_foreground_color(),
280 set_background_color(),
283 FMT_CONSTEXPR text_style
& operator|=(const text_style
& rhs
) {
284 if (!set_foreground_color
) {
285 set_foreground_color
= rhs
.set_foreground_color
;
286 foreground_color
= rhs
.foreground_color
;
287 } else if (rhs
.set_foreground_color
) {
288 if (!foreground_color
.is_rgb
|| !rhs
.foreground_color
.is_rgb
)
289 throw format_error("can't OR a terminal color");
290 foreground_color
.value
.rgb_color
|= rhs
.foreground_color
.value
.rgb_color
;
293 if (!set_background_color
) {
294 set_background_color
= rhs
.set_background_color
;
295 background_color
= rhs
.background_color
;
296 } else if (rhs
.set_background_color
) {
297 if (!background_color
.is_rgb
|| !rhs
.background_color
.is_rgb
)
298 throw format_error("can't OR a terminal color");
299 background_color
.value
.rgb_color
|= rhs
.background_color
.value
.rgb_color
;
302 ems
= static_cast<emphasis
>(static_cast<uint8_t>(ems
) |
303 static_cast<uint8_t>(rhs
.ems
));
307 friend FMT_CONSTEXPR text_style
operator|(text_style lhs
,
308 const text_style
& rhs
) {
312 FMT_CONSTEXPR text_style
& operator&=(const text_style
& rhs
) {
313 if (!set_foreground_color
) {
314 set_foreground_color
= rhs
.set_foreground_color
;
315 foreground_color
= rhs
.foreground_color
;
316 } else if (rhs
.set_foreground_color
) {
317 if (!foreground_color
.is_rgb
|| !rhs
.foreground_color
.is_rgb
)
318 throw format_error("can't AND a terminal color");
319 foreground_color
.value
.rgb_color
&= rhs
.foreground_color
.value
.rgb_color
;
322 if (!set_background_color
) {
323 set_background_color
= rhs
.set_background_color
;
324 background_color
= rhs
.background_color
;
325 } else if (rhs
.set_background_color
) {
326 if (!background_color
.is_rgb
|| !rhs
.background_color
.is_rgb
)
327 throw format_error("can't AND a terminal color");
328 background_color
.value
.rgb_color
&= rhs
.background_color
.value
.rgb_color
;
331 ems
= static_cast<emphasis
>(static_cast<uint8_t>(ems
) &
332 static_cast<uint8_t>(rhs
.ems
));
336 friend FMT_CONSTEXPR text_style
operator&(text_style lhs
,
337 const text_style
& rhs
) {
341 FMT_CONSTEXPR
bool has_foreground() const FMT_NOEXCEPT
{
342 return set_foreground_color
;
344 FMT_CONSTEXPR
bool has_background() const FMT_NOEXCEPT
{
345 return set_background_color
;
347 FMT_CONSTEXPR
bool has_emphasis() const FMT_NOEXCEPT
{
348 return static_cast<uint8_t>(ems
) != 0;
350 FMT_CONSTEXPR
internal::color_type
get_foreground() const FMT_NOEXCEPT
{
351 assert(has_foreground() && "no foreground specified for this style");
352 return foreground_color
;
354 FMT_CONSTEXPR
internal::color_type
get_background() const FMT_NOEXCEPT
{
355 assert(has_background() && "no background specified for this style");
356 return background_color
;
358 FMT_CONSTEXPR emphasis
get_emphasis() const FMT_NOEXCEPT
{
359 assert(has_emphasis() && "no emphasis specified for this style");
364 FMT_CONSTEXPR
text_style(bool is_foreground
,
365 internal::color_type text_color
) FMT_NOEXCEPT
366 : set_foreground_color(),
367 set_background_color(),
370 foreground_color
= text_color
;
371 set_foreground_color
= true;
373 background_color
= text_color
;
374 set_background_color
= true;
378 friend FMT_CONSTEXPR_DECL text_style
fg(internal::color_type foreground
)
380 friend FMT_CONSTEXPR_DECL text_style
bg(internal::color_type background
)
383 internal::color_type foreground_color
;
384 internal::color_type background_color
;
385 bool set_foreground_color
;
386 bool set_background_color
;
390 FMT_CONSTEXPR text_style
fg(internal::color_type foreground
) FMT_NOEXCEPT
{
391 return text_style(/*is_foreground=*/true, foreground
);
394 FMT_CONSTEXPR text_style
bg(internal::color_type background
) FMT_NOEXCEPT
{
395 return text_style(/*is_foreground=*/false, background
);
398 FMT_CONSTEXPR text_style
operator|(emphasis lhs
, emphasis rhs
) FMT_NOEXCEPT
{
399 return text_style(lhs
) | rhs
;
404 template <typename Char
> struct ansi_color_escape
{
405 FMT_CONSTEXPR
ansi_color_escape(internal::color_type text_color
,
406 const char* esc
) FMT_NOEXCEPT
{
407 // If we have a terminal color, we need to output another escape code
409 if (!text_color
.is_rgb
) {
410 bool is_background
= esc
== internal::data::BACKGROUND_COLOR
;
411 uint32_t value
= text_color
.value
.term_color
;
412 // Background ASCII codes are the same as the foreground ones but with
414 if (is_background
) value
+= 10u;
416 std::size_t index
= 0;
417 buffer
[index
++] = static_cast<Char
>('\x1b');
418 buffer
[index
++] = static_cast<Char
>('[');
421 buffer
[index
++] = static_cast<Char
>('1');
424 buffer
[index
++] = static_cast<Char
>('0' + value
/ 10u);
425 buffer
[index
++] = static_cast<Char
>('0' + value
% 10u);
427 buffer
[index
++] = static_cast<Char
>('m');
428 buffer
[index
++] = static_cast<Char
>('\0');
432 for (int i
= 0; i
< 7; i
++) {
433 buffer
[i
] = static_cast<Char
>(esc
[i
]);
435 rgb
color(text_color
.value
.rgb_color
);
436 to_esc(color
.r
, buffer
+ 7, ';');
437 to_esc(color
.g
, buffer
+ 11, ';');
438 to_esc(color
.b
, buffer
+ 15, 'm');
439 buffer
[19] = static_cast<Char
>(0);
441 FMT_CONSTEXPR
ansi_color_escape(emphasis em
) FMT_NOEXCEPT
{
442 uint8_t em_codes
[4] = {};
443 uint8_t em_bits
= static_cast<uint8_t>(em
);
444 if (em_bits
& static_cast<uint8_t>(emphasis::bold
)) em_codes
[0] = 1;
445 if (em_bits
& static_cast<uint8_t>(emphasis::italic
)) em_codes
[1] = 3;
446 if (em_bits
& static_cast<uint8_t>(emphasis::underline
)) em_codes
[2] = 4;
447 if (em_bits
& static_cast<uint8_t>(emphasis::strikethrough
))
450 std::size_t index
= 0;
451 for (int i
= 0; i
< 4; ++i
) {
452 if (!em_codes
[i
]) continue;
453 buffer
[index
++] = static_cast<Char
>('\x1b');
454 buffer
[index
++] = static_cast<Char
>('[');
455 buffer
[index
++] = static_cast<Char
>('0' + em_codes
[i
]);
456 buffer
[index
++] = static_cast<Char
>('m');
458 buffer
[index
++] = static_cast<Char
>(0);
460 FMT_CONSTEXPR
operator const Char
*() const FMT_NOEXCEPT
{ return buffer
; }
462 FMT_CONSTEXPR
const Char
* begin() const FMT_NOEXCEPT
{ return buffer
; }
463 FMT_CONSTEXPR
const Char
* end() const FMT_NOEXCEPT
{
464 return buffer
+ std::strlen(buffer
);
468 Char buffer
[7u + 3u * 4u + 1u];
470 static FMT_CONSTEXPR
void to_esc(uint8_t c
, Char
* out
,
471 char delimiter
) FMT_NOEXCEPT
{
472 out
[0] = static_cast<Char
>('0' + c
/ 100);
473 out
[1] = static_cast<Char
>('0' + c
/ 10 % 10);
474 out
[2] = static_cast<Char
>('0' + c
% 10);
475 out
[3] = static_cast<Char
>(delimiter
);
479 template <typename Char
>
480 FMT_CONSTEXPR ansi_color_escape
<Char
> make_foreground_color(
481 internal::color_type foreground
) FMT_NOEXCEPT
{
482 return ansi_color_escape
<Char
>(foreground
, internal::data::FOREGROUND_COLOR
);
485 template <typename Char
>
486 FMT_CONSTEXPR ansi_color_escape
<Char
> make_background_color(
487 internal::color_type background
) FMT_NOEXCEPT
{
488 return ansi_color_escape
<Char
>(background
, internal::data::BACKGROUND_COLOR
);
491 template <typename Char
>
492 FMT_CONSTEXPR ansi_color_escape
<Char
> make_emphasis(emphasis em
) FMT_NOEXCEPT
{
493 return ansi_color_escape
<Char
>(em
);
496 template <typename Char
>
497 inline void fputs(const Char
* chars
, FILE* stream
) FMT_NOEXCEPT
{
498 std::fputs(chars
, stream
);
502 inline void fputs
<wchar_t>(const wchar_t* chars
, FILE* stream
) FMT_NOEXCEPT
{
503 std::fputws(chars
, stream
);
506 template <typename Char
> inline void reset_color(FILE* stream
) FMT_NOEXCEPT
{
507 fputs(internal::data::RESET_COLOR
, stream
);
510 template <> inline void reset_color
<wchar_t>(FILE* stream
) FMT_NOEXCEPT
{
511 fputs(internal::data::WRESET_COLOR
, stream
);
514 template <typename Char
>
515 inline void reset_color(basic_memory_buffer
<Char
>& buffer
) FMT_NOEXCEPT
{
516 const char* begin
= data::RESET_COLOR
;
517 const char* end
= begin
+ sizeof(data::RESET_COLOR
) - 1;
518 buffer
.append(begin
, end
);
521 // The following specialization disables using std::FILE as a character type,
522 // which is needed because or else
523 // fmt::print(stderr, fmt::emphasis::bold, "");
524 // would take stderr (a std::FILE *) as the format string.
525 template <> struct is_string
<std::FILE*> : std::false_type
{};
526 template <> struct is_string
<const std::FILE*> : std::false_type
{};
528 template <typename Char
>
529 std::basic_string
<Char
> vformat(
530 const text_style
& ts
, basic_string_view
<Char
> format_str
,
531 basic_format_args
<typename buffer_context
<Char
>::type
> args
) {
532 basic_memory_buffer
<Char
> buffer
;
533 bool has_style
= false;
534 if (ts
.has_emphasis()) {
536 ansi_color_escape
<Char
> escape
= make_emphasis
<Char
>(ts
.get_emphasis());
537 buffer
.append(escape
.begin(), escape
.end());
539 if (ts
.has_foreground()) {
541 ansi_color_escape
<Char
> escape
=
542 make_foreground_color
<Char
>(ts
.get_foreground());
543 buffer
.append(escape
.begin(), escape
.end());
545 if (ts
.has_background()) {
547 ansi_color_escape
<Char
> escape
=
548 make_background_color
<Char
>(ts
.get_background());
549 buffer
.append(escape
.begin(), escape
.end());
551 internal::vformat_to(buffer
, format_str
, args
);
553 reset_color
<Char
>(buffer
);
555 return fmt::to_string(buffer
);
557 } // namespace internal
559 template <typename S
, typename Char
= typename
internal::char_t
<S
>::type
>
560 void vprint(std::FILE* f
, const text_style
& ts
, const S
& format
,
561 basic_format_args
<typename buffer_context
<Char
>::type
> args
) {
562 bool has_style
= false;
563 if (ts
.has_emphasis()) {
565 internal::fputs
<Char
>(internal::make_emphasis
<Char
>(ts
.get_emphasis()), f
);
567 if (ts
.has_foreground()) {
569 internal::fputs
<Char
>(
570 internal::make_foreground_color
<Char
>(ts
.get_foreground()), f
);
572 if (ts
.has_background()) {
574 internal::fputs
<Char
>(
575 internal::make_background_color
<Char
>(ts
.get_background()), f
);
577 vprint(f
, format
, args
);
579 internal::reset_color
<Char
>(f
);
584 Formats a string and prints it to the specified file stream using ANSI
585 escape sequences to specify text formatting.
587 fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
588 "Elapsed time: {0:.2f} seconds", 1.23);
590 template <typename String
, typename
... Args
,
591 FMT_ENABLE_IF(internal::is_string
<String
>::value
)>
592 void print(std::FILE* f
, const text_style
& ts
, const String
& format_str
,
593 const Args
&... args
) {
594 internal::check_format_string
<Args
...>(format_str
);
595 typedef typename
internal::char_t
<String
>::type char_t
;
596 typedef typename buffer_context
<char_t
>::type context_t
;
597 format_arg_store
<context_t
, Args
...> as
{args
...};
598 vprint(f
, ts
, format_str
, basic_format_args
<context_t
>(as
));
602 Formats a string and prints it to stdout using ANSI escape sequences to
603 specify text formatting.
605 fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
606 "Elapsed time: {0:.2f} seconds", 1.23);
608 template <typename String
, typename
... Args
,
609 FMT_ENABLE_IF(internal::is_string
<String
>::value
)>
610 void print(const text_style
& ts
, const String
& format_str
,
611 const Args
&... args
) {
612 return print(stdout
, ts
, format_str
, args
...);
615 template <typename S
, typename Char
= FMT_CHAR(S
)>
616 inline std::basic_string
<Char
> vformat(
617 const text_style
& ts
, const S
& format_str
,
618 basic_format_args
<typename buffer_context
<Char
>::type
> args
) {
619 return internal::vformat(ts
, to_string_view(format_str
), args
);
624 Formats arguments and returns the result as a string using ANSI
625 escape sequences to specify text formatting.
629 #include <fmt/color.h>
630 std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
631 "The answer is {}", 42);
634 template <typename S
, typename
... Args
>
635 inline std::basic_string
<FMT_CHAR(S
)> format(const text_style
& ts
,
637 const Args
&... args
) {
638 return internal::vformat(ts
, to_string_view(format_str
),
639 {internal::make_args_checked(format_str
, args
...)});
646 #endif // FMT_COLOR_H_