diff --git a/src/entt/meta/range.hpp b/src/entt/meta/range.hpp index 2bbf33c38..6dd774d46 100644 --- a/src/entt/meta/range.hpp +++ b/src/entt/meta/range.hpp @@ -38,7 +38,7 @@ public: meta_range_iterator() noexcept : it{} {} - meta_range_iterator(It iter) noexcept + meta_range_iterator(const It iter) noexcept : it{iter} {} meta_range_iterator &operator++() noexcept { @@ -50,26 +50,93 @@ public: return ++(*this), orig; } - [[nodiscard]] reference operator*() const noexcept { - return std::make_pair(it->first, to_value(0, it->second)); + constexpr meta_range_iterator &operator--() noexcept { + return --it, *this; } - [[nodiscard]] pointer operator->() const noexcept { + constexpr meta_range_iterator operator--(int) noexcept { + meta_range_iterator orig = *this; + return operator--(), orig; + } + + constexpr meta_range_iterator &operator+=(const difference_type value) noexcept { + it += value; + return *this; + } + + constexpr meta_range_iterator operator+(const difference_type value) const noexcept { + meta_range_iterator copy = *this; + return (copy += value); + } + + constexpr meta_range_iterator &operator-=(const difference_type value) noexcept { + return (*this += -value); + } + + constexpr meta_range_iterator operator-(const difference_type value) const noexcept { + return (*this + -value); + } + + [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept { + return {it[value].first, to_value(0, it[value].second)}; + } + + [[nodiscard]] constexpr pointer operator->() const noexcept { return operator*(); } - [[nodiscard]] bool operator==(const meta_range_iterator &other) const noexcept { - return it == other.it; + [[nodiscard]] constexpr reference operator*() const noexcept { + return {it->first, to_value(0, it->second)}; } - [[nodiscard]] bool operator!=(const meta_range_iterator &other) const noexcept { - return !(*this == other); - } + template + friend constexpr std::ptrdiff_t operator-(const meta_range_iterator &, const meta_range_iterator &) noexcept; + + template + friend constexpr bool operator==(const meta_range_iterator &, const meta_range_iterator &) noexcept; + + template + friend constexpr bool operator<(const meta_range_iterator &, const meta_range_iterator &) noexcept; private: It it; }; +template +[[nodiscard]] constexpr std::ptrdiff_t operator-(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it - rhs.it; +} + +template +[[nodiscard]] constexpr bool operator==(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it == rhs.it; +} + +template +[[nodiscard]] constexpr bool operator!=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs == rhs); +} + +template +[[nodiscard]] constexpr bool operator<(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return lhs.it < rhs.it; +} + +template +[[nodiscard]] constexpr bool operator>(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return rhs < lhs; +} + +template +[[nodiscard]] constexpr bool operator<=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs > rhs); +} + +template +[[nodiscard]] constexpr bool operator>=(const meta_range_iterator &lhs, const meta_range_iterator &rhs) noexcept { + return !(lhs < rhs); +} + } // namespace internal /** diff --git a/test/entt/meta/meta_range.cpp b/test/entt/meta/meta_range.cpp index 9b747411d..2d350d0e8 100644 --- a/test/entt/meta/meta_range.cpp +++ b/test/entt/meta/meta_range.cpp @@ -11,8 +11,7 @@ struct MetaRange: ::testing::Test { void SetUp() override { using namespace entt::literals; - entt::meta().type("int"_hs); - entt::meta().type("double"_hs); + entt::meta().type("int"_hs).data<42>("answer"_hs); } void TearDown() override { @@ -20,25 +19,77 @@ struct MetaRange: ::testing::Test { } }; -TEST_F(MetaRange, Range) { - using namespace entt::literals; - - auto range = entt::resolve(); - auto it = range.begin(); - - ASSERT_NE(it, range.end()); - ASSERT_TRUE(it != range.end()); - ASSERT_FALSE(it == range.end()); - - ASSERT_EQ(it->second.info(), entt::resolve().info()); - ASSERT_EQ((++it)->second.info(), entt::resolve("double"_hs).info()); - ASSERT_EQ((it++)->second.info(), entt::resolve().info()); - - ASSERT_EQ(it, range.end()); -} - TEST_F(MetaRange, EmptyRange) { entt::meta_reset(); auto range = entt::resolve(); ASSERT_EQ(range.begin(), range.end()); } + +TEST_F(MetaRange, Iterator) { + using namespace entt::literals; + + using iterator = typename decltype(entt::resolve())::iterator; + + static_assert(std::is_same_v>); + static_assert(std::is_same_v>>); + static_assert(std::is_same_v>); + + auto range = entt::resolve(); + + iterator end{range.begin()}; + iterator begin{}; + begin = range.end(); + std::swap(begin, end); + + ASSERT_EQ(begin, range.begin()); + ASSERT_EQ(end, range.end()); + ASSERT_NE(begin, end); + + ASSERT_EQ(begin++, range.begin()); + ASSERT_EQ(begin--, range.end()); + + ASSERT_EQ(begin + 1, range.end()); + ASSERT_EQ(end - 1, range.begin()); + + ASSERT_EQ(++begin, range.end()); + ASSERT_EQ(--begin, range.begin()); + + ASSERT_EQ(begin += 1, range.end()); + ASSERT_EQ(begin -= 1, range.begin()); + + ASSERT_EQ(begin + (end - begin), range.end()); + ASSERT_EQ(begin - (begin - end), range.end()); + + ASSERT_EQ(end - (end - begin), range.begin()); + ASSERT_EQ(end + (begin - end), range.begin()); + + ASSERT_EQ(begin[0u].first, range.begin()->first); + ASSERT_EQ(begin[0u].second, (*range.begin()).second); + + ASSERT_LT(begin, end); + ASSERT_LE(begin, range.begin()); + + ASSERT_GT(end, begin); + ASSERT_GE(end, range.end()); + + entt::meta().type("double"_hs); + range = entt::resolve(); + begin = range.begin(); + + ASSERT_EQ(begin[0u].first, entt::resolve().info().hash()); + ASSERT_EQ(begin[1u].second, entt::resolve("double"_hs)); +} + +TEST_F(MetaRange, DirectValue) { + using namespace entt::literals; + + auto type = entt::resolve(); + auto range = type.data(); + + ASSERT_NE(range.cbegin(), range.cend()); + + for(auto &&[id, data]: range) { + ASSERT_EQ(id, "answer"_hs); + ASSERT_EQ(data.get({}).cast(), 42); + } +}