diff --git a/src/entt/entity/handle.hpp b/src/entt/entity/handle.hpp index 0e515c557..51ac50115 100644 --- a/src/entt/entity/handle.hpp +++ b/src/entt/entity/handle.hpp @@ -2,6 +2,11 @@ #define ENTT_ENTITY_HANDLE_HPP +#include +#include +#include +#include "../config/config.h" +#include "../core/type_traits.hpp" #include "fwd.hpp" #include "registry.hpp" @@ -52,11 +57,20 @@ struct basic_handle { /** * @brief Constructs a const handle from a non-const one. + * @tparam Other A valid entity type (see entt_traits for more details). + * @tparam Args Scope of the handle to construct. * @return A const handle referring to the same registry and the same * entity. */ - [[nodiscard]] operator basic_handle() const ENTT_NOEXCEPT { - return reg ? basic_handle{*reg, entt} : basic_handle{}; + template + [[nodiscard]] operator basic_handle() const ENTT_NOEXCEPT { + static_assert( + (std::is_same_v || std::is_same_v, Entity>) + && (sizeof...(Type) == 0 || ((sizeof...(Args) != 0 && sizeof...(Args) <= sizeof...(Type)) && ... && (type_list_contains_v, Args>))), + "Invalid conversion between different handles" + ); + + return reg ? basic_handle{*reg, entt} : basic_handle{}; } /** @@ -162,12 +176,8 @@ struct basic_handle { */ template void remove() const { - if constexpr(sizeof...(Type) == 0 || sizeof...(Component) == 1) { - static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v)); - reg->template remove(entt); - } else { - (remove(), ...); - } + static_assert(sizeof...(Type) == 0 || (type_list_contains_v, Component> && ...)); + reg->template remove(entt); } /** @@ -178,12 +188,8 @@ struct basic_handle { */ template decltype(auto) remove_if_exists() const { - if constexpr(sizeof...(Type) == 0 || sizeof...(Component) == 1) { - static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v)); - return reg->template remove_if_exists(entt); - } else { - return (remove_if_exists(), ...); - } + static_assert(sizeof...(Type) == 0 || (type_list_contains_v, Component> && ...)); + return reg->template remove_if_exists(entt); } /** @@ -226,12 +232,8 @@ struct basic_handle { */ template [[nodiscard]] decltype(auto) get() const { - if constexpr(sizeof...(Type) == 0 || sizeof...(Component) == 1) { - static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v)); - return reg->template get(entt); - } else { - return std::forward_as_tuple(get()...); - } + static_assert(sizeof...(Type) == 0 || (type_list_contains_v, Component> && ...)); + return reg->template get(entt); } /** @@ -256,12 +258,8 @@ struct basic_handle { */ template [[nodiscard]] auto try_get() const { - if constexpr(sizeof...(Type) == 0 || sizeof...(Component) == 1) { - static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v)); - return reg->template try_get(entt); - } else { - return std::make_tuple(this->try_get()...); - } + static_assert(sizeof...(Type) == 0 || (type_list_contains_v, Component> && ...)); + return reg->template try_get(entt); } /** diff --git a/test/entt/entity/handle.cpp b/test/entt/entity/handle.cpp index 99600a31b..e8b021833 100644 --- a/test/entt/entity/handle.cpp +++ b/test/entt/entity/handle.cpp @@ -204,9 +204,13 @@ TEST(BasicHandle, ImplicitConversions) { entt::registry registry; const entt::handle handle{registry, registry.create()}; const entt::const_handle chandle = handle; + const entt::handle_view vhandle = handle; + const entt::const_handle_view cvhandle = vhandle; handle.emplace(42); ASSERT_EQ(handle.get(), chandle.get()); - ASSERT_EQ(chandle.get(), 42); + ASSERT_EQ(chandle.get(), vhandle.get()); + ASSERT_EQ(vhandle.get(), cvhandle.get()); + ASSERT_EQ(cvhandle.get(), 42); }