diff --git a/include/fmt/core.h b/include/fmt/core.h index ed4bc45a..31fa3365 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -287,14 +287,14 @@ FMT_DISABLE_CONVERSION_TO_INT(float); FMT_DISABLE_CONVERSION_TO_INT(double); FMT_DISABLE_CONVERSION_TO_INT(long double); -template +template struct named_arg; template struct is_named_arg : std::false_type {}; -template -struct is_named_arg> : std::true_type {}; +template +struct is_named_arg> : std::true_type {}; enum type { NONE, NAMED_ARG, @@ -488,12 +488,12 @@ class value { custom.format = &format_custom_arg; } - // Additional template param `Char` is needed here because get_type always - // uses char. - template - value(const named_arg &value) { + // Additional template param `Ctx` is needed here because get_type always + // uses basic_context. + template + value(const named_arg &value) { static_assert( - get_type &>() == NAMED_ARG, "invalid type"); + get_type &>() == NAMED_ARG, "invalid type"); pointer = &value; } @@ -664,12 +664,12 @@ inline typename std::enable_if>::type template struct named_arg : basic_arg { - typedef typename Context::char_type Char; + using char_type = typename Context::char_type; - basic_string_view name; + basic_string_view name; template - named_arg(basic_string_view argname, const T &value) + named_arg(basic_string_view argname, const T &value) : basic_arg(make_arg(value)), name(argname) {} }; @@ -678,10 +678,10 @@ class arg_map { private: FMT_DISALLOW_COPY_AND_ASSIGN(arg_map); - using Char = typename Context::char_type; + using char_type = typename Context::char_type; struct arg { - fmt::basic_string_view name; + fmt::basic_string_view name; basic_arg value; }; @@ -699,7 +699,7 @@ class arg_map { ~arg_map() { delete [] map_; } const basic_arg - *find(const fmt::basic_string_view &name) const { + *find(const fmt::basic_string_view &name) const { // The list is unsorted, so just return the first matching name. for (auto it = map_, end = map_ + size_; it != end; ++it) { if (it->name == name) diff --git a/include/fmt/format.cc b/include/fmt/format.cc index e9b590a5..792ca1e4 100644 --- a/include/fmt/format.cc +++ b/include/fmt/format.cc @@ -198,7 +198,7 @@ void format_error_code(buffer &out, int error_code, ++error_code_size; } error_code_size += internal::count_digits(abs_value); - basic_writer w(out); + basic_writer w(out); if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size) { w.write(message); w.write(SEP); @@ -380,13 +380,13 @@ FMT_FUNC void internal::format_windows_error( FMT_FUNC void format_system_error( buffer &out, int error_code, string_view message) FMT_NOEXCEPT { FMT_TRY { - memory_buffer buffer; - buffer.resize(internal::INLINE_BUFFER_SIZE); + memory_buffer buf; + buf.resize(internal::INLINE_BUFFER_SIZE); for (;;) { - char *system_message = &buffer[0]; - int result = safe_strerror(error_code, system_message, buffer.size()); + char *system_message = &buf[0]; + int result = safe_strerror(error_code, system_message, buf.size()); if (result == 0) { - basic_writer w(out); + basic_writer w(out); w.write(message); w.write(": "); w.write(system_message); @@ -394,7 +394,7 @@ FMT_FUNC void format_system_error( } if (result != ERANGE) break; // Can't get error message, report error code instead. - buffer.resize(buffer.size() * 2); + buf.resize(buf.size() * 2); } } FMT_CATCH(...) {} fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. diff --git a/include/fmt/format.h b/include/fmt/format.h index 3378ff5d..1427dd7d 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -336,6 +336,8 @@ class basic_buffer { virtual void grow(std::size_t capacity) = 0; public: + using value_type = T; + virtual ~basic_buffer() {} /** Returns the size of this buffer. */ @@ -1298,13 +1300,14 @@ class arg_formatter_base { typedef basic_format_specs format_specs; private: - basic_writer writer_; + using writer_type = basic_writer>; + writer_type writer_; format_specs &specs_; FMT_DISALLOW_COPY_AND_ASSIGN(arg_formatter_base); void write_char(Char value) { - using pointer_type = typename basic_writer::pointer_type; + using pointer_type = typename writer_type::pointer_type; Char fill = internal::char_traits::cast(specs_.fill()); pointer_type out = pointer_type(); const unsigned character_width = 1; @@ -1333,7 +1336,7 @@ class arg_formatter_base { } protected: - basic_writer &writer() { return writer_; } + writer_type &writer() { return writer_; } format_specs &spec() { return specs_; } void write(bool value) { @@ -2156,39 +2159,39 @@ FMT_API void format_system_error(fmt::buffer &out, int error_code, /** \rst This template provides operations for formatting and writing data into a - character buffer. The output buffer is specified by a subclass such as - :class:`fmt::BasicMemoryWriter`. + character buffer. You can use one of the following typedefs for common character types: +---------+-----------------------+ | Type | Definition | +=========+=======================+ - | writer | basic_writer | + | writer | basic_writer | +---------+-----------------------+ - | wwriter | basic_writer | + | wwriter | basic_writer | +---------+-----------------------+ \endrst */ -template +template class basic_writer { public: - typedef basic_format_specs format_specs; + using char_type = typename Buffer::value_type; + typedef basic_format_specs format_specs; private: // Output buffer. - basic_buffer &buffer_; + Buffer &buffer_; FMT_DISALLOW_COPY_AND_ASSIGN(basic_writer); #if FMT_SECURE_SCL typedef stdext::checked_array_iterator pointer_type; // Returns pointer value. - static Char *get(pointer_type p) { return p.base(); } + static char_type *get(pointer_type p) { return p.base(); } #else - typedef Char *pointer_type; - static Char *get(Char *p) { return p; } + typedef char_type *pointer_type; + static char_type *get(char_type *p) { return p; } #endif // Fills the padding around the content and returns the pointer to the @@ -2206,9 +2209,9 @@ class basic_writer { // Writes an unsigned decimal integer. template - Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) { + char_type *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) { unsigned num_digits = internal::count_digits(value); - Char *ptr = get(grow_buffer(prefix_size + num_digits)); + char_type *ptr = get(grow_buffer(prefix_size + num_digits)); internal::format_decimal(ptr + prefix_size, value, num_digits); return ptr; } @@ -2248,30 +2251,30 @@ class basic_writer { void write_double(T value, const format_specs &spec); // Writes a formatted string. - template + template pointer_type write_str( - const StrChar *s, std::size_t size, const align_spec &spec); + const Char *s, std::size_t size, const align_spec &spec); - template - void write_str(basic_string_view str, const format_specs &spec); + template + void write_str(basic_string_view str, const format_specs &spec); // Appends floating-point length specifier to the format string. // The second argument is only used for overload resolution. - void append_float_length(Char *&format_ptr, long double) { + void append_float_length(char_type *&format_ptr, long double) { *format_ptr++ = 'L'; } template - void append_float_length(Char *&, T) {} + void append_float_length(char_type *&, T) {} - template + template friend class internal::arg_formatter_base; public: /** Constructs a ``basic_writer`` object. */ - explicit basic_writer(basic_buffer &b) : buffer_(b) {} + explicit basic_writer(Buffer &b) : buffer_(b) {} /** \rst @@ -2289,13 +2292,13 @@ class basic_writer { Returns a pointer to the output buffer content. No terminating null character is appended. */ - const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; } + const char_type *data() const FMT_NOEXCEPT { return &buffer_[0]; } /** Returns a pointer to the output buffer content with terminating null character appended. */ - const Char *c_str() const { + const char_type *c_str() const { std::size_t size = buffer_.size(); buffer_.reserve(size + 1); buffer_[size] = '\0'; @@ -2307,8 +2310,8 @@ class basic_writer { Returns the content of the output buffer as an `std::string`. \endrst */ - std::basic_string str() const { - return std::basic_string(&buffer_[0], buffer_.size()); + std::basic_string str() const { + return std::basic_string(&buffer_[0], buffer_.size()); } void write(int value) { @@ -2354,7 +2357,7 @@ class basic_writer { } void write(wchar_t value) { - internal::require_wchar(); + internal::require_wchar(); buffer_.push_back(value); } @@ -2369,29 +2372,29 @@ class basic_writer { } void write(basic_string_view value) { - internal::require_wchar(); + internal::require_wchar(); const wchar_t *str = value.data(); buffer_.append(str, str + value.size()); } template - void write(basic_string_view str, FormatSpecs... specs) { + void write(basic_string_view str, FormatSpecs... specs) { write_str(str, format_specs(specs...)); } void clear() FMT_NOEXCEPT { buffer_.resize(0); } - basic_buffer &buffer() FMT_NOEXCEPT { return buffer_; } + Buffer &buffer() FMT_NOEXCEPT { return buffer_; } }; +template template -template -typename basic_writer::pointer_type basic_writer::write_str( - const StrChar *s, std::size_t size, const align_spec &spec) { +typename basic_writer::pointer_type basic_writer::write_str( + const Char *s, std::size_t size, const align_spec &spec) { pointer_type out = pointer_type(); if (spec.width() > size) { out = grow_buffer(spec.width()); - Char fill = internal::char_traits::cast(spec.fill()); + char_type fill = internal::char_traits::cast(spec.fill()); if (spec.align() == ALIGN_RIGHT) { std::uninitialized_fill_n(out, spec.width() - size, fill); out += spec.width() - size; @@ -2407,13 +2410,13 @@ typename basic_writer::pointer_type basic_writer::write_str( return out; } +template template -template -void basic_writer::write_str( - basic_string_view s, const format_specs &spec) { - // Check if StrChar is convertible to Char. - internal::char_traits::convert(StrChar()); - const StrChar *str_value = s.data(); +void basic_writer::write_str( + basic_string_view s, const format_specs &spec) { + // Check if Char is convertible to char_type. + internal::char_traits::convert(Char()); + const Char *str_value = s.data(); std::size_t str_size = s.size(); if (str_size == 0 && !str_value) FMT_THROW(format_error("string pointer is null")); @@ -2423,13 +2426,13 @@ void basic_writer::write_str( write_str(str_value, str_size, spec); } -template -typename basic_writer::pointer_type basic_writer::fill_padding( +template +typename basic_writer::pointer_type basic_writer::fill_padding( pointer_type buffer, unsigned total_size, std::size_t content_size, wchar_t fill) { std::size_t padding = total_size - content_size; std::size_t left_padding = padding / 2; - Char fill_char = internal::char_traits::cast(fill); + char_type fill_char = internal::char_traits::cast(fill); std::uninitialized_fill_n(buffer, left_padding, fill_char); buffer += left_padding; pointer_type content = buffer; @@ -2438,15 +2441,15 @@ typename basic_writer::pointer_type basic_writer::fill_padding( return content; } -template +template template -typename basic_writer::pointer_type - basic_writer::prepare_int_buffer( +typename basic_writer::pointer_type + basic_writer::prepare_int_buffer( unsigned num_digits, const Spec &spec, const char *prefix, unsigned prefix_size) { unsigned width = spec.width(); alignment align = spec.align(); - Char fill = internal::char_traits::cast(spec.fill()); + char_type fill = internal::char_traits::cast(spec.fill()); if (spec.precision() > static_cast(num_digits)) { // Octal prefix '0' is counted as a digit, so ignore it if precision // is specified. @@ -2502,18 +2505,18 @@ typename basic_writer::pointer_type return p - 1; } -template +template template -void basic_writer::write_int(T value, const Spec& spec) { +void basic_writer::write_int(T value, const Spec& spec) { using unsigned_type = typename internal::int_traits::main_type; struct spec_handler { - basic_writer &writer; + basic_writer &writer; const Spec& spec; unsigned prefix_size = 0; unsigned_type abs_value; char prefix[4] = ""; - spec_handler(basic_writer &w, T val, const Spec& s) + spec_handler(basic_writer &w, T val, const Spec& s) : writer(w), spec(s), abs_value(static_cast(val)) { if (internal::is_negative(val)) { prefix[0] = '-'; @@ -2542,7 +2545,7 @@ void basic_writer::write_int(T value, const Spec& spec) { do { ++num_digits; } while ((n >>= 4) != 0); - Char *p = + char_type *p = get(writer.prepare_int_buffer(num_digits, spec, prefix, prefix_size)); n = abs_value; const char *digits = spec.type() == 'x' ? @@ -2562,11 +2565,11 @@ void basic_writer::write_int(T value, const Spec& spec) { do { ++num_digits; } while ((n >>= 1) != 0); - Char *p = + char_type *p = get(writer.prepare_int_buffer(num_digits, spec, prefix, prefix_size)); n = abs_value; do { - *p-- = static_cast('0' + (n & 1)); + *p-- = static_cast('0' + (n & 1)); } while ((n >>= 1) != 0); } @@ -2578,24 +2581,24 @@ void basic_writer::write_int(T value, const Spec& spec) { do { ++num_digits; } while ((n >>= 3) != 0); - Char *p = + char_type *p = get(writer.prepare_int_buffer(num_digits, spec, prefix, prefix_size)); n = abs_value; do { - *p-- = static_cast('0' + (n & 7)); + *p-- = static_cast('0' + (n & 7)); } while ((n >>= 3) != 0); } void on_num() { unsigned num_digits = internal::count_digits(abs_value); - Char thousands_sep = internal::thousands_sep(writer.buffer_); - fmt::basic_string_view sep(&thousands_sep, 1); + char_type thousands_sep = internal::thousands_sep(writer.buffer_); + fmt::basic_string_view sep(&thousands_sep, 1); unsigned size = static_cast( num_digits + sep.size() * ((num_digits - 1) / 3)); pointer_type p = writer.prepare_int_buffer(size, spec, prefix, prefix_size) + 1; internal::format_decimal(get(p), abs_value, 0, - internal::add_thousands_sep(sep)); + internal::add_thousands_sep(sep)); } void on_error() { @@ -2605,9 +2608,9 @@ void basic_writer::write_int(T value, const Spec& spec) { internal::handle_int_type_spec(spec.type(), spec_handler(*this, value, spec)); } -template +template template -void basic_writer::write_double(T value, const format_specs &spec) { +void basic_writer::write_double(T value, const format_specs &spec) { // Check type. struct spec_handler { char type; @@ -2700,8 +2703,8 @@ void basic_writer::write_double(T value, const format_specs &spec) { // Build format string. enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg - Char format[MAX_FORMAT_SIZE]; - Char *format_ptr = format; + char_type format[MAX_FORMAT_SIZE]; + char_type *format_ptr = format; *format_ptr++ = '%'; unsigned width_for_sprintf = width; if (spec.flag(HASH_FLAG)) @@ -2724,9 +2727,9 @@ void basic_writer::write_double(T value, const format_specs &spec) { *format_ptr = '\0'; // Format using snprintf. - Char fill = internal::char_traits::cast(spec.fill()); + char_type fill = internal::char_traits::cast(spec.fill()); unsigned n = 0; - Char *start = 0; + char_type *start = 0; for (;;) { std::size_t buffer_size = buffer_.capacity() - offset; #if FMT_MSC_VER @@ -2739,7 +2742,7 @@ void basic_writer::write_double(T value, const format_specs &spec) { } #endif start = &buffer_[offset]; - int result = internal::char_traits::format_float( + int result = internal::char_traits::format_float( start, buffer_size, format, width_for_sprintf, spec.precision(), value); if (result >= 0) { n = internal::to_unsigned(result); @@ -2765,7 +2768,7 @@ void basic_writer::write_double(T value, const format_specs &spec) { if (spec.align() == ALIGN_CENTER && spec.width() > n) { width = spec.width(); pointer_type p = grow_buffer(width); - std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(Char)); + std::memmove(get(p) + (width - n) / 2, get(p), n * sizeof(char_type)); fill_padding(p, spec.width(), n, fill); return; } diff --git a/include/fmt/string.h b/include/fmt/string.h index 1f1d8339..62db9225 100644 --- a/include/fmt/string.h +++ b/include/fmt/string.h @@ -84,7 +84,7 @@ typedef basic_string_buffer wstring_buffer; template std::string to_string(const T &value) { string_buffer buf; - basic_writer(buf).write(value); + basic_writer(buf).write(value); std::string str; buf.move_to(str); return str; diff --git a/test/format-test.cc b/test/format-test.cc index 57945a3e..a021828f 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -31,12 +31,9 @@ #include #include #include +#include #include -#if FMT_USE_TYPE_TRAITS -# include -#endif - #include "gmock/gmock.h" // Test that the library compiles if None is defined to 0 as done by xlib.h. @@ -92,7 +89,7 @@ void std_format(long double value, std::wstring &result) { template ::testing::AssertionResult check_write(const T &value, const char *type) { fmt::basic_memory_buffer buffer; - fmt::basic_writer writer(buffer); + fmt::basic_writer> writer(buffer); writer.write(value); std::basic_string actual = writer.str(); std::basic_string expected; @@ -144,19 +141,17 @@ TEST(StringViewTest, ConvertToString) { EXPECT_EQ("abc", s); } -#if FMT_USE_TYPE_TRAITS TEST(WriterTest, NotCopyConstructible) { - EXPECT_FALSE(std::is_copy_constructible >::value); + EXPECT_FALSE(std::is_copy_constructible>::value); } TEST(WriterTest, NotCopyAssignable) { - EXPECT_FALSE(std::is_copy_assignable >::value); + EXPECT_FALSE(std::is_copy_assignable>::value); } -#endif TEST(WriterTest, Ctor) { memory_buffer buf; - fmt::basic_writer w(buf); + fmt::basic_writer w(buf); EXPECT_EQ(0u, w.size()); EXPECT_STREQ("", w.c_str()); EXPECT_EQ("", w.str()); @@ -164,7 +159,7 @@ TEST(WriterTest, Ctor) { TEST(WriterTest, Data) { memory_buffer buf; - fmt::basic_writer w(buf); + fmt::basic_writer w(buf); w.write(42); EXPECT_EQ("42", std::string(w.data(), w.size())); } @@ -217,14 +212,14 @@ TEST(WriterTest, WriteLongDouble) { TEST(WriterTest, WriteDoubleAtBufferBoundary) { memory_buffer buf; - fmt::basic_writer writer(buf); + fmt::basic_writer writer(buf); for (int i = 0; i < 100; ++i) writer.write(1.23456789); } TEST(WriterTest, WriteDoubleWithFilledBuffer) { memory_buffer buf; - fmt::basic_writer writer(buf); + fmt::basic_writer writer(buf); // Fill the buffer. for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i) writer.write(' '); @@ -256,7 +251,7 @@ TEST(WriterTest, WriteWideString) { template std::string write_str(T... args) { memory_buffer buf; - fmt::basic_writer writer(buf); + fmt::basic_writer writer(buf); using namespace fmt; writer.write(args...); return writer.str(); @@ -265,7 +260,7 @@ std::string write_str(T... args) { template std::wstring write_wstr(T... args) { wmemory_buffer buf; - fmt::basic_writer writer(buf); + fmt::basic_writer writer(buf); using namespace fmt; writer.write(args...); return writer.str(); @@ -356,7 +351,7 @@ TEST(WriterTest, pad) { EXPECT_EQ(" 44", write_str(44ull, width=7)); memory_buffer buf; - fmt::basic_writer w(buf); + fmt::basic_writer w(buf); w.clear(); w.write(42, fmt::width=5, fmt::fill='0'); EXPECT_EQ("00042", w.str());