mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-05 00:40:12 +00:00
internal::MemoryBuffer -> basic_memory_buffer
This commit is contained in:
parent
4ec8860783
commit
eedfd07f8b
@ -205,7 +205,7 @@ void format_error_code(buffer &out, int error_code,
|
|||||||
|
|
||||||
void report_error(FormatFunc func, int error_code,
|
void report_error(FormatFunc func, int error_code,
|
||||||
string_view message) FMT_NOEXCEPT {
|
string_view message) FMT_NOEXCEPT {
|
||||||
internal::MemoryBuffer<char> full_message;
|
memory_buffer 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.
|
||||||
@ -217,10 +217,10 @@ void report_error(FormatFunc func, int error_code,
|
|||||||
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;
|
||||||
internal::MemoryBuffer<char> buf;
|
memory_buffer buffer;
|
||||||
format_system_error(buf, err_code, vformat(format_str, args));
|
format_system_error(buffer, err_code, vformat(format_str, args));
|
||||||
std::runtime_error &base = *this;
|
std::runtime_error &base = *this;
|
||||||
base = std::runtime_error(to_string(buf));
|
base = std::runtime_error(to_string(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -382,7 +382,7 @@ FMT_FUNC void internal::format_windows_error(
|
|||||||
FMT_FUNC void format_system_error(
|
FMT_FUNC void format_system_error(
|
||||||
buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
|
buffer &out, int error_code, string_view message) FMT_NOEXCEPT {
|
||||||
FMT_TRY {
|
FMT_TRY {
|
||||||
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> buffer;
|
memory_buffer buffer;
|
||||||
buffer.resize(internal::INLINE_BUFFER_SIZE);
|
buffer.resize(internal::INLINE_BUFFER_SIZE);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char *system_message = &buffer[0];
|
char *system_message = &buffer[0];
|
||||||
@ -422,7 +422,7 @@ 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) {
|
||||||
internal::MemoryBuffer<char> buffer;
|
memory_buffer buffer;
|
||||||
vformat_to(buffer, format_str, args);
|
vformat_to(buffer, format_str, args);
|
||||||
std::fwrite(buffer.data(), 1, buffer.size(), f);
|
std::fwrite(buffer.data(), 1, buffer.size(), f);
|
||||||
}
|
}
|
||||||
@ -444,7 +444,7 @@ 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) {
|
||||||
internal::MemoryBuffer<char> buffer;
|
memory_buffer buffer;
|
||||||
printf(buffer, format, args);
|
printf(buffer, format, args);
|
||||||
std::size_t size = buffer.size();
|
std::size_t size = buffer.size();
|
||||||
return std::fwrite(
|
return std::fwrite(
|
||||||
|
210
fmt/format.h
210
fmt/format.h
@ -659,13 +659,39 @@ inline std::basic_string<Char> to_string(const basic_buffer<Char>& buffer) {
|
|||||||
return std::basic_string<Char>(buffer.data(), buffer.size());
|
return std::basic_string<Char>(buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
/**
|
||||||
|
\rst
|
||||||
|
A dynamically growing memory buffer for trivially copyable/constructible types
|
||||||
|
with the first SIZE elements stored in the object itself.
|
||||||
|
|
||||||
// A memory buffer for trivially copyable/constructible types with the first
|
You can use one of the following typedefs for common character types:
|
||||||
// SIZE elements stored in the object itself.
|
|
||||||
template <typename T, std::size_t SIZE = INLINE_BUFFER_SIZE,
|
+----------------+------------------------------+
|
||||||
|
| Type | Definition |
|
||||||
|
+================+==============================+
|
||||||
|
| memory_buffer | basic_memory_buffer<char> |
|
||||||
|
+----------------+------------------------------+
|
||||||
|
| wmemory_buffer | basic_memory_buffer<wchar_t> |
|
||||||
|
+----------------+------------------------------+
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
memory_buffer out;
|
||||||
|
format_to(out, "The answer is {}.", 42);
|
||||||
|
|
||||||
|
This will write the following output to the ``out`` object:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
The answer is 42.
|
||||||
|
|
||||||
|
The output can be converted to an ``std::string`` with ``to_string(out)``.
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
template <typename T, std::size_t SIZE = internal::INLINE_BUFFER_SIZE,
|
||||||
typename Allocator = std::allocator<T> >
|
typename Allocator = std::allocator<T> >
|
||||||
class MemoryBuffer : private Allocator, public basic_buffer<T> {
|
class basic_memory_buffer : private Allocator, public basic_buffer<T> {
|
||||||
private:
|
private:
|
||||||
T data_[SIZE];
|
T data_[SIZE];
|
||||||
|
|
||||||
@ -678,14 +704,14 @@ class MemoryBuffer : private Allocator, public basic_buffer<T> {
|
|||||||
void grow(std::size_t size);
|
void grow(std::size_t size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MemoryBuffer(const Allocator &alloc = Allocator())
|
explicit basic_memory_buffer(const Allocator &alloc = Allocator())
|
||||||
: Allocator(alloc), basic_buffer<T>(data_, SIZE) {}
|
: Allocator(alloc), basic_buffer<T>(data_, SIZE) {}
|
||||||
~MemoryBuffer() { deallocate(); }
|
~basic_memory_buffer() { deallocate(); }
|
||||||
|
|
||||||
#if FMT_USE_RVALUE_REFERENCES
|
#if FMT_USE_RVALUE_REFERENCES
|
||||||
private:
|
private:
|
||||||
// Move data from other to this buffer.
|
// Move data from other to this buffer.
|
||||||
void move(MemoryBuffer &other) {
|
void move(basic_memory_buffer &other) {
|
||||||
Allocator &this_alloc = *this, &other_alloc = other;
|
Allocator &this_alloc = *this, &other_alloc = other;
|
||||||
this_alloc = std::move(other_alloc);
|
this_alloc = std::move(other_alloc);
|
||||||
this->size_ = other.size_;
|
this->size_ = other.size_;
|
||||||
@ -693,7 +719,7 @@ class MemoryBuffer : private Allocator, public basic_buffer<T> {
|
|||||||
if (other.ptr_ == other.data_) {
|
if (other.ptr_ == other.data_) {
|
||||||
this->ptr_ = data_;
|
this->ptr_ = data_;
|
||||||
std::uninitialized_copy(other.data_, other.data_ + this->size_,
|
std::uninitialized_copy(other.data_, other.data_ + this->size_,
|
||||||
make_ptr(data_, this->capacity_));
|
internal::make_ptr(data_, this->capacity_));
|
||||||
} else {
|
} else {
|
||||||
this->ptr_ = other.ptr_;
|
this->ptr_ = other.ptr_;
|
||||||
// Set pointer to the inline array so that delete is not called
|
// Set pointer to the inline array so that delete is not called
|
||||||
@ -703,11 +729,22 @@ class MemoryBuffer : private Allocator, public basic_buffer<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MemoryBuffer(MemoryBuffer &&other) {
|
/**
|
||||||
|
\rst
|
||||||
|
Constructs a :class:`fmt::basic_memory_buffer` object moving the content
|
||||||
|
of the other object to it.
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
basic_memory_buffer(basic_memory_buffer &&other) {
|
||||||
move(other);
|
move(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBuffer &operator=(MemoryBuffer &&other) {
|
/**
|
||||||
|
\rst
|
||||||
|
Moves the content of the other ``basic_memory_buffer`` object to this one.
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
basic_memory_buffer &operator=(basic_memory_buffer &&other) {
|
||||||
assert(this != &other);
|
assert(this != &other);
|
||||||
deallocate();
|
deallocate();
|
||||||
move(other);
|
move(other);
|
||||||
@ -720,14 +757,14 @@ class MemoryBuffer : private Allocator, public basic_buffer<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, std::size_t SIZE, typename Allocator>
|
template <typename T, std::size_t SIZE, typename Allocator>
|
||||||
void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
|
void basic_memory_buffer<T, SIZE, Allocator>::grow(std::size_t size) {
|
||||||
std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
|
std::size_t new_capacity = this->capacity_ + this->capacity_ / 2;
|
||||||
if (size > new_capacity)
|
if (size > new_capacity)
|
||||||
new_capacity = size;
|
new_capacity = size;
|
||||||
T *new_ptr = this->allocate(new_capacity);
|
T *new_ptr = this->allocate(new_capacity);
|
||||||
// The following code doesn't throw, so the raw pointer above doesn't leak.
|
// The following code doesn't throw, so the raw pointer above doesn't leak.
|
||||||
std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
|
std::uninitialized_copy(this->ptr_, this->ptr_ + this->size_,
|
||||||
make_ptr(new_ptr, new_capacity));
|
internal::make_ptr(new_ptr, new_capacity));
|
||||||
std::size_t old_capacity = this->capacity_;
|
std::size_t old_capacity = this->capacity_;
|
||||||
T *old_ptr = this->ptr_;
|
T *old_ptr = this->ptr_;
|
||||||
this->capacity_ = new_capacity;
|
this->capacity_ = new_capacity;
|
||||||
@ -739,6 +776,45 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
|
|||||||
Allocator::deallocate(old_ptr, old_capacity);
|
Allocator::deallocate(old_ptr, old_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef basic_memory_buffer<char> memory_buffer;
|
||||||
|
typedef basic_memory_buffer<wchar_t> wmemory_buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
A fixed-size memory buffer. For a dynamically growing buffer use
|
||||||
|
:class:`fmt::basic_memory_buffer`.
|
||||||
|
|
||||||
|
Trying to increase the buffer size past the initial capacity will throw
|
||||||
|
``std::runtime_error``.
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
template <typename Char>
|
||||||
|
class FixedBuffer : public 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)
|
||||||
|
: basic_buffer<Char>(array, size) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\rst
|
||||||
|
Constructs a :class:`fmt::FixedBuffer` object for *array* of the
|
||||||
|
size known at compile time.
|
||||||
|
\endrst
|
||||||
|
*/
|
||||||
|
template <std::size_t SIZE>
|
||||||
|
explicit FixedBuffer(Char (&array)[SIZE]) : basic_buffer<Char>(array, SIZE) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FMT_API void grow(std::size_t size);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
class BasicCharTraits {
|
class BasicCharTraits {
|
||||||
public:
|
public:
|
||||||
@ -1047,7 +1123,7 @@ struct ConvertToInt {
|
|||||||
|
|
||||||
#define FMT_DISABLE_CONVERSION_TO_INT(Type) \
|
#define FMT_DISABLE_CONVERSION_TO_INT(Type) \
|
||||||
template <> \
|
template <> \
|
||||||
struct ConvertToInt<Type> { enum { value = 0 }; }
|
struct ConvertToInt<Type> { enum { value = 0 }; }
|
||||||
|
|
||||||
// Silence warnings about convering float to int.
|
// Silence warnings about convering float to int.
|
||||||
FMT_DISABLE_CONVERSION_TO_INT(float);
|
FMT_DISABLE_CONVERSION_TO_INT(float);
|
||||||
@ -2762,108 +2838,6 @@ void basic_writer<Char>::write_double(T value, const format_specs &spec) {
|
|||||||
grow_buffer(n);
|
grow_buffer(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
This class template provides operations for formatting and writing data
|
|
||||||
into a memory buffer that grows dynamically.
|
|
||||||
|
|
||||||
You can use one of the following typedefs for common character types
|
|
||||||
and the standard allocator:
|
|
||||||
|
|
||||||
+---------------+-----------------------------------------------------+
|
|
||||||
| Type | Definition |
|
|
||||||
+===============+=====================================================+
|
|
||||||
| MemoryWriter | BasicMemoryWriter<char, std::allocator<char>> |
|
|
||||||
+---------------+-----------------------------------------------------+
|
|
||||||
| WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
|
|
||||||
+---------------+-----------------------------------------------------+
|
|
||||||
|
|
||||||
**Example**::
|
|
||||||
|
|
||||||
MemoryWriter out;
|
|
||||||
out << "The answer is " << 42 << "\n";
|
|
||||||
out.write("({:+f}, {:+f})", -3.14, 3.14);
|
|
||||||
|
|
||||||
This will write the following output to the ``out`` object:
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
The answer is 42
|
|
||||||
(-3.140000, +3.140000)
|
|
||||||
|
|
||||||
The output can be converted to an ``std::string`` with ``out.str()`` or
|
|
||||||
accessed as a C string with ``out.c_str()``.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
template <typename Char, typename Allocator = std::allocator<Char> >
|
|
||||||
class BasicMemoryWriter : public basic_writer<Char> {
|
|
||||||
private:
|
|
||||||
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE, Allocator> buffer_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit BasicMemoryWriter(const Allocator& alloc = Allocator())
|
|
||||||
: basic_writer<Char>(buffer_), buffer_(alloc) {}
|
|
||||||
|
|
||||||
#if FMT_USE_RVALUE_REFERENCES
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Constructs a :class:`fmt::BasicMemoryWriter` object moving the content
|
|
||||||
of the other object to it.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
BasicMemoryWriter(BasicMemoryWriter &&other)
|
|
||||||
: basic_writer<Char>(buffer_), buffer_(std::move(other.buffer_)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Moves the content of the other ``BasicMemoryWriter`` object to this one.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
BasicMemoryWriter &operator=(BasicMemoryWriter &&other) {
|
|
||||||
buffer_ = std::move(other.buffer_);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef BasicMemoryWriter<char> MemoryWriter;
|
|
||||||
typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
A fixed-size memory buffer. For a dynamically growing buffer use
|
|
||||||
:class:`fmt::internal::MemoryBuffer`.
|
|
||||||
|
|
||||||
Trying to increase the buffer size past the initial capacity will throw
|
|
||||||
``std::runtime_error``.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
template <typename Char>
|
|
||||||
class FixedBuffer : public 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)
|
|
||||||
: basic_buffer<Char>(array, size) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\rst
|
|
||||||
Constructs a :class:`fmt::FixedBuffer` object for *array* of the
|
|
||||||
size known at compile time.
|
|
||||||
\endrst
|
|
||||||
*/
|
|
||||||
template <std::size_t SIZE>
|
|
||||||
explicit FixedBuffer(Char (&array)[SIZE]) : basic_buffer<Char>(array, SIZE) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FMT_API void grow(std::size_t size);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Reports a system error without throwing an exception.
|
// Reports a system error without throwing an exception.
|
||||||
// Can be used to report errors from destructors.
|
// Can be used to report errors from destructors.
|
||||||
FMT_API void report_system_error(int error_code,
|
FMT_API void report_system_error(int error_code,
|
||||||
@ -2959,7 +2933,7 @@ inline void format_to(wbuffer &buf, WCStringRef format_str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::string vformat(CStringRef format_str, args args) {
|
inline std::string vformat(CStringRef format_str, args args) {
|
||||||
internal::MemoryBuffer<char> buffer;
|
memory_buffer buffer;
|
||||||
vformat_to(buffer, format_str, args);
|
vformat_to(buffer, format_str, args);
|
||||||
return to_string(buffer);
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
@ -2979,7 +2953,7 @@ 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) {
|
||||||
internal::MemoryBuffer<wchar_t> buffer;
|
wmemory_buffer buffer;
|
||||||
vformat_to(buffer, format_str, args);
|
vformat_to(buffer, format_str, args);
|
||||||
return to_string(buffer);
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ FMT_FUNC void write(std::ostream &os, buffer &buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FMT_FUNC void vprint(std::ostream &os, CStringRef format_str, args args) {
|
FMT_FUNC void vprint(std::ostream &os, CStringRef format_str, args args) {
|
||||||
internal::MemoryBuffer<char> buffer;
|
memory_buffer buffer;
|
||||||
vformat_to(buffer, format_str, args);
|
vformat_to(buffer, format_str, args);
|
||||||
internal::write(os, buffer);
|
internal::write(os, buffer);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ void format_value(basic_buffer<Char> &buffer, const T &value) {
|
|||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
void format_value(basic_buffer<Char> &buf, 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;
|
basic_memory_buffer<Char> buffer;
|
||||||
internal::format_value(buffer, value);
|
internal::format_value(buffer, value);
|
||||||
basic_string_view<Char> str(buffer.data(), buffer.size());
|
basic_string_view<Char> str(buffer.data(), buffer.size());
|
||||||
do_format_arg< arg_formatter<Char> >(
|
do_format_arg< arg_formatter<Char> >(
|
||||||
|
@ -522,7 +522,7 @@ void printf(basic_buffer<Char> &buf, BasicCStringRef<Char> format,
|
|||||||
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) {
|
||||||
internal::MemoryBuffer<char> buffer;
|
memory_buffer buffer;
|
||||||
printf(buffer, format, args);
|
printf(buffer, format, args);
|
||||||
return to_string(buffer);
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
@ -543,7 +543,7 @@ 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) {
|
||||||
internal::MemoryBuffer<wchar_t> buffer;
|
wmemory_buffer buffer;
|
||||||
printf(buffer, format, args);
|
printf(buffer, format, args);
|
||||||
return to_string(buffer);
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
@ -590,7 +590,7 @@ 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) {
|
||||||
internal::MemoryBuffer<char> buffer;
|
memory_buffer buffer;
|
||||||
printf(buffer, format_str, args);
|
printf(buffer, format_str, args);
|
||||||
internal::write(os, buffer);
|
internal::write(os, buffer);
|
||||||
return static_cast<int>(buffer.size());
|
return static_cast<int>(buffer.size());
|
||||||
|
@ -24,7 +24,7 @@ void format_value(buffer &buf, const std::tm &tm, context &ctx) {
|
|||||||
++end;
|
++end;
|
||||||
if (*end != '}')
|
if (*end != '}')
|
||||||
FMT_THROW(format_error("missing '}' in format string"));
|
FMT_THROW(format_error("missing '}' in format string"));
|
||||||
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> format;
|
memory_buffer format;
|
||||||
format.append(s, end + 1);
|
format.append(s, end + 1);
|
||||||
format[format.size() - 1] = '\0';
|
format[format.size() - 1] = '\0';
|
||||||
std::size_t start = buf.size();
|
std::size_t start = buf.size();
|
||||||
|
@ -46,7 +46,7 @@ class CustomPrintfArgFormatter : public printf_arg_formatter<char> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string custom_vformat(fmt::CStringRef format_str, fmt::args args) {
|
std::string custom_vformat(fmt::CStringRef format_str, fmt::args args) {
|
||||||
fmt::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
// Pass custom argument formatter as a template arg to vwrite.
|
// Pass custom argument formatter as a template arg to vwrite.
|
||||||
fmt::vformat_to<CustomArgFormatter>(buffer, format_str, args);
|
fmt::vformat_to<CustomArgFormatter>(buffer, format_str, args);
|
||||||
return std::string(buffer.data(), buffer.size());
|
return std::string(buffer.data(), buffer.size());
|
||||||
@ -64,7 +64,7 @@ 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::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
CustomPrintfFormatter formatter(format_str, args);
|
CustomPrintfFormatter formatter(format_str, args);
|
||||||
formatter.format(buffer);
|
formatter.format(buffer);
|
||||||
return std::string(buffer.data(), buffer.size());
|
return std::string(buffer.data(), buffer.size());
|
||||||
|
@ -105,33 +105,33 @@ TEST(FormatTest, StrError) {
|
|||||||
TEST(FormatTest, FormatErrorCode) {
|
TEST(FormatTest, FormatErrorCode) {
|
||||||
std::string msg = "error 42", sep = ": ";
|
std::string msg = "error 42", sep = ": ";
|
||||||
{
|
{
|
||||||
fmt::MemoryWriter w;
|
fmt::memory_buffer buffer;
|
||||||
w.write("garbage");
|
format_to(buffer, "garbage");
|
||||||
fmt::format_error_code(w.buffer(), 42, "test");
|
fmt::format_error_code(buffer, 42, "test");
|
||||||
EXPECT_EQ("test: " + msg, w.str());
|
EXPECT_EQ("test: " + msg, to_string(buffer));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
fmt::MemoryWriter w;
|
fmt::memory_buffer buffer;
|
||||||
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.buffer(), 42, prefix);
|
fmt::format_error_code(buffer, 42, prefix);
|
||||||
EXPECT_EQ(msg, w.str());
|
EXPECT_EQ(msg, to_string(buffer));
|
||||||
}
|
}
|
||||||
int codes[] = {42, -1};
|
int codes[] = {42, -1};
|
||||||
for (std::size_t i = 0, n = sizeof(codes) / sizeof(*codes); i < n; ++i) {
|
for (std::size_t i = 0, n = sizeof(codes) / sizeof(*codes); i < n; ++i) {
|
||||||
// Test maximum buffer size.
|
// Test maximum buffer size.
|
||||||
msg = fmt::format("error {}", codes[i]);
|
msg = fmt::format("error {}", codes[i]);
|
||||||
fmt::MemoryWriter w;
|
fmt::memory_buffer buffer;
|
||||||
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.buffer(), codes[i], prefix);
|
fmt::format_error_code(buffer, codes[i], prefix);
|
||||||
EXPECT_EQ(prefix + sep + msg, w.str());
|
EXPECT_EQ(prefix + sep + msg, to_string(buffer));
|
||||||
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, buffer.size());
|
||||||
w.clear();
|
buffer.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.buffer(), codes[i], prefix);
|
fmt::format_error_code(buffer, codes[i], prefix);
|
||||||
EXPECT_EQ(msg, w.str());
|
EXPECT_EQ(msg, to_string(buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ using fmt::format;
|
|||||||
using fmt::format_error;
|
using fmt::format_error;
|
||||||
using fmt::string_view;
|
using fmt::string_view;
|
||||||
using fmt::CStringRef;
|
using fmt::CStringRef;
|
||||||
using fmt::MemoryWriter;
|
using fmt::memory_buffer;
|
||||||
using fmt::WMemoryWriter;
|
using fmt::wmemory_buffer;
|
||||||
using fmt::fill;
|
using fmt::fill;
|
||||||
using fmt::type;
|
using fmt::type;
|
||||||
using fmt::width;
|
using fmt::width;
|
||||||
@ -109,7 +109,8 @@ void std_format(long double value, std::wstring &result) {
|
|||||||
// as writing it to std::basic_ostringstream<Char>.
|
// as writing it to std::basic_ostringstream<Char>.
|
||||||
template <typename Char, typename T>
|
template <typename Char, typename T>
|
||||||
::testing::AssertionResult check_write(const T &value, const char *type) {
|
::testing::AssertionResult check_write(const T &value, const char *type) {
|
||||||
fmt::BasicMemoryWriter<Char> writer;
|
fmt::basic_memory_buffer<Char> buffer;
|
||||||
|
fmt::basic_writer<Char> writer(buffer);
|
||||||
writer.write(value);
|
writer.write(value);
|
||||||
std::basic_string<Char> actual = writer.str();
|
std::basic_string<Char> actual = writer.str();
|
||||||
std::basic_string<Char> expected;
|
std::basic_string<Char> expected;
|
||||||
@ -177,90 +178,16 @@ TEST(WriterTest, NotCopyAssignable) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST(WriterTest, Ctor) {
|
TEST(WriterTest, Ctor) {
|
||||||
MemoryWriter w;
|
memory_buffer buf;
|
||||||
|
fmt::basic_writer<char> w(buf);
|
||||||
EXPECT_EQ(0u, w.size());
|
EXPECT_EQ(0u, w.size());
|
||||||
EXPECT_STREQ("", w.c_str());
|
EXPECT_STREQ("", w.c_str());
|
||||||
EXPECT_EQ("", w.str());
|
EXPECT_EQ("", w.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_USE_RVALUE_REFERENCES
|
|
||||||
|
|
||||||
void check_move_writer(const std::string &str, MemoryWriter &w) {
|
|
||||||
MemoryWriter w2(std::move(w));
|
|
||||||
// Move shouldn't destroy the inline content of the first writer.
|
|
||||||
EXPECT_EQ(str, w.str());
|
|
||||||
EXPECT_EQ(str, w2.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(WriterTest, MoveCtor) {
|
|
||||||
MemoryWriter w;
|
|
||||||
w.write("test");
|
|
||||||
check_move_writer("test", w);
|
|
||||||
// This fills the inline buffer, but doesn't cause dynamic allocation.
|
|
||||||
std::string s;
|
|
||||||
for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i)
|
|
||||||
s += '*';
|
|
||||||
w.clear();
|
|
||||||
w.write(s);
|
|
||||||
check_move_writer(s, w);
|
|
||||||
const char *inline_buffer_ptr = w.data();
|
|
||||||
// Adding one more character causes the content to move from the inline to
|
|
||||||
// a dynamically allocated buffer.
|
|
||||||
w.write('*');
|
|
||||||
MemoryWriter w2(std::move(w));
|
|
||||||
// Move should rip the guts of the first writer.
|
|
||||||
EXPECT_EQ(inline_buffer_ptr, w.data());
|
|
||||||
EXPECT_EQ(s + '*', w2.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckMoveAssignWriter(const std::string &str, MemoryWriter &w) {
|
|
||||||
MemoryWriter w2;
|
|
||||||
w2 = std::move(w);
|
|
||||||
// Move shouldn't destroy the inline content of the first writer.
|
|
||||||
EXPECT_EQ(str, w.str());
|
|
||||||
EXPECT_EQ(str, w2.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(WriterTest, MoveAssignment) {
|
|
||||||
MemoryWriter w;
|
|
||||||
w.write("test");
|
|
||||||
CheckMoveAssignWriter("test", w);
|
|
||||||
// This fills the inline buffer, but doesn't cause dynamic allocation.
|
|
||||||
std::string s;
|
|
||||||
for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i)
|
|
||||||
s += '*';
|
|
||||||
w.clear();
|
|
||||||
w.write(s);
|
|
||||||
CheckMoveAssignWriter(s, w);
|
|
||||||
const char *inline_buffer_ptr = w.data();
|
|
||||||
// Adding one more character causes the content to move from the inline to
|
|
||||||
// a dynamically allocated buffer.
|
|
||||||
w.write('*');
|
|
||||||
MemoryWriter w2;
|
|
||||||
w2 = std::move(w);
|
|
||||||
// Move should rip the guts of the first writer.
|
|
||||||
EXPECT_EQ(inline_buffer_ptr, w.data());
|
|
||||||
EXPECT_EQ(s + '*', w2.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // FMT_USE_RVALUE_REFERENCES
|
|
||||||
|
|
||||||
TEST(WriterTest, Allocator) {
|
|
||||||
typedef testing::StrictMock< MockAllocator<char> > MockAllocator;
|
|
||||||
typedef AllocatorRef<MockAllocator> TestAllocator;
|
|
||||||
MockAllocator alloc;
|
|
||||||
fmt::BasicMemoryWriter<char, TestAllocator> w((TestAllocator(&alloc)));
|
|
||||||
std::size_t size =
|
|
||||||
static_cast<std::size_t>(1.5 * fmt::internal::INLINE_BUFFER_SIZE);
|
|
||||||
std::vector<char> mem(size);
|
|
||||||
EXPECT_CALL(alloc, allocate(size)).WillOnce(testing::Return(&mem[0]));
|
|
||||||
for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE + 1; ++i)
|
|
||||||
w.write('*');
|
|
||||||
EXPECT_CALL(alloc, deallocate(&mem[0], size));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(WriterTest, Data) {
|
TEST(WriterTest, Data) {
|
||||||
MemoryWriter w;
|
memory_buffer buf;
|
||||||
|
fmt::basic_writer<char> w(buf);
|
||||||
w.write(42);
|
w.write(42);
|
||||||
EXPECT_EQ("42", std::string(w.data(), w.size()));
|
EXPECT_EQ("42", std::string(w.data(), w.size()));
|
||||||
}
|
}
|
||||||
@ -312,13 +239,15 @@ TEST(WriterTest, WriteLongDouble) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(WriterTest, WriteDoubleAtBufferBoundary) {
|
TEST(WriterTest, WriteDoubleAtBufferBoundary) {
|
||||||
MemoryWriter writer;
|
memory_buffer buf;
|
||||||
|
fmt::basic_writer<char> writer(buf);
|
||||||
for (int i = 0; i < 100; ++i)
|
for (int i = 0; i < 100; ++i)
|
||||||
writer.write(1.23456789);
|
writer.write(1.23456789);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(WriterTest, WriteDoubleWithFilledBuffer) {
|
TEST(WriterTest, WriteDoubleWithFilledBuffer) {
|
||||||
MemoryWriter writer;
|
memory_buffer buf;
|
||||||
|
fmt::basic_writer<char> writer(buf);
|
||||||
// Fill the buffer.
|
// Fill the buffer.
|
||||||
for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i)
|
for (int i = 0; i < fmt::internal::INLINE_BUFFER_SIZE; ++i)
|
||||||
writer.write(' ');
|
writer.write(' ');
|
||||||
@ -349,7 +278,8 @@ TEST(WriterTest, WriteWideString) {
|
|||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
std::string write_str(T... args) {
|
std::string write_str(T... args) {
|
||||||
MemoryWriter writer;
|
memory_buffer buf;
|
||||||
|
fmt::basic_writer<char> writer(buf);
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
writer.write(args...);
|
writer.write(args...);
|
||||||
return writer.str();
|
return writer.str();
|
||||||
@ -357,7 +287,8 @@ std::string write_str(T... args) {
|
|||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
std::wstring write_wstr(T... args) {
|
std::wstring write_wstr(T... args) {
|
||||||
WMemoryWriter writer;
|
wmemory_buffer buf;
|
||||||
|
fmt::basic_writer<wchar_t> writer(buf);
|
||||||
using namespace fmt;
|
using namespace fmt;
|
||||||
writer.write(args...);
|
writer.write(args...);
|
||||||
return writer.str();
|
return writer.str();
|
||||||
@ -447,7 +378,8 @@ TEST(WriterTest, pad) {
|
|||||||
EXPECT_EQ(" 33", write_str(33ll, width=7));
|
EXPECT_EQ(" 33", write_str(33ll, width=7));
|
||||||
EXPECT_EQ(" 44", write_str(44ull, width=7));
|
EXPECT_EQ(" 44", write_str(44ull, width=7));
|
||||||
|
|
||||||
MemoryWriter w;
|
memory_buffer buf;
|
||||||
|
fmt::basic_writer<char> w(buf);
|
||||||
w.clear();
|
w.clear();
|
||||||
w.write(42, fmt::width=5, fmt::fill='0');
|
w.write(42, fmt::width=5, fmt::fill='0');
|
||||||
EXPECT_EQ("00042", w.str());
|
EXPECT_EQ("00042", w.str());
|
||||||
@ -475,13 +407,13 @@ TEST(WriterTest, WWriter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatToTest, FormatWithoutArgs) {
|
TEST(FormatToTest, FormatWithoutArgs) {
|
||||||
fmt::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
format_to(buffer, "test");
|
format_to(buffer, "test");
|
||||||
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
|
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatToTest, Format) {
|
TEST(FormatToTest, Format) {
|
||||||
fmt::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
format_to(buffer, "part{0}", 1);
|
format_to(buffer, "part{0}", 1);
|
||||||
EXPECT_EQ(strlen("part1"), buffer.size());
|
EXPECT_EQ(strlen("part1"), buffer.size());
|
||||||
EXPECT_EQ("part1", std::string(buffer.data(), buffer.size()));
|
EXPECT_EQ("part1", std::string(buffer.data(), buffer.size()));
|
||||||
@ -1370,18 +1302,9 @@ TEST(FormatterTest, FormatExamples) {
|
|||||||
EXPECT_EQ("42", format("{}", 42));
|
EXPECT_EQ("42", format("{}", 42));
|
||||||
EXPECT_EQ("42", format(std::string("{}"), 42));
|
EXPECT_EQ("42", format(std::string("{}"), 42));
|
||||||
|
|
||||||
MemoryWriter out;
|
memory_buffer out;
|
||||||
out.write("The answer is ");
|
format_to(out, "The answer is {}.", 42);
|
||||||
out.write(42);
|
EXPECT_EQ("The answer is 42.", to_string(out));
|
||||||
out.write("\n");
|
|
||||||
|
|
||||||
{
|
|
||||||
MemoryWriter writer;
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
format_to(writer.buffer(), "{}", i);
|
|
||||||
std::string s = writer.str(); // s == 0123456789
|
|
||||||
EXPECT_EQ("0123456789", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *filename = "nonexistent";
|
const char *filename = "nonexistent";
|
||||||
FILE *ftest = safe_fopen(filename, "r");
|
FILE *ftest = safe_fopen(filename, "r");
|
||||||
@ -1522,7 +1445,7 @@ 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) {
|
||||||
fmt::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
format_to(buffer, "[{}] ", id);
|
format_to(buffer, "[{}] ", id);
|
||||||
vformat_to(buffer, format, args);
|
vformat_to(buffer, format, args);
|
||||||
return to_string(buffer);
|
return to_string(buffer);
|
||||||
@ -1612,7 +1535,7 @@ 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::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
fmt::vformat_to<MockArgFormatter>(buffer, format_str, args);
|
fmt::vformat_to<MockArgFormatter>(buffer, format_str, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,9 +319,9 @@ TEST(StreamingAssertionsTest, EXPECT_WRITE) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(UtilTest, FormatSystemError) {
|
TEST(UtilTest, FormatSystemError) {
|
||||||
fmt::MemoryWriter out;
|
fmt::memory_buffer out;
|
||||||
fmt::format_system_error(out.buffer(), EDOM, "test message");
|
fmt::format_system_error(out, EDOM, "test message");
|
||||||
EXPECT_EQ(out.str(), format_system_error(EDOM, "test message"));
|
EXPECT_EQ(to_string(out), format_system_error(EDOM, "test message"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FMT_USE_FILE_DESCRIPTORS
|
#if FMT_USE_FILE_DESCRIPTORS
|
||||||
|
@ -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::string_view message) {
|
std::string format_system_error(int error_code, fmt::string_view message) {
|
||||||
fmt::internal::MemoryBuffer<char> out;
|
fmt::memory_buffer out;
|
||||||
fmt::format_system_error(out, error_code, message);
|
format_system_error(out, error_code, message);
|
||||||
return to_string(out);
|
return to_string(out);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ struct TestArgFormatter : fmt::arg_formatter<char> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST(OStreamTest, CustomArg) {
|
TEST(OStreamTest, CustomArg) {
|
||||||
fmt::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
fmt::context ctx("}", fmt::args());
|
fmt::context ctx("}", fmt::args());
|
||||||
fmt::format_specs spec;
|
fmt::format_specs spec;
|
||||||
TestArgFormatter af(buffer, ctx, spec);
|
TestArgFormatter af(buffer, ctx, spec);
|
||||||
@ -121,7 +121,7 @@ TEST(OStreamTest, Print) {
|
|||||||
|
|
||||||
TEST(OStreamTest, WriteToOStream) {
|
TEST(OStreamTest, WriteToOStream) {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
fmt::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
const char *foo = "foo";
|
const char *foo = "foo";
|
||||||
buffer.append(foo, foo + std::strlen(foo));
|
buffer.append(foo, foo + std::strlen(foo));
|
||||||
fmt::internal::write(os, buffer);
|
fmt::internal::write(os, buffer);
|
||||||
|
@ -54,8 +54,8 @@
|
|||||||
|
|
||||||
using fmt::basic_arg;
|
using fmt::basic_arg;
|
||||||
using fmt::basic_buffer;
|
using fmt::basic_buffer;
|
||||||
|
using fmt::basic_memory_buffer;
|
||||||
using fmt::string_view;
|
using fmt::string_view;
|
||||||
using fmt::internal::MemoryBuffer;
|
|
||||||
using fmt::internal::value;
|
using fmt::internal::value;
|
||||||
|
|
||||||
using testing::_;
|
using testing::_;
|
||||||
@ -238,7 +238,7 @@ TEST(BufferTest, AppendAllocatesEnoughStorage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemoryBufferTest, Ctor) {
|
TEST(MemoryBufferTest, Ctor) {
|
||||||
MemoryBuffer<char, 123> buffer;
|
basic_memory_buffer<char, 123> buffer;
|
||||||
EXPECT_EQ(0u, buffer.size());
|
EXPECT_EQ(0u, buffer.size());
|
||||||
EXPECT_EQ(123u, buffer.capacity());
|
EXPECT_EQ(123u, buffer.capacity());
|
||||||
}
|
}
|
||||||
@ -248,9 +248,9 @@ TEST(MemoryBufferTest, Ctor) {
|
|||||||
typedef AllocatorRef< std::allocator<char> > TestAllocator;
|
typedef AllocatorRef< std::allocator<char> > TestAllocator;
|
||||||
|
|
||||||
void check_move_buffer(const char *str,
|
void check_move_buffer(const char *str,
|
||||||
MemoryBuffer<char, 5, TestAllocator> &buffer) {
|
basic_memory_buffer<char, 5, TestAllocator> &buffer) {
|
||||||
std::allocator<char> *alloc = buffer.get_allocator().get();
|
std::allocator<char> *alloc = buffer.get_allocator().get();
|
||||||
MemoryBuffer<char, 5, TestAllocator> buffer2(std::move(buffer));
|
basic_memory_buffer<char, 5, TestAllocator> buffer2(std::move(buffer));
|
||||||
// Move shouldn't destroy the inline content of the first buffer.
|
// Move shouldn't destroy the inline content of the first buffer.
|
||||||
EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
|
EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
|
||||||
EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
|
EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
|
||||||
@ -262,7 +262,7 @@ void check_move_buffer(const char *str,
|
|||||||
|
|
||||||
TEST(MemoryBufferTest, MoveCtor) {
|
TEST(MemoryBufferTest, MoveCtor) {
|
||||||
std::allocator<char> alloc;
|
std::allocator<char> alloc;
|
||||||
MemoryBuffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc)));
|
basic_memory_buffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc)));
|
||||||
const char test[] = "test";
|
const char test[] = "test";
|
||||||
buffer.append(test, test + 4);
|
buffer.append(test, test + 4);
|
||||||
check_move_buffer("test", buffer);
|
check_move_buffer("test", buffer);
|
||||||
@ -274,15 +274,16 @@ TEST(MemoryBufferTest, MoveCtor) {
|
|||||||
// Adding one more character causes the content to move from the inline to
|
// Adding one more character causes the content to move from the inline to
|
||||||
// a dynamically allocated buffer.
|
// a dynamically allocated buffer.
|
||||||
buffer.push_back('b');
|
buffer.push_back('b');
|
||||||
MemoryBuffer<char, 5, TestAllocator> buffer2(std::move(buffer));
|
basic_memory_buffer<char, 5, TestAllocator> buffer2(std::move(buffer));
|
||||||
// Move should rip the guts of the first buffer.
|
// Move should rip the guts of the first buffer.
|
||||||
EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
|
EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
|
||||||
EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size()));
|
EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size()));
|
||||||
EXPECT_GT(buffer2.capacity(), 5u);
|
EXPECT_GT(buffer2.capacity(), 5u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_move_assign_buffer(const char *str, MemoryBuffer<char, 5> &buffer) {
|
void check_move_assign_buffer(
|
||||||
MemoryBuffer<char, 5> buffer2;
|
const char *str, basic_memory_buffer<char, 5> &buffer) {
|
||||||
|
basic_memory_buffer<char, 5> buffer2;
|
||||||
buffer2 = std::move(buffer);
|
buffer2 = std::move(buffer);
|
||||||
// Move shouldn't destroy the inline content of the first buffer.
|
// Move shouldn't destroy the inline content of the first buffer.
|
||||||
EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
|
EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
|
||||||
@ -291,7 +292,7 @@ void check_move_assign_buffer(const char *str, MemoryBuffer<char, 5> &buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(MemoryBufferTest, MoveAssignment) {
|
TEST(MemoryBufferTest, MoveAssignment) {
|
||||||
MemoryBuffer<char, 5> buffer;
|
basic_memory_buffer<char, 5> buffer;
|
||||||
const char test[] = "test";
|
const char test[] = "test";
|
||||||
buffer.append(test, test + 4);
|
buffer.append(test, test + 4);
|
||||||
check_move_assign_buffer("test", buffer);
|
check_move_assign_buffer("test", buffer);
|
||||||
@ -303,7 +304,7 @@ TEST(MemoryBufferTest, MoveAssignment) {
|
|||||||
// Adding one more character causes the content to move from the inline to
|
// Adding one more character causes the content to move from the inline to
|
||||||
// a dynamically allocated buffer.
|
// a dynamically allocated buffer.
|
||||||
buffer.push_back('b');
|
buffer.push_back('b');
|
||||||
MemoryBuffer<char, 5> buffer2;
|
basic_memory_buffer<char, 5> buffer2;
|
||||||
buffer2 = std::move(buffer);
|
buffer2 = std::move(buffer);
|
||||||
// Move should rip the guts of the first buffer.
|
// Move should rip the guts of the first buffer.
|
||||||
EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
|
EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
|
||||||
@ -315,7 +316,7 @@ TEST(MemoryBufferTest, MoveAssignment) {
|
|||||||
|
|
||||||
TEST(MemoryBufferTest, Grow) {
|
TEST(MemoryBufferTest, Grow) {
|
||||||
typedef AllocatorRef< MockAllocator<int> > Allocator;
|
typedef AllocatorRef< MockAllocator<int> > Allocator;
|
||||||
typedef MemoryBuffer<int, 10, Allocator> Base;
|
typedef basic_memory_buffer<int, 10, Allocator> Base;
|
||||||
MockAllocator<int> alloc;
|
MockAllocator<int> alloc;
|
||||||
struct TestMemoryBuffer : Base {
|
struct TestMemoryBuffer : Base {
|
||||||
TestMemoryBuffer(Allocator alloc) : Base(alloc) {}
|
TestMemoryBuffer(Allocator alloc) : Base(alloc) {}
|
||||||
@ -341,12 +342,12 @@ TEST(MemoryBufferTest, Grow) {
|
|||||||
|
|
||||||
TEST(MemoryBufferTest, Allocator) {
|
TEST(MemoryBufferTest, Allocator) {
|
||||||
typedef AllocatorRef< MockAllocator<char> > TestAllocator;
|
typedef AllocatorRef< MockAllocator<char> > TestAllocator;
|
||||||
MemoryBuffer<char, 10, TestAllocator> buffer;
|
basic_memory_buffer<char, 10, TestAllocator> buffer;
|
||||||
EXPECT_EQ(0, buffer.get_allocator().get());
|
EXPECT_EQ(0, buffer.get_allocator().get());
|
||||||
StrictMock< MockAllocator<char> > alloc;
|
StrictMock< MockAllocator<char> > alloc;
|
||||||
char mem;
|
char mem;
|
||||||
{
|
{
|
||||||
MemoryBuffer<char, 10, TestAllocator> buffer2((TestAllocator(&alloc)));
|
basic_memory_buffer<char, 10, TestAllocator> buffer2((TestAllocator(&alloc)));
|
||||||
EXPECT_EQ(&alloc, buffer2.get_allocator().get());
|
EXPECT_EQ(&alloc, buffer2.get_allocator().get());
|
||||||
std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
|
std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
|
||||||
EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem));
|
EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem));
|
||||||
@ -358,7 +359,7 @@ TEST(MemoryBufferTest, Allocator) {
|
|||||||
TEST(MemoryBufferTest, ExceptionInDeallocate) {
|
TEST(MemoryBufferTest, ExceptionInDeallocate) {
|
||||||
typedef AllocatorRef< MockAllocator<char> > TestAllocator;
|
typedef AllocatorRef< MockAllocator<char> > TestAllocator;
|
||||||
StrictMock< MockAllocator<char> > alloc;
|
StrictMock< MockAllocator<char> > alloc;
|
||||||
MemoryBuffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc)));
|
basic_memory_buffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc)));
|
||||||
std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
|
std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
|
||||||
std::vector<char> mem(size);
|
std::vector<char> mem(size);
|
||||||
{
|
{
|
||||||
@ -435,7 +436,7 @@ 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::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
arg.custom.format(buffer, &t, &ctx);
|
arg.custom.format(buffer, &t, &ctx);
|
||||||
EXPECT_TRUE(ctx.called);
|
EXPECT_TRUE(ctx.called);
|
||||||
}
|
}
|
||||||
@ -579,7 +580,7 @@ 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::internal::MemoryBuffer<char> buffer;
|
fmt::memory_buffer buffer;
|
||||||
fmt::context ctx("}", fmt::args());
|
fmt::context ctx("}", fmt::args());
|
||||||
custom.format(buffer, &test, &ctx);
|
custom.format(buffer, &test, &ctx);
|
||||||
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
|
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
|
||||||
@ -710,14 +711,14 @@ void check_throw_error(int error_code, FormatErrorMessage format) {
|
|||||||
} catch (const fmt::SystemError &e) {
|
} catch (const fmt::SystemError &e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
fmt::internal::MemoryBuffer<char> message;
|
fmt::memory_buffer message;
|
||||||
format(message, error_code, "test error");
|
format(message, error_code, "test error");
|
||||||
EXPECT_EQ(to_string(message), 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::internal::MemoryBuffer<char> message;
|
fmt::memory_buffer message;
|
||||||
fmt::format_system_error(message, EDOM, "test");
|
fmt::format_system_error(message, EDOM, "test");
|
||||||
EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)),
|
EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)),
|
||||||
to_string(message));
|
to_string(message));
|
||||||
@ -735,7 +736,7 @@ TEST(UtilTest, SystemError) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(UtilTest, ReportSystemError) {
|
TEST(UtilTest, ReportSystemError) {
|
||||||
fmt::internal::MemoryBuffer<char> out;
|
fmt::memory_buffer out;
|
||||||
fmt::format_system_error(out, EDOM, "test error");
|
fmt::format_system_error(out, EDOM, "test error");
|
||||||
out.push_back('\n');
|
out.push_back('\n');
|
||||||
EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"),
|
EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user