Class Subspace :: sus :: collections :: SliceMut

template <class T>
class SliceMut final
{ ... };

A dynamically-sized mutable view into a contiguous sequence of objects of type T.

Contiguous here means that elements are laid out so that every element is the same distance from its neighbors, where there are sus::mem::size_of<T>() many bytes between the start of each element.

Slices are a view into a block of memory represented as a pointer and a length.

A SliceMut<T> can be implicitly converted to a Slice<T>.

Static Methods

Constructs an empty Slice.

This constructor is implicit so that using the EmptyMarker allows the caller to avoid spelling out the full Slice type.

Constructs an empty SliceMut, which has no elements.

template <size_t N>
static auto from(T (&data)[N]) -> SliceMut<T>
requires
N <= ::sus::cast<usize>(isize::MAX_PRIMITIVE)

sus::construct::From<T[N]> trait.

Returns a SliceMut that refers to all elements of the data array.

static auto from_raw_collection_mut(UnsafeFnMarker, IterRefCounter refs, T* data, sus::usize len) -> SliceMut<T>

Constructs a slice from its raw parts with iterator invalidation tracking. Iterators produced from this slice will interact with the collection to allow it to know when they are being invalidated by the collection.

For building a SliceMut from primitive pointer, use from_raw_parts_mut().

Safety

The following must be upheld or Undefined Behaviour may result:

  • The refs should be constructed from an IterRefCounter in the collection with IterRefCounter::to_view_from_owner().
  • The len must be no more than the number of elements in the allocation at and after the position of data.
  • The pointer data must be a valid pointer to an allocation, not a dangling pointer, at any point during the SliceMut's lifetime. This must be true even if len is 0.

In some other langages such as Rust, the slice may hold an invalid pointer when the length is zero. But SliceMut must not hold a dangling pointer. Otherwise addition on the dangling pointer may happen in SliceMut methods, which is Undefined Behaviour in C++. To support dangling pointers, those methods would need length == 0 branches. Care must be applied when converting slices between languages as a result.

static auto from_raw_parts_mut(UnsafeFnMarker, T* data, sus::usize len) -> SliceMut<T>

Constructs a slice from its raw parts.

For building a SliceMut from a collection, use from_raw_collection_mut() in order to participate in iterator invalidation tracking.

Safety

The following must be upheld or Undefined Behaviour may result: IterRefCounter and wants to be able to observe when it invalidates the SliceMut by tracking its lifetime.

  • The len must be no more than the number of elements in the allocation at and after the position of data.
  • The pointer data must be a valid pointer to an allocation, not a dangling pointer, at any point during the SliceMut's lifetime. This must be true even if len is 0.

In some other langages such as Rust, the slice may hold an invalid pointer when the length is zero. But SliceMut must not hold a dangling pointer. Otherwise addition on the dangling pointer may happen in SliceMut methods, which is Undefined Behaviour in C++. To support dangling pointers, those methods would need length == 0 branches. Care must be applied when converting slices between languages as a result.

Methods

auto as_mut_ptr() const& -> T*

Returns a mutable pointer to the first element in the slice.

The caller must ensure that the collection outlives the pointer this function returns, or else it will end up pointing to garbage.

Modifying the collection referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.

auto as_mut_ptr_range() const& -> Range<T*>

Returns the two mutable pointers spanning the slice.

The returned range is half-open, which means that the end pointer points one past the last element of the slice. This way, an empty slice is represented by two equal pointers, and the difference between the two pointers represents the size of the slice.

The end pointer requires caution, as it does not point to a valid element in the slice.

This function is useful for interacting with interfaces which use two pointers to refer to a range of elements in memory, as is common in C++ stdlib algorthms. Note that the pointers can be unpacked from the Range with structured bindings as in auto [a, b] = s.as_mut_ptr_range();.

auto as_ptr() const& -> const T*

Returns a const pointer to the first element in the slice.

The caller must ensure that the collection outlives the pointer this function returns, or else it will end up pointing to garbage.

Modifying the collection referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.

auto as_ptr_range() const& -> Range<const T*>

Returns the two const pointers spanning the slice.

The returned range is half-open, which means that the end pointer points one past the last element of the slice. This way, an empty slice is represented by two equal pointers, and the difference between the two pointers represents the size of the slice.

The end pointer requires caution, as it does not point to a valid element in the slice.

This function is useful for interacting with interfaces which use two pointers to refer to a range of elements in memory, as is common in C++ stdlib algorthms. Note that the pointers can be unpacked from the Range with structured bindings as in auto [a, b] = s.as_ptr_range();.

auto as_slice() const& -> Slice<T>
auto binary_search(const T& x) const& -> Result<usize, usize>
requires
sus::cmp::Ord<T>

Binary searches this slice for a given element. This behaves similarly to contains if this slice is sorted.

If the value is found then sus::Ok is returned, with the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Subspace. If the value is not found then sus::Err is returned, with the index where a matching element could be inserted while maintaining sorted order.

auto binary_search_by(FnMut<std::weak_ordering(const T&)> auto f) const& -> Result<usize, usize>

Binary searches this slice with a comparator function. This behaves similarly to contains if this slice is sorted.

The comparator function should implement an order consistent with the sort order of the underlying slice, returning a std::strong_ordering that indicates whether its argument is less than, equal to or greater than the desired target.

If the value is found then sus::Ok is returned, with the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Subspace. If the value is not found then sus::Err is returned, with the index where a matching element could be inserted while maintaining sorted order.

template <class Key>
auto binary_search_by_key(const Key& key, FnMut<Key(const T&)> auto f) const& -> Result<usize, usize>
requires
sus::cmp::StrongOrd<Key>

Binary searches this slice with a key extraction function. This behaves similarly to contains if this slice is sorted.

Assumes that the slice is sorted by the key, for instance with sort_by_key using the same key extraction function.

If the value is found then sus::Ok is returned, with the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Subspace. If the value is not found then sus::Err is returned, with the index where a matching element could be inserted while maintaining sorted order.

auto chunks(usize chunk_size) const& -> Chunks<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See chunks_exact() for a variant of this iterator that returns chunks of always exactly chunk_size elements, and rchunks() for the same iterator but starting at the end of the slice.

Panics

Panics if chunk_size is 0.

auto chunks_exact(usize chunk_size) const& -> ChunksExact<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder function of the iterator.

TODO: Verify if: due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks().

See chunks() for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact() for the same iterator but starting at the end of the slice.

Panics

Panics if chunk_size is 0.

auto chunks_exact_mut(usize chunk_size) const& -> ChunksExactMut<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder() function of the iterator.

TODO: Verify if: Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks_mut.

See chunks_mut() for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact_mut() for the same iterator but starting at the end of the slice.

auto chunks_mut(usize chunk_size) const& -> ChunksMut<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the beginning of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See chunks_exact_mut() for a variant of this iterator that returns chunks of always exactly chunk_size elements, and rchunks_mut() for the same iterator but starting at the end of the slice.

Panics

Panics if chunk_size is 0.

auto clone_from_slice(const Slice<T>& src) const& -> void
requires
sus::mem::Clone<T>

Copies the elements from src into *this.

The length of src must be the same as *this.

Panics

This function will panic if the two slices have different lengths.

auto concat() const& -> auto
requires
sus::collections::Concat<T>

Flattens and concatenates the items in the Slice.

The items of type T are flattened into a collection of type T::ConcatOutputType. This method is only supported for types that satisfy the sus::collections::Concat<T> concept.

Slice itself satisfies Concat, with its output being Vec, so that a Slice of Slice<T>s can be concat() together into a single Vec<T>.

Example

i32 a1[] = {1, 2}, a2[] = {3, 4};
Slice<i32> as[] = {Slice<i32>::from(a1), Slice<i32>::from(a2)};
Vec<i32> v = Slice<Slice<i32>>::from(as).concat();
sus_check(v == Slice<i32>::from({1, 2, 3, 4}));
auto concat_into(sus::collections::Vec<T>& vec) const& -> void
requires
sus::mem::Clone<T>

Concatenates a clone of each element in the slice into vec.

This method exists to satisfy sus::collections::Concat<Slice<T>>, for concat() to append the elements in each Slice onto vec.

auto contains(const T& x) const& -> bool
requires
sus::cmp::Eq<T>

Returns true if the slice contains an element with the given value.

This operation is O(n).

Note that if you have a sorted slice, binary_search() may be faster.

auto copy_from_slice(const Slice<T>& src) const& -> void
requires
sus::mem::TrivialCopy<T>

Copies all elements from src into *this, using a memcpy() or equivalent.

The length of src must be the same as *this.

This function requires that T is TrivialCopy in order to give consistent performance across types. If T is not TrivialCopy, use clone_from_slice().

Panics This function will panic if the two slices have different lengths,

or if the two slices overlap.

auto copy_from_slice_unchecked(UnsafeFnMarker, const Slice<T>& src) const& -> void
requires
std::is_trivially_copy_assignable_v<T>

Copies all elements from src into *this, using a memcpy() or equivalent.

This function requires that T is trivially copy-assignable in order to give consistent performance across types. If T is not trivially copy- assignable, use clone_from_slice().

Safety

The following conditions must hold, or Undefined Behaviour results:

  • The length of src must be at least as large as *this.
  • The length of *this (and src) must be greater than 0, and must not overflow when multiplied by the size of T.
  • The src slice must not overlap (aka alias) with *this in memory.

Stops tracking iterator invalidation.

Safety

If the Slice points into a collection and that collection is invalidated, it will no longer be caught. The caller must provide conditions that can ensure the SliceMut's pointer into the collection will remain valid.

Iterator invalidation tracking also tracks the stability of the collection object itself, not just its contents, which can be overly strict.

This function can be used when the collection's contents will remain valid, but the collection itself may be moved, which would invalidate the tracking and be treated as invalidating the iterator. There is no way to restore tracking.

auto ends_with(const Slice<T>& suffix) const& -> bool
requires
sus::cmp::Eq<T>

Returns true if suffix is a suffix of the slice.

auto fill(T value) const& -> void
requires
sus::mem::Clone<T>

Fills the slice with elements by cloning value.

auto fill_with(FnMut<T()> auto f) const& -> void

Fills the slice with elements returned by calling a closure repeatedly.

This method uses a closure to create new values. If you’d rather Clone a given value, use fill(). If you want to default-construct elements for a type that satisfies sus::construct::Default, use fill_with_default().

auto fill_with_default() const& -> void
requires
sus::construct::Default<T>

Fills the slice with default-constructed elements of type T.

auto first() const& -> Option<const T&>

Returns the first element of the slice, or None if it is empty.

auto first_mut() const& -> Option<T&>

Returns a mutable reference to the first element of the slice, or None if it is empty.

auto get(usize i) const& -> Option<const T&>

Returns a const reference to the element at index i, or None if i is beyond the end of the Slice.

auto get_mut(usize i) const& -> Option<T&>

Returns a mutable reference to the element at index i, or None if i is beyond the end of the Slice.

auto get_range(const RangeBounds<usize> auto range) const& -> Option<Slice<T>>

Returns a subslice which contains elements in range, which specifies a start and a length.

The start is the index of the first element to be returned in the subslice, and the length is the number of elements in the output slice. As such, r.get_range(Range(0u, r.len())) returns a slice over the full set of elements in r.

Returns None if the Range would otherwise contain an element that is out of bounds.

auto get_range_mut(const RangeBounds<usize> auto range) const& -> Option<SliceMut<T>>

Returns a subslice which contains elements in range, which specifies a start and a length.

The start is the index of the first element to be returned in the subslice, and the length is the number of elements in the output slice. As such, r.get_range(Range(0u, r.len())) returns a slice over the full set of elements in r.

Returns None if the Range would otherwise contain an element that is out of bounds.

Returns a subslice which contains elements in range, which specifies a start and a length.

The start is the index of the first element to be returned in the subslice, and the length is the number of elements in the output slice. As such, r.get_range(Range(0u, r.len())) returns a slice over the full set of elements in r.

Safety

It is possible to specify a Range contains an element that is out of bounds of the Slice, which can result in Undefined Behaviour.

auto get_range_unchecked(UnsafeFnMarker, const RangeBounds<usize> auto range) const& -> Slice<T>

Returns a subslice which contains elements in range, which specifies a start and a length.

The start is the index of the first element to be returned in the subslice, and the length is the number of elements in the output slice. As such, r.get_range(Range(0u, r.len())) returns a slice over the full set of elements in r.

Safety

It is possible to specify a Range contains an element that is out of bounds of the Slice, which can result in Undefined Behaviour.

auto get_unchecked(UnsafeFnMarker, usize i) const& -> const T&

Returns a const reference to the element at index i.

Safety

The index i must be inside the bounds of the slice or Undefined Behaviour results. The size of the slice must therefore also have a length of at least 1.

Returns a mutable reference to the element at index i.

Safety

The index i must be inside the bounds of the slice or Undefined Behaviour results. The size of the slice must therefore also have a length of at least 1.

auto into_iter() && -> SliceIterMut<T&>

Converts the slice into an iterator that consumes the slice and returns each element in the same order they appear in the slice.

auto is_empty() const& -> bool

Returns true if the slice has a length of 0.

auto iter() const& -> SliceIter<const T&>

Returns an iterator over all the elements in the slice, visited in the same order they appear in the slice. The iterator gives const access to each element.

auto iter_mut() const& -> SliceIterMut<T&>

Returns an iterator over all the elements in the slice, visited in the same order they appear in the slice. The iterator gives mutable access to each element.

template <class Sep>
auto join(const Sep& separator) const& -> auto
requires
sus::collections::Join<T, Sep>

Flattens and concatenates the items in the Slice, cloning a separator between each item.

The items of type T are flattened into a collection of type T::JoinOutputType. This method is only supported for types that satisfy the sus::collections::Join<T> concept.

Slice itself satisfies Join, with its output being Vec, so that a Slice of Slice<T>s can be join() together into a single Vec<T>.

Example

i32 a1[] = {1, 2}, a2[] = {3, 4}, asep[] = {10, 11, 12};
Slice<i32> as[] = {Slice<i32>::from(a1), Slice<i32>::from(a2)};

// Join slices with a slice between.
Vec<i32> v = Slice<Slice<i32>>::from(as).join(Slice<i32>::from(asep));
sus_check(v == sus::Vec<i32>(1, 2, 10, 11, 12, 3, 4));

// Join slices with a single item between.
Vec<i32> v2 = Slice<Slice<i32>>::from(as).join(99);
sus_check(v2 == sus::Vec<i32>(1, 2, 99, 3, 4));
auto join_into(sus::collections::Vec<T>& vec) const& -> void
requires
sus::mem::Clone<T>

Joins a clone of each element in the slice into vec.

This method exists to satisfy sus::collections::Join<Slice<T>, U>, for join() to append the elements in each Slice onto vec.

auto last() const& -> Option<const T&>

Returns the last element of the slice, or None if it is empty.

auto last_mut() const& -> Option<T&>

Returns a mutable reference to the last element of the slice, or None if it is empty.

auto len() const& -> usize

Returns the number of elements in the slice.

auto partition_point(FnMut<bool(const T&)> auto pred) const& -> usize

Returns the index of the partition point according to the given predicate (the index of the first element of the second partition).

The slice is assumed to be partitioned according to the given predicate. This means that all elements for which the predicate returns true are at the start of the slice and all elements for which the predicate returns false are at the end. For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 (all odd numbers are at the start, all even at the end).

If this slice is not partitioned, the returned result is unspecified and meaningless, as this method performs a kind of binary search.

See also binary_search(), binary_search_by(), and binary_search_by_key().

auto rchunks(usize chunk_size) const& -> RChunks<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See rchunks_exact() for a variant of this iterator that returns chunks of always exactly chunk_size elements, and chunks() for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

auto rchunks_exact(usize chunk_size) const& -> RChunksExact<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end of the slice.

The chunks are slices and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder() function of the iterator.

TODO: Verify if: Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of rchunks().

See rchunks() for a variant of this iterator that also returns the remainder as a smaller chunk, and chunks_exact() for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

auto rchunks_exact_mut(usize chunk_size) const& -> RChunksExactMut<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved from the remainder() function of the iterator.

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the resulting code better than in the case of chunks_mut.

See rchunks_mut() for a variant of this iterator that also returns the remainder as a smaller chunk, and chunks_exact_mut() for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

auto rchunks_mut(usize chunk_size) const& -> RChunksMut<T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end of the slice.

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the length of the slice, then the last chunk will not have length chunk_size.

See rchunks_exact_mut() for a variant of this iterator that returns chunks of always exactly chunk_size elements, and chunks_mut() for the same iterator but starting at the beginning of the slice.

Panics

Panics if chunk_size is 0.

auto repeat(sus::usize n) const& -> sus::collections::Vec<T>
requires
sus::mem::TrivialCopy<T>

Creates a vector by copying a slice n times.

Panics

This function will panic if the capacity would become larger than isize::MAX.

Examples

auto v = sus::Vec<i32>(1, 2);
sus_check(v[".."_r].repeat(3) == sus::vec(1, 2, 1, 2, 1, 2).construct<i32>());
auto reverse() const& -> void
requires
sus::mem::Move<T>

Reverses the order of elements in the slice, in place.

Examples

auto forward = sus::Vec<i32>(1, 2, 3);
auto sf = forward[".."_r];
auto backward = sus::Vec<i32>(3, 2, 1);
auto sb = backward[".."_r];
sf.reverse();
sus_check(sf == sb);
auto rotate_left(usize mid) const& -> void
requires
sus::mem::Move<T>

Rotates the slice in-place such that the first mid elements of the slice move to the end while the last self.len() - mid elements move to the front. After calling rotate_left(), the element previously at index mid will become the first element in the slice.

Panics

This function will panic if mid is greater than the length of the slice. Note that mid == len() does not panic and is a no-op rotation.

Complexity

Takes linear (in len()) time.

auto rotate_right(usize k) const& -> void
requires
sus::mem::Move<T>

Rotates the slice in-place such that the first len() - k elements of the slice move to the end while the last k elements move to the front. After calling rotate_right(), the element previously at index len() - k will become the first element in the slice.

Panics

This function will panic if k is greater than the length of the slice. Note that k == len() does not panic and is a no-op rotation.

Complexity

Takes linear (in len()) time.

template <class Pred>
auto rsplit(Pred pred) const& -> RSplit<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over subslices separated by elements that match pred, starting at the end of the slice and working backwards. The matched element is not contained in the subslices.

As with split(), if the first or last element is matched, an empty slice will be the first (or last) item returned by the iterator.

template <class Pred>
auto rsplit_mut(Pred pred) const& -> RSplitMut<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over mutable subslices separated by elements that match pred, starting at the end of the slice and working backwards. The matched element is not contained in the subslices.

As with split_mut(), if the first or last element is matched, an empty slice will be the first (or last) item returned by the iterator.

template <class Pred>
auto rsplitn(sus::usize n, Pred pred) const& -> RSplitN<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over subslices separated by elements that match pred limited to returning at most n items. This starts at the end of the slice and works backwards. The matched element is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

template <class Pred>
auto rsplitn_mut(sus::usize n, Pred pred) const& -> RSplitNMut<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over subslices separated by elements that match pred limited to returning at most n items. This starts at the end of the slice and works backwards. The matched element is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

auto sort() const& -> void
requires
sus::cmp::Ord<T>

Sorts the slice.

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)^2) worst-case.

When applicable, unstable sorting is preferred because it is generally faster than stable sorting and it doesn’t allocate auxiliary memory. See sort_unstable().

Current implementation

The current implementation is std::stable_sort().

TODO: Rust's stable sort is O(n * log(n)), so this can be improved. It can also be constexpr?

auto sort_by(FnMut<std::weak_ordering(const T&, const T&)> auto compare) const& -> void

Sorts the slice with a comparator function.

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)^2) worst-case.

The comparator function must define a total ordering for the elements in the slice. If the ordering is not total, the order of the elements is unspecified.

Current implementation

The current implementation is std::stable_sort().

TODO: Rust's stable sort is O(n * log(n)), so this can be improved. It can also be constexpr?

template <class KeyFn, int &... , class Key = std::invoke_result_t<KeyFn &, const T &>>
auto sort_by_cached_key(KeyFn f) const& -> void
requires
sus::fn::FnMut<KeyFn, ::sus::fn::NonVoid (const T &)>
sus::cmp::Ord<Key>
template <class KeyFn, int &... , class Key = std::invoke_result_t<KeyFn &, const T &>>
auto sort_by_key(KeyFn f) const& -> void
requires
sus::fn::FnMut<KeyFn, ::sus::fn::NonVoid (const T &)>
sus::cmp::Ord<Key>

Sorts the slice with a key extraction function.

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) worst-case, where the key function is O(m).

For expensive key functions (e.g. functions that are not simple property accesses or basic operations), sort_by_cached_key() is likely to be significantly faster, as it does not recompute element keys.

When applicable, unstable sorting is preferred because it is generally faster than stable sorting and it doesn’t allocate auxiliary memory. See sort_unstable_by_key().

Current implementation

The current implementation is std::stable_sort().

TODO: Rust's stable sort is O(n * log(n)), so this can be improved. It can also be constexpr?

auto sort_unstable() const& -> void
requires
sus::cmp::Ord<T>

Sorts the slice, but might not preserve the order of equal elements.

Current implementation

The current implementation is std::sort(), which is O(n * log(n)) but can allocate while sorting.

TODO: Rust's sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not allocate), and O(n * log(n)) worst-case.

auto sort_unstable_by(FnMut<std::weak_ordering(const T&, const T&)> auto compare) const& -> void

Sorts the slice with a comparator function, but might not preserve the order of equal elements.

The comparator function must define a total ordering for the elements in the slice. If the ordering is not total, the order of the elements is unspecified.

Current implementation

The current implementation is std::sort(), which is O(n * log(n)) but can allocate while sorting.

TODO: Rust's sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not allocate), and O(n * log(n)) worst-case.

template <class KeyFn, int &... , class Key = std::invoke_result_t<KeyFn &, const T &>>
auto sort_unstable_by_key(KeyFn f) const& -> void
requires
sus::fn::FnMut<KeyFn, ::sus::fn::NonVoid (const T &)>
sus::cmp::Ord<Key>

Sorts the slice with a key extraction function, but might not preserve the order of equal elements.

Current implementation

The current implementation is std::sort(), which is O(n * log(n)) but can allocate while sorting.

TODO: Rust's sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not allocate), and O(n * log(n)) worst-case.

template <class Pred>
auto split(Pred pred) const& -> Split<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over subslices separated by elements that match pred. The matched element is not contained in the subslices.

If the first element is matched, an empty slice will be the first item returned by the iterator. Similarly, if the last element in the slice is matched, an empty slice will be the last item returned by the iterator.

auto split_at(usize mid) const& -> Tuple<Slice<T>, Slice<T>>

Divides one slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len()) (excluding the index len() itself).

Panics

Panics if mid > len().

auto split_at_mut(usize mid) const& -> Tuple<SliceMut<T>, SliceMut<T>>

Divides one mutable slice into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len()) (excluding the index len() itself).

Panics

Panics if mid > len().

Divides one slice of mutable references into two at an index, without doing bounds checking.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

For a safe alternative see split_at_mut().

Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= len().

Divides one slice into two at an index, without doing bounds checking.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

For a safe alternative see split_at().

Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= len().

auto split_first() const& -> Option<Tuple<const T&, Slice<T>>>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

auto split_first_mut() const& -> Option<Tuple<T&, SliceMut<T>>>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

template <class Pred>
auto split_inclusive(Pred pred) const& -> SplitInclusive<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over subslices separated by elements that match pred. The matched element is contained in the end of the previous subslice as a terminator.

If the last element of the slice is matched, that element will be considered the terminator of the preceding slice. That slice will be the last item returned by the iterator.

template <class Pred>
auto split_inclusive_mut(Pred pred) const& -> SplitInclusiveMut<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over subslices separated by elements that match pred. The matched element is contained in the end of the previous subslice as a terminator.

If the last element of the slice is matched, that element will be considered the terminator of the preceding slice. That slice will be the last item returned by the iterator.

auto split_last() const& -> Option<Tuple<const T&, Slice<T>>>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

auto split_last_mut() const& -> Option<Tuple<T&, SliceMut<T>>>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

template <class Pred>
auto split_mut(Pred pred) const& -> SplitMut<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over mutable subslices separated by elements that match pred. The matched element is not contained in the subslices.

If the first element is matched, an empty slice will be the first item returned by the iterator. Similarly, if the last element in the slice is matched, an empty slice will be the last item returned by the iterator.

template <class Pred>
auto splitn(sus::usize n, Pred pred) const& -> SplitN<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over subslices separated by elements that match pred, limited to returning at most n items. The matched element is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

template <class Pred>
auto splitn_mut(sus::usize n, Pred pred) const& -> SplitNMut<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>

Returns an iterator over mutable subslices separated by elements that match pred, limited to returning at most n items. The matched element is not contained in the subslices.

The last element returned, if any, will contain the remainder of the slice.

auto starts_with(const Slice<T>& needle) const& -> bool
requires
sus::cmp::Eq<T>

Returns true if needle is a prefix of the slice.

auto strip_prefix(const Slice<T>& prefix) const& -> Option<Slice<T>>
requires
sus::cmp::Eq<T>

Returns a subslice with the prefix removed.

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. If prefix is empty, simply returns the original slice.

If the slice does not start with prefix, returns None.

TODO: Accept a SlicePattern<T> concept instead of just a Slice<T>.

auto strip_prefix_mut(const Slice<T>& prefix) const& -> Option<SliceMut<T>>
requires
sus::cmp::Eq<T>

Returns a subslice with the prefix removed.

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. If prefix is empty, simply returns the original slice.

If the slice does not start with prefix, returns None.

TODO: Accept a SlicePattern<T> concept instead of just a Slice<T>.

auto strip_suffix(const Slice<T>& suffix) const& -> Option<Slice<T>>
requires
sus::cmp::Eq<T>

Returns a subslice with the suffix removed.

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. If suffix is empty, simply returns the original slice.

If the slice does not end with suffix, returns None.

auto strip_suffix_mut(const Slice<T>& suffix) const& -> Option<SliceMut<T>>
requires
sus::cmp::Eq<T>

Returns a subslice with the suffix removed.

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. If suffix is empty, simply returns the original slice.

If the slice does not end with suffix, returns None.

auto subrange(sus::usize start) const& -> Slice<T>
auto subrange(sus::usize start, sus::usize end) const& -> Slice<T>

Returns a subslice which contains elements in the range which is specified by a start and an end. This is an alias for the subscript operator with a RangeBounds argument, but without the need to construct a RangeBounds.

The returned slice contains all indices in start <= x < end. It is empty if start >= end.

NOTE: This is different from std::span::subspan which uses a start and a length. Instead, this matches the construction of a Range in C++ and a Range in Rust.

Panics

If the Range would otherwise contain an element that is out of bounds, the function will panic.

auto subrange_mut(sus::usize start) const& -> SliceMut<T>
auto subrange_mut(sus::usize start, sus::usize end) const& -> SliceMut<T>

Returns a mutable subslice which contains elements in the range which is specified by a start and an end. This is an alias for the subscript operator with a RangeBounds argument, but without the need to construct a RangeBounds.

The returned slice contains all indices in start <= x < end. It is empty if start >= end.

NOTE: This is different from std::span::subspan which uses a start and a length. Instead, this matches the construction of a Range in C++ and a Range in Rust.

Panics

If the Range would otherwise contain an element that is out of bounds, the function will panic.

auto swap(sus::usize a, sus::usize b) const& -> void

Swaps two elements in the slice.

Arguments

a - The index of the first element b - The index of the second element

Panics

Panics if a or b are out of bounds.

auto swap_nonoverlapping(UnsafeFnMarker, sus::usize a, sus::usize b) const& -> void

Swaps two elements in the slice. The arguments must not both refer to the same element.

For a safe alternative see swap(). For an unsafe variant that allows overlapping a and b, see swap_unchecked().

Arguments

a - The index of the first element b - The index of the second element

Safety

If a or b are out of bounds, or if a and b refer to the same element, Undefined Behaviour will occur.

auto swap_unchecked(UnsafeFnMarker, sus::usize a, sus::usize b) const& -> void

Swaps two elements in the slice.

For a safe alternative see swap().

Arguments

a - The index of the first element b - The index of the second element

Safety

If a or b are out of bounds, Undefined Behaviour will occur.

auto swap_with_slice(const SliceMut<T>& other) const& -> void

Swaps all elements in *this with those in other.

The length of other must be the same as *this.

Panics

This function will panic if the two slices have different lengths, or if other overlaps with *this.

auto to_vec() const& -> sus::collections::Vec<T>
requires
sus::mem::Clone<T>

Constructs a Vec<T> by cloning each value in the Slice.

The caller can choose traits for the Vec by specifying the trait type.

auto windows(sus::usize size) const& -> Windows<T>

Returns an iterator over all contiguous windows of length size. The windows overlap. If the slice is shorter than size, the iterator returns no values.

Panics

Panics if size is 0.

auto windows_mut(sus::usize size) const& -> WindowsMut<T>

Returns an iterator over all contiguous windows of length size. The windows overlap. If the slice is shorter than size, the iterator returns no values.

Panics

Panics if size is 0.

Operators

auto operator[](sus::usize i) const& -> T&

Returns a reference to the element at position i in the Slice.

Panics

If the index i is beyond the end of the slice, the function will panic.

auto operator[](const RangeBounds<sus::usize> auto range) const& -> SliceMut<T>

Returns a subslice which contains elements in range, which specifies a start and an end.

The start is the index of the first element to be returned in the subslice, and the end one past the last element in the output slice. As such, r.get_range(Range(0u, r.len())) returns a slice over the full set of elements in r.

Panics

If the Range would otherwise contain an element that is out of bounds, the function will panic.