From 4f1820bcade2509d3da48024a6f679e3ce8c2e4b Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 1 Oct 2021 10:24:05 +0200 Subject: [PATCH] iterator: review of input iterator pointer type --- src/entt/core/iterator.hpp | 39 +++++++++++++++++++++++++------------ src/entt/meta/meta.hpp | 4 ++-- src/entt/meta/range.hpp | 2 +- test/entt/core/iterator.cpp | 17 ++++++++++++---- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/src/entt/core/iterator.hpp b/src/entt/core/iterator.hpp index e62bee990..1588c8043 100644 --- a/src/entt/core/iterator.hpp +++ b/src/entt/core/iterator.hpp @@ -2,6 +2,7 @@ #define ENTT_CORE_ITERATOR_HPP #include +#include #include "../config/config.h" namespace entt { @@ -11,19 +12,40 @@ namespace entt { * @tparam Type of wrapped value. */ template -struct input_iterator_proxy { +struct input_iterator_pointer final { + /*! @brief Pointer type. */ + using pointer = decltype(std::addressof(std::declval())); + + /*! @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. */ - input_iterator_proxy(Type &&val) - : value{std::forward(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. * @return A pointer to the wrapped value. */ - [[nodiscard]] Type *operator->() ENTT_NOEXCEPT { + [[nodiscard]] pointer operator->() ENTT_NOEXCEPT { return std::addressof(value); } @@ -31,13 +53,6 @@ private: Type value; }; -/** - * @brief Deduction guide. - * @tparam Type Type of wrapped value. - */ -template -input_iterator_proxy(Type &&) -> input_iterator_proxy; - } // namespace entt #endif diff --git a/src/entt/meta/meta.hpp b/src/entt/meta/meta.hpp index 38219514b..c6712ad27 100644 --- a/src/entt/meta/meta.hpp +++ b/src/entt/meta/meta.hpp @@ -1480,7 +1480,7 @@ public: /*! @brief Type of elements returned by the iterator. */ using value_type = meta_any; /*! @brief Pointer type, it's a _safe_ temporary object. */ - using pointer = input_iterator_proxy; + using pointer = input_iterator_pointer; /*! @brief Reference type, it's **not** an actual reference. */ using reference = value_type; /*! @brief Iterator category. */ @@ -1686,7 +1686,7 @@ public: /*! @brief Type of elements returned by the iterator. */ using value_type = std::pair; /*! @brief Pointer type, it's a _safe_ temporary object. */ - using pointer = input_iterator_proxy; + using pointer = input_iterator_pointer; /*! @brief Reference type, it's **not** an actual reference. */ using reference = value_type; /*! @brief Iterator category. */ diff --git a/src/entt/meta/range.hpp b/src/entt/meta/range.hpp index 0b63697eb..53c015066 100644 --- a/src/entt/meta/range.hpp +++ b/src/entt/meta/range.hpp @@ -17,7 +17,7 @@ class meta_range { struct range_iterator { using difference_type = std::ptrdiff_t; using value_type = Type; - using pointer = input_iterator_proxy; + using pointer = input_iterator_pointer; using reference = value_type; using iterator_category = std::input_iterator_tag; using node_type = Node; diff --git a/test/entt/core/iterator.cpp b/test/entt/core/iterator.cpp index cb4f8bafc..b15d6ae24 100644 --- a/test/entt/core/iterator.cpp +++ b/test/entt/core/iterator.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -5,9 +6,17 @@ struct clazz { 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>); + static_assert(!std::is_copy_constructible_v>); + static_assert(std::is_move_constructible_v>); + static_assert(!std::is_copy_assignable_v>); + static_assert(std::is_move_assignable_v>); - 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); }