From 7ac10472dc3d84cdae093f27a31b6b6206166b60 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Mon, 26 Oct 2020 10:50:17 +0100 Subject: [PATCH] view/group: small review --- src/entt/entity/group.hpp | 128 +++++++++++++++++++++----------------- src/entt/entity/view.hpp | 39 ++++-------- 2 files changed, 83 insertions(+), 84 deletions(-) diff --git a/src/entt/entity/group.hpp b/src/entt/entity/group.hpp index daa7be9b9..34bc1b0c2 100644 --- a/src/entt/entity/group.hpp +++ b/src/entt/entity/group.hpp @@ -85,7 +85,7 @@ class basic_group, get_t> final { public: using difference_type = std::ptrdiff_t; - using value_type = decltype(std::tuple_cat(std::tuple::value_type>{}, std::declval().get({}))); + using value_type = decltype(std::tuple_cat(std::tuple{}, std::declval().get({}))); using pointer = void; using reference = value_type; using iterator_category = std::input_iterator_tag; @@ -601,19 +601,21 @@ class basic_group, get_t, Owned...> final template using pool_type = pool_t; - template - using component_iterator = decltype(std::declval>().begin()); - class iterable_group { friend class basic_group, get_t, Owned...>; - template - class iterable_group_iterator { + template + class iterable_group_iterator; + + template + class iterable_group_iterator, type_list> { friend class iterable_group; - iterable_group_iterator(const std::size_t idx, const basic_group &parent) ENTT_NOEXCEPT - : index{idx}, - group{parent} + template + iterable_group_iterator(It from, std::tuple args) ENTT_NOEXCEPT + : it{from}, + owned{std::get(args)...}, + get{std::get(args)...} {} public: @@ -624,11 +626,7 @@ class basic_group, get_t, Owned...> final using iterator_category = std::input_iterator_tag; iterable_group_iterator & operator++() ENTT_NOEXCEPT { - if constexpr(Reverse) { - return ++index, *this; - } else { - return --index, *this; - } + return ++it, std::apply([](auto &&... curr) { (++curr, ...); }, owned), *this; } iterable_group_iterator operator++(int) ENTT_NOEXCEPT { @@ -637,17 +635,15 @@ class basic_group, get_t, Owned...> final } [[nodiscard]] reference operator*() const ENTT_NOEXCEPT { - if constexpr(Reverse) { - const auto entt = group.data()[index]; - return std::tuple_cat(std::make_tuple(entt), group.get(entt, index)); - } else { - const auto entt = group.data()[index - 1u]; - return std::tuple_cat(std::make_tuple(entt), group.get(entt, index - 1u)); - } + return std::tuple_cat( + std::make_tuple(*it), + std::apply([](auto &&... curr) { return std::forward_as_tuple(*curr...); }, owned), + std::apply([entt = *it](auto &&... curr) { return std::forward_as_tuple(curr->get(entt)...); }, get) + ); } [[nodiscard]] bool operator==(const iterable_group_iterator &other) const ENTT_NOEXCEPT { - return other.index == index; + return other.it == it; } [[nodiscard]] bool operator!=(const iterable_group_iterator &other) const ENTT_NOEXCEPT { @@ -655,36 +651,59 @@ class basic_group, get_t, Owned...> final } private: - std::size_t index; - const basic_group group; + It it; + std::tuple owned; + std::tuple get; }; - iterable_group(const basic_group &parent) - : group{parent} + iterable_group(std::tuple *..., pool_type *...> cpools, const std::size_t &extent) + : pools{cpools}, + length{&extent} {} public: - using iterator = iterable_group_iterator; - using reverse_iterator = iterable_group_iterator; + using iterator = iterable_group_iterator< + typename basic_sparse_set::iterator, + type_list_cat_t, type_list<>, type_list>().end())>>...>, + type_list_cat_t, type_list<>, type_list *>>...> + >; + using reverse_iterator = iterable_group_iterator< + typename basic_sparse_set::reverse_iterator, + type_list_cat_t, type_list<>, type_list>().rbegin())>>...>, + type_list_cat_t, type_list<>, type_list *>>...> + >; [[nodiscard]] iterator begin() const ENTT_NOEXCEPT { - return iterator{group.size(), group}; + return iterator{ + std::get<0>(pools)->basic_sparse_set::end() - *length, + std::make_tuple((std::get *>(pools)->end() - *length)..., std::get *>(pools)...) + }; } [[nodiscard]] iterator end() const ENTT_NOEXCEPT { - return iterator{{}, group}; + return iterator{ + std::get<0>(pools)->basic_sparse_set::end(), + std::make_tuple((std::get *>(pools)->end())..., std::get *>(pools)...) + }; } [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT { - return reverse_iterator{{}, group}; + return reverse_iterator{ + std::get<0>(pools)->basic_sparse_set::rbegin(), + std::make_tuple((std::get *>(pools)->rbegin())..., std::get *>(pools)...) + }; } [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT { - return reverse_iterator{group.size(), group}; + return reverse_iterator{ + std::get<0>(pools)->basic_sparse_set::rbegin() + *length, + std::make_tuple((std::get *>(pools)->rbegin() + *length)..., std::get *>(pools)...) + }; } private: - const basic_group group; + const std::tuple *..., pool_type *...> pools; + const std::size_t *length; }; basic_group(const std::size_t &extent, pool_type &... opool, pool_type &... gpool) ENTT_NOEXCEPT @@ -692,36 +711,19 @@ class basic_group, get_t, Owned...> final length{&extent} {} - [[nodiscard]] decltype(auto) get(const Entity entt, const std::size_t index) const { - auto filter = [entt, index](auto *cpool) { - using value_type = typename std::remove_reference_t::value_type; - - if constexpr(is_eto_eligible_v) { - return std::tuple{}; - } else if constexpr((std::is_same_v> || ...)) { - return std::forward_as_tuple(cpool->raw()[index]); - } else { - return std::forward_as_tuple(cpool->get(entt)); - } - }; - - return std::tuple_cat(filter(std::get *>(pools))..., filter(std::get *>(pools))...); - } - template void traverse(Func func, type_list, type_list) const { [[maybe_unused]] auto it = std::make_tuple((std::get *>(pools)->end() - *length)...); [[maybe_unused]] auto data = std::get<0>(pools)->basic_sparse_set::end() - *length; for(auto next = *length; next; --next) { + const auto entt = *(data++); + auto component = std::tuple_cat(std::apply([](auto &&... curr) -> decltype(auto) { return std::forward_as_tuple(*(curr++)...); }, it), std::forward_as_tuple(std::get *>(pools)->get(entt)...)); + if constexpr(std::is_invocable_v({}))..., decltype(get({}))...>) { - const auto entt = *(data++); - func(entt, *(std::get>(it)++)..., std::get *>(pools)->get(entt)...); - } else if constexpr(sizeof...(Weak) == 0) { - func(*(std::get>(it)++)...); + std::apply(func, std::tuple_cat(std::make_tuple(entt), component)); } else { - const auto entt = *(data++); - func(*(std::get>(it)++)..., std::get *>(pools)->get(entt)...); + std::apply(func, component); } } } @@ -968,7 +970,19 @@ public: ENTT_ASSERT(contains(entt)); if constexpr(sizeof...(Component) == 0) { - return get(entt, std::get<0>(pools)->index(entt)); + auto filter = [entt, index = std::get<0>(pools)->index(entt)](auto *cpool) { + using value_type = typename std::remove_reference_t::value_type; + + if constexpr(is_eto_eligible_v) { + return std::tuple{}; + } else if constexpr((std::is_same_v> || ...)) { + return std::forward_as_tuple(cpool->raw()[index]); + } else { + return std::forward_as_tuple(cpool->get(entt)); + } + }; + + return std::tuple_cat(filter(std::get *>(pools))..., filter(std::get *>(pools))...); } else if constexpr(sizeof...(Component) == 1) { return (std::get *>(pools)->get(entt), ...); } else { @@ -1019,7 +1033,7 @@ public: * @return An iterable object to use to _visit_ the group. */ [[nodiscard]] iterable_group each() const ENTT_NOEXCEPT { - return iterable_group{*this}; + return iterable_group{pools, *length}; } /** diff --git a/src/entt/entity/view.hpp b/src/entt/entity/view.hpp index 0da21bbdd..bdef55906 100644 --- a/src/entt/entity/view.hpp +++ b/src/entt/entity/view.hpp @@ -164,7 +164,7 @@ class basic_view, Component...> final { public: using difference_type = std::ptrdiff_t; - using value_type = decltype(std::tuple_cat(std::tuple::value_type>{}, std::declval().get({}))); + using value_type = decltype(std::tuple_cat(std::tuple{}, std::declval().get({}))); using pointer = void; using reference = value_type; using iterator_category = std::input_iterator_tag; @@ -627,17 +627,18 @@ class basic_view, Component> final { class iterable_view { friend class basic_view, Component>; - template + template class iterable_view_iterator { friend class iterable_view; - iterable_view_iterator(It from, Other... data) ENTT_NOEXCEPT - : it{from, data...} + template + iterable_view_iterator(It... from, Discard...) ENTT_NOEXCEPT + : it{from...} {} public: using difference_type = std::ptrdiff_t; - using value_type = std::tuple::value_type, decltype(*std::declval())...>; + using value_type = decltype(std::tuple_cat(std::tuple{}, std::declval().get({}))); using pointer = void; using reference = value_type; using iterator_category = std::input_iterator_tag; @@ -656,7 +657,7 @@ class basic_view, Component> final { } [[nodiscard]] bool operator==(const iterable_view_iterator &other) const ENTT_NOEXCEPT { - return std::get(other.it) == std::get(it); + return std::get<0>(other.it) == std::get<0>(it); } [[nodiscard]] bool operator!=(const iterable_view_iterator &other) const ENTT_NOEXCEPT { @@ -664,7 +665,7 @@ class basic_view, Component> final { } private: - std::tuple it; + std::tuple it; }; iterable_view(pool_type &ref) @@ -684,35 +685,19 @@ class basic_view, Component> final { >; [[nodiscard]] iterator begin() const ENTT_NOEXCEPT { - if constexpr(is_eto_eligible_v) { - return iterator{pool->basic_sparse_set::begin()}; - } else { - return iterator{pool->basic_sparse_set::begin(), pool->begin()}; - } + return iterator{pool->basic_sparse_set::begin(), pool->begin()}; } [[nodiscard]] iterator end() const ENTT_NOEXCEPT { - if constexpr(is_eto_eligible_v) { - return iterator{pool->basic_sparse_set::end()}; - } else { - return iterator{pool->basic_sparse_set::end(), pool->end()}; - } + return iterator{pool->basic_sparse_set::end(), pool->end()}; } [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT { - if constexpr(is_eto_eligible_v) { - return reverse_iterator{pool->basic_sparse_set::rbegin()}; - } else { - return reverse_iterator{pool->basic_sparse_set::rbegin(), pool->rbegin()}; - } + return reverse_iterator{pool->basic_sparse_set::rbegin(), pool->rbegin()}; } [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT { - if constexpr(is_eto_eligible_v) { - return reverse_iterator{pool->basic_sparse_set::rend()}; - } else { - return reverse_iterator{pool->basic_sparse_set::rend(), pool->rend()}; - } + return reverse_iterator{pool->basic_sparse_set::rend(), pool->rend()}; } private: