Merge value and MakeValue
This commit is contained in:
parent
acd1811c50
commit
b2a0d8914a
85
fmt/format.h
85
fmt/format.h
@ -1017,7 +1017,7 @@ template <typename T = void>
|
||||
struct Null {};
|
||||
|
||||
// A helper class template to enable or disable overloads taking wide
|
||||
// characters and strings in MakeValue.
|
||||
// characters and strings in value's constructor.
|
||||
template <typename T, typename Char>
|
||||
struct WCharHelper {
|
||||
typedef Null<T> Supported;
|
||||
@ -1097,25 +1097,6 @@ struct CustomValue {
|
||||
FormatFunc format;
|
||||
};
|
||||
|
||||
// A formatting argument value.
|
||||
template <typename Context>
|
||||
struct value {
|
||||
union {
|
||||
int int_value;
|
||||
unsigned uint_value;
|
||||
LongLong long_long_value;
|
||||
ULongLong ulong_long_value;
|
||||
double double_value;
|
||||
long double long_double_value;
|
||||
const void *pointer;
|
||||
StringValue<char> string;
|
||||
StringValue<signed char> sstring;
|
||||
StringValue<unsigned char> ustring;
|
||||
StringValue<typename Context::char_type> tstring;
|
||||
CustomValue<typename Context::char_type> custom;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
struct NamedArg;
|
||||
|
||||
@ -1175,10 +1156,25 @@ template <> constexpr Type gettype<const void *>() { return POINTER; }
|
||||
template <typename T>
|
||||
constexpr Type type() { return gettype<typename std::decay<T>::type>(); }
|
||||
|
||||
// Makes a format_arg object from any type.
|
||||
// A formatting argument value.
|
||||
template <typename Context>
|
||||
class MakeValue : public value<Context> {
|
||||
class value {
|
||||
public:
|
||||
union {
|
||||
int int_value;
|
||||
unsigned uint_value;
|
||||
LongLong long_long_value;
|
||||
ULongLong ulong_long_value;
|
||||
double double_value;
|
||||
long double long_double_value;
|
||||
const void *pointer;
|
||||
StringValue<char> string;
|
||||
StringValue<signed char> sstring;
|
||||
StringValue<unsigned char> ustring;
|
||||
StringValue<typename Context::char_type> tstring;
|
||||
CustomValue<typename Context::char_type> custom;
|
||||
};
|
||||
|
||||
typedef typename Context::char_type Char;
|
||||
|
||||
private:
|
||||
@ -1188,21 +1184,21 @@ class MakeValue : public value<Context> {
|
||||
// of "[const] volatile char *" which is printed as bool by iostreams.
|
||||
// Do not implement!
|
||||
template <typename T>
|
||||
MakeValue(const T *value);
|
||||
value(const T *value);
|
||||
template <typename T>
|
||||
MakeValue(T *value);
|
||||
value(T *value);
|
||||
|
||||
// The following methods are private to disallow formatting of wide
|
||||
// characters and strings into narrow strings as in
|
||||
// fmt::format("{}", L"test");
|
||||
// To fix this, use a wide format string: fmt::format(L"{}", L"test").
|
||||
#if !FMT_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported);
|
||||
value(typename WCharHelper<wchar_t, Char>::Unsupported);
|
||||
#endif
|
||||
MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported);
|
||||
MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported);
|
||||
MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported);
|
||||
MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported);
|
||||
value(typename WCharHelper<wchar_t *, Char>::Unsupported);
|
||||
value(typename WCharHelper<const wchar_t *, Char>::Unsupported);
|
||||
value(typename WCharHelper<const std::wstring &, Char>::Unsupported);
|
||||
value(typename WCharHelper<WStringRef, Char>::Unsupported);
|
||||
|
||||
void set_string(StringRef str) {
|
||||
this->string.value = str.data();
|
||||
@ -1223,10 +1219,10 @@ class MakeValue : public value<Context> {
|
||||
}
|
||||
|
||||
public:
|
||||
MakeValue() {}
|
||||
value() {}
|
||||
|
||||
#define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \
|
||||
MakeValue(Type value) { \
|
||||
value(Type value) { \
|
||||
static_assert(internal::type<Type>() == internal::TYPE, "invalid type"); \
|
||||
this->field = rhs; \
|
||||
}
|
||||
@ -1240,7 +1236,7 @@ class MakeValue : public value<Context> {
|
||||
FMT_MAKE_VALUE(int, int_value, INT)
|
||||
FMT_MAKE_VALUE(unsigned, uint_value, UINT)
|
||||
|
||||
MakeValue(long value) {
|
||||
value(long value) {
|
||||
// To minimize the number of types we need to deal with, long is
|
||||
// translated either to int or to long long depending on its size.
|
||||
if (const_check(sizeof(long) == sizeof(int)))
|
||||
@ -1249,7 +1245,7 @@ class MakeValue : public value<Context> {
|
||||
this->long_long_value = value;
|
||||
}
|
||||
|
||||
MakeValue(unsigned long value) {
|
||||
value(unsigned long value) {
|
||||
if (const_check(sizeof(unsigned long) == sizeof(unsigned)))
|
||||
this->uint_value = static_cast<unsigned>(value);
|
||||
else
|
||||
@ -1267,14 +1263,14 @@ class MakeValue : public value<Context> {
|
||||
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
typedef typename WCharHelper<wchar_t, Char>::Supported WChar;
|
||||
MakeValue(WChar value) {
|
||||
value(WChar value) {
|
||||
static_assert(internal::type<WChar>() == internal::CHAR, "invalid type");
|
||||
this->int_value = value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define FMT_MAKE_STR_VALUE(Type, TYPE) \
|
||||
MakeValue(Type value) { \
|
||||
value(Type value) { \
|
||||
static_assert(internal::type<Type>() == internal::TYPE, "invalid type"); \
|
||||
set_string(value); \
|
||||
}
|
||||
@ -1290,8 +1286,8 @@ class MakeValue : public value<Context> {
|
||||
FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str())
|
||||
|
||||
#define FMT_MAKE_WSTR_VALUE(Type, TYPE) \
|
||||
MakeValue(typename WCharHelper<Type, Char>::Supported value) { \
|
||||
static_assert(internal::type<Type>() == internal::TYPE, "invalid type"); \
|
||||
value(typename WCharHelper<Type, Char>::Supported value) { \
|
||||
static_assert(internal::type<Type>() == internal::TYPE, "invalid type"); \
|
||||
set_string(value); \
|
||||
}
|
||||
|
||||
@ -1304,17 +1300,16 @@ class MakeValue : public value<Context> {
|
||||
FMT_MAKE_VALUE(const void *, pointer, POINTER)
|
||||
|
||||
template <typename T>
|
||||
MakeValue(const T &value,
|
||||
typename EnableIf<Not<
|
||||
ConvertToInt<T>::value>::value, int>::type = 0) {
|
||||
value(const T &value,
|
||||
typename EnableIf<Not<ConvertToInt<T>::value>::value, int>::type = 0) {
|
||||
static_assert(internal::type<T>() == internal::CUSTOM, "invalid type");
|
||||
this->custom.value = &value;
|
||||
this->custom.format = &format_custom_arg<T>;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
MakeValue(const T &value,
|
||||
typename EnableIf<ConvertToInt<T>::value, int>::type = 0) {
|
||||
value(const T &value,
|
||||
typename EnableIf<ConvertToInt<T>::value, int>::type = 0) {
|
||||
static_assert(internal::type<T>() == internal::INT, "invalid type");
|
||||
this->int_value = value;
|
||||
}
|
||||
@ -1322,7 +1317,7 @@ class MakeValue : public value<Context> {
|
||||
// Additional template param `Char_` is needed here because make_type always
|
||||
// uses char.
|
||||
template <typename Char_>
|
||||
MakeValue(const NamedArg<Char_> &value) {
|
||||
value(const NamedArg<Char_> &value) {
|
||||
static_assert(
|
||||
internal::type<const NamedArg<Char_> &>() == internal::NAMED_ARG,
|
||||
"invalid type");
|
||||
@ -1437,7 +1432,7 @@ template <typename Context, typename T>
|
||||
basic_format_arg<Context> make_arg(const T &value) {
|
||||
basic_format_arg<Context> arg;
|
||||
arg.type_ = internal::type<T>();
|
||||
arg.value_ = internal::MakeValue<Context>(value);
|
||||
arg.value_ = value;
|
||||
return arg;
|
||||
}
|
||||
|
||||
@ -1516,7 +1511,7 @@ enum { MAX_PACKED_ARGS = 16 };
|
||||
template <bool IS_PACKED, typename Context, typename T>
|
||||
inline typename std::enable_if<IS_PACKED, value<Context>>::type
|
||||
make_arg(const T& value) {
|
||||
return MakeValue<Context>(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
template <bool IS_PACKED, typename Context, typename T>
|
||||
|
@ -423,8 +423,7 @@ void format_value(fmt::Writer &, const Test &, CustomContext &ctx) {
|
||||
|
||||
TEST(UtilTest, MakeValueWithCustomFormatter) {
|
||||
::Test t;
|
||||
fmt::internal::value<CustomContext> arg =
|
||||
fmt::internal::MakeValue<CustomContext>(t);
|
||||
fmt::internal::value<CustomContext> arg(t);
|
||||
CustomContext ctx = {false};
|
||||
fmt::MemoryWriter w;
|
||||
arg.custom.format(w, &t, &ctx);
|
||||
|
Loading…
Reference in New Issue
Block a user