added Erase and EraseIf function to dali-vector 47/245247/2
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Tue, 6 Oct 2020 02:17:07 +0000 (11:17 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Wed, 7 Oct 2020 10:04:40 +0000 (19:04 +0900)
These functions uses erase-remove idiom for efficient
removal of more than one item from vector.
The signature is same as the standard erase() and erase_if()
function added to c++20.

Change-Id: I2d6769cde5b6acfbb03447b6576491021ab14fe1

automated-tests/src/dali/utc-Dali-Vector.cpp
dali/public-api/common/dali-vector.h

index f0dd410..7616cc0 100644 (file)
@@ -1389,6 +1389,108 @@ int UtcDaliVectorMoveAssignment(void)
   END_TEST;
 }
 
+int UtcDaliVectorEraseFreeFunction(void)
+{
+  tet_infoline("Testing Dali::Erase<Vector<int>>");
+
+  Vector<int> vector;
+
+  // erasing from empty vector
+  Dali::Erase(vector, 2);
+  DALI_TEST_EQUALS(ZERO, vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(ZERO, vector.Capacity(), TEST_LOCATION);
+
+
+  vector.PushBack(1);
+  vector.PushBack(2);
+  vector.PushBack(3);
+  vector.PushBack(4);
+  vector.PushBack(5);
+  vector.PushBack(3);
+
+  // erase multiple value
+  Dali::Erase(vector, 3);
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(4), vector.Count(), TEST_LOCATION);
+
+  DALI_TEST_EQUALS(vector[0], 1, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[2], 4, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[3], 5, TEST_LOCATION);
+
+
+  // erase an element present at start
+  Dali::Erase(vector, 1);
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(3), vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[0], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 4, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[2], 5, TEST_LOCATION);
+
+  // erase an element present at end
+  Dali::Erase(vector, 5);
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(2), vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[0], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 4, TEST_LOCATION);
+
+  // erase an element not present in the vector
+  Dali::Erase(vector, 42);
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(2), vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[0], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 4, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliVectorEraseIfFreeFunction(void)
+{
+  tet_infoline("Testing Dali::EraseIf<Vector<int>>");
+
+  Vector<int> vector;
+
+  // erasing from empty vector
+  Dali::EraseIf(vector, [](const auto & value) {return value == 2;});
+  DALI_TEST_EQUALS(ZERO, vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(ZERO, vector.Capacity(), TEST_LOCATION);
+
+
+  vector.PushBack(1);
+  vector.PushBack(2);
+  vector.PushBack(3);
+  vector.PushBack(4);
+  vector.PushBack(5);
+  vector.PushBack(3);
+
+  // erase multiple value
+  Dali::EraseIf(vector, [](const auto & value) {return value == 3;});
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(4), vector.Count(), TEST_LOCATION);
+
+  DALI_TEST_EQUALS(vector[0], 1, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[2], 4, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[3], 5, TEST_LOCATION);
+
+
+  // erase an element present at start
+  Dali::EraseIf(vector, [](const auto & value) {return value == 1;});
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(3), vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[0], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 4, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[2], 5, TEST_LOCATION);
+
+  // erase an element present at end
+  Dali::EraseIf(vector, [](const auto & value) {return value == 5;});
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(2), vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[0], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 4, TEST_LOCATION);
+
+  // erase an element not present in the vector
+  Dali::EraseIf(vector, [](const auto & value) {return value == 42;});
+  DALI_TEST_EQUALS(static_cast<Dali::VectorBase::SizeType>(2), vector.Count(), TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[0], 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(vector[1], 4, TEST_LOCATION);
+
+  END_TEST;
+}
+
 /*
  * this does not compile at the moment
  * Vector< Actor > classvector; this does not compile yet either
index e4bb8ce..5a61b64 100644 (file)
@@ -847,6 +847,38 @@ public: // API
 };
 
 /**
+ * @brief Erases all elements that compare equal to value from the vector.
+ *
+ * @SINCE_1_9.33
+ * @param[in] vector The vector
+ * @param[in] value The value to be removed.
+ */
+template <class T, class U>
+inline void Erase(Dali::Vector<T>& vector, const U& value)
+{
+  auto begin = vector.Begin();
+  auto end = vector.End();
+
+  vector.Erase(std::remove(begin, end, value), end);
+}
+
+/**
+ * @brief Erases all elements that satisfy the predicate from the vector.
+ *
+ * @SINCE_1_9.33
+ * @param[in] vector The vector
+ * @param[in] predicate The predicate
+ */
+template <class T, class Predicate>
+inline void EraseIf(Dali::Vector<T>& vector, Predicate predicate)
+{
+  auto begin = vector.Begin();
+  auto end = vector.End();
+
+  vector.Erase(std::remove_if(begin, end, predicate), end);
+}
+
+/**
  * @}
  */
 } // namespace Dali