1337143Sdim//===------------------------- charconv.cpp -------------------------------===// 2337143Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6337143Sdim// 7337143Sdim//===----------------------------------------------------------------------===// 8337143Sdim 9337143Sdim#include "charconv" 10337143Sdim#include <string.h> 11337143Sdim 12337143Sdim_LIBCPP_BEGIN_NAMESPACE_STD 13337143Sdim 14337143Sdimnamespace __itoa 15337143Sdim{ 16337143Sdim 17337143Sdimstatic constexpr char cDigitsLut[200] = { 18337143Sdim '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', 19337143Sdim '7', '0', '8', '0', '9', '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', 20337143Sdim '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', '2', '0', '2', '1', '2', 21337143Sdim '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', 22337143Sdim '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', 23337143Sdim '7', '3', '8', '3', '9', '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', 24337143Sdim '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', '5', '0', '5', '1', '5', 25337143Sdim '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', 26337143Sdim '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', 27337143Sdim '7', '6', '8', '6', '9', '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', 28337143Sdim '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', '8', '0', '8', '1', '8', 29337143Sdim '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', 30337143Sdim '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', 31337143Sdim '7', '9', '8', '9', '9'}; 32337143Sdim 33337143Sdimtemplate <typename T> 34337143Sdiminline _LIBCPP_INLINE_VISIBILITY char* 35337143Sdimappend1(char* buffer, T i) 36337143Sdim{ 37337143Sdim *buffer = '0' + static_cast<char>(i); 38337143Sdim return buffer + 1; 39337143Sdim} 40337143Sdim 41337143Sdimtemplate <typename T> 42337143Sdiminline _LIBCPP_INLINE_VISIBILITY char* 43337143Sdimappend2(char* buffer, T i) 44337143Sdim{ 45337143Sdim memcpy(buffer, &cDigitsLut[(i)*2], 2); 46337143Sdim return buffer + 2; 47337143Sdim} 48337143Sdim 49337143Sdimtemplate <typename T> 50337143Sdiminline _LIBCPP_INLINE_VISIBILITY char* 51337143Sdimappend3(char* buffer, T i) 52337143Sdim{ 53337143Sdim return append2(append1(buffer, (i) / 100), (i) % 100); 54337143Sdim} 55337143Sdim 56337143Sdimtemplate <typename T> 57337143Sdiminline _LIBCPP_INLINE_VISIBILITY char* 58337143Sdimappend4(char* buffer, T i) 59337143Sdim{ 60337143Sdim return append2(append2(buffer, (i) / 100), (i) % 100); 61337143Sdim} 62337143Sdim 63353358Sdimtemplate <typename T> 64353358Sdiminline _LIBCPP_INLINE_VISIBILITY char* 65353358Sdimappend2_no_zeros(char* buffer, T v) 66337143Sdim{ 67353358Sdim if (v < 10) 68353358Sdim return append1(buffer, v); 69353358Sdim else 70353358Sdim return append2(buffer, v); 71353358Sdim} 72353358Sdim 73353358Sdimtemplate <typename T> 74353358Sdiminline _LIBCPP_INLINE_VISIBILITY char* 75353358Sdimappend4_no_zeros(char* buffer, T v) 76353358Sdim{ 77353358Sdim if (v < 100) 78353358Sdim return append2_no_zeros(buffer, v); 79353358Sdim else if (v < 1000) 80353358Sdim return append3(buffer, v); 81353358Sdim else 82353358Sdim return append4(buffer, v); 83353358Sdim} 84353358Sdim 85353358Sdimtemplate <typename T> 86353358Sdiminline _LIBCPP_INLINE_VISIBILITY char* 87353358Sdimappend8_no_zeros(char* buffer, T v) 88353358Sdim{ 89353358Sdim if (v < 10000) 90337143Sdim { 91353358Sdim buffer = append4_no_zeros(buffer, v); 92337143Sdim } 93353358Sdim else 94337143Sdim { 95353358Sdim buffer = append4_no_zeros(buffer, v / 10000); 96353358Sdim buffer = append4(buffer, v % 10000); 97353358Sdim } 98353358Sdim return buffer; 99353358Sdim} 100337143Sdim 101353358Sdimchar* 102353358Sdim__u32toa(uint32_t value, char* buffer) 103353358Sdim{ 104353358Sdim if (value < 100000000) 105353358Sdim { 106353358Sdim buffer = append8_no_zeros(buffer, value); 107337143Sdim } 108337143Sdim else 109337143Sdim { 110337143Sdim // value = aabbbbcccc in decimal 111337143Sdim const uint32_t a = value / 100000000; // 1 to 42 112337143Sdim value %= 100000000; 113337143Sdim 114353358Sdim buffer = append2_no_zeros(buffer, a); 115337143Sdim buffer = append4(buffer, value / 10000); 116337143Sdim buffer = append4(buffer, value % 10000); 117337143Sdim } 118337143Sdim 119337143Sdim return buffer; 120337143Sdim} 121337143Sdim 122337143Sdimchar* 123337143Sdim__u64toa(uint64_t value, char* buffer) 124337143Sdim{ 125337143Sdim if (value < 100000000) 126337143Sdim { 127337143Sdim uint32_t v = static_cast<uint32_t>(value); 128353358Sdim buffer = append8_no_zeros(buffer, v); 129337143Sdim } 130337143Sdim else if (value < 10000000000000000) 131337143Sdim { 132337143Sdim const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 133337143Sdim const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 134337143Sdim 135353358Sdim buffer = append8_no_zeros(buffer, v0); 136337143Sdim buffer = append4(buffer, v1 / 10000); 137337143Sdim buffer = append4(buffer, v1 % 10000); 138337143Sdim } 139337143Sdim else 140337143Sdim { 141337143Sdim const uint32_t a = 142337143Sdim static_cast<uint32_t>(value / 10000000000000000); // 1 to 1844 143337143Sdim value %= 10000000000000000; 144337143Sdim 145353358Sdim buffer = append4_no_zeros(buffer, a); 146337143Sdim 147337143Sdim const uint32_t v0 = static_cast<uint32_t>(value / 100000000); 148337143Sdim const uint32_t v1 = static_cast<uint32_t>(value % 100000000); 149337143Sdim buffer = append4(buffer, v0 / 10000); 150337143Sdim buffer = append4(buffer, v0 % 10000); 151337143Sdim buffer = append4(buffer, v1 / 10000); 152337143Sdim buffer = append4(buffer, v1 % 10000); 153337143Sdim } 154337143Sdim 155337143Sdim return buffer; 156337143Sdim} 157337143Sdim 158337143Sdim} // namespace __itoa 159337143Sdim 160337143Sdim_LIBCPP_END_NAMESPACE_STD 161