cleanup type_id

This commit is contained in:
BlackMATov
2023-03-14 03:55:20 +07:00
parent b5919660c6
commit 8c898d7170
3 changed files with 98 additions and 14 deletions

View File

@@ -2457,21 +2457,43 @@ namespace meta_hpp
public:
type_id() = default;
explicit type_id(std::uintptr_t id)
: id_{id} {}
[[nodiscard]] bool is_valid() const noexcept {
return data_ != nullptr;
}
[[nodiscard]] explicit operator bool() const noexcept {
return is_valid();
}
void swap(type_id& other) noexcept {
std::swap(id_, other.id_);
std::swap(data_, other.data_);
}
[[nodiscard]] std::size_t get_hash() const noexcept {
return detail::hash_combiner{}(id_);
return data_ != nullptr ? detail::hash_combiner{}(data_) : 0;
}
[[nodiscard]] std::strong_ordering operator<=>(const type_id& other) const = default;
private:
std::uintptr_t id_{};
template < detail::type_family T >
friend class type_base;
explicit type_id(const detail::type_data_base* data)
: data_{data} {}
private:
const detail::type_data_base* data_{};
};
}
namespace std
{
template <>
struct hash<meta_hpp::type_id> {
size_t operator()(const meta_hpp::type_id& id) const noexcept {
return id.get_hash();
}
};
}
@@ -2505,8 +2527,7 @@ namespace meta_hpp
}
[[nodiscard]] id_type get_id() const noexcept {
// NOLINTNEXTLINE(*-reinterpret-cast)
return id_type{reinterpret_cast<std::uintptr_t>(data_)};
return id_type{data_};
}
[[nodiscard]] type_kind get_kind() const noexcept {

View File

@@ -0,0 +1,42 @@
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021-2023, by Matvey Cherevko (blackmatov@gmail.com)
******************************************************************************/
#include <meta.hpp/meta_all.hpp>
#include <doctest/doctest.h>
TEST_CASE("meta/meta_types/type_id") {
namespace meta = meta_hpp;
SUBCASE("ctors/0") {
const meta::type_id id;
CHECK_FALSE(id);
CHECK_FALSE(id.is_valid());
}
SUBCASE("ctors/1") {
const meta::type_id int_id = meta::resolve_type<int>().get_id();
const meta::type_id float_id = meta::resolve_type<float>().get_id();
REQUIRE(int_id);
REQUIRE(float_id);
CHECK_FALSE(int_id == float_id);
CHECK(int_id != float_id);
CHECK((int_id < float_id || (float_id < int_id)));
}
SUBCASE("get_hash") {
const meta::type_id int_id = meta::resolve_type<int>().get_id();
const meta::type_id float_id = meta::resolve_type<float>().get_id();
REQUIRE(int_id);
REQUIRE(float_id);
CHECK(meta::type_id{}.get_hash() == 0);
CHECK_FALSE(int_id.get_hash() == float_id.get_hash());
CHECK(int_id.get_hash() == meta::resolve_type<int>().get_id().get_hash());
}
}

View File

@@ -52,21 +52,43 @@ namespace meta_hpp
public:
type_id() = default;
explicit type_id(std::uintptr_t id)
: id_{id} {}
[[nodiscard]] bool is_valid() const noexcept {
return data_ != nullptr;
}
[[nodiscard]] explicit operator bool() const noexcept {
return is_valid();
}
void swap(type_id& other) noexcept {
std::swap(id_, other.id_);
std::swap(data_, other.data_);
}
[[nodiscard]] std::size_t get_hash() const noexcept {
return detail::hash_combiner{}(id_);
return data_ != nullptr ? detail::hash_combiner{}(data_) : 0;
}
[[nodiscard]] std::strong_ordering operator<=>(const type_id& other) const = default;
private:
std::uintptr_t id_{};
template < detail::type_family T >
friend class type_base;
explicit type_id(const detail::type_data_base* data)
: data_{data} {}
private:
const detail::type_data_base* data_{};
};
}
namespace std
{
template <>
struct hash<meta_hpp::type_id> {
size_t operator()(const meta_hpp::type_id& id) const noexcept {
return id.get_hash();
}
};
}
@@ -100,8 +122,7 @@ namespace meta_hpp
}
[[nodiscard]] id_type get_id() const noexcept {
// NOLINTNEXTLINE(*-reinterpret-cast)
return id_type{reinterpret_cast<std::uintptr_t>(data_)};
return id_type{data_};
}
[[nodiscard]] type_kind get_kind() const noexcept {