Don't erase writer type

This commit is contained in:
Victor Zverovich
2016-12-28 07:55:33 -08:00
parent abb6996f36
commit 422236af7c
4 changed files with 20 additions and 18 deletions

View File

@ -1089,9 +1089,11 @@ struct StringValue {
std::size_t size; std::size_t size;
}; };
typedef void (*FormatFunc)(void *writer, const void *arg, void *ctx); template <typename Char>
struct CustomValue { struct CustomValue {
typedef void (*FormatFunc)(
BasicWriter<Char> &writer, const void *arg, void *ctx);
const void *value; const void *value;
FormatFunc format; FormatFunc format;
}; };
@ -1111,7 +1113,7 @@ struct Value {
StringValue<signed char> sstring; StringValue<signed char> sstring;
StringValue<unsigned char> ustring; StringValue<unsigned char> ustring;
StringValue<Char> tstring; StringValue<Char> tstring;
CustomValue custom; CustomValue<Char> custom;
}; };
}; };
@ -1216,9 +1218,8 @@ class MakeValue : public Value<typename Context::char_type> {
// Formats an argument of a custom type, such as a user-defined class. // Formats an argument of a custom type, such as a user-defined class.
template <typename T> template <typename T>
static void format_custom_arg( static void format_custom_arg(
void *writer, const void *arg, void *context) { BasicWriter<Char> &writer, const void *arg, void *context) {
format_value(*static_cast<BasicWriter<Char>*>(writer), format_value(writer, *static_cast<const T*>(arg),
*static_cast<const T*>(arg),
*static_cast<Context*>(context)); *static_cast<Context*>(context));
} }
@ -2140,8 +2141,8 @@ class ArgFormatter : public internal::ArgFormatterBase<Char> {
using internal::ArgFormatterBase<Char>::operator(); using internal::ArgFormatterBase<Char>::operator();
/** Formats an argument of a custom (user-defined) type. */ /** Formats an argument of a custom (user-defined) type. */
void operator()(internal::CustomValue c) { void operator()(internal::CustomValue<Char> c) {
c.format(&this->writer(), c.value, &ctx_); c.format(this->writer(), c.value, &ctx_);
} }
}; };
@ -3371,8 +3372,8 @@ class CustomFormatter {
CustomFormatter(BasicWriter<Char> &writer, Context &ctx) CustomFormatter(BasicWriter<Char> &writer, Context &ctx)
: writer_(writer), ctx_(ctx) {} : writer_(writer), ctx_(ctx) {}
bool operator()(internal::CustomValue custom) { bool operator()(internal::CustomValue<Char> custom) {
custom.format(&writer_, custom.value, &ctx_); custom.format(writer_, custom.value, &ctx_);
return true; return true;
} }

View File

@ -281,11 +281,11 @@ class PrintfArgFormatter : public internal::ArgFormatterBase<Char> {
} }
/** Formats an argument of a custom (user-defined) type. */ /** Formats an argument of a custom (user-defined) type. */
void operator()(internal::CustomValue c) { void operator()(internal::CustomValue<Char> c) {
const Char format_str[] = {'}', '\0'}; const Char format_str[] = {'}', '\0'};
auto args = basic_format_args<basic_format_context<Char>, Char>(); auto args = basic_format_args<basic_format_context<Char>, Char>();
basic_format_context<Char> ctx(format_str, args); basic_format_context<Char> ctx(format_str, args);
c.format(&this->writer(), c.value, &ctx); c.format(this->writer(), c.value, &ctx);
} }
}; };

View File

@ -1637,7 +1637,7 @@ class MockArgFormatter : public fmt::internal::ArgFormatterBase<char> {
void operator()(int value) { call(value); } void operator()(int value) { call(value); }
void operator()(fmt::internal::CustomValue) {} void operator()(fmt::internal::CustomValue<char>) {}
}; };
void custom_vformat(fmt::CStringRef format_str, fmt::format_args args) { void custom_vformat(fmt::CStringRef format_str, fmt::format_args args) {

View File

@ -426,14 +426,15 @@ TEST(UtilTest, MakeValueWithCustomFormatter) {
fmt::internal::Value<char> arg = fmt::internal::MakeValue<CustomFormatter>(t); fmt::internal::Value<char> arg = fmt::internal::MakeValue<CustomFormatter>(t);
CustomFormatter ctx = {false}; CustomFormatter ctx = {false};
fmt::MemoryWriter w; fmt::MemoryWriter w;
arg.custom.format(&w, &t, &ctx); arg.custom.format(w, &t, &ctx);
EXPECT_TRUE(ctx.called); EXPECT_TRUE(ctx.called);
} }
namespace fmt { namespace fmt {
namespace internal { namespace internal {
bool operator==(CustomValue lhs, CustomValue rhs) { template <typename Char>
bool operator==(CustomValue<Char> lhs, CustomValue<Char> rhs) {
return lhs.value == rhs.value; return lhs.value == rhs.value;
} }
} }
@ -563,14 +564,14 @@ TEST(UtilTest, PointerArg) {
TEST(UtilTest, CustomArg) { TEST(UtilTest, CustomArg) {
::Test test; ::Test test;
typedef MockVisitor<fmt::internal::CustomValue> Visitor; typedef MockVisitor<fmt::internal::CustomValue<char>> Visitor;
testing::StrictMock<Visitor> visitor; testing::StrictMock<Visitor> visitor;
EXPECT_CALL(visitor, visit(_)).WillOnce( EXPECT_CALL(visitor, visit(_)).WillOnce(
testing::Invoke([&](fmt::internal::CustomValue custom) { testing::Invoke([&](fmt::internal::CustomValue<char> custom) {
EXPECT_EQ(&test, custom.value); EXPECT_EQ(&test, custom.value);
fmt::MemoryWriter w; fmt::MemoryWriter w;
fmt::format_context ctx("}", fmt::format_args()); fmt::format_context ctx("}", fmt::format_args());
custom.format(&w, &test, &ctx); custom.format(w, &test, &ctx);
EXPECT_EQ("test", w.str()); EXPECT_EQ("test", w.str());
return Visitor::Result(); return Visitor::Result();
})); }));