@@ -20,7 +20,7 @@ inline void PassFmt(util::ConstevalFormatString<NumArgs> fmt)
20
20
decltype (fmt)::Detail_CheckNumFormatSpecifiers (fmt.fmt );
21
21
}
22
22
template <unsigned WrongNumArgs>
23
- inline void FailFmtWithError (std::string_view wrong_fmt, std::string_view error)
23
+ inline void FailFmtWithError (const char * wrong_fmt, std::string_view error)
24
24
{
25
25
BOOST_CHECK_EXCEPTION (util::ConstevalFormatString<WrongNumArgs>::Detail_CheckNumFormatSpecifiers (wrong_fmt), const char *, HasReason (error));
26
26
}
@@ -44,6 +44,8 @@ BOOST_AUTO_TEST_CASE(ConstevalFormatString_NumSpec)
44
44
PassFmt<1 >(" %+2s" );
45
45
PassFmt<1 >(" %.6i" );
46
46
PassFmt<1 >(" %5.2f" );
47
+ PassFmt<1 >(" %5.f" );
48
+ PassFmt<1 >(" %.f" );
47
49
PassFmt<1 >(" %#x" );
48
50
PassFmt<1 >(" %1$5i" );
49
51
PassFmt<1 >(" %1$-5i" );
@@ -54,32 +56,60 @@ BOOST_AUTO_TEST_CASE(ConstevalFormatString_NumSpec)
54
56
PassFmt<1 >(" %_" );
55
57
PassFmt<1 >(" %\n " );
56
58
57
- // The `*` specifier behavior is unsupported and can lead to runtime
58
- // errors when used in a ConstevalFormatString. Please refer to the
59
- // note in the ConstevalFormatString docs.
60
- PassFmt<1 >(" %*c" );
61
- PassFmt<2 >(" %2$*3$d" );
62
- PassFmt<1 >(" %.*f" );
59
+ PassFmt<2 >(" %*c" );
60
+ PassFmt<2 >(" %+*c" );
61
+ PassFmt<2 >(" %.*f" );
62
+ PassFmt<3 >(" %*.*f" );
63
+ PassFmt<3 >(" %2$*3$d" );
64
+ PassFmt<3 >(" %2$*3$.9d" );
65
+ PassFmt<3 >(" %2$.*3$d" );
66
+ PassFmt<3 >(" %2$9.*3$d" );
67
+ PassFmt<3 >(" %2$+9.*3$d" );
68
+ PassFmt<4 >(" %3$*2$.*4$f" );
69
+
70
+ // Make sure multiple flag characters "- 0+" are accepted
71
+ PassFmt<3 >(" '%- 0+*.*f'" );
72
+ PassFmt<3 >(" '%1$- 0+*3$.*2$f'" );
63
73
64
74
auto err_mix{" Format specifiers must be all positional or all non-positional!" };
65
75
FailFmtWithError<1 >(" %s%1$s" , err_mix);
76
+ FailFmtWithError<2 >(" %2$*d" , err_mix);
77
+ FailFmtWithError<2 >(" %*2$d" , err_mix);
78
+ FailFmtWithError<2 >(" %.*3$d" , err_mix);
79
+ FailFmtWithError<2 >(" %2$.*d" , err_mix);
66
80
67
81
auto err_num{" Format specifier count must match the argument count!" };
68
82
FailFmtWithError<1 >(" " , err_num);
69
83
FailFmtWithError<0 >(" %s" , err_num);
70
84
FailFmtWithError<2 >(" %s" , err_num);
71
85
FailFmtWithError<0 >(" %1$s" , err_num);
72
86
FailFmtWithError<2 >(" %1$s" , err_num);
87
+ FailFmtWithError<1 >(" %*c" , err_num);
73
88
74
89
auto err_0_pos{" Positional format specifier must have position of at least 1" };
75
90
FailFmtWithError<1 >(" %$s" , err_0_pos);
76
91
FailFmtWithError<1 >(" %$" , err_0_pos);
77
92
FailFmtWithError<0 >(" %0$" , err_0_pos);
78
93
FailFmtWithError<0 >(" %0$s" , err_0_pos);
94
+ FailFmtWithError<2 >(" %2$*$d" , err_0_pos);
95
+ FailFmtWithError<2 >(" %2$*0$d" , err_0_pos);
96
+ FailFmtWithError<3 >(" %3$*2$.*$f" , err_0_pos);
97
+ FailFmtWithError<3 >(" %3$*2$.*0$f" , err_0_pos);
79
98
80
99
auto err_term{" Format specifier incorrectly terminated by end of string" };
81
100
FailFmtWithError<1 >(" %" , err_term);
101
+ FailFmtWithError<1 >(" %9" , err_term);
102
+ FailFmtWithError<1 >(" %9." , err_term);
103
+ FailFmtWithError<1 >(" %9.9" , err_term);
104
+ FailFmtWithError<1 >(" %*" , err_term);
105
+ FailFmtWithError<1 >(" %+*" , err_term);
106
+ FailFmtWithError<1 >(" %.*" , err_term);
107
+ FailFmtWithError<1 >(" %9.*" , err_term);
82
108
FailFmtWithError<1 >(" %1$" , err_term);
109
+ FailFmtWithError<1 >(" %1$9" , err_term);
110
+ FailFmtWithError<2 >(" %1$*2$" , err_term);
111
+ FailFmtWithError<2 >(" %1$.*2$" , err_term);
112
+ FailFmtWithError<2 >(" %1$9.*2$" , err_term);
83
113
}
84
114
85
115
BOOST_AUTO_TEST_SUITE_END ()
0 commit comments