xref: /llvm-project/libc/test/src/__support/integer_to_string_test.cpp (revision 513e4dc1af5e0a57dab5cd8df6fb1fc9e82b1e33)
1 //===-- Unittests for IntegerToString -------------------------------------===//
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 "src/__support/CPP/span.h"
10 #include "src/__support/CPP/string_view.h"
11 #include "src/__support/UInt.h"
12 #include "src/__support/UInt128.h"
13 #include "src/__support/integer_literals.h"
14 #include "src/__support/integer_to_string.h"
15 
16 #include "test/UnitTest/Test.h"
17 
18 #include "limits.h"
19 
20 using LIBC_NAMESPACE::IntegerToString;
21 using LIBC_NAMESPACE::cpp::span;
22 using LIBC_NAMESPACE::cpp::string_view;
23 using LIBC_NAMESPACE::radix::Bin;
24 using LIBC_NAMESPACE::radix::Custom;
25 using LIBC_NAMESPACE::radix::Dec;
26 using LIBC_NAMESPACE::radix::Hex;
27 using LIBC_NAMESPACE::radix::Oct;
28 using LIBC_NAMESPACE::operator""_u128;
29 using LIBC_NAMESPACE::operator""_u256;
30 
31 #define EXPECT(type, value, string_value)                                      \
32   {                                                                            \
33     const type buffer(value);                                                  \
34     EXPECT_EQ(buffer.view(), string_view(string_value));                       \
35   }
36 
37 TEST(LlvmLibcIntegerToStringTest, UINT8) {
38   using type = IntegerToString<uint8_t>;
39   EXPECT(type, 0, "0");
40   EXPECT(type, 1, "1");
41   EXPECT(type, 12, "12");
42   EXPECT(type, 123, "123");
43   EXPECT(type, UINT8_MAX, "255");
44   EXPECT(type, -1, "255");
45 }
46 
47 TEST(LlvmLibcIntegerToStringTest, INT8) {
48   using type = IntegerToString<int8_t>;
49   EXPECT(type, 0, "0");
50   EXPECT(type, 1, "1");
51   EXPECT(type, 12, "12");
52   EXPECT(type, 123, "123");
53   EXPECT(type, -12, "-12");
54   EXPECT(type, -123, "-123");
55   EXPECT(type, INT8_MAX, "127");
56   EXPECT(type, INT8_MIN, "-128");
57 }
58 
59 TEST(LlvmLibcIntegerToStringTest, UINT16) {
60   using type = IntegerToString<uint16_t>;
61   EXPECT(type, 0, "0");
62   EXPECT(type, 1, "1");
63   EXPECT(type, 12, "12");
64   EXPECT(type, 123, "123");
65   EXPECT(type, 1234, "1234");
66   EXPECT(type, 12345, "12345");
67   EXPECT(type, UINT16_MAX, "65535");
68   EXPECT(type, -1, "65535");
69 }
70 
71 TEST(LlvmLibcIntegerToStringTest, INT16) {
72   using type = IntegerToString<int16_t>;
73   EXPECT(type, 0, "0");
74   EXPECT(type, 1, "1");
75   EXPECT(type, 12, "12");
76   EXPECT(type, 123, "123");
77   EXPECT(type, 1234, "1234");
78   EXPECT(type, 12345, "12345");
79   EXPECT(type, -1, "-1");
80   EXPECT(type, -12, "-12");
81   EXPECT(type, -123, "-123");
82   EXPECT(type, -1234, "-1234");
83   EXPECT(type, -12345, "-12345");
84   EXPECT(type, INT16_MAX, "32767");
85   EXPECT(type, INT16_MIN, "-32768");
86 }
87 
88 TEST(LlvmLibcIntegerToStringTest, UINT32) {
89   using type = IntegerToString<uint32_t>;
90   EXPECT(type, 0, "0");
91   EXPECT(type, 1, "1");
92   EXPECT(type, 12, "12");
93   EXPECT(type, 123, "123");
94   EXPECT(type, 1234, "1234");
95   EXPECT(type, 12345, "12345");
96   EXPECT(type, 123456, "123456");
97   EXPECT(type, 1234567, "1234567");
98   EXPECT(type, 12345678, "12345678");
99   EXPECT(type, 123456789, "123456789");
100   EXPECT(type, 1234567890, "1234567890");
101   EXPECT(type, UINT32_MAX, "4294967295");
102   EXPECT(type, -1, "4294967295");
103 }
104 
105 TEST(LlvmLibcIntegerToStringTest, INT32) {
106   using type = IntegerToString<int32_t>;
107   EXPECT(type, 0, "0");
108   EXPECT(type, 1, "1");
109   EXPECT(type, 12, "12");
110   EXPECT(type, 123, "123");
111   EXPECT(type, 1234, "1234");
112   EXPECT(type, 12345, "12345");
113   EXPECT(type, 123456, "123456");
114   EXPECT(type, 1234567, "1234567");
115   EXPECT(type, 12345678, "12345678");
116   EXPECT(type, 123456789, "123456789");
117   EXPECT(type, 1234567890, "1234567890");
118   EXPECT(type, -1, "-1");
119   EXPECT(type, -12, "-12");
120   EXPECT(type, -123, "-123");
121   EXPECT(type, -1234, "-1234");
122   EXPECT(type, -12345, "-12345");
123   EXPECT(type, -123456, "-123456");
124   EXPECT(type, -1234567, "-1234567");
125   EXPECT(type, -12345678, "-12345678");
126   EXPECT(type, -123456789, "-123456789");
127   EXPECT(type, -1234567890, "-1234567890");
128   EXPECT(type, INT32_MAX, "2147483647");
129   EXPECT(type, INT32_MIN, "-2147483648");
130 }
131 
132 TEST(LlvmLibcIntegerToStringTest, UINT64) {
133   using type = IntegerToString<uint64_t>;
134   EXPECT(type, 0, "0");
135   EXPECT(type, 1, "1");
136   EXPECT(type, 12, "12");
137   EXPECT(type, 123, "123");
138   EXPECT(type, 1234, "1234");
139   EXPECT(type, 12345, "12345");
140   EXPECT(type, 123456, "123456");
141   EXPECT(type, 1234567, "1234567");
142   EXPECT(type, 12345678, "12345678");
143   EXPECT(type, 123456789, "123456789");
144   EXPECT(type, 1234567890, "1234567890");
145   EXPECT(type, 1234567890123456789, "1234567890123456789");
146   EXPECT(type, UINT64_MAX, "18446744073709551615");
147   EXPECT(type, -1, "18446744073709551615");
148 }
149 
150 TEST(LlvmLibcIntegerToStringTest, INT64) {
151   using type = IntegerToString<int64_t>;
152   EXPECT(type, 0, "0");
153   EXPECT(type, 1, "1");
154   EXPECT(type, 12, "12");
155   EXPECT(type, 123, "123");
156   EXPECT(type, 1234, "1234");
157   EXPECT(type, 12345, "12345");
158   EXPECT(type, 123456, "123456");
159   EXPECT(type, 1234567, "1234567");
160   EXPECT(type, 12345678, "12345678");
161   EXPECT(type, 123456789, "123456789");
162   EXPECT(type, 1234567890, "1234567890");
163   EXPECT(type, 1234567890123456789, "1234567890123456789");
164   EXPECT(type, -1, "-1");
165   EXPECT(type, -12, "-12");
166   EXPECT(type, -123, "-123");
167   EXPECT(type, -1234, "-1234");
168   EXPECT(type, -12345, "-12345");
169   EXPECT(type, -123456, "-123456");
170   EXPECT(type, -1234567, "-1234567");
171   EXPECT(type, -12345678, "-12345678");
172   EXPECT(type, -123456789, "-123456789");
173   EXPECT(type, -1234567890, "-1234567890");
174   EXPECT(type, -1234567890123456789, "-1234567890123456789");
175   EXPECT(type, INT64_MAX, "9223372036854775807");
176   EXPECT(type, INT64_MIN, "-9223372036854775808");
177 }
178 
179 TEST(LlvmLibcIntegerToStringTest, UINT64_Base_8) {
180   using type = IntegerToString<int64_t, Oct>;
181   EXPECT(type, 0, "0");
182   EXPECT(type, 012345, "12345");
183   EXPECT(type, 0123456701234567012345, "123456701234567012345");
184   EXPECT(type, 01777777777777777777777, "1777777777777777777777");
185 }
186 
187 TEST(LlvmLibcIntegerToStringTest, UINT64_Base_16) {
188   using type = IntegerToString<uint64_t, Hex>;
189   EXPECT(type, 0, "0");
190   EXPECT(type, 0x12345, "12345");
191   EXPECT(type, 0x123456789abcdef, "123456789abcdef");
192   EXPECT(type, 0xffffffffffffffff, "ffffffffffffffff");
193   using TYPE = IntegerToString<uint64_t, Hex::Uppercase>;
194   EXPECT(TYPE, 0x123456789abcdef, "123456789ABCDEF");
195 }
196 
197 TEST(LlvmLibcIntegerToStringTest, UINT64_Base_2) {
198   using type = IntegerToString<uint64_t, Bin>;
199   EXPECT(type, 0, "0");
200   EXPECT(type, 0b111100001100, "111100001100");
201   EXPECT(type, 0b100100011101010111100, "100100011101010111100");
202   EXPECT(type, 0xffffffffffffffff,
203          "1111111111111111111111111111111111111111111111111111111111111111");
204 }
205 
206 TEST(LlvmLibcIntegerToStringTest, UINT128_Base_16) {
207   using type = IntegerToString<UInt128, Hex::WithWidth<32>>;
208   EXPECT(type, 0, "00000000000000000000000000000000");
209   EXPECT(type, 0x12345, "00000000000000000000000000012345");
210   EXPECT(type, 0x12340000'00000000'00000000'00000000_u128,
211          "12340000000000000000000000000000");
212   EXPECT(type, 0x00000000'00000000'12340000'00000000_u128,
213          "00000000000000001234000000000000");
214   EXPECT(type, 0x00000000'00000001'23400000'00000000_u128,
215          "00000000000000012340000000000000");
216 }
217 
218 TEST(LlvmLibcIntegerToStringTest, UINT64_Base_36) {
219   using type = IntegerToString<uint64_t, Custom<36>>;
220   EXPECT(type, 0, "0");
221   EXPECT(type, 12345, "9ix");
222   EXPECT(type, 1047601316295595, "abcdefghij");
223   EXPECT(type, 2092218013456445, "klmnopqrst");
224   EXPECT(type, 0xffffffffffffffff, "3w5e11264sgsf");
225 
226   using TYPE = IntegerToString<uint64_t, Custom<36>::Uppercase>;
227   EXPECT(TYPE, 1867590395, "UVWXYZ");
228 }
229 
230 TEST(LlvmLibcIntegerToStringTest, UINT256_Base_16) {
231   using UInt256 = LIBC_NAMESPACE::cpp::UInt<256>;
232   using type = IntegerToString<UInt256, Hex::WithWidth<64>>;
233   EXPECT(
234       type,
235       0x0000000000000000000000000000000000000000000000000000000000000000_u256,
236       "0000000000000000000000000000000000000000000000000000000000000000");
237   EXPECT(
238       type,
239       0x0000000000000000000000000000000000000000000000000000000000012345_u256,
240       "0000000000000000000000000000000000000000000000000000000000012345");
241   EXPECT(
242       type,
243       0x0000000000000000000000000000000012340000000000000000000000000000_u256,
244       "0000000000000000000000000000000012340000000000000000000000000000");
245   EXPECT(
246       type,
247       0x0000000000000000000000000000000123400000000000000000000000000000_u256,
248       "0000000000000000000000000000000123400000000000000000000000000000");
249   EXPECT(
250       type,
251       0x1234000000000000000000000000000000000000000000000000000000000000_u256,
252       "1234000000000000000000000000000000000000000000000000000000000000");
253 }
254 
255 TEST(LlvmLibcIntegerToStringTest, NegativeInterpretedAsPositive) {
256   using BIN = IntegerToString<int8_t, Bin>;
257   using OCT = IntegerToString<int8_t, Oct>;
258   using DEC = IntegerToString<int8_t, Dec>;
259   using HEX = IntegerToString<int8_t, Hex>;
260   EXPECT(BIN, -1, "11111111");
261   EXPECT(OCT, -1, "377");
262   EXPECT(DEC, -1, "-1"); // Only DEC format negative values
263   EXPECT(HEX, -1, "ff");
264 }
265 
266 TEST(LlvmLibcIntegerToStringTest, Width) {
267   using BIN = IntegerToString<uint8_t, Bin::WithWidth<4>>;
268   using OCT = IntegerToString<uint8_t, Oct::WithWidth<4>>;
269   using DEC = IntegerToString<uint8_t, Dec::WithWidth<4>>;
270   using HEX = IntegerToString<uint8_t, Hex::WithWidth<4>>;
271   EXPECT(BIN, 1, "0001");
272   EXPECT(HEX, 1, "0001");
273   EXPECT(OCT, 1, "0001");
274   EXPECT(DEC, 1, "0001");
275 }
276 
277 TEST(LlvmLibcIntegerToStringTest, Prefix) {
278   // WithPrefix is not supported for Decimal
279   using BIN = IntegerToString<uint8_t, Bin::WithPrefix>;
280   using OCT = IntegerToString<uint8_t, Oct::WithPrefix>;
281   using HEX = IntegerToString<uint8_t, Hex::WithPrefix>;
282   EXPECT(BIN, 1, "0b1");
283   EXPECT(HEX, 1, "0x1");
284   EXPECT(OCT, 1, "01");
285   EXPECT(OCT, 0, "0"); // Zero is not prefixed for octal
286 }
287 
288 TEST(LlvmLibcIntegerToStringTest, Uppercase) {
289   using HEX = IntegerToString<uint64_t, Hex::Uppercase>;
290   EXPECT(HEX, 0xDEADC0DE, "DEADC0DE");
291 }
292 
293 TEST(LlvmLibcIntegerToStringTest, Sign) {
294   // WithSign only compiles with DEC
295   using DEC = IntegerToString<int8_t, Dec::WithSign>;
296   EXPECT(DEC, -1, "-1");
297   EXPECT(DEC, 0, "+0");
298   EXPECT(DEC, 1, "+1");
299 }
300 
301 TEST(LlvmLibcIntegerToStringTest, BufferOverrun) {
302   { // Writing '0' in an empty buffer requiring zero digits : works
303     const auto view =
304         IntegerToString<int, Dec::WithWidth<0>>::format_to(span<char>(), 0);
305     ASSERT_TRUE(view.has_value());
306     ASSERT_EQ(*view, string_view(""));
307   }
308   char buffer[1];
309   { // Writing '1' in a buffer of one char : works
310     const auto view = IntegerToString<int>::format_to(buffer, 1);
311     ASSERT_TRUE(view.has_value());
312     ASSERT_EQ(*view, string_view("1"));
313   }
314   { // Writing '11' in a buffer of one char : fails
315     const auto view = IntegerToString<int>::format_to(buffer, 11);
316     ASSERT_FALSE(view.has_value());
317   }
318 }
319