Commit e3b4a3f1 authored by Victor Zverovich's avatar Victor Zverovich

Disallow formatting of wchar_t when using a char formatter.

parent 206c846e
...@@ -396,13 +396,14 @@ inline const typename fmt::BasicFormatter<Char>::Arg ...@@ -396,13 +396,14 @@ inline const typename fmt::BasicFormatter<Char>::Arg
template <typename Char> template <typename Char>
void fmt::BasicFormatter<Char>::CheckSign(const Char *&s, const Arg &arg) { void fmt::BasicFormatter<Char>::CheckSign(const Char *&s, const Arg &arg) {
char sign = *s;
if (arg.type > LAST_NUMERIC_TYPE) { if (arg.type > LAST_NUMERIC_TYPE) {
ReportError(s, ReportError(s,
Format("format specifier '{0}' requires numeric argument") << *s); Format("format specifier '{}' requires numeric argument") << sign);
} }
if (arg.type == UINT || arg.type == ULONG || arg.type == ULONG_LONG) { if (arg.type == UINT || arg.type == ULONG || arg.type == ULONG_LONG) {
ReportError(s, ReportError(s,
Format("format specifier '{0}' requires signed argument") << *s); Format("format specifier '{}' requires signed argument") << sign);
} }
++s; ++s;
} }
......
...@@ -157,11 +157,16 @@ void Array<T, SIZE>::append(const T *begin, const T *end) { ...@@ -157,11 +157,16 @@ void Array<T, SIZE>::append(const T *begin, const T *end) {
} }
template <typename Char> template <typename Char>
struct CharTraits; class CharTraits;
template <> template <>
struct CharTraits<char> { class CharTraits<char> {
typedef wchar_t UnsupportedType; private:
// Conversion from wchar_t to char is not supported.
static char ConvertWChar(wchar_t);
public:
typedef const wchar_t *UnsupportedStrType;
template <typename T> template <typename T>
static int FormatFloat(char *buffer, std::size_t size, static int FormatFloat(char *buffer, std::size_t size,
...@@ -169,8 +174,11 @@ struct CharTraits<char> { ...@@ -169,8 +174,11 @@ struct CharTraits<char> {
}; };
template <> template <>
struct CharTraits<wchar_t> { class CharTraits<wchar_t> {
typedef char UnsupportedType; public:
typedef const char *UnsupportedStrType;
static wchar_t ConvertWChar(wchar_t value) { return value; }
template <typename T> template <typename T>
static int FormatFloat(wchar_t *buffer, std::size_t size, static int FormatFloat(wchar_t *buffer, std::size_t size,
...@@ -545,7 +553,7 @@ class BasicWriter { ...@@ -545,7 +553,7 @@ class BasicWriter {
// char stream and vice versa. If you want to print a wide string // char stream and vice versa. If you want to print a wide string
// as a pointer as std::ostream does, cast it to const void*. // as a pointer as std::ostream does, cast it to const void*.
// Do not implement! // Do not implement!
void operator<<(const typename internal::CharTraits<Char>::UnsupportedType *); void operator<<(typename internal::CharTraits<Char>::UnsupportedStrType);
public: public:
/** /**
...@@ -841,12 +849,6 @@ class BasicFormatter { ...@@ -841,12 +849,6 @@ class BasicFormatter {
template <typename T> template <typename T>
Arg(T *value); Arg(T *value);
// This method is private to disallow formatting of wide characters.
// If you want to output a wide character cast it to integer type.
// Do not implement!
// TODO
//Arg(wchar_t value);
public: public:
Type type; Type type;
union { union {
...@@ -884,7 +886,10 @@ class BasicFormatter { ...@@ -884,7 +886,10 @@ class BasicFormatter {
Arg(double value) : type(DOUBLE), double_value(value), formatter(0) {} Arg(double value) : type(DOUBLE), double_value(value), formatter(0) {}
Arg(long double value) Arg(long double value)
: type(LONG_DOUBLE), long_double_value(value), formatter(0) {} : type(LONG_DOUBLE), long_double_value(value), formatter(0) {}
Arg(Char value) : type(CHAR), int_value(value), formatter(0) {} Arg(char value) : type(CHAR), int_value(value), formatter(0) {}
Arg(wchar_t value)
: type(CHAR), int_value(internal::CharTraits<Char>::ConvertWChar(value)),
formatter(0) {}
Arg(const Char *value) : type(STRING), formatter(0) { Arg(const Char *value) : type(STRING), formatter(0) {
string.value = value; string.value = value;
......
...@@ -304,6 +304,13 @@ TEST(WriterTest, WriteChar) { ...@@ -304,6 +304,13 @@ TEST(WriterTest, WriteChar) {
CHECK_WRITE('a'); CHECK_WRITE('a');
} }
TEST(WriterTest, WriteWideChar) {
// TODO
//CHECK_WRITE_WCHAR(L'a');
// The following line shouldn't compile:
CHECK_WRITE_CHAR(L'a');
}
TEST(WriterTest, WriteString) { TEST(WriterTest, WriteString) {
CHECK_WRITE_CHAR("abc"); CHECK_WRITE_CHAR("abc");
// The following line shouldn't compile: // The following line shouldn't compile:
...@@ -1155,6 +1162,13 @@ TEST(FormatterTest, FormatChar) { ...@@ -1155,6 +1162,13 @@ TEST(FormatterTest, FormatChar) {
CheckUnknownTypes('a', "c", "char"); CheckUnknownTypes('a', "c", "char");
EXPECT_EQ("a", str(Format("{0}") << 'a')); EXPECT_EQ("a", str(Format("{0}") << 'a'));
EXPECT_EQ("z", str(Format("{0:c}") << 'z')); EXPECT_EQ("z", str(Format("{0:c}") << 'z'));
EXPECT_EQ(L"a", str(Format(L"{0}") << 'a'));
}
TEST(FormatterTest, FormatWChar) {
EXPECT_EQ(L"a", str(Format(L"{0}") << L'a'));
// This shouldn't compile:
//Format("{0}") << L'a';
} }
TEST(FormatterTest, FormatCString) { TEST(FormatterTest, FormatCString) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment