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