diff --git a/libcxx/include/charconv b/libcxx/include/charconv --- a/libcxx/include/charconv +++ b/libcxx/include/charconv @@ -487,16 +487,20 @@ inline _LIBCPP_HIDE_FROM_ABI to_chars_result to_chars(char* __first, char* __last, _Tp __value) { - return __to_chars_itoa(__first, __last, __value, is_signed<_Tp>()); + using __type = __make_32_64_or_128_bit_t<_Tp>; + static_assert(!is_same<__type, void>::value || sizeof(_Tp) > sizeof(int64_t), "unsupported integral type used in to_chars"); + return __to_chars_itoa(__first, __last, static_cast<__type>(__value), is_signed<_Tp>()); } template ::value, int>::type = 0> inline _LIBCPP_HIDE_FROM_ABI to_chars_result to_chars(char* __first, char* __last, _Tp __value, int __base) { - _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); - return __to_chars_integral(__first, __last, __value, __base, - is_signed<_Tp>()); + _LIBCPP_ASSERT(2 <= __base && __base <= 36, "base not in [2, 36]"); + + using __type = __make_32_64_or_128_bit_t<_Tp>; + static_assert(!is_same<__type, void>::value || sizeof(_Tp) > sizeof(int64_t), "unsupported integral type used in to_chars"); + return __to_chars_integral(__first, __last, static_cast<__type>(__value), __base, is_signed<_Tp>()); } template diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -517,6 +517,7 @@ #include <__type_traits/void_t.h> #include <__utility/declval.h> #include +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -1020,6 +1021,28 @@ } #endif +template +using __make_32_64_or_128_bit_t = typename conditional< + is_signed<_Tp>::value, + typename conditional< + sizeof(_Tp) <= sizeof(int32_t), int32_t, + typename conditional::type +#else + void +#endif + >::type>::type, + typename conditional< + sizeof(_Tp) <= sizeof(uint32_t), uint32_t, + typename conditional::type +#else + void +#endif + >::type>::type>::type; + #if _LIBCPP_STD_VER > 17 // Let COND_RES(X, Y) be: template