forked from OSchip/llvm-project
[libc++] Reduces std::to_chars instantiations.
Instead of instantiating all functions called by std::to_chars for the integral types only instantiate them for 32 and 64 bit integral types. This results in a smaller binary when using different types. In an example using the types: signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, and unsigned long long this saved 2792 bytes of code size. For libc++.so.1 is saves 688 bytes of code size (64-bit Linux). This was discovered while investigating a solution for #52709. Reviewed By: #libc, ldionne Differential Revision: https://reviews.llvm.org/D128215
This commit is contained in:
parent
9e6261edc0
commit
cf927669eb
|
@ -26,6 +26,9 @@ template <class _If, class _Then>
|
|||
template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
|
||||
#endif
|
||||
|
||||
// Helper so we can use "conditional_t" in all language versions.
|
||||
template <bool _Bp, class _If, class _Then> using __conditional_t = typename conditional<_Bp, _If, _Then>::type;
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___TYPE_TRAITS_CONDITIONAL_H
|
||||
|
|
|
@ -487,16 +487,21 @@ template <typename _Tp, typename enable_if<is_integral<_Tp>::value, int>::type =
|
|||
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, "unsupported integral type used in to_chars");
|
||||
static_assert(sizeof(_Tp) <= sizeof(int64_t), "128-bit integral support isn't available yet in to_chars");
|
||||
return std::__to_chars_itoa(__first, __last, static_cast<_Type>(__value), is_signed<_Tp>());
|
||||
}
|
||||
|
||||
template <typename _Tp, typename enable_if<is_integral<_Tp>::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(sizeof(_Tp) <= sizeof(int64_t), "128-bit integral support isn't available yet in to_chars");
|
||||
return std::__to_chars_integral(__first, __last, static_cast<_Type>(__value), __base, is_signed<_Tp>());
|
||||
}
|
||||
|
||||
template <typename _It, typename _Tp, typename _Fn, typename... _Ts>
|
||||
|
|
|
@ -517,6 +517,7 @@ namespace std
|
|||
#include <__type_traits/void_t.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <version>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -1020,6 +1021,29 @@ typename make_unsigned<_Tp>::type __to_unsigned_like(_Tp __x) noexcept {
|
|||
}
|
||||
#endif
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, typename make_unsigned<_Up>::type, _Up>;
|
||||
|
||||
/// Helper to promote an integral to smallest 32, 64, or 128 bit representation.
|
||||
///
|
||||
/// The restriction is the same as the integral version of to_char.
|
||||
template <class _Tp>
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
requires (is_signed_v<_Tp> || is_unsigned_v<_Tp> || is_same_v<_Tp, char>)
|
||||
#endif
|
||||
using __make_32_64_or_128_bit_t =
|
||||
__copy_unsigned_t<_Tp,
|
||||
__conditional_t<sizeof(_Tp) <= sizeof(int32_t), int32_t,
|
||||
__conditional_t<sizeof(_Tp) <= sizeof(int64_t), int64_t,
|
||||
#ifndef _LIBCPP_HAS_NO_INT128
|
||||
__conditional_t<sizeof(_Tp) <= sizeof(__int128_t), __int128_t,
|
||||
/* else */ void>
|
||||
#else
|
||||
/* else */ void
|
||||
#endif
|
||||
> >
|
||||
>;
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
// Let COND_RES(X, Y) be:
|
||||
template <class _Tp, class _Up>
|
||||
|
|
Loading…
Reference in New Issue