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