mirror of
https://github.com/fmtlib/fmt.git
synced 2026-05-04 19:44:09 +02:00
Improve handling of named arguments
This commit is contained in:
@@ -456,28 +456,6 @@ TEST(FormatDynArgsTest, CustomFormat) {
|
||||
EXPECT_EQ("cust=0 and cust=1 and cust=3", result);
|
||||
}
|
||||
|
||||
TEST(FormatDynArgsTest, NamedArgByRef) {
|
||||
fmt::dynamic_format_arg_store<fmt::format_context> store;
|
||||
|
||||
// Note: fmt::arg() constructs an object which holds a reference
|
||||
// to its value. It's not an aggregate, so it doesn't extend the
|
||||
// reference lifetime. As a result, it's a very bad idea passing temporary
|
||||
// as a named argument value. Only GCC with optimization level >0
|
||||
// complains about this.
|
||||
//
|
||||
// A real life usecase is when you have both name and value alive
|
||||
// guarantee their lifetime and thus don't want them to be copied into
|
||||
// storages.
|
||||
int a1_val{42};
|
||||
auto a1 = fmt::arg("a1_", a1_val);
|
||||
store.push_back(std::cref(a1));
|
||||
|
||||
std::string result = fmt::vformat("{a1_}", // and {} and {}",
|
||||
store);
|
||||
|
||||
EXPECT_EQ("42", result);
|
||||
}
|
||||
|
||||
struct copy_throwable {
|
||||
copy_throwable() {}
|
||||
copy_throwable(const copy_throwable&) { throw "deal with it"; }
|
||||
|
||||
+11
-11
@@ -640,7 +640,7 @@ TEST(FormatterTest, ArgErrors) {
|
||||
EXPECT_THROW_MSG(format("{"), format_error, "invalid format string");
|
||||
EXPECT_THROW_MSG(format("{?}"), format_error, "invalid format string");
|
||||
EXPECT_THROW_MSG(format("{0"), format_error, "invalid format string");
|
||||
EXPECT_THROW_MSG(format("{0}"), format_error, "argument index out of range");
|
||||
EXPECT_THROW_MSG(format("{0}"), format_error, "argument not found");
|
||||
EXPECT_THROW_MSG(format("{00}", 42), format_error, "invalid format string");
|
||||
|
||||
char format_str[BUFFER_SIZE];
|
||||
@@ -648,7 +648,7 @@ TEST(FormatterTest, ArgErrors) {
|
||||
EXPECT_THROW_MSG(format(format_str), format_error, "invalid format string");
|
||||
safe_sprintf(format_str, "{%u}", INT_MAX);
|
||||
EXPECT_THROW_MSG(format(format_str), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
|
||||
safe_sprintf(format_str, "{%u", INT_MAX + 1u);
|
||||
EXPECT_THROW_MSG(format(format_str), format_error, "number is too big");
|
||||
@@ -673,13 +673,13 @@ template <> struct TestFormat<0> {
|
||||
TEST(FormatterTest, ManyArgs) {
|
||||
EXPECT_EQ("19", TestFormat<20>::format("{19}"));
|
||||
EXPECT_THROW_MSG(TestFormat<20>::format("{20}"), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
EXPECT_THROW_MSG(TestFormat<21>::format("{21}"), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
enum { max_packed_args = fmt::internal::max_packed_args };
|
||||
std::string format_str = fmt::format("{{{}}}", max_packed_args + 1);
|
||||
EXPECT_THROW_MSG(TestFormat<max_packed_args>::format(format_str),
|
||||
format_error, "argument index out of range");
|
||||
format_error, "argument not found");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, NamedArg) {
|
||||
@@ -708,7 +708,7 @@ TEST(FormatterTest, AutoArgIndex) {
|
||||
"cannot switch from manual to automatic argument indexing");
|
||||
EXPECT_THROW_MSG(format("{:.{0}}", 1.2345, 2), format_error,
|
||||
"cannot switch from automatic to manual argument indexing");
|
||||
EXPECT_THROW_MSG(format("{}"), format_error, "argument index out of range");
|
||||
EXPECT_THROW_MSG(format("{}"), format_error, "argument not found");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, EmptySpecs) { EXPECT_EQ("42", format("{0:}", 42)); }
|
||||
@@ -1012,7 +1012,7 @@ TEST(FormatterTest, RuntimeWidth) {
|
||||
"cannot switch from manual to automatic argument indexing");
|
||||
EXPECT_THROW_MSG(format("{0:{?}}", 0), format_error, "invalid format string");
|
||||
EXPECT_THROW_MSG(format("{0:{1}}", 0), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
|
||||
EXPECT_THROW_MSG(format("{0:{0:}}", 0), format_error,
|
||||
"invalid format string");
|
||||
@@ -1161,7 +1161,7 @@ TEST(FormatterTest, RuntimePrecision) {
|
||||
EXPECT_THROW_MSG(format("{0:.{1}", 0, 0), format_error,
|
||||
"precision not allowed for this argument type");
|
||||
EXPECT_THROW_MSG(format("{0:.{1}}", 0), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
|
||||
EXPECT_THROW_MSG(format("{0:.{0:}}", 0), format_error,
|
||||
"invalid format string");
|
||||
@@ -2441,7 +2441,7 @@ TEST(FormatTest, FormatStringErrors) {
|
||||
EXPECT_ERROR("{:{<}", "invalid fill character '{'", 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 not found");
|
||||
# if FMT_NUMERIC_ALIGN
|
||||
EXPECT_ERROR("{0:=5", "unknown format specifier", int);
|
||||
EXPECT_ERROR("{:=}", "format specifier requires numeric argument",
|
||||
@@ -2482,8 +2482,8 @@ TEST(FormatTest, FormatStringErrors) {
|
||||
EXPECT_ERROR("{:.{0x}}", "invalid format string", int);
|
||||
EXPECT_ERROR("{:.{-}}", "invalid format string", int);
|
||||
EXPECT_ERROR("{:.x}", "missing precision specifier", int);
|
||||
EXPECT_ERROR_NOARGS("{}", "argument index out of range");
|
||||
EXPECT_ERROR("{1}", "argument index out of range", int);
|
||||
EXPECT_ERROR_NOARGS("{}", "argument not found");
|
||||
EXPECT_ERROR("{1}", "argument not found", int);
|
||||
EXPECT_ERROR("{1}{}",
|
||||
"cannot switch from manual to automatic argument indexing", int,
|
||||
int);
|
||||
|
||||
+6
-6
@@ -113,14 +113,14 @@ TEST(PrintfTest, SwitchArgIndexing) {
|
||||
|
||||
TEST(PrintfTest, InvalidArgIndex) {
|
||||
EXPECT_THROW_MSG(test_sprintf("%0$d", 42), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$d", 42), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX), 42), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$", 42), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM), 42), format_error,
|
||||
"number is too big");
|
||||
}
|
||||
@@ -223,7 +223,7 @@ TEST(PrintfTest, DynamicWidth) {
|
||||
EXPECT_THROW_MSG(test_sprintf("%*d", 5.0, 42), format_error,
|
||||
"width is not integer");
|
||||
EXPECT_THROW_MSG(test_sprintf("%*d"), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
EXPECT_THROW_MSG(test_sprintf("%*d", BIG_NUM, 42), format_error,
|
||||
"number is too big");
|
||||
}
|
||||
@@ -269,7 +269,7 @@ TEST(PrintfTest, DynamicPrecision) {
|
||||
EXPECT_THROW_MSG(test_sprintf("%.*d", 5.0, 42), format_error,
|
||||
"precision is not integer");
|
||||
EXPECT_THROW_MSG(test_sprintf("%.*d"), format_error,
|
||||
"argument index out of range");
|
||||
"argument not found");
|
||||
EXPECT_THROW_MSG(test_sprintf("%.*d", BIG_NUM, 42), format_error,
|
||||
"number is too big");
|
||||
if (sizeof(long long) != sizeof(int)) {
|
||||
|
||||
Reference in New Issue
Block a user