mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-27 15:35:18 +00:00
Allow precision specifier for non-float arguments
This commit is contained in:
parent
cd828a8691
commit
43aebf51d6
@ -157,7 +157,8 @@ displayed after the decimal point for a floating-point value formatted with
|
|||||||
``'f'`` and ``'F'``, or before and after the decimal point for a floating-point
|
``'f'`` and ``'F'``, or before and after the decimal point for a floating-point
|
||||||
value formatted with ``'g'`` or ``'G'``. For non-number types the field
|
value formatted with ``'g'`` or ``'G'``. For non-number types the field
|
||||||
indicates the maximum field size - in other words, how many characters will be
|
indicates the maximum field size - in other words, how many characters will be
|
||||||
used from the field content. The *precision* is not allowed for integer values.
|
used from the field content. The *precision* is not allowed for integer values
|
||||||
|
or pointers.
|
||||||
|
|
||||||
Finally, the *type* determines how the data should be presented.
|
Finally, the *type* determines how the data should be presented.
|
||||||
|
|
||||||
|
13
format.cc
13
format.cc
@ -561,9 +561,13 @@ class fmt::internal::ArgFormatter :
|
|||||||
if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
|
if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0)
|
||||||
FMT_THROW(FormatError("invalid format specifier for char"));
|
FMT_THROW(FormatError("invalid format specifier for char"));
|
||||||
typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr;
|
typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr;
|
||||||
|
Char fill = static_cast<Char>(spec_.fill());
|
||||||
|
if (spec_.precision_ == 0) {
|
||||||
|
std::fill_n(writer_.grow_buffer(spec_.width_), spec_.width_, fill);
|
||||||
|
return;
|
||||||
|
}
|
||||||
CharPtr out = CharPtr();
|
CharPtr out = CharPtr();
|
||||||
if (spec_.width_ > 1) {
|
if (spec_.width_ > 1) {
|
||||||
Char fill = static_cast<Char>(spec_.fill());
|
|
||||||
out = writer_.grow_buffer(spec_.width_);
|
out = writer_.grow_buffer(spec_.width_);
|
||||||
if (spec_.align_ == fmt::ALIGN_RIGHT) {
|
if (spec_.align_ == fmt::ALIGN_RIGHT) {
|
||||||
std::fill_n(out, spec_.width_ - 1, fill);
|
std::fill_n(out, spec_.width_ - 1, fill);
|
||||||
@ -615,6 +619,8 @@ void fmt::BasicWriter<Char>::write_str(
|
|||||||
if (*str_value)
|
if (*str_value)
|
||||||
str_size = std::char_traits<StrChar>::length(str_value);
|
str_size = std::char_traits<StrChar>::length(str_value);
|
||||||
}
|
}
|
||||||
|
if (spec.precision_ >= 0 && spec.precision_ < str_size)
|
||||||
|
str_size = spec.precision_;
|
||||||
write_str(str_value, str_size, spec);
|
write_str(str_value, str_size, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,9 +1017,10 @@ const Char *fmt::BasicFormatter<Char>::format(
|
|||||||
} else {
|
} else {
|
||||||
FMT_THROW(FormatError("missing precision specifier"));
|
FMT_THROW(FormatError("missing precision specifier"));
|
||||||
}
|
}
|
||||||
if (arg.type != Arg::DOUBLE && arg.type != Arg::LONG_DOUBLE) {
|
if (arg.type < Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) {
|
||||||
FMT_THROW(FormatError(
|
FMT_THROW(FormatError(
|
||||||
"precision specifier requires floating-point argument"));
|
fmt::format("precision not allowed in {} format specifier",
|
||||||
|
arg.type == Arg::POINTER ? "pointer" : "integer")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,53 +824,42 @@ TEST(FormatterTest, Precision) {
|
|||||||
FormatError, "missing precision specifier");
|
FormatError, "missing precision specifier");
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2", 0),
|
EXPECT_THROW_MSG(format("{0:.2", 0),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42),
|
EXPECT_THROW_MSG(format("{0:.2}", 42),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42u),
|
EXPECT_THROW_MSG(format("{0:.2}", 42u),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42u),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42u),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42l),
|
EXPECT_THROW_MSG(format("{0:.2}", 42l),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42l),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42l),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42ul),
|
EXPECT_THROW_MSG(format("{0:.2}", 42ul),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42ul),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42ul),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42ll),
|
EXPECT_THROW_MSG(format("{0:.2}", 42ll),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42ll),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42ll),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42ull),
|
EXPECT_THROW_MSG(format("{0:.2}", 42ull),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42ull),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42ull),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_EQ("1.2", format("{0:.2}", 1.2345));
|
EXPECT_EQ("1.2", format("{0:.2}", 1.2345));
|
||||||
EXPECT_EQ("1.2", format("{0:.2}", 1.2345l));
|
EXPECT_EQ("1.2", format("{0:.2}", 1.2345l));
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", reinterpret_cast<void*>(0xcafe)),
|
EXPECT_THROW_MSG(format("{0:.2}", reinterpret_cast<void*>(0xcafe)),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in pointer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)),
|
EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in pointer format specifier");
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 'x'),
|
EXPECT_EQ(" ", format("{0:3.0}", 'x'));
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
EXPECT_EQ("st", format("{0:.2}", "str"));
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 'x'),
|
EXPECT_EQ("te", format("{0:.2}", TestString("test")));
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", "str"),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", "str"),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", TestString()),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", TestString()),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(FormatterTest, RuntimePrecision) {
|
TEST(FormatterTest, RuntimePrecision) {
|
||||||
@ -893,7 +882,7 @@ TEST(FormatterTest, RuntimePrecision) {
|
|||||||
EXPECT_THROW_MSG(format("{0:.{x}}", 0),
|
EXPECT_THROW_MSG(format("{0:.{x}}", 0),
|
||||||
FormatError, "invalid format string");
|
FormatError, "invalid format string");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}", 0, 0),
|
EXPECT_THROW_MSG(format("{0:.{1}", 0, 0),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 0),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 0),
|
||||||
FormatError, "argument index out of range");
|
FormatError, "argument index out of range");
|
||||||
|
|
||||||
@ -920,51 +909,40 @@ TEST(FormatterTest, RuntimePrecision) {
|
|||||||
FormatError, "precision is not integer");
|
FormatError, "precision is not integer");
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42u, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42u, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42u, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42u, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42l, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42l, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42l, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42l, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42ul, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42ul, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ul, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ul, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42ll, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42ll, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ll, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ll, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42ull, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42ull, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in integer format specifier");
|
||||||
EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2));
|
EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2));
|
||||||
EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l));
|
EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l));
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", reinterpret_cast<void*>(0xcafe), 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", reinterpret_cast<void*>(0xcafe), 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in pointer format specifier");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2),
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
FormatError, "precision not allowed in pointer format specifier");
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 'x', 2),
|
EXPECT_EQ(" ", format("{0:3.{1}}", 'x', 0));
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
EXPECT_EQ("st", format("{0:.{1}}", "str", 2));
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 'x', 2),
|
EXPECT_EQ("te", format("{0:.{1}}", TestString("test"), 2));
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", "str", 2),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", "str", 2),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", TestString(), 2),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", TestString(), 2),
|
|
||||||
FormatError, "precision specifier requires floating-point argument");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user