Add ArrayList.sort_with_data
authorZeeshan Ali (Khattak) <zeeshanak@gnome.org>
Sat, 24 Jul 2010 01:40:11 +0000 (04:40 +0300)
committerMaciej Piechotka <uzytkownik2@gmail.com>
Fri, 30 Jul 2010 19:40:01 +0000 (21:40 +0200)
Add a variant of List.sort that takes CompareDataFunc rather than
CompareFunc so compare func could be a method or closure. We are
adding this to ArrayList rather than List to not break the API/ABI.
In 0.7.x, this method will be removed as List.sort will then do
exactly the same.

gee/arraylist.vala
gee/timsort.vala

index 3654fb1..01f48d8 100644 (file)
@@ -223,6 +223,18 @@ public class Gee.ArrayList<G> : AbstractList<G> {
                return true;
        }
 
+       /**
+        * Sorts items by comparing with the specified compare function.
+        *
+        * WARNING: This method has only been added as hack and will not
+        *          exist after the next odd minor version bump (>= 0.7.x).
+        *
+        * @param compare_func compare function to use to compare items
+        */
+       public void sort_with_data (CompareDataFunc compare) {
+               TimSort.sort_with_data<G> (this, compare);
+       }
+
        private void shift (int start, int delta) {
                assert (start >= 0);
                assert (start <= _size);
index 1fbc10b..cb79ced 100644 (file)
@@ -54,7 +54,17 @@ internal class Gee.TimSort<G> : Object {
                }
        }
 
-       private static void sort_list<G> (List<G> list, CompareFunc compare) {
+       public static void sort_with_data<G> (List<G> list, CompareDataFunc compare_data) {
+               if (list is ArrayList) {
+                       TimSort.sort_arraylist<G> ((ArrayList<G>) list, null, compare_data);
+               } else {
+                       TimSort.sort_list<G> (list, null, compare_data);
+               }
+       }
+
+       private static void sort_list<G> (List<G> list, CompareFunc? compare, CompareDataFunc? compare_data = null) {
+        assert (compare != null || compare_data != null);
+
                TimSort<G> helper = new TimSort<G> ();
 
                helper.list_collection = list;
@@ -63,6 +73,7 @@ internal class Gee.TimSort<G> : Object {
                helper.index = 0;
                helper.size = list.size;
                helper.compare = compare;
+               helper.compare_data = compare_data;
 
                helper.do_sort ();
 
@@ -73,7 +84,9 @@ internal class Gee.TimSort<G> : Object {
                }
        }
 
-       private static void sort_arraylist<G> (ArrayList<G> list, CompareFunc compare) {
+       private static void sort_arraylist<G> (ArrayList<G> list, CompareFunc? compare, CompareDataFunc? compare_data = null) {
+        assert (compare != null || compare_data != null);
+
                TimSort<G> helper = new TimSort<G> ();
 
                helper.list_collection = list;
@@ -81,6 +94,7 @@ internal class Gee.TimSort<G> : Object {
                helper.index = 0;
                helper.size = list._size;
                helper.compare = compare;
+               helper.compare_data = compare_data;
 
                helper.do_sort ();
        }
@@ -95,6 +109,7 @@ internal class Gee.TimSort<G> : Object {
        private Slice<G>*[] pending;
        private int minimum_gallop;
        private CompareFunc compare;
+       private CompareDataFunc compare_data;
 
        private void do_sort () {
                if (size < 2) {
@@ -153,11 +168,19 @@ internal class Gee.TimSort<G> : Object {
        private delegate bool LowerFunc (G left, G right);
 
        private inline bool lower_than (G left, G right) {
-               return compare (left, right) < 0;
+        if (compare != null) {
+            return compare (left, right) < 0;
+        } else {
+            return compare_data (left, right) < 0;
+        }
        }
 
        private inline bool lower_than_or_equal_to (G left, G right) {
-               return compare (left, right) <= 0;
+        if (compare != null) {
+            return compare (left, right) <= 0;
+        } else {
+            return compare_data (left, right) <= 0;
+        }
        }
 
        private int compute_minimum_run_length (int length) {