config/core/entity: added is_eto_eligible[_v] and used it where it makes sense
This commit is contained in:
@@ -44,11 +44,10 @@
|
||||
|
||||
#ifndef ENTT_NO_ETO
|
||||
# include <type_traits>
|
||||
# define ENTT_IS_EMPTY(Type) std::is_empty_v<Type>
|
||||
# define ENTT_IS_EMPTY(Type) std::is_empty<Type>
|
||||
#else
|
||||
# include <type_traits>
|
||||
# // sfinae-friendly definition
|
||||
# define ENTT_IS_EMPTY(Type) (void(std::is_empty_v<Type>), false)
|
||||
# define ENTT_IS_EMPTY(Type) std::false_type
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -206,6 +206,25 @@ template<class Type>
|
||||
inline constexpr auto is_equality_comparable_v = is_equality_comparable<Type>::value;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Provides the member constant `value` to true if a given type is empty
|
||||
* and the empty type optimization is enabled, false otherwise.
|
||||
* @tparam Type Potential empty type.
|
||||
*/
|
||||
template<typename Type, typename = void>
|
||||
struct is_eto_eligible
|
||||
: ENTT_IS_EMPTY(Type)
|
||||
{};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Helper variable template.
|
||||
* @tparam Type Potential empty type.
|
||||
*/
|
||||
template<typename Type>
|
||||
inline constexpr auto is_eto_eligible_v = is_eto_eligible<Type>::value;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Extracts the class of a non-static member object or function.
|
||||
* @tparam Member A pointer to a non-static member object or function.
|
||||
|
||||
@@ -78,7 +78,7 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>> {
|
||||
friend class group_proxy;
|
||||
|
||||
using it_type = typename sparse_set<Entity>::iterator;
|
||||
using ref_type = decltype(std::tuple_cat(std::declval<std::conditional_t<ENTT_IS_EMPTY(Get), std::tuple<>, std::tuple<pool_type<Get> *>>>()...));
|
||||
using ref_type = decltype(std::tuple_cat(std::declval<std::conditional_t<is_eto_eligible_v<Get>, std::tuple<>, std::tuple<pool_type<Get> *>>>()...));
|
||||
|
||||
proxy_iterator(it_type from, ref_type ref) ENTT_NOEXCEPT
|
||||
: it{from},
|
||||
@@ -89,12 +89,12 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>> {
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = decltype(std::tuple_cat(
|
||||
std::declval<std::tuple<Entity>>(),
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Get), std::tuple<>, std::tuple<Get>>>()...
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Get>, std::tuple<>, std::tuple<Get>>>()...
|
||||
));
|
||||
using pointer = void;
|
||||
using reference = decltype(std::tuple_cat(
|
||||
std::declval<std::tuple<Entity>>(),
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Get), std::tuple<>, std::tuple<Get &>>>()...
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Get>, std::tuple<>, std::tuple<Get &>>>()...
|
||||
));
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
@@ -134,7 +134,7 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>> {
|
||||
|
||||
[[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
|
||||
return proxy_iterator{handler->begin(), std::tuple_cat([](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool);
|
||||
@@ -144,7 +144,7 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>> {
|
||||
|
||||
[[nodiscard]] iterator end() const ENTT_NOEXCEPT {
|
||||
return proxy_iterator{handler->end(), std::tuple_cat([](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool);
|
||||
@@ -453,7 +453,7 @@ public:
|
||||
*/
|
||||
template<typename Func>
|
||||
void each(Func func) const {
|
||||
using get_type_list = type_list_cat_t<std::conditional_t<ENTT_IS_EMPTY(Get), type_list<>, type_list<Get>>...>;
|
||||
using get_type_list = type_list_cat_t<std::conditional_t<is_eto_eligible_v<Get>, type_list<>, type_list<Get>>...>;
|
||||
traverse(std::move(func), get_type_list{});
|
||||
}
|
||||
|
||||
@@ -617,8 +617,8 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> {
|
||||
friend class group_proxy;
|
||||
|
||||
using it_type = typename sparse_set<Entity>::iterator;
|
||||
using owned_type = decltype(std::tuple_cat(std::declval<std::conditional_t<ENTT_IS_EMPTY(Owned), std::tuple<>, std::tuple<component_iterator<Owned>>>>()...));
|
||||
using get_type = decltype(std::tuple_cat(std::declval<std::conditional_t<ENTT_IS_EMPTY(Get), std::tuple<>, std::tuple<pool_type<Get> *>>>()...));
|
||||
using owned_type = decltype(std::tuple_cat(std::declval<std::conditional_t<is_eto_eligible_v<Owned>, std::tuple<>, std::tuple<component_iterator<Owned>>>>()...));
|
||||
using get_type = decltype(std::tuple_cat(std::declval<std::conditional_t<is_eto_eligible_v<Get>, std::tuple<>, std::tuple<pool_type<Get> *>>>()...));
|
||||
|
||||
proxy_iterator(it_type from, owned_type oref, get_type gref) ENTT_NOEXCEPT
|
||||
: it{from},
|
||||
@@ -630,14 +630,14 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> {
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = decltype(std::tuple_cat(
|
||||
std::declval<std::tuple<Entity>>(),
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Owned), std::tuple<>, std::tuple<Owned>>>()...,
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Get), std::tuple<>, std::tuple<Get>>>()...
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Owned>, std::tuple<>, std::tuple<Owned>>>()...,
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Get>, std::tuple<>, std::tuple<Get>>>()...
|
||||
));
|
||||
using pointer = void;
|
||||
using reference = decltype(std::tuple_cat(
|
||||
std::declval<std::tuple<Entity>>(),
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Owned), std::tuple<>, std::tuple<Owned &>>>()...,
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Get), std::tuple<>, std::tuple<Get &>>>()...
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Owned>, std::tuple<>, std::tuple<Owned &>>>()...,
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Get>, std::tuple<>, std::tuple<Get &>>>()...
|
||||
));
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
@@ -684,14 +684,14 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> {
|
||||
return proxy_iterator{
|
||||
std::get<0>(pools)->sparse_set<Entity>::end() - *length,
|
||||
std::tuple_cat([length = *length](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool->end() - length);
|
||||
}
|
||||
}(std::get<pool_type<Owned> *>(pools))...),
|
||||
std::tuple_cat([](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool);
|
||||
@@ -704,14 +704,14 @@ class basic_group<Entity, exclude_t<Exclude...>, get_t<Get...>, Owned...> {
|
||||
return proxy_iterator{
|
||||
std::get<0>(pools)->sparse_set<Entity>::end(),
|
||||
std::tuple_cat([](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool->end());
|
||||
}
|
||||
}(std::get<pool_type<Owned> *>(pools))...),
|
||||
std::tuple_cat([](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool);
|
||||
@@ -1022,8 +1022,8 @@ public:
|
||||
*/
|
||||
template<typename Func>
|
||||
void each(Func func) const {
|
||||
using owned_type_list = type_list_cat_t<std::conditional_t<ENTT_IS_EMPTY(Owned), type_list<>, type_list<Owned>>...>;
|
||||
using get_type_list = type_list_cat_t<std::conditional_t<ENTT_IS_EMPTY(Get), type_list<>, type_list<Get>>...>;
|
||||
using owned_type_list = type_list_cat_t<std::conditional_t<is_eto_eligible_v<Owned>, type_list<>, type_list<Owned>>...>;
|
||||
using get_type_list = type_list_cat_t<std::conditional_t<is_eto_eligible_v<Get>, type_list<>, type_list<Get>>...>;
|
||||
traverse(std::move(func), owned_type_list{}, get_type_list{});
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class basic_registry {
|
||||
storage<entity_type, Component>::emplace(entt, std::forward<Args>(args)...);
|
||||
construction.publish(owner, entt);
|
||||
|
||||
if constexpr(!ENTT_IS_EMPTY(Component)) {
|
||||
if constexpr(!is_eto_eligible_v<Component>) {
|
||||
return this->get(entt);
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ class basic_registry {
|
||||
|
||||
template<typename... Func>
|
||||
decltype(auto) patch(basic_registry &owner, const Entity entt, [[maybe_unused]] Func &&... func) {
|
||||
if constexpr(ENTT_IS_EMPTY(Component)) {
|
||||
if constexpr(is_eto_eligible_v<Component>) {
|
||||
update.publish(owner, entt);
|
||||
} else {
|
||||
(std::forward<Func>(func)(this->get(entt)), ...);
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
#include <type_traits>
|
||||
#include "../config/config.h"
|
||||
#include "../core/algorithm.hpp"
|
||||
#include "sparse_set.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "sparse_set.hpp"
|
||||
|
||||
|
||||
namespace entt {
|
||||
@@ -521,8 +522,7 @@ private:
|
||||
|
||||
/*! @copydoc storage */
|
||||
template<typename Entity, typename Type>
|
||||
// the useless decltype(...) helps to get around a quite impressive issue of VS2017
|
||||
class storage<Entity, Type, std::enable_if_t<ENTT_IS_EMPTY(Type)>()>: public sparse_set<Entity> {
|
||||
class storage<Entity, Type, std::enable_if_t<is_eto_eligible_v<Type>>>: public sparse_set<Entity> {
|
||||
using underlying_type = sparse_set<Entity>;
|
||||
|
||||
public:
|
||||
|
||||
@@ -159,7 +159,7 @@ class basic_view<Entity, exclude_t<Exclude...>, Component...> {
|
||||
class proxy_iterator {
|
||||
friend class view_proxy;
|
||||
|
||||
using ref_type = decltype(std::tuple_cat(std::declval<std::conditional_t<ENTT_IS_EMPTY(Component), std::tuple<>, std::tuple<pool_type<Component> *>>>()...));
|
||||
using ref_type = decltype(std::tuple_cat(std::declval<std::conditional_t<is_eto_eligible_v<Component>, std::tuple<>, std::tuple<pool_type<Component> *>>>()...));
|
||||
|
||||
proxy_iterator(proxy_view_iterator from, ref_type ref) ENTT_NOEXCEPT
|
||||
: it{from},
|
||||
@@ -170,12 +170,12 @@ class basic_view<Entity, exclude_t<Exclude...>, Component...> {
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = decltype(std::tuple_cat(
|
||||
std::declval<std::tuple<Entity>>(),
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Component), std::tuple<>, std::tuple<Component>>>()...
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Component>, std::tuple<>, std::tuple<Component>>>()...
|
||||
));
|
||||
using pointer = void;
|
||||
using reference = decltype(std::tuple_cat(
|
||||
std::declval<std::tuple<Entity>>(),
|
||||
std::declval<std::conditional_t<ENTT_IS_EMPTY(Component), std::tuple<>, std::tuple<Component &>>>()...
|
||||
std::declval<std::conditional_t<is_eto_eligible_v<Component>, std::tuple<>, std::tuple<Component &>>>()...
|
||||
));
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
@@ -216,7 +216,7 @@ class basic_view<Entity, exclude_t<Exclude...>, Component...> {
|
||||
|
||||
[[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
|
||||
return proxy_iterator{first, std::tuple_cat([](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool);
|
||||
@@ -226,7 +226,7 @@ class basic_view<Entity, exclude_t<Exclude...>, Component...> {
|
||||
|
||||
[[nodiscard]] iterator end() const ENTT_NOEXCEPT {
|
||||
return proxy_iterator{last, std::tuple_cat([](auto *cpool) {
|
||||
if constexpr(ENTT_IS_EMPTY(typename std::decay_t<decltype(*cpool)>::object_type)) {
|
||||
if constexpr(is_eto_eligible_v<typename std::decay_t<decltype(*cpool)>::object_type>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::make_tuple(cpool);
|
||||
@@ -601,7 +601,7 @@ public:
|
||||
*/
|
||||
template<typename Comp, typename Func>
|
||||
void each(Func func) const {
|
||||
using non_empty_type = type_list_cat_t<std::conditional_t<ENTT_IS_EMPTY(Component), type_list<>, type_list<Component>>...>;
|
||||
using non_empty_type = type_list_cat_t<std::conditional_t<is_eto_eligible_v<Component>, type_list<>, type_list<Component>>...>;
|
||||
traverse<Comp>(std::move(func), non_empty_type{});
|
||||
}
|
||||
|
||||
@@ -679,7 +679,7 @@ public:
|
||||
*/
|
||||
template<typename Func>
|
||||
void chunked(Func func) const {
|
||||
using non_empty_type = type_list_cat_t<std::conditional_t<ENTT_IS_EMPTY(Component), type_list<>, type_list<Component>>...>;
|
||||
using non_empty_type = type_list_cat_t<std::conditional_t<is_eto_eligible_v<Component>, type_list<>, type_list<Component>>...>;
|
||||
view = candidate();
|
||||
iterate(std::move(func), non_empty_type{});
|
||||
}
|
||||
@@ -736,7 +736,7 @@ class basic_view<Entity, exclude_t<>, Component> {
|
||||
friend class view_proxy;
|
||||
|
||||
using it_type = std::conditional_t<
|
||||
ENTT_IS_EMPTY(Component),
|
||||
is_eto_eligible_v<Component>,
|
||||
std::tuple<typename sparse_set<Entity>::iterator>,
|
||||
std::tuple<typename sparse_set<Entity>::iterator, decltype(std::declval<pool_type>().begin())>
|
||||
>;
|
||||
@@ -747,9 +747,9 @@ class basic_view<Entity, exclude_t<>, Component> {
|
||||
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = std::conditional_t<ENTT_IS_EMPTY(Component), std::tuple<Entity>, std::tuple<Entity, Component>>;
|
||||
using value_type = std::conditional_t<is_eto_eligible_v<Component>, std::tuple<Entity>, std::tuple<Entity, Component>>;
|
||||
using pointer = void;
|
||||
using reference = std::conditional_t<ENTT_IS_EMPTY(Component), std::tuple<Entity>, std::tuple<Entity, Component &>>;
|
||||
using reference = std::conditional_t<is_eto_eligible_v<Component>, std::tuple<Entity>, std::tuple<Entity, Component &>>;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
proxy_iterator & operator++() ENTT_NOEXCEPT {
|
||||
@@ -785,7 +785,7 @@ class basic_view<Entity, exclude_t<>, Component> {
|
||||
using iterator = proxy_iterator;
|
||||
|
||||
[[nodiscard]] iterator begin() const ENTT_NOEXCEPT {
|
||||
if constexpr(ENTT_IS_EMPTY(Component)) {
|
||||
if constexpr(is_eto_eligible_v<Component>) {
|
||||
return proxy_iterator{std::make_tuple(pool->sparse_set<entity_type>::begin())};
|
||||
} else {
|
||||
return proxy_iterator{std::make_tuple(pool->sparse_set<entity_type>::begin(), pool->begin())};
|
||||
@@ -793,7 +793,7 @@ class basic_view<Entity, exclude_t<>, Component> {
|
||||
}
|
||||
|
||||
[[nodiscard]] iterator end() const ENTT_NOEXCEPT {
|
||||
if constexpr(ENTT_IS_EMPTY(Component)) {
|
||||
if constexpr(is_eto_eligible_v<Component>) {
|
||||
return proxy_iterator{std::make_tuple(pool->sparse_set<entity_type>::end())};
|
||||
} else {
|
||||
return proxy_iterator{std::make_tuple(pool->sparse_set<entity_type>::end(), pool->end())};
|
||||
@@ -1031,7 +1031,7 @@ public:
|
||||
*/
|
||||
template<typename Func>
|
||||
void each(Func func) const {
|
||||
if constexpr(ENTT_IS_EMPTY(Component)) {
|
||||
if constexpr(is_eto_eligible_v<Component>) {
|
||||
if constexpr(std::is_invocable_v<Func>) {
|
||||
for(auto pos = pool->size(); pos; --pos) {
|
||||
func();
|
||||
|
||||
Reference in New Issue
Block a user