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