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 __llvm_libc::IntegerToString; 20 using __llvm_libc::cpp::span; 21 using __llvm_libc::cpp::string_view; 22 using __llvm_libc::radix::Bin; 23 using __llvm_libc::radix::Custom; 24 using __llvm_libc::radix::Dec; 25 using __llvm_libc::radix::Hex; 26 using __llvm_libc::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 = __llvm_libc::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