Browse Source

iterator: review of input iterator pointer type

Michele Caini 4 years ago
parent
commit
4f1820bcad
4 changed files with 43 additions and 19 deletions
  1. 27 12
      src/entt/core/iterator.hpp
  2. 2 2
      src/entt/meta/meta.hpp
  3. 1 1
      src/entt/meta/range.hpp
  4. 13 4
      test/entt/core/iterator.cpp

+ 27 - 12
src/entt/core/iterator.hpp

@@ -2,6 +2,7 @@
 #define ENTT_CORE_ITERATOR_HPP
 #define ENTT_CORE_ITERATOR_HPP
 
 
 #include <memory>
 #include <memory>
+#include <utility>
 #include "../config/config.h"
 #include "../config/config.h"
 
 
 namespace entt {
 namespace entt {
@@ -11,19 +12,40 @@ namespace entt {
  * @tparam Type of wrapped value.
  * @tparam Type of wrapped value.
  */
  */
 template<typename Type>
 template<typename Type>
-struct input_iterator_proxy {
+struct input_iterator_pointer final {
+    /*! @brief Pointer type. */
+    using pointer = decltype(std::addressof(std::declval<Type &>()));
+
+    /*! @brief Default copy constructor, deleted on purpose. */
+    input_iterator_pointer(const input_iterator_pointer &) = delete;
+
+    /*! @brief Default move constructor. */
+    input_iterator_pointer(input_iterator_pointer &&) = default;
+
     /**
     /**
-     * @brief Constructs a proxy object from a given value.
+     * @brief Constructs a proxy object by move.
      * @param val Value to use to initialize the proxy object.
      * @param val Value to use to initialize the proxy object.
      */
      */
-    input_iterator_proxy(Type &&val)
-        : value{std::forward<Type>(val)} {}
+    input_iterator_pointer(Type &&val)
+        : value{std::move(val)} {}
+
+    /**
+     * @brief Default copy assignment operator, deleted on purpose.
+     * @return This proxy object.
+     */
+    input_iterator_pointer &operator=(const input_iterator_pointer &) = delete;
+
+    /**
+     * @brief Default move assignment operator.
+     * @return This proxy object.
+     */
+    input_iterator_pointer &operator=(input_iterator_pointer &&) = default;
 
 
     /**
     /**
      * @brief Access operator for accessing wrapped values.
      * @brief Access operator for accessing wrapped values.
      * @return A pointer to the wrapped value.
      * @return A pointer to the wrapped value.
      */
      */
-    [[nodiscard]] Type *operator->() ENTT_NOEXCEPT {
+    [[nodiscard]] pointer operator->() ENTT_NOEXCEPT {
         return std::addressof(value);
         return std::addressof(value);
     }
     }
 
 
@@ -31,13 +53,6 @@ private:
     Type value;
     Type value;
 };
 };
 
 
-/**
- * @brief Deduction guide.
- * @tparam Type Type of wrapped value.
- */
-template<typename Type>
-input_iterator_proxy(Type &&) -> input_iterator_proxy<Type>;
-
 } // namespace entt
 } // namespace entt
 
 
 #endif
 #endif

+ 2 - 2
src/entt/meta/meta.hpp

@@ -1480,7 +1480,7 @@ public:
     /*! @brief Type of elements returned by the iterator. */
     /*! @brief Type of elements returned by the iterator. */
     using value_type = meta_any;
     using value_type = meta_any;
     /*! @brief Pointer type, it's a _safe_ temporary object. */
     /*! @brief Pointer type, it's a _safe_ temporary object. */
-    using pointer = input_iterator_proxy<value_type>;
+    using pointer = input_iterator_pointer<value_type>;
     /*! @brief Reference type, it's **not** an actual reference. */
     /*! @brief Reference type, it's **not** an actual reference. */
     using reference = value_type;
     using reference = value_type;
     /*! @brief Iterator category. */
     /*! @brief Iterator category. */
@@ -1686,7 +1686,7 @@ public:
     /*! @brief Type of elements returned by the iterator. */
     /*! @brief Type of elements returned by the iterator. */
     using value_type = std::pair<meta_any, meta_any>;
     using value_type = std::pair<meta_any, meta_any>;
     /*! @brief Pointer type, it's a _safe_ temporary object. */
     /*! @brief Pointer type, it's a _safe_ temporary object. */
-    using pointer = input_iterator_proxy<value_type>;
+    using pointer = input_iterator_pointer<value_type>;
     /*! @brief Reference type, it's **not** an actual reference. */
     /*! @brief Reference type, it's **not** an actual reference. */
     using reference = value_type;
     using reference = value_type;
     /*! @brief Iterator category. */
     /*! @brief Iterator category. */

+ 1 - 1
src/entt/meta/range.hpp

@@ -17,7 +17,7 @@ class meta_range {
     struct range_iterator {
     struct range_iterator {
         using difference_type = std::ptrdiff_t;
         using difference_type = std::ptrdiff_t;
         using value_type = Type;
         using value_type = Type;
-        using pointer = input_iterator_proxy<value_type>;
+        using pointer = input_iterator_pointer<value_type>;
         using reference = value_type;
         using reference = value_type;
         using iterator_category = std::input_iterator_tag;
         using iterator_category = std::input_iterator_tag;
         using node_type = Node;
         using node_type = Node;

+ 13 - 4
test/entt/core/iterator.cpp

@@ -1,3 +1,4 @@
+#include <utility>
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
 #include <entt/core/iterator.hpp>
 #include <entt/core/iterator.hpp>
 
 
@@ -5,9 +6,17 @@ struct clazz {
     int value{0};
     int value{0};
 };
 };
 
 
-TEST(Iterator, InputIteratorProxy) {
-    entt::input_iterator_proxy proxy{clazz{}};
-    proxy->value = 42;
+TEST(Iterator, InputIteratorPointer) {
+    static_assert(!std::is_default_constructible_v<entt::input_iterator_pointer<clazz>>);
+    static_assert(!std::is_copy_constructible_v<entt::input_iterator_pointer<clazz>>);
+    static_assert(std::is_move_constructible_v<entt::input_iterator_pointer<clazz>>);
+    static_assert(!std::is_copy_assignable_v<entt::input_iterator_pointer<clazz>>);
+    static_assert(std::is_move_assignable_v<entt::input_iterator_pointer<clazz>>);
 
 
-    ASSERT_EQ(proxy->value, 42);
+    clazz instance{};
+    entt::input_iterator_pointer ptr{std::move(instance)};
+    ptr->value = 42;
+
+    ASSERT_EQ(instance.value, 0);
+    ASSERT_EQ(ptr->value, 42);
 }
 }