diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -116,6 +116,9 @@ # 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 std::to_chars base 10 implementation from the dylib. +// The implementation moved the header. +# 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 diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -26,7 +26,6 @@ include/ryu/d2s.h include/ryu/d2s_full_table.h include/ryu/d2s_intrinsics.h - include/ryu/digit_table.h include/ryu/f2s.h include/ryu/ryu.h include/to_chars_floating_point.h diff --git a/libcxx/src/charconv.cpp b/libcxx/src/charconv.cpp --- a/libcxx/src/charconv.cpp +++ b/libcxx/src/charconv.cpp @@ -9,141 +9,31 @@ #include #include -#include "include/ryu/digit_table.h" #include "include/to_chars_floating_point.h" _LIBCPP_BEGIN_NAMESPACE_STD -namespace __itoa -{ - -template -inline _LIBCPP_INLINE_VISIBILITY char* -append1(char* buffer, T i) noexcept -{ - *buffer = '0' + static_cast(i); - return buffer + 1; -} - -template -inline _LIBCPP_INLINE_VISIBILITY char* -append2(char* buffer, T i) noexcept -{ - memcpy(buffer, &__DIGIT_TABLE[(i)*2], 2); - return buffer + 2; -} - -template -inline _LIBCPP_INLINE_VISIBILITY char* -append3(char* buffer, T i) noexcept -{ - return append2(append1(buffer, (i) / 100), (i) % 100); -} +#ifndef _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10 -template -inline _LIBCPP_INLINE_VISIBILITY char* -append4(char* buffer, T i) noexcept -{ - return append2(append2(buffer, (i) / 100), (i) % 100); -} - -template -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 -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 -inline _LIBCPP_INLINE_VISIBILITY char* -append8_no_zeros(char* buffer, T v) noexcept +namespace __itoa { - 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(value); - buffer = append8_no_zeros(buffer, v); - } - else if (value < 10000000000000000) - { - const uint32_t v0 = static_cast(value / 100000000); - const uint32_t v1 = static_cast(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(value / 10000000000000000); // 1 to 1844 - value %= 10000000000000000; - - buffer = append4_no_zeros(buffer, a); - - const uint32_t v0 = static_cast(value / 100000000); - const uint32_t v1 = static_cast(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. diff --git a/libcxx/src/include/ryu/digit_table.h b/libcxx/src/include/ryu/digit_table.h deleted file mode 100644 --- a/libcxx/src/include/ryu/digit_table.h +++ /dev/null @@ -1,68 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -// Copyright (c) Microsoft Corporation. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -// Copyright 2018 Ulf Adams -// Copyright (c) Microsoft Corporation. All rights reserved. - -// Boost Software License - Version 1.0 - August 17th, 2003 - -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: - -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#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 <__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' -}; - -_LIBCPP_END_NAMESPACE_STD - -// clang-format on - -#endif // _LIBCPP_SRC_INCLUDE_RYU_DIGIT_TABLE_H diff --git a/libcxx/src/ryu/d2fixed.cpp b/libcxx/src/ryu/d2fixed.cpp --- a/libcxx/src/ryu/d2fixed.cpp +++ b/libcxx/src/ryu/d2fixed.cpp @@ -50,7 +50,6 @@ #include "include/ryu/d2fixed_full_table.h" #include "include/ryu/d2s.h" #include "include/ryu/d2s_intrinsics.h" -#include "include/ryu/digit_table.h" _LIBCPP_BEGIN_NAMESPACE_STD @@ -135,19 +134,19 @@ __digits /= 10000; const uint32_t __c0 = (__c % 100) << 1; const uint32_t __c1 = (__c / 100) << 1; - _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(__result + __olength - __i - 4, __DIGIT_TABLE + __c1, 2); + _VSTD::memcpy(__result + __olength - __i - 2, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(__result + __olength - __i - 4, __itoa::__digits_base_10 + __c1, 2); __i += 4; } if (__digits >= 100) { const uint32_t __c = (__digits % 100) << 1; __digits /= 100; - _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(__result + __olength - __i - 2, __itoa::__digits_base_10 + __c, 2); __i += 2; } if (__digits >= 10) { const uint32_t __c = __digits << 1; - _VSTD::memcpy(__result + __olength - __i - 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(__result + __olength - __i - 2, __itoa::__digits_base_10 + __c, 2); } else { __result[0] = static_cast('0' + __digits); } @@ -164,21 +163,21 @@ __digits /= 10000; const uint32_t __c0 = (__c % 100) << 1; const uint32_t __c1 = (__c / 100) << 1; - _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(__result + __olength + 1 - __i - 4, __DIGIT_TABLE + __c1, 2); + _VSTD::memcpy(__result + __olength + 1 - __i - 2, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(__result + __olength + 1 - __i - 4, __itoa::__digits_base_10 + __c1, 2); __i += 4; } if (__digits >= 100) { const uint32_t __c = (__digits % 100) << 1; __digits /= 100; - _VSTD::memcpy(__result + __olength + 1 - __i - 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(__result + __olength + 1 - __i - 2, __itoa::__digits_base_10 + __c, 2); __i += 2; } if (__digits >= 10) { const uint32_t __c = __digits << 1; - __result[2] = __DIGIT_TABLE[__c + 1]; + __result[2] = __itoa::__digits_base_10[__c + 1]; __result[1] = '.'; - __result[0] = __DIGIT_TABLE[__c]; + __result[0] = __itoa::__digits_base_10[__c]; } else { __result[1] = '.'; __result[0] = static_cast('0' + __digits); @@ -190,7 +189,7 @@ for (; __i < __count - 1; __i += 2) { const uint32_t __c = (__digits % 100) << 1; __digits /= 100; - _VSTD::memcpy(__result + __count - __i - 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(__result + __count - __i - 2, __itoa::__digits_base_10 + __c, 2); } if (__i < __count) { const char __c = static_cast('0' + (__digits % 10)); @@ -213,8 +212,8 @@ __digits /= 10000; const uint32_t __c0 = (__c % 100) << 1; const uint32_t __c1 = (__c / 100) << 1; - _VSTD::memcpy(__result + 7 - __i, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(__result + 5 - __i, __DIGIT_TABLE + __c1, 2); + _VSTD::memcpy(__result + 7 - __i, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(__result + 5 - __i, __itoa::__digits_base_10 + __c1, 2); } __result[0] = static_cast('0' + __digits); } @@ -654,11 +653,11 @@ if (__exp >= 100) { const int32_t __c = __exp % 10; - _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * (__exp / 10), 2); + _VSTD::memcpy(_First, __itoa::__digits_base_10 + 2 * (__exp / 10), 2); _First[2] = static_cast('0' + __c); _First += 3; } else { - _VSTD::memcpy(_First, __DIGIT_TABLE + 2 * __exp, 2); + _VSTD::memcpy(_First, __itoa::__digits_base_10 + 2 * __exp, 2); _First += 2; } diff --git a/libcxx/src/ryu/d2s.cpp b/libcxx/src/ryu/d2s.cpp --- a/libcxx/src/ryu/d2s.cpp +++ b/libcxx/src/ryu/d2s.cpp @@ -48,7 +48,6 @@ #include "include/ryu/d2s.h" #include "include/ryu/d2s_full_table.h" #include "include/ryu/d2s_intrinsics.h" -#include "include/ryu/digit_table.h" #include "include/ryu/ryu.h" _LIBCPP_BEGIN_NAMESPACE_STD @@ -527,10 +526,10 @@ const uint32_t __d0 = (__d % 100) << 1; const uint32_t __d1 = (__d / 100) << 1; - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d0, 2); - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __d1, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c1, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __d0, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __d1, 2); } uint32_t __output2 = static_cast(_Output); while (__output2 >= 10000) { @@ -542,17 +541,17 @@ __output2 /= 10000; const uint32_t __c0 = (__c % 100) << 1; const uint32_t __c1 = (__c / 100) << 1; - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c1, 2); } if (__output2 >= 100) { const uint32_t __c = (__output2 % 100) << 1; __output2 /= 100; - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c, 2); } if (__output2 >= 10) { const uint32_t __c = __output2 << 1; - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c, 2); } else { *--_Mid = static_cast('0' + __output2); } @@ -602,10 +601,10 @@ const uint32_t __c1 = (__c / 100) << 1; const uint32_t __d0 = (__d % 100) << 1; const uint32_t __d1 = (__d / 100) << 1; - _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); - _VSTD::memcpy(__result + __olength - __i - 5, __DIGIT_TABLE + __d0, 2); - _VSTD::memcpy(__result + __olength - __i - 7, __DIGIT_TABLE + __d1, 2); + _VSTD::memcpy(__result + __olength - __i - 1, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(__result + __olength - __i - 3, __itoa::__digits_base_10 + __c1, 2); + _VSTD::memcpy(__result + __olength - __i - 5, __itoa::__digits_base_10 + __d0, 2); + _VSTD::memcpy(__result + __olength - __i - 7, __itoa::__digits_base_10 + __d1, 2); __i += 8; } uint32_t __output2 = static_cast(_Output); @@ -618,21 +617,21 @@ __output2 /= 10000; const uint32_t __c0 = (__c % 100) << 1; const uint32_t __c1 = (__c / 100) << 1; - _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); + _VSTD::memcpy(__result + __olength - __i - 1, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(__result + __olength - __i - 3, __itoa::__digits_base_10 + __c1, 2); __i += 4; } if (__output2 >= 100) { const uint32_t __c = (__output2 % 100) << 1; __output2 /= 100; - _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(__result + __olength - __i - 1, __itoa::__digits_base_10 + __c, 2); __i += 2; } if (__output2 >= 10) { const uint32_t __c = __output2 << 1; // We can't use memcpy here: the decimal dot goes between these two digits. - __result[2] = __DIGIT_TABLE[__c + 1]; - __result[0] = __DIGIT_TABLE[__c]; + __result[2] = __itoa::__digits_base_10[__c + 1]; + __result[0] = __itoa::__digits_base_10[__c]; } else { __result[0] = static_cast('0' + __output2); } @@ -657,11 +656,11 @@ if (_Scientific_exponent >= 100) { const int32_t __c = _Scientific_exponent % 10; - _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * (_Scientific_exponent / 10), 2); + _VSTD::memcpy(__result + __index, __itoa::__digits_base_10 + 2 * (_Scientific_exponent / 10), 2); __result[__index + 2] = static_cast('0' + __c); __index += 3; } else { - _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2); + _VSTD::memcpy(__result + __index, __itoa::__digits_base_10 + 2 * _Scientific_exponent, 2); __index += 2; } diff --git a/libcxx/src/ryu/f2s.cpp b/libcxx/src/ryu/f2s.cpp --- a/libcxx/src/ryu/f2s.cpp +++ b/libcxx/src/ryu/f2s.cpp @@ -46,7 +46,6 @@ #include "include/ryu/common.h" #include "include/ryu/d2fixed.h" #include "include/ryu/d2s_intrinsics.h" -#include "include/ryu/digit_table.h" #include "include/ryu/f2s.h" #include "include/ryu/ryu.h" @@ -565,17 +564,17 @@ _Output /= 10000; const uint32_t __c0 = (__c % 100) << 1; const uint32_t __c1 = (__c / 100) << 1; - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c1, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c1, 2); } if (_Output >= 100) { const uint32_t __c = (_Output % 100) << 1; _Output /= 100; - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c, 2); } if (_Output >= 10) { const uint32_t __c = _Output << 1; - _VSTD::memcpy(_Mid -= 2, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(_Mid -= 2, __itoa::__digits_base_10 + __c, 2); } else { *--_Mid = static_cast('0' + _Output); } @@ -617,21 +616,21 @@ _Output /= 10000; const uint32_t __c0 = (__c % 100) << 1; const uint32_t __c1 = (__c / 100) << 1; - _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c0, 2); - _VSTD::memcpy(__result + __olength - __i - 3, __DIGIT_TABLE + __c1, 2); + _VSTD::memcpy(__result + __olength - __i - 1, __itoa::__digits_base_10 + __c0, 2); + _VSTD::memcpy(__result + __olength - __i - 3, __itoa::__digits_base_10 + __c1, 2); __i += 4; } if (_Output >= 100) { const uint32_t __c = (_Output % 100) << 1; _Output /= 100; - _VSTD::memcpy(__result + __olength - __i - 1, __DIGIT_TABLE + __c, 2); + _VSTD::memcpy(__result + __olength - __i - 1, __itoa::__digits_base_10 + __c, 2); __i += 2; } if (_Output >= 10) { const uint32_t __c = _Output << 1; // We can't use memcpy here: the decimal dot goes between these two digits. - __result[2] = __DIGIT_TABLE[__c + 1]; - __result[0] = __DIGIT_TABLE[__c]; + __result[2] = __itoa::__digits_base_10[__c + 1]; + __result[0] = __itoa::__digits_base_10[__c]; } else { __result[0] = static_cast('0' + _Output); } @@ -654,7 +653,7 @@ __result[__index++] = '+'; } - _VSTD::memcpy(__result + __index, __DIGIT_TABLE + 2 * _Scientific_exponent, 2); + _VSTD::memcpy(__result + __index, __itoa::__digits_base_10 + 2 * _Scientific_exponent, 2); __index += 2; return { _First + _Total_scientific_length, errc{} };