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