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