Don't erase writer type
diff --git a/fmt/format.h b/fmt/format.h
index dc8ce0c..723e539 100644
--- a/fmt/format.h
+++ b/fmt/format.h
@@ -1089,9 +1089,11 @@
std::size_t size;
};
-typedef void (*FormatFunc)(void *writer, const void *arg, void *ctx);
-
+template <typename Char>
struct CustomValue {
+ typedef void (*FormatFunc)(
+ BasicWriter<Char> &writer, const void *arg, void *ctx);
+
const void *value;
FormatFunc format;
};
@@ -1111,7 +1113,7 @@
StringValue<signed char> sstring;
StringValue<unsigned char> ustring;
StringValue<Char> tstring;
- CustomValue custom;
+ CustomValue<Char> custom;
};
};
@@ -1216,9 +1218,8 @@
// Formats an argument of a custom type, such as a user-defined class.
template <typename T>
static void format_custom_arg(
- void *writer, const void *arg, void *context) {
- format_value(*static_cast<BasicWriter<Char>*>(writer),
- *static_cast<const T*>(arg),
+ BasicWriter<Char> &writer, const void *arg, void *context) {
+ format_value(writer, *static_cast<const T*>(arg),
*static_cast<Context*>(context));
}
@@ -2140,8 +2141,8 @@
using internal::ArgFormatterBase<Char>::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<Char> c) {
+ c.format(this->writer(), c.value, &ctx_);
}
};
@@ -3371,8 +3372,8 @@
CustomFormatter(BasicWriter<Char> &writer, Context &ctx)
: writer_(writer), ctx_(ctx) {}
- bool operator()(internal::CustomValue custom) {
- custom.format(&writer_, custom.value, &ctx_);
+ bool operator()(internal::CustomValue<Char> custom) {
+ custom.format(writer_, custom.value, &ctx_);
return true;
}
diff --git a/fmt/printf.h b/fmt/printf.h
index c0064ae..92d50ef 100644
--- a/fmt/printf.h
+++ b/fmt/printf.h
@@ -281,11 +281,11 @@
}
/** 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'};
auto args = basic_format_args<basic_format_context<Char>, Char>();
basic_format_context<Char> 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 6829f62..b8693d5 100644
--- a/test/format-test.cc
+++ b/test/format-test.cc
@@ -1637,7 +1637,7 @@
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) {
diff --git a/test/util-test.cc b/test/util-test.cc
index e02b68d..0e276d5 100644
--- a/test/util-test.cc
+++ b/test/util-test.cc
@@ -426,14 +426,15 @@
fmt::internal::Value<char> arg = fmt::internal::MakeValue<CustomFormatter>(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 <typename Char>
+bool operator==(CustomValue<Char> lhs, CustomValue<Char> rhs) {
return lhs.value == rhs.value;
}
}
@@ -563,14 +564,14 @@
TEST(UtilTest, CustomArg) {
::Test test;
- typedef MockVisitor<fmt::internal::CustomValue> Visitor;
+ typedef MockVisitor<fmt::internal::CustomValue<char>> Visitor;
testing::StrictMock<Visitor> visitor;
EXPECT_CALL(visitor, visit(_)).WillOnce(
- testing::Invoke([&](fmt::internal::CustomValue custom) {
+ testing::Invoke([&](fmt::internal::CustomValue<char> 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();
}));