diff options
Diffstat (limited to 'blist/_btuple.py')
-rw-r--r-- | blist/_btuple.py | 86 |
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 |