diff --git a/CMakeLists.txt b/CMakeLists.txt index c1a68cc..7fa7c21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() -add_compile_options(-Wall -Wextra) +add_compile_options(-Wall -Wextra -g) # TODO: enabled by LTO option if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b95cbb5..6cd7662 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -38,6 +38,7 @@ add_library(klotski::core ALIAS klotski_core) if (KLSK_DEV_MODE) add_executable(klotski_core_bin main.cc) + target_compile_options(klotski_core_bin PRIVATE -fno-rtti -fno-exceptions) target_link_libraries(klotski_core_bin PRIVATE klotski::core) endif() diff --git a/src/core/group/group.h b/src/core/group/group.h index 240e2db..761d2ff 100644 --- a/src/core/group/group.h +++ b/src/core/group/group.h @@ -150,9 +150,12 @@ #pragma once -#include "raw_code/raw_code.h" -#include "short_code/short_code.h" -#include "common_code/common_code.h" +#include + +#include "ranges/ranges_fwd.h" +#include "raw_code/raw_code_fwd.h" +#include "short_code/short_code_fwd.h" +#include "common_code/common_code_fwd.h" #include "internal/constant/group.h" #include "internal/constant/group_union.h" @@ -195,13 +198,13 @@ public: using Groups = std::vector; /// Get all groups under the current type id. - [[nodiscard]] constexpr Groups groups() const; // TODO: constexpr not support `std::vector` + [[nodiscard]] Groups groups() const; /// Get all klotski cases under the current type id. [[nodiscard]] cases::RangesUnion cases() const; /// Get the group instance with the specified pattern id. - [[nodiscard]] constexpr std::optional groups(uint_least16_t pattern_id) const; + [[nodiscard]] std::optional groups(uint_least16_t pattern_id) const; // ------------------------------------------------------------------------------------- // @@ -240,23 +243,21 @@ private: // ------------------------------------------------------------------------------------- // }; -// TODO: using macro for all likely-class - +static_assert(sizeof(GroupUnion) == 1); static_assert(std::is_standard_layout_v); static_assert(std::is_trivially_copyable_v); -static_assert(!std::is_default_constructible_v); -static_assert(std::is_trivially_destructible_v); -static_assert(std::is_nothrow_destructible_v); +static_assert(std::has_unique_object_representations_v); -static_assert(std::is_nothrow_copy_assignable_v); -static_assert(std::is_nothrow_move_assignable_v); -static_assert(std::is_nothrow_copy_constructible_v); -static_assert(std::is_nothrow_move_constructible_v); +} // namespace klotski::group -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); +template <> +struct std::hash { + constexpr std::size_t operator()(const klotski::group::GroupUnion &gu) const noexcept { + return std::hash{}(gu.unwrap()); + } +}; + +namespace klotski::group { class Group { public: @@ -274,7 +275,7 @@ public: Horizontal = 1, // horizontal self-symmetry Centro = 2, // centrosymmetric Vertical = 3, // vertical self-symmetry - Ordinary = 4, // non self-symmetric + Ordinary = 4, // non-self-symmetric }; // ------------------------------------------------------------------------------------- // @@ -342,7 +343,7 @@ public: // ------------------------------------------------------------------------------------- // /// Get the group in string form. - [[nodiscard]] std::string to_string() const; + [[nodiscard]] KLSK_INLINE std::string to_string() const; #ifndef KLSK_NDEBUG /// Output group info only for debug. @@ -368,8 +369,21 @@ private: // ------------------------------------------------------------------------------------- // }; +static_assert(sizeof(Group) == 4); static_assert(std::is_standard_layout_v); static_assert(std::is_trivially_copyable_v); +static_assert(std::has_unique_object_representations_v); + +} // namespace klotski::group + +template <> +struct std::hash { + constexpr std::size_t operator()(const klotski::group::Group &g) const noexcept { + return std::hash{}(std::bit_cast(g)); + } +}; + +namespace klotski::group { class CaseInfo { public: @@ -394,7 +408,7 @@ public: // ------------------------------------------------------------------------------------- // /// Get case info in string form. - [[nodiscard]] std::string to_string() const; + [[nodiscard]] KLSK_INLINE std::string to_string() const; #ifndef KLSK_NDEBUG /// Output case info only for debug. @@ -416,8 +430,21 @@ private: // ------------------------------------------------------------------------------------- // }; +static_assert(sizeof(CaseInfo) == 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::group + +template <> +struct std::hash { + constexpr std::size_t operator()(const klotski::group::CaseInfo &info) const noexcept { + return std::hash{}(std::bit_cast(info)); + } +}; + +namespace klotski::group { class GroupCases { public: @@ -491,12 +518,10 @@ private: } // namespace klotski::group -#include "internal/type_id.inl" -#include "internal/group_union.inl" - #include "internal/group.inl" -#include "internal/group_mirror.inl" - #include "internal/group_cases.inl" +#include "internal/group_union.inl" + +#include "internal/mirror.inl" +#include "internal/type_id.inl" #include "internal/case_info.inl" -#include "internal/hash.inl" diff --git a/src/core/group/group_fwd.h b/src/core/group/group_fwd.h new file mode 100644 index 0000000..ffb1c21 --- /dev/null +++ b/src/core/group/group_fwd.h @@ -0,0 +1,15 @@ +/// Klotski Engine by Dnomd343 @2024 + +#pragma once + +#include "internal/constant/group.h" +#include "internal/constant/group_union.h" + +namespace klotski::group { + +class Group; +class CaseInfo; +class GroupCases; +class GroupUnion; + +} // namespace klotski::group diff --git a/src/core/group/internal/case_info.inl b/src/core/group/internal/case_info.inl index baf668f..7a1fb86 100644 --- a/src/core/group/internal/case_info.inl +++ b/src/core/group/internal/case_info.inl @@ -4,25 +4,41 @@ namespace klotski::group { -inline std::ostream& operator<<(std::ostream &out, CaseInfo self) { +// ----------------------------------------------------------------------------------------- // + +constexpr Group CaseInfo::group() const { + return group_; +} + +constexpr uint32_t CaseInfo::case_id() const { + return case_id_; +} + +// ----------------------------------------------------------------------------------------- // + +KLSK_INLINE_H std::string CaseInfo::to_string() const { + // TODO: benchmark of format `{}-{}{}-{}` + return std::format("{}-{}", group_.to_string(), case_id_); +} + +#ifndef KLSK_NDEBUG +inline std::ostream& operator<<(std::ostream &out, const CaseInfo self) { out << self.to_string(); return out; } +#endif constexpr auto operator==(const CaseInfo &lhs, const CaseInfo &rhs) { return lhs.group_ == rhs.group_ && lhs.case_id_ == rhs.case_id_; } -inline std::string CaseInfo::to_string() const { - return std::format("{}-{}", group_.to_string(), case_id_); -} +// ----------------------------------------------------------------------------------------- // -constexpr Group CaseInfo::group() const { - return group_; -} +constexpr CaseInfo::CaseInfo(const Group group, const uint32_t case_id) + : group_(group), case_id_(case_id) {} -constexpr uint32_t CaseInfo::case_id() const { - return case_id_; +constexpr CaseInfo CaseInfo::unsafe_create(const Group group, const uint32_t case_id) { + return {group, case_id}; } constexpr std::optional CaseInfo::create(const Group group, const uint32_t case_id) { @@ -32,10 +48,6 @@ constexpr std::optional CaseInfo::create(const Group group, const uint return unsafe_create(group, case_id); } -constexpr CaseInfo CaseInfo::unsafe_create(const Group group, const uint32_t case_id) { - return {group, case_id}; -} - -constexpr CaseInfo::CaseInfo(const Group group, const uint32_t case_id) : group_(group), case_id_(case_id) {} +// ----------------------------------------------------------------------------------------- // } // namespace klotski::group diff --git a/src/core/group/internal/constant/group.h b/src/core/group/internal/constant/group.h index e428a61..df98557 100644 --- a/src/core/group/internal/constant/group.h +++ b/src/core/group/internal/constant/group.h @@ -4,14 +4,21 @@ namespace klotski::group { -// seed(36) + size(20) + type(3) - +/// Properties of all patterns as follows: +/// (H) 5-bit ~ Padding for u64. +/// 36-bit ~ The seed of the group with the Toward::A. +/// 20-bit ~ The number of cases in the included groups. +/// (L) 3-bit ~ MirrorType enumeration of the included groups. constexpr auto PATTERN_DATA = std::to_array({ #include "pattern.inc" }); -// seed(36) + type_id(8) + pattern_id(10) + toward(2) - +/// Properties of all groups as follows: +/// (H) 8-bit ~ Padding for u64. +/// 36-bit ~ The seed of current group. +/// 8-bit ~ The type_id of current group. +/// 10-bit ~ The pattern_id of current group. +/// (L) 2-bit ~ Toward enumeration of current group. constexpr auto GROUP_DATA = std::to_array({ #include "group.inc" }); diff --git a/src/core/group/internal/constant/group_union.h b/src/core/group/internal/constant/group_union.h index 168be1e..7015d29 100644 --- a/src/core/group/internal/constant/group_union.h +++ b/src/core/group/internal/constant/group_union.h @@ -7,8 +7,6 @@ namespace klotski::group { constexpr uint32_t TYPE_ID_LIMIT = 203; -constexpr uint32_t ALL_GROUP_NUM = 25422; // TODO: from GROUP_NUM -constexpr uint32_t ALL_PATTERN_NUM = 6577; // TODO: from PATTERN_NUM /// The number of groups contained in GroupUnion. constexpr auto GROUP_NUM = std::to_array({ @@ -27,8 +25,11 @@ constexpr auto GROUP_NUM = std::to_array({ 214, 6 , 18 , 54 , 2 , 44 , 40 , 124 , 84 , 70 , 18 , }); +constexpr uint32_t ALL_GROUP_NUM = array_sum(GROUP_NUM); + constexpr auto GROUP_OFFSET = to_offset(GROUP_NUM); +/// The number of patterns contained in GroupUnion. constexpr auto PATTERN_NUM = std::to_array({ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 4 , 1 , 1 , 1 , 1 , @@ -45,7 +46,9 @@ constexpr auto PATTERN_NUM = std::to_array({ 58, 2 , 6 , 15 , 1 , 11 , 12, 31 , 24 , 19 , 6 , }); -const auto PATTERN_OFFSET = to_offset(PATTERN_NUM); +constexpr uint32_t ALL_PATTERN_NUM = array_sum(PATTERN_NUM); + +constexpr auto PATTERN_OFFSET = to_offset(PATTERN_NUM); /// The maximum Group size in each GroupUnion. constexpr auto MAX_GROUP_SIZE = std::to_array({ @@ -119,7 +122,7 @@ constexpr auto BLOCK_NUM = std::to_array>( {7, 4, 0 }, {7, 5, 0 }, {7, 6, 0 }, }); -/// The number of cases with different heads in GroupUnion. +/// The number of cases with different heads in GroupUnion. (0/2/12/14, 1/13, 4/6/8/10, 5/9) constexpr auto GROUP_UNION_CASES_NUM = std::to_array>({ {1 , 1 , 1 , 1 }, {16 , 16 , 16 , 16 }, {120 , 120 , 120 , 120 }, {560 , 560 , 560 , 560 }, {1820 , 1820 , 1820 , 1820 }, {4368 , 4368 , 4368 , 4368 }, diff --git a/src/core/group/internal/group.inl b/src/core/group/internal/group.inl index fbb8883..c35e9db 100644 --- a/src/core/group/internal/group.inl +++ b/src/core/group/internal/group.inl @@ -2,12 +2,23 @@ #include -#include "constant/group.h" +#include "short_code/short_code.h" +#include "common_code/common_code.h" namespace klotski::group { // ----------------------------------------------------------------------------------------- // +constexpr uint32_t Group::flat_id() const { + return PATTERN_OFFSET[type_id_] + pattern_id_; +} + +constexpr uint32_t Group::size() const { + return (PATTERN_DATA[flat_id()] >> 3) & 0xFFFFF; +} + +// ----------------------------------------------------------------------------------------- // + constexpr auto Group::toward() const -> Toward { return toward_; } @@ -24,11 +35,11 @@ constexpr char Group::toward_char() const { // TODO: select chars from pre-build std::array switch (mirror_type()) { case MirrorType::Full: - return '\0'; + return 'x'; case MirrorType::Horizontal: return (toward_ == Toward::A) ? 'n' : 'u'; case MirrorType::Centro: - return (toward_ == Toward::A) ? 'h' : 's'; + return (toward_ == Toward::A) ? 's' : 'o'; case MirrorType::Vertical: return (toward_ == Toward::A) ? 'p' : 'q'; case MirrorType::Ordinary: @@ -50,6 +61,16 @@ constexpr char Group::toward_char() const { // ----------------------------------------------------------------------------------------- // +inline Group Group::from_short_code(const codec::ShortCode short_code) { + return from_common_code(short_code.to_common_code()); +} + +inline Group Group::from_common_code(const codec::CommonCode common_code) { + return from_raw_code(common_code.to_raw_code()); +} + +// ----------------------------------------------------------------------------------------- // + #ifndef KLSK_NDEBUG inline std::ostream& operator<<(std::ostream &out, const Group self) { out << self.to_string(); @@ -57,12 +78,8 @@ inline std::ostream& operator<<(std::ostream &out, const Group self) { } #endif -inline std::string Group::to_string() const { - auto c = toward_char(); - if (c == '\0') { - return std::format("{}-{}", type_id_, pattern_id_); - } - return std::format("{}-{}{}", type_id_, pattern_id_, c); +KLSK_INLINE_H std::string Group::to_string() const { + return std::format("{}-{}{}", type_id_, pattern_id_, toward_char()); } constexpr auto operator==(const Group &lhs, const Group &rhs) { @@ -71,18 +88,27 @@ constexpr auto operator==(const Group &lhs, const Group &rhs) { && lhs.pattern_id_ == rhs.pattern_id_; } -constexpr Group Group::unsafe_create(const uint_fast8_t type_id, const uint_least16_t pattern_id, const Toward toward) { +// ----------------------------------------------------------------------------------------- // + +constexpr Group::Group(const Toward toward, + const uint_fast8_t type_id, + const uint_least16_t pattern_id) + : toward_(toward), type_id_(type_id), pattern_id_(pattern_id) {} + +constexpr Group Group::unsafe_create(const uint_fast8_t type_id, + const uint_least16_t pattern_id, + const Toward toward) { return {toward, type_id, pattern_id}; } -constexpr std::optional Group::create(const uint_fast8_t type_id, const uint_least16_t pattern_id, const Toward toward) { - if (type_id >= TYPE_ID_LIMIT) { - return std::nullopt; - } - if (pattern_id >= GroupUnion::unsafe_create(type_id).pattern_num()) { +constexpr std::optional Group::create(const uint_fast8_t type_id, + const uint_least16_t pattern_id, + const Toward toward) { + if (type_id >= TYPE_ID_LIMIT || pattern_id >= PATTERN_NUM[type_id]) { return std::nullopt; } + // TODO: perf check process if (toward == Toward::A) { return unsafe_create(type_id, pattern_id, toward); } @@ -122,22 +148,6 @@ constexpr std::optional Group::create(const uint_fast8_t type_id, const u return std::nullopt; // TODO: never reach } -constexpr uint32_t Group::flat_id() const { - return PATTERN_OFFSET[type_id_] + pattern_id_; -} - -constexpr uint32_t Group::size() const { - return (PATTERN_DATA[flat_id()] >> 3) & 0xFFFFF; -} - -inline Group Group::from_short_code(const codec::ShortCode short_code) { - return from_common_code(short_code.to_common_code()); -} - -inline Group Group::from_common_code(const codec::CommonCode common_code) { - return from_raw_code(common_code.to_raw_code()); -} - -constexpr Group::Group(const Toward toward, const uint_fast8_t type_id, const uint_least16_t pattern_id) : toward_(toward), type_id_(type_id), pattern_id_(pattern_id) {} +// ----------------------------------------------------------------------------------------- // } // namespace klotski::group diff --git a/src/core/group/internal/group_cases.inl b/src/core/group/internal/group_cases.inl index c243d8a..a4c75a8 100644 --- a/src/core/group/internal/group_cases.inl +++ b/src/core/group/internal/group_cases.inl @@ -2,18 +2,20 @@ namespace klotski::group { -inline codec::CommonCode GroupCases::obtain_code(CaseInfo info) { +// TODO: maybe move `fast_obtain_*` into `.inl` file + +inline codec::CommonCode GroupCases::obtain_code(const CaseInfo info) { if (fast_) { return fast_obtain_code(info); } return tiny_obtain_code(info); } -inline CaseInfo GroupCases::obtain_info(const codec::CommonCode common_code) { +inline Group GroupCases::obtain_group(const codec::ShortCode short_code) { if (fast_) { - return fast_obtain_info(common_code); + return fast_obtain_group(short_code); } - return tiny_obtain_info(common_code); + return Group::from_short_code(short_code); } inline Group GroupCases::obtain_group(const codec::CommonCode common_code) { @@ -23,18 +25,18 @@ inline Group GroupCases::obtain_group(const codec::CommonCode common_code) { return Group::from_common_code(common_code); } -inline Group GroupCases::obtain_group(const codec::ShortCode short_code) { +inline CaseInfo GroupCases::obtain_info(const codec::ShortCode short_code) { if (fast_) { - return fast_obtain_group(short_code); + return fast_obtain_info(short_code); } - return Group::from_short_code(short_code); + return tiny_obtain_info(short_code.to_common_code()); } -inline CaseInfo GroupCases::obtain_info(const codec::ShortCode short_code) { +inline CaseInfo GroupCases::obtain_info(const codec::CommonCode common_code) { if (fast_) { - return fast_obtain_info(short_code); + return fast_obtain_info(common_code); } - return tiny_obtain_info(short_code.to_common_code()); + return tiny_obtain_info(common_code); } } // namespace klotski::group diff --git a/src/core/group/internal/group_union.cc b/src/core/group/internal/group_union.cc index 6590352..ca96411 100644 --- a/src/core/group/internal/group_union.cc +++ b/src/core/group/internal/group_union.cc @@ -1,5 +1,4 @@ #include "group/group.h" -#include "constant/group_union.h" using klotski::cases::Ranges; using klotski::group::GroupUnion; @@ -8,21 +7,21 @@ using klotski::cases::RangesUnion; using klotski::cases::BASIC_RANGES_NUM; #define RANGE_DERIVE(HEAD) ranges.derive(HEAD, cases.ranges(HEAD)) +#define RANGE_RESERVE(HEAD, SIZE) cases.ranges(HEAD).reserve(SIZE) RangesUnion GroupUnion::cases() const { - auto [n, n_2x1, n_1x1] = BLOCK_NUM[type_id_]; - auto [s_a, s_b, s_c, s_d] = GROUP_UNION_CASES_NUM[type_id_]; - Ranges ranges {}; ranges.reserve(BASIC_RANGES_NUM[type_id_]); + const auto [n, n_2x1, n_1x1] = BLOCK_NUM[type_id_]; ranges.spawn(n, n_2x1, n_1x1); ranges.reverse(); RangesUnion cases; - cases.ranges(0x0).reserve(s_a); cases.ranges(0x1).reserve(s_b); cases.ranges(0x2).reserve(s_a); - cases.ranges(0x4).reserve(s_c); cases.ranges(0x5).reserve(s_d); cases.ranges(0x6).reserve(s_c); - cases.ranges(0x8).reserve(s_c); cases.ranges(0x9).reserve(s_d); cases.ranges(0xA).reserve(s_c); - cases.ranges(0xC).reserve(s_a); cases.ranges(0xD).reserve(s_b); cases.ranges(0xE).reserve(s_a); + const auto [s_a, s_b, s_c, s_d] = GROUP_UNION_CASES_NUM[type_id_]; + RANGE_RESERVE(0x0, s_a); RANGE_RESERVE(0x1, s_b); RANGE_RESERVE(0x2, s_a); + RANGE_RESERVE(0x4, s_c); RANGE_RESERVE(0x5, s_d); RANGE_RESERVE(0x6, s_c); + RANGE_RESERVE(0x8, s_c); RANGE_RESERVE(0x9, s_d); RANGE_RESERVE(0xA, s_c); + RANGE_RESERVE(0xC, s_a); RANGE_RESERVE(0xD, s_b); RANGE_RESERVE(0xE, s_a); RANGE_DERIVE(0x0); RANGE_DERIVE(0x1); RANGE_DERIVE(0x2); RANGE_DERIVE(0x4); RANGE_DERIVE(0x5); RANGE_DERIVE(0x6); diff --git a/src/core/group/internal/group_union.inl b/src/core/group/internal/group_union.inl index 0f9b480..a922b9c 100644 --- a/src/core/group/internal/group_union.inl +++ b/src/core/group/internal/group_union.inl @@ -1,7 +1,10 @@ #pragma once #include -#include // TODO: only for debug output + +#include "raw_code/raw_code.h" +#include "short_code/short_code.h" +#include "common_code/common_code.h" namespace klotski::group { @@ -44,7 +47,7 @@ constexpr std::optional GroupUnion::create(const uint_fast8_t type_i #ifndef KLSK_NDEBUG inline std::ostream& operator<<(std::ostream &out, GroupUnion self) { - out << static_cast(self.type_id_); + out << std::format("{}", self.type_id_); return out; } #endif @@ -69,8 +72,9 @@ constexpr GroupUnion GroupUnion::from_common_code(const codec::CommonCode common // ----------------------------------------------------------------------------------------- // -constexpr auto GroupUnion::groups() const -> Groups { - auto build = [this](size_t offset) { +// TODO: benchmark of force-inline +inline auto GroupUnion::groups() const -> Groups { + auto build = [this](const size_t offset) { const auto raw = GROUP_DATA[offset]; const uint_fast16_t pattern_id = (raw >> 2) & 0x3FF; const auto toward = static_cast(raw & 0b11); @@ -82,12 +86,13 @@ constexpr auto GroupUnion::groups() const -> Groups { | std::ranges::to(); } -constexpr auto GroupUnion::groups(const uint_least16_t pattern_id) const -> std::optional { +// TODO: benchmark of force-inline +inline auto GroupUnion::groups(const uint_least16_t pattern_id) const -> std::optional { if (pattern_id >= pattern_num()) { return std::nullopt; } - auto flat_id = PATTERN_OFFSET[type_id_] + pattern_id; + const auto flat_id = PATTERN_OFFSET[type_id_] + pattern_id; switch (static_cast(PATTERN_DATA[flat_id] & 0b111)) { case Group::MirrorType::Full: return Groups { diff --git a/src/core/group/internal/hash.inl b/src/core/group/internal/hash.inl deleted file mode 100644 index f6655fa..0000000 --- a/src/core/group/internal/hash.inl +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -namespace std { - -template <> -struct hash { - constexpr std::size_t operator()(const klotski::group::Group &g) const noexcept { - // TODO: perf hash alg - return std::hash{}(g.type_id() ^ g.pattern_id() ^ (int)g.toward()); - } -}; - -template <> -struct hash { - constexpr std::size_t operator()(const klotski::group::GroupUnion &gu) const noexcept { - return std::hash{}(gu.unwrap()); - } -}; - -template <> -struct hash { - constexpr std::size_t operator()(const klotski::group::CaseInfo &info) const noexcept { - // TODO: perf hash alg - const auto h1 = std::hash{}(info.group()); - const auto h2 = std::hash{}(info.case_id()); - return h1 ^ h2; - } -}; - -} // namespace std diff --git a/src/core/group/internal/group_mirror.inl b/src/core/group/internal/mirror.inl similarity index 100% rename from src/core/group/internal/group_mirror.inl rename to src/core/group/internal/mirror.inl diff --git a/src/core/group/internal/type_id.inl b/src/core/group/internal/type_id.inl index e0f7f56..31bccfa 100644 --- a/src/core/group/internal/type_id.inl +++ b/src/core/group/internal/type_id.inl @@ -1,5 +1,7 @@ #pragma once +#include "common_code/common_code.h" + namespace klotski::group { KLSK_INLINE_CE uint_fast8_t to_type_id(const int n, const int n_2x1, const int n_1x1) { diff --git a/src/core_test/group/group_union.cc b/src/core_test/group/group_union.cc index 1f04e37..fbc76a7 100644 --- a/src/core_test/group/group_union.cc +++ b/src/core_test/group/group_union.cc @@ -22,6 +22,22 @@ using klotski::group::GroupUnion; using klotski::group::TYPE_ID_LIMIT; using klotski::group::ALL_GROUP_NUM; +static_assert(std::is_standard_layout_v); +static_assert(std::is_trivially_copyable_v); +static_assert(!std::is_default_constructible_v); +static_assert(std::is_trivially_destructible_v); +static_assert(std::is_nothrow_destructible_v); + +static_assert(std::is_nothrow_copy_assignable_v); +static_assert(std::is_nothrow_move_assignable_v); +static_assert(std::is_nothrow_copy_constructible_v); +static_assert(std::is_nothrow_move_constructible_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); + #define EXPECT_REPEAT(R, val) \ EXPECT_FALSE(R.empty()); \ EXPECT_EQ(R.front(), val); \