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 template <typename T> 64 inline _LIBCPP_INLINE_VISIBILITY char* 65 append2_no_zeros(char* buffer, T v) 66 { 67 if (v < 10) 68 return append1(buffer, v); 69 else 70 return append2(buffer, v); 71 } 72 73 template <typename T> 74 inline _LIBCPP_INLINE_VISIBILITY char* 75 append4_no_zeros(char* buffer, T v) 76 { 77 if (v < 100) 78 return append2_no_zeros(buffer, v); 79 else if (v < 1000) 80 return append3(buffer, v); 81 else 82 return append4(buffer, v); 83 } 84 85 template <typename T> 86 inline _LIBCPP_INLINE_VISIBILITY char* 87 append8_no_zeros(char* buffer, T v) 88 { 89 if (v < 10000) 90 { 91 buffer = append4_no_zeros(buffer, v); 92 } 93 else 94 { 95 buffer = append4_no_zeros(buffer, v / 10000); 96 buffer = append4(buffer, v % 10000); 97 } 98 return buffer; 99 } 100 101 char* 102 __u32toa(uint32_t value, char* buffer) 103 { 104 if (value < 100000000) 105 { 106 buffer = append8_no_zeros(buffer, value); 107 } 108 else 109 { 110 // value = aabbbbcccc in decimal 111 const uint32_t a = value / 100000000; // 1 to 42 112 value %= 100000000; 113 114 buffer = append2_no_zeros(buffer, a); 115 buffer = append4(buffer, value / 10000); 116 buffer = append4(buffer, value % 10000); 117 } 118 119 return buffer; 120 } 121 122 char* 123 __u64toa(uint64_t value, char* buffer) 124 { 125 if (value < 100000000) 126 { 127 uint32_t v = static_cast<uint32_t>(value); 128 buffer = append8_no_zeros(buffer, v); 129 } 130 else if (value < 10000000000000000) 131 { 132 const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 133 const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 134 135 buffer = append8_no_zeros(buffer, v0); 136 buffer = append4(buffer, v1 / 10000); 137 buffer = append4(buffer, v1 % 10000); 138 } 139 else 140 { 141 const uint32_t a = 142 static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844 143 value %= 10000000000000000; 144 145 buffer = append4_no_zeros(buffer, a); 146 147 const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 148 const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 149 buffer = append4(buffer, v0 / 10000); 150 buffer = append4(buffer, v0 % 10000); 151 buffer = append4(buffer, v1 / 10000); 152 buffer = append4(buffer, v1 % 10000); 153 } 154 155 return buffer; 156 } 157 158 } // namespace __itoa 159 160 _LIBCPP_END_NAMESPACE_STD 161