From 75dd86e8ef168b50a52f17cf20df5ebe4e22466c Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 29 Jul 2020 18:50:31 +0200 Subject: [PATCH] sparse set: added reverse iterators --- src/entt/entity/sparse_set.hpp | 38 ++++++++++++++++++++++------ test/entt/entity/sparse_set.cpp | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 8 deletions(-) diff --git a/src/entt/entity/sparse_set.hpp b/src/entt/entity/sparse_set.hpp index 5732188e7..54dad2e61 100644 --- a/src/entt/entity/sparse_set.hpp +++ b/src/entt/entity/sparse_set.hpp @@ -180,6 +180,8 @@ public: using size_type = std::size_t; /*! @brief Random access iterator type. */ using iterator = sparse_set_iterator; + /*! @brief Reverse iterator type. */ + using reverse_iterator = const entity_type *; /*! @brief Default constructor. */ sparse_set() = default; @@ -284,10 +286,6 @@ public: * array. If the sparse set is empty, the returned iterator will be equal to * `end()`. * - * @note - * Random access iterators stay true to the order imposed by a call to - * `respect`. - * * @return An iterator to the first entity of the internal packed array. */ [[nodiscard]] iterator begin() const ENTT_NOEXCEPT { @@ -302,10 +300,6 @@ public: * the internal packed array. Attempting to dereference the returned * iterator results in undefined behavior. * - * @note - * Random access iterators stay true to the order imposed by a call to - * `respect`. - * * @return An iterator to the element following the last entity of the * internal packed array. */ @@ -313,6 +307,34 @@ public: return iterator{packed, {}}; } + /** + * @brief Returns a reverse iterator to the beginning. + * + * The returned iterator points to the first entity of the reversed internal + * packed array. If the sparse set is empty, the returned iterator will be + * equal to `rend()`. + * + * @return An iterator to the first entity of the reversed internal packed + * array. + */ + [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT { + return packed.data(); + } + + /** + * @brief Returns a reverse iterator to the end. + * + * The returned iterator points to the element following the last entity in + * the reversed internal packed array. Attempting to dereference the + * returned iterator results in undefined behavior. + * + * @return An iterator to the element following the last entity of the + * reversed internal packed array. + */ + [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT { + return rbegin() + packed.size(); + } + /** * @brief Finds an entity. * @param entt A valid entity identifier. diff --git a/test/entt/entity/sparse_set.cpp b/test/entt/entity/sparse_set.cpp index 8e1933a2a..35b3253b1 100644 --- a/test/entt/entity/sparse_set.cpp +++ b/test/entt/entity/sparse_set.cpp @@ -183,6 +183,50 @@ TEST(SparseSet, Iterator) { ASSERT_EQ(*begin.operator->(), entt::entity{3}); } +TEST(SparseSet, ReverseIterator) { + using reverse_iterator = typename entt::sparse_set::reverse_iterator; + + entt::sparse_set set; + set.emplace(entt::entity{3}); + + reverse_iterator end{set.rbegin()}; + reverse_iterator begin{}; + begin = set.rend(); + std::swap(begin, end); + + ASSERT_EQ(begin, set.rbegin()); + ASSERT_EQ(end, set.rend()); + ASSERT_NE(begin, end); + + ASSERT_EQ(begin++, set.rbegin()); + ASSERT_EQ(begin--, set.rend()); + + ASSERT_EQ(begin+1, set.rend()); + ASSERT_EQ(end-1, set.rbegin()); + + ASSERT_EQ(++begin, set.rend()); + ASSERT_EQ(--begin, set.rbegin()); + + ASSERT_EQ(begin += 1, set.rend()); + ASSERT_EQ(begin -= 1, set.rbegin()); + + ASSERT_EQ(begin + (end - begin), set.rend()); + ASSERT_EQ(begin - (begin - end), set.rend()); + + ASSERT_EQ(end - (end - begin), set.rbegin()); + ASSERT_EQ(end + (begin - end), set.rbegin()); + + ASSERT_EQ(begin[0], *set.rbegin()); + + ASSERT_LT(begin, end); + ASSERT_LE(begin, set.rbegin()); + + ASSERT_GT(end, begin); + ASSERT_GE(end, set.rend()); + + ASSERT_EQ(*begin, entt::entity{3}); +} + TEST(SparseSet, Find) { entt::sparse_set set; set.emplace(entt::entity{3});