Browse Source

meta: make meta_sequence_container::meta_iterator model a bidirectional iterator (and keep staying in the input iterator category)

Michele Caini 4 years ago
parent
commit
21f00cf251
2 changed files with 44 additions and 9 deletions
  1. 39 6
      src/entt/meta/meta.hpp
  2. 5 3
      test/entt/meta/meta_container.cpp

+ 39 - 6
src/entt/meta/meta.hpp

@@ -1484,18 +1484,44 @@ public:
         : vtable{&basic_vtable<It>},
           handle{std::move(iter)} {}
 
-    /*! @brief Pre-increment operator. @return This iterator. */
+    /**
+     * @brief Pre-increment operator.
+     * @return This iterator.
+     */
     meta_iterator &operator++() ENTT_NOEXCEPT {
         const std::ptrdiff_t diff{1};
-        return vtable(operation::incr, handle, &diff), *this;
+        vtable(operation::incr, handle, &diff);
+        return *this;
     }
 
-    /*! @brief Post-increment operator. @return This iterator. */
+    /**
+     * @brief Post-increment operator.
+     * @return This iterator.
+     */
     meta_iterator operator++(int) ENTT_NOEXCEPT {
         meta_iterator orig = *this;
         return ++(*this), orig;
     }
 
+    /**
+     * @brief Pre-decrement operator.
+     * @return This iterator.
+     */
+    meta_iterator &operator--() ENTT_NOEXCEPT {
+        const std::ptrdiff_t diff{-1};
+        vtable(operation::incr, handle, &diff);
+        return *this;
+    }
+
+    /**
+     * @brief Post-decrement operator.
+     * @return This iterator.
+     */
+    meta_iterator operator--(int) ENTT_NOEXCEPT {
+        meta_iterator orig = *this;
+        return --(*this), orig;
+    }
+
     /**
      * @brief Indirection operator for accessing the pointed opaque object.
      * @return The element to which the iterator points.
@@ -1692,12 +1718,19 @@ public:
         : vtable{&basic_vtable<KeyOnly, It>},
           handle{std::move(iter)} {}
 
-    /*! @brief Pre-increment operator. @return This iterator. */
+    /**
+     * @brief Pre-increment operator.
+     * @return This iterator.
+     */
     meta_iterator &operator++() ENTT_NOEXCEPT {
-        return vtable(operation::incr, handle, nullptr), *this;
+        vtable(operation::incr, handle, nullptr);
+        return *this;
     }
 
-    /*! @brief Post-increment operator. @return This iterator. */
+    /**
+     * @brief Post-increment operator.
+     * @return This iterator.
+     */
     meta_iterator operator++(int) ENTT_NOEXCEPT {
         meta_iterator orig = *this;
         return ++(*this), orig;

+ 5 - 3
test/entt/meta/meta_container.cpp

@@ -77,14 +77,16 @@ TEST_F(MetaContainer, SequenceContainerIterator) {
     ASSERT_FALSE(first == last);
     ASSERT_TRUE(first != last);
 
-    ASSERT_NE(first, last);
     ASSERT_EQ((first++)->cast<int>(), 2);
     ASSERT_EQ((++first)->cast<int>(), 4);
-    ASSERT_NE(first++, last);
-    ASSERT_EQ(first, last);
 
+    ASSERT_NE(first++, last);
     ASSERT_TRUE(first == last);
     ASSERT_FALSE(first != last);
+    ASSERT_EQ(first--, last);
+
+    ASSERT_EQ((first--)->cast<int>(), 4);
+    ASSERT_EQ((--first)->cast<int>(), 2);
 }
 
 TEST_F(MetaContainer, AssociativeContainerIterator) {