| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1 |
// Formatting library for C++ - std::ostream support |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3 |
// Copyright (c) 2012 - present, Victor Zverovich |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6 |
// For the license information refer to format.h. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8 |
#ifndef FMT_OSTREAM_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9 |
#define FMT_OSTREAM_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11 |
#include <ostream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13 |
#include "format.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
15 |
FMT_BEGIN_NAMESPACE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
16 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
17 |
template <typename OutputIt, typename Char> class basic_printf_context; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
18 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
19 |
namespace detail { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
20 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
21 |
// Checks if T has a user-defined operator<<. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
22 |
template <typename T, typename Char, typename Enable = void> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
23 |
class is_streamable { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
24 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
25 |
template <typename U> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
26 |
static auto test(int) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
27 |
-> bool_constant<sizeof(std::declval<std::basic_ostream<Char>&>() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
28 |
<< std::declval<U>()) != 0>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
29 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
30 |
template <typename> static auto test(...) -> std::false_type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
31 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
32 |
using result = decltype(test<T>(0)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
33 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
34 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
35 |
is_streamable() = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
36 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
37 |
static const bool value = result::value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
38 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
39 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
40 |
// Formatting of built-in types and arrays is intentionally disabled because |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
41 |
// it's handled by standard (non-ostream) formatters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
42 |
template <typename T, typename Char> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
43 |
struct is_streamable< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
44 |
T, Char, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
45 |
enable_if_t< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
46 |
std::is_arithmetic<T>::value || std::is_array<T>::value || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
47 |
std::is_pointer<T>::value || std::is_same<T, char8_type>::value || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
48 |
std::is_same<T, std::basic_string<Char>>::value || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
49 |
std::is_same<T, std_string_view<Char>>::value || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
50 |
(std::is_convertible<T, int>::value && !std::is_enum<T>::value)>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
51 |
: std::false_type {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
52 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
53 |
// Write the content of buf to os. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
54 |
// It is a separate function rather than a part of vprint to simplify testing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
55 |
template <typename Char> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
56 |
void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
57 |
const Char* buf_data = buf.data(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
58 |
using unsigned_streamsize = std::make_unsigned<std::streamsize>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
59 |
unsigned_streamsize size = buf.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
60 |
unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
61 |
do { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
62 |
unsigned_streamsize n = size <= max_size ? size : max_size; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
63 |
os.write(buf_data, static_cast<std::streamsize>(n)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
64 |
buf_data += n; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
65 |
size -= n; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
66 |
} while (size != 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
67 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
68 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
69 |
template <typename Char, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
70 |
void format_value(buffer<Char>& buf, const T& value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
71 |
locale_ref loc = locale_ref()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
72 |
auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
73 |
auto&& output = std::basic_ostream<Char>(&format_buf); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
74 |
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
75 |
if (loc) output.imbue(loc.get<std::locale>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
76 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
77 |
output << value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
78 |
output.exceptions(std::ios_base::failbit | std::ios_base::badbit); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
79 |
buf.try_resize(buf.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
80 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
81 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
82 |
// Formats an object of type T that has an overloaded ostream operator<<. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
83 |
template <typename T, typename Char> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
84 |
struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
85 |
: private formatter<basic_string_view<Char>, Char> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
86 |
using formatter<basic_string_view<Char>, Char>::parse; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
87 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
88 |
template <typename OutputIt> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
89 |
auto format(const T& value, basic_format_context<OutputIt, Char>& ctx) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
90 |
-> OutputIt { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
91 |
auto buffer = basic_memory_buffer<Char>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
92 |
format_value(buffer, value, ctx.locale()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
93 |
return formatter<basic_string_view<Char>, Char>::format( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
94 |
{buffer.data(), buffer.size()}, ctx); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
95 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
96 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
97 |
// DEPRECATED! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
98 |
template <typename OutputIt> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
99 |
auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
100 |
-> OutputIt { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
101 |
auto buffer = basic_memory_buffer<Char>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
102 |
format_value(buffer, value, ctx.locale()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
103 |
return std::copy(buffer.begin(), buffer.end(), ctx.out()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
104 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
105 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
106 |
} // namespace detail |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
107 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
108 |
FMT_MODULE_EXPORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
109 |
template <typename Char> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
110 |
void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
111 |
basic_format_args<buffer_context<type_identity_t<Char>>> args) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
112 |
auto buffer = basic_memory_buffer<Char>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
113 |
detail::vformat_to(buffer, format_str, args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
114 |
detail::write_buffer(os, buffer); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
115 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
116 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
117 |
/** |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
118 |
\rst |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
119 |
Prints formatted data to the stream *os*. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
120 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
121 |
**Example**:: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
122 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
123 |
fmt::print(cerr, "Don't {}!", "panic"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
124 |
\endrst |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
125 |
*/ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
126 |
FMT_MODULE_EXPORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
127 |
template <typename S, typename... Args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
128 |
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
129 |
void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
130 |
vprint(os, to_string_view(format_str), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
131 |
fmt::make_args_checked<Args...>(format_str, args...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
132 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
133 |
FMT_END_NAMESPACE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
134 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
135 |
#endif // FMT_OSTREAM_H_ |
|
|
1970-01-01 00:00 |
136 |
|