зеркало из https://github.com/microsoft/STL.git
Implement LWG-3720 Restrict the valid types of arg-id for width and precision in std-format-spec (#3511)
Co-authored-by: A. Jiang <de34@live.cn>
This commit is contained in:
Родитель
4e5425cee4
Коммит
efd50e8961
|
@ -1410,13 +1410,17 @@ _NODISCARD constexpr basic_format_arg<_Context> _Get_arg(const _Context& _Ctx, c
|
||||||
return _Arg;
|
return _Arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class _Ty>
|
||||||
|
inline constexpr bool _Is_signed_or_unsigned_large_integer_t =
|
||||||
|
_Is_any_of_v<remove_cv_t<_Ty>, int, unsigned int, long, unsigned long, long long, unsigned long long>;
|
||||||
|
|
||||||
// Checks that the type and value of an argument associated with a dynamic
|
// Checks that the type and value of an argument associated with a dynamic
|
||||||
// width specifier are valid.
|
// width specifier are valid.
|
||||||
class _Width_checker {
|
class _Width_checker {
|
||||||
public:
|
public:
|
||||||
template <class _Ty>
|
template <class _Ty>
|
||||||
_NODISCARD constexpr unsigned long long operator()(const _Ty _Value) const {
|
_NODISCARD constexpr unsigned long long operator()(const _Ty _Value) const {
|
||||||
if constexpr (is_integral_v<_Ty>) {
|
if constexpr (_Is_signed_or_unsigned_large_integer_t<_Ty>) {
|
||||||
if constexpr (is_signed_v<_Ty>) {
|
if constexpr (is_signed_v<_Ty>) {
|
||||||
if (_Value < 0) {
|
if (_Value < 0) {
|
||||||
_Throw_format_error("Negative width.");
|
_Throw_format_error("Negative width.");
|
||||||
|
@ -1435,7 +1439,7 @@ class _Precision_checker {
|
||||||
public:
|
public:
|
||||||
template <class _Ty>
|
template <class _Ty>
|
||||||
_NODISCARD constexpr unsigned long long operator()(const _Ty _Value) const {
|
_NODISCARD constexpr unsigned long long operator()(const _Ty _Value) const {
|
||||||
if constexpr (is_integral_v<_Ty>) {
|
if constexpr (_Is_signed_or_unsigned_large_integer_t<_Ty>) {
|
||||||
if constexpr (is_signed_v<_Ty>) {
|
if constexpr (is_signed_v<_Ty>) {
|
||||||
if (_Value < 0) {
|
if (_Value < 0) {
|
||||||
_Throw_format_error("Negative precision.");
|
_Throw_format_error("Negative precision.");
|
||||||
|
|
|
@ -1356,10 +1356,13 @@ void libfmt_formatter_test_runtime_width() {
|
||||||
throw_helper(STR("{0:{1}}"), 0, (int_max + 1u));
|
throw_helper(STR("{0:{1}}"), 0, (int_max + 1u));
|
||||||
throw_helper(STR("{0:{1}}"), 0, -1l);
|
throw_helper(STR("{0:{1}}"), 0, -1l);
|
||||||
throw_helper(STR("{0:{1}}"), 0, (int_max + 1ul));
|
throw_helper(STR("{0:{1}}"), 0, (int_max + 1ul));
|
||||||
assert(format(STR("{0:{1}}"), 0, '0')
|
|
||||||
== STR(" 0")); // behavior differs from libfmt, but conforms
|
|
||||||
throw_helper(STR("{0:{1}}"), 0, 0.0);
|
throw_helper(STR("{0:{1}}"), 0, 0.0);
|
||||||
|
|
||||||
|
// LWG-3720: Restrict the valid types of arg-id for width and precision in std-format-spec
|
||||||
|
throw_helper(STR("{:*^{}}"), 'a', true);
|
||||||
|
throw_helper(STR("{:*^{}}"), 'a', '0');
|
||||||
|
assert(format(STR("{:*^{}}"), 'a', static_cast<signed char>(2)) == STR("a*"));
|
||||||
|
|
||||||
assert(format(STR("{0:{1}}"), 42, 0) == STR("42")); // LWG-3721: zero dynamic width is OK
|
assert(format(STR("{0:{1}}"), 42, 0) == STR("42")); // LWG-3721: zero dynamic width is OK
|
||||||
|
|
||||||
assert(format(STR("{0:{1}}"), -42, 4) == STR(" -42"));
|
assert(format(STR("{0:{1}}"), -42, 4) == STR(" -42"));
|
||||||
|
@ -1407,6 +1410,11 @@ void libfmt_formatter_test_runtime_precision() {
|
||||||
throw_helper(STR("{0:.{1}}"), reinterpret_cast<void*>(0xcafe), 2);
|
throw_helper(STR("{0:.{1}}"), reinterpret_cast<void*>(0xcafe), 2);
|
||||||
throw_helper(STR("{0:.{1}f}"), reinterpret_cast<void*>(0xcafe), 2);
|
throw_helper(STR("{0:.{1}f}"), reinterpret_cast<void*>(0xcafe), 2);
|
||||||
assert(format(STR("{0:.{1}}"), STR("str"), 2) == STR("st"));
|
assert(format(STR("{0:.{1}}"), STR("str"), 2) == STR("st"));
|
||||||
|
|
||||||
|
// LWG-3720: Restrict the valid types of arg-id for width and precision in std-format-spec
|
||||||
|
throw_helper(STR("{:.{}f}"), 3.14f, true);
|
||||||
|
throw_helper(STR("{:.{}f}"), 3.14f, '0');
|
||||||
|
assert(format(STR("{:.{}f}"), 3.14f, static_cast<signed char>(2)) == STR("3.14"));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class charT>
|
template <class charT>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче