Browse Source

dense_map: use underlying iterators to exploit their checks

Michele Caini 4 years ago
parent
commit
bd3df1e06a
1 changed files with 25 additions and 21 deletions
  1. 25 21
      src/entt/container/dense_map.hpp

+ 25 - 21
src/entt/container/dense_map.hpp

@@ -58,7 +58,8 @@ struct dense_map_node final {
 
 template<typename It>
 class dense_map_iterator final {
-    friend dense_map_iterator<const std::remove_pointer_t<It> *>;
+    template<typename>
+    friend class dense_map_iterator;
 
     using first_type = decltype(std::as_const(std::declval<It>()->element.first));
     using second_type = decltype((std::declval<It>()->element.second));
@@ -75,8 +76,8 @@ public:
     dense_map_iterator(const It iter) ENTT_NOEXCEPT
         : it{iter} {}
 
-    template<bool Const = std::is_const_v<std::remove_pointer_t<It>>, typename = std::enable_if_t<Const>>
-    dense_map_iterator(const dense_map_iterator<std::remove_const_t<std::remove_pointer_t<It>> *> &other) ENTT_NOEXCEPT
+    template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
+    dense_map_iterator(const dense_map_iterator<Other> &other) ENTT_NOEXCEPT
         : it{other.it} {}
 
     dense_map_iterator &operator++() ENTT_NOEXCEPT {
@@ -177,7 +178,8 @@ template<typename ILhs, typename IRhs>
 
 template<typename It>
 class dense_map_local_iterator final {
-    friend dense_map_local_iterator<const std::remove_pointer_t<It> *>;
+    template<typename>
+    friend class dense_map_local_iterator;
 
     using first_type = decltype(std::as_const(std::declval<It>()->element.first));
     using second_type = decltype((std::declval<It>()->element.second));
@@ -195,8 +197,8 @@ public:
         : it{iter},
           offset{pos} {}
 
-    template<bool Const = std::is_const_v<std::remove_pointer_t<It>>, typename = std::enable_if_t<Const>>
-    dense_map_local_iterator(const dense_map_local_iterator<std::remove_const_t<std::remove_pointer_t<It>> *> &other) ENTT_NOEXCEPT
+    template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
+    dense_map_local_iterator(const dense_map_local_iterator<Other> &other) ENTT_NOEXCEPT
         : it{other.it},
           offset{other.offset} {}
 
@@ -358,13 +360,13 @@ public:
     /*! @brief Allocator type. */
     using allocator_type = Allocator;
     /*! @brief Input iterator type. */
-    using iterator = internal::dense_map_iterator<typename packed_container_type::pointer>;
+    using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
     /*! @brief Constant input iterator type. */
-    using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_pointer>;
+    using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
     /*! @brief Input iterator type. */
-    using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::pointer>;
+    using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
     /*! @brief Constant input iterator type. */
-    using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_pointer>;
+    using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
 
     /*! @brief Default constructor. */
     dense_map()
@@ -466,7 +468,7 @@ public:
      * @return An iterator to the first instance of the internal array.
      */
     [[nodiscard]] const_iterator cbegin() const ENTT_NOEXCEPT {
-        return packed.first().data();
+        return packed.first().begin();
     }
 
     /*! @copydoc cbegin */
@@ -476,7 +478,7 @@ public:
 
     /*! @copydoc begin */
     [[nodiscard]] iterator begin() ENTT_NOEXCEPT {
-        return packed.first().data();
+        return packed.first().begin();
     }
 
     /**
@@ -490,7 +492,7 @@ public:
      * internal array.
      */
     [[nodiscard]] const_iterator cend() const ENTT_NOEXCEPT {
-        return packed.first().data() + size();
+        return packed.first().end();
     }
 
     /*! @copydoc cend */
@@ -500,7 +502,7 @@ public:
 
     /*! @copydoc end */
     [[nodiscard]] iterator end() ENTT_NOEXCEPT {
-        return packed.first().data() + size();
+        return packed.first().end();
     }
 
     /**
@@ -662,11 +664,13 @@ public:
      * @return An iterator following the last removed element.
      */
     iterator erase(const_iterator first, const_iterator last) {
-        for(; last != first; --last) {
-            erase((last - 1u)->first);
+        const auto dist = first - cbegin();
+
+        for(auto from = last - cbegin(); from != dist; --from) {
+            erase(packed.first()[from - 1u].element.first);
         }
 
-        return (begin() + (last - cbegin()));
+        return (begin() + dist);
     }
 
     /**
@@ -798,7 +802,7 @@ public:
      * @return An iterator to the beginning of the given bucket.
      */
     [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
-        return {packed.first().data(), sparse.first()[index]};
+        return {packed.first().begin(), sparse.first()[index]};
     }
 
     /**
@@ -816,7 +820,7 @@ public:
      * @return An iterator to the beginning of the given bucket.
      */
     [[nodiscard]] local_iterator begin(const size_type index) {
-        return {packed.first().data(), sparse.first()[index]};
+        return {packed.first().begin(), sparse.first()[index]};
     }
 
     /**
@@ -825,7 +829,7 @@ public:
      * @return An iterator to the end of the given bucket.
      */
     [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
-        return {packed.first().data(), std::numeric_limits<size_type>::max()};
+        return {packed.first().begin(), std::numeric_limits<size_type>::max()};
     }
 
     /**
@@ -843,7 +847,7 @@ public:
      * @return An iterator to the end of the given bucket.
      */
     [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
-        return {packed.first().data(), std::numeric_limits<size_type>::max()};
+        return {packed.first().begin(), std::numeric_limits<size_type>::max()};
     }
 
     /**