diff --git a/docs/md/entity.md b/docs/md/entity.md
index 38cf26f0c..c206405a5 100644
--- a/docs/md/entity.md
+++ b/docs/md/entity.md
@@ -1683,7 +1683,9 @@ it cannot be caught by a non-const reference. Capture it by copy or by const
reference instead.
More in general, none of the features offered by the library is affected, but
-for the ones that require to return actual instances.
+for the ones that require to return actual instances.
+This optimization can be disabled by defining the `ENTT_DISABLE_ETO` macro. In
+this case, the empty types will be treated like all other types, no matter what.
# Multithreading
diff --git a/src/entt/config/config.h b/src/entt/config/config.h
index ae750a9ee..a940c1f69 100644
--- a/src/entt/config/config.h
+++ b/src/entt/config/config.h
@@ -25,6 +25,15 @@
#endif // ENTT_NO_ATOMIC
+#ifndef ENTT_DISABLE_ETO
+#include
+#define ENTT_ENABLE_ETO(Type) std::is_empty_v
+#else // ENTT_DISABLE_ETO
+// sfinae-friendly definition
+#define ENTT_ENABLE_ETO(Type) (false && std::is_empty_v)
+#endif // ENTT_DISABLE_ETO
+
+
#ifndef ENTT_ID_TYPE
#include
#define ENTT_ID_TYPE std::uint32_t
diff --git a/src/entt/entity/group.hpp b/src/entt/entity/group.hpp
index 904b378c3..bc0ddba98 100644
--- a/src/entt/entity/group.hpp
+++ b/src/entt/entity/group.hpp
@@ -344,7 +344,7 @@ public:
*/
template
void less(Func func) const {
- using get_type_list = type_list_cat_t, type_list<>, type_list>...>;
+ using get_type_list = type_list_cat_t, type_list>...>;
traverse(std::move(func), get_type_list{});
}
@@ -763,8 +763,8 @@ public:
*/
template
void less(Func func) const {
- using owned_type_list = type_list_cat_t, type_list<>, type_list>...>;
- using get_type_list = type_list_cat_t, type_list<>, type_list>...>;
+ using owned_type_list = type_list_cat_t, type_list>...>;
+ using get_type_list = type_list_cat_t, type_list>...>;
traverse(std::move(func), owned_type_list{}, get_type_list{});
}
diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp
index fb92c860e..7dd9f5d0d 100644
--- a/src/entt/entity/registry.hpp
+++ b/src/entt/entity/registry.hpp
@@ -70,7 +70,7 @@ class basic_registry {
template
decltype(auto) assign(basic_registry ®istry, const Entity entt, Args &&... args) {
- if constexpr(std::is_empty_v) {
+ if constexpr(ENTT_ENABLE_ETO(Component)) {
storage::construct(entt);
construction.publish(entt, registry, Component{});
return Component{std::forward(args)...};
@@ -101,7 +101,7 @@ class basic_registry {
template
decltype(auto) replace(basic_registry ®istry, const Entity entt, Args &&... args) {
- if constexpr(std::is_empty_v) {
+ if constexpr(ENTT_ENABLE_ETO(Component)) {
ENTT_ASSERT((storage::has(entt)));
update.publish(entt, registry, Component{});
return Component{std::forward(args)...};
@@ -113,7 +113,7 @@ class basic_registry {
}
private:
- using reference_type = std::conditional_t, const Component &, Component &>;
+ using reference_type = std::conditional_t;
sigh construction{};
sigh update{};
sigh destruction{};
diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp
index ff6360717..2d2d1b4c3 100644
--- a/src/entt/entity/storage.hpp
+++ b/src/entt/entity/storage.hpp
@@ -453,8 +453,6 @@ public:
};
if constexpr(std::is_invocable_v) {
- static_assert(!std::is_empty_v);
-
underlying_type::arrange(from, to, std::move(apply), [this, compare = std::move(compare)](const auto lhs, const auto rhs) {
return compare(std::as_const(instances[underlying_type::index(lhs)]), std::as_const(instances[underlying_type::index(rhs)]));
}, std::move(algo), std::forward(args)...);
@@ -476,7 +474,7 @@ private:
/*! @copydoc basic_storage */
template
-class basic_storage>>: public sparse_set {
+class basic_storage>: public sparse_set {
using traits_type = entt_traits>;
using underlying_type = sparse_set;
diff --git a/src/entt/entity/view.hpp b/src/entt/entity/view.hpp
index 6c3aa2729..95fe43db9 100644
--- a/src/entt/entity/view.hpp
+++ b/src/entt/entity/view.hpp
@@ -503,7 +503,7 @@ public:
template
void less(Func func) const {
using other_type = type_list_cat_t, type_list<>, type_list>...>;
- using non_empty_type = type_list_cat_t, type_list<>, type_list>...>;
+ using non_empty_type = type_list_cat_t, type_list>...>;
traverse(std::move(func), other_type{}, non_empty_type{});
}
@@ -767,7 +767,7 @@ public:
*/
template
void less(Func func) const {
- if constexpr(std::is_empty_v) {
+ if constexpr(ENTT_ENABLE_ETO(Component)) {
if constexpr(std::is_invocable_v) {
for(auto pos = pool->size(); pos; --pos) {
func();
diff --git a/test/snapshot/snapshot.cpp b/test/snapshot/snapshot.cpp
index 48e549b3c..80dd8ab50 100644
--- a/test/snapshot/snapshot.cpp
+++ b/test/snapshot/snapshot.cpp
@@ -21,17 +21,17 @@ struct relationship {
template
void serialize(Archive &archive, position &position) {
- archive(position.x, position.y);
+ archive(position.x, position.y);
}
template
void serialize(Archive &archive, timer &timer) {
- archive(timer.duration);
+ archive(timer.duration);
}
template
void serialize(Archive &archive, relationship &relationship) {
- archive(relationship.parent);
+ archive(relationship.parent);
}
TEST(Snapshot, Full) {