diff --git a/src/core/benchmark/group.cc b/src/core/benchmark/group.cc index dd7fbbb..5eca71b 100644 --- a/src/core/benchmark/group.cc +++ b/src/core/benchmark/group.cc @@ -253,7 +253,12 @@ static void SpawnGroups(benchmark::State &state) { auto gu = GroupUnion::unsafe_create(169); for (auto _ : state) { - volatile auto kk = gu.groups(); + // volatile auto kk = gu.groups(); + + for (auto pattern_id = 0; pattern_id < gu.pattern_num(); ++pattern_id) { + volatile auto kk = gu.groups(pattern_id); + } + } } diff --git a/src/core/group/group.h b/src/core/group/group.h index 3b5450e..a3f9f17 100644 --- a/src/core/group/group.h +++ b/src/core/group/group.h @@ -70,6 +70,9 @@ #include "short_code/short_code.h" #include "common_code/common_code.h" +#include "internal/constant/group.h" +#include "internal/constant/group_union.h" + namespace klotski::group { class Group; diff --git a/src/core/group/internal/group_union.cc b/src/core/group/internal/group_union.cc index 17a555e..75afa5c 100644 --- a/src/core/group/internal/group_union.cc +++ b/src/core/group/internal/group_union.cc @@ -2,8 +2,6 @@ #include "constant/group_union.h" using klotski::cases::Ranges; -using klotski::codec::RawCode; -using klotski::codec::CommonCode; using klotski::group::GroupUnion; using klotski::cases::RangesUnion; diff --git a/src/core/group/internal/group_union.inl b/src/core/group/internal/group_union.inl index 3f7bbf0..4c351ad 100644 --- a/src/core/group/internal/group_union.inl +++ b/src/core/group/internal/group_union.inl @@ -2,10 +2,6 @@ #include -// TODO: include at group header -#include "constant/group.h" -#include "constant/group_union.h" - namespace klotski::group { // ----------------------------------------------------------------------------------------- // @@ -72,136 +68,50 @@ constexpr GroupUnion GroupUnion::from_common_code(const codec::CommonCode common // ----------------------------------------------------------------------------------------- // -//inline std::vector GroupUnion::groups() const { -// auto build = [this](const uint32_t group_id) { -// return Group::unsafe_create(type_id_, group_id); -// }; -// return std::views::iota(0U, group_num()) -// | std::views::transform(build) -// | std::ranges::to(); -//} - -constexpr std::vector GroupUnion::groups() const { - - // std::vector groups; - // groups.reserve(group_num()); - // for (uint32_t pattern_id = 0; pattern_id < pattern_num(); ++pattern_id) { - // auto group = Group::unsafe_create(type_id_, pattern_id, Group::Toward::A); - // groups.emplace_back(group); - // switch (group.mirror_type()) { - // case Group::MirrorType::Full: - // continue; - // case Group::MirrorType::Horizontal: - // groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::C)); - // break; - // case Group::MirrorType::Centro: - // case Group::MirrorType::Vertical: - // groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::B)); - // break; - // case Group::MirrorType::Ordinary: - // groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::B)); - // groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::C)); - // groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::D)); - // break; - // } - // } - // return groups; - - - // auto build = [this](const uint32_t pattern_id) -> std::vector { - // auto flat_id = PATTERN_OFFSET[type_id_] + pattern_id; - // auto mirror_type = static_cast(PATTERN_DATA[flat_id] & 0b111); - // - // switch (mirror_type) { - // case Group::MirrorType::Full: - // return { - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), - // }; - // case Group::MirrorType::Horizontal: - // return { - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::C), - // }; - // case Group::MirrorType::Centro: - // case Group::MirrorType::Vertical: - // return { - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::B), - // }; - // case Group::MirrorType::Ordinary: - // return { - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::B), - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::C), - // Group::unsafe_create(type_id_, pattern_id, Group::Toward::D), - // }; - // } - // }; - // - // return std::views::iota(0U, pattern_num()) - // | std::views::transform(build) - // | std::views::join - // | std::ranges::to(); - - // std::vector groups; - // groups.reserve(group_num()); - - auto begin = GROUP_OFFSET[type_id_]; - auto end = begin + group_num(); - - auto build = [this](uint32_t kk) { - auto raw = GROUP_DATA[kk]; - uint32_t pattern_id = (raw >> 2) & 0b1111111111; - uint32_t toward = raw & 0b11; - return Group::unsafe_create(type_id_, pattern_id, (Group::Toward)toward); +constexpr auto GroupUnion::groups() const -> Groups { + auto build = [this](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); + return Group::unsafe_create(type_id_, pattern_id, toward); }; - - return std::views::iota(begin, end) | std::views::transform(build) | std::ranges::to(); - - - // auto build = [this](uint64_t raw) { - // uint32_t pattern_id = (raw >> 2) & 0b1111111111; - // uint32_t toward = raw & 0b11; - // return Group::unsafe_create(type_id_, pattern_id, (Group::Toward)toward); - // }; - // return GROUP_DATA | std::views::drop(GROUP_OFFSET[type_id_]) | std::views::take(group_num()) | std::views::transform(build) | std::ranges::to(); - // return std::ranges::subrange(GROUP_DATA.begin() + begin, GROUP_DATA.begin() + begin + group_num()) | std::views::transform(build) | std::ranges::to(); - - // for (auto i = begin; i < end; ++i) { - // auto raw = GROUP_DATA[i]; - // uint32_t pattern_id = (raw >> 2) & 0b1111111111; - // uint32_t toward = raw & 0b11; - // auto group = Group::unsafe_create(type_id_, pattern_id, (Group::Toward)toward); - // groups.emplace_back(group); - // } - // - // return groups; + const auto offset = GROUP_OFFSET[type_id_]; + return std::views::iota(offset, offset + group_num()) + | std::views::transform(build) + | std::ranges::to(); } -constexpr std::optional> GroupUnion::groups(const uint_fast16_t pattern_id) const { +constexpr auto GroupUnion::groups(const uint_fast16_t pattern_id) const -> std::optional { if (pattern_id >= pattern_num()) { return std::nullopt; } - std::vector groups; - auto group = Group::unsafe_create(type_id_, pattern_id, Group::Toward::A); - groups.emplace_back(group); - switch (group.mirror_type()) { + + auto flat_id = PATTERN_OFFSET[type_id_] + pattern_id; + switch (static_cast(PATTERN_DATA[flat_id] & 0b111)) { case Group::MirrorType::Full: - break; + return Groups { + Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), + }; case Group::MirrorType::Horizontal: - groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::C)); - break; + return Groups { + Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), + Group::unsafe_create(type_id_, pattern_id, Group::Toward::C), + }; case Group::MirrorType::Centro: case Group::MirrorType::Vertical: - groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::B)); - break; + return Groups { + Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), + Group::unsafe_create(type_id_, pattern_id, Group::Toward::B), + }; case Group::MirrorType::Ordinary: - groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::B)); - groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::C)); - groups.emplace_back(Group::unsafe_create(type_id_, pattern_id, Group::Toward::D)); - break; + return Groups { + Group::unsafe_create(type_id_, pattern_id, Group::Toward::A), + Group::unsafe_create(type_id_, pattern_id, Group::Toward::B), + Group::unsafe_create(type_id_, pattern_id, Group::Toward::C), + Group::unsafe_create(type_id_, pattern_id, Group::Toward::D), + }; } - return groups; + KLSK_UNREACHABLE; } // ----------------------------------------------------------------------------------------- // diff --git a/src/core/utils/utility.h b/src/core/utils/utility.h index 55933af..64850eb 100644 --- a/src/core/utils/utility.h +++ b/src/core/utils/utility.h @@ -29,6 +29,8 @@ #define KLSK_ASSUME(expr) [[assume(expr)]] #endif +#define KLSK_UNREACHABLE __builtin_unreachable() // TODO: using `std::unreachable` + /// Force function declaration to be inline. #define KLSK_INLINE __attribute__ ((always_inline)) #define KLSK_INLINE_CE KLSK_INLINE constexpr