From 5c7c15b4a7797ac0e7a5ed1d9c00aa36961d4b66 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 14 Dec 2024 17:19:18 +0800 Subject: [PATCH] test: enhance RawCode test suites --- src/core/main.cc | 17 -------- src/core/raw_code/raw_code.h | 2 + src/core_test/codec/raw_code.cc | 72 ++++++++++++++++++++++++++------- 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/src/core/main.cc b/src/core/main.cc index 81b0b3f..cec091a 100644 --- a/src/core/main.cc +++ b/src/core/main.cc @@ -45,23 +45,6 @@ int main() { const auto start = std::chrono::system_clock::now(); - static_assert(RawCode::check(0x603EDF5CAFFF5E2)); - constexpr auto raw_code = RawCode::unsafe_create(0x603EDF5CAFFF5E2); - - static_assert(raw_code.unwrap() == 0x603EDF5CAFFF5E2); - static_assert(static_cast(raw_code) == 0x603EDF5CAFFF5E2); - static_assert(raw_code == RawCode::create(0x603EDF5CAFFF5E2)->unwrap()); - - static_assert(raw_code.to_common_code() == 0x1A9BF0C00); - static_assert(RawCode::from_common_code(0x1A9BF0C00).value() == 0x603EDF5CAFFF5E2); - static_assert(RawCode(CommonCode::unsafe_create(0x1A9BF0C00)) == 0x603EDF5CAFFF5E2); - static_assert(RawCode::from_common_code(CommonCode::unsafe_create(0x1A9BF0C00)) == 0x603EDF5CAFFF5E2); - - static_assert(!raw_code.is_vertical_mirror()); - static_assert(raw_code.is_horizontal_mirror()); - static_assert(raw_code.to_vertical_mirror() == 0xFFF5E2FCF4DA603); - static_assert(raw_code.to_horizontal_mirror() == 0x603EDF5CAFFF5E2); - static_assert(ShortCode::check(4091296)); constexpr auto short_code = ShortCode::unsafe_create(4091296); diff --git a/src/core/raw_code/raw_code.h b/src/core/raw_code/raw_code.h index 8c5641c..0245bf6 100644 --- a/src/core/raw_code/raw_code.h +++ b/src/core/raw_code/raw_code.h @@ -66,6 +66,7 @@ #include #include #include +#include #include "common_code/common_code_fwd.h" @@ -172,6 +173,7 @@ private: static_assert(sizeof(RawCode) == 8); static_assert(std::is_standard_layout_v); static_assert(std::is_trivially_copyable_v); +static_assert(std::has_unique_object_representations_v); } // namespace klotski::codec diff --git a/src/core_test/codec/raw_code.cc b/src/core_test/codec/raw_code.cc index f01a598..8121ec3 100644 --- a/src/core_test/codec/raw_code.cc +++ b/src/core_test/codec/raw_code.cc @@ -1,6 +1,8 @@ #include #include "test_samples.h" + +#include "helper/hash.h" #include "helper/expect.h" #include "helper/mirror.h" #include "helper/parallel.h" @@ -18,6 +20,15 @@ using klotski::codec::CommonCode; using klotski::cases::AllCases; using klotski::cases::ALL_CASES_NUM_; +static_assert(helper::is_hashable_v); +static_assert(!std::is_default_constructible_v); + +static_assert(std::is_trivially_destructible_v); +static_assert(std::is_trivially_copy_assignable_v); +static_assert(std::is_trivially_move_assignable_v); +static_assert(std::is_trivially_copy_constructible_v); +static_assert(std::is_trivially_move_constructible_v); + TEST(RawCode, basic) { EXPECT_FALSE(RawCode::check(0x0A34'182B'3810'2D21)); // invalid code EXPECT_FALSE(RawCode::check(0x8603'EDF5'CAFF'F5E2)); // high 4-bits not zero @@ -41,14 +52,14 @@ TEST(RawCode, basic) { } TEST(RawCode, exporter) { - auto raw_code = RawCode::unsafe_create(TEST_R_CODE); + const auto raw_code = RawCode::unsafe_create(TEST_R_CODE); EXPECT_EQ(raw_code.unwrap(), TEST_R_CODE); EXPECT_EQ(raw_code.to_common_code(), TEST_C_CODE); } TEST(RawCode, operators) { - auto raw_code = RawCode::unsafe_create(TEST_R_CODE); - EXPECT_EQ((uint64_t)raw_code, TEST_R_CODE); // uint64_t cast + const auto raw_code = RawCode::unsafe_create(TEST_R_CODE); + EXPECT_EQ(static_cast(raw_code), TEST_R_CODE); // uint64_t cast EXPECT_NE(0, raw_code); // uint64_t != RawCode EXPECT_NE(raw_code, 0); // RawCode != uint64_t @@ -83,13 +94,43 @@ TEST(RawCode, operators) { EXPECT_GT(RawCode::unsafe_create(TEST_R_CODE + 1), raw_code); // RawCode > RawCode } +TEST(RawCode, constexpr) { + static_assert(RawCode::check(TEST_R_CODE)); + static_assert(!RawCode::check(TEST_R_CODE_ERR)); + + static_assert(RawCode::create(TEST_R_CODE).has_value()); + static_assert(!RawCode::create(TEST_R_CODE_ERR).has_value()); + static_assert(RawCode::create(TEST_R_CODE).value() == TEST_R_CODE); + + constexpr auto code = RawCode::unsafe_create(TEST_R_CODE); + static_assert(static_cast(code) == TEST_R_CODE); + static_assert(code.unwrap() == TEST_R_CODE); + + static_assert(code.to_common_code() == TEST_C_CODE); + static_assert(RawCode(CommonCode::unsafe_create(TEST_C_CODE)) == TEST_R_CODE); + static_assert(RawCode::from_common_code(TEST_C_CODE).value() == TEST_R_CODE); + static_assert(RawCode::from_common_code(CommonCode::unsafe_create(TEST_C_CODE)) == TEST_R_CODE); + + constexpr auto mirror_1 = RawCode::unsafe_create(TEST_MIRROR_R1); + static_assert(!mirror_1.is_vertical_mirror()); + static_assert(mirror_1.is_horizontal_mirror()); + static_assert(mirror_1.to_vertical_mirror() == TEST_MIRROR_R1_VM); + static_assert(mirror_1.to_horizontal_mirror() == TEST_MIRROR_R1_HM); + + constexpr auto mirror_2 = RawCode::unsafe_create(TEST_MIRROR_R2); + static_assert(!mirror_2.is_vertical_mirror()); + static_assert(!mirror_2.is_horizontal_mirror()); + static_assert(mirror_2.to_vertical_mirror() == TEST_MIRROR_R2_VM); + static_assert(mirror_2.to_horizontal_mirror() == TEST_MIRROR_R2_HM); +} + TEST(RawCode, initialize) { - auto raw_code = RawCode::unsafe_create(TEST_R_CODE); - auto common_code = CommonCode::unsafe_create(TEST_C_CODE); + const auto raw_code = RawCode::unsafe_create(TEST_R_CODE); + const auto common_code = CommonCode::unsafe_create(TEST_C_CODE); // operator= - auto r1 = raw_code; - auto r2 = RawCode {raw_code}; + const auto r1 = raw_code; + const auto r2 = RawCode {raw_code}; EXPECT_EQ(r1, TEST_R_CODE); // l-value EXPECT_EQ(r2, TEST_R_CODE); // r-value @@ -154,26 +195,27 @@ TEST(RawCode, code_mirror) { } TEST(RawCode, DISABLED_global_verify) { - // convert to RawCode and ignore errors - static auto force_convert = +[](uint64_t common_code) -> uint64_t { + // convert CommonCode to RawCode and ignore errors + static const auto force_convert = +[](const uint64_t common_code) -> uint64_t { auto range = range_reverse(static_cast(common_code)); - auto raw_code = K_MASK_2x2 << (common_code >> 32) * 3; + auto raw_code = K_MASK_2x2 << (common_code >> 32) * 3; // block 2x2 for (int addr = 0; range; range >>= 2) { while ((raw_code >> addr) & 0b111 && addr < 60) // found next space addr += 3; if (addr >= 60) // invalid address return 0; switch (range & 0b11) { - case 0b01: raw_code |= K_MASK_1x2 << addr; break; - case 0b10: raw_code |= K_MASK_2x1 << addr; break; - case 0b11: raw_code |= K_MASK_1x1 << addr; break; - case 0b00: addr += 3; + case 0b01: raw_code |= K_MASK_1x2 << addr; addr += 6; continue; + case 0b10: raw_code |= K_MASK_2x1 << addr; addr += 3; continue; + case 0b11: raw_code |= K_MASK_1x1 << addr; addr += 3; continue; + case 0b00: addr += 3; continue; + default: std::unreachable(); } } return raw_code; }; - const auto result = SCOPE_PARALLEL(0x10'0000'0000ULL, [](uint64_t start, uint64_t end) { + const auto result = SCOPE_PARALLEL(0x10'0000'0000ULL, [](const uint64_t start, const uint64_t end) { std::vector codes; for (uint64_t common_code = start; common_code < end; ++common_code) { if (RawCode::check(force_convert(common_code))) {