Add a fixed-size array writer

This commit is contained in:
Victor Zverovich 2015-03-01 18:08:24 -08:00
parent 63b4f0ae1a
commit beaf6f7436
2 changed files with 107 additions and 9 deletions

View File

@ -436,6 +436,19 @@ void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) {
this->deallocate(old_ptr, old_capacity);
}
// A fixed-size buffer.
template <typename Char>
class FixedBuffer : public fmt::internal::Buffer<Char> {
public:
FixedBuffer(Char *array, std::size_t size)
: fmt::internal::Buffer<Char>(array, size) {}
protected:
void grow(std::size_t size) {
throw std::runtime_error("buffer overflow");
}
};
#ifndef _MSC_VER
// Portable version of signbit.
inline int getsign(double x) {
@ -2111,20 +2124,20 @@ void BasicWriter<Char>::write_double(
/**
\rst
This template provides operations for formatting and writing data into
a character stream. The output is stored in a memory buffer that grows
This class template provides operations for formatting and writing data
into a character stream. The output is stored in 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 | BasicWriter<char, std::allocator<char>> |
+---------------+-----------------------------------------------+
| WMemoryWriter | BasicWriter<wchar_t, std::allocator<wchar_t>> |
+---------------+-----------------------------------------------+
+---------------+-----------------------------------------------------+
| Type | Definition |
+===============+=====================================================+
| MemoryWriter | BasicMemoryWriter<char, std::allocator<char>> |
+---------------+-----------------------------------------------------+
| WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
+---------------+-----------------------------------------------------+
**Example**::
@ -2174,6 +2187,55 @@ class BasicMemoryWriter : public BasicWriter<Char> {
typedef BasicMemoryWriter<char> MemoryWriter;
typedef BasicMemoryWriter<wchar_t> WMemoryWriter;
/**
\rst
This class template provides operations for formatting and writing data
into a fixed-size array. For writing into a dynamically growing buffer
use :class:`fmt::BasicMemoryWriter`.
Any write method will throw std::runtime_error if the output doesn't fit
into the array.
You can use one of the following typedefs for common character types:
+--------------+---------------------------+
| Type | Definition |
+==============+===========================+
| ArrayWriter | BasicArrayWriter<char> |
+--------------+---------------------------+
| WArrayWriter | BasicArrayWriter<wchar_t> |
+--------------+---------------------------+
\endrst
*/
template <typename Char>
class BasicArrayWriter : public BasicWriter<Char> {
private:
internal::FixedBuffer<Char> buffer_;
public:
/**
\rst
Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
given size.
\endrst
*/
BasicArrayWriter(Char *array, std::size_t size)
: BasicWriter<Char>(buffer_), buffer_(array, size) {}
/**
\rst
Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the
size known at compile time.
\endrst
*/
template <std::size_t SIZE>
explicit BasicArrayWriter(Char (&array)[SIZE])
: BasicWriter<Char>(buffer_), buffer_(array, SIZE) {}
};
typedef BasicArrayWriter<char> ArrayWriter;
typedef BasicArrayWriter<wchar_t> WArrayWriter;
// Formats a value.
template <typename Char, typename T>
void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) {

View File

@ -461,6 +461,42 @@ TEST(WriterTest, WWriter) {
EXPECT_EQ(L"cafe", (fmt::WMemoryWriter() << fmt::hex(0xcafe)).str());
}
TEST(ArrayWriterTest, Ctor) {
char array[10] = "garbage";
fmt::ArrayWriter w(array, sizeof(array));
EXPECT_EQ(0u, w.size());
EXPECT_STREQ("", w.c_str());
}
TEST(ArrayWriterTest, CompileTimeSizeCtor) {
char array[10] = "garbage";
fmt::ArrayWriter w(array);
EXPECT_EQ(0u, w.size());
EXPECT_STREQ("", w.c_str());
w.write("{:10}", 1);
}
TEST(ArrayWriterTest, Write) {
char array[10];
fmt::ArrayWriter w(array, sizeof(array));
w.write("{}", 42);
EXPECT_EQ("42", w.str());
}
TEST(ArrayWriterTest, BufferOverflow) {
char array[10];
fmt::ArrayWriter w(array, sizeof(array));
w.write("{:10}", 1);
EXPECT_THROW_MSG(w.write("{}", 1), std::runtime_error, "buffer overflow");
}
TEST(ArrayWriterTest, WChar) {
wchar_t array[10];
fmt::WArrayWriter w(array);
w.write(L"{}", 42);
EXPECT_EQ(L"42", w.str());
}
TEST(FormatterTest, Escape) {
EXPECT_EQ("{", format("{{"));
EXPECT_EQ("before {", format("before {{"));