8 #ifndef FMTQUILL_OSTREAM_H_ 9 #define FMTQUILL_OSTREAM_H_ 11 #ifndef FMTQUILL_MODULE 17 # include <ext/stdio_filebuf.h> 18 # include <ext/stdio_sync_filebuf.h> 25 #ifdef _MSVC_STL_UPDATE 26 # define FMTQUILL_MSVC_STL_UPDATE _MSVC_STL_UPDATE 27 #elif defined(_MSC_VER) && _MSC_VER < 1912 // VS 15.5 28 # define FMTQUILL_MSVC_STL_UPDATE _MSVC_LANG 30 # define FMTQUILL_MSVC_STL_UPDATE 0 33 FMTQUILL_BEGIN_NAMESPACE
39 struct file_access_tag {};
41 template <
typename Tag,
typename BufType, FILE* BufType::*FileMemberPtr>
43 friend auto get_file(BufType& obj) -> FILE* {
return obj.*FileMemberPtr; }
46 #if FMTQUILL_MSVC_STL_UPDATE 47 template class file_access<file_access_tag, std::filebuf,
48 &std::filebuf::_Myfile>;
49 auto get_file(std::filebuf&) -> FILE*;
54 template <
typename Char>
56 const Char* buf_data = buf.
data();
57 using unsigned_streamsize = make_unsigned_t<std::streamsize>;
58 unsigned_streamsize size = buf.
size();
59 unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
61 unsigned_streamsize n = size <= max_size ? size : max_size;
62 os.write(buf_data, static_cast<std::streamsize>(n));
74 template <
typename Char>
76 void set_debug_format() =
delete;
78 template <
typename T,
typename Context>
79 auto format(
const T& value, Context& ctx)
const -> decltype(ctx.out()) {
83 output.imbue(std::locale::classic());
85 output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
87 {buffer.data(), buffer.size()}, ctx);
93 template <
typename T,
typename Char>
96 template <
typename Context>
98 -> decltype(ctx.out()) {
111 template <
typename T>
118 detail::vformat_to(buffer, fmt, args);
120 #if FMTQUILL_MSVC_STL_UPDATE && FMTQUILL_USE_RTTI 121 if (
auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))
122 f = detail::get_file(*buf);
123 #elif defined(_WIN32) && defined(__GLIBCXX__) && FMTQUILL_USE_RTTI 124 auto* rdbuf = os.rdbuf();
125 if (
auto* sfbuf =
dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*
>(rdbuf))
127 else if (
auto* fbuf =
dynamic_cast<__gnu_cxx::stdio_filebuf<char>*
>(rdbuf))
135 if (detail::write_console(fd, {buffer.data(), buffer.size()}))
return;
139 detail::ignore_unused(f);
140 detail::write_buffer(os, buffer);
150 FMTQUILL_EXPORT
template <
typename... T>
151 void print(
std::ostream& os, format_string<T...> fmt, T&&... args) {
152 fmtquill::vargs<T...>
vargs = {{args...}};
153 if (detail::const_check(detail::use_utf8))
return vprint(os, fmt.str,
vargs);
155 detail::vformat_to(buffer, fmt.str,
vargs);
156 detail::write_buffer(os, buffer);
159 FMTQUILL_EXPORT
template <
typename... T>
160 void println(
std::ostream& os, format_string<T...> fmt, T&&... args) {
161 fmtquill::print(os, FMTQUILL_STRING(
"{}\n"),
162 fmtquill::format(fmt, std::forward<T>(args)...));
165 FMTQUILL_END_NAMESPACE
167 #endif // FMTQUILL_OSTREAM_H_ A dynamically growing memory buffer for trivially copyable/constructible types with the first SIZE el...
Definition: format.h:790
FMTQUILL_CONSTEXPR auto data() noexcept -> T *
Returns a pointer to the buffer data (not null-terminated).
Definition: base.h:1799
Definition: doctest.h:530
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
constexpr auto size() const noexcept -> size_t
Returns the size of this buffer.
Definition: base.h:1793