[pypy-commit] pypy SpecialisedTuples: (mwp) use unrolling_iterable to generate access to tuple elements

mwp noreply at buildbot.pypy.org
Thu Nov 10 10:47:54 CET 2011


Author: Mark Pearse <mark.pearse at skynet.be>
Branch: SpecialisedTuples
Changeset: r49106:7e8c19d6251f
Date: 2011-11-07 17:01 +0100
http://bitbucket.org/pypy/pypy/changeset/7e8c19d6251f/

Log:	(mwp) use unrolling_iterable to generate access to tuple elements

diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py
--- a/pypy/objspace/std/specialisedtupleobject.py
+++ b/pypy/objspace/std/specialisedtupleobject.py
@@ -1,15 +1,10 @@
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std.model import registerimplementation, W_Object
 from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.inttype import wrapint
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.floatobject import W_FloatObject
-from pypy.objspace.std.stringobject import W_StringObject
-from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std.tupleobject import W_TupleObject
-from pypy.objspace.std import slicetype
 from pypy.rlib.rarithmetic import intmask
 from pypy.rlib.objectmodel import compute_hash
+from pypy.rlib.unroll import unrolling_iterable
 
 class NotSpecialised(Exception):
     pass         
@@ -66,101 +61,66 @@
                         
 
 def make_specialised_class(class_name, typelist):
+    iter_n = unrolling_iterable(range(len(typelist)))
     class cls(W_SpecialisedTupleObject):
-        def __init__(self, space, val0, val1):
-            assert len(typelist) == 2
-            assert isinstance(val0, typelist[0])
-            assert isinstance(val1, typelist[1])
+        def __init__(self, space, *values):
+            assert len(typelist) == len(values)
+            for i in iter_n:
+                assert isinstance(values[i], typelist[i])
             self.space = space
-            self.val0 = val0
-            self.val1 = val1
+            for i in iter_n:
+                setattr(self, 'value%s' % i, values[i])
     
         def length(self):
-            return 2
+            return len(typelist)
     
         def tolist(self):
-            return [self.space.wrap(self.val0), self.space.wrap(self.val1)]
+            return [self.space.wrap(getattr(self, 'value%s' % i)) for i in iter_n]
             
         def hash(self, space):
             mult = 1000003
             x = 0x345678
             z = 2
-            for val in [self.val0, self.val1]:
+            for i in iter_n:
 #                y = compute_hash(val)
-                y = space.int_w(space.hash(space.wrap(val)))                		
+                y = space.int_w(space.hash(space.wrap(getattr(self, 'value%s' % i))))                		
                 x = (x ^ y) * mult
                 z -= 1
                 mult += 82520 + z + z
             x += 97531
             return space.wrap(intmask(x))
     
+        def _eq(self, w_other):
+            if w_other.length() != len(typelist):
+                return False
+            for i in iter_n:
+                if getattr(self, 'value%s' % i) != getattr(w_other, 'value%s' % i):
+                    return False
+            else:
+                return True
+    
         def eq(self, space, w_other):
-            if w_other.length() != 2:
-                return space.w_False
-            if self.val0 == w_other.val0 and self.val1 == w_other.val1:	#xxx
-                return space.w_True
-            else:
-                return space.w_False
+            return space.newbool(self._eq(w_other))
     
         def ne(self, space, w_other):
-            if w_other.length() != 2:
-                return space.w_True
-            if self.val0 != w_other.val0:
-                return space.w_True
-            if self.val1 != w_other.val1:
-                return space.w_True
-            return space.w_False
+            return space.newbool(not self._eq(w_other))
     
-        def lt(self, space, w_other):
-            assert self.length() <= 2
+        def _compare(self, compare_op, w_other):
             ncmp = min(self.length(), w_other.length())
-            if ncmp >= 1:
-                if not self.val0 == w_other.val0:
-                    return space.newbool(self.val0 < w_other.val0)
-            if ncmp >= 2:
-                if not self.val1 == w_other.val1:
-                    return space.newbool(self.val1 < w_other.val1)
-            return space.newbool(self.length() < w_other.length())
-    
-        def le(self, space, w_other):
-            assert self.length() <= 2
-            ncmp = min(self.length(), w_other.length())
-            if ncmp >= 1:
-                if not self.val0 == w_other.val0:
-                    return space.newbool(self.val0 <= w_other.val0)
-            if ncmp >= 2:
-                if not self.val1 == w_other.val1:
-                    return space.newbool(self.val1 <= w_other.val1)
-            return space.newbool(self.length() <= w_other.length())
-    
-        def ge(self, space, w_other):
-            assert self.length() <= 2
-            ncmp = min(self.length(), w_other.length())
-            if ncmp >= 1:
-                if not self.val0 == w_other.val0:
-                    return space.newbool(self.val0 >= w_other.val0)
-            if ncmp >= 2:
-                if not self.val1 == w_other.val1:
-                    return space.newbool(self.val1 >= w_other.val1)
-            return space.newbool(self.length() >= w_other.length())
-    
-        def gt(self, space, w_other):
-            assert self.length() <= 2
-            ncmp = min(self.length(), w_other.length())
-            if ncmp >= 1:
-                if not self.val0 == w_other.val0:
-                    return space.newbool(self.val0 > w_other.val0)
-            if ncmp >= 2:
-                if not self.val1 == w_other.val1:
-                    return space.newbool(self.val1 > w_other.val1)
-            return space.newbool(self.length() > w_other.length())
-    
+            for i in iter_n:
+                if ncmp > i:
+                    l_val = getattr(self, 'value%s' % i)
+                    r_val = getattr(w_other, 'value%s' % i)
+                    if l_val != r_val:
+                        return compare_op(l_val, r_val)
+            return compare_op(self.length(), w_other.length())
+            
         def getitem(self, index):
-            if index == 0:
-                return self.space.wrap(self.val0)
-            if index == 1:
-                return self.space.wrap(self.val1)
+            for i in iter_n:
+                if index == i:
+                    return self.space.wrap(getattr(self, 'value%s' % i))
             raise IndexError
+
     cls.__name__ = class_name      
     _specialisations.append((cls,typelist))
     return cls
@@ -194,17 +154,19 @@
 def ne__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
     return w_tuple1.ne(space, w_tuple2)
 
+from operator import lt, le, ge, gt   
+ 
 def lt__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.lt(space, w_tuple2)
+    return space.newbool(w_tuple1._compare(lt, w_tuple2))
 
 def le__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.le(space, w_tuple2)
+    return space.newbool(w_tuple1._compare(le, w_tuple2))
 
 def ge__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.ge(space, w_tuple2)
+    return space.newbool(w_tuple1._compare(ge, w_tuple2))
 
 def gt__SpecialisedTuple_SpecialisedTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.gt(space, w_tuple2)
+    return space.newbool(w_tuple1._compare(gt, w_tuple2))
 
 def hash__SpecialisedTuple(space, w_tuple):
     return w_tuple.hash(space)


More information about the pypy-commit mailing list