Use textual representation for bool by default (#170)

This commit is contained in:
vitaut 2015-06-11 09:00:06 -07:00
parent fd5c2e909b
commit 9d09214e7a
5 changed files with 32 additions and 9 deletions

View File

@ -220,6 +220,9 @@ The available integer presentation types are:
+---------+----------------------------------------------------------+ +---------+----------------------------------------------------------+
Integer presentation types can also be used with character and Boolean values. Integer presentation types can also be used with character and Boolean values.
Boolean values are formatted using textual representation, either ``true`` or
``false``, if the presentation type is not specified.
The available presentation types for floating-point values are: The available presentation types for floating-point values are:
+---------+----------------------------------------------------------+ +---------+----------------------------------------------------------+

View File

@ -653,6 +653,16 @@ class fmt::internal::ArgFormatter :
template <typename T> template <typename T>
void visit_any_double(T value) { writer_.write_double(value, spec_); } void visit_any_double(T value) { writer_.write_double(value, spec_); }
void visit_bool(bool value) {
if (spec_.type_) {
writer_.write_int(value, spec_);
return;
}
const char *str_value = value ? "true" : "false";
Arg::StringValue<char> str = { str_value, strlen(str_value) };
writer_.write_str(str, spec_);
}
void visit_char(int value) { void visit_char(int value) {
if (spec_.type_ && spec_.type_ != 'c') { if (spec_.type_ && spec_.type_ != 'c') {
spec_.flags_ |= CHAR_FLAG; spec_.flags_ |= CHAR_FLAG;

View File

@ -760,7 +760,7 @@ struct Value {
enum Type { enum Type {
NONE, NAMED_ARG, NONE, NAMED_ARG,
// Integer types should go first, // Integer types should go first,
INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR, INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR,
// followed by floating-point types. // followed by floating-point types.
DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
CSTRING, STRING, WSTRING, POINTER, CUSTOM CSTRING, STRING, WSTRING, POINTER, CUSTOM
@ -886,7 +886,7 @@ class MakeValue : public Arg {
MakeValue(Type value) { field = value; } \ MakeValue(Type value) { field = value; } \
static uint64_t type(Type) { return Arg::TYPE; } static uint64_t type(Type) { return Arg::TYPE; }
FMT_MAKE_VALUE(bool, int_value, INT) FMT_MAKE_VALUE(bool, int_value, BOOL)
FMT_MAKE_VALUE(short, int_value, INT) FMT_MAKE_VALUE(short, int_value, INT)
FMT_MAKE_VALUE(unsigned short, uint_value, UINT) FMT_MAKE_VALUE(unsigned short, uint_value, UINT)
FMT_MAKE_VALUE(int, int_value, INT) FMT_MAKE_VALUE(int, int_value, INT)
@ -1036,6 +1036,9 @@ class ArgVisitor {
Result visit_ulong_long(ULongLong value) { Result visit_ulong_long(ULongLong value) {
return FMT_DISPATCH(visit_any_int(value)); return FMT_DISPATCH(visit_any_int(value));
} }
Result visit_bool(bool value) {
return FMT_DISPATCH(visit_any_int(value));
}
Result visit_char(int value) { Result visit_char(int value) {
return FMT_DISPATCH(visit_any_int(value)); return FMT_DISPATCH(visit_any_int(value));
} }
@ -1081,12 +1084,14 @@ class ArgVisitor {
return FMT_DISPATCH(visit_long_long(arg.long_long_value)); return FMT_DISPATCH(visit_long_long(arg.long_long_value));
case Arg::ULONG_LONG: case Arg::ULONG_LONG:
return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value));
case Arg::BOOL:
return FMT_DISPATCH(visit_bool(arg.int_value));
case Arg::CHAR:
return FMT_DISPATCH(visit_char(arg.int_value));
case Arg::DOUBLE: case Arg::DOUBLE:
return FMT_DISPATCH(visit_double(arg.double_value)); return FMT_DISPATCH(visit_double(arg.double_value));
case Arg::LONG_DOUBLE: case Arg::LONG_DOUBLE:
return FMT_DISPATCH(visit_long_double(arg.long_double_value)); return FMT_DISPATCH(visit_long_double(arg.long_double_value));
case Arg::CHAR:
return FMT_DISPATCH(visit_char(arg.int_value));
case Arg::CSTRING: { case Arg::CSTRING: {
Arg::StringValue<char> str = arg.string; Arg::StringValue<char> str = arg.string;
str.size = 0; str.size = 0;

View File

@ -1147,8 +1147,12 @@ void check_unknown_types(
} }
} }
TEST(FormatterTest, FormatBool) { TEST(BoolTest, FormatBool) {
EXPECT_EQ(L"1", format(L"{}", true)); EXPECT_EQ("true", format("{}", true));
EXPECT_EQ("false", format("{}", false));
EXPECT_EQ("1", format("{:d}", true));
EXPECT_EQ("true ", format("{:5}", true));
EXPECT_EQ(L"true", format(L"{}", true));
} }
TEST(FormatterTest, FormatShort) { TEST(FormatterTest, FormatShort) {

View File

@ -413,9 +413,10 @@ ARG_INFO(INT, int, int_value);
ARG_INFO(UINT, unsigned, uint_value); ARG_INFO(UINT, unsigned, uint_value);
ARG_INFO(LONG_LONG, fmt::LongLong, long_long_value); ARG_INFO(LONG_LONG, fmt::LongLong, long_long_value);
ARG_INFO(ULONG_LONG, fmt::ULongLong, ulong_long_value); ARG_INFO(ULONG_LONG, fmt::ULongLong, ulong_long_value);
ARG_INFO(BOOL, int, int_value);
ARG_INFO(CHAR, int, int_value);
ARG_INFO(DOUBLE, double, double_value); ARG_INFO(DOUBLE, double, double_value);
ARG_INFO(LONG_DOUBLE, long double, long_double_value); ARG_INFO(LONG_DOUBLE, long double, long_double_value);
ARG_INFO(CHAR, int, int_value);
ARG_INFO(CSTRING, const char *, string.value); ARG_INFO(CSTRING, const char *, string.value);
ARG_INFO(STRING, const char *, string.value); ARG_INFO(STRING, const char *, string.value);
ARG_INFO(WSTRING, const wchar_t *, wstring.value); ARG_INFO(WSTRING, const wchar_t *, wstring.value);
@ -463,8 +464,8 @@ TEST(ArgTest, ArgInfo) {
TEST(ArgTest, MakeArg) { TEST(ArgTest, MakeArg) {
// Test bool. // Test bool.
EXPECT_ARG_(char, INT, bool, int, true); EXPECT_ARG_(char, BOOL, bool, int, true);
EXPECT_ARG_(wchar_t, INT, bool, int, true); EXPECT_ARG_(wchar_t, BOOL, bool, int, true);
// Test char. // Test char.
EXPECT_ARG(CHAR, signed char, 'a'); EXPECT_ARG(CHAR, signed char, 'a');