mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
Make numeric alignment optional
This commit is contained in:
@ -101,11 +101,6 @@ The meaning of the various alignment options is as follows:
|
|||||||
| ``'>'`` | Forces the field to be right-aligned within the |
|
| ``'>'`` | Forces the field to be right-aligned within the |
|
||||||
| | available space (this is the default for numbers). |
|
| | available space (this is the default for numbers). |
|
||||||
+---------+----------------------------------------------------------+
|
+---------+----------------------------------------------------------+
|
||||||
| ``'='`` | Forces the padding to be placed after the sign (if any) |
|
|
||||||
| | but before the digits. This is used for printing fields |
|
|
||||||
| | in the form '+000000120'. This alignment option is only |
|
|
||||||
| | valid for numeric types. |
|
|
||||||
+---------+----------------------------------------------------------+
|
|
||||||
| ``'^'`` | Forces the field to be centered within the available |
|
| ``'^'`` | Forces the field to be centered within the available |
|
||||||
| | space. |
|
| | space. |
|
||||||
+---------+----------------------------------------------------------+
|
+---------+----------------------------------------------------------+
|
||||||
@ -154,9 +149,11 @@ conversions, trailing zeros are not removed from the result.
|
|||||||
*width* is a decimal integer defining the minimum field width. If not
|
*width* is a decimal integer defining the minimum field width. If not
|
||||||
specified, then the field width will be determined by the content.
|
specified, then the field width will be determined by the content.
|
||||||
|
|
||||||
Preceding the *width* field by a zero (``'0'``) character enables
|
Preceding the *width* field by a zero (``'0'``) character enables sign-aware
|
||||||
sign-aware zero-padding for numeric types. This is equivalent to a *fill*
|
zero-padding for numeric types. It forces the padding to be placed after the
|
||||||
character of ``'0'`` with an *alignment* type of ``'='``.
|
sign or base (if any) but before the digits. This is used for printing fields in
|
||||||
|
the form '+000000120'. This option is only valid for numeric types and it has no
|
||||||
|
effect on formatting of infinity and NaN.
|
||||||
|
|
||||||
The *precision* is a decimal number indicating how many digits should be
|
The *precision* is a decimal number indicating how many digits should be
|
||||||
displayed after the decimal point for a floating-point value formatted with
|
displayed after the decimal point for a floating-point value formatted with
|
||||||
|
@ -185,6 +185,10 @@ inline uint32_t clzll(uint64_t x) {
|
|||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FMT_NUMERIC_ALIGN
|
||||||
|
# define FMT_NUMERIC_ALIGN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
@ -2300,9 +2304,11 @@ FMT_CONSTEXPR const Char* parse_align(const Char* begin, const Char* end,
|
|||||||
case '>':
|
case '>':
|
||||||
align = align::right;
|
align = align::right;
|
||||||
break;
|
break;
|
||||||
|
#if FMT_NUMERIC_ALIGN
|
||||||
case '=':
|
case '=':
|
||||||
align = align::numeric;
|
align = align::numeric;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case '^':
|
case '^':
|
||||||
align = align::center;
|
align = align::center;
|
||||||
break;
|
break;
|
||||||
|
@ -697,12 +697,6 @@ TEST(FormatToTest, WideString) {
|
|||||||
EXPECT_STREQ(buf.data(), L"42");
|
EXPECT_STREQ(buf.data(), L"42");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatToTest, FormatToNonbackInsertIteratorWithSignAndNumericAlignment) {
|
|
||||||
char buffer[16] = {};
|
|
||||||
fmt::format_to(fmt::internal::make_checked(buffer, 16), "{: =+}", 42.0);
|
|
||||||
EXPECT_STREQ("+42.0", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(FormatToTest, FormatToMemoryBuffer) {
|
TEST(FormatToTest, FormatToMemoryBuffer) {
|
||||||
fmt::basic_memory_buffer<char, 100> buffer;
|
fmt::basic_memory_buffer<char, 100> buffer;
|
||||||
fmt::format_to(buffer, "{}", "foo");
|
fmt::format_to(buffer, "{}", "foo");
|
||||||
@ -856,6 +850,7 @@ TEST(FormatterTest, RightAlign) {
|
|||||||
EXPECT_EQ(" 0xface", format("{0:>8}", reinterpret_cast<void*>(0xface)));
|
EXPECT_EQ(" 0xface", format("{0:>8}", reinterpret_cast<void*>(0xface)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FMT_NUMERIC_ALIGN
|
||||||
TEST(FormatterTest, NumericAlign) {
|
TEST(FormatterTest, NumericAlign) {
|
||||||
EXPECT_EQ(" 42", format("{0:=4}", 42));
|
EXPECT_EQ(" 42", format("{0:=4}", 42));
|
||||||
EXPECT_EQ("+ 42", format("{0:=+4}", 42));
|
EXPECT_EQ("+ 42", format("{0:=+4}", 42));
|
||||||
@ -882,6 +877,13 @@ TEST(FormatterTest, NumericAlign) {
|
|||||||
EXPECT_EQ(" 1.0", fmt::format("{:= }", 1.0));
|
EXPECT_EQ(" 1.0", fmt::format("{:= }", 1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(FormatToTest, FormatToNonbackInsertIteratorWithSignAndNumericAlignment) {
|
||||||
|
char buffer[16] = {};
|
||||||
|
fmt::format_to(fmt::internal::make_checked(buffer, 16), "{: =+}", 42.0);
|
||||||
|
EXPECT_STREQ("+42.0", buffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(FormatterTest, CenterAlign) {
|
TEST(FormatterTest, CenterAlign) {
|
||||||
EXPECT_EQ(" 42 ", format("{0:^5}", 42));
|
EXPECT_EQ(" 42 ", format("{0:^5}", 42));
|
||||||
EXPECT_EQ(" 42 ", format("{0:^5o}", 042));
|
EXPECT_EQ(" 42 ", format("{0:^5o}", 042));
|
||||||
@ -2055,8 +2057,10 @@ TEST(FormatTest, DynamicFormatter) {
|
|||||||
"cannot switch from manual to automatic argument indexing");
|
"cannot switch from manual to automatic argument indexing");
|
||||||
EXPECT_THROW_MSG(format("{:{0}}", num), format_error,
|
EXPECT_THROW_MSG(format("{:{0}}", num), format_error,
|
||||||
"cannot switch from automatic to manual argument indexing");
|
"cannot switch from automatic to manual argument indexing");
|
||||||
|
#if FMT_NUMERIC_ALIGN
|
||||||
EXPECT_THROW_MSG(format("{:=}", str), format_error,
|
EXPECT_THROW_MSG(format("{:=}", str), format_error,
|
||||||
"format specifier requires numeric argument");
|
"format specifier requires numeric argument");
|
||||||
|
#endif
|
||||||
EXPECT_THROW_MSG(format("{:+}", str), format_error,
|
EXPECT_THROW_MSG(format("{:+}", str), format_error,
|
||||||
"format specifier requires numeric argument");
|
"format specifier requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{:-}", str), format_error,
|
EXPECT_THROW_MSG(format("{:-}", str), format_error,
|
||||||
@ -2439,13 +2443,15 @@ TEST(FormatTest, FormatStringErrors) {
|
|||||||
EXPECT_ERROR("{0:s", "unknown format specifier", Date);
|
EXPECT_ERROR("{0:s", "unknown format specifier", Date);
|
||||||
# if FMT_MSC_VER >= 1916
|
# if FMT_MSC_VER >= 1916
|
||||||
// This causes an internal compiler error in MSVC2017.
|
// This causes an internal compiler error in MSVC2017.
|
||||||
EXPECT_ERROR("{0:=5", "unknown format specifier", int);
|
|
||||||
EXPECT_ERROR("{:{<}", "invalid fill character '{'", int);
|
EXPECT_ERROR("{:{<}", "invalid fill character '{'", int);
|
||||||
EXPECT_ERROR("{:10000000000}", "number is too big", int);
|
EXPECT_ERROR("{:10000000000}", "number is too big", int);
|
||||||
EXPECT_ERROR("{:.10000000000}", "number is too big", int);
|
EXPECT_ERROR("{:.10000000000}", "number is too big", int);
|
||||||
EXPECT_ERROR_NOARGS("{:x}", "argument index out of range");
|
EXPECT_ERROR_NOARGS("{:x}", "argument index out of range");
|
||||||
|
#if FMT_NUMERIC_ALIGN
|
||||||
|
EXPECT_ERROR("{0:=5", "unknown format specifier", int);
|
||||||
EXPECT_ERROR("{:=}", "format specifier requires numeric argument",
|
EXPECT_ERROR("{:=}", "format specifier requires numeric argument",
|
||||||
const char*);
|
const char*);
|
||||||
|
#endif
|
||||||
EXPECT_ERROR("{:+}", "format specifier requires numeric argument",
|
EXPECT_ERROR("{:+}", "format specifier requires numeric argument",
|
||||||
const char*);
|
const char*);
|
||||||
EXPECT_ERROR("{:-}", "format specifier requires numeric argument",
|
EXPECT_ERROR("{:-}", "format specifier requires numeric argument",
|
||||||
|
@ -95,8 +95,10 @@ TEST(OStreamTest, Format) {
|
|||||||
TEST(OStreamTest, FormatSpecs) {
|
TEST(OStreamTest, FormatSpecs) {
|
||||||
EXPECT_EQ("def ", format("{0:<5}", TestString("def")));
|
EXPECT_EQ("def ", format("{0:<5}", TestString("def")));
|
||||||
EXPECT_EQ(" def", format("{0:>5}", TestString("def")));
|
EXPECT_EQ(" def", format("{0:>5}", TestString("def")));
|
||||||
|
#if FMT_NUMERIC_ALIGN
|
||||||
EXPECT_THROW_MSG(format("{0:=5}", TestString("def")), format_error,
|
EXPECT_THROW_MSG(format("{0:=5}", TestString("def")), format_error,
|
||||||
"format specifier requires numeric argument");
|
"format specifier requires numeric argument");
|
||||||
|
#endif
|
||||||
EXPECT_EQ(" def ", format("{0:^5}", TestString("def")));
|
EXPECT_EQ(" def ", format("{0:^5}", TestString("def")));
|
||||||
EXPECT_EQ("def**", format("{0:*<5}", TestString("def")));
|
EXPECT_EQ("def**", format("{0:*<5}", TestString("def")));
|
||||||
EXPECT_THROW_MSG(format("{0:+}", TestString()), format_error,
|
EXPECT_THROW_MSG(format("{0:+}", TestString()), format_error,
|
||||||
|
@ -30,18 +30,14 @@ TEST(StdFormatTest, Alignment) {
|
|||||||
// Error: '=' with charT and no integer presentation type
|
// Error: '=' with charT and no integer presentation type
|
||||||
EXPECT_THROW(string s5 = format("{:=6}", 'x'), std::format_error);
|
EXPECT_THROW(string s5 = format("{:=6}", 'x'), std::format_error);
|
||||||
string s6 = format("{:6d}", c); // s6 == " 120"
|
string s6 = format("{:6d}", c); // s6 == " 120"
|
||||||
string s7 = format("{:=+06d}", c); // s7 == "+00120"
|
string s7 = format("{:6}", true); // s9 == "true "
|
||||||
string s8 = format("{:0=#6x}", 0xa); // s8 == "0x000a"
|
|
||||||
string s9 = format("{:6}", true); // s9 == "true "
|
|
||||||
EXPECT_EQ(s0, " 42");
|
EXPECT_EQ(s0, " 42");
|
||||||
EXPECT_EQ(s1, "x ");
|
EXPECT_EQ(s1, "x ");
|
||||||
EXPECT_EQ(s2, "x*****");
|
EXPECT_EQ(s2, "x*****");
|
||||||
EXPECT_EQ(s3, "*****x");
|
EXPECT_EQ(s3, "*****x");
|
||||||
EXPECT_EQ(s4, "**x***");
|
EXPECT_EQ(s4, "**x***");
|
||||||
EXPECT_EQ(s6, " 120");
|
EXPECT_EQ(s6, " 120");
|
||||||
EXPECT_EQ(s7, "+00120");
|
EXPECT_EQ(s7, "true ");
|
||||||
EXPECT_EQ(s8, "0x000a");
|
|
||||||
EXPECT_EQ(s9, "true ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(StdFormatTest, Float) {
|
TEST(StdFormatTest, Float) {
|
||||||
|
Reference in New Issue
Block a user