meta_range: iterator review

This commit is contained in:
Michele Caini
2021-10-20 08:36:17 +02:00
parent 2271aa5b89
commit 75a0cefcb3
2 changed files with 68 additions and 45 deletions

View File

@@ -7,60 +7,80 @@
namespace entt {
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
namespace internal {
template<typename Type, typename Node>
struct meta_range_iterator {
using difference_type = std::ptrdiff_t;
using value_type = Type;
using pointer = input_iterator_pointer<value_type>;
using reference = value_type;
using iterator_category = std::input_iterator_tag;
using node_type = Node;
meta_range_iterator() ENTT_NOEXCEPT = default;
meta_range_iterator(node_type *head) ENTT_NOEXCEPT
: it{head} {}
meta_range_iterator &operator++() ENTT_NOEXCEPT {
return (it = it->next), *this;
}
meta_range_iterator operator++(int) ENTT_NOEXCEPT {
meta_range_iterator orig = *this;
return ++(*this), orig;
}
[[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
return it;
}
[[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
return operator*();
}
[[nodiscard]] const node_type *base() const ENTT_NOEXCEPT {
return it;
}
private:
node_type *it{};
};
template<typename Type, typename Node>
[[nodiscard]] bool operator==(const meta_range_iterator<Type, Node> &lhs, const meta_range_iterator<Type, Node> &rhs) ENTT_NOEXCEPT {
return lhs.base() == rhs.base();
}
template<typename Type, typename Node>
[[nodiscard]] bool operator!=(const meta_range_iterator<Type, Node> &lhs, const meta_range_iterator<Type, Node> &rhs) ENTT_NOEXCEPT {
return !(lhs == rhs);
}
} // namespace internal
/**
* Internal details not to be documented.
* @endcond
*/
/**
* @brief Iterable range to use to iterate all types of meta objects.
* @tparam Type Type of meta objects returned.
* @tparam Node Type of meta nodes iterated.
*/
template<typename Type, typename Node = typename Type::node_type>
class meta_range {
struct range_iterator {
using difference_type = std::ptrdiff_t;
using value_type = Type;
using pointer = input_iterator_pointer<value_type>;
using reference = value_type;
using iterator_category = std::input_iterator_tag;
using node_type = Node;
range_iterator() ENTT_NOEXCEPT = default;
range_iterator(node_type *head) ENTT_NOEXCEPT
: it{head} {}
range_iterator &operator++() ENTT_NOEXCEPT {
return (it = it->next), *this;
}
range_iterator operator++(int) ENTT_NOEXCEPT {
range_iterator orig = *this;
return ++(*this), orig;
}
[[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
return it;
}
[[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
return operator*();
}
[[nodiscard]] bool operator==(const range_iterator &other) const ENTT_NOEXCEPT {
return other.it == it;
}
[[nodiscard]] bool operator!=(const range_iterator &other) const ENTT_NOEXCEPT {
return !(*this == other);
}
private:
node_type *it{};
};
public:
struct meta_range {
/*! @brief Node type. */
using node_type = Node;
/*! @brief Input iterator type. */
using iterator = range_iterator;
using iterator = internal::meta_range_iterator<Type, Node>;
/*! @brief Constant input iterator type. */
using const_iterator = iterator;

View File

@@ -52,4 +52,7 @@ TEST_F(MetaRange, IteratorConversion) {
ASSERT_EQ(*it, entt::resolve<double>());
ASSERT_EQ(*it, *cit);
ASSERT_EQ(it, cit);
ASSERT_NE(++cit, it);
}