mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Don't erase writer type
This commit is contained in:
21
fmt/format.h
21
fmt/format.h
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
}));
|
}));
|
||||||
|
Reference in New Issue
Block a user