Browse Source

one shot bubble sort alg

Michele Caini 7 years ago
parent
commit
6794d21487
5 changed files with 65 additions and 18 deletions
  1. 2 1
      TODO
  2. 39 6
      src/entt/core/algorithm.hpp
  3. 16 2
      test/entt/core/algorithm.cpp
  4. 0 1
      test/entt/core/ident.cpp
  5. 8 8
      test/entt/signal/sigh.cpp

+ 2 - 1
TODO

@@ -6,8 +6,9 @@
 * define systems as composable mixins (initializazion, reactive, update, whatever) with flexible auto-detected arguments (registry, views, etc)
 * create dedicated flat map based on types implementation (sort of "type map") for types to use within the registry and so on...
 * registry::create with a "hint" on the entity identifier to use, it should ease combining multiple registries
+* optimize for empty components, it would be a mid improvement in terms of memory usage
+* add some lazy iterative sorters like "single bubble sort loop"
 * can we do more for shared libraries? who knows... see #144
-* filtered views (has, hasn't and so on)
 * work stealing job system (see #100)
 * reflection system (maybe)
 * C++17. That's all.

+ 39 - 6
src/entt/core/algorithm.hpp

@@ -18,11 +18,11 @@ namespace entt {
  * This class fills the gap by wrapping some flavors of `std::sort` in a
  * function object.
  */
-struct StdSort {
+struct StdSort final {
     /**
-     * @brief Sorts the element in a range.
+     * @brief Sorts the elements in a range.
      *
-     * Sorts the element in a range using the given binary comparison function.
+     * Sorts the elements in a range using the given binary comparison function.
      *
      * @tparam It Type of random access iterator.
      * @tparam Compare Type of comparison function object.
@@ -40,11 +40,11 @@ struct StdSort {
 
 
 /*! @brief Function object for performing insertion sort. */
-struct InsertionSort {
+struct InsertionSort final {
     /**
-     * @brief Sorts the element in a range.
+     * @brief Sorts the elements in a range.
      *
-     * Sorts the element in a range using the given binary comparison function.
+     * Sorts the elements in a range using the given binary comparison function.
      *
      * @tparam It Type of random access iterator.
      * @tparam Compare Type of comparison function object.
@@ -72,6 +72,39 @@ struct InsertionSort {
 };
 
 
+/*! @brief Function object for performing bubble sort (single iteration). */
+struct OneShotBubbleSort final {
+    /**
+     * @brief Tries to sort the elements in a range.
+     *
+     * Performs a single iteration to sort the elements in a range using the
+     * given binary comparison function. The range may not be completely sorted
+     * after running this function.
+     *
+     * @tparam It Type of random access iterator.
+     * @tparam Compare Type of comparison function object.
+     * @param first An iterator to the first element of the range to sort.
+     * @param last An iterator past the last element of the range to sort.
+     * @param compare A valid comparison function object.
+     */
+    template<typename It, typename Compare = std::less<>>
+    void operator()(It first, It last, Compare compare = Compare{}) const {
+        if(first != last) {
+            auto it = first++;
+
+            while(first != last) {
+                if(compare(*first, *it)) {
+                    using std::swap;
+                    std::swap(*first, *it);
+                }
+
+                it = first++;
+            }
+        }
+    }
+};
+
+
 }
 
 

+ 16 - 2
test/entt/core/algorithm.cpp

@@ -9,7 +9,7 @@ TEST(Algorithm, StdSort) {
 
     sort(arr.begin(), arr.end());
 
-    for(auto i = 0; i < 4; ++i) {
+    for(typename decltype(arr)::size_type i = 0; i < (arr.size() - 1); ++i) {
         ASSERT_LT(arr[i], arr[i+1]);
     }
 }
@@ -20,7 +20,21 @@ TEST(Algorithm, InsertionSort) {
 
     sort(arr.begin(), arr.end());
 
-    for(auto i = 0; i < 4; ++i) {
+    for(typename decltype(arr)::size_type i = 0; i < (arr.size() - 1); ++i) {
+        ASSERT_LT(arr[i], arr[i+1]);
+    }
+}
+
+TEST(Algorithm, OneShotBubbleSort) {
+    std::array<int, 5> arr{{4, 1, 3, 2, 0}};
+    entt::OneShotBubbleSort sort;
+
+    sort(arr.begin(), arr.end());
+    sort(arr.begin(), arr.end());
+    sort(arr.begin(), arr.end());
+    sort(arr.begin(), arr.end());
+
+    for(typename decltype(arr)::size_type i = 0; i < (arr.size() - 1); ++i) {
         ASSERT_LT(arr[i], arr[i+1]);
     }
 }

+ 0 - 1
test/entt/core/ident.cpp

@@ -20,7 +20,6 @@ TEST(Identifier, Uniqueness) {
     switch(ID::get<AnotherType>()) {
     case ID::get<AType>():
         FAIL();
-        break;
     case ID::get<AnotherType>():
         SUCCEED();
     }

+ 8 - 8
test/entt/signal/sigh.cpp

@@ -142,7 +142,7 @@ TEST(SigH, Functions) {
     sigh.publish(v);
 
     ASSERT_FALSE(sigh.empty());
-    ASSERT_EQ((entt::SigH<bool(int)>::size_type)1, sigh.size());
+    ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(1), sigh.size());
     ASSERT_EQ(42, v);
 
     v = 0;
@@ -150,7 +150,7 @@ TEST(SigH, Functions) {
     sigh.publish(v);
 
     ASSERT_TRUE(sigh.empty());
-    ASSERT_EQ((entt::SigH<bool(int)>::size_type)0, sigh.size());
+    ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(0), sigh.size());
     ASSERT_EQ(0, v);
 
     sigh.sink().connect<&SigHListener::f>();
@@ -166,25 +166,25 @@ TEST(SigH, Members) {
 
     ASSERT_TRUE(s.k);
     ASSERT_FALSE(sigh.empty());
-    ASSERT_EQ((entt::SigH<bool(int)>::size_type)1, sigh.size());
+    ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(1), sigh.size());
 
     sigh.sink().disconnect<SigHListener, &SigHListener::g>(ptr);
     sigh.publish(42);
 
     ASSERT_TRUE(s.k);
     ASSERT_TRUE(sigh.empty());
-    ASSERT_EQ((entt::SigH<bool(int)>::size_type)0, sigh.size());
+    ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(0), sigh.size());
 
     sigh.sink().connect<SigHListener, &SigHListener::g>(ptr);
     sigh.sink().connect<SigHListener, &SigHListener::h>(ptr);
 
     ASSERT_FALSE(sigh.empty());
-    ASSERT_EQ((entt::SigH<bool(int)>::size_type)2, sigh.size());
+    ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(2), sigh.size());
 
     sigh.sink().disconnect(ptr);
 
     ASSERT_TRUE(sigh.empty());
-    ASSERT_EQ((entt::SigH<bool(int)>::size_type)0, sigh.size());
+    ASSERT_EQ(static_cast<entt::SigH<bool(int)>::size_type>(0), sigh.size());
 }
 
 TEST(SigH, Collector) {
@@ -205,7 +205,7 @@ TEST(SigH, Collector) {
 
     ASSERT_FALSE(sigh_all.empty());
     ASSERT_FALSE(collector_all.vec.empty());
-    ASSERT_EQ((std::vector<int>::size_type)2, collector_all.vec.size());
+    ASSERT_EQ(static_cast<std::vector<int>::size_type>(2), collector_all.vec.size());
     ASSERT_EQ(42, collector_all.vec[0]);
     ASSERT_EQ(42, collector_all.vec[1]);
 
@@ -217,6 +217,6 @@ TEST(SigH, Collector) {
 
     ASSERT_FALSE(sigh_first.empty());
     ASSERT_FALSE(collector_first.vec.empty());
-    ASSERT_EQ((std::vector<int>::size_type)1, collector_first.vec.size());
+    ASSERT_EQ(static_cast<std::vector<int>::size_type>(1), collector_first.vec.size());
     ASSERT_EQ(42, collector_first.vec[0]);
 }