diff --git a/format.h b/format.h index 8d947fa7..a71c2eff 100644 --- a/format.h +++ b/format.h @@ -742,6 +742,23 @@ struct Arg : Value { Type type; }; +template +struct None {}; + +// A helper class template to enable or disable overloads taking wide strings +// in MakeValue. +template +struct WStringHelper { + typedef None Supported; + typedef T Unsupported; +}; + +template +struct WStringHelper { + typedef T Supported; + typedef None Unsupported; +}; + // Makes a Value object from any type. template class MakeValue : public Value { @@ -756,6 +773,14 @@ class MakeValue : public Value { template MakeValue(T *value); + // The following methods are private to disallow formatting of wide + // strings into narrow strings as in fmt::format("{}", L"test"). + // To fix this, use a wide format string: fmt::format(L"{}", L"test"). + MakeValue(typename WStringHelper::Unsupported); + MakeValue(typename WStringHelper::Unsupported); + MakeValue(typename WStringHelper::Unsupported); + MakeValue(typename WStringHelper::Unsupported); + void set_string(StringRef str) { string.value = str.c_str(); string.size = str.size(); @@ -837,10 +862,16 @@ class MakeValue : public Value { FMT_MAKE_STR_VALUE(const std::string &, STRING) FMT_MAKE_STR_VALUE(StringRef, STRING) - FMT_MAKE_STR_VALUE(wchar_t *, WSTRING) - FMT_MAKE_STR_VALUE(const wchar_t *, WSTRING) - FMT_MAKE_STR_VALUE(const std::wstring &, WSTRING) - FMT_MAKE_STR_VALUE(WStringRef, WSTRING) +#define FMT_MAKE_WSTR_VALUE(Type, TYPE) \ + MakeValue(typename WStringHelper::Supported value) { \ + set_string(value); \ + } \ + static uint64_t type(Type) { return Arg::TYPE; } + + FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING) + FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING) + FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING) + FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING) FMT_MAKE_VALUE(void *, pointer, POINTER) FMT_MAKE_VALUE(const void *, pointer, POINTER)