Disallow formatting of wchar_t when using a char formatter.

This commit is contained in:
Victor Zverovich 2013-12-07 08:12:03 -08:00
parent 206c846e12
commit e3b4a3f166
3 changed files with 35 additions and 15 deletions

View File

@ -396,13 +396,14 @@ inline const typename fmt::BasicFormatter<Char>::Arg
template <typename Char>
void fmt::BasicFormatter<Char>::CheckSign(const Char *&s, const Arg &arg) {
char sign = *s;
if (arg.type > LAST_NUMERIC_TYPE) {
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) {
ReportError(s,
Format("format specifier '{0}' requires signed argument") << *s);
Format("format specifier '{}' requires signed argument") << sign);
}
++s;
}

View File

@ -157,11 +157,16 @@ void Array<T, SIZE>::append(const T *begin, const T *end) {
}
template <typename Char>
struct CharTraits;
class CharTraits;
template <>
struct CharTraits<char> {
typedef wchar_t UnsupportedType;
class CharTraits<char> {
private:
// Conversion from wchar_t to char is not supported.
static char ConvertWChar(wchar_t);
public:
typedef const wchar_t *UnsupportedStrType;
template <typename T>
static int FormatFloat(char *buffer, std::size_t size,
@ -169,8 +174,11 @@ struct CharTraits<char> {
};
template <>
struct CharTraits<wchar_t> {
typedef char UnsupportedType;
class CharTraits<wchar_t> {
public:
typedef const char *UnsupportedStrType;
static wchar_t ConvertWChar(wchar_t value) { return value; }
template <typename T>
static int FormatFloat(wchar_t *buffer, std::size_t size,
@ -545,7 +553,7 @@ class BasicWriter {
// 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*.
// Do not implement!
void operator<<(const typename internal::CharTraits<Char>::UnsupportedType *);
void operator<<(typename internal::CharTraits<Char>::UnsupportedStrType);
public:
/**
@ -841,12 +849,6 @@ class BasicFormatter {
template <typename T>
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:
Type type;
union {
@ -884,7 +886,10 @@ class BasicFormatter {
Arg(double value) : type(DOUBLE), double_value(value), formatter(0) {}
Arg(long double value)
: 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) {
string.value = value;

View File

@ -304,6 +304,13 @@ TEST(WriterTest, WriteChar) {
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) {
CHECK_WRITE_CHAR("abc");
// The following line shouldn't compile:
@ -1155,6 +1162,13 @@ TEST(FormatterTest, FormatChar) {
CheckUnknownTypes('a', "c", "char");
EXPECT_EQ("a", str(Format("{0}") << 'a'));
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) {