[libc++] Lets to_chars use header implementation.

This removes the duplicated code from the dylib. Instead the dylib will
call the new functions in the header. Since this code is unneeded it's
removed from the unstable ABI.

Depends on D125704

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D125761
This commit is contained in:
Mark de Wever 2022-05-16 18:48:04 +02:00
parent dcdb0bf25b
commit 89818f2dc0
3 changed files with 16 additions and 133 deletions

View File

@ -116,6 +116,10 @@
# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
// According to the Standard, `bitset::operator[] const` returns bool
# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
// Remove the base 10 implementation of std::to_chars from the dylib.
// The implementation moved to the header, but we still export the symbols from
// the dylib for backwards compatibility.
# define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
#elif _LIBCPP_ABI_VERSION == 1
# if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
// Enable compiling copies of now inline methods into the dylib to support

View File

@ -9,141 +9,31 @@
#include <charconv>
#include <string.h>
#include "include/ryu/digit_table.h"
#include "include/to_chars_floating_point.h"
_LIBCPP_BEGIN_NAMESPACE_STD
#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
namespace __itoa
{
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append1(char* buffer, T i) noexcept
{
*buffer = '0' + static_cast<char>(i);
return buffer + 1;
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append2(char* buffer, T i) noexcept
{
memcpy(buffer, &__DIGIT_TABLE[(i)*2], 2);
return buffer + 2;
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append3(char* buffer, T i) noexcept
{
return append2(append1(buffer, (i) / 100), (i) % 100);
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append4(char* buffer, T i) noexcept
{
return append2(append2(buffer, (i) / 100), (i) % 100);
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append2_no_zeros(char* buffer, T v) noexcept
{
if (v < 10)
return append1(buffer, v);
else
return append2(buffer, v);
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append4_no_zeros(char* buffer, T v) noexcept
{
if (v < 100)
return append2_no_zeros(buffer, v);
else if (v < 1000)
return append3(buffer, v);
else
return append4(buffer, v);
}
template <typename T>
inline _LIBCPP_INLINE_VISIBILITY char*
append8_no_zeros(char* buffer, T v) noexcept
{
if (v < 10000)
{
buffer = append4_no_zeros(buffer, v);
}
else
{
buffer = append4_no_zeros(buffer, v / 10000);
buffer = append4(buffer, v % 10000);
}
return buffer;
}
_LIBCPP_FUNC_VIS char*
__u32toa(uint32_t value, char* buffer) noexcept
{
if (value < 100000000)
{
buffer = append8_no_zeros(buffer, value);
}
else
{
// value = aabbbbcccc in decimal
const uint32_t a = value / 100000000; // 1 to 42
value %= 100000000;
buffer = append2_no_zeros(buffer, a);
buffer = append4(buffer, value / 10000);
buffer = append4(buffer, value % 10000);
}
return buffer;
return __base_10_u32(value, buffer);
}
_LIBCPP_FUNC_VIS char*
__u64toa(uint64_t value, char* buffer) noexcept
{
if (value < 100000000)
{
uint32_t v = static_cast<uint32_t>(value);
buffer = append8_no_zeros(buffer, v);
}
else if (value < 10000000000000000)
{
const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
buffer = append8_no_zeros(buffer, v0);
buffer = append4(buffer, v1 / 10000);
buffer = append4(buffer, v1 % 10000);
}
else
{
const uint32_t a =
static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844
value %= 10000000000000000;
buffer = append4_no_zeros(buffer, a);
const uint32_t v0 = static_cast<uint32_t>(value / 100000000);
const uint32_t v1 = static_cast<uint32_t>(value % 100000000);
buffer = append4(buffer, v0 / 10000);
buffer = append4(buffer, v0 % 10000);
buffer = append4(buffer, v1 / 10000);
buffer = append4(buffer, v1 % 10000);
}
return buffer;
return __base_10_u64(value, buffer);
}
} // namespace __itoa
#endif // _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10
// The original version of floating-point to_chars was written by Microsoft and
// contributed with the following license.

View File

@ -39,30 +39,19 @@
#ifndef _LIBCPP_SRC_INCLUDE_RYU_DIGIT_TABLE_H
#define _LIBCPP_SRC_INCLUDE_RYU_DIGIT_TABLE_H
// Avoid formatting to keep the changes with the original code minimal.
// clang-format off
#include <__charconv/tables.h>
#include <__config>
_LIBCPP_BEGIN_NAMESPACE_STD
// A table of all two-digit numbers. This is used to speed up decimal digit
// generation by copying pairs of digits into the final output.
inline constexpr char __DIGIT_TABLE[200] = {
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
'3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
'4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
'5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
'6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
'7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
'8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
};
//
// In order to minimize the diff in the Ryu code between MSVC STL and libc++
// the code uses the name __DIGIT_TABLE. In order to avoid code duplication it
// reuses the table already available in libc++.
inline constexpr auto& __DIGIT_TABLE = __itoa::__digits_base_10<>::__value;
_LIBCPP_END_NAMESPACE_STD
// clang-format on
#endif // _LIBCPP_SRC_INCLUDE_RYU_DIGIT_TABLE_H