Pass buffer instead of writer to format_value

This commit is contained in:
Victor Zverovich
2017-02-14 16:29:47 -05:00
parent 6e568f3a08
commit fefaf07b6f
13 changed files with 258 additions and 297 deletions
+11 -11
View File
@@ -16,9 +16,9 @@ using fmt::PrintfArgFormatter;
// rounded to 0.
class CustomArgFormatter : public fmt::ArgFormatter<char> {
public:
CustomArgFormatter(fmt::writer &w, fmt::basic_context<char> &ctx,
CustomArgFormatter(fmt::buffer &buf, fmt::basic_context<char> &ctx,
fmt::format_specs &s)
: fmt::ArgFormatter<char>(w, ctx, s) {}
: fmt::ArgFormatter<char>(buf, ctx, s) {}
using fmt::ArgFormatter<char>::operator();
@@ -33,8 +33,8 @@ class CustomArgFormatter : public fmt::ArgFormatter<char> {
// rounded to 0.
class CustomPrintfArgFormatter : public PrintfArgFormatter<char> {
public:
CustomPrintfArgFormatter(fmt::basic_writer<char> &w, fmt::format_specs &spec)
: PrintfArgFormatter<char>(w, spec) {}
CustomPrintfArgFormatter(fmt::buffer &buf, fmt::format_specs &spec)
: PrintfArgFormatter<char>(buf, spec) {}
using PrintfArgFormatter<char>::operator();
@@ -46,10 +46,10 @@ class CustomPrintfArgFormatter : public PrintfArgFormatter<char> {
};
std::string custom_vformat(fmt::CStringRef format_str, fmt::args args) {
fmt::MemoryWriter writer;
// Pass custom argument formatter as a template arg to vformat.
fmt::vwrite<CustomArgFormatter>(writer, format_str, args);
return writer.str();
fmt::internal::MemoryBuffer<char> buffer;
// Pass custom argument formatter as a template arg to vwrite.
fmt::vformat_to<CustomArgFormatter>(buffer, format_str, args);
return std::string(buffer.data(), buffer.size());
}
template <typename... Args>
@@ -64,10 +64,10 @@ typedef fmt::printf_context<char, CustomPrintfArgFormatter>
std::string custom_vsprintf(
const char* format_str,
fmt::basic_args<CustomPrintfFormatter> args) {
fmt::MemoryWriter writer;
fmt::internal::MemoryBuffer<char> buffer;
CustomPrintfFormatter formatter(format_str, args);
formatter.format(writer);
return writer.str();
formatter.format(buffer);
return std::string(buffer.data(), buffer.size());
}
template <typename... Args>
+4 -4
View File
@@ -107,14 +107,14 @@ TEST(FormatTest, FormatErrorCode) {
{
fmt::MemoryWriter w;
w.write("garbage");
fmt::format_error_code(w, 42, "test");
fmt::format_error_code(w.buffer(), 42, "test");
EXPECT_EQ("test: " + msg, w.str());
}
{
fmt::MemoryWriter w;
std::string prefix(
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());
}
int codes[] = {42, -1};
@@ -124,14 +124,14 @@ TEST(FormatTest, FormatErrorCode) {
fmt::MemoryWriter w;
std::string prefix(
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());
std::size_t size = fmt::internal::INLINE_BUFFER_SIZE;
EXPECT_EQ(size, w.size());
w.clear();
// Test with a message that doesn't fit into the buffer.
prefix += 'x';
fmt::format_error_code(w, codes[i], prefix);
fmt::format_error_code(w.buffer(), codes[i], prefix);
EXPECT_EQ(msg, w.str());
}
}
+35 -50
View File
@@ -265,12 +265,6 @@ TEST(WriterTest, Data) {
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) {
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'*'));
}
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) {
EXPECT_EQ(L"cafe", write_wstr(0xcafe, type='x'));
}
@@ -501,32 +481,43 @@ TEST(ArrayWriterTest, Ctor) {
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) {
char array[10] = "garbage";
fmt::ArrayWriter w(array);
EXPECT_EQ(0u, w.size());
EXPECT_STREQ("", w.c_str());
w.format("{:10}", 1);
}
TEST(ArrayWriterTest, Write) {
char array[10];
fmt::ArrayWriter w(array, sizeof(array));
w.format("{}", 42);
EXPECT_EQ("42", w.str());
format_to(w.buffer(), "{:10}", 1);
}
TEST(ArrayWriterTest, BufferOverflow) {
char array[10];
fmt::ArrayWriter w(array, sizeof(array));
w.format("{:10}", 1);
EXPECT_THROW_MSG(w.format("{}", 1), std::runtime_error, "buffer overflow");
format_to(w.buffer(), "{:10}", 1);
EXPECT_THROW_MSG(format_to(w.buffer(), "{}", 1), std::runtime_error,
"buffer overflow");
}
TEST(ArrayWriterTest, WChar) {
wchar_t array[10];
fmt::WArrayWriter w(array);
w.format(L"{}", 42);
format_to(w.buffer(), L"{}", 42);
EXPECT_EQ(L"42", w.str());
}
@@ -1366,12 +1357,8 @@ TEST(FormatterTest, FormatCStringRef) {
EXPECT_EQ("test", format("{0}", CStringRef("test")));
}
void format_value(fmt::writer &w, const Date &d, fmt::context &) {
w.write(d.year());
w.write('-');
w.write(d.month());
w.write('-');
w.write(d.day());
void format_value(fmt::buffer &buf, const Date &d, fmt::context &) {
fmt::format_to(buf, "{}-{}-{}", d.year(), d.month(), d.day());
}
TEST(FormatterTest, FormatCustom) {
@@ -1383,8 +1370,8 @@ TEST(FormatterTest, FormatCustom) {
class Answer {};
template <typename Char>
void format_value(basic_writer<Char> &w, Answer, fmt::context &) {
w.write("42");
void format_value(fmt::basic_buffer<Char> &buf, Answer, fmt::context &) {
fmt::format_to(buf, "{}", 42);
}
TEST(FormatterTest, CustomFormat) {
@@ -1417,13 +1404,11 @@ TEST(FormatterTest, FormatExamples) {
out.write("The answer is ");
out.write(42);
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;
for (int i = 0; i < 10; i++)
writer.format("{}", i);
format_to(writer.buffer(), "{}", i);
std::string s = writer.str(); // s == 0123456789
EXPECT_EQ("0123456789", s);
}
@@ -1567,10 +1552,10 @@ TEST(StrTest, Convert) {
}
std::string vformat_message(int id, const char *format, fmt::args args) {
MemoryWriter w;
w.format("[{}] ", id);
w.vformat(format, args);
return w.str();
fmt::internal::MemoryBuffer<char> buffer;
format_to(buffer, "[{}] ", id);
vformat_to(buffer, format, args);
return to_string(buffer);
}
template <typename... Args>
@@ -1643,9 +1628,9 @@ class MockArgFormatter : public fmt::internal::ArgFormatterBase<char> {
public:
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::internal::ArgFormatterBase<char>(w, s) {
: fmt::internal::ArgFormatterBase<char>(b, s) {
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) {
fmt::MemoryWriter writer;
fmt::vwrite<MockArgFormatter>(writer, format_str, args);
fmt::internal::MemoryBuffer<char> buffer;
fmt::vformat_to<MockArgFormatter>(buffer, format_str, args);
}
template <typename... Args>
+1 -1
View File
@@ -320,7 +320,7 @@ TEST(StreamingAssertionsTest, EXPECT_WRITE) {
TEST(UtilTest, FormatSystemError) {
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"));
}
+2 -2
View File
@@ -104,7 +104,7 @@ std::string read(File &f, std::size_t count) {
#endif // FMT_USE_FILE_DESCRIPTORS
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);
return out.str();
return to_string(out);
}
+17 -22
View File
@@ -59,17 +59,17 @@ TEST(OStreamTest, Enum) {
}
struct TestArgFormatter : fmt::ArgFormatter<char> {
TestArgFormatter(fmt::writer &w, fmt::context &ctx, fmt::format_specs &s)
: fmt::ArgFormatter<char>(w, ctx, s) {}
TestArgFormatter(fmt::buffer &buf, fmt::context &ctx, fmt::format_specs &s)
: fmt::ArgFormatter<char>(buf, ctx, s) {}
};
TEST(OStreamTest, CustomArg) {
fmt::MemoryWriter writer;
fmt::internal::MemoryBuffer<char> buffer;
fmt::context ctx("}", fmt::args());
fmt::format_specs spec;
TestArgFormatter af(writer, ctx, spec);
TestArgFormatter af(buffer, ctx, spec);
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) {
@@ -121,9 +121,10 @@ TEST(OStreamTest, Print) {
TEST(OStreamTest, WriteToOStream) {
std::ostringstream os;
fmt::MemoryWriter w;
w.write("foo");
fmt::internal::write(os, w);
fmt::internal::MemoryBuffer<char> buffer;
const char *foo = "foo";
buffer.append(foo, foo + std::strlen(foo));
fmt::internal::write(os, buffer);
EXPECT_EQ("foo", os.str());
}
@@ -133,16 +134,10 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
if (max_size <= fmt::internal::to_unsigned(max_streamsize))
return;
class TestWriter : public fmt::basic_writer<char> {
private:
struct TestBuffer : fmt::basic_buffer<char> {
explicit TestBuffer(std::size_t size) { size_ = 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 TestBuffer : fmt::basic_buffer<char> {
explicit TestBuffer(std::size_t size) { size_ = size; }
void grow(std::size_t) {}
} buffer(max_size);
struct MockStreamBuf : std::streambuf {
MOCK_METHOD2(xsputn, std::streamsize (const void *s, std::streamsize n));
@@ -150,11 +145,11 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
const void *v = s;
return xsputn(v, n);
}
} buffer;
} streambuf;
struct TestOStream : std::ostream {
explicit TestOStream(MockStreamBuf &buffer) : std::ostream(&buffer) {}
} os(buffer);
} os(streambuf);
testing::InSequence sequence;
const char *data = 0;
@@ -163,10 +158,10 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
typedef fmt::internal::MakeUnsigned<std::streamsize>::Type UStreamSize;
UStreamSize n = std::min<UStreamSize>(
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));
data += n;
size -= static_cast<std::size_t>(n);
} while (size != 0);
fmt::internal::write(os, w);
fmt::internal::write(os, buffer);
}
+20 -17
View File
@@ -67,9 +67,10 @@ namespace {
struct Test {};
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> &) {
w.write("test");
const Char *test = "test";
b.append(test, test + std::strlen(test));
}
template <typename Context, typename T>
@@ -416,7 +417,7 @@ struct CustomContext {
bool called;
};
void format_value(fmt::writer &, const Test &, CustomContext &ctx) {
void format_value(fmt::buffer &, const Test &, CustomContext &ctx) {
ctx.called = true;
}
@@ -424,8 +425,8 @@ TEST(UtilTest, MakeValueWithCustomFormatter) {
::Test t;
fmt::internal::value<CustomContext> arg(t);
CustomContext ctx = {false};
fmt::MemoryWriter w;
arg.custom.format(w, &t, &ctx);
fmt::internal::MemoryBuffer<char> buffer;
arg.custom.format(buffer, &t, &ctx);
EXPECT_TRUE(ctx.called);
}
@@ -568,10 +569,10 @@ TEST(UtilTest, CustomArg) {
EXPECT_CALL(visitor, visit(_)).WillOnce(
testing::Invoke([&](fmt::internal::CustomValue<char> custom) {
EXPECT_EQ(&test, custom.value);
fmt::MemoryWriter w;
fmt::internal::MemoryBuffer<char> buffer;
fmt::context ctx("}", fmt::args());
custom.format(w, &test, &ctx);
EXPECT_EQ("test", w.str());
custom.format(buffer, &test, &ctx);
EXPECT_EQ("test", std::string(buffer.data(), buffer.size()));
return Visitor::Result();
}));
fmt::visit(visitor, make_arg<fmt::context>(test));
@@ -689,7 +690,7 @@ TEST(UtilTest, UTF16ToUTF8Convert) {
#endif // _WIN32
typedef void (*FormatErrorMessage)(
fmt::writer &out, int error_code, StringRef message);
fmt::buffer &out, int error_code, StringRef message);
template <typename Error>
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) {
error = e;
}
fmt::MemoryWriter message;
fmt::internal::MemoryBuffer<char> message;
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());
}
TEST(UtilTest, FormatSystemError) {
fmt::MemoryWriter message;
fmt::internal::MemoryBuffer<char> message;
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();
fmt::format_system_error(
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) {
@@ -723,10 +725,11 @@ TEST(UtilTest, SystemError) {
}
TEST(UtilTest, ReportSystemError) {
fmt::MemoryWriter out;
fmt::internal::MemoryBuffer<char> out;
fmt::format_system_error(out, EDOM, "test error");
out.write('\n');
EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"), out.str());
out.push_back('\n');
EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"),
to_string(out));
}
#ifdef _WIN32