sain.collections.slice

  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]):
 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])
95    def __init__(self, ptr: collections.Sequence[T]) -> None:
96        self.__buf = ptr
def into_inner(self) -> Sequence[~T]:
 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]:
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]):
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])
181    def __init__(self, ptr: collections.MutableSequence[T]) -> None:
182        self.__buf = ptr
def into_inner(self) -> MutableSequence[~T]:
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]:
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:
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]):
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:
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