Browse Source

update: split CaseInfo class from GroupCases

master
Dnomd343 2 weeks ago
parent
commit
6dcc88b171
  1. 77
      src/core/group/group.h
  2. 37
      src/core/group/internal/case_info.inl
  3. 6
      src/core/group/internal/group.inl
  4. 8
      src/core/group/internal/group_cases.cc
  5. 34
      src/core/group/internal/group_cases.inl

77
src/core/group/group.h

@ -255,49 +255,62 @@ private:
Toward toward_;
uint32_t pattern_id_;
Group(uint32_t type_id, uint32_t pattern_id, Toward toward) {
type_id_ = type_id;
pattern_id_ = pattern_id;
toward_ = toward;
}
/// Tiled merge of type_id and pattern_id.
[[nodiscard]] constexpr uint32_t flat_id() const;
};
/// Spawn all the unsorted codes of the current group.
std::vector<codec::RawCode> Group_extend(codec::RawCode raw_code, uint32_t reserve = 0);
/// Hidden constructor called from unsafe_create.
constexpr Group(uint32_t type_id, uint32_t pattern_id, Toward toward);
class GroupCases {
public:
// ------------------------------------------------------------------------------------- //
};
// TODO: move to `::klotski::group::CaseInfo`
class CaseInfo {
public:
CaseInfo() = delete;
// ------------------------------------------------------------------------------------- //
/// Get the original group.
[[nodiscard]] constexpr Group group() const;
/// Get the original case id.
[[nodiscard]] constexpr uint32_t case_id() const;
static CaseInfo unsafe_create(Group group, uint32_t case_id);
/// Get the string form of current case.
[[nodiscard]] constexpr std::string to_string() const;
// ------------------------------------------------------------------------------------- //
CaseInfo() = delete;
/// Create CaseInfo without any check.
static constexpr CaseInfo unsafe_create(Group group, uint32_t case_id);
static std::optional<CaseInfo> create(Group group, uint32_t case_id);
/// Create CaseInfo with validity check.
static constexpr std::optional<CaseInfo> create(Group group, uint32_t case_id);
[[nodiscard]] std::string to_string() const;
// ------------------------------------------------------------------------------------- //
#ifndef KLSK_NDEBUG
/// Output case info only for debug.
friend std::ostream& operator<<(std::ostream &out, CaseInfo self);
#endif
private:
CaseInfo(Group group, uint32_t case_id) : group_(group), case_id_(case_id) {}
/// Compare the internal values of two CaseInfo.
friend constexpr auto operator==(const CaseInfo &lhs, const CaseInfo &rhs);
// ------------------------------------------------------------------------------------- //
private:
Group group_;
uint32_t case_id_;
/// Hidden constructor called from unsafe_create.
constexpr CaseInfo(Group group, uint32_t case_id);
// ------------------------------------------------------------------------------------- //
};
class GroupCases {
public:
// ------------------------------------------------------------------------------------- //
/// Execute the build process.
@ -308,15 +321,17 @@ public:
// ------------------------------------------------------------------------------------- //
/// Get the CommonCode from CaseInfo.
static codec::CommonCode obtain_code(CaseInfo info);
/// Get the Group which ShortCode is located.
static Group obtain_group(codec::ShortCode short_code);
/// Get the Group which CommonCode is located.
static Group obtain_group(codec::CommonCode common_code);
// ------------------------------------------------------------------------------------- //
/// Get the CommonCode from CaseInfo.
static codec::CommonCode obtain_code(CaseInfo info);
/// Get the CaseInfo corresponding to the ShortCode.
static CaseInfo obtain_info(codec::ShortCode short_code);
@ -364,14 +379,17 @@ private:
// ------------------------------------------------------------------------------------- //
};
/// Spawn all the unsorted codes of the current group.
std::vector<codec::RawCode> Group_extend(codec::RawCode raw_code, uint32_t reserve = 0);
static_assert(std::is_standard_layout_v<Group>);
static_assert(std::is_trivially_copyable_v<Group>);
static_assert(std::is_standard_layout_v<GroupUnion>);
static_assert(std::is_trivially_copyable_v<GroupUnion>);
static_assert(std::is_standard_layout_v<GroupCases::CaseInfo>);
static_assert(std::is_trivially_copyable_v<GroupCases::CaseInfo>);
static_assert(std::is_standard_layout_v<CaseInfo>);
static_assert(std::is_trivially_copyable_v<CaseInfo>);
} // namespace klotski::group
@ -379,9 +397,12 @@ static_assert(std::is_trivially_copyable_v<GroupCases::CaseInfo>);
#include "internal/group_union.inl"
#include "internal/group_cases.inl"
#include "internal/group.inl"
#include "internal/case_info.inl"
// ----------------------------------------------------------------------------------------- //
// TODO: move to `hash.inl`
namespace std {
template <>
@ -401,6 +422,16 @@ struct std::hash<klotski::group::GroupUnion> {
// TODO: add `std::hash` for CaseInfo
template <>
struct std::hash<klotski::group::CaseInfo> {
constexpr std::size_t operator()(const klotski::group::CaseInfo &info) const noexcept {
// TODO: perf hash alg
const auto h1 = std::hash<klotski::group::Group>{}(info.group());
const auto h2 = std::hash<uint32_t>{}(info.case_id());
return h1 ^ h2;
}
};
} // namespace std
// ----------------------------------------------------------------------------------------- //

37
src/core/group/internal/case_info.inl

@ -0,0 +1,37 @@
#pragma once
#include <format>
namespace klotski::group {
inline std::ostream& operator<<(std::ostream &out, CaseInfo self) {
out << self.to_string();
return out;
}
constexpr std::string CaseInfo::to_string() const {
return std::format("{}-{}", group_.to_string(), case_id_);
}
constexpr Group CaseInfo::group() const {
return group_;
}
constexpr uint32_t CaseInfo::case_id() const {
return case_id_;
}
constexpr std::optional<CaseInfo> CaseInfo::create(Group group, uint32_t case_id) {
if (case_id >= group.size()) {
return std::nullopt;
}
return unsafe_create(group, case_id);
}
constexpr CaseInfo CaseInfo::unsafe_create(Group group, uint32_t case_id) {
return {group, case_id};
}
constexpr CaseInfo::CaseInfo(Group group, uint32_t case_id) : group_(group), case_id_(case_id) {}
} // namespace klotski::group

6
src/core/group/internal/group.inl

@ -178,4 +178,10 @@ constexpr Group Group::to_horizontal_mirror() const {
}
}
constexpr Group::Group(uint32_t type_id, uint32_t pattern_id, Toward toward) {
type_id_ = type_id;
pattern_id_ = pattern_id;
toward_ = toward;
}
} // namespace klotski::group

8
src/core/group/internal/group_cases.cc

@ -12,6 +12,8 @@ using klotski::group::GroupCases;
using klotski::group::GroupUnion;
using klotski::cases::RangesUnion;
using klotski::group::CaseInfo;
using klotski::group::ALL_GROUP_NUM;
using klotski::group::TYPE_ID_LIMIT;
using klotski::cases::ALL_CASES_NUM_;
@ -123,7 +125,7 @@ CommonCode GroupCases::fast_obtain_code(CaseInfo info) {
return CommonCode::unsafe_create(head << 32 | range);
}
GroupCases::CaseInfo GroupCases::fast_obtain_info(ShortCode short_code) {
CaseInfo GroupCases::fast_obtain_info(ShortCode short_code) {
uint16_t type_id = GroupUnion::from_short_code(short_code).unwrap(); // NOTE: need to convert as CommonCode
uint16_t pattern_id = (*rev_data)[short_code.unwrap()].pattern_id;
uint16_t toward_id = (*rev_data)[short_code.unwrap()].toward_id;
@ -133,7 +135,7 @@ GroupCases::CaseInfo GroupCases::fast_obtain_info(ShortCode short_code) {
return CaseInfo::unsafe_create(group, case_id);
}
GroupCases::CaseInfo GroupCases::fast_obtain_info(CommonCode common_code) {
CaseInfo GroupCases::fast_obtain_info(CommonCode common_code) {
auto short_code = common_code.to_short_code();
uint16_t type_id = GroupUnion::from_common_code(common_code).unwrap();
uint16_t pattern_id = (*rev_data)[short_code.unwrap()].pattern_id;
@ -193,7 +195,7 @@ static std::unordered_map<uint64_t, Group> build_map_data() {
return data;
}
GroupCases::CaseInfo GroupCases::tiny_obtain_info(CommonCode common_code) {
CaseInfo GroupCases::tiny_obtain_info(CommonCode common_code) {
auto raw_codes = Group_extend(common_code.to_raw_code());
std::vector<CommonCode> common_codes;
common_codes.reserve(raw_codes.size());

34
src/core/group/internal/group_cases.inl

@ -1,37 +1,7 @@
#pragma once
#include <format>
namespace klotski::group {
inline std::ostream& operator<<(std::ostream &out, GroupCases::CaseInfo self) {
out << self.to_string();
return out;
}
inline std::string GroupCases::CaseInfo::to_string() const {
return std::format("{}-{}", group_.to_string(), case_id_);
}
constexpr Group GroupCases::CaseInfo::group() const {
return group_;
}
constexpr uint32_t GroupCases::CaseInfo::case_id() const {
return case_id_;
}
inline std::optional<GroupCases::CaseInfo> GroupCases::CaseInfo::create(klotski::group::Group group, uint32_t case_id) {
if (case_id >= group.size()) {
return std::nullopt;
}
return unsafe_create(group, case_id);
}
inline GroupCases::CaseInfo GroupCases::CaseInfo::unsafe_create(klotski::group::Group group, uint32_t case_id) {
return {group, case_id};
}
inline codec::CommonCode GroupCases::obtain_code(CaseInfo info) {
if (fast_) {
return fast_obtain_code(info);
@ -39,7 +9,7 @@ inline codec::CommonCode GroupCases::obtain_code(CaseInfo info) {
return tiny_obtain_code(info);
}
inline GroupCases::CaseInfo GroupCases::obtain_info(codec::CommonCode common_code) {
inline CaseInfo GroupCases::obtain_info(codec::CommonCode common_code) {
if (fast_) {
return fast_obtain_info(common_code);
}
@ -60,7 +30,7 @@ inline Group GroupCases::obtain_group(codec::ShortCode short_code) {
return Group::from_short_code(short_code);
}
inline GroupCases::CaseInfo GroupCases::obtain_info(codec::ShortCode short_code) {
inline CaseInfo GroupCases::obtain_info(codec::ShortCode short_code) {
if (fast_) {
return fast_obtain_info(short_code);
}

Loading…
Cancel
Save