@@ -23,7 +23,7 @@ struct entt_traits<Type, std::enable_if_t<std::is_enum_v<Type>>>
2323};
2424
2525template <typename Type>
26- struct entt_traits <Type, std::enable_if_t <std::is_class_v<Type> >>
26+ struct entt_traits <Type, std::void_t < typename Type::entity_type >>
2727 : entt_traits<typename Type::entity_type> {
2828 using value_type = Type;
2929};
@@ -57,8 +57,12 @@ struct entt_traits<std::uint64_t> {
5757 * @brief Common basic entity traits implementation.
5858 * @tparam Traits Actual entity traits to use.
5959 */
60+
61+ template <typename Traits, typename = void >
62+ class basic_entt_traits ;
63+
6064template <typename Traits>
61- class basic_entt_traits {
65+ class basic_entt_traits <Traits, std:: void_t < decltype ( sizeof (Traits))>> {
6266 static constexpr auto length = popcount(Traits::entity_mask);
6367
6468 static_assert (Traits::entity_mask && ((Traits::entity_mask & (Traits::entity_mask + 1 )) == 0 ), " Invalid entity mask" );
@@ -159,8 +163,11 @@ class basic_entt_traits {
159163 * @brief Entity traits.
160164 * @tparam Type Type of identifier.
161165 */
166+ template <typename Type, typename = void >
167+ struct entt_traits ;
168+
162169template <typename Type>
163- struct entt_traits : basic_entt_traits<internal::entt_traits<Type>> {
170+ struct entt_traits <Type, std:: void_t < decltype ( sizeof (basic_entt_traits<internal::entt_traits<Type>>))>> : basic_entt_traits<internal::entt_traits<Type>> {
164171 /* ! @brief Base type. */
165172 using base_type = basic_entt_traits<internal::entt_traits<Type>>;
166173 /* ! @brief Page size, default is `ENTT_SPARSE_PAGE`. */
@@ -207,7 +214,7 @@ struct null_t {
207214 * @tparam Entity Type of identifier.
208215 * @return The null representation for the given type.
209216 */
210- template <typename Entity>
217+ template <typename Entity, decltype ( sizeof (entt_traits<Entity>)) * = nullptr >
211218 [[nodiscard]] constexpr operator Entity () const noexcept {
212219 using traits_type = entt_traits<Entity>;
213220 constexpr auto value = traits_type::construct (traits_type::entity_mask, traits_type::version_mask);
@@ -238,7 +245,7 @@ struct null_t {
238245 * @param entity Identifier with which to compare.
239246 * @return False if the two elements differ, true otherwise.
240247 */
241- template <typename Entity>
248+ template <typename Entity, decltype ( sizeof (entt_traits<Entity>)) * = nullptr >
242249 [[nodiscard]] constexpr bool operator ==(const Entity entity) const noexcept {
243250 using traits_type = entt_traits<Entity>;
244251 return traits_type::to_entity (entity) == traits_type::to_entity (*this );
@@ -251,7 +258,8 @@ struct null_t {
251258 * @return True if the two elements differ, false otherwise.
252259 */
253260 template <typename Entity>
254- [[nodiscard]] constexpr bool operator !=(const Entity entity) const noexcept {
261+ [[nodiscard]] constexpr auto operator !=(const Entity entity) const noexcept
262+ -> decltype (this ->operator ==(entity)) {
255263 return !(entity == *this );
256264 }
257265};
@@ -264,7 +272,8 @@ struct null_t {
264272 * @return False if the two elements differ, true otherwise.
265273 */
266274template <typename Entity>
267- [[nodiscard]] constexpr bool operator ==(const Entity lhs, const null_t rhs) noexcept {
275+ [[nodiscard]] constexpr auto operator ==(const Entity lhs, const null_t rhs) noexcept
276+ -> decltype (rhs.operator ==(lhs)) {
268277 return rhs.operator ==(lhs);
269278}
270279
@@ -276,7 +285,8 @@ template<typename Entity>
276285 * @return True if the two elements differ, false otherwise.
277286 */
278287template <typename Entity>
279- [[nodiscard]] constexpr bool operator !=(const Entity lhs, const null_t rhs) noexcept {
288+ [[nodiscard]] constexpr auto operator !=(const Entity lhs, const null_t rhs) noexcept
289+ -> decltype (rhs.operator ==(lhs)) {
280290 return !(rhs == lhs);
281291}
282292
@@ -287,7 +297,7 @@ struct tombstone_t {
287297 * @tparam Entity Type of identifier.
288298 * @return The tombstone representation for the given type.
289299 */
290- template <typename Entity>
300+ template <typename Entity, decltype ( sizeof (entt_traits<Entity>)) * = nullptr >
291301 [[nodiscard]] constexpr operator Entity () const noexcept {
292302 using traits_type = entt_traits<Entity>;
293303 constexpr auto value = traits_type::construct (traits_type::entity_mask, traits_type::version_mask);
@@ -318,7 +328,7 @@ struct tombstone_t {
318328 * @param entity Identifier with which to compare.
319329 * @return False if the two elements differ, true otherwise.
320330 */
321- template <typename Entity>
331+ template <typename Entity, decltype ( sizeof (entt_traits<Entity>)) * = nullptr >
322332 [[nodiscard]] constexpr bool operator ==(const Entity entity) const noexcept {
323333 using traits_type = entt_traits<Entity>;
324334
@@ -336,8 +346,9 @@ struct tombstone_t {
336346 * @return True if the two elements differ, false otherwise.
337347 */
338348 template <typename Entity>
339- [[nodiscard]] constexpr bool operator !=(const Entity entity) const noexcept {
340- return !(entity == *this );
349+ [[nodiscard]] constexpr auto operator !=(const Entity entity) const noexcept
350+ -> decltype (this ->operator ==(entity)) {
351+ return !(*this == entity);
341352 }
342353};
343354
@@ -349,7 +360,8 @@ struct tombstone_t {
349360 * @return False if the two elements differ, true otherwise.
350361 */
351362template <typename Entity>
352- [[nodiscard]] constexpr bool operator ==(const Entity lhs, const tombstone_t rhs) noexcept {
363+ [[nodiscard]] constexpr auto operator ==(const Entity lhs, const tombstone_t rhs) noexcept
364+ -> decltype (rhs.operator ==(lhs)) {
353365 return rhs.operator ==(lhs);
354366}
355367
@@ -361,7 +373,8 @@ template<typename Entity>
361373 * @return True if the two elements differ, false otherwise.
362374 */
363375template <typename Entity>
364- [[nodiscard]] constexpr bool operator !=(const Entity lhs, const tombstone_t rhs) noexcept {
376+ [[nodiscard]] constexpr auto operator !=(const Entity lhs, const tombstone_t rhs) noexcept
377+ -> decltype (rhs.operator ==(lhs)) {
365378 return !(rhs == lhs);
366379}
367380
0 commit comments