1 //===------------------------- charconv.cpp -------------------------------===// 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 _LIBCPP_BEGIN_NAMESPACE_STD 13 14 namespace __itoa 15 { 16 17 static constexpr char cDigitsLut[200] = { 18 '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', 19 '7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', 20 '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0', '2', '1', '2', 21 '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', 22 '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', 23 '7', '3', '8', '3', '9', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', 24 '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '5', '0', '5', '1', '5', 25 '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', 26 '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', 27 '7', '6', '8', '6', '9', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', 28 '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '8', '0', '8', '1', '8', 29 '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', 30 '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', 31 '7', '9', '8', '9', '9'}; 32 33 template <typename T> 34 inline _LIBCPP_INLINE_VISIBILITY char* 35 append1(char* buffer, T i) 36 { 37 *buffer = '0' + static_cast<char>(i); 38 return buffer + 1; 39 } 40 41 template <typename T> 42 inline _LIBCPP_INLINE_VISIBILITY char* 43 append2(char* buffer, T i) 44 { 45 memcpy(buffer, &cDigitsLut[(i)*2], 2); 46 return buffer + 2; 47 } 48 49 template <typename T> 50 inline _LIBCPP_INLINE_VISIBILITY char* 51 append3(char* buffer, T i) 52 { 53 return append2(append1(buffer, (i) / 100), (i) % 100); 54 } 55 56 template <typename T> 57 inline _LIBCPP_INLINE_VISIBILITY char* 58 append4(char* buffer, T i) 59 { 60 return append2(append2(buffer, (i) / 100), (i) % 100); 61 } 62 63 char* 64 __u32toa(uint32_t value, char* buffer) 65 { 66 if (value < 10000) 67 { 68 if (value < 100) 69 { 70 if (value < 10) 71 buffer = append1(buffer, value); 72 else 73 buffer = append2(buffer, value); 74 } 75 else 76 { 77 if (value < 1000) 78 buffer = append3(buffer, value); 79 else 80 buffer = append4(buffer, value); 81 } 82 } 83 else if (value < 100000000) 84 { 85 // value = bbbbcccc 86 const uint32_t b = value / 10000; 87 const uint32_t c = value % 10000; 88 89 if (value < 1000000) 90 { 91 if (value < 100000) 92 buffer = append1(buffer, b); 93 else 94 buffer = append2(buffer, b); 95 } 96 else 97 { 98 if (value < 10000000) 99 buffer = append3(buffer, b); 100 else 101 buffer = append4(buffer, b); 102 } 103 104 buffer = append4(buffer, c); 105 } 106 else 107 { 108 // value = aabbbbcccc in decimal 109 const uint32_t a = value / 100000000; // 1 to 42 110 value %= 100000000; 111 112 if (a < 10) 113 buffer = append1(buffer, a); 114 else 115 buffer = append2(buffer, a); 116 117 buffer = append4(buffer, value / 10000); 118 buffer = append4(buffer, value % 10000); 119 } 120 121 return buffer; 122 } 123 124 char* 125 __u64toa(uint64_t value, char* buffer) 126 { 127 if (value < 100000000) 128 { 129 uint32_t v = static_cast<uint32_t>(value); 130 if (v < 10000) 131 { 132 if (v < 100) 133 { 134 if (v < 10) 135 buffer = append1(buffer, v); 136 else 137 buffer = append2(buffer, v); 138 } 139 else 140 { 141 if (v < 1000) 142 buffer = append3(buffer, v); 143 else 144 buffer = append4(buffer, v); 145 } 146 } 147 else 148 { 149 // value = bbbbcccc 150 const uint32_t b = v / 10000; 151 const uint32_t c = v % 10000; 152 153 if (v < 1000000) 154 { 155 if (v < 100000) 156 buffer = append1(buffer, b); 157 else 158 buffer = append2(buffer, b); 159 } 160 else 161 { 162 if (v < 10000000) 163 buffer = append3(buffer, b); 164 else 165 buffer = append4(buffer, b); 166 } 167 168 buffer = append4(buffer, c); 169 } 170 } 171 else if (value < 10000000000000000) 172 { 173 const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 174 const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 175 176 const uint32_t b0 = v0 / 10000; 177 const uint32_t c0 = v0 % 10000; 178 179 if (v0 < 1000000) 180 { 181 if (v0 < 100000) 182 buffer = append1(buffer, b0); 183 else 184 buffer = append2(buffer, b0); 185 } 186 else 187 { 188 if (v0 < 10000000) 189 buffer = append3(buffer, b0); 190 else 191 buffer = append4(buffer, b0); 192 } 193 194 buffer = append4(buffer, c0); 195 buffer = append4(buffer, v1 / 10000); 196 buffer = append4(buffer, v1 % 10000); 197 } 198 else 199 { 200 const uint32_t a = 201 static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844 202 value %= 10000000000000000; 203 204 if (a < 100) 205 { 206 if (a < 10) 207 buffer = append1(buffer, a); 208 else 209 buffer = append2(buffer, a); 210 } 211 else 212 { 213 if (a < 1000) 214 buffer = append3(buffer, a); 215 else 216 buffer = append4(buffer, a); 217 } 218 219 const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 220 const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 221 buffer = append4(buffer, v0 / 10000); 222 buffer = append4(buffer, v0 % 10000); 223 buffer = append4(buffer, v1 / 10000); 224 buffer = append4(buffer, v1 % 10000); 225 } 226 227 return buffer; 228 } 229 230 } // namespace __itoa 231 232 _LIBCPP_END_NAMESPACE_STD 233