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); 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 #ifndef _MSC_VER
// Portable version of signbit. // Portable version of signbit.
inline int getsign(double x) { inline int getsign(double x) {
@ -2111,20 +2124,20 @@ void BasicWriter<Char>::write_double(
/** /**
\rst \rst
This template provides operations for formatting and writing data into This class template provides operations for formatting and writing data
a character stream. The output is stored in a memory buffer that grows into a character stream. The output is stored in a memory buffer that grows
dynamically. dynamically.
You can use one of the following typedefs for common character types You can use one of the following typedefs for common character types
and the standard allocator: and the standard allocator:
+---------------+-----------------------------------------------+ +---------------+-----------------------------------------------------+
| Type | Definition | | Type | Definition |
+===============+===============================================+ +===============+=====================================================+
| MemoryWriter | BasicWriter<char, std::allocator<char>> | | MemoryWriter | BasicMemoryWriter<char, std::allocator<char>> |
+---------------+-----------------------------------------------+ +---------------+-----------------------------------------------------+
| WMemoryWriter | BasicWriter<wchar_t, std::allocator<wchar_t>> | | WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> |
+---------------+-----------------------------------------------+ +---------------+-----------------------------------------------------+
**Example**:: **Example**::
@ -2174,6 +2187,55 @@ class BasicMemoryWriter : public BasicWriter<Char> {
typedef BasicMemoryWriter<char> MemoryWriter; typedef BasicMemoryWriter<char> MemoryWriter;
typedef BasicMemoryWriter<wchar_t> WMemoryWriter; 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. // Formats a value.
template <typename Char, typename T> template <typename Char, typename T>
void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) { 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()); 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) { TEST(FormatterTest, Escape) {
EXPECT_EQ("{", format("{{")); EXPECT_EQ("{", format("{{"));
EXPECT_EQ("before {", format("before {{")); EXPECT_EQ("before {", format("before {{"));