[pypy-commit] pypy int-float-list-strategy: int-or-float sort()

arigo noreply at buildbot.pypy.org
Wed Jul 1 23:53:52 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: int-float-list-strategy
Changeset: r78392:a46ca0349945
Date: 2015-07-01 23:37 +0200
http://bitbucket.org/pypy/pypy/changeset/a46ca0349945/

Log:	int-or-float sort()

diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -1613,6 +1613,9 @@
     def getitems(self, w_list):
         return self.unerase(w_list.lstorage)
 
+    # no sort() method here: W_ListObject.descr_sort() handles this
+    # case explicitly
+
 
 class IntegerListStrategy(ListStrategy):
     import_from_mixin(AbstractUnwrappedStrategy)
@@ -1800,6 +1803,17 @@
     def list_is_correct_type(self, w_list):
         return w_list.strategy is self.space.fromcache(IntOrFloatListStrategy)
 
+    def sort(self, w_list, reverse):
+        l = self.unerase(w_list.lstorage)
+        sorter = IntOrFloatSort(l, len(l))
+        # Reverse sort stability achieved by initially reversing the list,
+        # applying a stable forward sort, then reversing the final result.
+        if reverse:
+            l.reverse()
+        sorter.sort()
+        if reverse:
+            l.reverse()
+
 
 class BytesListStrategy(ListStrategy):
     import_from_mixin(AbstractUnwrappedStrategy)
@@ -1896,6 +1910,7 @@
 TimSort = make_timsort_class()
 IntBaseTimSort = make_timsort_class()
 FloatBaseTimSort = make_timsort_class()
+IntOrFloatBaseTimSort = make_timsort_class()
 StringBaseTimSort = make_timsort_class()
 UnicodeBaseTimSort = make_timsort_class()
 
@@ -1926,6 +1941,19 @@
         return a < b
 
 
+class IntOrFloatSort(IntOrFloatBaseTimSort):
+    def lt(self, a, b):
+        if longlong2float.is_int32_from_longlong_nan(a):
+            fa = float(longlong2float.decode_int32_from_longlong_nan(a))
+        else:
+            fa = longlong2float.longlong2float(a)
+        if longlong2float.is_int32_from_longlong_nan(b):
+            fb = float(longlong2float.decode_int32_from_longlong_nan(b))
+        else:
+            fb = longlong2float.longlong2float(b)
+        return fa < fb
+
+
 class StringSort(StringBaseTimSort):
     def lt(self, a, b):
         return a < b
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -894,6 +894,17 @@
         # lst = [0, 1.2]; lst[:] = [3]
         # lst = [0, 1.2]; lst[:] = [3.4]
 
+    def test_int_or_float_sort(self):
+        space = self.space
+        w_l = W_ListObject(space, [space.wrap(1.2), space.wrap(1),
+                                   space.wrap(1.0), space.wrap(5)])
+        w_l.sort(False)
+        assert [(type(x), x) for x in space.unwrap(w_l)] == [
+            (int, 1), (float, 1.0), (float, 1.2), (int, 5)]
+        w_l.sort(True)
+        assert [(type(x), x) for x in space.unwrap(w_l)] == [
+            (int, 5), (float, 1.2), (int, 1), (float, 1.0)]
+
 
 class TestW_ListStrategiesDisabled:
     spaceconfig = {"objspace.std.withliststrategies": False}


More information about the pypy-commit mailing list