# ___________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright (c) 2008-2024
# National Technology and Engineering Solutions of Sandia, LLC
# Under the terms of Contract DE-NA0003525 with National Technology and
# Engineering Solutions of Sandia, LLC, the U.S. Government retains certain
# rights in this software.
# This software is distributed under the 3-clause BSD License.
# ___________________________________________________________________________
from collections import OrderedDict
from collections.abc import MutableSet
from pyomo.common.autoslots import AutoSlots
[docs]
class OrderedSet(AutoSlots.Mixin, MutableSet):
__slots__ = ('_dict',)
[docs]
def __init__(self, iterable=None):
# Starting in Python 3.7, dict is ordered (and is faster than
# OrderedDict). dict began supporting reversed() in 3.8.
self._dict = {}
if iterable is not None:
self.update(iterable)
def __str__(self):
"""String representation of the mapping."""
return "OrderedSet(%s)" % (', '.join(repr(x) for x in self))
def update(self, iterable):
if isinstance(iterable, OrderedSet):
self._dict.update(iterable._dict)
else:
self._dict.update((val, None) for val in iterable)
#
# Implement MutableSet abstract methods
#
def __contains__(self, val):
return val in self._dict
def __iter__(self):
return iter(self._dict)
def __len__(self):
return len(self._dict)
[docs]
def add(self, val):
"""Add an element."""
self._dict[val] = None
[docs]
def discard(self, val):
"""Remove an element. Do not raise an exception if absent."""
if val in self._dict:
del self._dict[val]
#
# The remaining MutableSet methods have slow default
# implementations.
#
[docs]
def clear(self):
"""Remove all elements from this set."""
self._dict.clear()
[docs]
def remove(self, val):
"""Remove an element. If not a member, raise a KeyError."""
del self._dict[val]
def intersection(self, other):
other = set(other)
res = OrderedSet(filter(other.__contains__, self))
return res
def union(self, other):
res = OrderedSet(self)
res.update(other)
return res
#
# Not strictly part of MutableSet, but it makes sense that OrderedSet
# should be reversible
#
def __reversed__(self):
return reversed(self._dict)