From 422236af7c07da132d9c487e9f124d53609d5c86 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Wed, 28 Dec 2016 07:55:33 -0800 Subject: [PATCH] Don't erase writer type --- fmt/format.h | 21 +++++++++++---------- fmt/printf.h | 4 ++-- test/format-test.cc | 2 +- test/util-test.cc | 11 ++++++----- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/fmt/format.h b/fmt/format.h index dc8ce0c9..723e5395 100644 --- a/fmt/format.h +++ b/fmt/format.h @@ -1089,9 +1089,11 @@ struct StringValue { std::size_t size; }; -typedef void (*FormatFunc)(void *writer, const void *arg, void *ctx); - +template struct CustomValue { + typedef void (*FormatFunc)( + BasicWriter &writer, const void *arg, void *ctx); + const void *value; FormatFunc format; }; @@ -1111,7 +1113,7 @@ struct Value { StringValue sstring; StringValue ustring; StringValue tstring; - CustomValue custom; + CustomValue custom; }; }; @@ -1216,9 +1218,8 @@ class MakeValue : public Value { // Formats an argument of a custom type, such as a user-defined class. template static void format_custom_arg( - void *writer, const void *arg, void *context) { - format_value(*static_cast*>(writer), - *static_cast(arg), + BasicWriter &writer, const void *arg, void *context) { + format_value(writer, *static_cast(arg), *static_cast(context)); } @@ -2140,8 +2141,8 @@ class ArgFormatter : public internal::ArgFormatterBase { using internal::ArgFormatterBase::operator(); /** Formats an argument of a custom (user-defined) type. */ - void operator()(internal::CustomValue c) { - c.format(&this->writer(), c.value, &ctx_); + void operator()(internal::CustomValue c) { + c.format(this->writer(), c.value, &ctx_); } }; @@ -3371,8 +3372,8 @@ class CustomFormatter { CustomFormatter(BasicWriter &writer, Context &ctx) : writer_(writer), ctx_(ctx) {} - bool operator()(internal::CustomValue custom) { - custom.format(&writer_, custom.value, &ctx_); + bool operator()(internal::CustomValue custom) { + custom.format(writer_, custom.value, &ctx_); return true; } diff --git a/fmt/printf.h b/fmt/printf.h index c0064ae7..92d50ef4 100644 --- a/fmt/printf.h +++ b/fmt/printf.h @@ -281,11 +281,11 @@ class PrintfArgFormatter : public internal::ArgFormatterBase { } /** Formats an argument of a custom (user-defined) type. */ - void operator()(internal::CustomValue c) { + void operator()(internal::CustomValue c) { const Char format_str[] = {'}', '\0'}; auto args = basic_format_args, Char>(); basic_format_context ctx(format_str, args); - c.format(&this->writer(), c.value, &ctx); + c.format(this->writer(), c.value, &ctx); } }; diff --git a/test/format-test.cc b/test/format-test.cc index 6829f622..b8693d5e 100644 --- a/test/format-test.cc +++ b/test/format-test.cc @@ -1637,7 +1637,7 @@ class MockArgFormatter : public fmt::internal::ArgFormatterBase { void operator()(int value) { call(value); } - void operator()(fmt::internal::CustomValue) {} + void operator()(fmt::internal::CustomValue) {} }; void custom_vformat(fmt::CStringRef format_str, fmt::format_args args) { diff --git a/test/util-test.cc b/test/util-test.cc index e02b68d8..0e276d52 100644 --- a/test/util-test.cc +++ b/test/util-test.cc @@ -426,14 +426,15 @@ TEST(UtilTest, MakeValueWithCustomFormatter) { fmt::internal::Value arg = fmt::internal::MakeValue(t); CustomFormatter ctx = {false}; fmt::MemoryWriter w; - arg.custom.format(&w, &t, &ctx); + arg.custom.format(w, &t, &ctx); EXPECT_TRUE(ctx.called); } namespace fmt { namespace internal { -bool operator==(CustomValue lhs, CustomValue rhs) { +template +bool operator==(CustomValue lhs, CustomValue rhs) { return lhs.value == rhs.value; } } @@ -563,14 +564,14 @@ TEST(UtilTest, PointerArg) { TEST(UtilTest, CustomArg) { ::Test test; - typedef MockVisitor Visitor; + typedef MockVisitor> Visitor; testing::StrictMock visitor; EXPECT_CALL(visitor, visit(_)).WillOnce( - testing::Invoke([&](fmt::internal::CustomValue custom) { + testing::Invoke([&](fmt::internal::CustomValue custom) { EXPECT_EQ(&test, custom.value); fmt::MemoryWriter w; fmt::format_context ctx("}", fmt::format_args()); - custom.format(&w, &test, &ctx); + custom.format(w, &test, &ctx); EXPECT_EQ("test", w.str()); return Visitor::Result(); }));