Photon 1.0.0
Loading...
Searching...
No Matches
ostream.h
Go to the documentation of this file.
1// Formatting library for C++ - std::ostream support
2//
3// Copyright (c) 2012 - present, Victor Zverovich
4// All rights reserved.
5//
6// For the license information refer to format.h.
7
8#ifndef FMT_OSTREAM_H_
9#define FMT_OSTREAM_H_
10
11#include <fstream>
12#include <ostream>
13#if defined(_WIN32) && defined(__GLIBCXX__)
14#include <ext/stdio_filebuf.h>
15#include <ext/stdio_sync_filebuf.h>
16#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
17#include <__std_stream>
18#endif
19
20#include "format.h"
21
23
24template <typename OutputIt, typename Char>
26
27namespace detail
28{
29
30 // Checks if T has a user-defined operator<<.
31 template <typename T, typename Char, typename Enable = void>
33 {
34 private:
35 template <typename U>
36 static auto test(int)
37 -> bool_constant<sizeof(std::declval<std::basic_ostream<Char>&>()
38 << std::declval<U>()) != 0>;
39
40 template <typename>
41 static auto test(...) -> std::false_type;
42
43 using result = decltype(test<T>(0));
44
45 public:
46 is_streamable() = default;
47
48 static const bool value = result::value;
49 };
50
51 // Formatting of built-in types and arrays is intentionally disabled because
52 // it's handled by standard (non-ostream) formatters.
53 template <typename T, typename Char>
55 T,
56 Char,
58 std::is_arithmetic<T>::value || std::is_array<T>::value ||
59 std::is_pointer<T>::value || std::is_same<T, char8_type>::value ||
60 std::is_convertible<T, fmt::basic_string_view<Char>>::value ||
61 std::is_same<T, std_string_view<Char>>::value ||
62 (std::is_convertible<T, int>::value && !std::is_enum<T>::value)>>
63 : std::false_type
64 {
65 };
66
67 // Generate a unique explicit instantion in every translation unit using a tag
68 // type in an anonymous namespace.
69 namespace
70 {
71 struct file_access_tag
72 {
73 };
74 } // namespace
75 template <class Tag, class BufType, FILE* BufType::*FileMemberPtr>
77 {
78 friend auto get_file(BufType& obj) -> FILE*
79 {
80 return obj.*FileMemberPtr;
81 }
82 };
83
84#if FMT_MSC_VERSION
85 template class file_access<file_access_tag, std::filebuf, &std::filebuf::_Myfile>;
86 auto get_file(std::filebuf&) -> FILE*;
87#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
88 template class file_access<file_access_tag, std::__stdoutbuf<char>, &std::__stdoutbuf<char>::__file_>;
89 auto get_file(std::__stdoutbuf<char>&) -> FILE*;
90#endif
91
92 inline bool write_ostream_unicode(std::ostream& os, fmt::string_view data)
93 {
94#if FMT_MSC_VERSION
95 if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
96 if (FILE* f = get_file(*buf))
97 return write_console(f, data);
98#elif defined(_WIN32) && defined(__GLIBCXX__)
99 auto* rdbuf = os.rdbuf();
100 FILE* c_file;
101 if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))
102 c_file = fbuf->file();
103 else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))
104 c_file = fbuf->file();
105 else
106 return false;
107 if (c_file)
108 return write_console(c_file, data);
109#elif defined(_WIN32) && defined(_LIBCPP_VERSION)
110 if (auto* buf = dynamic_cast<std::__stdoutbuf<char>*>(os.rdbuf()))
111 if (FILE* f = get_file(*buf))
112 return write_console(f, data);
113#else
114 ignore_unused(os, data);
115#endif
116 return false;
117 }
118 inline bool write_ostream_unicode(std::wostream&,
119 fmt::basic_string_view<wchar_t>)
120 {
121 return false;
122 }
123
124 // Write the content of buf to os.
125 // It is a separate function rather than a part of vprint to simplify testing.
126 template <typename Char>
127 void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf)
128 {
129 const Char* buf_data = buf.data();
130 using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
131 unsigned_streamsize size = buf.size();
132 unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
133 do
134 {
135 unsigned_streamsize n = size <= max_size ? size : max_size;
136 os.write(buf_data, static_cast<std::streamsize>(n));
137 buf_data += n;
138 size -= n;
139 } while (size != 0);
140 }
141
142 template <typename Char, typename T>
143 void format_value(buffer<Char>& buf, const T& value, locale_ref loc = locale_ref())
144 {
145 auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
146 auto&& output = std::basic_ostream<Char>(&format_buf);
147#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
148 if (loc)
149 output.imbue(loc.get<std::locale>());
150#endif
151 output << value;
152 output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
153 }
154
155 template <typename T>
157 {
158 const T& value;
159 };
160
161} // namespace detail
162
163// Formats an object of type T that has an overloaded ostream operator<<.
164template <typename Char>
165struct basic_ostream_formatter : formatter<basic_string_view<Char>, Char>
166{
167 void set_debug_format() = delete;
168
169 template <typename T, typename OutputIt>
171 -> OutputIt
172 {
174 format_value(buffer, value, ctx.locale());
176 {buffer.data(), buffer.size()}, ctx);
177 }
178};
179
181
182template <typename T, typename Char>
183struct formatter<detail::streamed_view<T>, Char>
185{
186 template <typename OutputIt>
188 basic_format_context<OutputIt, Char>& ctx) const -> OutputIt
189 {
191 }
192};
193
204template <typename T>
206{
207 return {value};
208}
209
210namespace detail
211{
212
213 // Formats an object of type T that has an overloaded ostream operator<<.
214 template <typename T, typename Char>
217 {
219 };
220
221 inline void vprint_directly(std::ostream& os, string_view format_str, format_args args)
222 {
223 auto buffer = memory_buffer();
224 detail::vformat_to(buffer, format_str, args);
225 detail::write_buffer(os, buffer);
226 }
227
228} // namespace detail
229
230FMT_MODULE_EXPORT template <typename Char>
231void vprint(std::basic_ostream<Char>& os,
234{
236 detail::vformat_to(buffer, format_str, args);
238 return;
240}
241
251FMT_MODULE_EXPORT template <typename... T>
252void print(std::ostream& os, format_string<T...> fmt, T&&... args)
253{
254 const auto& vargs = fmt::make_format_args(args...);
255 if (detail::is_utf8())
256 vprint(os, fmt, vargs);
257 else
258 detail::vprint_directly(os, fmt, vargs);
259}
260
262template <typename... Args>
263void print(std::wostream& os,
265 Args&&... args)
266{
267 vprint(os, fmt, fmt::make_format_args<buffer_context<wchar_t>>(args...));
268}
269
271
272#endif // FMT_OSTREAM_H_
Definition core.h:2524
Definition core.h:2338
Definition core.h:4010
Definition format.h:955
Definition printf.h:33
Definition core.h:1032
FMT_CONSTEXPR auto data() noexcept -> T *
Definition core.h:1102
constexpr auto size() const noexcept -> size_t
Definition core.h:1090
Definition ostream.h:77
friend auto get_file(BufType &obj) -> FILE *
Definition ostream.h:78
Definition format.h:284
Definition ostream.h:33
static auto test(...) -> std::false_type
decltype(test< T >(0)) result
Definition ostream.h:43
static auto test(int) -> bool_constant< sizeof(std::declval< std::basic_ostream< Char > & >()<< std::declval< U >()) !=0 >
Definition core.h:2245
Definition core.h:1598
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
Definition color.h:646
typename std::enable_if< B, T >::type enable_if_t
Definition core.h:302
std::integral_constant< bool, B > bool_constant
Definition core.h:306
basic_format_string< char, type_identity_t< Args >... > format_string
Definition core.h:4059
#define FMT_BEGIN_NAMESPACE
Definition core.h:214
#define FMT_MODULE_EXPORT
Definition core.h:225
FMT_BEGIN_DETAIL_NAMESPACE FMT_CONSTEXPR void ignore_unused(const T &...)
Definition core.h:373
FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned< Int >::type
Definition core.h:455
typename type_identity< T >::type type_identity_t
Definition core.h:319
#define FMT_END_NAMESPACE
Definition core.h:219
basic_memory_buffer< char > memory_buffer
Definition format.h:1095
Definition args.h:20
bool write_ostream_unicode(std::ostream &os, fmt::string_view data)
Definition ostream.h:92
void vprint_directly(std::ostream &os, string_view format_str, format_args args)
Definition ostream.h:221
void format_value(buffer< Char > &buf, const T &value, locale_ref loc=locale_ref())
Definition ostream.h:143
void write_buffer(std::basic_ostream< Char > &os, buffer< Char > &buf)
Definition ostream.h:127
Definition bin_to_hex.h:111
Definition uuid.h:926
auto streamed(const T &value) -> detail::streamed_view< T >
Definition ostream.h:205
basic_ostream_formatter< char > ostream_formatter
Definition ostream.h:180
FMT_MODULE_EXPORT void print(std::ostream &os, format_string< T... > fmt, T &&... args)
Definition ostream.h:252
FMT_MODULE_EXPORT void vprint(std::basic_ostream< Char > &os, basic_string_view< type_identity_t< Char > > format_str, basic_format_args< buffer_context< type_identity_t< Char > > > args)
Definition ostream.h:231
Definition ostream.h:166
void set_debug_format()=delete
auto format(const T &value, basic_format_context< OutputIt, Char > &ctx) const -> OutputIt
Definition ostream.h:170
Definition format.h:1901
Definition ostream.h:157
const T & value
Definition ostream.h:158
Definition core.h:1420
auto format(detail::streamed_view< T > view, basic_format_context< OutputIt, Char > &ctx) const -> OutputIt
Definition ostream.h:187
Definition core.h:944
Definition core.h:1434
annotation output
Definition tag_strings.h:122