17template <
typename CHar>
class basic_printf_parse_context;
22template <
class Char>
class formatbuf :
public std::basic_streambuf<Char> {
24 using int_type =
typename std::basic_streambuf<Char>::int_type;
25 using traits_type =
typename std::basic_streambuf<Char>::traits_type;
27 buffer<Char>& buffer_;
30 formatbuf(buffer<Char>& buf) : buffer_(buf) {}
40 int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
41 if (!traits_type::eq_int_type(ch, traits_type::eof()))
42 buffer_.push_back(
static_cast<Char
>(ch));
46 std::streamsize xsputn(
const Char* s, std::streamsize count) FMT_OVERRIDE {
47 buffer_.append(s, s + count);
52template <
typename Char>
struct test_stream : std::basic_ostream<Char> {
55 void_t<> operator<<(null<>);
56 void_t<> operator<<(
const Char*);
58 template <
typename T, FMT_ENABLE_IF(std::is_convertible<T,
int>::value &&
59 !std::is_enum<T>::value)>
60 void_t<> operator<<(T);
65template <
typename T,
typename Char>
class is_streamable {
68 static bool_constant<!std::is_same<
decltype(std::declval<test_stream<Char>&>()
69 << std::declval<U>()),
73 template <
typename>
static std::false_type test(...);
75 using result =
decltype(test<T>(0));
78 static const bool value = result::value;
82template <
typename Char>
83void write(std::basic_ostream<Char>& os, buffer<Char>& buf) {
84 const Char* buf_data = buf.data();
85 using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
86 unsigned_streamsize size = buf.size();
87 unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
89 unsigned_streamsize n = size <= max_size ? size : max_size;
90 os.write(buf_data,
static_cast<std::streamsize
>(n));
96template <
typename Char,
typename T>
97void format_value(buffer<Char>& buf,
const T& value,
98 locale_ref loc = locale_ref()) {
99 formatbuf<Char> format_buf(buf);
100 std::basic_ostream<Char> output(&format_buf);
101#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
102 if (loc) output.imbue(loc.get<std::locale>());
104 output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
106 buf.resize(buf.size());
110template <
typename T,
typename Char>
111struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
112 :
private formatter<basic_string_view<Char>, Char> {
114 return formatter<basic_string_view<Char>, Char>::parse(ctx);
116 template <
typename ParseCtx,
117 FMT_ENABLE_IF(std::is_same<
118 ParseCtx, basic_printf_parse_context<Char>>::value)>
119 auto parse(ParseCtx& ctx) ->
decltype(ctx.begin()) {
123 template <
typename OutputIt>
124 auto format(
const T& value, basic_format_context<OutputIt, Char>& ctx)
127 format_value(buffer, value, ctx.locale());
129 return formatter<basic_string_view<Char>, Char>::format(str, ctx);
131 template <
typename OutputIt>
135 format_value(buffer, value, ctx.locale());
136 return std::copy(buffer.begin(), buffer.end(), ctx.out());
141template <
typename Char>
145 internal::vformat_to(buffer, format_str, args);
146 internal::write(os, buffer);
158template <
typename S,
typename... Args,
159 typename Char = enable_if_t<internal::is_string<S>::value, char_t<S>>>
160void print(std::basic_ostream<Char>& os,
const S& format_str, Args&&... args) {
161 vprint(os, to_string_view(format_str),
162 internal::make_args_checked<Args...>(format_str, args...));
std::size_t size() const FMT_NOEXCEPT
Definition: core.h:684
T * data() FMT_NOEXCEPT
Definition: core.h:690