Class Subspace :: sus :: collections :: Vec

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

A resizeable contiguous buffer of type T.

Vec requires Move for its items:

  • They can't be references as a pointer to reference is not valid.
  • On realloc, items need to be moved between allocations. Vec requires items are not references:
  • References can not be moved in the vector as assignment modifies the pointee, and Vec does not wrap references to store them as pointers (for now). Vec requires items are not const:
  • A const Vec contains const values, it does not give mutable access to its contents, so the const internal type would be redundant.

Static Methods

Constructs an empty Vec.

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

template <class... Ts>
Vec(Ts&&... values)
requires
std::convertible_to<T>...

Constructs a Vec, which constructs objects of type T from the given values.

This constructor also satisfies sus::construct::Default by accepting no arguments to create an empty Vec.

The vector will be able to hold at least the elements created from the arguments. This method is allowed to allocate for more elements than needed. If no arguments are passed, it creates an empty Vec and will not allocate.

Vec(Vec<T>&& o)

Satisifes the Move concept.

static auto from(Slice<T> slice) -> Vec<T>
requires
sus::mem::Clone<T>
static auto from(SliceMut<T> slice) -> Vec<T>
requires
sus::mem::Clone<T>

Constructs a Vec by cloning elements out of a slice.

Satisfies sus::construct::From<Slice<T>> and sus::construct::From<SliceMut<T>>.

template <class C, size_t N>
static auto from(const C (&arr)[N]) -> Vec<T>
requires
std::same_as<T, u8>
std::same_as<C, char> || std::same_as<C, signed char> ||
              std::same_as<C, unsigned char>
N <= ::sus::cast<usize>(isize::MAX)

Allocate a Vec<u8> and fill it with a string from a char array.

Panics

This function expects the input string to be null-terminated, and it will panic otherwise.

static auto from_raw_parts(UnsafeFnMarker, T* ptr, sus::usize length, sus::usize capacity) -> Vec<T>

Creates a Vec directly from a pointer, a capacity, and a length.

Safety

This is highly unsafe, due to the number of invariants that aren’t checked:

  • ptr must be heap allocated with the same method as Vec uses internally, which is not currently stable. (TODO: Want our own global allocator API.) The only safe way to get this pointer is from from_raw_parts().
  • T needs to have an alignment no more than what ptr was allocated with.
  • The size of T times the capacity (ie. the allocated size in bytes) needs to be the same size the pointer was allocated with.
  • length needs to be less than or equal to capacity.
  • The first length values must be properly initialized values of type T.
  • The allocated size in bytes must be no larger than isize::MAX.
  • If ptr is null, then length and capacity must be 0_usize, and vice versa.
static auto with_capacity(sus::usize capacity) -> Vec<T>

Creates a Vec with at least the specified capacity.

The vector will be able to hold at least capacity elements without reallocating. This method is allowed to allocate for more elements than capacity. If capacity is 0, the vector will not allocate.

It is important to note that although the returned vector has the minimum capacity specified, the vector will have a zero length.

A Vec<T> can be implicitly converted to a Slice<T>. If it is not const, it can also be converted to a SliceMut<T>.

Panics

Panics if the capacity exceeds isize::MAX bytes.

Methods

auto as_mut_ptr() & -> 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.

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();.

Returns a SliceMut that references all the elements of the vector as mutable references.

auto as_ptr() const& -> const T*
auto as_ptr() && -> const T*
deleted

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*>
auto as_ptr_range() && -> Range<const T*>
deleted

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 as_slice() && -> Slice<T>
deleted

Returns a Slice that references all the elements of the vector as const references.

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 capacity() const& -> sus::usize

Returns the number of elements there is space allocated for in the vector.

This may be larger than the number of elements present, which is returned by len.

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

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>
auto chunks_exact(usize chunk_size) && -> ChunksExact<T>
deleted

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.

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) & -> 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 clear() -> void

Clears the vector, removing all values.

Note that this method has no effect on the allocated capacity of the vector.

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

Satisfies the Clone concept.

auto clone_from(const Vec<T>& source) -> void
requires
!std::allocator_traits<
             A>::propagate_on_container_copy_assignment::value

An optimization to reuse the existing storage for Clone.

auto clone_from_slice(const Slice<T>& src) -> 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(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) -> 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) -> 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.
auto drain(RangeBounds<sus::usize> auto range) -> Drain<T>

Removes the specified range from the vector in bulk, returning all removed elements as an iterator. If the iterator is dropped before being fully consumed, it drops the remaining removed elements.

The Vec becomes moved-from and will panic on use while the Drain iterator is in use, and will be usable again once Drain is destroyed or Drain::keep_rest is called.

Panics

Panics if the starting point is greater than the end point or if the end point is greater than the length of the vector.

template <class... Us>
auto emplace(Us&&... args) -> void
requires
sus::mem::Move<T>
!(sizeof...(Us) == 1u &&
               (... && std::same_as<std::decay_t<T>, std::decay_t<Us>>))

Constructs and appends an element to the back of the vector.

The parameters to emplace() are used to construct the element. This typically works best for aggregate types, rather than types with a named static method constructor (such as T::with_foo(foo)). Prefer to use push() for most cases.

Disallows construction from a reference to T, as push() should be used in that case to avoid invalidating the input reference while constructing from it.

Panics

Panics if the new capacity exceeds isize::MAX bytes.

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 extend(IntoIterator<const T&> auto&& ii) -> void
requires
sus::mem::Copy<T>
sus::mem::IsMoveRef<decltype(ii)>

Extends the Vec with the contents of an iterator, copying from the elements.

Satisfies the Extend<const T&> concept for Vec<T>.

If T is Clone but not Copy, then the elements should be cloned explicitly by the caller (possibly through Iterator::cloned). Then use the extend (non-copy) method instead, moving the elements into the Vec.

auto extend(IntoIterator<T> auto&& ii) -> void
requires
sus::mem::IsMoveRef<decltype(ii)>

Extends the Vec with the contents of an iterator.

Satisfies the Extend<T> concept for Vec<T>.

auto extend_from_slice(Slice<T> s) -> void
requires
sus::mem::Clone<T>

Extends the Vec by cloning the contents of a slice.

If T is TrivialCopy, then the copy is done by memcpy.

Panics

If the Slice is non-empty and points into the Vec, the function will panic, as resizing the Vec would invalidate the Slice.

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

Fills the slice with elements by cloning value.

auto fill_with(FnMut<T()> auto f) -> 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() -> void
requires
sus::construct::Default<T>

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

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

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

auto first_mut() & -> 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&>
auto get(usize i) && -> Option<const T&>
deleted

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) & -> 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>>
auto get_range(const RangeBounds<usize> auto range) && -> Option<Slice<T>>
deleted

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) & -> 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>
auto get_range_unchecked(UnsafeFnMarker, const RangeBounds<usize> auto range) && -> Slice<T>
deleted

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&
auto get_unchecked(UnsafeFnMarker, usize i) && -> const T&
deleted

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 grow_to_exact(sus::usize cap) -> void

Increase the capacity of the vector (the total number of elements that the vector can hold without requiring reallocation) to cap, if there is not already room. Does nothing if capacity is already sufficient.

This is similar to std::vector::reserve().

Panics

Panics if the new capacity exceeds isize::MAX() bytes.

auto into_iter() && -> VecIntoIter<T>
requires
sus::mem::Move<T>

Consumes the Vec into an Iterator that will return ownership of each element in the same order they appear in the Vec.

auto into_raw_parts() && -> Tuple<T*, sus::usize, sus::usize>

Decomposes a Vec into its raw components.

Returns the raw pointer to the underlying data, the length of the vector (in elements), and the allocated capacity of the data (in elements). These are the same arguments in the same order as the arguments to from_raw_parts.

After calling this function, the caller is responsible for the memory previously managed by the Vec. The only way to do this is to convert the raw pointer, length, and capacity back into a Vec with the from_raw_parts function, allowing the destructor to perform the cleanup.

auto is_empty() const& -> bool

Returns true if the slice has a length of 0.

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

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.

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(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&>
auto last() && -> Option<const T&>
deleted

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

auto last_mut() & -> 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 pop() -> Option<T>

Removes the last element from a vector and returns it, or None if it is empty.

auto push(T t) -> void
requires
sus::mem::Move<T>

Appends an element to the back of the vector.

Panics

Panics if the new capacity exceeds isize::MAX bytes.

Implementation note

Avoids use of a reference, and receives by value, to sidestep the whole issue of the reference being to something inside the vector which reserve then invalidates.

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

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>
auto rchunks_exact(usize chunk_size) && -> RChunksExact<T>
deleted

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.

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) & -> 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& -> 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 reserve(sus::usize additional) -> void

Reserves capacity for at least additional more elements to be inserted in the given Vec<T>. The collection may reserve more space to speculatively avoid frequent reallocations. After calling reserve, capacity will be greater than or equal to self.len() + additional. Does nothing if capacity is already sufficient.

The grow_to_exact() function is similar to std::vector::reserve(), taking a capacity instead of the number of elements to ensure space for.

Panics

Panics if the new capacity exceeds isize::MAX bytes.

auto reserve_exact(sus::usize additional) -> void

Reserves the minimum capacity for at least additional more elements to be inserted in the given Vec<T>. Unlike reserve, this will not deliberately over-allocate to speculatively avoid frequent allocations. After calling reserve_exact, capacity will be greater than or equal to len() + additional. Does nothing if the capacity is already sufficient.

Note that the allocator may give the collection more space than it requests. Therefore, capacity can not be relied upon to be precisely minimal. Prefer reserve if future insertions are expected.

Panics

Panics if the new capacity exceeds isize::MAX bytes.

auto reverse() -> 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) -> 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) -> 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 &)>
template <class Pred>
auto rsplit(Pred) && -> Split<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>
deleted

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) & -> 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 &)>
template <class Pred>
auto rsplitn(sus::usize n, Pred pred) && -> RSplit<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>
deleted

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) & -> 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 set_len(UnsafeFnMarker, sus::usize new_len) -> void

Forces the length of the vector to new_len.

This is a low-level operation that maintains none of the normal invariants of the type. Normally changing the length of a vector is done using one of the safe operations instead, such as truncate(), resize(), extend(), or clear().

Safety

  • new_len must be less than or equal to capacity().
  • The elements at old_len..new_len must be constructed before or after the call.
  • The elements at new_len..old_len must be destructed before or after the call.
auto sort() -> 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) -> 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) -> 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) -> 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() -> 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) -> 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) -> 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 &)>
template <class Pred>
auto split(Pred) && -> Split<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>
deleted

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>>
auto split_at(usize mid) && -> Tuple<Slice<T>, Slice<T>>
deleted

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().

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>>>
auto split_first() && -> Option<Tuple<const T&, Slice<T>>>
deleted

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

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 &)>
template <class Pred>
auto split_inclusive(Pred) && -> SplitInclusive<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>
deleted

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) & -> 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>>>
auto split_last() && -> Option<Tuple<const T&, Slice<T>>>
deleted

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

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) & -> 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 &)>
template <class Pred>
auto splitn(sus::usize n, Pred pred) && -> Split<T, Pred>
requires
sus::fn::FnMut<Pred, _Bool (const T &)>
deleted

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) & -> 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>
auto strip_prefix(const Slice<T>& prefix) const& -> Option<Slice<T>>
deleted

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) & -> 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>
auto strip_suffix(const Slice<T>& suffix) const& -> Option<Slice<T>>
deleted

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) & -> 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>
auto subrange(sus::usize start) && -> Slice<T>
deleted
auto subrange(sus::usize start, sus::usize end) && -> Slice<T>
deleted

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) & -> SliceMut<T>
auto subrange_mut(sus::usize start, sus::usize end) & -> 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) -> 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) -> 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) -> 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) -> 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& -> 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 truncate(sus::usize len) -> void

Shortens the vector, keeping the first len elements and dropping the rest.

If len is greater than the vector's current length, this has no effect.

The drain method can emulate truncate, but causes the excess elements to be returned instead of dropped.

Note that this method has no effect on the allocated capacity of the vector.

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) & -> 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.

Conversions

Converts to a Slice<T>. A Vec can be used anywhere a Slice is wanted.

Converts to a SliceMut<T>. A mutable Vec can be used anywhere a SliceMut is wanted.

Operators

auto operator=(Vec<T>&& o) -> Vec<T>&

Satisifes the Move concept.

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

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

Panics

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

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

Returns a mutable reference to the element at position i in the Vec.

Panics

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

auto operator[](const RangeBounds<usize> auto range) const& -> Slice<T>
auto operator[](const RangeBounds<usize> auto range) && -> Slice<T>
deleted

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.

Panics

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

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

Returns a mutable 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.

Panics

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