summaryrefslogtreecommitdiff
path: root/blist/_btuple.py
diff options
context:
space:
mode:
Diffstat (limited to 'blist/_btuple.py')
-rw-r--r--blist/_btuple.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/blist/_btuple.py b/blist/_btuple.py
new file mode 100644
index 0000000..1e409cd
--- /dev/null
+++ b/blist/_btuple.py
@@ -0,0 +1,86 @@
+from blist._blist import blist
+from ctypes import c_int
+import collections
+class btuple(collections.Sequence):
+ def __init__(self, seq=None):
+ if isinstance(seq, btuple):
+ self._blist = seq._blist
+ elif seq is not None:
+ self._blist = blist(seq)
+ else:
+ self._blist = blist()
+ self._hash = -1
+
+ def _btuple_or_tuple(self, other, f):
+ if isinstance(other, btuple):
+ rv = f(self._blist, other._blist)
+ elif isinstance(other, tuple):
+ rv = f(self._blist, blist(other))
+ else:
+ return NotImplemented
+ if isinstance(rv, blist):
+ rv = btuple(rv)
+ return rv
+
+ def __hash__(self):
+ # Based on tuplehash from tupleobject.c
+ if self._hash != -1:
+ return self._hash
+
+ n = len(self)
+ mult = c_int(1000003)
+ x = c_int(0x345678)
+ for ob in self:
+ n -= 1
+ y = c_int(hash(ob))
+ x = (x ^ y) * mult
+ mult += c_int(82520) + n + n
+ x += c_int(97531)
+ if x == -1:
+ x = -2;
+ self._hash = x.value
+ return self._hash
+
+ def __add__(self, other):
+ return self._btuple_or_tuple(other, blist.__add__)
+ def __radd__(self, other):
+ return self._btuple_or_tuple(other, blist.__radd__)
+ def __contains__(self, item):
+ return item in self._blist
+ def __eq__(self, other):
+ return self._btuple_or_tuple(other, blist.__eq__)
+ def __ge__(self, other):
+ return self._btuple_or_tuple(other, blist.__ge__)
+ def __gt__(self, other):
+ return self._btuple_or_tuple(other, blist.__gt__)
+ def __le__(self, other):
+ return self._btuple_or_tuple(other, blist.__le__)
+ def __lt__(self, other):
+ return self._btuple_or_tuple(other, blist.__lt__)
+ def __ne__(self, other):
+ return self._btuple_or_tuple(other, blist.__ne__)
+ def __iter__(self):
+ return iter(self._blist)
+ def __len__(self):
+ return len(self._blist)
+ def __getitem__(self, key):
+ if isinstance(key, slice):
+ return btuple(self._blist[key])
+ return self._blist[key]
+ def __getslice__(self, i, j):
+ return btuple(self._blist[i:j])
+ def __repr__(self):
+ return 'btuple((' + repr(self._blist)[7:-2] + '))'
+ def __str__(self):
+ return repr(self)
+ def __mul__(self, i):
+ return btuple(self._blist * i)
+ def __rmul__(self, i):
+ return btuple(i * self._blist)
+ def count(self, item):
+ return self._blist.count(item)
+ def index(self, item):
+ return self._blist.index(item)
+
+del c_int
+del collections