1349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "charconv" 100b57cec5SDimitry Andric #include <string.h> 110b57cec5SDimitry Andric 12*0eae32dcSDimitry Andric #include "include/ryu/digit_table.h" 13*0eae32dcSDimitry Andric #include "include/to_chars_floating_point.h" 14*0eae32dcSDimitry Andric 150b57cec5SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric namespace __itoa 180b57cec5SDimitry Andric { 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric template <typename T> 210b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY char* 225ffd83dbSDimitry Andric append1(char* buffer, T i) noexcept 230b57cec5SDimitry Andric { 240b57cec5SDimitry Andric *buffer = '0' + static_cast<char>(i); 250b57cec5SDimitry Andric return buffer + 1; 260b57cec5SDimitry Andric } 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric template <typename T> 290b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY char* 305ffd83dbSDimitry Andric append2(char* buffer, T i) noexcept 310b57cec5SDimitry Andric { 32*0eae32dcSDimitry Andric memcpy(buffer, &__DIGIT_TABLE[(i)*2], 2); 330b57cec5SDimitry Andric return buffer + 2; 340b57cec5SDimitry Andric } 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric template <typename T> 370b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY char* 385ffd83dbSDimitry Andric append3(char* buffer, T i) noexcept 390b57cec5SDimitry Andric { 400b57cec5SDimitry Andric return append2(append1(buffer, (i) / 100), (i) % 100); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric template <typename T> 440b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY char* 455ffd83dbSDimitry Andric append4(char* buffer, T i) noexcept 460b57cec5SDimitry Andric { 470b57cec5SDimitry Andric return append2(append2(buffer, (i) / 100), (i) % 100); 480b57cec5SDimitry Andric } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric template <typename T> 510b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY char* 525ffd83dbSDimitry Andric append2_no_zeros(char* buffer, T v) noexcept 530b57cec5SDimitry Andric { 540b57cec5SDimitry Andric if (v < 10) 550b57cec5SDimitry Andric return append1(buffer, v); 560b57cec5SDimitry Andric else 570b57cec5SDimitry Andric return append2(buffer, v); 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric template <typename T> 610b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY char* 625ffd83dbSDimitry Andric append4_no_zeros(char* buffer, T v) noexcept 630b57cec5SDimitry Andric { 640b57cec5SDimitry Andric if (v < 100) 650b57cec5SDimitry Andric return append2_no_zeros(buffer, v); 660b57cec5SDimitry Andric else if (v < 1000) 670b57cec5SDimitry Andric return append3(buffer, v); 680b57cec5SDimitry Andric else 690b57cec5SDimitry Andric return append4(buffer, v); 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric template <typename T> 730b57cec5SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY char* 745ffd83dbSDimitry Andric append8_no_zeros(char* buffer, T v) noexcept 750b57cec5SDimitry Andric { 760b57cec5SDimitry Andric if (v < 10000) 770b57cec5SDimitry Andric { 780b57cec5SDimitry Andric buffer = append4_no_zeros(buffer, v); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric else 810b57cec5SDimitry Andric { 820b57cec5SDimitry Andric buffer = append4_no_zeros(buffer, v / 10000); 830b57cec5SDimitry Andric buffer = append4(buffer, v % 10000); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric return buffer; 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric char* 89fe6060f1SDimitry Andric __u32toa(uint32_t value, char* buffer) noexcept 900b57cec5SDimitry Andric { 910b57cec5SDimitry Andric if (value < 100000000) 920b57cec5SDimitry Andric { 930b57cec5SDimitry Andric buffer = append8_no_zeros(buffer, value); 940b57cec5SDimitry Andric } 950b57cec5SDimitry Andric else 960b57cec5SDimitry Andric { 970b57cec5SDimitry Andric // value = aabbbbcccc in decimal 980b57cec5SDimitry Andric const uint32_t a = value / 100000000; // 1 to 42 990b57cec5SDimitry Andric value %= 100000000; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric buffer = append2_no_zeros(buffer, a); 1020b57cec5SDimitry Andric buffer = append4(buffer, value / 10000); 1030b57cec5SDimitry Andric buffer = append4(buffer, value % 10000); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric return buffer; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric char* 110fe6060f1SDimitry Andric __u64toa(uint64_t value, char* buffer) noexcept 1110b57cec5SDimitry Andric { 1120b57cec5SDimitry Andric if (value < 100000000) 1130b57cec5SDimitry Andric { 1140b57cec5SDimitry Andric uint32_t v = static_cast<uint32_t>(value); 1150b57cec5SDimitry Andric buffer = append8_no_zeros(buffer, v); 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric else if (value < 10000000000000000) 1180b57cec5SDimitry Andric { 1190b57cec5SDimitry Andric const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 1200b57cec5SDimitry Andric const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric buffer = append8_no_zeros(buffer, v0); 1230b57cec5SDimitry Andric buffer = append4(buffer, v1 / 10000); 1240b57cec5SDimitry Andric buffer = append4(buffer, v1 % 10000); 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric else 1270b57cec5SDimitry Andric { 1280b57cec5SDimitry Andric const uint32_t a = 1290b57cec5SDimitry Andric static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844 1300b57cec5SDimitry Andric value %= 10000000000000000; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric buffer = append4_no_zeros(buffer, a); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 1350b57cec5SDimitry Andric const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 1360b57cec5SDimitry Andric buffer = append4(buffer, v0 / 10000); 1370b57cec5SDimitry Andric buffer = append4(buffer, v0 % 10000); 1380b57cec5SDimitry Andric buffer = append4(buffer, v1 / 10000); 1390b57cec5SDimitry Andric buffer = append4(buffer, v1 % 10000); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric return buffer; 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric } // namespace __itoa 1460b57cec5SDimitry Andric 147*0eae32dcSDimitry Andric // The original version of floating-point to_chars was written by Microsoft and 148*0eae32dcSDimitry Andric // contributed with the following license. 149*0eae32dcSDimitry Andric 150*0eae32dcSDimitry Andric // Copyright (c) Microsoft Corporation. 151*0eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 152*0eae32dcSDimitry Andric 153*0eae32dcSDimitry Andric // This implementation is dedicated to the memory of Mary and Thavatchai. 154*0eae32dcSDimitry Andric 155*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, float __value) { 156*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0); 157*0eae32dcSDimitry Andric } 158*0eae32dcSDimitry Andric 159*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, double __value) { 160*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0); 161*0eae32dcSDimitry Andric } 162*0eae32dcSDimitry Andric 163*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, long double __value) { 164*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, static_cast<double>(__value), 165*0eae32dcSDimitry Andric chars_format{}, 0); 166*0eae32dcSDimitry Andric } 167*0eae32dcSDimitry Andric 168*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt) { 169*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0); 170*0eae32dcSDimitry Andric } 171*0eae32dcSDimitry Andric 172*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt) { 173*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0); 174*0eae32dcSDimitry Andric } 175*0eae32dcSDimitry Andric 176*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt) { 177*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, static_cast<double>(__value), 178*0eae32dcSDimitry Andric __fmt, 0); 179*0eae32dcSDimitry Andric } 180*0eae32dcSDimitry Andric 181*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision) { 182*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt, 183*0eae32dcSDimitry Andric __precision); 184*0eae32dcSDimitry Andric } 185*0eae32dcSDimitry Andric 186*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision) { 187*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt, 188*0eae32dcSDimitry Andric __precision); 189*0eae32dcSDimitry Andric } 190*0eae32dcSDimitry Andric 191*0eae32dcSDimitry Andric to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision) { 192*0eae32dcSDimitry Andric return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>( 193*0eae32dcSDimitry Andric __first, __last, static_cast<double>(__value), __fmt, __precision); 194*0eae32dcSDimitry Andric } 195*0eae32dcSDimitry Andric 1960b57cec5SDimitry Andric _LIBCPP_END_NAMESPACE_STD 197