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

source code of libc/test/src/__support/integer_to_string_test.cpp