diff --git a/libcxx/include/__format/formatter_integer.h b/libcxx/include/__format/formatter_integer.h --- a/libcxx/include/__format/formatter_integer.h +++ b/libcxx/include/__format/formatter_integer.h @@ -13,23 +13,18 @@ #include <__availability> #include <__concepts/arithmetic.h> #include <__config> -#include <__format/format_error.h> // TODO FMT Remove after adding 128-bit support #include <__format/format_fwd.h> #include <__format/format_parse_context.h> #include <__format/formatter.h> #include <__format/formatter_integral.h> #include <__format/formatter_output.h> #include <__format/parser_std_format_spec.h> -#include // TODO FMT Remove after adding 128-bit support #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -_LIBCPP_PUSH_MACROS // TODO FMT Remove after adding 128-bit support -#include <__undef_macros> - _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER > 17 @@ -79,18 +74,7 @@ # ifndef _LIBCPP_HAS_NO_INT128 template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__int128_t, _CharT> - : public __formatter_integer<_CharT> { - using _Base = __formatter_integer<_CharT>; - - _LIBCPP_HIDE_FROM_ABI auto format(__int128_t __value, auto& __ctx) const -> decltype(__ctx.out()) { - // TODO FMT Implement full 128 bit support. - using _To = long long; - if (__value < numeric_limits<_To>::min() || __value > numeric_limits<_To>::max()) - std::__throw_format_error("128-bit value is outside of implemented range"); - - return _Base::format(static_cast<_To>(__value), __ctx); - } -}; + : public __formatter_integer<_CharT> {}; # endif // Unsigned integral types. @@ -112,24 +96,11 @@ # ifndef _LIBCPP_HAS_NO_INT128 template <__formatter::__char_type _CharT> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter<__uint128_t, _CharT> - : public __formatter_integer<_CharT> { - using _Base = __formatter_integer<_CharT>; - - _LIBCPP_HIDE_FROM_ABI auto format(__uint128_t __value, auto& __ctx) const -> decltype(__ctx.out()) { - // TODO FMT Implement full 128 bit support. - using _To = unsigned long long; - if (__value < numeric_limits<_To>::min() || __value > numeric_limits<_To>::max()) - std::__throw_format_error("128-bit value is outside of implemented range"); - - return _Base::format(static_cast<_To>(__value), __ctx); - } -}; + : public __formatter_integer<_CharT> {}; # endif #endif //_LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD -_LIBCPP_POP_MACROS - #endif // _LIBCPP___FORMAT_FORMATTER_INTEGER_H diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.signed_integral.pass.cpp @@ -86,18 +86,17 @@ test_termination_condition(STR("2147483647"), STR("}"), A(2147483647)); } if (sizeof(A) > 4) { - // -9223372036854775808 can't be used directly, it gives the following - // diagnostic: - // integer literal is too large to be represented in a signed integer type, - // interpreting as unsigned [-Werror,-Wimplicitly-unsigned-literal] - test_termination_condition(STR("-9223372036854775808"), STR("}"), - A(-9223372036854775807 - 1)); - test_termination_condition(STR("9223372036854775807"), STR("}"), - A(9223372036854775807)); + test_termination_condition(STR("-9223372036854775808"), STR("}"), A(std::numeric_limits::min())); + test_termination_condition(STR("9223372036854775807"), STR("}"), A(std::numeric_limits::max())); } - - // TODO FMT Implement the __int128_t minimum and maximum once the formatter - // can handle these values. +#ifndef TEST_HAS_NO_INT128 + if (sizeof(A) > 8) { + test_termination_condition( + STR("-170141183460469231731687303715884105728"), STR("}"), A(std::numeric_limits<__int128_t>::min())); + test_termination_condition( + STR("170141183460469231731687303715884105727"), STR("}"), A(std::numeric_limits<__int128_t>::max())); + } +#endif } template diff --git a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp --- a/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp +++ b/libcxx/test/std/utilities/format/format.formatter/format.formatter.spec/formatter.unsigned_integral.pass.cpp @@ -83,9 +83,11 @@ if (sizeof(A) > 4) test_termination_condition(STR("8446744073709551615"), STR("}"), A(8446744073709551615)); - - // TODO FMT Implement the __uint128_t maximum once the formatter can handle - // these values. +#ifndef TEST_HAS_NO_INT128 + if (sizeof(A) > 8) + test_termination_condition( + STR("340282366920938463463374607431768211455"), STR("}"), A(std::numeric_limits<__uint128_t>::max())); +#endif } template diff --git a/libcxx/test/std/utilities/format/format.functions/format_tests.h b/libcxx/test/std/utilities/format/format.functions/format_tests.h --- a/libcxx/test/std/utilities/format/format.functions/format_tests.h +++ b/libcxx/test/std/utilities/format/format.functions/format_tests.h @@ -702,19 +702,16 @@ check_exception("The format-spec type has a type not supported for an integer argument", fmt, I(42)); // *** Validate range *** - // TODO FMT Update test after adding 128-bit support. - if constexpr (sizeof(I) <= sizeof(long long)) { - // The code has some duplications to keep the if statement readable. - if constexpr (std::signed_integral) { - if constexpr (std::signed_integral && sizeof(I) > sizeof(CharT)) { - check_exception("Integral value outside the range of the char type", SV("{:c}"), std::numeric_limits::min()); - check_exception("Integral value outside the range of the char type", SV("{:c}"), std::numeric_limits::max()); - } else if constexpr (std::unsigned_integral && sizeof(I) >= sizeof(CharT)) { - check_exception("Integral value outside the range of the char type", SV("{:c}"), std::numeric_limits::max()); - } - } else if constexpr (sizeof(I) > sizeof(CharT)) { + // The code has some duplications to keep the if statement readable. + if constexpr (std::signed_integral) { + if constexpr (std::signed_integral && sizeof(I) > sizeof(CharT)) { + check_exception("Integral value outside the range of the char type", SV("{:c}"), std::numeric_limits::min()); + check_exception("Integral value outside the range of the char type", SV("{:c}"), std::numeric_limits::max()); + } else if constexpr (std::unsigned_integral && sizeof(I) >= sizeof(CharT)) { check_exception("Integral value outside the range of the char type", SV("{:c}"), std::numeric_limits::max()); } + } else if constexpr (sizeof(I) > sizeof(CharT)) { + check_exception("Integral value outside the range of the char type", SV("{:c}"), std::numeric_limits::max()); } } @@ -756,6 +753,18 @@ check.template operator()<"{:#}">(SV("-9223372036854775808"), std::numeric_limits::min()); check.template operator()<"{:#x}">(SV("-0x8000000000000000"), std::numeric_limits::min()); +#ifndef TEST_HAS_NO_INT128 + check.template operator()<"{:#b}">( + SV("-0b1000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000"), + std::numeric_limits<__int128_t>::min()); + check.template + operator()<"{:#o}">(SV("-02000000000000000000000000000000000000000000"), std::numeric_limits<__int128_t>::min()); + check.template + operator()<"{:#}">(SV("-170141183460469231731687303715884105728"), std::numeric_limits<__int128_t>::min()); + check.template operator()<"{:#x}">(SV("-0x80000000000000000000000000000000"), std::numeric_limits<__int128_t>::min()); +#endif + check.template operator()<"{:#b}">(SV("0b1111111"), std::numeric_limits::max()); check.template operator()<"{:#o}">(SV("0177"), std::numeric_limits::max()); check.template operator()<"{:#}">(SV("127"), std::numeric_limits::max()); @@ -777,7 +786,17 @@ check.template operator()<"{:#}">(SV("9223372036854775807"), std::numeric_limits::max()); check.template operator()<"{:#x}">(SV("0x7fffffffffffffff"), std::numeric_limits::max()); - // TODO FMT Add __int128_t test after implementing full range. +#ifndef TEST_HAS_NO_INT128 + check.template operator()<"{:#b}">( + SV("0b111111111111111111111111111111111111111111111111111111111111111" + "1111111111111111111111111111111111111111111111111111111111111111"), + std::numeric_limits<__int128_t>::max()); + check.template + operator()<"{:#o}">(SV("01777777777777777777777777777777777777777777"), std::numeric_limits<__int128_t>::max()); + check.template + operator()<"{:#}">(SV("170141183460469231731687303715884105727"), std::numeric_limits<__int128_t>::max()); + check.template operator()<"{:#x}">(SV("0x7fffffffffffffffffffffffffffffff"), std::numeric_limits<__int128_t>::max()); +#endif } template @@ -812,7 +831,17 @@ check.template operator()<"{:#}">(SV("18446744073709551615"), std::numeric_limits::max()); check.template operator()<"{:#x}">(SV("0xffffffffffffffff"), std::numeric_limits::max()); - // TODO FMT Add __uint128_t test after implementing full range. +#ifndef TEST_HAS_NO_INT128 + check.template operator()<"{:#b}">( + SV("0b1111111111111111111111111111111111111111111111111111111111111111" + "1111111111111111111111111111111111111111111111111111111111111111"), + std::numeric_limits<__uint128_t>::max()); + check.template + operator()<"{:#o}">(SV("03777777777777777777777777777777777777777777"), std::numeric_limits<__uint128_t>::max()); + check.template + operator()<"{:#}">(SV("340282366920938463463374607431768211455"), std::numeric_limits<__uint128_t>::max()); + check.template operator()<"{:#x}">(SV("0xffffffffffffffffffffffffffffffff"), std::numeric_limits<__uint128_t>::max()); +#endif } template @@ -2588,21 +2617,6 @@ check.template operator()<"hello {}">(SV("hello 42"), static_cast(42)); #ifndef TEST_HAS_NO_INT128 check.template operator()<"hello {}">(SV("hello 42"), static_cast<__int128_t>(42)); - { - // Note 128-bit support is only partly implemented test the range - // conditions here. - static constexpr auto fmt = string_literal("{}"); - std::basic_string min = std::format(fmt.template sv(), std::numeric_limits::min()); - check.template operator()<"{}">(std::basic_string_view(min), - static_cast<__int128_t>(std::numeric_limits::min())); - std::basic_string max = std::format(fmt.template sv(), std::numeric_limits::max()); - check.template operator()<"{}">(std::basic_string_view(max), - static_cast<__int128_t>(std::numeric_limits::max())); - check_exception("128-bit value is outside of implemented range", SV("{}"), - static_cast<__int128_t>(std::numeric_limits::min()) - 1); - check_exception("128-bit value is outside of implemented range", SV("{}"), - static_cast<__int128_t>(std::numeric_limits::max()) + 1); - } #endif format_test_signed_integer(check, check_exception); @@ -2614,16 +2628,6 @@ check.template operator()<"hello {}">(SV("hello 42"), static_cast(42)); #ifndef TEST_HAS_NO_INT128 check.template operator()<"hello {}">(SV("hello 42"), static_cast<__uint128_t>(42)); - { - // Note 128-bit support is only partly implemented test the range - // conditions here. - static constexpr auto fmt = string_literal("{}"); - std::basic_string max = std::format(fmt.template sv(), std::numeric_limits::max()); - check.template operator()<"{}">(std::basic_string_view(max), - static_cast<__uint128_t>(std::numeric_limits::max())); - check_exception("128-bit value is outside of implemented range", SV("{}"), - static_cast<__uint128_t>(std::numeric_limits::max()) + 1); - } #endif format_test_unsigned_integer(check, check_exception);