iterator: review of input iterator pointer type

This commit is contained in:
Michele Caini
2021-10-01 10:24:05 +02:00
parent e375097e43
commit 4f1820bcad
4 changed files with 43 additions and 19 deletions

View File

@@ -2,6 +2,7 @@
#define ENTT_CORE_ITERATOR_HPP
#include <memory>
#include <utility>
#include "../config/config.h"
namespace entt {
@@ -11,19 +12,40 @@ namespace entt {
* @tparam Type of wrapped value.
*/
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.
*/
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.
* @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<typename Type>
input_iterator_proxy(Type &&) -> input_iterator_proxy<Type>;
} // namespace entt
#endif

View File

@@ -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<value_type>;
using pointer = input_iterator_pointer<value_type>;
/*! @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<meta_any, meta_any>;
/*! @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. */
using reference = value_type;
/*! @brief Iterator category. */

View File

@@ -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<value_type>;
using pointer = input_iterator_pointer<value_type>;
using reference = value_type;
using iterator_category = std::input_iterator_tag;
using node_type = Node;

View File

@@ -1,3 +1,4 @@
#include <utility>
#include <gtest/gtest.h>
#include <entt/core/iterator.hpp>
@@ -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<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);
}