type info: revised to support opaque type info objects (contains breaking changes)

This commit is contained in:
Michele Caini
2020-09-16 16:08:23 +02:00
parent 0fb244e381
commit 25a073f20b
22 changed files with 171 additions and 163 deletions

View File

@@ -21,7 +21,7 @@ namespace entt {
namespace internal {
struct ENTT_API type_index {
struct ENTT_API type_seq {
[[nodiscard]] static id_type next() ENTT_NOEXCEPT {
static ENTT_MAYBE_ATOMIC(id_type) value{};
return value++;
@@ -56,60 +56,68 @@ template<typename Type>
* @tparam Type Type for which to generate a sequential identifier.
*/
template<typename Type, typename = void>
struct ENTT_API type_index {
struct ENTT_API type_seq {
/**
* @brief Returns the sequential identifier of a given type.
* @return The sequential identifier of a given type.
*/
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const id_type value = internal::type_index::next();
static const id_type value = internal::type_seq::next();
return value;
}
};
/**
* @brief Type info.
* @tparam Type Type for which to generate information.
*/
* @brief Type hash.
* @tparam Type Type for which to generate a hash value.
*/
template<typename Type, typename = void>
struct type_info {
struct type_hash {
/**
* @brief Returns the numeric representation of a given type.
* @return The numeric representation of the given type.
*/
* @brief Returns the numeric representation of a given type.
* @return The numeric representation of the given type.
*/
#if defined ENTT_PRETTY_FUNCTION_CONSTEXPR
[[nodiscard]] static constexpr id_type id() ENTT_NOEXCEPT {
[[nodiscard]] static constexpr id_type value() ENTT_NOEXCEPT {
constexpr auto value = hashed_string::value(ENTT_PRETTY_FUNCTION);
return value;
}
#elif defined ENTT_PRETTY_FUNCTION
[[nodiscard]] static id_type id() ENTT_NOEXCEPT {
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const auto value = hashed_string::value(ENTT_PRETTY_FUNCTION);
return value;
}
#else
[[nodiscard]] static id_type id() ENTT_NOEXCEPT {
return type_index<Type>::value();
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
return type_seq<Type>::value();
}
#endif
};
/**
* @brief Type hash.
* @tparam Type Type for which to generate a name.
*/
template<typename Type, typename = void>
struct type_name {
/**
* @brief Returns the name of a given type.
* @return The name of the given type.
*/
* @brief Returns the name of a given type.
* @return The name of the given type.
*/
#if defined ENTT_PRETTY_FUNCTION_CONSTEXPR
[[nodiscard]] static constexpr std::string_view name() ENTT_NOEXCEPT {
[[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
constexpr auto value = internal::type_name<Type>();
return value;
}
#elif defined ENTT_PRETTY_FUNCTION
[[nodiscard]] static std::string_view name() ENTT_NOEXCEPT {
[[nodiscard]] static std::string_view value() ENTT_NOEXCEPT {
static const auto value = internal::type_name<Type>();
return value;
}
#else
[[nodiscard]] static constexpr std::string_view name() ENTT_NOEXCEPT {
[[nodiscard]] static constexpr std::string_view value() ENTT_NOEXCEPT {
return internal::type_name<Type>();
}
#endif

View File

@@ -43,7 +43,7 @@ class basic_registry {
using traits_type = entt_traits<Entity>;
struct pool_data {
id_type type_id{};
id_type type_hash{};
std::unique_ptr<sparse_set<Entity>> pool{};
void(* erase)(sparse_set<Entity> &, basic_registry &, const Entity);
};
@@ -99,20 +99,20 @@ class basic_registry {
};
struct variable_data {
id_type type_id;
id_type type_hash;
std::unique_ptr<void, void(*)(void *)> value;
};
template<typename Component>
[[nodiscard]] const pool_t<Entity, Component> & assure() const {
const auto index = type_index<Component>::value();
const auto index = type_seq<Component>::value();
if(!(index < pools.size())) {
pools.resize(size_type(index)+1u);
}
if(auto &&pdata = pools[index]; !pdata.pool) {
pdata.type_id = type_info<Component>::id();
pdata.type_hash = type_hash<Component>::value();
pdata.pool.reset(new pool_t<Entity, Component>());
pdata.erase = +[](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
static_cast<pool_t<Entity, Component> &>(cpool).erase(owner, entt);
@@ -1148,12 +1148,12 @@ public:
std::vector<const sparse_set<Entity> *> filter(std::distance(from, to));
std::transform(first, last, component.begin(), [this](const auto ctype) {
const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.pool && pdata.type_id == ctype; });
const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.pool && pdata.type_hash == ctype; });
return it == pools.cend() ? nullptr : it->pool.get();
});
std::transform(from, to, filter.begin(), [this](const auto ctype) {
const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.pool && pdata.type_id == ctype; });
const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.pool && pdata.type_hash == ctype; });
return it == pools.cend() ? nullptr : it->pool.get();
});
@@ -1200,9 +1200,9 @@ public:
if(auto it = std::find_if(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
return gdata.size == size
&& (gdata.owned(type_info<std::decay_t<Owned>>::id()) && ...)
&& (gdata.get(type_info<std::decay_t<Get>>::id()) && ...)
&& (gdata.exclude(type_info<Exclude>::id()) && ...);
&& (gdata.owned(type_hash<std::decay_t<Owned>>::value()) && ...)
&& (gdata.get(type_hash<std::decay_t<Get>>::value()) && ...)
&& (gdata.exclude(type_hash<Exclude>::value()) && ...);
}); it != groups.cend())
{
handler = static_cast<handler_type *>(it->group.get());
@@ -1212,9 +1212,9 @@ public:
group_data candidate = {
size,
{ new handler_type{}, [](void *instance) { delete static_cast<handler_type *>(instance); } },
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<std::decay_t<Owned>>::id()) || ...); },
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<std::decay_t<Get>>::id()) || ...); },
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<Exclude>::id()) || ...); },
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<std::decay_t<Owned>>::value()) || ...); },
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<std::decay_t<Get>>::value()) || ...); },
[]([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_hash<Exclude>::value()) || ...); },
};
handler = static_cast<handler_type *>(candidate.group.get());
@@ -1226,17 +1226,17 @@ public:
groups.push_back(std::move(candidate));
} else {
ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
const auto overlapping = (0u + ... + gdata.owned(type_info<std::decay_t<Owned>>::id()));
const auto sz = overlapping + (0u + ... + gdata.get(type_info<std::decay_t<Get>>::id())) + (0u + ... + gdata.exclude(type_info<Exclude>::id()));
const auto overlapping = (0u + ... + gdata.owned(type_hash<std::decay_t<Owned>>::value()));
const auto sz = overlapping + (0u + ... + gdata.get(type_hash<std::decay_t<Get>>::value())) + (0u + ... + gdata.exclude(type_hash<Exclude>::value()));
return !overlapping || ((sz == size) || (sz == gdata.size));
}));
const auto next = std::find_if_not(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
return !(0u + ... + gdata.owned(type_info<std::decay_t<Owned>>::id())) || (size > gdata.size);
return !(0u + ... + gdata.owned(type_hash<std::decay_t<Owned>>::value())) || (size > gdata.size);
});
const auto prev = std::find_if(std::make_reverse_iterator(next), groups.crend(), [](const auto &gdata) {
return (0u + ... + gdata.owned(type_info<std::decay_t<Owned>>::id()));
return (0u + ... + gdata.owned(type_hash<std::decay_t<Owned>>::value()));
});
maybe_valid_if = (next == groups.cend() ? maybe_valid_if : next->group.get());
@@ -1324,7 +1324,7 @@ public:
*/
template<typename... Component>
[[nodiscard]] bool sortable() const {
return std::none_of(groups.cbegin(), groups.cend(), [](auto &&gdata) { return (gdata.owned(type_info<std::decay_t<Component>>::id()) || ...); });
return std::none_of(groups.cbegin(), groups.cend(), [](auto &&gdata) { return (gdata.owned(type_hash<std::decay_t<Component>>::value()) || ...); });
}
/**
@@ -1338,7 +1338,7 @@ public:
[[nodiscard]] bool sortable(const basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> &) ENTT_NOEXCEPT {
constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
return std::find_if(groups.cbegin(), groups.cend(), [size](const auto &gdata) {
return (0u + ... + gdata.owned(type_info<std::decay_t<Owned>>::id())) && (size < gdata.size);
return (0u + ... + gdata.owned(type_hash<std::decay_t<Owned>>::value())) && (size < gdata.size);
}) == groups.cend();
}
@@ -1448,7 +1448,7 @@ public:
*
* Returned identifiers are those of the components owned by the entity.
*
* @sa type_info
* @sa type_hash
*
* @warning
* It's not specified whether a component attached to or removed from the
@@ -1462,7 +1462,7 @@ public:
void visit(entity_type entity, Func func) const {
for(auto pos = pools.size(); pos; --pos) {
if(const auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->contains(entity)) {
func(pdata.type_id);
func(pdata.type_hash);
}
}
}
@@ -1478,7 +1478,7 @@ public:
*
* Returned identifiers are those of the components managed by the registry.
*
* @sa type_info
* @sa type_hash
*
* @warning
* It's not specified whether a component for which a pool is created during
@@ -1491,7 +1491,7 @@ public:
void visit(Func func) const {
for(auto pos = pools.size(); pos; --pos) {
if(const auto &pdata = pools[pos-1]; pdata.pool) {
func(pdata.type_id);
func(pdata.type_hash);
}
}
}
@@ -1510,7 +1510,7 @@ public:
template<typename Type, typename... Args>
Type & set(Args &&... args) {
unset<Type>();
vars.push_back(variable_data{type_info<Type>::id(), { new Type{std::forward<Args>(args)...}, [](void *instance) { delete static_cast<Type *>(instance); } }});
vars.push_back(variable_data{type_hash<Type>::value(), { new Type{std::forward<Args>(args)...}, [](void *instance) { delete static_cast<Type *>(instance); } }});
return *static_cast<Type *>(vars.back().value.get());
}
@@ -1521,7 +1521,7 @@ public:
template<typename Type>
void unset() {
vars.erase(std::remove_if(vars.begin(), vars.end(), [](auto &&var) {
return var.type_id == type_info<Type>::id();
return var.type_hash == type_hash<Type>::value();
}), vars.end());
}
@@ -1550,7 +1550,7 @@ public:
*/
template<typename Type>
[[nodiscard]] const Type * try_ctx() const {
auto it = std::find_if(vars.cbegin(), vars.cend(), [](auto &&var) { return var.type_id == type_info<Type>::id(); });
auto it = std::find_if(vars.cbegin(), vars.cend(), [](auto &&var) { return var.type_hash == type_hash<Type>::value(); });
return it == vars.cend() ? nullptr : static_cast<const Type *>(it->value.get());
}
@@ -1596,7 +1596,7 @@ public:
*
* Returned identifiers are those of the context variables currently set.
*
* @sa type_info
* @sa type_hash
*
* @warning
* It's not specified whether a context variable created during the visit is
@@ -1608,7 +1608,7 @@ public:
template<typename Func>
void ctx(Func func) const {
for(auto pos = vars.size(); pos; --pos) {
func(vars[pos-1].type_id);
func(vars[pos-1].type_hash);
}
}

View File

@@ -347,7 +347,7 @@ public:
* @param id Optional unique identifier.
* @return An extended meta factory for the given type.
*/
auto type(const id_type id = type_info<Type>::id()) {
auto type(const id_type id = type_hash<Type>::value()) {
auto * const node = internal::meta_info<Type>::resolve();
ENTT_ASSERT(!exists(id, *internal::meta_context::global()));

View File

@@ -260,7 +260,7 @@ struct meta_func_node {
struct meta_type_node {
using size_type = std::size_t;
const id_type type_id;
const id_type type_hash;
id_type id;
meta_type_node * next;
meta_prop_node * prop;
@@ -404,7 +404,7 @@ class ENTT_API meta_node {
public:
[[nodiscard]] static meta_type_node * resolve() ENTT_NOEXCEPT {
static meta_type_node node{
type_info<Type>::id(),
type_hash<Type>::value(),
{},
nullptr,
nullptr,

View File

@@ -342,9 +342,9 @@ public:
template<typename Type>
[[nodiscard]] const Type * try_cast() const {
if(node) {
if(const auto type_id = internal::meta_info<Type>::resolve()->type_id; node->type_id == type_id) {
if(const auto type_hash = internal::meta_info<Type>::resolve()->type_hash; node->type_hash == type_hash) {
return static_cast<const Type *>(storage.data());
} else if(const auto *base = internal::find_if<&internal::meta_type_node::base>([type_id](const auto *curr) { return curr->type()->type_id == type_id; }, node); base) {
} else if(const auto *base = internal::find_if<&internal::meta_type_node::base>([type_hash](const auto *curr) { return curr->type()->type_hash == type_hash; }, node); base) {
return static_cast<const Type *>(base->cast(storage.data()));
}
}
@@ -394,9 +394,9 @@ public:
template<typename Type>
[[nodiscard]] meta_any convert() const {
if(node) {
if(const auto type_id = internal::meta_info<Type>::resolve()->type_id; node->type_id == type_id) {
if(const auto type_hash = internal::meta_info<Type>::resolve()->type_hash; node->type_hash == type_hash) {
return *this;
} else if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([type_id](const auto *curr) { return curr->type()->type_id == type_id; }, node); conv) {
} else if(const auto * const conv = internal::find_if<&internal::meta_type_node::conv>([type_hash](const auto *curr) { return curr->type()->type_hash == type_hash; }, node); conv) {
return conv->conv(storage.data());
}
}
@@ -411,7 +411,7 @@ public:
*/
template<typename Type>
bool convert() {
bool valid = (node && node->type_id == internal::meta_info<Type>::resolve()->type_id);
bool valid = (node && node->type_hash == internal::meta_info<Type>::resolve()->type_hash);
if(!valid) {
if(auto any = std::as_const(*this).convert<Type>(); any) {
@@ -487,7 +487,7 @@ public:
* @return False if the two objects differ in their content, true otherwise.
*/
[[nodiscard]] bool operator==(const meta_any &other) const {
return (!node && !other.node) || (node && other.node && node->type_id == other.node->type_id && node->compare(storage.data(), other.storage.data()));
return (!node && !other.node) || (node && other.node && node->type_hash == other.node->type_hash && node->compare(storage.data(), other.storage.data()));
}
/**
@@ -1010,9 +1010,9 @@ class meta_type {
return std::find_if(range.begin(), range.end(), [](const auto &candidate) {
return candidate.size == sizeof...(Args) && ([](auto *from, auto *to) {
return (from->type_id == to->type_id)
|| internal::find_if<&node_type::base>([to](const auto *curr) { return curr->type()->type_id == to->type_id; }, from)
|| internal::find_if<&node_type::conv>([to](const auto *curr) { return curr->type()->type_id == to->type_id; }, from);
return (from->type_hash == to->type_hash)
|| internal::find_if<&node_type::base>([to](const auto *curr) { return curr->type()->type_hash == to->type_hash; }, from)
|| internal::find_if<&node_type::conv>([to](const auto *curr) { return curr->type()->type_hash == to->type_hash; }, from);
}(internal::meta_info<Args>::resolve(), candidate.arg(Indexes)) && ...);
}).operator->();
}
@@ -1029,11 +1029,11 @@ public:
{}
/**
* @brief Returns the type id of the underlying type.
* @return The type id of the underlying type.
* @brief Returns the type hash of the underlying type.
* @return The type hash of the underlying type.
*/
[[nodiscard]] id_type type_id() const ENTT_NOEXCEPT {
return node->type_id;
[[nodiscard]] id_type hash() const ENTT_NOEXCEPT {
return node->type_hash;
}
/**
@@ -1240,8 +1240,8 @@ public:
*/
template<typename Type>
[[nodiscard]] meta_conv conv() const {
return internal::find_if<&node_type::conv>([type_id = internal::meta_info<Type>::resolve()->type_id](const auto *curr) {
return curr->type()->type_id == type_id;
return internal::find_if<&node_type::conv>([type_hash = internal::meta_info<Type>::resolve()->type_hash](const auto *curr) {
return curr->type()->type_hash == type_hash;
}, node);
}
@@ -1454,7 +1454,7 @@ public:
* otherwise.
*/
[[nodiscard]] bool operator==(const meta_type &other) const ENTT_NOEXCEPT {
return (!node && !other.node) || (node && other.node && node->type_id == other.node->type_id);
return (!node && !other.node) || (node && other.node && node->type_hash == other.node->type_hash);
}
/**

View File

@@ -43,13 +43,13 @@ template<typename Type>
/**
* @brief Returns the meta type associated with a given type id, if any.
* @brief Returns the meta type associated with a given type hash, if any.
* @param id Unique identifier.
* @return The meta type associated with the given type id, if any.
* @return The meta type associated with the given type hash, if any.
*/
[[nodiscard]] inline meta_type resolve_type(const id_type id) ENTT_NOEXCEPT {
internal::meta_range range{*internal::meta_context::global()};
return std::find_if(range.begin(), range.end(), [id](const auto &curr) { return curr.type_id == id; }).operator->();
return std::find_if(range.begin(), range.end(), [id](const auto &curr) { return curr.type_hash == id; }).operator->();
}

View File

@@ -87,7 +87,7 @@ class dispatcher {
template<typename Event>
[[nodiscard]] pool_handler<Event> & assure() {
const auto index = type_index<Event>::value();
const auto index = type_seq<Event>::value();
if(!(index < pools.size())) {
pools.resize(std::size_t(index)+1u);

View File

@@ -123,7 +123,7 @@ class emitter {
template<typename Event>
[[nodiscard]] const pool_handler<Event> & assure() const {
const auto index = type_index<Event>::value();
const auto index = type_seq<Event>::value();
if(!(index < pools.size())) {
pools.resize(std::size_t(index)+1u);

View File

@@ -271,7 +271,7 @@ TEST(Benchmark, IterateSingleComponentRuntime1M) {
}
auto test = [&](auto func) {
entt::id_type types[] = { entt::type_info<position>::id() };
entt::id_type types[] = { entt::type_hash<position>::value() };
timer timer;
registry.runtime_view(std::begin(types), std::end(types)).each(func);
@@ -437,8 +437,8 @@ TEST(Benchmark, IterateTwoComponentsRuntime1M) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value()
};
timer timer;
@@ -468,8 +468,8 @@ TEST(Benchmark, IterateTwoComponentsRuntime1MHalf) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value()
};
timer timer;
@@ -499,8 +499,8 @@ TEST(Benchmark, IterateTwoComponentsRuntime1MOne) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value()
};
timer timer;
@@ -675,9 +675,9 @@ TEST(Benchmark, IterateThreeComponentsRuntime1M) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id(),
entt::type_info<comp<0>>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value(),
entt::type_hash<comp<0>>::value()
};
timer timer;
@@ -709,9 +709,9 @@ TEST(Benchmark, IterateThreeComponentsRuntime1MHalf) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id(),
entt::type_info<comp<0>>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value(),
entt::type_hash<comp<0>>::value()
};
timer timer;
@@ -743,9 +743,9 @@ TEST(Benchmark, IterateThreeComponentsRuntime1MOne) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id(),
entt::type_info<comp<0>>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value(),
entt::type_hash<comp<0>>::value()
};
timer timer;
@@ -961,11 +961,11 @@ TEST(Benchmark, IterateFiveComponentsRuntime1M) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id(),
entt::type_info<comp<0>>::id(),
entt::type_info<comp<1>>::id(),
entt::type_info<comp<2>>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value(),
entt::type_hash<comp<0>>::value(),
entt::type_hash<comp<1>>::value(),
entt::type_hash<comp<2>>::value()
};
timer timer;
@@ -1001,11 +1001,11 @@ TEST(Benchmark, IterateFiveComponentsRuntime1MHalf) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id(),
entt::type_info<comp<0>>::id(),
entt::type_info<comp<1>>::id(),
entt::type_info<comp<2>>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value(),
entt::type_hash<comp<0>>::value(),
entt::type_hash<comp<1>>::value(),
entt::type_hash<comp<2>>::value()
};
timer timer;
@@ -1041,11 +1041,11 @@ TEST(Benchmark, IterateFiveComponentsRuntime1MOne) {
auto test = [&](auto func) {
entt::id_type types[] = {
entt::type_info<position>::id(),
entt::type_info<velocity>::id(),
entt::type_info<comp<0>>::id(),
entt::type_info<comp<1>>::id(),
entt::type_info<comp<2>>::id()
entt::type_hash<position>::value(),
entt::type_hash<velocity>::value(),
entt::type_hash<comp<0>>::value(),
entt::type_hash<comp<1>>::value(),
entt::type_hash<comp<2>>::value()
};
timer timer;

View File

@@ -4,26 +4,26 @@
#include <entt/core/type_info.hpp>
#include <entt/core/type_traits.hpp>
TEST(TypeInfo, Id) {
ASSERT_NE(entt::type_info<int>::id(), entt::type_info<const int>::id());
ASSERT_NE(entt::type_info<int>::id(), entt::type_info<char>::id());
ASSERT_EQ(entt::type_info<int>::id(), entt::type_info<int>::id());
TEST(TypeSeq, Functionalities) {
ASSERT_EQ(entt::type_seq<int>::value(), entt::type_seq<int>::value());
ASSERT_NE(entt::type_seq<int>::value(), entt::type_seq<char>::value());
ASSERT_NE(entt::type_seq<int>::value(), entt::type_seq<int &&>::value());
ASSERT_NE(entt::type_seq<int &>::value(), entt::type_seq<const int &>::value());
}
TEST(TypeInfo, Name) {
ASSERT_EQ(entt::type_info<int>::name(), std::string_view{"int"});
ASSERT_TRUE((entt::type_info<entt::integral_constant<3>>::name() == std::string_view{"std::integral_constant<int, 3>"})
|| (entt::type_info<entt::integral_constant<3>>::name() == std::string_view{"std::__1::integral_constant<int, 3>"})
|| (entt::type_info<entt::integral_constant<3>>::name() == std::string_view{"struct std::integral_constant<int,3>"}));
ASSERT_TRUE(((entt::type_info<entt::type_list<entt::type_list<int, char>, double>>::name()) == std::string_view{"entt::type_list<entt::type_list<int, char>, double>"})
|| ((entt::type_info<entt::type_list<entt::type_list<int, char>, double>>::name()) == std::string_view{"struct entt::type_list<struct entt::type_list<int,char>,double>"}));
TEST(TypeHash, Functionalities) {
ASSERT_NE(entt::type_hash<int>::value(), entt::type_hash<const int>::value());
ASSERT_NE(entt::type_hash<int>::value(), entt::type_hash<char>::value());
ASSERT_EQ(entt::type_hash<int>::value(), entt::type_hash<int>::value());
}
TEST(TypeIndex, Functionalities) {
ASSERT_EQ(entt::type_index<int>::value(), entt::type_index<int>::value());
ASSERT_NE(entt::type_index<int>::value(), entt::type_index<char>::value());
ASSERT_NE(entt::type_index<int>::value(), entt::type_index<int &&>::value());
ASSERT_NE(entt::type_index<int &>::value(), entt::type_index<const int &>::value());
TEST(TypeName, Functionalities) {
ASSERT_EQ(entt::type_name<int>::value(), std::string_view{"int"});
ASSERT_TRUE((entt::type_name<entt::integral_constant<3>>::value() == std::string_view{"std::integral_constant<int, 3>"})
|| (entt::type_name<entt::integral_constant<3>>::value() == std::string_view{"std::__1::integral_constant<int, 3>"})
|| (entt::type_name<entt::integral_constant<3>>::value() == std::string_view{"struct std::integral_constant<int,3>"}));
ASSERT_TRUE(((entt::type_name<entt::type_list<entt::type_list<int, char>, double>>::value()) == std::string_view{"entt::type_list<entt::type_list<int, char>, double>"})
|| ((entt::type_name<entt::type_list<entt::type_list<int, char>, double>>::value()) == std::string_view{"struct entt::type_list<struct entt::type_list<int,char>,double>"}));
}

View File

@@ -67,7 +67,7 @@ TEST(BasicHandle, Component) {
ASSERT_TRUE(registry.empty<char>());
ASSERT_EQ(0u, handle.remove_if_exists<char>());
handle.visit([](auto id) { ASSERT_EQ(entt::type_info<int>::id(), id); });
handle.visit([](auto id) { ASSERT_EQ(entt::type_hash<int>::value(), id); });
ASSERT_TRUE((handle.any<int, char>()));
ASSERT_FALSE((handle.has<int, char>()));

View File

@@ -64,7 +64,7 @@ TEST(Registry, Context) {
auto count = 0;
registry.ctx([&count](const auto var) {
ASSERT_EQ(var, entt::type_info<char>::id());
ASSERT_EQ(var, entt::type_hash<char>::value());
++count;
});
@@ -1436,9 +1436,9 @@ TEST(Registry, Visit) {
bool hasType[3]{};
registry.visit([&hasType](const auto component) {
hasType[0] = hasType[0] || (component == entt::type_info<int>::id());
hasType[1] = hasType[1] || (component == entt::type_info<double>::id());
hasType[2] = hasType[2] || (component == entt::type_info<char>::id());
hasType[0] = hasType[0] || (component == entt::type_hash<int>::value());
hasType[1] = hasType[1] || (component == entt::type_hash<double>::value());
hasType[2] = hasType[2] || (component == entt::type_hash<char>::value());
});
ASSERT_TRUE(hasType[0] && hasType[1] && hasType[2]);
@@ -1446,9 +1446,9 @@ TEST(Registry, Visit) {
hasType[0] = hasType[1] = hasType[2] = false;
registry.visit(entity, [&hasType](const auto component) {
hasType[0] = hasType[0] || (component == entt::type_info<int>::id());
hasType[1] = hasType[1] || (component == entt::type_info<double>::id());
hasType[2] = hasType[2] || (component == entt::type_info<char>::id());
hasType[0] = hasType[0] || (component == entt::type_hash<int>::value());
hasType[1] = hasType[1] || (component == entt::type_hash<double>::value());
hasType[2] = hasType[2] || (component == entt::type_hash<char>::value());
});
ASSERT_TRUE(hasType[0] && !hasType[1] && hasType[2]);
@@ -1456,9 +1456,9 @@ TEST(Registry, Visit) {
hasType[0] = hasType[2] = false;
registry.visit(other, [&hasType](const auto component) {
hasType[0] = hasType[0] || (component == entt::type_info<int>::id());
hasType[1] = hasType[1] || (component == entt::type_info<double>::id());
hasType[2] = hasType[2] || (component == entt::type_info<char>::id());
hasType[0] = hasType[0] || (component == entt::type_hash<int>::value());
hasType[1] = hasType[1] || (component == entt::type_hash<double>::value());
hasType[2] = hasType[2] || (component == entt::type_hash<char>::value());
});
ASSERT_TRUE(!hasType[0] && hasType[1] && !hasType[2]);

View File

@@ -12,7 +12,7 @@ TEST(RuntimeView, Functionalities) {
registry.reserve<int>(0);
registry.reserve<char>(0);
entt::id_type types[] = { entt::type_info<int>::id(), entt::type_info<char>::id() };
entt::id_type types[] = { entt::type_hash<int>::value(), entt::type_hash<char>::value() };
auto view = registry.runtime_view(std::begin(types), std::end(types));
ASSERT_TRUE(view.empty());
@@ -55,7 +55,7 @@ TEST(RuntimeView, Iterator) {
registry.emplace<int>(entity);
registry.emplace<char>(entity);
entt::id_type types[] = { entt::type_info<int>::id(), entt::type_info<char>::id() };
entt::id_type types[] = { entt::type_hash<int>::value(), entt::type_hash<char>::value() };
auto view = registry.runtime_view(std::begin(types), std::end(types));
using iterator = typename decltype(view)::iterator;
@@ -91,7 +91,7 @@ TEST(RuntimeView, Contains) {
registry.destroy(e0);
entt::id_type types[] = { entt::type_info<int>::id(), entt::type_info<char>::id() };
entt::id_type types[] = { entt::type_hash<int>::value(), entt::type_hash<char>::value() };
auto view = registry.runtime_view(std::begin(types), std::end(types));
ASSERT_FALSE(view.contains(e0));
@@ -110,7 +110,7 @@ TEST(RuntimeView, Empty) {
registry.emplace<char>(e1);
registry.emplace<float>(e1);
entt::id_type types[] = { entt::type_info<int>::id(), entt::type_info<char>::id(), entt::type_info<float>::id() };
entt::id_type types[] = { entt::type_hash<int>::value(), entt::type_hash<char>::value(), entt::type_hash<float>::value() };
auto view = registry.runtime_view(std::begin(types), std::end(types));
view.each([](auto) { FAIL(); });
@@ -130,7 +130,7 @@ TEST(RuntimeView, Each) {
registry.emplace<int>(e1);
registry.emplace<char>(e1);
entt::id_type types[] = { entt::type_info<int>::id(), entt::type_info<char>::id() };
entt::id_type types[] = { entt::type_hash<int>::value(), entt::type_hash<char>::value() };
auto view = registry.runtime_view(std::begin(types), std::end(types));
std::size_t cnt = 0;
@@ -152,7 +152,7 @@ TEST(RuntimeView, EachWithHoles) {
registry.emplace<int>(e0, 0);
registry.emplace<int>(e2, 2);
entt::id_type types[] = { entt::type_info<int>::id(), entt::type_info<char>::id() };
entt::id_type types[] = { entt::type_hash<int>::value(), entt::type_hash<char>::value() };
auto view = registry.runtime_view(std::begin(types), std::end(types));
view.each([e0](auto entity) {
@@ -166,7 +166,7 @@ TEST(RuntimeView, MissingPool) {
const auto e0 = registry.create();
registry.emplace<int>(e0);
entt::id_type types[] = { entt::type_info<int>::id(), entt::type_info<char>::id() };
entt::id_type types[] = { entt::type_hash<int>::value(), entt::type_hash<char>::value() };
auto view = registry.runtime_view(std::begin(types), std::end(types));
ASSERT_TRUE(view.empty());
@@ -211,8 +211,8 @@ TEST(RuntimeView, ExcludedComponents) {
registry.emplace<int>(e1);
registry.emplace<char>(e1);
entt::id_type components[] = { entt::type_info<int>::id() };
entt::id_type filter[] = { entt::type_info<char>::id(), entt::type_info<double>::id() };
entt::id_type components[] = { entt::type_hash<int>::value() };
entt::id_type filter[] = { entt::type_hash<char>::value(), entt::type_hash<double>::value() };
auto view = registry.runtime_view(std::begin(components), std::end(components), std::begin(filter), std::end(filter));
ASSERT_FALSE(view.empty());

View File

@@ -20,9 +20,9 @@ TEST_F(MetaRange, Range) {
ASSERT_TRUE(it != range.end());
ASSERT_FALSE(it == range.end());
ASSERT_EQ((*it).type_id(), entt::resolve<double>().type_id());
ASSERT_EQ((*(++it)).type_id(), entt::resolve_id("int"_hs).type_id());
ASSERT_EQ((*it++).type_id(), entt::resolve<int>().type_id());
ASSERT_EQ((*it).hash(), entt::resolve<double>().hash());
ASSERT_EQ((*(++it)).hash(), entt::resolve_id("int"_hs).hash());
ASSERT_EQ((*it++).hash(), entt::resolve<int>().hash());
ASSERT_EQ(it, range.end());
}

View File

@@ -94,7 +94,7 @@ struct MetaType: ::testing::Test {
TEST_F(MetaType, Resolve) {
ASSERT_EQ(entt::resolve<double>(), entt::resolve_id("double"_hs));
ASSERT_EQ(entt::resolve<double>(), entt::resolve_type(entt::type_info<double>::id()));
ASSERT_EQ(entt::resolve<double>(), entt::resolve_type(entt::type_hash<double>::value()));
auto range = entt::resolve();
// it could be "char"_hs rather than entt::hashed_string::value("char") if it weren't for a bug in VS2017
@@ -118,7 +118,7 @@ TEST_F(MetaType, Functionalities) {
ASSERT_TRUE(type);
ASSERT_NE(type, entt::meta_type{});
ASSERT_EQ(type.id(), "clazz"_hs);
ASSERT_EQ(type.type_id(), entt::type_info<clazz_t>::id());
ASSERT_EQ(type.hash(), entt::type_hash<clazz_t>::value());
for(auto curr: type.prop()) {
ASSERT_EQ(curr.key(), property_t::value);
@@ -348,7 +348,7 @@ TEST_F(MetaType, AbstractClass) {
auto type = entt::resolve<abstract_t>();
concrete_t instance;
ASSERT_EQ(type.type_id(), entt::type_info<abstract_t>::id());
ASSERT_EQ(type.hash(), entt::type_hash<abstract_t>::value());
ASSERT_EQ(instance.base_t::value, 'c');
ASSERT_EQ(instance.value, 3);

View File

@@ -8,9 +8,9 @@
#include "types.h"
template<typename Type>
struct entt::type_index<Type> {
struct entt::type_seq<Type> {
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const entt::id_type value = type_context::instance()->value(entt::type_info<Type>::id());
static const entt::id_type value = type_context::instance()->value(entt::type_hash<Type>::value());
return value;
}
};

View File

@@ -7,9 +7,9 @@
inline static type_context *context;
template<typename Type>
struct entt::type_index<Type> {
struct entt::type_seq<Type> {
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const entt::id_type value = context->value(type_info<Type>::id());
static const entt::id_type value = context->value(entt::type_hash<Type>::value());
return value;
}
};

View File

@@ -8,9 +8,9 @@
#include "types.h"
template<typename Type>
struct entt::type_index<Type> {
struct entt::type_seq<Type> {
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const entt::id_type value = type_context::instance()->value(entt::type_info<Type>::id());
static const entt::id_type value = type_context::instance()->value(entt::type_hash<Type>::value());
return value;
}
};

View File

@@ -7,9 +7,9 @@
inline static type_context *context;
template<typename Type>
struct entt::type_index<Type> {
struct entt::type_seq<Type> {
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const entt::id_type value = context->value(type_info<Type>::id());
static const entt::id_type value = context->value(entt::type_hash<Type>::value());
return value;
}
};

View File

@@ -7,18 +7,18 @@
#include <entt/meta/meta.hpp>
template<typename>
struct type_id;
struct custom_type_hash;
#define ASSIGN_TYPE_ID(clazz)\
template<>\
struct type_id<clazz>\
struct custom_type_hash<clazz>\
: std::integral_constant<entt::id_type, entt::basic_hashed_string<std::remove_cv_t<std::remove_pointer_t<std::decay_t<decltype(#clazz)>>>>{#clazz}>\
{}
template<typename Type>
struct entt::type_info<Type> {
static constexpr entt::id_type id() ENTT_NOEXCEPT {
return type_id<Type>::value;
struct entt::type_seq<Type> {
static constexpr entt::id_type value() ENTT_NOEXCEPT {
return custom_type_hash<Type>::value;
}
};

View File

@@ -8,9 +8,9 @@
#include "types.h"
template<typename Type>
struct entt::type_index<Type> {
struct entt::type_seq<Type> {
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const entt::id_type value = type_context::instance()->value(entt::type_info<Type>::id());
static const entt::id_type value = type_context::instance()->value(entt::type_hash<Type>::value());
return value;
}
};

View File

@@ -7,9 +7,9 @@
inline static type_context *context;
template<typename Type>
struct entt::type_index<Type> {
struct entt::type_seq<Type> {
[[nodiscard]] static id_type value() ENTT_NOEXCEPT {
static const entt::id_type value = context->value(type_info<Type>::id());
static const entt::id_type value = context->value(entt::type_hash<Type>::value());
return value;
}
};