Jelajahi Sumber

dense_hash_map/set: avoid exposing internal details from iterators

Michele Caini 4 tahun lalu
induk
melakukan
69ef3efd2d

+ 23 - 21
src/entt/container/dense_hash_map.hpp

@@ -109,9 +109,14 @@ public:
         return *operator->();
     }
 
-    [[nodiscard]] iterator_type base() const ENTT_NOEXCEPT {
-        return it;
-    }
+    template<typename ILhs, typename IRhs>
+    friend auto operator-(const dense_hash_map_iterator<ILhs> &, const dense_hash_map_iterator<IRhs> &) ENTT_NOEXCEPT;
+
+    template<typename ILhs, typename IRhs>
+    friend bool operator==(const dense_hash_map_iterator<ILhs> &, const dense_hash_map_iterator<IRhs> &) ENTT_NOEXCEPT;
+
+    template<typename ILhs, typename IRhs>
+    friend bool operator<(const dense_hash_map_iterator<ILhs> &, const dense_hash_map_iterator<IRhs> &) ENTT_NOEXCEPT;
 
 private:
     iterator_type it;
@@ -119,12 +124,12 @@ private:
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] auto operator-(const dense_hash_map_iterator<ILhs> &lhs, const dense_hash_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() - rhs.base();
+    return lhs.it - rhs.it;
 }
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator==(const dense_hash_map_iterator<ILhs> &lhs, const dense_hash_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() == rhs.base();
+    return lhs.it == rhs.it;
 }
 
 template<typename ILhs, typename IRhs>
@@ -134,12 +139,12 @@ template<typename ILhs, typename IRhs>
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator<(const dense_hash_map_iterator<ILhs> &lhs, const dense_hash_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() < rhs.base();
+    return lhs.it < rhs.it;
 }
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator>(const dense_hash_map_iterator<ILhs> &lhs, const dense_hash_map_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() > rhs.base();
+    return rhs < lhs;
 }
 
 template<typename ILhs, typename IRhs>
@@ -170,15 +175,15 @@ public:
 
     dense_hash_map_local_iterator(iterator_type iter, const std::size_t pos) ENTT_NOEXCEPT
         : it{iter},
-          curr{pos} {}
+          offset{pos} {}
 
     template<bool Const = std::is_const_v<std::remove_pointer_t<iterator_type>>, typename = std::enable_if_t<Const>>
     dense_hash_map_local_iterator(const dense_hash_map_local_iterator<std::remove_const_t<std::remove_pointer_t<iterator_type>> *> &other)
         : it{other.it},
-          curr{other.curr} {}
+          offset{other.offset} {}
 
     dense_hash_map_local_iterator &operator++() ENTT_NOEXCEPT {
-        return curr = it[curr].next, *this;
+        return offset = it[offset].next, *this;
     }
 
     dense_hash_map_local_iterator operator++(int) ENTT_NOEXCEPT {
@@ -187,28 +192,25 @@ public:
     }
 
     [[nodiscard]] pointer operator->() const {
-        return std::addressof(it[curr].element);
+        return std::addressof(it[offset].element);
     }
 
     [[nodiscard]] reference operator*() const {
         return *operator->();
     }
 
-    [[nodiscard]] iterator_type base() const ENTT_NOEXCEPT {
-        return (it + curr);
+    [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
+        return offset;
     }
 
-    template<typename ILhs, typename IRhs>
-    friend bool operator==(const dense_hash_map_local_iterator<ILhs> &, const dense_hash_map_local_iterator<IRhs> &) ENTT_NOEXCEPT;
-
 private:
     iterator_type it;
-    std::size_t curr;
+    std::size_t offset;
 };
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator==(const dense_hash_map_local_iterator<ILhs> &lhs, const dense_hash_map_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.curr == rhs.curr;
+    return lhs.index() == rhs.index();
 }
 
 template<typename ILhs, typename IRhs>
@@ -257,7 +259,7 @@ class dense_hash_map final {
     [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) {
         for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
             if(packed.second()(it->first, key)) {
-                return iterator{it.base()};
+                return begin() + it.index();
             }
         }
 
@@ -266,9 +268,9 @@ class dense_hash_map final {
 
     template<typename Other>
     [[nodiscard]] auto constrained_find(const Other &key, std::size_t bucket) const {
-        for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
+        for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
             if(packed.second()(it->first, key)) {
-                return const_iterator{it.base()};
+                return cbegin() + it.index();
             }
         }
 

+ 23 - 21
src/entt/container/dense_hash_set.hpp

@@ -109,9 +109,14 @@ public:
         return *operator->();
     }
 
-    [[nodiscard]] iterator_type base() const ENTT_NOEXCEPT {
-        return it;
-    }
+    template<typename ILhs, typename IRhs>
+    friend auto operator-(const dense_hash_set_iterator<ILhs> &, const dense_hash_set_iterator<IRhs> &) ENTT_NOEXCEPT;
+
+    template<typename ILhs, typename IRhs>
+    friend bool operator==(const dense_hash_set_iterator<ILhs> &, const dense_hash_set_iterator<IRhs> &) ENTT_NOEXCEPT;
+
+    template<typename ILhs, typename IRhs>
+    friend bool operator<(const dense_hash_set_iterator<ILhs> &, const dense_hash_set_iterator<IRhs> &) ENTT_NOEXCEPT;
 
 private:
     iterator_type it;
@@ -119,12 +124,12 @@ private:
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] auto operator-(const dense_hash_set_iterator<ILhs> &lhs, const dense_hash_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() - rhs.base();
+    return lhs.it - rhs.it;
 }
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator==(const dense_hash_set_iterator<ILhs> &lhs, const dense_hash_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() == rhs.base();
+    return lhs.it == rhs.it;
 }
 
 template<typename ILhs, typename IRhs>
@@ -134,12 +139,12 @@ template<typename ILhs, typename IRhs>
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator<(const dense_hash_set_iterator<ILhs> &lhs, const dense_hash_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() < rhs.base();
+    return lhs.it < rhs.it;
 }
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator>(const dense_hash_set_iterator<ILhs> &lhs, const dense_hash_set_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.base() > rhs.base();
+    return rhs < lhs;
 }
 
 template<typename ILhs, typename IRhs>
@@ -170,15 +175,15 @@ public:
 
     dense_hash_set_local_iterator(iterator_type iter, const std::size_t pos) ENTT_NOEXCEPT
         : it{iter},
-          curr{pos} {}
+          offset{pos} {}
 
     template<bool Const = std::is_const_v<std::remove_pointer_t<iterator_type>>, typename = std::enable_if_t<Const>>
     dense_hash_set_local_iterator(const dense_hash_set_local_iterator<std::remove_const_t<std::remove_pointer_t<iterator_type>> *> &other)
         : it{other.it},
-          curr{other.curr} {}
+          offset{other.offset} {}
 
     dense_hash_set_local_iterator &operator++() ENTT_NOEXCEPT {
-        return curr = it[curr].next, *this;
+        return offset = it[offset].next, *this;
     }
 
     dense_hash_set_local_iterator operator++(int) ENTT_NOEXCEPT {
@@ -187,28 +192,25 @@ public:
     }
 
     [[nodiscard]] pointer operator->() const {
-        return std::addressof(it[curr].element);
+        return std::addressof(it[offset].element);
     }
 
     [[nodiscard]] reference operator*() const {
         return *operator->();
     }
 
-    [[nodiscard]] iterator_type base() const ENTT_NOEXCEPT {
-        return (it + curr);
+    [[nodiscard]] std::size_t index() const ENTT_NOEXCEPT {
+        return offset;
     }
 
-    template<typename ILhs, typename IRhs>
-    friend bool operator==(const dense_hash_set_local_iterator<ILhs> &, const dense_hash_set_local_iterator<IRhs> &) ENTT_NOEXCEPT;
-
 private:
     iterator_type it;
-    std::size_t curr;
+    std::size_t offset;
 };
 
 template<typename ILhs, typename IRhs>
 [[nodiscard]] bool operator==(const dense_hash_set_local_iterator<ILhs> &lhs, const dense_hash_set_local_iterator<IRhs> &rhs) ENTT_NOEXCEPT {
-    return lhs.curr == rhs.curr;
+    return lhs.index() == rhs.index();
 }
 
 template<typename ILhs, typename IRhs>
@@ -256,7 +258,7 @@ class dense_hash_set final {
     [[nodiscard]] auto constrained_find(const Other &value, std::size_t bucket) {
         for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
             if(packed.second()(*it, value)) {
-                return iterator{it.base()};
+                return begin() + it.index();
             }
         }
 
@@ -265,9 +267,9 @@ class dense_hash_set final {
 
     template<typename Other>
     [[nodiscard]] auto constrained_find(const Other &value, std::size_t bucket) const {
-        for(auto it = begin(bucket), last = end(bucket); it != last; ++it) {
+        for(auto it = cbegin(bucket), last = cend(bucket); it != last; ++it) {
             if(packed.second()(*it, value)) {
-                return const_iterator{it.base()};
+                return cbegin() + it.index();
             }
         }
 

+ 0 - 6
test/entt/container/dense_hash_map.cpp

@@ -920,11 +920,8 @@ TEST(DenseHashMap, LocalIterator) {
     ASSERT_EQ(begin->first, 3u + minimum_bucket_count);
     ASSERT_EQ((*begin).second, 99u);
 
-    ASSERT_EQ(begin.base(), map.begin().base() + 1u);
     ASSERT_EQ(begin++, map.begin(3u));
-    ASSERT_EQ(begin.base(), map.begin().base());
     ASSERT_EQ(++begin, map.end(3u));
-    ASSERT_NE(begin.base(), map.end().base());
 }
 
 TEST(DenseHashMap, ConstLocalIterator) {
@@ -951,11 +948,8 @@ TEST(DenseHashMap, ConstLocalIterator) {
     ASSERT_EQ(cbegin->first, 3u + minimum_bucket_count);
     ASSERT_EQ((*cbegin).second, 99u);
 
-    ASSERT_EQ(cbegin.base(), map.cbegin().base() + 1u);
     ASSERT_EQ(cbegin++, map.begin(3u));
-    ASSERT_EQ(cbegin.base(), map.cbegin().base());
     ASSERT_EQ(++cbegin, map.end(3u));
-    ASSERT_NE(cbegin.base(), map.cend().base());
 }
 
 TEST(DenseHashMap, LocalIteratorConversion) {

+ 0 - 6
test/entt/container/dense_hash_set.cpp

@@ -674,11 +674,8 @@ TEST(DenseHashSet, LocalIterator) {
     ASSERT_EQ(*begin.operator->(), 3u + minimum_bucket_count);
     ASSERT_EQ(*begin, 3u + minimum_bucket_count);
 
-    ASSERT_EQ(begin.base(), set.begin().base() + 1u);
     ASSERT_EQ(begin++, set.begin(3u));
-    ASSERT_EQ(begin.base(), set.begin().base());
     ASSERT_EQ(++begin, set.end(3u));
-    ASSERT_NE(begin.base(), set.end().base());
 }
 
 TEST(DenseHashSet, ConstLocalIterator) {
@@ -705,11 +702,8 @@ TEST(DenseHashSet, ConstLocalIterator) {
     ASSERT_EQ(*cbegin.operator->(), 3u + minimum_bucket_count);
     ASSERT_EQ(*cbegin, 3u + minimum_bucket_count);
 
-    ASSERT_EQ(cbegin.base(), set.cbegin().base() + 1u);
     ASSERT_EQ(cbegin++, set.begin(3u));
-    ASSERT_EQ(cbegin.base(), set.cbegin().base());
     ASSERT_EQ(++cbegin, set.end(3u));
-    ASSERT_NE(cbegin.base(), set.cend().base());
 }
 
 TEST(DenseHashSet, LocalIteratorConversion) {