from collections.abc import Collection, Container, Generator, Iterable, Iterator, MutableSet
from itertools import islice
from typing import Any, Literal, Protocol, SupportsIndex, TypeVar, overload, type_check_only
from typing_extensions import Self

_T_co = TypeVar("_T_co", covariant=True)

@type_check_only
class _RSub(Iterable[_T_co], Protocol):
    def __new__(cls: type[_RSub[_T_co]], param: list[_T_co], /) -> _RSub[_T_co]: ...

class IndexedSet(MutableSet[Any]):
    item_index_map: dict[Any, Any]
    item_list: list[Any]
    dead_indices: list[int]
    def __init__(self, other: Iterable[Any] | None = None) -> None: ...
    def __len__(self) -> int: ...
    def __contains__(self, item: Any) -> bool: ...
    def __iter__(self) -> Iterator[Any]: ...
    def __reversed__(self) -> Generator[Any]: ...
    @classmethod
    def from_iterable(cls, it: Iterable[Any]) -> Self: ...
    def add(self, item: Any) -> None: ...
    def remove(self, item: Any) -> None: ...
    def discard(self, item: Any) -> None: ...
    def clear(self) -> None: ...
    def isdisjoint(self, other: Iterable[Any]) -> bool: ...
    def issubset(self, other: Collection[Any]) -> bool: ...
    def issuperset(self, other: Collection[Any]) -> bool: ...
    def union(self, *others: Iterable[Any]) -> Self: ...
    def iter_intersection(self, *others: Container[Any]) -> Generator[Any]: ...
    def intersection(self, *others: Container[Any]) -> Self: ...
    def iter_difference(self, *others: Iterable[Any]) -> Generator[Any]: ...
    def difference(self, *others: Iterable[Any]) -> Self: ...
    def symmetric_difference(self, *others: Container[Any]) -> Self: ...
    # __or__ = union
    __ror__ = union
    # __and__ = intersection
    __rand__ = intersection
    # __sub__ = difference
    # __xor__ = symmetric_difference
    __rxor__ = symmetric_difference
    def __rsub__(self, other: _RSub[_T_co]) -> _RSub[_T_co]: ...
    def update(self, *others: Iterable[Any]) -> None: ...
    def intersection_update(self, *others: Iterable[Any]) -> None: ...
    def difference_update(self, *others: Container[Any]) -> None: ...
    def symmetric_difference_update(self, other: Iterable[Any]) -> None: ...
    def iter_slice(self, start: int, stop: int, step: int | None = None) -> islice[Iterable[Any]]: ...

    @overload
    def __getitem__(self, index: slice) -> Self: ...
    @overload
    def __getitem__(self, index: SupportsIndex) -> Any: ...

    def pop(self, index: int | None = None) -> Any: ...
    def count(self, val: Any) -> Literal[0, 1]: ...
    def reverse(self) -> None: ...
    def sort(self, **kwargs) -> None: ...
    def index(self, val: Any) -> int: ...

def complement(wrapped: Iterable[Any]) -> _ComplementSet: ...

class _ComplementSet:
    __slots__ = ("_included", "_excluded")
    def __init__(
        self, included: set[Any] | frozenset[Any] | None = None, excluded: set[Any] | frozenset[Any] | None = None
    ) -> None: ...
    def complemented(self) -> _ComplementSet: ...
    __invert__ = complemented
    def complement(self) -> None: ...
    def __contains__(self, item: Any) -> bool: ...
    def add(self, item: Any) -> None: ...
    def remove(self, item: Any) -> None: ...
    def pop(self) -> Any: ...
    def intersection(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    def __and__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    __rand__ = __and__
    def __iand__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> Self: ...
    def union(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    def __or__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    __ror__ = __or__
    def __ior__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> Self: ...
    def update(self, items: Iterable[Any]) -> None: ...
    def discard(self, items: Iterable[Any]) -> None: ...
    def symmetric_difference(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    def __xor__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    __rxor__ = __xor__
    def symmetric_difference_update(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> None: ...
    def isdisjoint(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> bool: ...
    def issubset(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> bool: ...
    def __le__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> bool: ...
    def __lt__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> bool: ...
    def issuperset(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> bool: ...
    def __ge__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> bool: ...
    def __gt__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> bool: ...
    def difference(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    def __sub__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    def __rsub__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> _ComplementSet: ...
    def difference_update(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> None: ...
    def __isub__(self, other: set[Any] | frozenset[Any] | _ComplementSet) -> Self: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator[Any]: ...
    def __bool__(self) -> bool: ...

__all__ = ["IndexedSet", "complement"]
