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