diff --git a/include/fmt/core.h b/include/fmt/core.h index ffe39ee9..0fb46fa3 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -576,12 +576,14 @@ class value { } }; -template -struct typed_value : value { +// Value initializer used to delay conversion to value and reduce memory churn. +template +struct init { + T val; static const type type_tag = TYPE; - template - FMT_CONSTEXPR typed_value(const T &val) : value(val) {} + FMT_CONSTEXPR init(const T &v) : val(v) {} + FMT_CONSTEXPR operator value() const { return value(val); } }; template @@ -589,15 +591,13 @@ FMT_CONSTEXPR basic_format_arg make_arg(const T &value); #define FMT_MAKE_VALUE(TAG, ArgType, ValueType) \ template \ - FMT_CONSTEXPR typed_value make_value(ArgType val) { \ + FMT_CONSTEXPR init make_value(ArgType val) { \ return static_cast(val); \ } #define FMT_MAKE_VALUE_SAME(TAG, Type) \ template \ - FMT_CONSTEXPR typed_value make_value(Type val) { \ - return val; \ - } + FMT_CONSTEXPR init make_value(Type val) { return val; } FMT_MAKE_VALUE(bool_type, bool, int) FMT_MAKE_VALUE(int_type, short, int) @@ -625,7 +625,7 @@ FMT_MAKE_VALUE(char_type, char, int) #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) template -inline typed_value make_value(wchar_t val) { +inline init make_value(wchar_t val) { require_wchar(); return static_cast(val); } @@ -672,13 +672,13 @@ typename std::enable_if::value>::type template inline typename std::enable_if< std::is_enum::value && convert_to_int::value, - typed_value>::type + init>::type make_value(const T &val) { return static_cast(val); } template inline typename std::enable_if< std::is_constructible, T>::value, - typed_value>::type + init, string_type>>::type make_value(const T &val) { return basic_string_view(val); } template @@ -688,11 +688,11 @@ inline typename std::enable_if< !std::is_constructible, T>::value, // Implicit conversion to std::string is not handled here because it's // unsafe: https://github.com/fmtlib/fmt/issues/729 - typed_value>::type + init>::type make_value(const T &val) { return val; } template -typed_value +init make_value(const named_arg &val) { basic_format_arg arg = make_arg(val.value); std::memcpy(val.data, &arg, sizeof(arg)); diff --git a/test/core-test.cc b/test/core-test.cc index 8648c736..1711b17f 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -448,7 +448,7 @@ struct custom_context { TEST(UtilTest, MakeValueWithCustomFormatter) { ::Test t; fmt::internal::value arg = - fmt::internal::make_value(t); + fmt::internal::make_value(t); custom_context ctx = {false}; arg.custom.format(&t, ctx); EXPECT_TRUE(ctx.called);