1 // Copyright (C) 206 Jonathan Müller <jonathanmueller.dev@gmail.com> 2 // This file is subject to the license terms in the LICENSE file 3 // found in the top-level directory of this distribution. 4 5 #include <type_safe/integer.hpp> 6 7 #include <catch.hpp> 8 9 #include <sstream> 10 11 using namespace type_safe; 12 13 #ifndef TYPE_SAFE_TEST_NO_STATIC_ASSERT 14 static_assert(std::is_standard_layout<integer<int>>::value, ""); 15 static_assert(std::is_trivially_copyable<integer<int>>::value, ""); 16 // conversion checks 17 static_assert(sizeof(short) < sizeof(int), ""); 18 static_assert(std::is_constructible<integer<short>, short>::value, ""); 19 static_assert(!std::is_constructible<integer<short>, int>::value, ""); 20 static_assert(!std::is_constructible<integer<short>, unsigned short>::value, ""); 21 static_assert(!std::is_constructible<integer<unsigned short>, short>::value, ""); 22 23 static_assert(std::is_assignable<integer<short>, short>::value, ""); 24 static_assert(!std::is_assignable<integer<short>, int>::value, ""); 25 static_assert(!std::is_assignable<integer<short>, unsigned short>::value, ""); 26 static_assert(!std::is_assignable<integer<unsigned short>, short>::value, ""); 27 28 static_assert(sizeof(int) < sizeof(long long), ""); 29 static_assert(std::is_constructible<integer<int>, int>::value, ""); 30 static_assert(std::is_constructible<integer<int>, short>::value, ""); 31 static_assert(!std::is_constructible<integer<int>, long long>::value, ""); 32 static_assert(!std::is_constructible<integer<int>, unsigned>::value, ""); 33 static_assert(!std::is_constructible<integer<unsigned>, int>::value, ""); 34 35 static_assert(std::is_assignable<integer<int>, int>::value, ""); 36 static_assert(std::is_assignable<integer<int>, short>::value, ""); 37 static_assert(!std::is_assignable<integer<int>, long long>::value, ""); 38 static_assert(!std::is_assignable<integer<int>, unsigned>::value, ""); 39 static_assert(!std::is_assignable<integer<unsigned>, int>::value, ""); 40 #endif 41 42 TEST_CASE("integer") 43 { 44 using int_t = integer<int>; 45 46 SECTION("constructor") 47 { 48 int_t a(0); 49 REQUIRE(static_cast<int>(a) == 0); 50 int_t b(32); 51 REQUIRE(static_cast<int>(b) == 32); 52 int_t c(-25); 53 REQUIRE(static_cast<int>(c) == -25); 54 } 55 SECTION("assignment") 56 { 57 int_t a(0); 58 a = 32; 59 REQUIRE(static_cast<int>(a) == 32); 60 a = -25; 61 REQUIRE(static_cast<int>(a) == -25); 62 } 63 SECTION("unary") 64 { 65 int_t a(13); 66 REQUIRE(static_cast<int>(+a) == static_cast<int>(a)); 67 REQUIRE(static_cast<int>(-a) == -static_cast<int>(a)); 68 } 69 SECTION("increment") 70 { 71 int_t a(0); 72 REQUIRE(static_cast<int>(++a) == 1); 73 REQUIRE(static_cast<int>(a++) == 1); 74 REQUIRE(static_cast<int>(a) == 2); 75 } 76 SECTION("decrement") 77 { 78 int_t a(0); 79 REQUIRE(static_cast<int>(--a) == -1); 80 REQUIRE(static_cast<int>(a--) == -1); 81 REQUIRE(static_cast<int>(a) == -2); 82 } 83 SECTION("addition") 84 { 85 int_t wrapper(0); 86 int normal(0); 87 REQUIRE(static_cast<int>(wrapper) == normal); 88 89 wrapper += 5; 90 normal += 5; 91 REQUIRE(static_cast<int>(wrapper) == normal); 92 93 wrapper += short(5); 94 normal += short(5); 95 REQUIRE(static_cast<int>(wrapper) == normal); 96 97 wrapper = wrapper + (-23); 98 normal = normal + (-23); 99 REQUIRE(static_cast<int>(wrapper) == normal); 100 101 wrapper = 22 + wrapper; 102 normal = 22 + normal; 103 REQUIRE(static_cast<int>(wrapper) == normal); 104 105 wrapper = int_t(-4) + wrapper; 106 normal = (-4) + normal; 107 REQUIRE(static_cast<int>(wrapper) == normal); 108 } 109 SECTION("subtraction") 110 { 111 int_t wrapper(0); 112 int normal(0); 113 REQUIRE(static_cast<int>(wrapper) == normal); 114 115 wrapper -= 5; 116 normal -= 5; 117 REQUIRE(static_cast<int>(wrapper) == normal); 118 119 wrapper -= short(5); 120 normal -= short(5); 121 REQUIRE(static_cast<int>(wrapper) == normal); 122 123 wrapper = wrapper - (-23); 124 normal = normal - (-23); 125 REQUIRE(static_cast<int>(wrapper) == normal); 126 127 wrapper = 22 - wrapper; 128 normal = 22 - normal; 129 REQUIRE(static_cast<int>(wrapper) == normal); 130 131 wrapper = int_t(-4) - wrapper; 132 normal = (-4) - normal; 133 REQUIRE(static_cast<int>(wrapper) == normal); 134 } 135 SECTION("multiplication") 136 { 137 int_t wrapper(1); 138 int normal(1); 139 REQUIRE(static_cast<int>(wrapper) == normal); 140 141 wrapper *= 5; 142 normal *= 5; 143 REQUIRE(static_cast<int>(wrapper) == normal); 144 145 wrapper *= short(5); 146 normal *= short(5); 147 REQUIRE(static_cast<int>(wrapper) == normal); 148 149 wrapper = wrapper * (-23); 150 normal = normal * (-23); 151 REQUIRE(static_cast<int>(wrapper) == normal); 152 153 wrapper = 22 * wrapper; 154 normal = 22 * normal; 155 REQUIRE(static_cast<int>(wrapper) == normal); 156 157 wrapper = int_t(-4) * wrapper; 158 normal = (-4) * normal; 159 REQUIRE(static_cast<int>(wrapper) == normal); 160 } 161 SECTION("division") 162 { 163 int_t wrapper(23 * 25); 164 int normal(23 * 25); 165 REQUIRE(static_cast<int>(wrapper) == normal); 166 167 wrapper /= 5; 168 normal /= 5; 169 REQUIRE(static_cast<int>(wrapper) == normal); 170 171 wrapper /= short(5); 172 normal /= short(5); 173 REQUIRE(static_cast<int>(wrapper) == normal); 174 175 wrapper = wrapper / (-23); 176 normal = normal / (-23); 177 REQUIRE(static_cast<int>(wrapper) == normal); 178 179 wrapper = 22 / wrapper; 180 normal = 22 / normal; 181 REQUIRE(static_cast<int>(wrapper) == normal); 182 183 wrapper = int_t(-4) / wrapper; 184 normal = (-4) / normal; 185 REQUIRE(static_cast<int>(wrapper) == normal); 186 } 187 SECTION("modulo") 188 { 189 int_t wrapper(24 * 6); 190 int normal(24 * 6); 191 REQUIRE(static_cast<int>(wrapper) == normal); 192 193 wrapper %= 5; 194 normal %= 5; 195 REQUIRE(static_cast<int>(wrapper) == normal); 196 197 wrapper %= short(5); 198 normal %= short(5); 199 REQUIRE(static_cast<int>(wrapper) == normal); 200 201 wrapper = wrapper % (-23); 202 normal = normal % (-23); 203 REQUIRE(static_cast<int>(wrapper) == normal); 204 205 wrapper = 22 % wrapper; 206 normal = 22 % normal; 207 REQUIRE(static_cast<int>(wrapper) == normal); 208 209 wrapper = int_t(-4) % wrapper; 210 normal = (-4) % normal; 211 REQUIRE(static_cast<int>(wrapper) == normal); 212 } 213 SECTION("comparison") 214 { 215 // == 216 REQUIRE(bool(int_t(4) == int_t(4))); 217 REQUIRE(!(int_t(5) == int_t(4))); 218 219 REQUIRE(bool(4 == int_t(4))); 220 REQUIRE(!(5 == int_t(4))); 221 222 REQUIRE(bool(int_t(4) == 4)); 223 REQUIRE(!(int_t(5) == 4)); 224 225 // != 226 REQUIRE(bool(int_t(5) != int_t(4))); 227 REQUIRE(!(int_t(4) != int_t(4))); 228 229 REQUIRE(bool(5 != int_t(4))); 230 REQUIRE(!(4 != int_t(4))); 231 232 REQUIRE(bool(int_t(5) != 4)); 233 REQUIRE(!(int_t(4) != 4)); 234 235 // < 236 REQUIRE(bool(int_t(4) < int_t(5))); 237 REQUIRE(!(int_t(5) < int_t(4))); 238 REQUIRE(!(int_t(4) < int_t(4))); 239 240 REQUIRE(bool(4 < int_t(5))); 241 REQUIRE(!(5 < int_t(4))); 242 REQUIRE(!(4 < int_t(4))); 243 244 REQUIRE(bool(int_t(4) < 5)); 245 REQUIRE(!(int_t(5) < 4)); 246 REQUIRE(!(int_t(4) < 4)); 247 248 // <= 249 REQUIRE(bool(int_t(4) <= int_t(5))); 250 REQUIRE(!(int_t(5) <= int_t(4))); 251 REQUIRE(bool(int_t(4) <= int_t(4))); 252 253 REQUIRE(bool(4 <= int_t(5))); 254 REQUIRE(!(5 <= int_t(4))); 255 REQUIRE(bool(4 <= int_t(4))); 256 257 REQUIRE(bool(int_t(4) <= 5)); 258 REQUIRE(!(int_t(5) <= 4)); 259 REQUIRE(bool(int_t(4) <= 4)); 260 261 // > 262 REQUIRE(bool(int_t(5) > int_t(4))); 263 REQUIRE(!(int_t(4) > int_t(5))); 264 REQUIRE(!(int_t(5) > int_t(5))); 265 266 REQUIRE(bool(5 > int_t(4))); 267 REQUIRE(!(4 > int_t(5))); 268 REQUIRE(!(5 > int_t(5))); 269 270 REQUIRE(bool(int_t(5) > 4)); 271 REQUIRE(!(int_t(4) > 5)); 272 REQUIRE(!(int_t(5) > 5)); 273 274 // >= 275 REQUIRE(bool(int_t(5) >= int_t(4))); 276 REQUIRE(!(int_t(4) >= int_t(5))); 277 REQUIRE(bool(int_t(5) >= int_t(5))); 278 279 REQUIRE(bool(5 >= int_t(4))); 280 REQUIRE(!(4 >= int_t(5))); 281 REQUIRE(bool(5 >= int_t(5))); 282 283 REQUIRE(bool(int_t(5) >= 4)); 284 REQUIRE(!(int_t(4) >= 5)); 285 REQUIRE(bool(int_t(5) >= 5)); 286 } 287 SECTION("make_(un)signed") 288 { 289 int_t a = 5; 290 integer<unsigned> b = make_unsigned(a); 291 REQUIRE(static_cast<unsigned>(b) == 5); 292 293 b = 125u; 294 a = make_signed(b); 295 REQUIRE(static_cast<int>(a) == 125); 296 } 297 SECTION("i/o") 298 { 299 std::ostringstream out; 300 std::istringstream in("10"); 301 302 int_t i(0); 303 out << i; 304 REQUIRE(out.str() == "0"); 305 306 in >> i; 307 REQUIRE(static_cast<int>(i) == 10); 308 } 309 SECTION("abs") 310 { 311 int i = 123; 312 integer<unsigned> ia = type_safe::abs(i); 313 REQUIRE(static_cast<unsigned>(ia) == 123u); 314 315 i = -123; 316 ia = type_safe::abs(i); 317 REQUIRE(static_cast<unsigned>(ia) == 123u); 318 } 319 SECTION("signed_to_unsigned") 320 { 321 // From int8_t 322 REQUIRE(!std::is_convertible<integer<int8_t>, integer<uint8_t>>::value); 323 REQUIRE(!std::is_convertible<integer<int8_t>, integer<uint16_t>>::value); 324 REQUIRE(!std::is_convertible<integer<int8_t>, integer<uint32_t>>::value); 325 REQUIRE(!std::is_convertible<integer<int8_t>, integer<uint64_t>>::value); 326 327 // From int16_t 328 REQUIRE(!std::is_convertible<integer<int16_t>, integer<uint8_t>>::value); 329 REQUIRE(!std::is_convertible<integer<int16_t>, integer<uint16_t>>::value); 330 REQUIRE(!std::is_convertible<integer<int16_t>, integer<uint32_t>>::value); 331 REQUIRE(!std::is_convertible<integer<int16_t>, integer<uint64_t>>::value); 332 333 // From int32_t 334 REQUIRE(!std::is_convertible<integer<int32_t>, integer<uint8_t>>::value); 335 REQUIRE(!std::is_convertible<integer<int32_t>, integer<uint16_t>>::value); 336 REQUIRE(!std::is_convertible<integer<int32_t>, integer<uint32_t>>::value); 337 REQUIRE(!std::is_convertible<integer<int32_t>, integer<uint64_t>>::value); 338 339 // From int64_t 340 REQUIRE(!std::is_convertible<integer<int64_t>, integer<uint8_t>>::value); 341 REQUIRE(!std::is_convertible<integer<int64_t>, integer<uint16_t>>::value); 342 REQUIRE(!std::is_convertible<integer<int64_t>, integer<uint32_t>>::value); 343 REQUIRE(!std::is_convertible<integer<int64_t>, integer<uint64_t>>::value); 344 } 345 SECTION("unsigned_to_signed") 346 { 347 // From uint8_t 348 REQUIRE(!std::is_convertible<integer<uint8_t>, integer<int8_t>>::value); 349 REQUIRE(std::is_convertible<integer<uint8_t>, integer<int16_t>>::value); 350 REQUIRE(std::is_convertible<integer<uint8_t>, integer<int32_t>>::value); 351 REQUIRE(std::is_convertible<integer<uint8_t>, integer<int64_t>>::value); 352 353 // From uint16_t 354 REQUIRE(!std::is_convertible<integer<uint16_t>, integer<int8_t>>::value); 355 REQUIRE(!std::is_convertible<integer<uint16_t>, integer<int16_t>>::value); 356 REQUIRE(std::is_convertible<integer<uint16_t>, integer<int32_t>>::value); 357 REQUIRE(std::is_convertible<integer<uint16_t>, integer<int64_t>>::value); 358 359 // From uint32_t 360 REQUIRE(!std::is_convertible<integer<uint32_t>, integer<int8_t>>::value); 361 REQUIRE(!std::is_convertible<integer<uint32_t>, integer<int16_t>>::value); 362 REQUIRE(!std::is_convertible<integer<uint32_t>, integer<int32_t>>::value); 363 REQUIRE(std::is_convertible<integer<uint32_t>, integer<int64_t>>::value); 364 365 // From uint32_t 366 REQUIRE(!std::is_convertible<integer<uint64_t>, integer<int8_t>>::value); 367 REQUIRE(!std::is_convertible<integer<uint64_t>, integer<int16_t>>::value); 368 REQUIRE(!std::is_convertible<integer<uint64_t>, integer<int32_t>>::value); 369 REQUIRE(!std::is_convertible<integer<uint64_t>, integer<int64_t>>::value); 370 } 371 SECTION("signed_to_signed") 372 { 373 // From int8_t 374 REQUIRE(std::is_convertible<integer<int8_t>, integer<int8_t>>::value); 375 REQUIRE(std::is_convertible<integer<int8_t>, integer<int16_t>>::value); 376 REQUIRE(std::is_convertible<integer<int8_t>, integer<int32_t>>::value); 377 REQUIRE(std::is_convertible<integer<int8_t>, integer<int64_t>>::value); 378 379 // From int16_t 380 REQUIRE(!std::is_convertible<integer<int16_t>, integer<int8_t>>::value); 381 REQUIRE(std::is_convertible<integer<int16_t>, integer<int16_t>>::value); 382 REQUIRE(std::is_convertible<integer<int16_t>, integer<int32_t>>::value); 383 REQUIRE(std::is_convertible<integer<int16_t>, integer<int64_t>>::value); 384 385 // From int32_t 386 REQUIRE(!std::is_convertible<integer<int32_t>, integer<int8_t>>::value); 387 REQUIRE(!std::is_convertible<integer<int32_t>, integer<int16_t>>::value); 388 REQUIRE(std::is_convertible<integer<int32_t>, integer<int32_t>>::value); 389 REQUIRE(std::is_convertible<integer<int32_t>, integer<int64_t>>::value); 390 391 // From int64_t 392 REQUIRE(!std::is_convertible<integer<int64_t>, integer<int8_t>>::value); 393 REQUIRE(!std::is_convertible<integer<int64_t>, integer<int16_t>>::value); 394 REQUIRE(!std::is_convertible<integer<int64_t>, integer<int32_t>>::value); 395 REQUIRE(std::is_convertible<integer<int64_t>, integer<int64_t>>::value); 396 } 397 SECTION("unsigned_to_unsigned") 398 { 399 // From uint8_t 400 REQUIRE(std::is_convertible<integer<uint8_t>, integer<uint8_t>>::value); 401 REQUIRE(std::is_convertible<integer<uint8_t>, integer<uint16_t>>::value); 402 REQUIRE(std::is_convertible<integer<uint8_t>, integer<uint32_t>>::value); 403 REQUIRE(std::is_convertible<integer<uint8_t>, integer<uint64_t>>::value); 404 405 // From uint16_t 406 REQUIRE(!std::is_convertible<integer<uint16_t>, integer<uint8_t>>::value); 407 REQUIRE(std::is_convertible<integer<uint16_t>, integer<uint16_t>>::value); 408 REQUIRE(std::is_convertible<integer<uint16_t>, integer<uint32_t>>::value); 409 REQUIRE(std::is_convertible<integer<uint16_t>, integer<uint64_t>>::value); 410 411 // From uint32_t 412 REQUIRE(!std::is_convertible<integer<uint32_t>, integer<uint8_t>>::value); 413 REQUIRE(!std::is_convertible<integer<uint32_t>, integer<uint16_t>>::value); 414 REQUIRE(std::is_convertible<integer<uint32_t>, integer<uint32_t>>::value); 415 REQUIRE(std::is_convertible<integer<uint32_t>, integer<uint64_t>>::value); 416 417 // From uint64_t 418 REQUIRE(!std::is_convertible<integer<uint64_t>, integer<uint8_t>>::value); 419 REQUIRE(!std::is_convertible<integer<uint64_t>, integer<uint16_t>>::value); 420 REQUIRE(!std::is_convertible<integer<uint64_t>, integer<uint32_t>>::value); 421 REQUIRE(std::is_convertible<integer<uint64_t>, integer<uint64_t>>::value); 422 } 423 } 424