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/UInt.h" 13 #include "src/__support/UInt128.h" 14 #include "src/__support/integer_literals.h" 15 #include "src/__support/integer_to_string.h" 16 17 #include "test/UnitTest/Test.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 using LIBC_NAMESPACE::operator""_u128; 28 using 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 36 TEST(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 46 TEST(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 58 TEST(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 70 TEST(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 87 TEST(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 104 TEST(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 131 TEST(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 149 TEST(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 178 TEST(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 186 TEST(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 196 TEST(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 205 TEST(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 217 TEST(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 229 TEST(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 254 TEST(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 265 TEST(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 276 TEST(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 287 TEST(LlvmLibcIntegerToStringTest, Uppercase) { 288 using HEX = IntegerToString<uint64_t, Hex::Uppercase>; 289 EXPECT(HEX, 0xDEADC0DE, "DEADC0DE"); 290 } 291 292 TEST(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 300 TEST(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(span<char>(), 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, 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, 11); 315 ASSERT_FALSE(view.has_value()); 316 } 317 } 318