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