-from abc import abstractmethod
+from abc import ABCMeta, abstractmethod
+from functools import lru_cache
from typing import (AbstractSet, Any, Iterable, Iterator, Mapping, MutableSet,
TypeVar, overload)
"OSet",
"top_set_bit_index",
"trailing_zero_count",
+ "InternedMeta",
]
-class OFSet(AbstractSet[_T_co]):
+class InternedMeta(ABCMeta):
+ def __init__(self, *args, **kwargs):
+ # type: (*Any, **Any) -> None
+ super().__init__(*args, **kwargs)
+ self.__INTERN_TABLE = {} # type: dict[Any, Any]
+
+ def __intern(self, value):
+ # type: (_T) -> _T
+ value = self.__INTERN_TABLE.setdefault(value, value)
+ if value.__dict__.get("_InternedMeta__interned", False):
+ return value
+ value.__dict__["_InternedMeta__interned"] = True
+ hash_v = hash(value)
+ value.__dict__["__hash__"] = lambda: hash_v
+ old_eq = value.__eq__
+
+ def __eq__(__o):
+ # type: (_T) -> bool
+ if value.__class__ is __o.__class__:
+ return value is __o
+ return old_eq(__o)
+ value.__dict__["__eq__"] = __eq__
+ return value
+
+ def __call__(self, *args, **kwargs):
+ # type: (*Any, **Any) -> Any
+ return self.__intern(super().__call__(*args, **kwargs))
+
+
+class OFSet(AbstractSet[_T_co], metaclass=InternedMeta):
""" ordered frozen set """
- __slots__ = "__items",
+ __slots__ = "__items", "__dict__", "__weakref__"
def __init__(self, items=()):
# type: (Iterable[_T_co]) -> None
class OSet(MutableSet[_T]):
""" ordered mutable set """
- __slots__ = "__items",
+ __slots__ = "__items", "__dict__"
def __init__(self, items=()):
# type: (Iterable[_T]) -> None
return f"OSet({list(self)})"
-class FMap(Mapping[_T, _T_co]):
+class FMap(Mapping[_T, _T_co], metaclass=InternedMeta):
"""ordered frozen hashable mapping"""
- __slots__ = "__items", "__hash"
+ __slots__ = "__items", "__hash", "__dict__", "__weakref__"
@overload
def __init__(self, items):
class BaseBitSet(AbstractSet[int]):
- __slots__ = "__bits",
+ __slots__ = "__bits", "__dict__", "__weakref__"
@classmethod
@abstractmethod
return super().__isub__(it)
-class FBitSet(BaseBitSet):
+class FBitSet(BaseBitSet, metaclass=InternedMeta):
"""Frozen Bit Set"""
@final