"""
$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/dulcinea/lib/persistent_set.py $
$Id: persistent_set.py 27472 2005-09-23 21:01:55Z dbinger $
"""
from durus.persistent import Persistent

class PersistentSet (Persistent):

    s_is = set

    def __init__(self, *args):
        self.s = set(*args)

    def __and__(self, other):
        if isinstance(other, PersistentSet):
            return self.__class__(self.s.__and__(other.s))
        else:
            return self.__class__(self.s.__and__(other))

    def __cmp__(self, other):
        return self.s.__cmp__(other)

    def __contains__(self, item):
        return self.s.__contains__(item)

    def __eq__(self, other):
        if not isinstance(other, PersistentSet):
            return False
        return self.s == other.s

    def __ge__(self, other):
        if not isinstance(other, PersistentSet):
            raise TypeError("can only compare to a PersistentSet")
        return self.s >= other.s

    def __gt__(self, other):
        if not isinstance(other, PersistentSet):
            raise TypeError("can only compare to a PersistentSet")
        return self.s > other.s

    def __hash__(self):
        return self.s.__hash__(self)

    def __iand__(self, other):
        self._p_note_change()
        if isinstance(other, PersistentSet):
            self.s.__iand__(other.s)
        else:
            self.s.__iand__(other)
        return self

    def __ior__(self, other):
        self._p_note_change()
        if isinstance(other, PersistentSet):
            self.s.__ior__(other.s)
        else:
            self.s.__ior__(other)
        return self

    def __isub__(self, other):
        self._p_note_change()
        if isinstance(other, PersistentSet):
            self.s.__isub__(other.s)
        else:
            self.s.__isub__(other)
        return self

    def __iter__(self):
        for x in self.s:
            yield x

    def __ixor__(self, other):
        self._p_note_change()
        if isinstance(other, PersistentSet):
            self.s.__ixor__(other.s)
        else:
            self.s.__ixor__(other)
        return self

    def __le__(self, other):
        if not isinstance(other, PersistentSet):
            raise TypeError("can only compare to a PersistentSet")
        return self.s <= other.s

    def __len__(self):
        return len(self.s)

    def __lt__(self, other):
        if not isinstance(other, PersistentSet):
            raise TypeError("can only compare to a PersistentSet")
        return self.s < other.s

    def __ne__(self, other):
        if not isinstance(other, PersistentSet):
            return True
        return self.s != other.s

    def __or__(self, other):
        if isinstance(other, PersistentSet):
            return self.__class__(self.s.__or__(other.s))
        else:
            return self.__class__(self.s.__or__(other))

    def __rand__(self, other):
        return self.__class__(other.__and__(self.s))

    def __ror__(self, other):
        return self.__class__(other.__or__(self.s))

    def __rsub__(self, other):
        return self.__class__(other.__sub__(self.s))

    def __rxor__(self, other):
        return self.__class__(other.__xor__(self.s))

    def __str__(self):
        return 'P' + self.s.__str__()

    def __sub__(self, other):
        if isinstance(other, PersistentSet):
            return self.__class__(self.s.__sub__(other.s))
        else:
            return self.__class__(self.s.__sub__(other))

    def __xor__(self, other):
        if isinstance(other, PersistentSet):
            return self.__class__(self.s.__xor__(other.s))
        else:
            return self.__class__(self.s.__xor__(other))

    def add(self, item):
        self._p_note_change()
        self.s.add(item)

    def clear(self):
        self._p_note_change()
        self.s.clear()

    def copy(self):
        return self.__class__(self.s)

    def discard(self, item):
        self._p_note_change()
        self.s.discard(item)

    def pop(self):
        self._p_note_change()
        return self.s.pop()

    def remove(self, item):
        self._p_note_change()
        self.s.remove(item)

    difference = __sub__
    difference_update = __isub__
    intersection = __and__
    intersection_update = __iand__
    issubset = __le__
    issuperset = __ge__
    symmetric_difference = __xor__
    symmetric_difference_update = __ixor__
    union = __or__
    update = __ior__
