sain.collections.slice API documentation

# sain.collections.slice

View Source

      1# BSD 3-Clause License
      2#
      3# Copyright (c) 2022-Present, nxtlo
      4# All rights reserved.
      5#
      6# Redistribution and use in source and binary forms, with or without
      7# modification, are permitted provided that the following conditions are met:
      8#
      9# * Redistributions of source code must retain the above copyright notice, this
     10#   list of conditions and the following disclaimer.
     11#
     12# * Redistributions in binary form must reproduce the above copyright notice,
     13#   this list of conditions and the following disclaimer in the documentation
     14#   and/or other materials provided with the distribution.
     15#
     16# * Neither the name of the copyright holder nor the names of its
     17#   contributors may be used to endorse or promote products derived from
     18#   this software without specific prior written permission.
     19#
     20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     21# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     23# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
     24# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     25# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     26# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     27# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     28# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30
     31from __future__ import annotations
     32
     33__all__ = ("Slice", "SliceMut", "SpecContains")
     34
     35import typing
     36from collections import abc as collections
     37
     38from sain import iter as _iter
     39
     40T = typing.TypeVar("T")
     41
     42
     43Pattern = T | collections.Iterable[T]
     44
     45
     46class SpecContains(typing.Generic[T]):
     47    """Provides a default `contains` method."""
     48
     49    __slots__ = ()
     50
     51    @typing.final
     52    def contains(self: collections.Container[T], pat: Pattern[T]) -> bool:
     53        """Check if `pat` is contained in `self`.
     54
     55        `pat` here can be either an element of type `T` or an iterable of type `T`.
     56
     57        If an iterable is passed, it will check if at least one of the elements is in `self`.
     58
     59        Example
     60        ```py
     61        vec = Vec([1, 2, 3, 4])
     62        assert vec.contains(1) is True
     63        assert vec.contains([3, 4]) is True
     64        assert vec.contains(map(int, ['1', '2'])) is True
     65        ```
     66
     67        The implementation is roughly this simple:
     68        ```py
     69        if isinstance(pat, Iterable):
     70            return any(_ in sequence for _ in pat)
     71        return pat in sequence
     72        ```
     73        """
     74        if isinstance(pat, collections.Iterable):
     75            return any(_ in self for _ in pat)  # pyright: ignore - bad type inference.
     76
     77        return pat in self
     78
     79
     80@typing.final
     81class Slice(typing.Generic[T], collections.Sequence[T], SpecContains[T]):
     82    """An immutable view over some sequence of type `T`.
     83
     84    Similar to `&[T]`
     85
     86    Parameters
     87    ----------
     88    ptr : `collections.Sequence[T]`
     89        The sequence to point to.
     90    """
     91
     92    __slots__ = ("__buf",)
     93
     94    def __init__(self, ptr: collections.Sequence[T]) -> None:
     95        self.__buf = ptr
     96
     97    def into_inner(self) -> collections.Sequence[T]:
     98        """Consume this `Slice`, returning the sequence that's being pointed to.
     99
    100        `self` will no longer reference the sequence.
    101
    102        Example
    103        -------
    104        ```py
    105        def from_parts(slice: Slice[int], len: int) -> list[int]:
    106            uninit: list[int] = []
    107            uninit.extend(slice.into_inner()[:len])
    108            return uninit
    109
    110        vec = Vec([1, 2, 3, 4])
    111        new = from_parts(vec.as_ref(), 2)
    112        assert new == [1, 2]
    113        ```
    114        """
    115        ptr = self.__buf
    116        del self.__buf
    117        return ptr
    118
    119    def iter(self) -> _iter.TrustedIter[T]:
    120        """Returns an iterator over the slice.
    121
    122        The iterator yields all items from start to end.
    123
    124        Example
    125        -------
    126        ```py
    127        x = Vec([1, 2, 3])
    128        iterator = x.iter()
    129
    130        assert iterator.next() == Some(1)
    131        assert iterator.next() == Some(2)
    132        assert iterator.next() == Some(3)
    133        assert iterator.next().is_none()
    134        ```
    135        """
    136        return _iter.TrustedIter(self.__buf)
    137
    138    def __len__(self) -> int:
    139        return len(self.__buf)
    140
    141    def __iter__(self) -> collections.Iterator[T]:
    142        return iter(self.__buf)
    143
    144    def __repr__(self) -> str:
    145        return repr(self.__buf)
    146
    147    @typing.overload
    148    def __getitem__(self, index: slice) -> Slice[T]: ...
    149
    150    @typing.overload
    151    def __getitem__(self, index: int) -> T: ...
    152
    153    def __getitem__(self, index: int | slice) -> T | Slice[T]:
    154        if isinstance(index, slice):
    155            return Slice(self.__buf[index])
    156
    157        return self.__buf[index]
    158
    159    def __eq__(self, other: object, /) -> bool:
    160        return self.__buf == other
    161
    162    def __ne__(self, other: object, /) -> bool:
    163        return self.__buf != other
    164
    165
    166@typing.final
    167class SliceMut(typing.Generic[T], collections.MutableSequence[T], SpecContains[T]):
    168    """A mutable view over some sequence of type `T`.
    169
    170    Similar to `&mut [T]`
    171
    172    Parameters
    173    ----------
    174    ptr : `collections.MutableSequence[T]`
    175        The mutable sequence to point to.
    176    """
    177
    178    __slots__ = ("__buf",)
    179
    180    def __init__(self, ptr: collections.MutableSequence[T]) -> None:
    181        self.__buf = ptr
    182
    183    def into_inner(self) -> collections.MutableSequence[T]:
    184        """Consume this `SliceMut`, returning the sequence that's being pointed to.
    185
    186        `self` will no longer reference the sequence.
    187
    188        Example
    189        -------
    190        ```py
    191        x = Vec(["x", "y", "z"])
    192
    193        # mutable reference to `x`
    194        mut_ref = x.as_mut()
    195        # make all elements in `x` uppercase, then detach from `mut_ref`.
    196        mut_ref.into_inner()[:] = [s.upper() for s in mut_ref]
    197
    198        assert x == ["X", "Y", "Z"]
    199        ```
    200        """
    201        ptr = self.__buf
    202        del self.__buf
    203        return ptr
    204
    205    def iter(self) -> _iter.TrustedIter[T]:
    206        """Returns an iterator over the slice.
    207
    208        The iterator yields all items from start to end.
    209
    210        Example
    211        -------
    212        ```py
    213        x = Vec([1, 2, 3])
    214        iterator = x.iter()
    215
    216        assert iterator.next() == Some(1)
    217        assert iterator.next() == Some(2)
    218        assert iterator.next() == Some(3)
    219        assert iterator.next().is_none()
    220        ```
    221        """
    222        return _iter.TrustedIter(self.__buf)
    223
    224    def insert(self, index: int, value: T) -> None:
    225        self.__buf.insert(index, value)
    226
    227    def __len__(self) -> int:
    228        return len(self.__buf)
    229
    230    def __iter__(self) -> collections.Iterator[T]:
    231        return iter(self.__buf)
    232
    233    def __repr__(self) -> str:
    234        return repr(self.__buf)
    235
    236    def __setitem__(self, index: int, item: T) -> None:
    237        self.__buf.__setitem__(index, item)
    238
    239    def __delitem__(self, at: int) -> None:
    240        del self.__buf[at]
    241
    242    @typing.overload
    243    def __getitem__(self, index: slice) -> Slice[T]: ...
    244
    245    @typing.overload
    246    def __getitem__(self, index: int) -> T: ...
    247
    248    def __getitem__(self, index: int | slice) -> T | Slice[T]:
    249        if isinstance(index, slice):
    250            return Slice(self.__buf[index])
    251
    252        return self.__buf[index]
    253
    254    def __eq__(self, other: object, /) -> bool:
    255        return self.__buf == other
    256
    257    def __ne__(self, other: object, /) -> bool:
    258        return self.__buf != other

@typing.final
class Slice(typing.Generic[~T], collections.abc.Sequence[~T], sain.collections.slice.SpecContains[~T]): View Source

     81@typing.final
     82class Slice(typing.Generic[T], collections.Sequence[T], SpecContains[T]):
     83    """An immutable view over some sequence of type `T`.
     84
     85    Similar to `&[T]`
     86
     87    Parameters
     88    ----------
     89    ptr : `collections.Sequence[T]`
     90        The sequence to point to.
     91    """
     92
     93    __slots__ = ("__buf",)
     94
     95    def __init__(self, ptr: collections.Sequence[T]) -> None:
     96        self.__buf = ptr
     97
     98    def into_inner(self) -> collections.Sequence[T]:
     99        """Consume this `Slice`, returning the sequence that's being pointed to.
    100
    101        `self` will no longer reference the sequence.
    102
    103        Example
    104        -------
    105        ```py
    106        def from_parts(slice: Slice[int], len: int) -> list[int]:
    107            uninit: list[int] = []
    108            uninit.extend(slice.into_inner()[:len])
    109            return uninit
    110
    111        vec = Vec([1, 2, 3, 4])
    112        new = from_parts(vec.as_ref(), 2)
    113        assert new == [1, 2]
    114        ```
    115        """
    116        ptr = self.__buf
    117        del self.__buf
    118        return ptr
    119
    120    def iter(self) -> _iter.TrustedIter[T]:
    121        """Returns an iterator over the slice.
    122
    123        The iterator yields all items from start to end.
    124
    125        Example
    126        -------
    127        ```py
    128        x = Vec([1, 2, 3])
    129        iterator = x.iter()
    130
    131        assert iterator.next() == Some(1)
    132        assert iterator.next() == Some(2)
    133        assert iterator.next() == Some(3)
    134        assert iterator.next().is_none()
    135        ```
    136        """
    137        return _iter.TrustedIter(self.__buf)
    138
    139    def __len__(self) -> int:
    140        return len(self.__buf)
    141
    142    def __iter__(self) -> collections.Iterator[T]:
    143        return iter(self.__buf)
    144
    145    def __repr__(self) -> str:
    146        return repr(self.__buf)
    147
    148    @typing.overload
    149    def __getitem__(self, index: slice) -> Slice[T]: ...
    150
    151    @typing.overload
    152    def __getitem__(self, index: int) -> T: ...
    153
    154    def __getitem__(self, index: int | slice) -> T | Slice[T]:
    155        if isinstance(index, slice):
    156            return Slice(self.__buf[index])
    157
    158        return self.__buf[index]
    159
    160    def __eq__(self, other: object, /) -> bool:
    161        return self.__buf == other
    162
    163    def __ne__(self, other: object, /) -> bool:
    164        return self.__buf != other

An immutable view over some sequence of type `T`.

Similar to `&[T]`

###### Parameters

- ptr (`collections.Sequence[T]`): The sequence to point to.

Slice(ptr: Sequence[~T]) View Source

    95    def __init__(self, ptr: collections.Sequence[T]) -> None:
    96        self.__buf = ptr

def into_inner(self) -> Sequence[~T]: View Source

     98    def into_inner(self) -> collections.Sequence[T]:
     99        """Consume this `Slice`, returning the sequence that's being pointed to.
    100
    101        `self` will no longer reference the sequence.
    102
    103        Example
    104        -------
    105        ```py
    106        def from_parts(slice: Slice[int], len: int) -> list[int]:
    107            uninit: list[int] = []
    108            uninit.extend(slice.into_inner()[:len])
    109            return uninit
    110
    111        vec = Vec([1, 2, 3, 4])
    112        new = from_parts(vec.as_ref(), 2)
    113        assert new == [1, 2]
    114        ```
    115        """
    116        ptr = self.__buf
    117        del self.__buf
    118        return ptr

Consume this `Slice`, returning the sequence that's being pointed to.

`self` will no longer reference the sequence.

###### Example

    def from_parts(slice: Slice[int], len: int) -> list[int]:
        uninit: list[int] = []
        uninit.extend(slice.into_inner()[:len])
        return uninit

    vec = Vec([1, 2, 3, 4])
    new = from_parts(vec.as_ref(), 2)
    assert new == [1, 2]

def iter(self) -> sain.iter.TrustedIter[~T]: View Source

    120    def iter(self) -> _iter.TrustedIter[T]:
    121        """Returns an iterator over the slice.
    122
    123        The iterator yields all items from start to end.
    124
    125        Example
    126        -------
    127        ```py
    128        x = Vec([1, 2, 3])
    129        iterator = x.iter()
    130
    131        assert iterator.next() == Some(1)
    132        assert iterator.next() == Some(2)
    133        assert iterator.next() == Some(3)
    134        assert iterator.next().is_none()
    135        ```
    136        """
    137        return _iter.TrustedIter(self.__buf)

Returns an iterator over the slice.

The iterator yields all items from start to end.

###### Example

    x = Vec([1, 2, 3])
    iterator = x.iter()

    assert iterator.next() == Some(1)
    assert iterator.next() == Some(2)
    assert iterator.next() == Some(3)
    assert iterator.next().is_none()

##### Inherited Members

SpecContains
  contains

@typing.final
class SliceMut(typing.Generic[~T], collections.abc.MutableSequence[~T], sain.collections.slice.SpecContains[~T]): View Source

    167@typing.final
    168class SliceMut(typing.Generic[T], collections.MutableSequence[T], SpecContains[T]):
    169    """A mutable view over some sequence of type `T`.
    170
    171    Similar to `&mut [T]`
    172
    173    Parameters
    174    ----------
    175    ptr : `collections.MutableSequence[T]`
    176        The mutable sequence to point to.
    177    """
    178
    179    __slots__ = ("__buf",)
    180
    181    def __init__(self, ptr: collections.MutableSequence[T]) -> None:
    182        self.__buf = ptr
    183
    184    def into_inner(self) -> collections.MutableSequence[T]:
    185        """Consume this `SliceMut`, returning the sequence that's being pointed to.
    186
    187        `self` will no longer reference the sequence.
    188
    189        Example
    190        -------
    191        ```py
    192        x = Vec(["x", "y", "z"])
    193
    194        # mutable reference to `x`
    195        mut_ref = x.as_mut()
    196        # make all elements in `x` uppercase, then detach from `mut_ref`.
    197        mut_ref.into_inner()[:] = [s.upper() for s in mut_ref]
    198
    199        assert x == ["X", "Y", "Z"]
    200        ```
    201        """
    202        ptr = self.__buf
    203        del self.__buf
    204        return ptr
    205
    206    def iter(self) -> _iter.TrustedIter[T]:
    207        """Returns an iterator over the slice.
    208
    209        The iterator yields all items from start to end.
    210
    211        Example
    212        -------
    213        ```py
    214        x = Vec([1, 2, 3])
    215        iterator = x.iter()
    216
    217        assert iterator.next() == Some(1)
    218        assert iterator.next() == Some(2)
    219        assert iterator.next() == Some(3)
    220        assert iterator.next().is_none()
    221        ```
    222        """
    223        return _iter.TrustedIter(self.__buf)
    224
    225    def insert(self, index: int, value: T) -> None:
    226        self.__buf.insert(index, value)
    227
    228    def __len__(self) -> int:
    229        return len(self.__buf)
    230
    231    def __iter__(self) -> collections.Iterator[T]:
    232        return iter(self.__buf)
    233
    234    def __repr__(self) -> str:
    235        return repr(self.__buf)
    236
    237    def __setitem__(self, index: int, item: T) -> None:
    238        self.__buf.__setitem__(index, item)
    239
    240    def __delitem__(self, at: int) -> None:
    241        del self.__buf[at]
    242
    243    @typing.overload
    244    def __getitem__(self, index: slice) -> Slice[T]: ...
    245
    246    @typing.overload
    247    def __getitem__(self, index: int) -> T: ...
    248
    249    def __getitem__(self, index: int | slice) -> T | Slice[T]:
    250        if isinstance(index, slice):
    251            return Slice(self.__buf[index])
    252
    253        return self.__buf[index]
    254
    255    def __eq__(self, other: object, /) -> bool:
    256        return self.__buf == other
    257
    258    def __ne__(self, other: object, /) -> bool:
    259        return self.__buf != other

A mutable view over some sequence of type `T`.

Similar to `&mut [T]`

###### Parameters

- ptr (`collections.MutableSequence[T]`): The mutable sequence to point to.

SliceMut(ptr: MutableSequence[~T]) View Source

    181    def __init__(self, ptr: collections.MutableSequence[T]) -> None:
    182        self.__buf = ptr

def into_inner(self) -> MutableSequence[~T]: View Source

    184    def into_inner(self) -> collections.MutableSequence[T]:
    185        """Consume this `SliceMut`, returning the sequence that's being pointed to.
    186
    187        `self` will no longer reference the sequence.
    188
    189        Example
    190        -------
    191        ```py
    192        x = Vec(["x", "y", "z"])
    193
    194        # mutable reference to `x`
    195        mut_ref = x.as_mut()
    196        # make all elements in `x` uppercase, then detach from `mut_ref`.
    197        mut_ref.into_inner()[:] = [s.upper() for s in mut_ref]
    198
    199        assert x == ["X", "Y", "Z"]
    200        ```
    201        """
    202        ptr = self.__buf
    203        del self.__buf
    204        return ptr

Consume this `SliceMut`, returning the sequence that's being pointed to.

`self` will no longer reference the sequence.

###### Example

    x = Vec(["x", "y", "z"])

    # mutable reference to `x`
    mut_ref = x.as_mut()
    # make all elements in `x` uppercase, then detach from `mut_ref`.
    mut_ref.into_inner()[:] = [s.upper() for s in mut_ref]

    assert x == ["X", "Y", "Z"]

def iter(self) -> sain.iter.TrustedIter[~T]: View Source

    206    def iter(self) -> _iter.TrustedIter[T]:
    207        """Returns an iterator over the slice.
    208
    209        The iterator yields all items from start to end.
    210
    211        Example
    212        -------
    213        ```py
    214        x = Vec([1, 2, 3])
    215        iterator = x.iter()
    216
    217        assert iterator.next() == Some(1)
    218        assert iterator.next() == Some(2)
    219        assert iterator.next() == Some(3)
    220        assert iterator.next().is_none()
    221        ```
    222        """
    223        return _iter.TrustedIter(self.__buf)

Returns an iterator over the slice.

The iterator yields all items from start to end.

###### Example

    x = Vec([1, 2, 3])
    iterator = x.iter()

    assert iterator.next() == Some(1)
    assert iterator.next() == Some(2)
    assert iterator.next() == Some(3)
    assert iterator.next().is_none()

def insert(self, index: int, value: ~T) -> None: View Source

    225    def insert(self, index: int, value: T) -> None:
    226        self.__buf.insert(index, value)

S.insert(index, value) -- insert value before index

##### Inherited Members

SpecContains
  contains

class SpecContains(typing.Generic[~T]): View Source

    47class SpecContains(typing.Generic[T]):
    48    """Provides a default `contains` method."""
    49
    50    __slots__ = ()
    51
    52    @typing.final
    53    def contains(self: collections.Container[T], pat: Pattern[T]) -> bool:
    54        """Check if `pat` is contained in `self`.
    55
    56        `pat` here can be either an element of type `T` or an iterable of type `T`.
    57
    58        If an iterable is passed, it will check if at least one of the elements is in `self`.
    59
    60        Example
    61        ```py
    62        vec = Vec([1, 2, 3, 4])
    63        assert vec.contains(1) is True
    64        assert vec.contains([3, 4]) is True
    65        assert vec.contains(map(int, ['1', '2'])) is True
    66        ```
    67
    68        The implementation is roughly this simple:
    69        ```py
    70        if isinstance(pat, Iterable):
    71            return any(_ in sequence for _ in pat)
    72        return pat in sequence
    73        ```
    74        """
    75        if isinstance(pat, collections.Iterable):
    76            return any(_ in self for _ in pat)  # pyright: ignore - bad type inference.
    77
    78        return pat in self

Provides a default `contains` method.

@typing.final
def contains(self: Container[~T], pat: Union[~T, Iterable[~T]]) -> bool: View Source

    52    @typing.final
    53    def contains(self: collections.Container[T], pat: Pattern[T]) -> bool:
    54        """Check if `pat` is contained in `self`.
    55
    56        `pat` here can be either an element of type `T` or an iterable of type `T`.
    57
    58        If an iterable is passed, it will check if at least one of the elements is in `self`.
    59
    60        Example
    61        ```py
    62        vec = Vec([1, 2, 3, 4])
    63        assert vec.contains(1) is True
    64        assert vec.contains([3, 4]) is True
    65        assert vec.contains(map(int, ['1', '2'])) is True
    66        ```
    67
    68        The implementation is roughly this simple:
    69        ```py
    70        if isinstance(pat, Iterable):
    71            return any(_ in sequence for _ in pat)
    72        return pat in sequence
    73        ```
    74        """
    75        if isinstance(pat, collections.Iterable):
    76            return any(_ in self for _ in pat)  # pyright: ignore - bad type inference.
    77
    78        return pat in self

Check if `pat` is contained in `self`.

`pat` here can be either an element of type `T` or an iterable of type `T`.

If an iterable is passed, it will check if at least one of the elements is in `self`.

Example

    vec = Vec([1, 2, 3, 4])
    assert vec.contains(1) is True
    assert vec.contains([3, 4]) is True
    assert vec.contains(map(int, ['1', '2'])) is True

The implementation is roughly this simple:

    if isinstance(pat, Iterable):
        return any(_ in sequence for _ in pat)
    return pat in sequence