|
| 1 | +#include <cstddef> |
| 2 | +#include <cstdint> |
| 3 | +#include <gtest/gtest.h> |
| 4 | +#include <type_traits> |
| 5 | + |
| 6 | +import mcpplibs.primitives.literals; |
| 7 | + |
| 8 | +using namespace mcpplibs::primitives::literals; |
| 9 | + |
| 10 | +namespace { |
| 11 | + |
| 12 | +template <auto Value> struct literal_value_tag; |
| 13 | + |
| 14 | +template <typename Probe> |
| 15 | +concept literal_available = requires { typename literal_value_tag<Probe::value()>; }; |
| 16 | + |
| 17 | +struct U8OverflowProbe { |
| 18 | + static consteval auto value() { return 256_u8; } |
| 19 | +}; |
| 20 | + |
| 21 | +struct I8OverflowProbe { |
| 22 | + static consteval auto value() { return 128_i8; } |
| 23 | +}; |
| 24 | + |
| 25 | +struct F32ExactPrecisionLossProbe { |
| 26 | + static consteval auto value() { return 16777217_f32e; } |
| 27 | +}; |
| 28 | + |
| 29 | +struct F64ExactPrecisionLossProbe { |
| 30 | + static consteval auto value() { return 9007199254740993_f64e; } |
| 31 | +}; |
| 32 | + |
| 33 | +struct F32OverflowProbe { |
| 34 | + static consteval auto value() { return 1.0e39_f32; } |
| 35 | +}; |
| 36 | + |
| 37 | +struct F32ExactOverflowProbe { |
| 38 | + static consteval auto value() { return 1.0e39_f32e; } |
| 39 | +}; |
| 40 | + |
| 41 | +struct F32ExactUnderflowProbe { |
| 42 | + static consteval auto value() { return 1.0e-50_f32e; } |
| 43 | +}; |
| 44 | + |
| 45 | +static_assert(!literal_available<U8OverflowProbe>); |
| 46 | +static_assert(!literal_available<I8OverflowProbe>); |
| 47 | +static_assert(!literal_available<F32ExactPrecisionLossProbe>); |
| 48 | +static_assert(!literal_available<F64ExactPrecisionLossProbe>); |
| 49 | +static_assert(!literal_available<F32OverflowProbe>); |
| 50 | +static_assert(!literal_available<F32ExactOverflowProbe>); |
| 51 | +static_assert(!literal_available<F32ExactUnderflowProbe>); |
| 52 | + |
| 53 | +} // namespace |
| 54 | + |
| 55 | +TEST(LiteralsTest, IntegerLiteralsReturnExpectedUnderlyingTypes) { |
| 56 | + static_assert(std::same_as<decltype(42_u8), std::uint8_t>); |
| 57 | + static_assert(std::same_as<decltype(42_u16), std::uint16_t>); |
| 58 | + static_assert(std::same_as<decltype(42_u32), std::uint32_t>); |
| 59 | + static_assert(std::same_as<decltype(42_u64), std::uint64_t>); |
| 60 | + static_assert(std::same_as<decltype(42_size), std::size_t>); |
| 61 | + static_assert(std::same_as<decltype(42_diff), std::ptrdiff_t>); |
| 62 | + static_assert(std::same_as<decltype(42_i8), std::int8_t>); |
| 63 | + static_assert(std::same_as<decltype(42_i16), std::int16_t>); |
| 64 | + static_assert(std::same_as<decltype(42_i32), std::int32_t>); |
| 65 | + static_assert(std::same_as<decltype(42_i64), std::int64_t>); |
| 66 | + |
| 67 | + EXPECT_EQ(42_u8, static_cast<std::uint8_t>(42)); |
| 68 | + EXPECT_EQ(42_u16, static_cast<std::uint16_t>(42)); |
| 69 | + EXPECT_EQ(42_u32, static_cast<std::uint32_t>(42)); |
| 70 | + EXPECT_EQ(42_u64, static_cast<std::uint64_t>(42)); |
| 71 | + EXPECT_EQ(42_size, static_cast<std::size_t>(42)); |
| 72 | + EXPECT_EQ(42_diff, static_cast<std::ptrdiff_t>(42)); |
| 73 | + EXPECT_EQ(42_i8, static_cast<std::int8_t>(42)); |
| 74 | + EXPECT_EQ(42_i16, static_cast<std::int16_t>(42)); |
| 75 | + EXPECT_EQ(42_i32, static_cast<std::int32_t>(42)); |
| 76 | + EXPECT_EQ(42_i64, static_cast<std::int64_t>(42)); |
| 77 | +} |
| 78 | + |
| 79 | +TEST(LiteralsTest, FloatingLiteralsReturnExpectedUnderlyingTypes) { |
| 80 | + static_assert(std::same_as<decltype(1.25_f32), float>); |
| 81 | + static_assert(std::same_as<decltype(1.25_f32e), float>); |
| 82 | + static_assert(std::same_as<decltype(1.25_f64), double>); |
| 83 | + static_assert(std::same_as<decltype(1.25_f64e), double>); |
| 84 | + static_assert(std::same_as<decltype(1.25_f80), long double>); |
| 85 | + static_assert(std::same_as<decltype(1.25_f80e), long double>); |
| 86 | + static_assert(std::same_as<decltype(16777216_f32), float>); |
| 87 | + static_assert(std::same_as<decltype(16777216_f32e), float>); |
| 88 | + static_assert(std::same_as<decltype(16777217_f32), float>); |
| 89 | + static_assert(std::same_as<decltype(9007199254740992_f64), double>); |
| 90 | + static_assert(std::same_as<decltype(9007199254740992_f64e), double>); |
| 91 | + static_assert(std::same_as<decltype(9007199254740993_f64), double>); |
| 92 | + static_assert(std::same_as<decltype(0.1_f32), float>); |
| 93 | + static_assert(std::same_as<decltype(0.1_f64), double>); |
| 94 | + |
| 95 | + EXPECT_FLOAT_EQ(1.25_f32, 1.25f); |
| 96 | + EXPECT_FLOAT_EQ(1.25_f32e, 1.25f); |
| 97 | + EXPECT_DOUBLE_EQ(1.25_f64, 1.25); |
| 98 | + EXPECT_DOUBLE_EQ(1.25_f64e, 1.25); |
| 99 | + EXPECT_EQ(1.25_f80, static_cast<long double>(1.25)); |
| 100 | + EXPECT_EQ(1.25_f80e, static_cast<long double>(1.25)); |
| 101 | + EXPECT_FLOAT_EQ(16777216_f32, 16777216.0f); |
| 102 | + EXPECT_FLOAT_EQ(16777216_f32e, 16777216.0f); |
| 103 | + EXPECT_FLOAT_EQ(16777217_f32, static_cast<float>(16777217.0L)); |
| 104 | + EXPECT_DOUBLE_EQ(9007199254740992_f64, 9007199254740992.0); |
| 105 | + EXPECT_DOUBLE_EQ(9007199254740992_f64e, 9007199254740992.0); |
| 106 | + EXPECT_DOUBLE_EQ(9007199254740993_f64, static_cast<double>(9007199254740993.0L)); |
| 107 | + EXPECT_FLOAT_EQ(0.1_f32, static_cast<float>(0.1L)); |
| 108 | + EXPECT_FLOAT_EQ(2_f32, 2.0f); |
| 109 | + EXPECT_FLOAT_EQ(2_f32e, 2.0f); |
| 110 | + EXPECT_DOUBLE_EQ(0.1_f64, static_cast<double>(0.1L)); |
| 111 | + EXPECT_DOUBLE_EQ(2_f64, 2.0); |
| 112 | + EXPECT_DOUBLE_EQ(2_f64e, 2.0); |
| 113 | + EXPECT_EQ(2_f80, static_cast<long double>(2.0)); |
| 114 | + EXPECT_EQ(2_f80e, static_cast<long double>(2.0)); |
| 115 | +} |
| 116 | + |
| 117 | +TEST(LiteralsTest, CharacterLiteralsReturnExpectedUnderlyingTypes) { |
| 118 | + static_assert(std::same_as<decltype('A'_uchar), unsigned char>); |
| 119 | + static_assert(std::same_as<decltype(u8'A'_char8), char8_t>); |
| 120 | + static_assert(std::same_as<decltype(u'A'_char16), char16_t>); |
| 121 | + static_assert(std::same_as<decltype(U'A'_char32), char32_t>); |
| 122 | + static_assert(std::same_as<decltype(L'A'_wchar), wchar_t>); |
| 123 | + |
| 124 | + EXPECT_EQ('A'_uchar, static_cast<unsigned char>('A')); |
| 125 | + EXPECT_EQ(u8'A'_char8, u8'A'); |
| 126 | + EXPECT_EQ(u'A'_char16, u'A'); |
| 127 | + EXPECT_EQ(U'A'_char32, U'A'); |
| 128 | + EXPECT_EQ(L'A'_wchar, L'A'); |
| 129 | +} |
0 commit comments