1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "charconv" 10 #include <string.h> 11 12 #include "include/ryu/digit_table.h" 13 #include "include/to_chars_floating_point.h" 14 15 _LIBCPP_BEGIN_NAMESPACE_STD 16 17 namespace __itoa 18 { 19 20 template <typename T> 21 inline _LIBCPP_INLINE_VISIBILITY char* 22 append1(char* buffer, T i) noexcept 23 { 24 *buffer = '0' + static_cast<char>(i); 25 return buffer + 1; 26 } 27 28 template <typename T> 29 inline _LIBCPP_INLINE_VISIBILITY char* 30 append2(char* buffer, T i) noexcept 31 { 32 memcpy(buffer, &__DIGIT_TABLE[(i)*2], 2); 33 return buffer + 2; 34 } 35 36 template <typename T> 37 inline _LIBCPP_INLINE_VISIBILITY char* 38 append3(char* buffer, T i) noexcept 39 { 40 return append2(append1(buffer, (i) / 100), (i) % 100); 41 } 42 43 template <typename T> 44 inline _LIBCPP_INLINE_VISIBILITY char* 45 append4(char* buffer, T i) noexcept 46 { 47 return append2(append2(buffer, (i) / 100), (i) % 100); 48 } 49 50 template <typename T> 51 inline _LIBCPP_INLINE_VISIBILITY char* 52 append2_no_zeros(char* buffer, T v) noexcept 53 { 54 if (v < 10) 55 return append1(buffer, v); 56 else 57 return append2(buffer, v); 58 } 59 60 template <typename T> 61 inline _LIBCPP_INLINE_VISIBILITY char* 62 append4_no_zeros(char* buffer, T v) noexcept 63 { 64 if (v < 100) 65 return append2_no_zeros(buffer, v); 66 else if (v < 1000) 67 return append3(buffer, v); 68 else 69 return append4(buffer, v); 70 } 71 72 template <typename T> 73 inline _LIBCPP_INLINE_VISIBILITY char* 74 append8_no_zeros(char* buffer, T v) noexcept 75 { 76 if (v < 10000) 77 { 78 buffer = append4_no_zeros(buffer, v); 79 } 80 else 81 { 82 buffer = append4_no_zeros(buffer, v / 10000); 83 buffer = append4(buffer, v % 10000); 84 } 85 return buffer; 86 } 87 88 char* 89 __u32toa(uint32_t value, char* buffer) noexcept 90 { 91 if (value < 100000000) 92 { 93 buffer = append8_no_zeros(buffer, value); 94 } 95 else 96 { 97 // value = aabbbbcccc in decimal 98 const uint32_t a = value / 100000000; // 1 to 42 99 value %= 100000000; 100 101 buffer = append2_no_zeros(buffer, a); 102 buffer = append4(buffer, value / 10000); 103 buffer = append4(buffer, value % 10000); 104 } 105 106 return buffer; 107 } 108 109 char* 110 __u64toa(uint64_t value, char* buffer) noexcept 111 { 112 if (value < 100000000) 113 { 114 uint32_t v = static_cast<uint32_t>(value); 115 buffer = append8_no_zeros(buffer, v); 116 } 117 else if (value < 10000000000000000) 118 { 119 const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 120 const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 121 122 buffer = append8_no_zeros(buffer, v0); 123 buffer = append4(buffer, v1 / 10000); 124 buffer = append4(buffer, v1 % 10000); 125 } 126 else 127 { 128 const uint32_t a = 129 static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844 130 value %= 10000000000000000; 131 132 buffer = append4_no_zeros(buffer, a); 133 134 const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 135 const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 136 buffer = append4(buffer, v0 / 10000); 137 buffer = append4(buffer, v0 % 10000); 138 buffer = append4(buffer, v1 / 10000); 139 buffer = append4(buffer, v1 % 10000); 140 } 141 142 return buffer; 143 } 144 145 } // namespace __itoa 146 147 // The original version of floating-point to_chars was written by Microsoft and 148 // contributed with the following license. 149 150 // Copyright (c) Microsoft Corporation. 151 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 152 153 // This implementation is dedicated to the memory of Mary and Thavatchai. 154 155 to_chars_result to_chars(char* __first, char* __last, float __value) { 156 return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0); 157 } 158 159 to_chars_result to_chars(char* __first, char* __last, double __value) { 160 return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, __value, chars_format{}, 0); 161 } 162 163 to_chars_result to_chars(char* __first, char* __last, long double __value) { 164 return _Floating_to_chars<_Floating_to_chars_overload::_Plain>(__first, __last, static_cast<double>(__value), 165 chars_format{}, 0); 166 } 167 168 to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt) { 169 return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0); 170 } 171 172 to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt) { 173 return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, __value, __fmt, 0); 174 } 175 176 to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt) { 177 return _Floating_to_chars<_Floating_to_chars_overload::_Format_only>(__first, __last, static_cast<double>(__value), 178 __fmt, 0); 179 } 180 181 to_chars_result to_chars(char* __first, char* __last, float __value, chars_format __fmt, int __precision) { 182 return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt, 183 __precision); 184 } 185 186 to_chars_result to_chars(char* __first, char* __last, double __value, chars_format __fmt, int __precision) { 187 return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>(__first, __last, __value, __fmt, 188 __precision); 189 } 190 191 to_chars_result to_chars(char* __first, char* __last, long double __value, chars_format __fmt, int __precision) { 192 return _Floating_to_chars<_Floating_to_chars_overload::_Format_precision>( 193 __first, __last, static_cast<double>(__value), __fmt, __precision); 194 } 195 196 _LIBCPP_END_NAMESPACE_STD 197