storage: added reverse iterators
This commit is contained in:
@@ -165,6 +165,11 @@ public:
|
||||
using iterator = storage_iterator<false>;
|
||||
/*! @brief Constant random access iterator type. */
|
||||
using const_iterator = storage_iterator<true>;
|
||||
/*! @brief Reverse iterator type. */
|
||||
using reverse_iterator = Type *;
|
||||
/*! @brief Constant reverse iterator type. */
|
||||
using const_reverse_iterator = const Type *;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Increases the capacity of a storage.
|
||||
@@ -209,14 +214,10 @@ public:
|
||||
/**
|
||||
* @brief Returns an iterator to the beginning.
|
||||
*
|
||||
* The returned iterator points to the first instance of the given type. If
|
||||
* the storage is empty, the returned iterator will be equal to `end()`.
|
||||
* The returned iterator points to the first instance of the internal array.
|
||||
* If the storage is empty, the returned iterator will be equal to `end()`.
|
||||
*
|
||||
* @note
|
||||
* Random access iterators stay true to the order imposed by a call to
|
||||
* either `sort` or `respect`.
|
||||
*
|
||||
* @return An iterator to the first instance of the given type.
|
||||
* @return An iterator to the first instance of the internal array.
|
||||
*/
|
||||
[[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
|
||||
const typename traits_type::difference_type pos = underlying_type::size();
|
||||
@@ -238,15 +239,11 @@ public:
|
||||
* @brief Returns an iterator to the end.
|
||||
*
|
||||
* The returned iterator points to the element following the last instance
|
||||
* of the given type. Attempting to dereference the returned iterator
|
||||
* of the internal 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
|
||||
* either `sort` or `respect`.
|
||||
*
|
||||
* @return An iterator to the element following the last instance of the
|
||||
* given type.
|
||||
* internal array.
|
||||
*/
|
||||
[[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
|
||||
return const_iterator{instances, {}};
|
||||
@@ -262,6 +259,53 @@ public:
|
||||
return iterator{instances, {}};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a reverse iterator to the beginning.
|
||||
*
|
||||
* The returned iterator points to the first instance of the reversed
|
||||
* internal array. If the storage is empty, the returned iterator will be
|
||||
* equal to `rend()`.
|
||||
*
|
||||
* @return An iterator to the first instance of the reversed internal array.
|
||||
*/
|
||||
[[nodiscard]] const_reverse_iterator crbegin() const ENTT_NOEXCEPT {
|
||||
return instances.data();
|
||||
}
|
||||
|
||||
/*! @copydoc crbegin */
|
||||
[[nodiscard]] const_reverse_iterator rbegin() const ENTT_NOEXCEPT {
|
||||
return crbegin();
|
||||
}
|
||||
|
||||
/*! @copydoc rbegin */
|
||||
[[nodiscard]] reverse_iterator rbegin() ENTT_NOEXCEPT {
|
||||
return instances.data();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a reverse iterator to the end.
|
||||
*
|
||||
* The returned iterator points to the element following the last instance
|
||||
* of the reversed internal array. Attempting to dereference the returned
|
||||
* iterator results in undefined behavior.
|
||||
*
|
||||
* @return An iterator to the element following the last instance of the
|
||||
* reversed internal array.
|
||||
*/
|
||||
[[nodiscard]] const_reverse_iterator crend() const ENTT_NOEXCEPT {
|
||||
return crbegin() + instances.size();
|
||||
}
|
||||
|
||||
/*! @copydoc crend */
|
||||
[[nodiscard]] const_reverse_iterator rend() const ENTT_NOEXCEPT {
|
||||
return crend();
|
||||
}
|
||||
|
||||
/*! @copydoc rend */
|
||||
[[nodiscard]] reverse_iterator rend() ENTT_NOEXCEPT {
|
||||
return rbegin() + instances.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the object associated with an entity.
|
||||
*
|
||||
|
||||
@@ -218,6 +218,90 @@ TEST(Storage, ConstIterator) {
|
||||
ASSERT_GE(cend, pool.cend());
|
||||
}
|
||||
|
||||
TEST(Storage, ReverseIterator) {
|
||||
using reverse_iterator = typename entt::storage<entt::entity, boxed_int>::reverse_iterator;
|
||||
|
||||
entt::storage<entt::entity, boxed_int> pool;
|
||||
pool.emplace(entt::entity{3}, 42);
|
||||
|
||||
reverse_iterator end{pool.rbegin()};
|
||||
reverse_iterator begin{};
|
||||
begin = pool.rend();
|
||||
std::swap(begin, end);
|
||||
|
||||
ASSERT_EQ(begin, pool.rbegin());
|
||||
ASSERT_EQ(end, pool.rend());
|
||||
ASSERT_NE(begin, end);
|
||||
|
||||
ASSERT_EQ(begin++, pool.rbegin());
|
||||
ASSERT_EQ(begin--, pool.rend());
|
||||
|
||||
ASSERT_EQ(begin+1, pool.rend());
|
||||
ASSERT_EQ(end-1, pool.rbegin());
|
||||
|
||||
ASSERT_EQ(++begin, pool.rend());
|
||||
ASSERT_EQ(--begin, pool.rbegin());
|
||||
|
||||
ASSERT_EQ(begin += 1, pool.rend());
|
||||
ASSERT_EQ(begin -= 1, pool.rbegin());
|
||||
|
||||
ASSERT_EQ(begin + (end - begin), pool.rend());
|
||||
ASSERT_EQ(begin - (begin - end), pool.rend());
|
||||
|
||||
ASSERT_EQ(end - (end - begin), pool.rbegin());
|
||||
ASSERT_EQ(end + (begin - end), pool.rbegin());
|
||||
|
||||
ASSERT_EQ(begin[0].value, pool.rbegin()->value);
|
||||
|
||||
ASSERT_LT(begin, end);
|
||||
ASSERT_LE(begin, pool.rbegin());
|
||||
|
||||
ASSERT_GT(end, begin);
|
||||
ASSERT_GE(end, pool.rend());
|
||||
}
|
||||
|
||||
TEST(Storage, ConstReverseIterator) {
|
||||
using const_reverse_iterator = typename entt::storage<entt::entity, boxed_int>::const_reverse_iterator;
|
||||
|
||||
entt::storage<entt::entity, boxed_int> pool;
|
||||
pool.emplace(entt::entity{3}, 42);
|
||||
|
||||
const_reverse_iterator cend{pool.crbegin()};
|
||||
const_reverse_iterator cbegin{};
|
||||
cbegin = pool.crend();
|
||||
std::swap(cbegin, cend);
|
||||
|
||||
ASSERT_EQ(cbegin, pool.crbegin());
|
||||
ASSERT_EQ(cend, pool.crend());
|
||||
ASSERT_NE(cbegin, cend);
|
||||
|
||||
ASSERT_EQ(cbegin++, pool.crbegin());
|
||||
ASSERT_EQ(cbegin--, pool.crend());
|
||||
|
||||
ASSERT_EQ(cbegin+1, pool.crend());
|
||||
ASSERT_EQ(cend-1, pool.crbegin());
|
||||
|
||||
ASSERT_EQ(++cbegin, pool.crend());
|
||||
ASSERT_EQ(--cbegin, pool.crbegin());
|
||||
|
||||
ASSERT_EQ(cbegin += 1, pool.crend());
|
||||
ASSERT_EQ(cbegin -= 1, pool.crbegin());
|
||||
|
||||
ASSERT_EQ(cbegin + (cend - cbegin), pool.crend());
|
||||
ASSERT_EQ(cbegin - (cbegin - cend), pool.crend());
|
||||
|
||||
ASSERT_EQ(cend - (cend - cbegin), pool.crbegin());
|
||||
ASSERT_EQ(cend + (cbegin - cend), pool.crbegin());
|
||||
|
||||
ASSERT_EQ(cbegin[0].value, pool.crbegin()->value);
|
||||
|
||||
ASSERT_LT(cbegin, cend);
|
||||
ASSERT_LE(cbegin, pool.crbegin());
|
||||
|
||||
ASSERT_GT(cend, cbegin);
|
||||
ASSERT_GE(cend, pool.crend());
|
||||
}
|
||||
|
||||
TEST(Storage, Raw) {
|
||||
entt::storage<entt::entity, int> pool;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user