group: reduce instantiations due to extended iterators and merge their definitions
This commit is contained in:
@@ -15,6 +15,82 @@
|
||||
|
||||
namespace entt {
|
||||
|
||||
/**
|
||||
* @cond TURN_OFF_DOXYGEN
|
||||
* Internal details not to be documented.
|
||||
*/
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename, typename, typename>
|
||||
class extended_group_iterator;
|
||||
|
||||
template<typename It, typename... Owned, typename... Get>
|
||||
class extended_group_iterator<It, owned_t<Owned...>, get_t<Get...>> {
|
||||
template<typename Type>
|
||||
auto index_to_element(Type &cpool) const {
|
||||
if constexpr(ignore_as_empty_v<std::remove_const_t<typename Type::value_type>>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::forward_as_tuple(cpool.rbegin()[it.index()]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Owned>().get_as_tuple({})..., std::declval<Get>().get_as_tuple({})...));
|
||||
using pointer = input_iterator_pointer<value_type>;
|
||||
using reference = value_type;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
extended_group_iterator() = default;
|
||||
|
||||
extended_group_iterator(It from, const std::tuple<Owned *..., Get *...> &cpools)
|
||||
: it{from},
|
||||
pools{cpools} {}
|
||||
|
||||
extended_group_iterator &operator++() ENTT_NOEXCEPT {
|
||||
return ++it, *this;
|
||||
}
|
||||
|
||||
extended_group_iterator operator++(int) ENTT_NOEXCEPT {
|
||||
extended_group_iterator orig = *this;
|
||||
return ++(*this), orig;
|
||||
}
|
||||
|
||||
[[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
|
||||
return std::tuple_cat(std::make_tuple(*it), index_to_element(*std::get<Owned *>(pools))..., std::get<Get *>(pools)->get_as_tuple(*it)...);
|
||||
}
|
||||
|
||||
[[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
|
||||
return operator*();
|
||||
}
|
||||
|
||||
template<typename... Lhs, typename... Rhs>
|
||||
friend bool operator==(const extended_group_iterator<Lhs...> &, const extended_group_iterator<Rhs...> &) ENTT_NOEXCEPT;
|
||||
|
||||
private:
|
||||
It it;
|
||||
std::tuple<Owned *..., Get *...> pools;
|
||||
};
|
||||
|
||||
template<typename... Lhs, typename... Rhs>
|
||||
[[nodiscard]] bool operator==(const extended_group_iterator<Lhs...> &lhs, const extended_group_iterator<Rhs...> &rhs) ENTT_NOEXCEPT {
|
||||
return lhs.it == rhs.it;
|
||||
}
|
||||
|
||||
template<typename... Lhs, typename... Rhs>
|
||||
[[nodiscard]] bool operator!=(const extended_group_iterator<Lhs...> &lhs, const extended_group_iterator<Rhs...> &rhs) ENTT_NOEXCEPT {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
/**
|
||||
* Internal details not to be documented.
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Group.
|
||||
*
|
||||
@@ -43,19 +119,6 @@ class basic_group;
|
||||
* In all other cases, modifying the pools iterated by the group in any way
|
||||
* invalidates all the iterators and using them results in undefined behavior.
|
||||
*
|
||||
* @note
|
||||
* Groups share references to the underlying data structures of the registry
|
||||
* that generated them. Therefore any change to the entities and to the
|
||||
* components made by means of the registry are immediately reflected by all the
|
||||
* groups.<br/>
|
||||
* Moreover, sorting a non-owning group affects all the instances of the same
|
||||
* group (it means that users don't have to call `sort` on each instance to sort
|
||||
* all of them because they _share_ entities and components).
|
||||
*
|
||||
* @warning
|
||||
* Lifetime of a group must not overcome that of the registry that generated it.
|
||||
* In any other case, attempting to use a group results in undefined behavior.
|
||||
*
|
||||
* @tparam Entity A valid entity type (see entt_traits for more details).
|
||||
* @tparam Get Type of components observed by the group.
|
||||
* @tparam Exclude Types of components used to filter the group.
|
||||
@@ -70,50 +133,6 @@ class basic_group<Entity, owned_t<>, get_t<Get...>, exclude_t<Exclude...>> {
|
||||
|
||||
using basic_common_type = std::common_type_t<typename storage_type<Get>::base_type...>;
|
||||
|
||||
struct extended_group_iterator final {
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = decltype(std::tuple_cat(std::tuple<Entity>{}, std::declval<basic_group>().get({})));
|
||||
using pointer = input_iterator_pointer<value_type>;
|
||||
using reference = value_type;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
extended_group_iterator() = default;
|
||||
|
||||
extended_group_iterator(typename basic_common_type::iterator from, const std::tuple<storage_type<Get> *...> &args)
|
||||
: it{from},
|
||||
pools{args} {}
|
||||
|
||||
extended_group_iterator &operator++() ENTT_NOEXCEPT {
|
||||
return ++it, *this;
|
||||
}
|
||||
|
||||
extended_group_iterator operator++(int) ENTT_NOEXCEPT {
|
||||
extended_group_iterator orig = *this;
|
||||
return ++(*this), orig;
|
||||
}
|
||||
|
||||
[[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
|
||||
const auto entt = *it;
|
||||
return std::tuple_cat(std::make_tuple(entt), std::get<storage_type<Get> *>(pools)->get_as_tuple(entt)...);
|
||||
}
|
||||
|
||||
[[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
|
||||
return operator*();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(const extended_group_iterator &other) const ENTT_NOEXCEPT {
|
||||
return other.it == it;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator!=(const extended_group_iterator &other) const ENTT_NOEXCEPT {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
typename basic_common_type::iterator it;
|
||||
std::tuple<storage_type<Get> *...> pools;
|
||||
};
|
||||
|
||||
basic_group(basic_common_type &ref, storage_type<Get> &...gpool) ENTT_NOEXCEPT
|
||||
: handler{&ref},
|
||||
pools{&gpool...} {}
|
||||
@@ -130,7 +149,7 @@ public:
|
||||
/*! @brief Reversed iterator type. */
|
||||
using reverse_iterator = typename base_type::reverse_iterator;
|
||||
/*! @brief Iterable group type. */
|
||||
using iterable = iterable_adaptor<extended_group_iterator>;
|
||||
using iterable = iterable_adaptor<internal::extended_group_iterator<iterator, owned_t<>, get_t<storage_type<Get>...>>>;
|
||||
|
||||
/*! @brief Default constructor to use to create empty, invalid groups. */
|
||||
basic_group() ENTT_NOEXCEPT
|
||||
@@ -381,8 +400,7 @@ public:
|
||||
* @return An iterable object to use to _visit_ the group.
|
||||
*/
|
||||
[[nodiscard]] iterable each() const ENTT_NOEXCEPT {
|
||||
return handler ? iterable{extended_group_iterator{handler->begin(), pools}, extended_group_iterator{handler->end(), pools}}
|
||||
: iterable{extended_group_iterator{{}, pools}, extended_group_iterator{{}, pools}};
|
||||
return iterable{{begin(), pools}, {end(), pools}};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -497,19 +515,6 @@ private:
|
||||
* In all other cases, modifying the pools iterated by the group in any way
|
||||
* invalidates all the iterators and using them results in undefined behavior.
|
||||
*
|
||||
* @note
|
||||
* Groups share references to the underlying data structures of the registry
|
||||
* that generated them. Therefore any change to the entities and to the
|
||||
* components made by means of the registry are immediately reflected by all the
|
||||
* groups.
|
||||
* Moreover, sorting an owning group affects all the instance of the same group
|
||||
* (it means that users don't have to call `sort` on each instance to sort all
|
||||
* of them because they share the underlying data structure).
|
||||
*
|
||||
* @warning
|
||||
* Lifetime of a group must not overcome that of the registry that generated it.
|
||||
* In any other case, attempting to use a group results in undefined behavior.
|
||||
*
|
||||
* @tparam Entity A valid entity type (see entt_traits for more details).
|
||||
* @tparam Owned Types of components owned by the group.
|
||||
* @tparam Get Types of components observed by the group.
|
||||
@@ -523,65 +528,6 @@ class basic_group<Entity, owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...
|
||||
template<typename Comp>
|
||||
using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Comp>>::storage_type, Comp>;
|
||||
|
||||
using basic_common_type = std::common_type_t<typename storage_type<Owned>::base_type..., typename storage_type<Get>::base_type...>;
|
||||
|
||||
class extended_group_iterator final {
|
||||
template<typename Type>
|
||||
auto index_to_element(storage_type<Type> &cpool) const {
|
||||
if constexpr(ignore_as_empty_v<std::remove_const_t<Type>>) {
|
||||
return std::make_tuple();
|
||||
} else {
|
||||
return std::forward_as_tuple(cpool.rbegin()[it.index()]);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = decltype(std::tuple_cat(std::tuple<Entity>{}, std::declval<basic_group>().get({})));
|
||||
using pointer = input_iterator_pointer<value_type>;
|
||||
using reference = value_type;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
|
||||
extended_group_iterator() = default;
|
||||
|
||||
template<typename... Other>
|
||||
extended_group_iterator(typename basic_common_type::iterator from, const std::tuple<storage_type<Owned> *..., storage_type<Get> *...> &cpools)
|
||||
: it{from},
|
||||
pools{cpools} {}
|
||||
|
||||
extended_group_iterator &operator++() ENTT_NOEXCEPT {
|
||||
return ++it, *this;
|
||||
}
|
||||
|
||||
extended_group_iterator operator++(int) ENTT_NOEXCEPT {
|
||||
extended_group_iterator orig = *this;
|
||||
return ++(*this), orig;
|
||||
}
|
||||
|
||||
[[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
|
||||
return std::tuple_cat(
|
||||
std::make_tuple(*it),
|
||||
index_to_element<Owned>(*std::get<storage_type<Owned> *>(pools))...,
|
||||
std::get<storage_type<Get> *>(pools)->get_as_tuple(*it)...);
|
||||
}
|
||||
|
||||
[[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
|
||||
return operator*();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator==(const extended_group_iterator &other) const ENTT_NOEXCEPT {
|
||||
return other.it == it;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool operator!=(const extended_group_iterator &other) const ENTT_NOEXCEPT {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
typename basic_common_type::iterator it;
|
||||
std::tuple<storage_type<Owned> *..., storage_type<Get> *...> pools;
|
||||
};
|
||||
|
||||
basic_group(const std::size_t &extent, storage_type<Owned> &...opool, storage_type<Get> &...gpool) ENTT_NOEXCEPT
|
||||
: pools{&opool..., &gpool...},
|
||||
length{&extent} {}
|
||||
@@ -592,13 +538,13 @@ public:
|
||||
/*! @brief Unsigned integer type. */
|
||||
using size_type = std::size_t;
|
||||
/*! @brief Common type among all storage types. */
|
||||
using base_type = basic_common_type;
|
||||
using base_type = std::common_type_t<typename storage_type<Owned>::base_type..., typename storage_type<Get>::base_type...>;
|
||||
/*! @brief Random access iterator type. */
|
||||
using iterator = typename base_type::iterator;
|
||||
/*! @brief Reversed iterator type. */
|
||||
using reverse_iterator = typename base_type::reverse_iterator;
|
||||
/*! @brief Iterable group type. */
|
||||
using iterable = iterable_adaptor<extended_group_iterator>;
|
||||
using iterable = iterable_adaptor<internal::extended_group_iterator<iterator, owned_t<storage_type<Owned>...>, get_t<storage_type<Get>...>>>;
|
||||
|
||||
/*! @brief Default constructor to use to create empty, invalid groups. */
|
||||
basic_group() ENTT_NOEXCEPT
|
||||
@@ -825,8 +771,7 @@ public:
|
||||
* @return An iterable object to use to _visit_ the group.
|
||||
*/
|
||||
[[nodiscard]] iterable each() const ENTT_NOEXCEPT {
|
||||
iterator last = length ? std::get<0>(pools)->basic_common_type::end() : iterator{};
|
||||
return {extended_group_iterator{last - *length, pools}, extended_group_iterator{last, pools}};
|
||||
return {{begin(), pools}, {end(), pools}};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user