ArrayN

Struct ArrayN 

Source
pub struct ArrayN<T, const N: usize>
where T: Copy + Default,
{ pub len: usize, pub arr: [T; N], }
Expand description

A fixed-capacity array with dynamic length.

ArrayN provides a stack-allocated array with a compile-time fixed capacity N but allows the actual used length to vary at runtime. This is useful for scenarios where you need the performance benefits of stack allocation but don’t always use the full capacity.

§Type Parameters

  • T - The element type, must implement Copy and Default
  • N - The maximum capacity of the array (compile-time constant)

§Examples

use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::empty();
arr.push(1);
arr.push(2);
assert_eq!(arr.len(), 2);
assert_eq!(arr.capacity(), 4);

Fields§

§len: usize

The current number of elements in use

§arr: [T; N]

The underlying fixed-size array storage

Implementations§

Source§

impl<T, const N: usize> ArrayN<T, N>
where T: Copy + Default,

Source

pub fn from_slice(slice: &[T]) -> Self

Creates an ArrayN from a slice.

Copies elements from the provided slice into a new ArrayN. The slice length must not exceed the array’s capacity N.

§Parameters
  • slice - The source slice to copy elements from
§Returns

A new ArrayN containing the copied elements with length equal to the slice length.

§Panics

Panics in debug mode if slice.len() > N.

§Examples
use slsl::ArrayN;

let slice = &[1, 2, 3];
let arr = ArrayN::<i32, 5>::from_slice(slice);
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], 1);
Source

pub fn empty() -> Self

Creates an empty ArrayN with uninitialized storage.

This is more efficient than default() as it doesn’t initialize the array elements, but the elements should not be accessed until they are explicitly set.

§Returns

An empty ArrayN with zero length and uninitialized elements.

§Safety

The returned array has uninitialized elements. Only access elements after they have been explicitly set (e.g., via push() or direct assignment).

§Examples
use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::empty();
assert_eq!(arr.len(), 0);
arr.push(42);
assert_eq!(arr[0], 42);
Source

pub fn with_len(self, len: usize) -> Self

Sets the length of the array and returns self.

This is a builder-style method that allows chaining. The caller must ensure that all elements up to the new length are properly initialized.

§Parameters
  • len - The new length to set
§Returns

Self with the updated length.

§Panics

Panics in debug mode if len > N.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::default().with_len(2);
assert_eq!(arr.len(), 2);
Source

pub fn full(val: T, len: usize) -> Self

Creates an ArrayN filled with a specific value.

All array elements are initialized to the provided value, but only the first len elements are considered active.

§Parameters
  • val - The value to fill the array with
  • len - The active length of the array
§Returns

A new ArrayN with all elements set to val and length set to len.

§Panics

Panics in debug mode if len > N.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::full(42, 3);
assert_eq!(arr.len(), 3);
assert_eq!(arr[0], 42);
assert_eq!(arr[2], 42);
Source

pub unsafe fn set_len(&mut self, new_len: usize)

Set the length of the array (unsafe)

§Safety

The caller must ensure that new_len is within the capacity bounds and that all elements up to new_len are properly initialized.

Source

pub fn len(&self) -> usize

Returns the current number of elements in the array.

§Returns

The number of active elements (not the total capacity).

§Examples
use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::empty();
assert_eq!(arr.len(), 0);
arr.push(1);
assert_eq!(arr.len(), 1);
Source

pub fn is_empty(&self) -> bool

Returns true if the array contains no elements.

§Returns

true if the length is 0, false otherwise.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::empty();
assert!(arr.is_empty());

let arr2 = ArrayN::<i32, 4>::full(1, 2);
assert!(!arr2.is_empty());
Source

pub const fn capacity(&self) -> usize

Returns the maximum number of elements the array can hold.

This is the compile-time constant N and never changes.

§Returns

The maximum capacity N.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 8>::empty();
assert_eq!(arr.capacity(), 8);
Source

pub fn as_slice(&self) -> &[T]

Returns a slice containing only the active elements.

This provides a view into the used portion of the array, excluding any unused capacity.

§Returns

A slice &[T] of the active elements.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
let slice = arr.as_slice();
assert_eq!(slice, &[1, 2, 3]);
Source

pub fn as_mut_slice(&mut self) -> &mut [T]

Returns a mutable slice containing only the active elements.

This provides mutable access to the used portion of the array.

§Returns

A mutable slice &mut [T] of the active elements.

§Examples
use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
let slice = arr.as_mut_slice();
slice[0] = 10;
assert_eq!(arr[0], 10);
Source

pub fn get(&self, index: usize) -> Option<T>

Returns the element at the given index, or None if out of bounds.

This provides safe access to array elements without panicking.

§Parameters
  • index - The index to access
§Returns

Some(element) if the index is valid, None otherwise.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
assert_eq!(arr.get(1), Some(2));
assert_eq!(arr.get(5), None);
Source

pub fn push(&mut self, value: T)

Adds an element to the end of the array.

Increases the length by 1 and sets the new element to the provided value.

§Parameters
  • value - The element to add
§Panics

Panics in debug mode if the array is already at capacity.

§Examples
use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::empty();
arr.push(1);
arr.push(2);
assert_eq!(arr.len(), 2);
assert_eq!(arr[1], 2);
Source

pub fn remove(&mut self, index: usize)

Removes the element at the specified index.

All elements after the removed element are shifted left to fill the gap. The length is decreased by 1.

§Parameters
  • index - The index of the element to remove
§Panics

Panics in debug mode if the index is out of bounds.

§Examples
use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3, 4]);
arr.remove(1);
assert_eq!(arr.as_slice(), &[1, 3, 4]);
Source§

impl<T, const N: usize> ArrayN<T, N>
where T: Copy + Default,

Source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the active elements.

§Returns

An iterator yielding references to the active elements.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
let sum: i32 = arr.iter().sum();
assert_eq!(sum, 6);
Source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns a mutable iterator over the active elements.

§Returns

An iterator yielding mutable references to the active elements.

§Examples
use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
for elem in arr.iter_mut() {
    *elem *= 2;
}
assert_eq!(arr.as_slice(), &[2, 4, 6]);
Source§

impl ArrayN<usize, { MAX_DIM }>

Source

pub fn numel(&self) -> usize

Returns the total number of elements in the tensor.

This method calculates the product of all dimensions in the shape, which gives the total number of elements that would be stored in a tensor with this shape.

§Returns

The total number of elements as a usize. Returns 1 for empty shapes (0-dimensional tensors/scalars).

§Examples
use slsl::Shape;

// 2D shape: 3x4 matrix
let shape = Shape::from_slice(&[3, 4]);
assert_eq!(shape.numel(), 12); // 3 * 4

// 1D shape: vector of 5 elements
let shape_1d = Shape::from_slice(&[5]);
assert_eq!(shape_1d.numel(), 5);

// Empty shape: scalar (0-dimensional)
let shape_scalar = Shape::empty();
assert_eq!(shape_scalar.numel(), 1);

Methods from Deref<Target = [T]>§

1.0.0 · Source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

§Examples
let a = [1, 2, 3];
assert_eq!(a.len(), 3);
1.0.0 · Source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

§Examples
let a = [1, 2, 3];
assert!(!a.is_empty());

let b: &[i32] = &[];
assert!(b.is_empty());
1.0.0 · Source

pub fn first(&self) -> Option<&T>

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

§Examples
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());

let w: &[i32] = &[];
assert_eq!(None, w.first());
1.5.0 · Source

pub fn split_first(&self) -> Option<(&T, &[T])>

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

§Examples
let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first() {
    assert_eq!(first, &0);
    assert_eq!(elements, &[1, 2]);
}
1.5.0 · Source

pub fn split_last(&self) -> Option<(&T, &[T])>

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

§Examples
let x = &[0, 1, 2];

if let Some((last, elements)) = x.split_last() {
    assert_eq!(last, &2);
    assert_eq!(elements, &[0, 1]);
}
1.0.0 · Source

pub fn last(&self) -> Option<&T>

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

§Examples
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());

let w: &[i32] = &[];
assert_eq!(None, w.last());
1.77.0 · Source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Returns an array reference to the first N items in the slice.

If the slice is not at least N in length, this will return None.

§Examples
let u = [10, 40, 30];
assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());

let v: &[i32] = &[10];
assert_eq!(None, v.first_chunk::<2>());

let w: &[i32] = &[];
assert_eq!(Some(&[]), w.first_chunk::<0>());
1.77.0 · Source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Returns an array reference to the first N items in the slice and the remaining slice.

If the slice is not at least N in length, this will return None.

§Examples
let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first_chunk::<2>() {
    assert_eq!(first, &[0, 1]);
    assert_eq!(elements, &[2]);
}

assert_eq!(None, x.split_first_chunk::<4>());
1.77.0 · Source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Returns an array reference to the last N items in the slice and the remaining slice.

If the slice is not at least N in length, this will return None.

§Examples
let x = &[0, 1, 2];

if let Some((elements, last)) = x.split_last_chunk::<2>() {
    assert_eq!(elements, &[0]);
    assert_eq!(last, &[1, 2]);
}

assert_eq!(None, x.split_last_chunk::<4>());
1.77.0 · Source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Returns an array reference to the last N items in the slice.

If the slice is not at least N in length, this will return None.

§Examples
let u = [10, 40, 30];
assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());

let v: &[i32] = &[10];
assert_eq!(None, v.last_chunk::<2>());

let w: &[i32] = &[];
assert_eq!(Some(&[]), w.last_chunk::<0>());
1.0.0 · Source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of index.

  • If given a position, returns a reference to the element at that position or None if out of bounds.
  • If given a range, returns the subslice corresponding to that range, or None if out of bounds.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));
1.0.0 · Source

pub unsafe fn get_unchecked<I>( &self, index: I, ) -> &<I as SliceIndex<[T]>>::Output
where I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds checking.

For a safe alternative see get.

§Safety

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

You can think of this like .get(index).unwrap_unchecked(). It’s UB to call .get_unchecked(len), even if you immediately convert to a pointer. And it’s UB to call .get_unchecked(..len + 1), .get_unchecked(..=len), or similar.

§Examples
let x = &[1, 2, 4];

unsafe {
    assert_eq!(x.get_unchecked(1), &2);
}
1.0.0 · Source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

The caller must ensure that the slice outlives the pointer this function returns, or else it will end up dangling.

The caller must also ensure that the memory the pointer (non-transitively) points to is never written to (except inside an UnsafeCell) using this pointer or any pointer derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

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

§Examples
let x = &[1, 2, 4];
let x_ptr = x.as_ptr();

unsafe {
    for i in 0..x.len() {
        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
    }
}
1.48.0 · Source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw 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.

See as_ptr for warnings on using these pointers. The end pointer requires extra caution, as it does not point to a valid element in the slice.

This function is useful for interacting with foreign interfaces which use two pointers to refer to a range of elements in memory, as is common in C++.

It can also be useful to check if a pointer to an element refers to an element of this slice:

let a = [1, 2, 3];
let x = &a[1] as *const _;
let y = &5 as *const _;

assert!(a.as_ptr_range().contains(&x));
assert!(!a.as_ptr_range().contains(&y));
Source

pub fn as_array<const N: usize>(&self) -> Option<&[T; N]>

🔬This is a nightly-only experimental API. (slice_as_array)

Gets a reference to the underlying array.

If N is not exactly equal to the length of self, then this method returns None.

1.0.0 · Source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

The iterator yields all items from start to end.

§Examples
let x = &[1, 2, 4];
let mut iterator = x.iter();

assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), Some(&2));
assert_eq!(iterator.next(), Some(&4));
assert_eq!(iterator.next(), None);
1.0.0 · Source

pub fn windows(&self, size: usize) -> 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 zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.windows(3);
assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
assert!(iter.next().is_none());

If the slice is shorter than size:

let slice = ['f', 'o', 'o'];
let mut iter = slice.windows(4);
assert!(iter.next().is_none());

Because the Iterator trait cannot represent the required lifetimes, there is no windows_mut analog to windows; [0,1,2].windows_mut(2).collect() would violate the rules of references (though a LendingIterator analog is possible). You can sometimes use Cell::as_slice_of_cells in conjunction with windows instead:

use std::cell::Cell;

let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
let slice = &mut array[..];
let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
for w in slice_of_cells.windows(3) {
    Cell::swap(&w[0], &w[2]);
}
assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
1.0.0 · Source

pub fn chunks(&self, chunk_size: usize) -> 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.

If your chunk_size is a constant, consider using as_chunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert_eq!(iter.next().unwrap(), &['m']);
assert!(iter.next().is_none());
1.31.0 · Source

pub fn chunks_exact(&self, chunk_size: usize) -> 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.

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.

If your chunk_size is a constant, consider using as_chunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks_exact(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['m']);
1.88.0 · Source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

Splits the slice into a slice of N-element arrays, assuming that there’s no remainder.

This is the inverse operation to as_flattened.

As this is unsafe, consider whether you could use as_chunks or as_rchunks instead, perhaps via something like if let (chunks, []) = slice.as_chunks() or let (chunks, []) = slice.as_chunks() else { unreachable!() };.

§Safety

This may only be called when

  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • N != 0.
§Examples
let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &[[char; 1]] =
    // SAFETY: 1-element chunks never have remainder
    unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &[[char; 3]] =
    // SAFETY: The slice length (6) is a multiple of 3
    unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);

// These would be unsound:
// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
1.88.0 · Source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

Splits the slice into a slice of N-element arrays, starting at the beginning of the slice, and a remainder slice with length strictly less than N.

The remainder is meaningful in the division sense. Given let (chunks, remainder) = slice.as_chunks(), then:

  • chunks.len() equals slice.len() / N,
  • remainder.len() equals slice.len() % N, and
  • slice.len() equals chunks.len() * N + remainder.len().

You can flatten the chunks back into a slice-of-T with as_flattened.

§Panics

Panics if N is zero.

Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let (chunks, remainder) = slice.as_chunks();
assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
assert_eq!(remainder, &['m']);

If you expect the slice to be an exact multiple, you can combine let-else with an empty slice pattern:

let slice = ['R', 'u', 's', 't'];
let (chunks, []) = slice.as_chunks::<2>() else {
    panic!("slice didn't have even length")
};
assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
1.88.0 · Source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

Splits the slice into a slice of N-element arrays, starting at the end of the slice, and a remainder slice with length strictly less than N.

The remainder is meaningful in the division sense. Given let (remainder, chunks) = slice.as_rchunks(), then:

  • remainder.len() equals slice.len() % N,
  • chunks.len() equals slice.len() / N, and
  • slice.len() equals chunks.len() * N + remainder.len().

You can flatten the chunks back into a slice-of-T with as_flattened.

§Panics

Panics if N is zero.

Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let (remainder, chunks) = slice.as_rchunks();
assert_eq!(remainder, &['l']);
assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
Source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, starting at the beginning of the slice.

This is the const generic equivalent of windows.

If N is greater than the size of the slice, it will return no windows.

§Panics

Panics if N is zero. This check will most probably get changed to a compile time error before this method gets stabilized.

§Examples
#![feature(array_windows)]
let slice = [0, 1, 2, 3];
let mut iter = slice.array_windows();
assert_eq!(iter.next().unwrap(), &[0, 1]);
assert_eq!(iter.next().unwrap(), &[1, 2]);
assert_eq!(iter.next().unwrap(), &[2, 3]);
assert!(iter.next().is_none());
1.31.0 · Source

pub fn rchunks(&self, chunk_size: usize) -> 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.

If your chunk_size is a constant, consider using as_rchunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert_eq!(iter.next().unwrap(), &['l']);
assert!(iter.next().is_none());
1.31.0 · Source

pub fn rchunks_exact(&self, chunk_size: usize) -> 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.

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.

If your chunk_size is a constant, consider using as_rchunks instead, which will give references to arrays of exactly that length, rather than slices.

§Panics

Panics if chunk_size is zero.

§Examples
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks_exact(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['l']);
1.77.0 · Source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs of elements using the predicate to separate them.

The predicate is called for every pair of consecutive elements, meaning that it is called on slice[0] and slice[1], followed by slice[1] and slice[2], and so on.

§Examples
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];

let mut iter = slice.chunk_by(|a, b| a == b);

assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), None);

This method can be used to extract the sorted subslices:

let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];

let mut iter = slice.chunk_by(|a, b| a <= b);

assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
assert_eq!(iter.next(), None);
1.0.0 · Source

pub fn split_at(&self, mid: usize) -> (&[T], &[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. For a non-panicking alternative see split_at_checked.

§Examples
let v = ['a', 'b', 'c'];

{
   let (left, right) = v.split_at(0);
   assert_eq!(left, []);
   assert_eq!(right, ['a', 'b', 'c']);
}

{
    let (left, right) = v.split_at(2);
    assert_eq!(left, ['a', 'b']);
    assert_eq!(right, ['c']);
}

{
    let (left, right) = v.split_at(3);
    assert_eq!(left, ['a', 'b', 'c']);
    assert_eq!(right, []);
}
1.79.0 · Source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

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 <= self.len().

§Examples
let v = ['a', 'b', 'c'];

unsafe {
   let (left, right) = v.split_at_unchecked(0);
   assert_eq!(left, []);
   assert_eq!(right, ['a', 'b', 'c']);
}

unsafe {
    let (left, right) = v.split_at_unchecked(2);
    assert_eq!(left, ['a', 'b']);
    assert_eq!(right, ['c']);
}

unsafe {
    let (left, right) = v.split_at_unchecked(3);
    assert_eq!(left, ['a', 'b', 'c']);
    assert_eq!(right, []);
}
1.80.0 · Source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is too short.

If mid ≤ len returns a pair of slices where 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).

Otherwise, if mid > len, returns None.

§Examples
let v = [1, -2, 3, -4, 5, -6];

{
   let (left, right) = v.split_at_checked(0).unwrap();
   assert_eq!(left, []);
   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
}

{
    let (left, right) = v.split_at_checked(2).unwrap();
    assert_eq!(left, [1, -2]);
    assert_eq!(right, [3, -4, 5, -6]);
}

{
    let (left, right) = v.split_at_checked(6).unwrap();
    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
    assert_eq!(right, []);
}

assert_eq!(None, v.split_at_checked(7));
1.0.0 · Source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where F: FnMut(&T) -> bool,

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

§Examples
let slice = [10, 40, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());

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:

let slice = [10, 40, 33];
let mut iter = slice.split(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[]);
assert!(iter.next().is_none());

If two matched elements are directly adjacent, an empty slice will be present between them:

let slice = [10, 6, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10]);
assert_eq!(iter.next().unwrap(), &[]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
1.51.0 · Source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where F: FnMut(&T) -> bool,

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.

§Examples
let slice = [10, 40, 33, 20];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());

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.

let slice = [3, 10, 40, 33];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);

assert_eq!(iter.next().unwrap(), &[3]);
assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert!(iter.next().is_none());
1.27.0 · Source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where F: FnMut(&T) -> bool,

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.

§Examples
let slice = [11, 22, 33, 0, 44, 55];
let mut iter = slice.rsplit(|num| *num == 0);

assert_eq!(iter.next().unwrap(), &[44, 55]);
assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
assert_eq!(iter.next(), None);

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.

let v = &[0, 1, 1, 2, 3, 5, 8];
let mut it = v.rsplit(|n| *n % 2 == 0);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next().unwrap(), &[3, 5]);
assert_eq!(it.next().unwrap(), &[1, 1]);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next(), None);
1.0.0 · Source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where F: FnMut(&T) -> bool,

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.

§Examples

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], [20, 60, 50]):

let v = [10, 40, 30, 20, 60, 50];

for group in v.splitn(2, |num| *num % 3 == 0) {
    println!("{group:?}");
}
1.0.0 · Source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where F: FnMut(&T) -> bool,

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.

§Examples

Print the slice split once, starting from the end, by numbers divisible by 3 (i.e., [50], [10, 40, 30, 20]):

let v = [10, 40, 30, 20, 60, 50];

for group in v.rsplitn(2, |num| *num % 3 == 0) {
    println!("{group:?}");
}
Source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified predicate.

If any matching elements are present in the slice, returns the prefix before the match and suffix after. The matching element itself is not included. If no elements match, returns None.

§Examples
#![feature(slice_split_once)]
let s = [1, 2, 3, 2, 4];
assert_eq!(s.split_once(|&x| x == 2), Some((
    &[1][..],
    &[3, 2, 4][..]
)));
assert_eq!(s.split_once(|&x| x == 0), None);
Source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified predicate.

If any matching elements are present in the slice, returns the prefix before the match and suffix after. The matching element itself is not included. If no elements match, returns None.

§Examples
#![feature(slice_split_once)]
let s = [1, 2, 3, 2, 4];
assert_eq!(s.rsplit_once(|&x| x == 2), Some((
    &[1, 2, 3][..],
    &[4][..]
)));
assert_eq!(s.rsplit_once(|&x| x == 0), None);
1.0.0 · Source

pub fn contains(&self, x: &T) -> bool
where T: PartialEq,

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.

§Examples
let v = [10, 40, 30];
assert!(v.contains(&30));
assert!(!v.contains(&50));

If you do not have a &T, but some other value that you can compare with one (for example, String implements PartialEq<str>), you can use iter().any:

let v = [String::from("hello"), String::from("world")]; // slice of `String`
assert!(v.iter().any(|e| e == "hello")); // search with `&str`
assert!(!v.iter().any(|e| e == "hi"));
1.0.0 · Source

pub fn starts_with(&self, needle: &[T]) -> bool
where T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

§Examples
let v = [10, 40, 30];
assert!(v.starts_with(&[10]));
assert!(v.starts_with(&[10, 40]));
assert!(v.starts_with(&v));
assert!(!v.starts_with(&[50]));
assert!(!v.starts_with(&[10, 50]));

Always returns true if needle is an empty slice:

let v = &[10, 40, 30];
assert!(v.starts_with(&[]));
let v: &[u8] = &[];
assert!(v.starts_with(&[]));
1.0.0 · Source

pub fn ends_with(&self, needle: &[T]) -> bool
where T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

§Examples
let v = [10, 40, 30];
assert!(v.ends_with(&[30]));
assert!(v.ends_with(&[40, 30]));
assert!(v.ends_with(&v));
assert!(!v.ends_with(&[50]));
assert!(!v.ends_with(&[50, 30]));

Always returns true if needle is an empty slice:

let v = &[10, 40, 30];
assert!(v.ends_with(&[]));
let v: &[u8] = &[];
assert!(v.ends_with(&[]));
1.51.0 · Source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

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 prefix is equal to the original slice, returns an empty slice.

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

§Examples
let v = &[10, 40, 30];
assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_prefix(&[50]), None);
assert_eq!(v.strip_prefix(&[10, 50]), None);

let prefix : &str = "he";
assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
           Some(b"llo".as_ref()));
1.51.0 · Source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

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 suffix is equal to the original slice, returns an empty slice.

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

§Examples
let v = &[10, 40, 30];
assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_suffix(&[50]), None);
assert_eq!(v.strip_suffix(&[50, 30]), None);
Source

pub fn trim_prefix<P>(&self, prefix: &P) -> &[T]
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

🔬This is a nightly-only experimental API. (trim_prefix_suffix)

Returns a subslice with the optional prefix removed.

If the slice starts with prefix, returns the subslice after the prefix. If prefix is empty or the slice does not start with prefix, simply returns the original slice. If prefix is equal to the original slice, returns an empty slice.

§Examples
#![feature(trim_prefix_suffix)]

let v = &[10, 40, 30];

// Prefix present - removes it
assert_eq!(v.trim_prefix(&[10]), &[40, 30][..]);
assert_eq!(v.trim_prefix(&[10, 40]), &[30][..]);
assert_eq!(v.trim_prefix(&[10, 40, 30]), &[][..]);

// Prefix absent - returns original slice
assert_eq!(v.trim_prefix(&[50]), &[10, 40, 30][..]);
assert_eq!(v.trim_prefix(&[10, 50]), &[10, 40, 30][..]);

let prefix : &str = "he";
assert_eq!(b"hello".trim_prefix(prefix.as_bytes()), b"llo".as_ref());
Source

pub fn trim_suffix<P>(&self, suffix: &P) -> &[T]
where P: SlicePattern<Item = T> + ?Sized, T: PartialEq,

🔬This is a nightly-only experimental API. (trim_prefix_suffix)

Returns a subslice with the optional suffix removed.

If the slice ends with suffix, returns the subslice before the suffix. If suffix is empty or the slice does not end with suffix, simply returns the original slice. If suffix is equal to the original slice, returns an empty slice.

§Examples
#![feature(trim_prefix_suffix)]

let v = &[10, 40, 30];

// Suffix present - removes it
assert_eq!(v.trim_suffix(&[30]), &[10, 40][..]);
assert_eq!(v.trim_suffix(&[40, 30]), &[10][..]);
assert_eq!(v.trim_suffix(&[10, 40, 30]), &[][..]);

// Suffix absent - returns original slice
assert_eq!(v.trim_suffix(&[50]), &[10, 40, 30][..]);
assert_eq!(v.trim_suffix(&[50, 30]), &[10, 40, 30][..]);

Binary searches this slice for a given element. If the slice is not sorted, the returned result is unspecified and meaningless.

If the value is found then Result::Ok is returned, containing 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 Rust. If the value is not found then Result::Err is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search_by, binary_search_by_key, and partition_point.

§Examples

Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

assert_eq!(s.binary_search(&13),  Ok(9));
assert_eq!(s.binary_search(&4),   Err(7));
assert_eq!(s.binary_search(&100), Err(13));
let r = s.binary_search(&1);
assert!(match r { Ok(1..=4) => true, _ => false, });

If you want to find that whole range of matching items, rather than an arbitrary matching one, that can be done using partition_point:

let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

let low = s.partition_point(|x| x < &1);
assert_eq!(low, 1);
let high = s.partition_point(|x| x <= &1);
assert_eq!(high, 5);
let r = s.binary_search(&1);
assert!((low..high).contains(&r.unwrap()));

assert!(s[..low].iter().all(|&x| x < 1));
assert!(s[low..high].iter().all(|&x| x == 1));
assert!(s[high..].iter().all(|&x| x > 1));

// For something not found, the "range" of equal items is empty
assert_eq!(s.partition_point(|x| x < &11), 9);
assert_eq!(s.partition_point(|x| x <= &11), 9);
assert_eq!(s.binary_search(&11), Err(9));

If you want to insert an item to a sorted vector, while maintaining sort order, consider using partition_point:

let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x <= num);
// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
// to shift less elements.
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1.0.0 · Source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

The comparator function should return an order code that indicates whether its argument is Less, Equal or Greater the desired target. If the slice is not sorted or if the comparator function does not implement an order consistent with the sort order of the underlying slice, the returned result is unspecified and meaningless.

If the value is found then Result::Ok is returned, containing 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 Rust. If the value is not found then Result::Err is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search, binary_search_by_key, and partition_point.

§Examples

Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];

let seek = 13;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
let seek = 4;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
let seek = 100;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
let seek = 1;
let r = s.binary_search_by(|probe| probe.cmp(&seek));
assert!(match r { Ok(1..=4) => true, _ => false, });
1.10.0 · Source

pub fn binary_search_by_key<'a, B, F>( &'a self, b: &B, f: F, ) -> Result<usize, usize>
where F: FnMut(&'a T) -> B, B: Ord,

Binary searches this slice with a key extraction function.

Assumes that the slice is sorted by the key, for instance with sort_by_key using the same key extraction function. If the slice is not sorted by the key, the returned result is unspecified and meaningless.

If the value is found then Result::Ok is returned, containing 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 Rust. If the value is not found then Result::Err is returned, containing the index where a matching element could be inserted while maintaining sorted order.

See also binary_search, binary_search_by, and partition_point.

§Examples

Looks up a series of four elements in a slice of pairs sorted by their second elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4].

let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
         (1, 21), (2, 34), (4, 55)];

assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
let r = s.binary_search_by_key(&1, |&(a, b)| b);
assert!(match r { Ok(1..=4) => true, _ => false, });
1.30.0 · Source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmutes the slice to a slice of another type, ensuring alignment of the types is maintained.

This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new type, and the suffix slice. The middle part will be as big as possible under the given alignment constraint and element size.

This method has no purpose when either input element T or output element U are zero-sized and will return the original slice without splitting anything.

§Safety

This method is essentially a transmute with respect to the elements in the returned middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

§Examples

Basic usage:

unsafe {
    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
    // less_efficient_algorithm_for_bytes(prefix);
    // more_efficient_algorithm_for_aligned_shorts(shorts);
    // less_efficient_algorithm_for_bytes(suffix);
}
Source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])

🔬This is a nightly-only experimental API. (portable_simd)

Splits a slice into a prefix, a middle of aligned SIMD types, and a suffix.

This is a safe wrapper around slice::align_to, so inherits the same guarantees as that method.

§Panics

This will panic if the size of the SIMD type is different from LANES times that of the scalar.

At the time of writing, the trait restrictions on Simd<T, LANES> keeps that from ever happening, as only power-of-two numbers of lanes are supported. It’s possible that, in the future, those restrictions might be lifted in a way that would make it possible to see panics from this method for something like LANES == 3.

§Examples
#![feature(portable_simd)]
use core::simd::prelude::*;

let short = &[1, 2, 3];
let (prefix, middle, suffix) = short.as_simd::<4>();
assert_eq!(middle, []); // Not enough elements for anything in the middle

// They might be split in any possible way between prefix and suffix
let it = prefix.iter().chain(suffix).copied();
assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);

fn basic_simd_sum(x: &[f32]) -> f32 {
    use std::ops::Add;
    let (prefix, middle, suffix) = x.as_simd();
    let sums = f32x4::from_array([
        prefix.iter().copied().sum(),
        0.0,
        0.0,
        suffix.iter().copied().sum(),
    ]);
    let sums = middle.iter().copied().fold(sums, f32x4::add);
    sums.reduce_sum()
}

let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
1.82.0 · Source

pub fn is_sorted(&self) -> bool
where T: PartialOrd,

Checks if the elements of this slice are sorted.

That is, for each element a and its following element b, a <= b must hold. If the slice yields exactly zero or one element, true is returned.

Note that if Self::Item is only PartialOrd, but not Ord, the above definition implies that this function returns false if any two consecutive items are not comparable.

§Examples
let empty: [i32; 0] = [];

assert!([1, 2, 2, 9].is_sorted());
assert!(![1, 3, 2, 4].is_sorted());
assert!([0].is_sorted());
assert!(empty.is_sorted());
assert!(![0.0, 1.0, f32::NAN].is_sorted());
1.82.0 · Source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where F: FnMut(&'a T, &'a T) -> bool,

Checks if the elements of this slice are sorted using the given comparator function.

Instead of using PartialOrd::partial_cmp, this function uses the given compare function to determine whether two elements are to be considered in sorted order.

§Examples
assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));

assert!([0].is_sorted_by(|a, b| true));
assert!([0].is_sorted_by(|a, b| false));

let empty: [i32; 0] = [];
assert!(empty.is_sorted_by(|a, b| false));
assert!(empty.is_sorted_by(|a, b| true));
1.82.0 · Source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where F: FnMut(&'a T) -> K, K: PartialOrd,

Checks if the elements of this slice are sorted using the given key extraction function.

Instead of comparing the slice’s elements directly, this function compares the keys of the elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its documentation for more information.

§Examples
assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
1.52.0 · Source

pub fn partition_point<P>(&self, pred: P) -> usize
where P: FnMut(&T) -> bool,

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.

§Examples
let v = [1, 2, 3, 3, 5, 6, 7];
let i = v.partition_point(|&x| x < 5);

assert_eq!(i, 4);
assert!(v[..i].iter().all(|&x| x < 5));
assert!(v[i..].iter().all(|&x| !(x < 5)));

If all elements of the slice match the predicate, including if the slice is empty, then the length of the slice will be returned:

let a = [2, 4, 8];
assert_eq!(a.partition_point(|x| x < &100), a.len());
let a: [i32; 0] = [];
assert_eq!(a.partition_point(|x| x < &100), 0);

If you want to insert an item to a sorted vector, while maintaining sort order:

let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x <= num);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
Source

pub fn element_offset(&self, element: &T) -> Option<usize>

🔬This is a nightly-only experimental API. (substr_range)

Returns the index that an element reference points to.

Returns None if element does not point to the start of an element within the slice.

This method is useful for extending slice iterators like slice::split.

Note that this uses pointer arithmetic and does not compare elements. To find the index of an element via comparison, use .iter().position() instead.

§Panics

Panics if T is zero-sized.

§Examples

Basic usage:

#![feature(substr_range)]

let nums: &[u32] = &[1, 7, 1, 1];
let num = &nums[2];

assert_eq!(num, &1);
assert_eq!(nums.element_offset(num), Some(2));

Returning None with an unaligned element:

#![feature(substr_range)]

let arr: &[[u32; 2]] = &[[0, 1], [2, 3]];
let flat_arr: &[u32] = arr.as_flattened();

let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap();
let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap();

assert_eq!(ok_elm, &[0, 1]);
assert_eq!(weird_elm, &[1, 2]);

assert_eq!(arr.element_offset(ok_elm), Some(0)); // Points to element 0
assert_eq!(arr.element_offset(weird_elm), None); // Points between element 0 and 1
Source

pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>>

🔬This is a nightly-only experimental API. (substr_range)

Returns the range of indices that a subslice points to.

Returns None if subslice does not point within the slice or if it is not aligned with the elements in the slice.

This method does not compare elements. Instead, this method finds the location in the slice that subslice was obtained from. To find the index of a subslice via comparison, instead use .windows().position().

This method is useful for extending slice iterators like slice::split.

Note that this may return a false positive (either Some(0..0) or Some(self.len()..self.len())) if subslice has a length of zero and points to the beginning or end of another, separate, slice.

§Panics

Panics if T is zero-sized.

§Examples

Basic usage:

#![feature(substr_range)]

let nums = &[0, 5, 10, 0, 0, 5];

let mut iter = nums
    .split(|t| *t == 0)
    .map(|n| nums.subslice_range(n).unwrap());

assert_eq!(iter.next(), Some(0..0));
assert_eq!(iter.next(), Some(1..3));
assert_eq!(iter.next(), Some(4..4));
assert_eq!(iter.next(), Some(5..6));
1.0.0 · Source

pub fn to_vec(&self) -> Vec<T>
where T: Clone,

Copies self into a new Vec.

§Examples
let s = [10, 40, 30];
let x = s.to_vec();
// Here, `s` and `x` can be modified independently.
Source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where A: Allocator, T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)

Copies self into a new Vec with an allocator.

§Examples
#![feature(allocator_api)]

use std::alloc::System;

let s = [10, 40, 30];
let x = s.to_vec_in(System);
// Here, `s` and `x` can be modified independently.
1.40.0 · Source

pub fn repeat(&self, n: usize) -> Vec<T>
where T: Copy,

Creates a vector by copying a slice n times.

§Panics

This function will panic if the capacity would overflow.

§Examples
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);

A panic upon overflow:

// this will panic at runtime
b"0123456789abcdef".repeat(usize::MAX);
1.0.0 · Source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where [T]: Concat<Item>, Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

§Examples
assert_eq!(["hello", "world"].concat(), "helloworld");
assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
1.3.0 · Source

pub fn join<Separator>( &self, sep: Separator, ) -> <[T] as Join<Separator>>::Output
where [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a given separator between each.

§Examples
assert_eq!(["hello", "world"].join(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
1.0.0 · Source

pub fn connect<Separator>( &self, sep: Separator, ) -> <[T] as Join<Separator>>::Output
where [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a given separator between each.

§Examples
assert_eq!(["hello", "world"].connect(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);

Trait Implementations§

Source§

impl<T, const N: usize> Clone for ArrayN<T, N>
where T: Copy + Default + Clone,

Source§

fn clone(&self) -> ArrayN<T, N>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T, const N: usize> Debug for ArrayN<T, N>
where T: Copy + Default + Display,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the ArrayN for debugging, showing it as a list of elements.

Only the active elements (up to len) are displayed.

Source§

impl<T: Copy + Default, const N: usize> Default for ArrayN<T, N>

Source§

fn default() -> Self

Creates a new ArrayN with zero length and default-initialized elements.

§Returns

An empty ArrayN with all elements initialized to their default values.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::default();
assert_eq!(arr.len(), 0);
assert!(arr.is_empty());
Source§

impl<T: Copy + Default, const N: usize> Deref for ArrayN<T, N>

Source§

fn deref(&self) -> &Self::Target

Dereferences the ArrayN to a slice containing only the active elements.

This allows ArrayN to be used anywhere a slice is expected.

§Returns

A slice &[T] containing only the elements from index 0 to len-1.

Source§

type Target = [T]

The resulting type after dereferencing.
Source§

impl<T, const N: usize> Display for ArrayN<T, N>
where T: Copy + Default + Display,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the ArrayN as a comma-separated list enclosed in brackets.

Only the active elements (up to len) are displayed.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
assert_eq!(format!("{}", arr), "[1, 2, 3]");
Source§

impl<T, const N: usize> From<&[T]> for ArrayN<T, N>
where T: Copy + Default,

Source§

fn from(dims: &[T]) -> Self

Creates an ArrayN from a slice.

§Parameters
  • dims - The source slice to copy from
§Returns

A new ArrayN containing the elements from the slice.

§Panics

Panics in debug mode if dims.len() > N.

Source§

impl<T, const N: usize, const M: usize> From<[T; M]> for ArrayN<T, N>
where T: Copy + Default,

Source§

fn from(dims: [T; M]) -> Self

Creates an ArrayN from a fixed-size array.

§Parameters
  • dims - The source array to copy from
§Returns

A new ArrayN containing the elements from the source array.

§Panics

Panics in debug mode if M > N.

Source§

impl<const N: usize> From<()> for ArrayN<usize, N>

Source§

fn from(_: ()) -> Self

Creates an empty ArrayN<usize, N> from the unit type.

§Returns

An empty ArrayN with zero length.

Source§

impl<const N: usize> From<(usize,)> for ArrayN<usize, N>

Source§

fn from(dims: (usize,)) -> Self

Creates an ArrayN<usize, N> from a single-element tuple.

§Parameters
  • dims - A tuple containing one usize value
§Returns

A new ArrayN with length 1 containing the tuple’s value.

Source§

impl<const N: usize> From<(usize, usize)> for ArrayN<usize, N>

Source§

fn from(dims: (usize, usize)) -> Self

Creates an ArrayN<usize, N> from a two-element tuple.

§Parameters
  • dims - A tuple containing two usize values
§Returns

A new ArrayN with length 2 containing the tuple’s values.

Source§

impl<const N: usize> From<(usize, usize, usize)> for ArrayN<usize, N>

Source§

fn from(dims: (usize, usize, usize)) -> Self

Creates an ArrayN<usize, N> from a three-element tuple.

§Parameters
  • dims - A tuple containing three usize values
§Returns

A new ArrayN with length 3 containing the tuple’s values.

Source§

impl<const N: usize> From<(usize, usize, usize, usize)> for ArrayN<usize, N>

Source§

fn from(dims: (usize, usize, usize, usize)) -> Self

Creates an ArrayN<usize, N> from a four-element tuple.

§Parameters
  • dims - A tuple containing four usize values
§Returns

A new ArrayN with length 4 containing the tuple’s values.

Source§

impl<T, const N: usize> From<Vec<T>> for ArrayN<T, N>
where T: Copy + Default,

Source§

fn from(dims: Vec<T>) -> Self

Creates an ArrayN from a Vec.

§Parameters
  • dims - The source vector to copy from
§Returns

A new ArrayN containing the elements from the vector.

§Panics

Panics in debug mode if dims.len() > N.

Source§

impl<const N: usize> From<i32> for ArrayN<usize, N>

Source§

fn from(value: i32) -> Self

Creates an ArrayN<usize, N> from an i32 value.

The i32 value is cast to usize.

§Parameters
  • value - The i32 value to convert and store
§Returns

A new ArrayN with length 1 containing the converted value.

Source§

impl<const N: usize> From<isize> for ArrayN<usize, N>

Source§

fn from(value: isize) -> Self

Creates an ArrayN<usize, N> from an isize value.

The isize value is cast to usize.

§Parameters
  • value - The isize value to convert and store
§Returns

A new ArrayN with length 1 containing the converted value.

Source§

impl<const N: usize> From<u32> for ArrayN<usize, N>

Source§

fn from(value: u32) -> Self

Creates an ArrayN<usize, N> from a u32 value.

The u32 value is cast to usize.

§Parameters
  • value - The u32 value to convert and store
§Returns

A new ArrayN with length 1 containing the converted value.

Source§

impl<const N: usize> From<usize> for ArrayN<usize, N>

Source§

fn from(value: usize) -> Self

Creates an ArrayN<usize, N> from a single usize value.

§Parameters
  • value - The value to store as the first element
§Returns

A new ArrayN with length 1 containing the provided value.

Source§

impl<T, const N: usize> Index<usize> for ArrayN<T, N>
where T: Copy + Default,

Source§

fn index(&self, index: usize) -> &Self::Output

Returns a reference to the element at the given index.

§Parameters
  • index - The index to access
§Returns

A reference to the element at the specified index.

§Panics

Panics in debug mode if the index is out of bounds.

§Examples
use slsl::ArrayN;

let arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
assert_eq!(arr[1], 2);
Source§

type Output = T

The returned type after indexing.
Source§

impl<T, const N: usize> IndexMut<usize> for ArrayN<T, N>
where T: Copy + Default,

Source§

fn index_mut(&mut self, index: usize) -> &mut Self::Output

Returns a mutable reference to the element at the given index.

§Parameters
  • index - The index to access
§Returns

A mutable reference to the element at the specified index.

§Panics

Panics in debug mode if the index is out of bounds.

§Examples
use slsl::ArrayN;

let mut arr = ArrayN::<i32, 4>::from_slice(&[1, 2, 3]);
arr[1] = 10;
assert_eq!(arr[1], 10);
Source§

impl<'a, T, const N: usize> IntoIterator for &'a ArrayN<T, N>
where T: Copy + Default,

Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator over references to the active elements.

§Returns

An iterator yielding references to the active elements.

Source§

type Item = &'a T

The type of the elements being iterated over.
Source§

type IntoIter = Iter<'a, T>

Which kind of iterator are we turning this into?
Source§

impl<'a, T, const N: usize> IntoIterator for &'a mut ArrayN<T, N>
where T: Copy + Default,

Source§

fn into_iter(self) -> Self::IntoIter

Creates a mutable iterator over references to the active elements.

§Returns

An iterator yielding mutable references to the active elements.

Source§

type Item = &'a mut T

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'a, T>

Which kind of iterator are we turning this into?
Source§

impl<T, const N: usize> PartialEq for ArrayN<T, N>
where T: Copy + Default + PartialEq,

Source§

fn eq(&self, other: &Self) -> bool

Compares two ArrayN instances for equality.

Two arrays are equal if they have the same length and all their active elements are equal. The unused capacity is ignored.

§Parameters
  • other - The other ArrayN to compare with
§Returns

true if the arrays are equal, false otherwise.

1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T, const N: usize> Copy for ArrayN<T, N>
where T: Copy + Default + Copy,

Source§

impl<T, const N: usize> Eq for ArrayN<T, N>
where T: Copy + Default + Eq,

Auto Trait Implementations§

§

impl<T, const N: usize> Freeze for ArrayN<T, N>
where T: Freeze,

§

impl<T, const N: usize> RefUnwindSafe for ArrayN<T, N>
where T: RefUnwindSafe,

§

impl<T, const N: usize> Send for ArrayN<T, N>
where T: Send,

§

impl<T, const N: usize> Sync for ArrayN<T, N>
where T: Sync,

§

impl<T, const N: usize> Unpin for ArrayN<T, N>
where T: Unpin,

§

impl<T, const N: usize> UnwindSafe for ArrayN<T, N>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> Boilerplate for T
where T: Copy + Send + Sync + Debug + PartialEq + 'static,