mirror of
https://github.com/fmtlib/fmt.git
synced 2025-04-10 03:44:32 +00:00
Test precision.
This commit is contained in:
parent
095b43a8f0
commit
bbd13a492b
108
format.cc
108
format.cc
@ -72,6 +72,7 @@ void fmt::Formatter::Format() {
|
|||||||
const char *s = start;
|
const char *s = start;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
if (*s++ != '{') continue;
|
if (*s++ != '{') continue;
|
||||||
|
// TODO: handle escape sequence
|
||||||
buffer_.insert(buffer_.end(), start, s - 1);
|
buffer_.insert(buffer_.end(), start, s - 1);
|
||||||
|
|
||||||
// Parse argument index.
|
// Parse argument index.
|
||||||
@ -90,26 +91,31 @@ void fmt::Formatter::Format() {
|
|||||||
int width = -1;
|
int width = -1;
|
||||||
int precision = -1;
|
int precision = -1;
|
||||||
char type = 0;
|
char type = 0;
|
||||||
|
bool is_floating_point = false;
|
||||||
if (*s == ':') {
|
if (*s == ':') {
|
||||||
++s;
|
++s;
|
||||||
if (*s == '+') {
|
if (*s == '+') {
|
||||||
if (arg.type > LAST_NUMERIC_TYPE) {
|
if (arg.type > LAST_NUMERIC_TYPE) {
|
||||||
Throw<FormatError>(s,
|
Throw<FormatError>(s,
|
||||||
"format specifier '+' used with non-numeric type");
|
"format specifier '+' requires numeric argument");
|
||||||
|
}
|
||||||
|
if (arg.type == UINT || arg.type == ULONG) {
|
||||||
|
Throw<FormatError>(s,
|
||||||
|
"format specifier '+' requires signed argument");
|
||||||
}
|
}
|
||||||
*arg_format_ptr++ = *s++;
|
*arg_format_ptr++ = *s++;
|
||||||
}
|
}
|
||||||
if (*s == '0') {
|
if (*s == '0') {
|
||||||
if (arg.type > LAST_NUMERIC_TYPE) {
|
if (arg.type > LAST_NUMERIC_TYPE) {
|
||||||
Throw<FormatError>(s,
|
Throw<FormatError>(s,
|
||||||
"format specifier '0' used with non-numeric type");
|
"format specifier '0' requires numeric argument");
|
||||||
}
|
}
|
||||||
*arg_format_ptr++ = *s++;
|
*arg_format_ptr++ = *s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse width.
|
// Parse width.
|
||||||
if ('0' <= *s && *s <= '9') {
|
if ('0' <= *s && *s <= '9') {
|
||||||
if (arg.type > LAST_NUMERIC_TYPE)
|
if (arg.type > LAST_NUMERIC_TYPE && arg.type != POINTER)
|
||||||
*arg_format_ptr++ = '-';
|
*arg_format_ptr++ = '-';
|
||||||
*arg_format_ptr++ = '*';
|
*arg_format_ptr++ = '*';
|
||||||
unsigned value = ParseUInt(s);
|
unsigned value = ParseUInt(s);
|
||||||
@ -127,16 +133,36 @@ void fmt::Formatter::Format() {
|
|||||||
if ('0' <= *s && *s <= '9') {
|
if ('0' <= *s && *s <= '9') {
|
||||||
unsigned value = ParseUInt(s);
|
unsigned value = ParseUInt(s);
|
||||||
if (value > INT_MAX)
|
if (value > INT_MAX)
|
||||||
Throw<FormatError>(s, "number is too big in format"); // TODO: test
|
Throw<FormatError>(s, "number is too big in format");
|
||||||
precision = value;
|
precision = value;
|
||||||
} else {
|
} else {
|
||||||
// TODO: error
|
Throw<FormatError>(s, "missing precision in format");
|
||||||
|
}
|
||||||
|
if (arg.type > LAST_NUMERIC_TYPE ||
|
||||||
|
(*s == '}' && arg.type != DOUBLE && arg.type != LONG_DOUBLE)) {
|
||||||
|
Throw<FormatError>(s,
|
||||||
|
"precision specifier requires floating-point type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse type.
|
// Parse type.
|
||||||
if (*s == 'f' || *s == 'g')
|
if (*s != '}' && *s) {
|
||||||
type = *s++; // TODO: check if the type matches
|
type = *s++;
|
||||||
|
if (arg.type <= LAST_NUMERIC_TYPE) {
|
||||||
|
switch (type) {
|
||||||
|
case 'd': case 'o': case 'x': case 'X':
|
||||||
|
// TODO: check that argument is integer
|
||||||
|
break;
|
||||||
|
case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
|
||||||
|
is_floating_point = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO: error
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: check non-numeric types (string, character)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*s++ != '}')
|
if (*s++ != '}')
|
||||||
@ -145,36 +171,39 @@ void fmt::Formatter::Format() {
|
|||||||
|
|
||||||
// Format argument.
|
// Format argument.
|
||||||
switch (arg.type) {
|
switch (arg.type) {
|
||||||
case CHAR:
|
|
||||||
if (width == -1 && precision == -1) {
|
|
||||||
buffer_.push_back(arg.int_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*arg_format_ptr++ = 'c';
|
|
||||||
*arg_format_ptr = '\0';
|
|
||||||
FormatBuiltinArg(arg_format, arg.int_value, width, precision);
|
|
||||||
break;
|
|
||||||
case INT:
|
case INT:
|
||||||
*arg_format_ptr++ = 'd';
|
*arg_format_ptr++ = type ? type : 'd';
|
||||||
*arg_format_ptr = '\0';
|
*arg_format_ptr = '\0';
|
||||||
FormatBuiltinArg(arg_format, arg.int_value, width, precision);
|
if (is_floating_point)
|
||||||
|
FormatBuiltinArg<double>(arg_format, arg.int_value, width, precision);
|
||||||
|
else
|
||||||
|
FormatBuiltinArg(arg_format, arg.int_value, width, precision);
|
||||||
break;
|
break;
|
||||||
case UINT:
|
case UINT:
|
||||||
*arg_format_ptr++ = 'd';
|
*arg_format_ptr++ = type ? type : 'u';
|
||||||
*arg_format_ptr = '\0';
|
*arg_format_ptr = '\0';
|
||||||
FormatBuiltinArg(arg_format, arg.uint_value, width, precision);
|
if (is_floating_point)
|
||||||
|
FormatBuiltinArg<double>(arg_format, arg.uint_value, width, precision);
|
||||||
|
else
|
||||||
|
FormatBuiltinArg(arg_format, arg.uint_value, width, precision);
|
||||||
break;
|
break;
|
||||||
case LONG:
|
case LONG:
|
||||||
*arg_format_ptr++ = 'l';
|
*arg_format_ptr++ = 'l';
|
||||||
*arg_format_ptr++ = 'd';
|
*arg_format_ptr++ = type ? type : 'd';
|
||||||
*arg_format_ptr = '\0';
|
*arg_format_ptr = '\0';
|
||||||
FormatBuiltinArg(arg_format, arg.long_value, width, precision);
|
if (is_floating_point)
|
||||||
|
FormatBuiltinArg<double>(arg_format, arg.long_value, width, precision);
|
||||||
|
else
|
||||||
|
FormatBuiltinArg(arg_format, arg.long_value, width, precision);
|
||||||
break;
|
break;
|
||||||
case ULONG:
|
case ULONG:
|
||||||
*arg_format_ptr++ = 'l';
|
*arg_format_ptr++ = 'l';
|
||||||
*arg_format_ptr++ = 'd';
|
*arg_format_ptr++ = type ? type : 'u';
|
||||||
*arg_format_ptr = '\0';
|
*arg_format_ptr = '\0';
|
||||||
FormatBuiltinArg(arg_format, arg.ulong_value, width, precision);
|
if (is_floating_point)
|
||||||
|
FormatBuiltinArg<double>(arg_format, arg.ulong_value, width, precision);
|
||||||
|
else
|
||||||
|
FormatBuiltinArg(arg_format, arg.ulong_value, width, precision);
|
||||||
break;
|
break;
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
*arg_format_ptr++ = type ? type : 'g';
|
*arg_format_ptr++ = type ? type : 'g';
|
||||||
@ -183,15 +212,31 @@ void fmt::Formatter::Format() {
|
|||||||
break;
|
break;
|
||||||
case LONG_DOUBLE:
|
case LONG_DOUBLE:
|
||||||
*arg_format_ptr++ = 'L';
|
*arg_format_ptr++ = 'L';
|
||||||
*arg_format_ptr++ = 'g';
|
*arg_format_ptr++ = type ? type : 'g';
|
||||||
*arg_format_ptr = '\0';
|
*arg_format_ptr = '\0';
|
||||||
FormatBuiltinArg(arg_format, arg.long_double_value, width, precision);
|
FormatBuiltinArg(arg_format, arg.long_double_value, width, precision);
|
||||||
break;
|
break;
|
||||||
|
case POINTER:
|
||||||
|
// TODO: don't allow any type specifiers other than 'p'
|
||||||
|
*arg_format_ptr++ = 'p';
|
||||||
|
*arg_format_ptr = '\0';
|
||||||
|
FormatBuiltinArg(arg_format, arg.pointer_value, width, precision);
|
||||||
|
break;
|
||||||
|
case CHAR:
|
||||||
|
// TODO: check if type is 'c' or none
|
||||||
|
if (width <= 1) {
|
||||||
|
buffer_.push_back(arg.int_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*arg_format_ptr++ = 'c';
|
||||||
|
*arg_format_ptr = '\0';
|
||||||
|
FormatBuiltinArg(arg_format, arg.int_value, width, precision);
|
||||||
|
break;
|
||||||
case STRING:
|
case STRING:
|
||||||
// TODO: align string left by default
|
// TODO: check if type is 's' or none
|
||||||
if (width == -1 && precision == -1) {
|
if (width == -1 || width <= arg.size) {
|
||||||
const char *str = arg.string_value;
|
const char *str = arg.string_value;
|
||||||
std::size_t size = arg.size;
|
size_t size = arg.size;
|
||||||
if (size == 0 && *str)
|
if (size == 0 && *str)
|
||||||
size = std::strlen(str);
|
size = std::strlen(str);
|
||||||
buffer_.reserve(buffer_.size() + size + 1);
|
buffer_.reserve(buffer_.size() + size + 1);
|
||||||
@ -203,17 +248,14 @@ void fmt::Formatter::Format() {
|
|||||||
FormatBuiltinArg(arg_format, arg.string_value, width, precision);
|
FormatBuiltinArg(arg_format, arg.string_value, width, precision);
|
||||||
break;
|
break;
|
||||||
case WSTRING:
|
case WSTRING:
|
||||||
|
// TODO: check if type is 's' or none
|
||||||
*arg_format_ptr++ = 'l';
|
*arg_format_ptr++ = 'l';
|
||||||
*arg_format_ptr++ = 's';
|
*arg_format_ptr++ = 's';
|
||||||
*arg_format_ptr = '\0';
|
*arg_format_ptr = '\0';
|
||||||
FormatBuiltinArg(arg_format, arg.wstring_value, width, precision);
|
FormatBuiltinArg(arg_format, arg.wstring_value, width, precision);
|
||||||
break;
|
break;
|
||||||
case POINTER:
|
|
||||||
*arg_format_ptr++ = 'p';
|
|
||||||
*arg_format_ptr = '\0';
|
|
||||||
FormatBuiltinArg(arg_format, arg.pointer_value, width, precision);
|
|
||||||
break;
|
|
||||||
case CUSTOM:
|
case CUSTOM:
|
||||||
|
// TODO: check if type is 's' or none
|
||||||
(this->*arg.format)(arg.custom_value, width);
|
(this->*arg.format)(arg.custom_value, width);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
17
format.h
17
format.h
@ -33,8 +33,9 @@ class Formatter {
|
|||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
// Numeric types should go first.
|
// Numeric types should go first.
|
||||||
INT, UINT, LONG, ULONG, DOUBLE, LONG_DOUBLE, POINTER,
|
INT, UINT, LONG, ULONG, DOUBLE, LONG_DOUBLE,
|
||||||
LAST_NUMERIC_TYPE = POINTER, CHAR, STRING, WSTRING, CUSTOM
|
LAST_NUMERIC_TYPE = LONG_DOUBLE,
|
||||||
|
CHAR, STRING, WSTRING, POINTER, CUSTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (Formatter::*FormatFunc)(const void *arg, int width);
|
typedef void (Formatter::*FormatFunc)(const void *arg, int width);
|
||||||
@ -63,7 +64,6 @@ class Formatter {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Arg(char value) : type(CHAR), int_value(value) {}
|
|
||||||
explicit Arg(int value) : type(INT), int_value(value) {}
|
explicit Arg(int value) : type(INT), int_value(value) {}
|
||||||
explicit Arg(unsigned value) : type(UINT), uint_value(value) {}
|
explicit Arg(unsigned value) : type(UINT), uint_value(value) {}
|
||||||
explicit Arg(long value) : type(LONG), long_value(value) {}
|
explicit Arg(long value) : type(LONG), long_value(value) {}
|
||||||
@ -71,6 +71,7 @@ class Formatter {
|
|||||||
explicit Arg(double value) : type(DOUBLE), double_value(value) {}
|
explicit Arg(double value) : type(DOUBLE), double_value(value) {}
|
||||||
explicit Arg(long double value)
|
explicit Arg(long double value)
|
||||||
: type(LONG_DOUBLE), long_double_value(value) {}
|
: type(LONG_DOUBLE), long_double_value(value) {}
|
||||||
|
explicit Arg(char value) : type(CHAR), int_value(value) {}
|
||||||
explicit Arg(const char *value, std::size_t size = 0)
|
explicit Arg(const char *value, std::size_t size = 0)
|
||||||
: type(STRING), string_value(value), size(size) {}
|
: type(STRING), string_value(value), size(size) {}
|
||||||
explicit Arg(const wchar_t *value) : type(WSTRING), wstring_value(value) {}
|
explicit Arg(const wchar_t *value) : type(WSTRING), wstring_value(value) {}
|
||||||
@ -158,11 +159,6 @@ class ArgFormatter {
|
|||||||
return af.FinishFormatting()->c_str();
|
return af.FinishFormatting()->c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
ArgFormatter &operator<<(char value) {
|
|
||||||
formatter_->Add(Formatter::Arg(value));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArgFormatter &operator<<(int value) {
|
ArgFormatter &operator<<(int value) {
|
||||||
formatter_->Add(Formatter::Arg(value));
|
formatter_->Add(Formatter::Arg(value));
|
||||||
return *this;
|
return *this;
|
||||||
@ -193,6 +189,11 @@ class ArgFormatter {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArgFormatter &operator<<(char value) {
|
||||||
|
formatter_->Add(Formatter::Arg(value));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
ArgFormatter &operator<<(const char *value) {
|
ArgFormatter &operator<<(const char *value) {
|
||||||
formatter_->Add(Formatter::Arg(value));
|
formatter_->Add(Formatter::Arg(value));
|
||||||
return *this;
|
return *this;
|
||||||
|
102
format_test.cc
102
format_test.cc
@ -117,23 +117,25 @@ TEST(FormatterTest, PlusFlag) {
|
|||||||
EXPECT_EQ("+42", str(Format("{0:+}") << 42));
|
EXPECT_EQ("+42", str(Format("{0:+}") << 42));
|
||||||
EXPECT_EQ("-42", str(Format("{0:+}") << -42));
|
EXPECT_EQ("-42", str(Format("{0:+}") << -42));
|
||||||
EXPECT_EQ("+42", str(Format("{0:+}") << 42));
|
EXPECT_EQ("+42", str(Format("{0:+}") << 42));
|
||||||
EXPECT_EQ("+42", str(Format("{0:+}") << 42u));
|
EXPECT_THROW_MSG(Format("{0:+}") << 42u,
|
||||||
|
FormatError, "format specifier '+' requires signed argument");
|
||||||
EXPECT_EQ("+42", str(Format("{0:+}") << 42l));
|
EXPECT_EQ("+42", str(Format("{0:+}") << 42l));
|
||||||
EXPECT_EQ("+42", str(Format("{0:+}") << 42ul));
|
EXPECT_THROW_MSG(Format("{0:+}") << 42ul,
|
||||||
|
FormatError, "format specifier '+' requires signed argument");
|
||||||
EXPECT_EQ("+42", str(Format("{0:+}") << 42.0));
|
EXPECT_EQ("+42", str(Format("{0:+}") << 42.0));
|
||||||
EXPECT_EQ("+42", str(Format("{0:+}") << 42.0l));
|
EXPECT_EQ("+42", str(Format("{0:+}") << 42.0l));
|
||||||
EXPECT_EQ("+0x42",
|
|
||||||
str(Format("{0:+}") << reinterpret_cast<void*>(0x42)));
|
|
||||||
EXPECT_THROW_MSG(Format("{0:+") << 'c',
|
EXPECT_THROW_MSG(Format("{0:+") << 'c',
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(Format("{0:+}") << 'c',
|
EXPECT_THROW_MSG(Format("{0:+}") << 'c',
|
||||||
FormatError, "format specifier '+' used with non-numeric type");
|
FormatError, "format specifier '+' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(Format("{0:+}") << "abc",
|
EXPECT_THROW_MSG(Format("{0:+}") << "abc",
|
||||||
FormatError, "format specifier '+' used with non-numeric type");
|
FormatError, "format specifier '+' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(Format("{0:+}") << L"abc",
|
EXPECT_THROW_MSG(Format("{0:+}") << L"abc",
|
||||||
FormatError, "format specifier '+' used with non-numeric type");
|
FormatError, "format specifier '+' requires numeric argument");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:+}") << reinterpret_cast<void*>(0x42),
|
||||||
|
FormatError, "format specifier '+' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(Format("{0:+}") << TestString(),
|
EXPECT_THROW_MSG(Format("{0:+}") << TestString(),
|
||||||
FormatError, "format specifier '+' used with non-numeric type");
|
FormatError, "format specifier '+' requires numeric argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, ZeroFlag) {
|
TEST(FormatterTest, ZeroFlag) {
|
||||||
@ -144,18 +146,18 @@ TEST(FormatterTest, ZeroFlag) {
|
|||||||
EXPECT_EQ("00042", str(Format("{0:05}") << 42ul));
|
EXPECT_EQ("00042", str(Format("{0:05}") << 42ul));
|
||||||
EXPECT_EQ("-0042", str(Format("{0:05}") << -42.0));
|
EXPECT_EQ("-0042", str(Format("{0:05}") << -42.0));
|
||||||
EXPECT_EQ("-0042", str(Format("{0:05}") << -42.0l));
|
EXPECT_EQ("-0042", str(Format("{0:05}") << -42.0l));
|
||||||
EXPECT_EQ("0x0042",
|
|
||||||
str(Format("{0:06}") << reinterpret_cast<void*>(0x42)));
|
|
||||||
EXPECT_THROW_MSG(Format("{0:0") << 'c',
|
EXPECT_THROW_MSG(Format("{0:0") << 'c',
|
||||||
FormatError, "unmatched '{' in format");
|
FormatError, "unmatched '{' in format");
|
||||||
EXPECT_THROW_MSG(Format("{0:05}") << 'c',
|
EXPECT_THROW_MSG(Format("{0:05}") << 'c',
|
||||||
FormatError, "format specifier '0' used with non-numeric type");
|
FormatError, "format specifier '0' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(Format("{0:05}") << "abc",
|
EXPECT_THROW_MSG(Format("{0:05}") << "abc",
|
||||||
FormatError, "format specifier '0' used with non-numeric type");
|
FormatError, "format specifier '0' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(Format("{0:05}") << L"abc",
|
EXPECT_THROW_MSG(Format("{0:05}") << L"abc",
|
||||||
FormatError, "format specifier '0' used with non-numeric type");
|
FormatError, "format specifier '0' requires numeric argument");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:05}") << reinterpret_cast<void*>(0x42),
|
||||||
|
FormatError, "format specifier '0' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(Format("{0:05}") << TestString(),
|
EXPECT_THROW_MSG(Format("{0:05}") << TestString(),
|
||||||
FormatError, "format specifier '0' used with non-numeric type");
|
FormatError, "format specifier '0' requires numeric argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, Width) {
|
TEST(FormatterTest, Width) {
|
||||||
@ -181,7 +183,7 @@ TEST(FormatterTest, Width) {
|
|||||||
EXPECT_EQ(" -42", str(Format("{0:4}") << -42));
|
EXPECT_EQ(" -42", str(Format("{0:4}") << -42));
|
||||||
EXPECT_EQ(" 42", str(Format("{0:5}") << 42u));
|
EXPECT_EQ(" 42", str(Format("{0:5}") << 42u));
|
||||||
EXPECT_EQ(" -42", str(Format("{0:6}") << -42l));
|
EXPECT_EQ(" -42", str(Format("{0:6}") << -42l));
|
||||||
EXPECT_EQ(" 42", str(Format("{0:7}") << 42lu));
|
EXPECT_EQ(" 42", str(Format("{0:7}") << 42ul));
|
||||||
EXPECT_EQ(" -1.23", str(Format("{0:8}") << -1.23));
|
EXPECT_EQ(" -1.23", str(Format("{0:8}") << -1.23));
|
||||||
EXPECT_EQ(" -1.23", str(Format("{0:9}") << -1.23l));
|
EXPECT_EQ(" -1.23", str(Format("{0:9}") << -1.23l));
|
||||||
EXPECT_EQ(" 0xcafe",
|
EXPECT_EQ(" 0xcafe",
|
||||||
@ -192,6 +194,76 @@ TEST(FormatterTest, Width) {
|
|||||||
EXPECT_EQ("test ", str(Format("{0:14}") << TestString("test")));
|
EXPECT_EQ("test ", str(Format("{0:14}") << TestString("test")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatterTest, Precision) {
|
||||||
|
char format[256];
|
||||||
|
if (ULONG_MAX > UINT_MAX) {
|
||||||
|
std::sprintf(format, "{0:.%lu", INT_MAX + 1l);
|
||||||
|
EXPECT_THROW_MSG(Format(format), FormatError, "unmatched '{' in format");
|
||||||
|
std::sprintf(format, "{0:.%lu}", UINT_MAX + 1l);
|
||||||
|
EXPECT_THROW_MSG(Format(format) << 0,
|
||||||
|
FormatError, "number is too big in format");
|
||||||
|
} else {
|
||||||
|
std::sprintf(format, "{0:.%u0", UINT_MAX);
|
||||||
|
EXPECT_THROW_MSG(Format(format), FormatError, "unmatched '{' in format");
|
||||||
|
std::sprintf(format, "{0:.%u0}", UINT_MAX);
|
||||||
|
EXPECT_THROW_MSG(Format(format) << 0,
|
||||||
|
FormatError, "number is too big in format");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sprintf(format, "{0:.%u", INT_MAX + 1u);
|
||||||
|
EXPECT_THROW_MSG(Format(format), FormatError, "unmatched '{' in format");
|
||||||
|
std::sprintf(format, "{0:.%u}", INT_MAX + 1u);
|
||||||
|
EXPECT_THROW_MSG(Format(format) << 0,
|
||||||
|
FormatError, "number is too big in format");
|
||||||
|
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.") << 0,
|
||||||
|
FormatError, "unmatched '{' in format");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.}") << 0,
|
||||||
|
FormatError, "missing precision in format");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2") << 0,
|
||||||
|
FormatError, "unmatched '{' in format");
|
||||||
|
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << 42,
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_EQ("42.00", str(Format("{0:.2f}") << 42));
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << 42u,
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_EQ("42.00", str(Format("{0:.2f}") << 42u));
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << 42l,
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_EQ("42.00", str(Format("{0:.2f}") << 42l));
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << 42ul,
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_EQ("42.00", str(Format("{0:.2f}") << 42ul));
|
||||||
|
EXPECT_EQ("1.2", str(Format("{0:.2}") << 1.2345));
|
||||||
|
EXPECT_EQ("1.2", str(Format("{0:.2}") << 1.2345l));
|
||||||
|
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << reinterpret_cast<void*>(0xcafe),
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2f}") << reinterpret_cast<void*>(0xcafe),
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << 'x',
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2f}") << 'x',
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << "str",
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2f}") << "str",
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << L"str",
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2f}") << L"str",
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2}") << TestString(),
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
EXPECT_THROW_MSG(Format("{0:.2f}") << TestString(),
|
||||||
|
FormatError, "precision specifier requires floating-point type");
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, FormatInt) {
|
TEST(FormatterTest, FormatInt) {
|
||||||
EXPECT_EQ("42", str(Format("{0}") << 42));
|
EXPECT_EQ("42", str(Format("{0}") << 42));
|
||||||
EXPECT_EQ("-1234", str(Format("{0}") << -1234));
|
EXPECT_EQ("-1234", str(Format("{0}") << -1234));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user