Pass buffer instead of writer to format_value
This commit is contained in:
parent
6e568f3a08
commit
fefaf07b6f
@ -106,7 +106,7 @@ inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
|
|||||||
|
|
||||||
const char RESET_COLOR[] = "\x1b[0m";
|
const char RESET_COLOR[] = "\x1b[0m";
|
||||||
|
|
||||||
typedef void (*FormatFunc)(writer &, int, StringRef);
|
typedef void (*FormatFunc)(buffer &, int, StringRef);
|
||||||
|
|
||||||
// Portable thread-safe version of strerror.
|
// Portable thread-safe version of strerror.
|
||||||
// Sets buffer to point to a string describing the error code.
|
// Sets buffer to point to a string describing the error code.
|
||||||
@ -176,7 +176,7 @@ int safe_strerror(
|
|||||||
return StrError(error_code, buffer, buffer_size).run();
|
return StrError(error_code, buffer, buffer_size).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_error_code(writer &out, int error_code,
|
void format_error_code(buffer &out, int error_code,
|
||||||
StringRef message) FMT_NOEXCEPT {
|
StringRef message) FMT_NOEXCEPT {
|
||||||
// Report error code making sure that the output fits into
|
// Report error code making sure that the output fits into
|
||||||
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
|
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
|
||||||
@ -193,18 +193,19 @@ void format_error_code(writer &out, int error_code,
|
|||||||
++error_code_size;
|
++error_code_size;
|
||||||
}
|
}
|
||||||
error_code_size += internal::count_digits(abs_value);
|
error_code_size += internal::count_digits(abs_value);
|
||||||
|
basic_writer<char> w(out);
|
||||||
if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size) {
|
if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size) {
|
||||||
out.write(message);
|
w.write(message);
|
||||||
out.write(SEP);
|
w.write(SEP);
|
||||||
}
|
}
|
||||||
out.write(ERROR_STR);
|
w.write(ERROR_STR);
|
||||||
out.write(error_code);
|
w.write(error_code);
|
||||||
assert(out.size() <= internal::INLINE_BUFFER_SIZE);
|
assert(out.size() <= internal::INLINE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_error(FormatFunc func, int error_code,
|
void report_error(FormatFunc func, int error_code,
|
||||||
StringRef message) FMT_NOEXCEPT {
|
StringRef message) FMT_NOEXCEPT {
|
||||||
MemoryWriter full_message;
|
internal::MemoryBuffer<char> full_message;
|
||||||
func(full_message, error_code, message);
|
func(full_message, error_code, message);
|
||||||
// Use Writer::data instead of Writer::c_str to avoid potential memory
|
// Use Writer::data instead of Writer::c_str to avoid potential memory
|
||||||
// allocation.
|
// allocation.
|
||||||
@ -213,23 +214,13 @@ void report_error(FormatFunc func, int error_code,
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
// This method is used to preserve binary compatibility with fmt 3.0.
|
|
||||||
// It can be removed in 4.0.
|
|
||||||
FMT_FUNC void format_system_error(
|
|
||||||
writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
|
|
||||||
fmt::format_system_error(out, error_code, message);
|
|
||||||
}
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
FMT_FUNC void SystemError::init(
|
FMT_FUNC void SystemError::init(
|
||||||
int err_code, CStringRef format_str, args args) {
|
int err_code, CStringRef format_str, args args) {
|
||||||
error_code_ = err_code;
|
error_code_ = err_code;
|
||||||
MemoryWriter w;
|
internal::MemoryBuffer<char> buf;
|
||||||
format_system_error(w, err_code, vformat(format_str, args));
|
format_system_error(buf, err_code, vformat(format_str, args));
|
||||||
std::runtime_error &base = *this;
|
std::runtime_error &base = *this;
|
||||||
base = std::runtime_error(w.str());
|
base = std::runtime_error(to_string(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -388,7 +379,7 @@ FMT_FUNC void internal::format_windows_error(
|
|||||||
#endif // FMT_USE_WINDOWS_H
|
#endif // FMT_USE_WINDOWS_H
|
||||||
|
|
||||||
FMT_FUNC void format_system_error(
|
FMT_FUNC void format_system_error(
|
||||||
writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
|
buffer &out, int error_code, StringRef message) FMT_NOEXCEPT {
|
||||||
FMT_TRY {
|
FMT_TRY {
|
||||||
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> buffer;
|
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> buffer;
|
||||||
buffer.resize(internal::INLINE_BUFFER_SIZE);
|
buffer.resize(internal::INLINE_BUFFER_SIZE);
|
||||||
@ -396,9 +387,10 @@ FMT_FUNC void format_system_error(
|
|||||||
char *system_message = &buffer[0];
|
char *system_message = &buffer[0];
|
||||||
int result = safe_strerror(error_code, system_message, buffer.size());
|
int result = safe_strerror(error_code, system_message, buffer.size());
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
out.write(message);
|
basic_writer<char> w(out);
|
||||||
out.write(": ");
|
w.write(message);
|
||||||
out.write(system_message);
|
w.write(": ");
|
||||||
|
w.write(system_message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (result != ERANGE)
|
if (result != ERANGE)
|
||||||
@ -410,7 +402,7 @@ FMT_FUNC void format_system_error(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
void internal::FixedBuffer<Char>::grow(std::size_t) {
|
void FixedBuffer<Char>::grow(std::size_t) {
|
||||||
FMT_THROW(std::runtime_error("buffer overflow"));
|
FMT_THROW(std::runtime_error("buffer overflow"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,9 +421,9 @@ FMT_FUNC void report_windows_error(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_FUNC void vprint(std::FILE *f, CStringRef format_str, args args) {
|
FMT_FUNC void vprint(std::FILE *f, CStringRef format_str, args args) {
|
||||||
MemoryWriter w;
|
internal::MemoryBuffer<char> buffer;
|
||||||
w.vformat(format_str, args);
|
vformat_to(buffer, format_str, args);
|
||||||
std::fwrite(w.data(), 1, w.size(), f);
|
std::fwrite(buffer.data(), 1, buffer.size(), f);
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void vprint(CStringRef format_str, args args) {
|
FMT_FUNC void vprint(CStringRef format_str, args args) {
|
||||||
@ -451,10 +443,11 @@ void printf(basic_writer<Char> &w, BasicCStringRef<Char> format,
|
|||||||
args args);
|
args args);
|
||||||
|
|
||||||
FMT_FUNC int vfprintf(std::FILE *f, CStringRef format, printf_args args) {
|
FMT_FUNC int vfprintf(std::FILE *f, CStringRef format, printf_args args) {
|
||||||
MemoryWriter w;
|
internal::MemoryBuffer<char> buffer;
|
||||||
printf(w, format, args);
|
printf(buffer, format, args);
|
||||||
std::size_t size = w.size();
|
std::size_t size = buffer.size();
|
||||||
return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
|
return std::fwrite(
|
||||||
|
buffer.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
@ -463,11 +456,11 @@ template struct internal::BasicData<void>;
|
|||||||
|
|
||||||
// Explicit instantiations for char.
|
// Explicit instantiations for char.
|
||||||
|
|
||||||
template void internal::FixedBuffer<char>::grow(std::size_t);
|
template void FixedBuffer<char>::grow(std::size_t);
|
||||||
|
|
||||||
template void internal::ArgMap<context>::init(const args &args);
|
template void internal::ArgMap<context>::init(const args &args);
|
||||||
|
|
||||||
template void printf_context<char>::format(writer &writer);
|
template void printf_context<char>::format(buffer &);
|
||||||
|
|
||||||
template int internal::CharTraits<char>::format_float(
|
template int internal::CharTraits<char>::format_float(
|
||||||
char *buffer, std::size_t size, const char *format,
|
char *buffer, std::size_t size, const char *format,
|
||||||
@ -481,11 +474,11 @@ template int internal::CharTraits<char>::format_float(
|
|||||||
|
|
||||||
template class basic_context<wchar_t>;
|
template class basic_context<wchar_t>;
|
||||||
|
|
||||||
template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
|
template void FixedBuffer<wchar_t>::grow(std::size_t);
|
||||||
|
|
||||||
template void internal::ArgMap<wcontext>::init(const wargs &args);
|
template void internal::ArgMap<wcontext>::init(const wargs &args);
|
||||||
|
|
||||||
template void printf_context<wchar_t>::format(wwriter &writer);
|
template void printf_context<wchar_t>::format(wbuffer &);
|
||||||
|
|
||||||
template int internal::CharTraits<wchar_t>::format_float(
|
template int internal::CharTraits<wchar_t>::format_float(
|
||||||
wchar_t *buffer, std::size_t size, const wchar_t *format,
|
wchar_t *buffer, std::size_t size, const wchar_t *format,
|
||||||
|
197
fmt/format.h
197
fmt/format.h
@ -365,10 +365,13 @@ using std::move;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class basic_writer;
|
class basic_buffer;
|
||||||
|
|
||||||
typedef basic_writer<char> writer;
|
typedef basic_buffer<char> buffer;
|
||||||
typedef basic_writer<wchar_t> wwriter;
|
typedef basic_buffer<wchar_t> wbuffer;
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
class basic_writer;
|
||||||
|
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
class basic_arg;
|
class basic_arg;
|
||||||
@ -616,6 +619,9 @@ class basic_buffer {
|
|||||||
/** Returns the capacity of this buffer. */
|
/** Returns the capacity of this buffer. */
|
||||||
std::size_t capacity() const { return capacity_; }
|
std::size_t capacity() const { return capacity_; }
|
||||||
|
|
||||||
|
/** Returns a pointer to the buffer data. */
|
||||||
|
const T *data() const { return ptr_; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Resizes the buffer. If T is a POD type new elements may not be initialized.
|
Resizes the buffer. If T is a POD type new elements may not be initialized.
|
||||||
*/
|
*/
|
||||||
@ -662,11 +668,17 @@ void basic_buffer<T>::append(const U *begin, const U *end) {
|
|||||||
size_ = new_size;
|
size_ = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
inline std::basic_string<Char> to_string(const basic_buffer<Char>& buffer) {
|
||||||
|
return std::basic_string<Char>(buffer.data(), buffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// A memory buffer for trivially copyable/constructible types with the first
|
// A memory buffer for trivially copyable/constructible types with the first
|
||||||
// SIZE elements stored in the object itself.
|
// SIZE elements stored in the object itself.
|
||||||
template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> >
|
template <typename T, std::size_t SIZE = INLINE_BUFFER_SIZE,
|
||||||
|
typename Allocator = std::allocator<T> >
|
||||||
class MemoryBuffer : private Allocator, public basic_buffer<T> {
|
class MemoryBuffer : private Allocator, public basic_buffer<T> {
|
||||||
private:
|
private:
|
||||||
T data_[SIZE];
|
T data_[SIZE];
|
||||||
@ -741,17 +753,6 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
|
|||||||
Allocator::deallocate(old_ptr, old_capacity);
|
Allocator::deallocate(old_ptr, old_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A fixed-size buffer.
|
|
||||||
template <typename Char>
|
|
||||||
class FixedBuffer : public fmt::basic_buffer<Char> {
|
|
||||||
public:
|
|
||||||
FixedBuffer(Char *array, std::size_t size)
|
|
||||||
: fmt::basic_buffer<Char>(array, size) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FMT_API void grow(std::size_t size);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class BasicCharTraits {
|
class BasicCharTraits {
|
||||||
public:
|
public:
|
||||||
@ -988,7 +989,7 @@ class UTF16ToUTF8 {
|
|||||||
FMT_API int convert(WStringRef s);
|
FMT_API int convert(WStringRef s);
|
||||||
};
|
};
|
||||||
|
|
||||||
FMT_API void format_windows_error(fmt::writer &out, int error_code,
|
FMT_API void format_windows_error(fmt::buffer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT;
|
fmt::StringRef message) FMT_NOEXCEPT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1085,7 +1086,7 @@ struct string_value {
|
|||||||
template <typename Char>
|
template <typename Char>
|
||||||
struct CustomValue {
|
struct CustomValue {
|
||||||
typedef void (*FormatFunc)(
|
typedef void (*FormatFunc)(
|
||||||
basic_writer<Char> &writer, const void *arg, void *ctx);
|
basic_buffer<Char> &buffer, const void *arg, void *ctx);
|
||||||
|
|
||||||
const void *value;
|
const void *value;
|
||||||
FormatFunc format;
|
FormatFunc format;
|
||||||
@ -1207,8 +1208,8 @@ class value {
|
|||||||
// Formats an argument of a custom type, such as a user-defined class.
|
// Formats an argument of a custom type, such as a user-defined class.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void format_custom_arg(
|
static void format_custom_arg(
|
||||||
basic_writer<Char> &writer, const void *arg, void *context) {
|
basic_buffer<Char> &buffer, const void *arg, void *context) {
|
||||||
format_value(writer, *static_cast<const T*>(arg),
|
format_value(buffer, *static_cast<const T*>(arg),
|
||||||
*static_cast<Context*>(context));
|
*static_cast<Context*>(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1464,7 +1465,7 @@ inline fmt::StringRef thousands_sep(...) { return ""; }
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Formatter, typename T, typename Char>
|
template <typename Formatter, typename T, typename Char>
|
||||||
void format_value(basic_writer<Char> &, const T &, Formatter &, const Char *) {
|
void format_value(basic_buffer<Char> &, const T &, Formatter &, const Char *) {
|
||||||
FMT_STATIC_ASSERT(False<T>::value,
|
FMT_STATIC_ASSERT(False<T>::value,
|
||||||
"Cannot format argument. To enable the use of ostream "
|
"Cannot format argument. To enable the use of ostream "
|
||||||
"operator<< include fmt/ostream.h. Otherwise provide "
|
"operator<< include fmt/ostream.h. Otherwise provide "
|
||||||
@ -1858,7 +1859,7 @@ class ArgFormatterBase {
|
|||||||
typedef basic_format_specs<Char> format_specs;
|
typedef basic_format_specs<Char> format_specs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
basic_writer<Char> &writer_;
|
basic_writer<Char> writer_;
|
||||||
format_specs &spec_;
|
format_specs &spec_;
|
||||||
|
|
||||||
FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase);
|
FMT_DISALLOW_COPY_AND_ASSIGN(ArgFormatterBase);
|
||||||
@ -1901,8 +1902,8 @@ class ArgFormatterBase {
|
|||||||
public:
|
public:
|
||||||
typedef Char char_type;
|
typedef Char char_type;
|
||||||
|
|
||||||
ArgFormatterBase(basic_writer<Char> &w, format_specs &s)
|
ArgFormatterBase(basic_buffer<Char> &b, format_specs &s)
|
||||||
: writer_(w), spec_(s) {}
|
: writer_(b), spec_(s) {}
|
||||||
|
|
||||||
void operator()(monostate) {
|
void operator()(monostate) {
|
||||||
FMT_ASSERT(false, "invalid argument type");
|
FMT_ASSERT(false, "invalid argument type");
|
||||||
@ -1973,12 +1974,6 @@ class ArgFormatterBase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
inline void write(basic_writer<Char> &w, const Char *start, const Char *end) {
|
|
||||||
if (start != end)
|
|
||||||
w.write(BasicStringRef<Char>(start, internal::to_unsigned(end - start)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char, typename Context>
|
template <typename Char, typename Context>
|
||||||
class context_base {
|
class context_base {
|
||||||
private:
|
private:
|
||||||
@ -2047,20 +2042,20 @@ class ArgFormatter : public internal::ArgFormatterBase<Char> {
|
|||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Constructs an argument formatter object.
|
Constructs an argument formatter object.
|
||||||
*writer* is a reference to the writer to be used for output,
|
*buffer* is a reference to the buffer to be used for output,
|
||||||
*ctx* is a reference to the formatting context, *spec* contains
|
*ctx* is a reference to the formatting context, *spec* contains
|
||||||
format specifier information for standard argument types.
|
format specifier information for standard argument types.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
ArgFormatter(basic_writer<Char> &writer, basic_context<Char> &ctx,
|
ArgFormatter(basic_buffer<Char> &buffer, basic_context<Char> &ctx,
|
||||||
format_specs &spec)
|
format_specs &spec)
|
||||||
: internal::ArgFormatterBase<Char>(writer, spec), ctx_(ctx) {}
|
: internal::ArgFormatterBase<Char>(buffer, spec), ctx_(ctx) {}
|
||||||
|
|
||||||
using internal::ArgFormatterBase<Char>::operator();
|
using internal::ArgFormatterBase<Char>::operator();
|
||||||
|
|
||||||
/** Formats an argument of a custom (user-defined) type. */
|
/** Formats an argument of a custom (user-defined) type. */
|
||||||
void operator()(internal::CustomValue<Char> c) {
|
void operator()(internal::CustomValue<Char> c) {
|
||||||
c.format(this->writer(), c.value, &ctx_);
|
c.format(this->writer().buffer(), c.value, &ctx_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2160,7 +2155,7 @@ class SystemError : public internal::RuntimeError {
|
|||||||
may look like "Unknown error -1" and is platform-dependent.
|
may look like "Unknown error -1" and is platform-dependent.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
FMT_API void format_system_error(fmt::writer &out, int error_code,
|
FMT_API void format_system_error(fmt::buffer &out, int error_code,
|
||||||
fmt::StringRef message) FMT_NOEXCEPT;
|
fmt::StringRef message) FMT_NOEXCEPT;
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
@ -2298,13 +2293,12 @@ class basic_writer {
|
|||||||
template <typename Char_>
|
template <typename Char_>
|
||||||
friend class PrintfArgFormatter;
|
friend class PrintfArgFormatter;
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
/**
|
/**
|
||||||
Constructs a ``basic_writer`` object.
|
Constructs a ``basic_writer`` object.
|
||||||
*/
|
*/
|
||||||
explicit basic_writer(basic_buffer<Char> &b) : buffer_(b) {}
|
explicit basic_writer(basic_buffer<Char> &b) : buffer_(b) {}
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Destroys a ``basic_writer`` object.
|
Destroys a ``basic_writer`` object.
|
||||||
@ -2343,38 +2337,6 @@ class basic_writer {
|
|||||||
return std::basic_string<Char>(&buffer_[0], buffer_.size());
|
return std::basic_string<Char>(&buffer_[0], buffer_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void vformat(BasicCStringRef<Char> format,
|
|
||||||
basic_args<basic_context<Char>> args);
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Writes formatted data.
|
|
||||||
|
|
||||||
*args* is an argument list representing arbitrary arguments.
|
|
||||||
|
|
||||||
**Example**::
|
|
||||||
|
|
||||||
MemoryWriter out;
|
|
||||||
out.format("Current point:\n");
|
|
||||||
out.format("({:+f}, {:+f})", -3.14, 3.14);
|
|
||||||
|
|
||||||
This will write the following output to the ``out`` object:
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
Current point:
|
|
||||||
(-3.140000, +3.140000)
|
|
||||||
|
|
||||||
The output can be accessed using :func:`data()`, :func:`c_str` or
|
|
||||||
:func:`str` methods.
|
|
||||||
|
|
||||||
See also :ref:`syntax`.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
template <typename... Args>
|
|
||||||
void format(BasicCStringRef<Char> format, const Args & ... args) {
|
|
||||||
vformat(format, make_args<basic_context<Char>>(args...));
|
|
||||||
}
|
|
||||||
|
|
||||||
void write(int value) {
|
void write(int value) {
|
||||||
write_decimal(value);
|
write_decimal(value);
|
||||||
}
|
}
|
||||||
@ -2881,6 +2843,23 @@ class BasicMemoryWriter : public basic_writer<Char> {
|
|||||||
typedef BasicMemoryWriter<char> MemoryWriter;
|
typedef BasicMemoryWriter<char> MemoryWriter;
|
||||||
typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
|
typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
|
||||||
|
|
||||||
|
// A fixed-size buffer.
|
||||||
|
template <typename Char>
|
||||||
|
class FixedBuffer : public fmt::basic_buffer<Char> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Constructs a :class:`fmt::FixedBuffer` object for *array* of the
|
||||||
|
given size.
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
FixedBuffer(Char *array, std::size_t size)
|
||||||
|
: fmt::basic_buffer<Char>(array, size) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FMT_API void grow(std::size_t size);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
This class template provides operations for formatting and writing data
|
This class template provides operations for formatting and writing data
|
||||||
@ -2904,15 +2883,9 @@ typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
|
|||||||
template <typename Char>
|
template <typename Char>
|
||||||
class BasicArrayWriter : public basic_writer<Char> {
|
class BasicArrayWriter : public basic_writer<Char> {
|
||||||
private:
|
private:
|
||||||
internal::FixedBuffer<Char> buffer_;
|
FixedBuffer<Char> buffer_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
|
|
||||||
given size.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
BasicArrayWriter(Char *array, std::size_t size)
|
BasicArrayWriter(Char *array, std::size_t size)
|
||||||
: basic_writer<Char>(buffer_), buffer_(array, size) {}
|
: basic_writer<Char>(buffer_), buffer_(array, size) {}
|
||||||
|
|
||||||
@ -3000,10 +2973,34 @@ inline void print_colored(Color c, CStringRef format_str,
|
|||||||
vprint_colored(c, format_str, make_args(args...));
|
vprint_colored(c, format_str, make_args(args...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename ArgFormatter, typename Char, typename Context>
|
||||||
|
void vformat_to(basic_buffer<Char> &buffer, BasicCStringRef<Char> format_str,
|
||||||
|
basic_args<Context> args);
|
||||||
|
|
||||||
|
inline void vformat_to(buffer &buf, CStringRef format_str, args args) {
|
||||||
|
vformat_to<ArgFormatter<char>>(buf, format_str, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void vformat_to(wbuffer &buf, WCStringRef format_str, wargs args) {
|
||||||
|
vformat_to<ArgFormatter<wchar_t>>(buf, format_str, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
inline void format_to(buffer &buf, CStringRef format_str,
|
||||||
|
const Args & ... args) {
|
||||||
|
vformat_to(buf, format_str, make_args(args...));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
inline void format_to(wbuffer &buf, WCStringRef format_str,
|
||||||
|
const Args & ... args) {
|
||||||
|
vformat_to(buf, format_str, make_args<wcontext>(args...));
|
||||||
|
}
|
||||||
|
|
||||||
inline std::string vformat(CStringRef format_str, args args) {
|
inline std::string vformat(CStringRef format_str, args args) {
|
||||||
MemoryWriter w;
|
internal::MemoryBuffer<char> buffer;
|
||||||
w.vformat(format_str, args);
|
vformat_to(buffer, format_str, args);
|
||||||
return w.str();
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3021,15 +3018,14 @@ inline std::string format(CStringRef format_str, const Args & ... args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::wstring vformat(WCStringRef format_str, wargs args) {
|
inline std::wstring vformat(WCStringRef format_str, wargs args) {
|
||||||
WMemoryWriter w;
|
internal::MemoryBuffer<wchar_t> buffer;
|
||||||
w.vformat(format_str, args);
|
vformat_to(buffer, format_str, args);
|
||||||
return w.str();
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
inline std::wstring format(WCStringRef format_str, const Args & ... args) {
|
inline std::wstring format(WCStringRef format_str, const Args & ... args) {
|
||||||
auto vargs = make_args<wcontext>(args...);
|
return vformat(format_str, make_args<wcontext>(args...));
|
||||||
return vformat(format_str, vargs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_API void vprint(std::FILE *f, CStringRef format_str, args args);
|
FMT_API void vprint(std::FILE *f, CStringRef format_str, args args);
|
||||||
@ -3273,15 +3269,15 @@ void check_sign(const Char *&s, const basic_arg<Context> &arg) {
|
|||||||
template <typename Char, typename Context>
|
template <typename Char, typename Context>
|
||||||
class CustomFormatter {
|
class CustomFormatter {
|
||||||
private:
|
private:
|
||||||
basic_writer<Char> &writer_;
|
basic_buffer<Char> &buffer_;
|
||||||
Context &ctx_;
|
Context &ctx_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CustomFormatter(basic_writer<Char> &writer, Context &ctx)
|
CustomFormatter(basic_buffer<Char> &buffer, Context &ctx)
|
||||||
: writer_(writer), ctx_(ctx) {}
|
: buffer_(buffer), ctx_(ctx) {}
|
||||||
|
|
||||||
bool operator()(internal::CustomValue<Char> custom) {
|
bool operator()(internal::CustomValue<Char> custom) {
|
||||||
custom.format(writer_, custom.value, &ctx_);
|
custom.format(buffer_, custom.value, &ctx_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3374,12 +3370,12 @@ inline typename basic_context<Char>::format_arg
|
|||||||
|
|
||||||
// Formats a single argument.
|
// Formats a single argument.
|
||||||
template <typename ArgFormatter, typename Char, typename Context>
|
template <typename ArgFormatter, typename Char, typename Context>
|
||||||
void do_format_arg(basic_writer<Char> &writer, basic_arg<Context> arg,
|
void do_format_arg(basic_buffer<Char> &buffer, basic_arg<Context> arg,
|
||||||
Context &ctx) {
|
Context &ctx) {
|
||||||
const Char *&s = ctx.ptr();
|
const Char *&s = ctx.ptr();
|
||||||
basic_format_specs<Char> spec;
|
basic_format_specs<Char> spec;
|
||||||
if (*s == ':') {
|
if (*s == ':') {
|
||||||
if (visit(internal::CustomFormatter<Char, Context>(writer, ctx), arg))
|
if (visit(internal::CustomFormatter<Char, Context>(buffer, ctx), arg))
|
||||||
return;
|
return;
|
||||||
++s;
|
++s;
|
||||||
// Parse fill and alignment.
|
// Parse fill and alignment.
|
||||||
@ -3495,13 +3491,13 @@ void do_format_arg(basic_writer<Char> &writer, basic_arg<Context> arg,
|
|||||||
FMT_THROW(format_error("missing '}' in format string"));
|
FMT_THROW(format_error("missing '}' in format string"));
|
||||||
|
|
||||||
// Format argument.
|
// Format argument.
|
||||||
visit(ArgFormatter(writer, ctx, spec), arg);
|
visit(ArgFormatter(buffer, ctx, spec), arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Formats arguments and writes the output to the writer. */
|
/** Formats arguments and writes the output to the buffer. */
|
||||||
template <typename ArgFormatter, typename Char, typename Context>
|
template <typename ArgFormatter, typename Char, typename Context>
|
||||||
void vwrite(basic_writer<Char> &writer, BasicCStringRef<Char> format_str,
|
void vformat_to(basic_buffer<Char> &buffer, BasicCStringRef<Char> format_str,
|
||||||
basic_args<Context> args) {
|
basic_args<Context> args) {
|
||||||
basic_context<Char> ctx(format_str.c_str(), args);
|
basic_context<Char> ctx(format_str.c_str(), args);
|
||||||
const Char *&s = ctx.ptr();
|
const Char *&s = ctx.ptr();
|
||||||
const Char *start = s;
|
const Char *start = s;
|
||||||
@ -3509,26 +3505,19 @@ void vwrite(basic_writer<Char> &writer, BasicCStringRef<Char> format_str,
|
|||||||
Char c = *s++;
|
Char c = *s++;
|
||||||
if (c != '{' && c != '}') continue;
|
if (c != '{' && c != '}') continue;
|
||||||
if (*s == c) {
|
if (*s == c) {
|
||||||
internal::write(writer, start, s);
|
buffer.append(start, s);
|
||||||
start = ++s;
|
start = ++s;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == '}')
|
if (c == '}')
|
||||||
FMT_THROW(format_error("unmatched '}' in format string"));
|
FMT_THROW(format_error("unmatched '}' in format string"));
|
||||||
internal::write(writer, start, s - 1);
|
buffer.append(start, s - 1);
|
||||||
do_format_arg<ArgFormatter>(writer, ctx.parse_arg_id(), ctx);
|
do_format_arg<ArgFormatter>(buffer, ctx.parse_arg_id(), ctx);
|
||||||
if (*s != '}')
|
if (*s != '}')
|
||||||
FMT_THROW(format_error(fmt::format("unknown format specifier")));
|
FMT_THROW(format_error(fmt::format("unknown format specifier")));
|
||||||
start = ++s;
|
start = ++s;
|
||||||
}
|
}
|
||||||
internal::write(writer, start, s);
|
buffer.append(start, s);
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Char>
|
|
||||||
inline void basic_writer<Char>::vformat(
|
|
||||||
BasicCStringRef<Char> format,
|
|
||||||
basic_args<basic_context<Char>> args) {
|
|
||||||
vwrite<ArgFormatter<Char>>(*this, format, args);
|
|
||||||
}
|
}
|
||||||
} // namespace fmt
|
} // namespace fmt
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
namespace fmt {
|
namespace fmt {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
FMT_FUNC void write(std::ostream &os, writer &w) {
|
FMT_FUNC void write(std::ostream &os, buffer &buf) {
|
||||||
const char *data = w.data();
|
const char *data = buf.data();
|
||||||
typedef internal::MakeUnsigned<std::streamsize>::Type UnsignedStreamSize;
|
typedef internal::MakeUnsigned<std::streamsize>::Type UnsignedStreamSize;
|
||||||
UnsignedStreamSize size = w.size();
|
UnsignedStreamSize size = buf.size();
|
||||||
UnsignedStreamSize max_size =
|
UnsignedStreamSize max_size =
|
||||||
internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
|
internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
|
||||||
do {
|
do {
|
||||||
@ -27,10 +27,9 @@ FMT_FUNC void write(std::ostream &os, writer &w) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void vprint(std::ostream &os, CStringRef format_str,
|
FMT_FUNC void vprint(std::ostream &os, CStringRef format_str, args args) {
|
||||||
args args) {
|
internal::MemoryBuffer<char> buffer;
|
||||||
MemoryWriter w;
|
vformat_to(buffer, format_str, args);
|
||||||
w.vformat(format_str, args);
|
internal::write(os, buffer);
|
||||||
internal::write(os, w);
|
|
||||||
}
|
}
|
||||||
} // namespace fmt
|
} // namespace fmt
|
||||||
|
@ -67,28 +67,27 @@ struct ConvertToIntImpl<T, true> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write the content of w to os.
|
// Write the content of buf to os.
|
||||||
void write(std::ostream &os, writer &w);
|
void write(std::ostream &os, buffer &buf);
|
||||||
|
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
BasicStringRef<Char> format_value(
|
void format_value(basic_buffer<Char> &buffer, const T &value) {
|
||||||
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> &buffer,
|
|
||||||
const T &value) {
|
|
||||||
internal::FormatBuf<Char> format_buf(buffer);
|
internal::FormatBuf<Char> format_buf(buffer);
|
||||||
std::basic_ostream<Char> output(&format_buf);
|
std::basic_ostream<Char> output(&format_buf);
|
||||||
output << value;
|
output << value;
|
||||||
return BasicStringRef<Char>(&buffer[0], format_buf.size());
|
buffer.resize(format_buf.size());
|
||||||
}
|
}
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
// Formats a value.
|
// Formats a value.
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
void format_value(basic_writer<Char> &w, const T &value,
|
void format_value(basic_buffer<Char> &buf, const T &value,
|
||||||
basic_context<Char> &ctx) {
|
basic_context<Char> &ctx) {
|
||||||
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
||||||
auto str = internal::format_value(buffer, value);
|
internal::format_value(buffer, value);
|
||||||
|
BasicStringRef<Char> str(buffer.data(), buffer.size());
|
||||||
do_format_arg< ArgFormatter<Char> >(
|
do_format_arg< ArgFormatter<Char> >(
|
||||||
w, internal::make_arg< basic_context<Char> >(str), ctx);
|
buf, internal::make_arg< basic_context<Char> >(str), ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_API void vprint(std::ostream &os, CStringRef format_str, args args);
|
FMT_API void vprint(std::ostream &os, CStringRef format_str, args args);
|
||||||
|
51
fmt/printf.h
51
fmt/printf.h
@ -225,12 +225,12 @@ class PrintfArgFormatter : public internal::ArgFormatterBase<Char> {
|
|||||||
/**
|
/**
|
||||||
\rst
|
\rst
|
||||||
Constructs an argument formatter object.
|
Constructs an argument formatter object.
|
||||||
*writer* is a reference to the output writer and *spec* contains format
|
*buffer* is a reference to the output buffer and *spec* contains format
|
||||||
specifier information for standard argument types.
|
specifier information for standard argument types.
|
||||||
\endrst
|
\endrst
|
||||||
*/
|
*/
|
||||||
PrintfArgFormatter(basic_writer<Char> &writer, format_specs &spec)
|
PrintfArgFormatter(basic_buffer<Char> &buffer, format_specs &spec)
|
||||||
: internal::ArgFormatterBase<Char>(writer, spec) {}
|
: internal::ArgFormatterBase<Char>(buffer, spec) {}
|
||||||
|
|
||||||
using Base::operator();
|
using Base::operator();
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ class PrintfArgFormatter : public internal::ArgFormatterBase<Char> {
|
|||||||
const Char format_str[] = {'}', '\0'};
|
const Char format_str[] = {'}', '\0'};
|
||||||
auto args = basic_args<basic_context<Char>>();
|
auto args = basic_args<basic_context<Char>>();
|
||||||
basic_context<Char> ctx(format_str, args);
|
basic_context<Char> ctx(format_str, args);
|
||||||
c.format(this->writer(), c.value, &ctx);
|
c.format(this->writer().buffer(), c.value, &ctx);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -331,8 +331,8 @@ class printf_context :
|
|||||||
basic_args<printf_context> args)
|
basic_args<printf_context> args)
|
||||||
: Base(format_str.c_str(), args) {}
|
: Base(format_str.c_str(), args) {}
|
||||||
|
|
||||||
/** Formats stored arguments and writes the output to the writer. */
|
/** Formats stored arguments and writes the output to the buffer. */
|
||||||
FMT_API void format(basic_writer<Char> &writer);
|
FMT_API void format(basic_buffer<Char> &buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Char, typename AF>
|
template <typename Char, typename AF>
|
||||||
@ -408,18 +408,18 @@ unsigned printf_context<Char, AF>::parse_header(
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char, typename AF>
|
template <typename Char, typename AF>
|
||||||
void printf_context<Char, AF>::format(basic_writer<Char> &writer) {
|
void printf_context<Char, AF>::format(basic_buffer<Char> &buffer) {
|
||||||
const Char *start = this->ptr();
|
const Char *start = this->ptr();
|
||||||
const Char *s = start;
|
const Char *s = start;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
Char c = *s++;
|
Char c = *s++;
|
||||||
if (c != '%') continue;
|
if (c != '%') continue;
|
||||||
if (*s == c) {
|
if (*s == c) {
|
||||||
internal::write(writer, start, s);
|
buffer.append(start, s);
|
||||||
start = ++s;
|
start = ++s;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
internal::write(writer, start, s - 1);
|
buffer.append(start, s - 1);
|
||||||
|
|
||||||
format_specs spec;
|
format_specs spec;
|
||||||
spec.align_ = ALIGN_RIGHT;
|
spec.align_ = ALIGN_RIGHT;
|
||||||
@ -501,31 +501,30 @@ void printf_context<Char, AF>::format(basic_writer<Char> &writer) {
|
|||||||
start = s;
|
start = s;
|
||||||
|
|
||||||
// Format argument.
|
// Format argument.
|
||||||
visit(AF(writer, spec), arg);
|
visit(AF(buffer, spec), arg);
|
||||||
}
|
}
|
||||||
internal::write(writer, start, s);
|
buffer.append(start, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formats a value.
|
// Formats a value.
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
void format_value(basic_writer<Char> &w, const T &value,
|
void format_value(basic_buffer<Char> &buf, const T &value,
|
||||||
printf_context<Char>& ctx) {
|
printf_context<Char>& ctx) {
|
||||||
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
|
internal::format_value(buf, value);
|
||||||
w.write(internal::format_value(buffer, value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
void printf(basic_writer<Char> &w, BasicCStringRef<Char> format,
|
void printf(basic_buffer<Char> &buf, BasicCStringRef<Char> format,
|
||||||
basic_args<printf_context<Char>> args) {
|
basic_args<printf_context<Char>> args) {
|
||||||
printf_context<Char>(format, args).format(w);
|
printf_context<Char>(format, args).format(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef basic_args<printf_context<char>> printf_args;
|
typedef basic_args<printf_context<char>> printf_args;
|
||||||
|
|
||||||
inline std::string vsprintf(CStringRef format, printf_args args) {
|
inline std::string vsprintf(CStringRef format, printf_args args) {
|
||||||
MemoryWriter w;
|
internal::MemoryBuffer<char> buffer;
|
||||||
printf(w, format, args);
|
printf(buffer, format, args);
|
||||||
return w.str();
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -544,9 +543,9 @@ inline std::string sprintf(CStringRef format_str, const Args & ... args) {
|
|||||||
|
|
||||||
inline std::wstring vsprintf(
|
inline std::wstring vsprintf(
|
||||||
WCStringRef format, basic_args<printf_context<wchar_t>> args) {
|
WCStringRef format, basic_args<printf_context<wchar_t>> args) {
|
||||||
WMemoryWriter w;
|
internal::MemoryBuffer<wchar_t> buffer;
|
||||||
printf(w, format, args);
|
printf(buffer, format, args);
|
||||||
return w.str();
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
@ -591,10 +590,10 @@ inline int printf(CStringRef format_str, const Args & ... args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline int vfprintf(std::ostream &os, CStringRef format_str, printf_args args) {
|
inline int vfprintf(std::ostream &os, CStringRef format_str, printf_args args) {
|
||||||
MemoryWriter w;
|
internal::MemoryBuffer<char> buffer;
|
||||||
printf(w, format_str, args);
|
printf(buffer, format_str, args);
|
||||||
internal::write(os, w);
|
internal::write(os, buffer);
|
||||||
return static_cast<int>(w.size());
|
return static_cast<int>(buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
13
fmt/time.h
13
fmt/time.h
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
namespace fmt {
|
namespace fmt {
|
||||||
|
|
||||||
void format_value(writer &w, const std::tm &tm, context &ctx) {
|
void format_value(buffer &buf, const std::tm &tm, context &ctx) {
|
||||||
const char *&s = ctx.ptr();
|
const char *&s = ctx.ptr();
|
||||||
if (*s == ':')
|
if (*s == ':')
|
||||||
++s;
|
++s;
|
||||||
@ -27,13 +27,12 @@ void format_value(writer &w, const std::tm &tm, context &ctx) {
|
|||||||
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
|
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
|
||||||
format.append(s, end + 1);
|
format.append(s, end + 1);
|
||||||
format[format.size() - 1] = '\0';
|
format[format.size() - 1] = '\0';
|
||||||
basic_buffer<char> &buffer = w.buffer();
|
std::size_t start = buf.size();
|
||||||
std::size_t start = buffer.size();
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
std::size_t size = buffer.capacity() - start;
|
std::size_t size = buf.capacity() - start;
|
||||||
std::size_t count = std::strftime(&buffer[start], size, &format[0], &tm);
|
std::size_t count = std::strftime(&buf[start], size, &format[0], &tm);
|
||||||
if (count != 0) {
|
if (count != 0) {
|
||||||
buffer.resize(start + count);
|
buf.resize(start + count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (size >= format.size() * 256) {
|
if (size >= format.size() * 256) {
|
||||||
@ -44,7 +43,7 @@ void format_value(writer &w, const std::tm &tm, context &ctx) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const std::size_t MIN_GROWTH = 10;
|
const std::size_t MIN_GROWTH = 10;
|
||||||
buffer.reserve(buffer.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH));
|
buf.reserve(buf.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH));
|
||||||
}
|
}
|
||||||
s = end;
|
s = end;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ using fmt::PrintfArgFormatter;
|
|||||||
// rounded to 0.
|
// rounded to 0.
|
||||||
class CustomArgFormatter : public fmt::ArgFormatter<char> {
|
class CustomArgFormatter : public fmt::ArgFormatter<char> {
|
||||||
public:
|
public:
|
||||||
CustomArgFormatter(fmt::writer &w, fmt::basic_context<char> &ctx,
|
CustomArgFormatter(fmt::buffer &buf, fmt::basic_context<char> &ctx,
|
||||||
fmt::format_specs &s)
|
fmt::format_specs &s)
|
||||||
: fmt::ArgFormatter<char>(w, ctx, s) {}
|
: fmt::ArgFormatter<char>(buf, ctx, s) {}
|
||||||
|
|
||||||
using fmt::ArgFormatter<char>::operator();
|
using fmt::ArgFormatter<char>::operator();
|
||||||
|
|
||||||
@ -33,8 +33,8 @@ class CustomArgFormatter : public fmt::ArgFormatter<char> {
|
|||||||
// rounded to 0.
|
// rounded to 0.
|
||||||
class CustomPrintfArgFormatter : public PrintfArgFormatter<char> {
|
class CustomPrintfArgFormatter : public PrintfArgFormatter<char> {
|
||||||
public:
|
public:
|
||||||
CustomPrintfArgFormatter(fmt::basic_writer<char> &w, fmt::format_specs &spec)
|
CustomPrintfArgFormatter(fmt::buffer &buf, fmt::format_specs &spec)
|
||||||
: PrintfArgFormatter<char>(w, spec) {}
|
: PrintfArgFormatter<char>(buf, spec) {}
|
||||||
|
|
||||||
using PrintfArgFormatter<char>::operator();
|
using PrintfArgFormatter<char>::operator();
|
||||||
|
|
||||||
@ -46,10 +46,10 @@ class CustomPrintfArgFormatter : public PrintfArgFormatter<char> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string custom_vformat(fmt::CStringRef format_str, fmt::args args) {
|
std::string custom_vformat(fmt::CStringRef format_str, fmt::args args) {
|
||||||
fmt::MemoryWriter writer;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
// Pass custom argument formatter as a template arg to vformat.
|
// Pass custom argument formatter as a template arg to vwrite.
|
||||||
fmt::vwrite<CustomArgFormatter>(writer, format_str, args);
|
fmt::vformat_to<CustomArgFormatter>(buffer, format_str, args);
|
||||||
return writer.str();
|
return std::string(buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
@ -64,10 +64,10 @@ typedef fmt::printf_context<char, CustomPrintfArgFormatter>
|
|||||||
std::string custom_vsprintf(
|
std::string custom_vsprintf(
|
||||||
const char* format_str,
|
const char* format_str,
|
||||||
fmt::basic_args<CustomPrintfFormatter> args) {
|
fmt::basic_args<CustomPrintfFormatter> args) {
|
||||||
fmt::MemoryWriter writer;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
CustomPrintfFormatter formatter(format_str, args);
|
CustomPrintfFormatter formatter(format_str, args);
|
||||||
formatter.format(writer);
|
formatter.format(buffer);
|
||||||
return writer.str();
|
return std::string(buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@ -107,14 +107,14 @@ TEST(FormatTest, FormatErrorCode) {
|
|||||||
{
|
{
|
||||||
fmt::MemoryWriter w;
|
fmt::MemoryWriter w;
|
||||||
w.write("garbage");
|
w.write("garbage");
|
||||||
fmt::format_error_code(w, 42, "test");
|
fmt::format_error_code(w.buffer(), 42, "test");
|
||||||
EXPECT_EQ("test: " + msg, w.str());
|
EXPECT_EQ("test: " + msg, w.str());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
fmt::MemoryWriter w;
|
fmt::MemoryWriter w;
|
||||||
std::string prefix(
|
std::string prefix(
|
||||||
fmt::internal::INLINE_BUFFER_SIZE - msg.size() - sep.size() + 1, 'x');
|
fmt::internal::INLINE_BUFFER_SIZE - msg.size() - sep.size() + 1, 'x');
|
||||||
fmt::format_error_code(w, 42, prefix);
|
fmt::format_error_code(w.buffer(), 42, prefix);
|
||||||
EXPECT_EQ(msg, w.str());
|
EXPECT_EQ(msg, w.str());
|
||||||
}
|
}
|
||||||
int codes[] = {42, -1};
|
int codes[] = {42, -1};
|
||||||
@ -124,14 +124,14 @@ TEST(FormatTest, FormatErrorCode) {
|
|||||||
fmt::MemoryWriter w;
|
fmt::MemoryWriter w;
|
||||||
std::string prefix(
|
std::string prefix(
|
||||||
fmt::internal::INLINE_BUFFER_SIZE - msg.size() - sep.size(), 'x');
|
fmt::internal::INLINE_BUFFER_SIZE - msg.size() - sep.size(), 'x');
|
||||||
fmt::format_error_code(w, codes[i], prefix);
|
fmt::format_error_code(w.buffer(), codes[i], prefix);
|
||||||
EXPECT_EQ(prefix + sep + msg, w.str());
|
EXPECT_EQ(prefix + sep + msg, w.str());
|
||||||
std::size_t size = fmt::internal::INLINE_BUFFER_SIZE;
|
std::size_t size = fmt::internal::INLINE_BUFFER_SIZE;
|
||||||
EXPECT_EQ(size, w.size());
|
EXPECT_EQ(size, w.size());
|
||||||
w.clear();
|
w.clear();
|
||||||
// Test with a message that doesn't fit into the buffer.
|
// Test with a message that doesn't fit into the buffer.
|
||||||
prefix += 'x';
|
prefix += 'x';
|
||||||
fmt::format_error_code(w, codes[i], prefix);
|
fmt::format_error_code(w.buffer(), codes[i], prefix);
|
||||||
EXPECT_EQ(msg, w.str());
|
EXPECT_EQ(msg, w.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,12 +265,6 @@ TEST(WriterTest, Data) {
|
|||||||
EXPECT_EQ("42", std::string(w.data(), w.size()));
|
EXPECT_EQ("42", std::string(w.data(), w.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WriterTest, WriteWithoutArgs) {
|
|
||||||
MemoryWriter w;
|
|
||||||
w.format("test");
|
|
||||||
EXPECT_EQ("test", std::string(w.data(), w.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(WriterTest, WriteInt) {
|
TEST(WriterTest, WriteInt) {
|
||||||
CHECK_WRITE(42);
|
CHECK_WRITE(42);
|
||||||
CHECK_WRITE(-42);
|
CHECK_WRITE(-42);
|
||||||
@ -476,20 +470,6 @@ TEST(WriterTest, PadWString) {
|
|||||||
EXPECT_EQ(L"test******", write_wstr(L"test", width=10, fill=L'*'));
|
EXPECT_EQ(L"test******", write_wstr(L"test", width=10, fill=L'*'));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WriterTest, Format) {
|
|
||||||
MemoryWriter w;
|
|
||||||
w.format("part{0}", 1);
|
|
||||||
EXPECT_EQ(strlen("part1"), w.size());
|
|
||||||
EXPECT_STREQ("part1", w.c_str());
|
|
||||||
EXPECT_STREQ("part1", w.data());
|
|
||||||
EXPECT_EQ("part1", w.str());
|
|
||||||
w.format("part{0}", 2);
|
|
||||||
EXPECT_EQ(strlen("part1part2"), w.size());
|
|
||||||
EXPECT_STREQ("part1part2", w.c_str());
|
|
||||||
EXPECT_STREQ("part1part2", w.data());
|
|
||||||
EXPECT_EQ("part1part2", w.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(WriterTest, WWriter) {
|
TEST(WriterTest, WWriter) {
|
||||||
EXPECT_EQ(L"cafe", write_wstr(0xcafe, type='x'));
|
EXPECT_EQ(L"cafe", write_wstr(0xcafe, type='x'));
|
||||||
}
|
}
|
||||||
@ -501,32 +481,43 @@ TEST(ArrayWriterTest, Ctor) {
|
|||||||
EXPECT_STREQ("", w.c_str());
|
EXPECT_STREQ("", w.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatToTest, FormatWithoutArgs) {
|
||||||
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
|
format_to(buffer, "test");
|
||||||
|
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FormatToTest, Format) {
|
||||||
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
|
format_to(buffer, "part{0}", 1);
|
||||||
|
EXPECT_EQ(strlen("part1"), buffer.size());
|
||||||
|
EXPECT_EQ("part1", std::string(buffer.data(), buffer.size()));
|
||||||
|
format_to(buffer, "part{0}", 2);
|
||||||
|
EXPECT_EQ(strlen("part1part2"), buffer.size());
|
||||||
|
EXPECT_EQ("part1part2", std::string(buffer.data(), buffer.size()));
|
||||||
|
EXPECT_EQ("part1part2", to_string(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ArrayWriterTest, CompileTimeSizeCtor) {
|
TEST(ArrayWriterTest, CompileTimeSizeCtor) {
|
||||||
char array[10] = "garbage";
|
char array[10] = "garbage";
|
||||||
fmt::ArrayWriter w(array);
|
fmt::ArrayWriter w(array);
|
||||||
EXPECT_EQ(0u, w.size());
|
EXPECT_EQ(0u, w.size());
|
||||||
EXPECT_STREQ("", w.c_str());
|
EXPECT_STREQ("", w.c_str());
|
||||||
w.format("{:10}", 1);
|
format_to(w.buffer(), "{:10}", 1);
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ArrayWriterTest, Write) {
|
|
||||||
char array[10];
|
|
||||||
fmt::ArrayWriter w(array, sizeof(array));
|
|
||||||
w.format("{}", 42);
|
|
||||||
EXPECT_EQ("42", w.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArrayWriterTest, BufferOverflow) {
|
TEST(ArrayWriterTest, BufferOverflow) {
|
||||||
char array[10];
|
char array[10];
|
||||||
fmt::ArrayWriter w(array, sizeof(array));
|
fmt::ArrayWriter w(array, sizeof(array));
|
||||||
w.format("{:10}", 1);
|
format_to(w.buffer(), "{:10}", 1);
|
||||||
EXPECT_THROW_MSG(w.format("{}", 1), std::runtime_error, "buffer overflow");
|
EXPECT_THROW_MSG(format_to(w.buffer(), "{}", 1), std::runtime_error,
|
||||||
|
"buffer overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArrayWriterTest, WChar) {
|
TEST(ArrayWriterTest, WChar) {
|
||||||
wchar_t array[10];
|
wchar_t array[10];
|
||||||
fmt::WArrayWriter w(array);
|
fmt::WArrayWriter w(array);
|
||||||
w.format(L"{}", 42);
|
format_to(w.buffer(), L"{}", 42);
|
||||||
EXPECT_EQ(L"42", w.str());
|
EXPECT_EQ(L"42", w.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,12 +1357,8 @@ TEST(FormatterTest, FormatCStringRef) {
|
|||||||
EXPECT_EQ("test", format("{0}", CStringRef("test")));
|
EXPECT_EQ("test", format("{0}", CStringRef("test")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_value(fmt::writer &w, const Date &d, fmt::context &) {
|
void format_value(fmt::buffer &buf, const Date &d, fmt::context &) {
|
||||||
w.write(d.year());
|
fmt::format_to(buf, "{}-{}-{}", d.year(), d.month(), d.day());
|
||||||
w.write('-');
|
|
||||||
w.write(d.month());
|
|
||||||
w.write('-');
|
|
||||||
w.write(d.day());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, FormatCustom) {
|
TEST(FormatterTest, FormatCustom) {
|
||||||
@ -1383,8 +1370,8 @@ TEST(FormatterTest, FormatCustom) {
|
|||||||
class Answer {};
|
class Answer {};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
void format_value(basic_writer<Char> &w, Answer, fmt::context &) {
|
void format_value(fmt::basic_buffer<Char> &buf, Answer, fmt::context &) {
|
||||||
w.write("42");
|
fmt::format_to(buf, "{}", 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, CustomFormat) {
|
TEST(FormatterTest, CustomFormat) {
|
||||||
@ -1417,13 +1404,11 @@ TEST(FormatterTest, FormatExamples) {
|
|||||||
out.write("The answer is ");
|
out.write("The answer is ");
|
||||||
out.write(42);
|
out.write(42);
|
||||||
out.write("\n");
|
out.write("\n");
|
||||||
out.format("({:+f}, {:+f})", -3.14, 3.14);
|
|
||||||
EXPECT_EQ("The answer is 42\n(-3.140000, +3.140000)", out.str());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
MemoryWriter writer;
|
MemoryWriter writer;
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
writer.format("{}", i);
|
format_to(writer.buffer(), "{}", i);
|
||||||
std::string s = writer.str(); // s == 0123456789
|
std::string s = writer.str(); // s == 0123456789
|
||||||
EXPECT_EQ("0123456789", s);
|
EXPECT_EQ("0123456789", s);
|
||||||
}
|
}
|
||||||
@ -1567,10 +1552,10 @@ TEST(StrTest, Convert) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string vformat_message(int id, const char *format, fmt::args args) {
|
std::string vformat_message(int id, const char *format, fmt::args args) {
|
||||||
MemoryWriter w;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
w.format("[{}] ", id);
|
format_to(buffer, "[{}] ", id);
|
||||||
w.vformat(format, args);
|
vformat_to(buffer, format, args);
|
||||||
return w.str();
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
@ -1643,9 +1628,9 @@ class MockArgFormatter : public fmt::internal::ArgFormatterBase<char> {
|
|||||||
public:
|
public:
|
||||||
typedef fmt::internal::ArgFormatterBase<char> Base;
|
typedef fmt::internal::ArgFormatterBase<char> Base;
|
||||||
|
|
||||||
MockArgFormatter(fmt::writer &w, fmt::context &ctx,
|
MockArgFormatter(fmt::buffer &b, fmt::context &ctx,
|
||||||
fmt::format_specs &s)
|
fmt::format_specs &s)
|
||||||
: fmt::internal::ArgFormatterBase<char>(w, s) {
|
: fmt::internal::ArgFormatterBase<char>(b, s) {
|
||||||
EXPECT_CALL(*this, call(42));
|
EXPECT_CALL(*this, call(42));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1657,8 +1642,8 @@ class MockArgFormatter : public fmt::internal::ArgFormatterBase<char> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void custom_vformat(fmt::CStringRef format_str, fmt::args args) {
|
void custom_vformat(fmt::CStringRef format_str, fmt::args args) {
|
||||||
fmt::MemoryWriter writer;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
fmt::vwrite<MockArgFormatter>(writer, format_str, args);
|
fmt::vformat_to<MockArgFormatter>(buffer, format_str, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@ -320,7 +320,7 @@ TEST(StreamingAssertionsTest, EXPECT_WRITE) {
|
|||||||
|
|
||||||
TEST(UtilTest, FormatSystemError) {
|
TEST(UtilTest, FormatSystemError) {
|
||||||
fmt::MemoryWriter out;
|
fmt::MemoryWriter out;
|
||||||
fmt::format_system_error(out, EDOM, "test message");
|
fmt::format_system_error(out.buffer(), EDOM, "test message");
|
||||||
EXPECT_EQ(out.str(), format_system_error(EDOM, "test message"));
|
EXPECT_EQ(out.str(), format_system_error(EDOM, "test message"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ std::string read(File &f, std::size_t count) {
|
|||||||
#endif // FMT_USE_FILE_DESCRIPTORS
|
#endif // FMT_USE_FILE_DESCRIPTORS
|
||||||
|
|
||||||
std::string format_system_error(int error_code, fmt::StringRef message) {
|
std::string format_system_error(int error_code, fmt::StringRef message) {
|
||||||
fmt::MemoryWriter out;
|
fmt::internal::MemoryBuffer<char> out;
|
||||||
fmt::format_system_error(out, error_code, message);
|
fmt::format_system_error(out, error_code, message);
|
||||||
return out.str();
|
return to_string(out);
|
||||||
}
|
}
|
||||||
|
@ -59,17 +59,17 @@ TEST(OStreamTest, Enum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct TestArgFormatter : fmt::ArgFormatter<char> {
|
struct TestArgFormatter : fmt::ArgFormatter<char> {
|
||||||
TestArgFormatter(fmt::writer &w, fmt::context &ctx, fmt::format_specs &s)
|
TestArgFormatter(fmt::buffer &buf, fmt::context &ctx, fmt::format_specs &s)
|
||||||
: fmt::ArgFormatter<char>(w, ctx, s) {}
|
: fmt::ArgFormatter<char>(buf, ctx, s) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(OStreamTest, CustomArg) {
|
TEST(OStreamTest, CustomArg) {
|
||||||
fmt::MemoryWriter writer;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
fmt::context ctx("}", fmt::args());
|
fmt::context ctx("}", fmt::args());
|
||||||
fmt::format_specs spec;
|
fmt::format_specs spec;
|
||||||
TestArgFormatter af(writer, ctx, spec);
|
TestArgFormatter af(buffer, ctx, spec);
|
||||||
visit(af, fmt::internal::make_arg<fmt::context>(TestEnum()));
|
visit(af, fmt::internal::make_arg<fmt::context>(TestEnum()));
|
||||||
EXPECT_EQ("TestEnum", writer.str());
|
EXPECT_EQ("TestEnum", std::string(buffer.data(), buffer.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(OStreamTest, Format) {
|
TEST(OStreamTest, Format) {
|
||||||
@ -121,9 +121,10 @@ TEST(OStreamTest, Print) {
|
|||||||
|
|
||||||
TEST(OStreamTest, WriteToOStream) {
|
TEST(OStreamTest, WriteToOStream) {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
fmt::MemoryWriter w;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
w.write("foo");
|
const char *foo = "foo";
|
||||||
fmt::internal::write(os, w);
|
buffer.append(foo, foo + std::strlen(foo));
|
||||||
|
fmt::internal::write(os, buffer);
|
||||||
EXPECT_EQ("foo", os.str());
|
EXPECT_EQ("foo", os.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,16 +134,10 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
|
|||||||
if (max_size <= fmt::internal::to_unsigned(max_streamsize))
|
if (max_size <= fmt::internal::to_unsigned(max_streamsize))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
class TestWriter : public fmt::basic_writer<char> {
|
struct TestBuffer : fmt::basic_buffer<char> {
|
||||||
private:
|
explicit TestBuffer(std::size_t size) { size_ = size; }
|
||||||
struct TestBuffer : fmt::basic_buffer<char> {
|
void grow(std::size_t) {}
|
||||||
explicit TestBuffer(std::size_t size) { size_ = size; }
|
} buffer(max_size);
|
||||||
void grow(std::size_t) {}
|
|
||||||
} buffer_;
|
|
||||||
public:
|
|
||||||
explicit TestWriter(std::size_t size)
|
|
||||||
: fmt::basic_writer<char>(buffer_), buffer_(size) {}
|
|
||||||
} w(max_size);
|
|
||||||
|
|
||||||
struct MockStreamBuf : std::streambuf {
|
struct MockStreamBuf : std::streambuf {
|
||||||
MOCK_METHOD2(xsputn, std::streamsize (const void *s, std::streamsize n));
|
MOCK_METHOD2(xsputn, std::streamsize (const void *s, std::streamsize n));
|
||||||
@ -150,11 +145,11 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
|
|||||||
const void *v = s;
|
const void *v = s;
|
||||||
return xsputn(v, n);
|
return xsputn(v, n);
|
||||||
}
|
}
|
||||||
} buffer;
|
} streambuf;
|
||||||
|
|
||||||
struct TestOStream : std::ostream {
|
struct TestOStream : std::ostream {
|
||||||
explicit TestOStream(MockStreamBuf &buffer) : std::ostream(&buffer) {}
|
explicit TestOStream(MockStreamBuf &buffer) : std::ostream(&buffer) {}
|
||||||
} os(buffer);
|
} os(streambuf);
|
||||||
|
|
||||||
testing::InSequence sequence;
|
testing::InSequence sequence;
|
||||||
const char *data = 0;
|
const char *data = 0;
|
||||||
@ -163,10 +158,10 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
|
|||||||
typedef fmt::internal::MakeUnsigned<std::streamsize>::Type UStreamSize;
|
typedef fmt::internal::MakeUnsigned<std::streamsize>::Type UStreamSize;
|
||||||
UStreamSize n = std::min<UStreamSize>(
|
UStreamSize n = std::min<UStreamSize>(
|
||||||
size, fmt::internal::to_unsigned(max_streamsize));
|
size, fmt::internal::to_unsigned(max_streamsize));
|
||||||
EXPECT_CALL(buffer, xsputn(data, static_cast<std::streamsize>(n)))
|
EXPECT_CALL(streambuf, xsputn(data, static_cast<std::streamsize>(n)))
|
||||||
.WillOnce(testing::Return(max_streamsize));
|
.WillOnce(testing::Return(max_streamsize));
|
||||||
data += n;
|
data += n;
|
||||||
size -= static_cast<std::size_t>(n);
|
size -= static_cast<std::size_t>(n);
|
||||||
} while (size != 0);
|
} while (size != 0);
|
||||||
fmt::internal::write(os, w);
|
fmt::internal::write(os, buffer);
|
||||||
}
|
}
|
||||||
|
@ -67,9 +67,10 @@ namespace {
|
|||||||
struct Test {};
|
struct Test {};
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
void format_value(fmt::basic_writer<Char> &w, Test,
|
void format_value(fmt::basic_buffer<Char> &b, Test,
|
||||||
fmt::basic_context<Char> &) {
|
fmt::basic_context<Char> &) {
|
||||||
w.write("test");
|
const Char *test = "test";
|
||||||
|
b.append(test, test + std::strlen(test));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Context, typename T>
|
template <typename Context, typename T>
|
||||||
@ -416,7 +417,7 @@ struct CustomContext {
|
|||||||
bool called;
|
bool called;
|
||||||
};
|
};
|
||||||
|
|
||||||
void format_value(fmt::writer &, const Test &, CustomContext &ctx) {
|
void format_value(fmt::buffer &, const Test &, CustomContext &ctx) {
|
||||||
ctx.called = true;
|
ctx.called = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,8 +425,8 @@ TEST(UtilTest, MakeValueWithCustomFormatter) {
|
|||||||
::Test t;
|
::Test t;
|
||||||
fmt::internal::value<CustomContext> arg(t);
|
fmt::internal::value<CustomContext> arg(t);
|
||||||
CustomContext ctx = {false};
|
CustomContext ctx = {false};
|
||||||
fmt::MemoryWriter w;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
arg.custom.format(w, &t, &ctx);
|
arg.custom.format(buffer, &t, &ctx);
|
||||||
EXPECT_TRUE(ctx.called);
|
EXPECT_TRUE(ctx.called);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,10 +569,10 @@ TEST(UtilTest, CustomArg) {
|
|||||||
EXPECT_CALL(visitor, visit(_)).WillOnce(
|
EXPECT_CALL(visitor, visit(_)).WillOnce(
|
||||||
testing::Invoke([&](fmt::internal::CustomValue<char> custom) {
|
testing::Invoke([&](fmt::internal::CustomValue<char> custom) {
|
||||||
EXPECT_EQ(&test, custom.value);
|
EXPECT_EQ(&test, custom.value);
|
||||||
fmt::MemoryWriter w;
|
fmt::internal::MemoryBuffer<char> buffer;
|
||||||
fmt::context ctx("}", fmt::args());
|
fmt::context ctx("}", fmt::args());
|
||||||
custom.format(w, &test, &ctx);
|
custom.format(buffer, &test, &ctx);
|
||||||
EXPECT_EQ("test", w.str());
|
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
|
||||||
return Visitor::Result();
|
return Visitor::Result();
|
||||||
}));
|
}));
|
||||||
fmt::visit(visitor, make_arg<fmt::context>(test));
|
fmt::visit(visitor, make_arg<fmt::context>(test));
|
||||||
@ -689,7 +690,7 @@ TEST(UtilTest, UTF16ToUTF8Convert) {
|
|||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
|
||||||
typedef void (*FormatErrorMessage)(
|
typedef void (*FormatErrorMessage)(
|
||||||
fmt::writer &out, int error_code, StringRef message);
|
fmt::buffer &out, int error_code, StringRef message);
|
||||||
|
|
||||||
template <typename Error>
|
template <typename Error>
|
||||||
void check_throw_error(int error_code, FormatErrorMessage format) {
|
void check_throw_error(int error_code, FormatErrorMessage format) {
|
||||||
@ -699,20 +700,21 @@ void check_throw_error(int error_code, FormatErrorMessage format) {
|
|||||||
} catch (const fmt::SystemError &e) {
|
} catch (const fmt::SystemError &e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
fmt::MemoryWriter message;
|
fmt::internal::MemoryBuffer<char> message;
|
||||||
format(message, error_code, "test error");
|
format(message, error_code, "test error");
|
||||||
EXPECT_EQ(message.str(), error.what());
|
EXPECT_EQ(to_string(message), error.what());
|
||||||
EXPECT_EQ(error_code, error.error_code());
|
EXPECT_EQ(error_code, error.error_code());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(UtilTest, FormatSystemError) {
|
TEST(UtilTest, FormatSystemError) {
|
||||||
fmt::MemoryWriter message;
|
fmt::internal::MemoryBuffer<char> message;
|
||||||
fmt::format_system_error(message, EDOM, "test");
|
fmt::format_system_error(message, EDOM, "test");
|
||||||
EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), message.str());
|
EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)),
|
||||||
|
to_string(message));
|
||||||
message.clear();
|
message.clear();
|
||||||
fmt::format_system_error(
|
fmt::format_system_error(
|
||||||
message, EDOM, fmt::StringRef(0, std::numeric_limits<size_t>::max()));
|
message, EDOM, fmt::StringRef(0, std::numeric_limits<size_t>::max()));
|
||||||
EXPECT_EQ(fmt::format("error {}", EDOM), message.str());
|
EXPECT_EQ(fmt::format("error {}", EDOM), to_string(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(UtilTest, SystemError) {
|
TEST(UtilTest, SystemError) {
|
||||||
@ -723,10 +725,11 @@ TEST(UtilTest, SystemError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(UtilTest, ReportSystemError) {
|
TEST(UtilTest, ReportSystemError) {
|
||||||
fmt::MemoryWriter out;
|
fmt::internal::MemoryBuffer<char> out;
|
||||||
fmt::format_system_error(out, EDOM, "test error");
|
fmt::format_system_error(out, EDOM, "test error");
|
||||||
out.write('\n');
|
out.push_back('\n');
|
||||||
EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"), out.str());
|
EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"),
|
||||||
|
to_string(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
Loading…
Reference in New Issue
Block a user