Primitive array
Expand
Fixed size arrays, written [T; N]
Implementations
impl<T, #uint N> [T; N]
fn all(self, f: impl Fn(T) -> bool) -> bool
Returns whether the provided predicate is true for all array elements.
Note that an empty array has no elements, so the result will always be true regardless of
the predicate.
Examples
assert [].any(fn |x| x == 0u8) == false;
assert [7u8, 10u8, 13u8].all(fn |x| x > 5) == true;
assert [7u8, 10u8, 13u8].all(fn |x| x > 12) == false;
assert [7u8, 10u8, 13u8].all(fn |x| x > 20) == false;fn any(self, f: impl Fn(T) -> bool) -> bool
Returns whether the provided predicate is true for at least one array element.
Note that an empty array has no elements, so the result will always be false regardless of
the predicate.
Examples
assert [].any(fn |x| x == 0u8) == false;
assert [7u8, 10u8, 13u8].any(fn |x| x > 5) == true;
assert [7u8, 10u8, 13u8].any(fn |x| x > 12) == true;
assert [7u8, 10u8, 13u8].any(fn |x| x > 20) == false;fn chunks<#uint ChunkSize>(self) -> [[T; ChunkSize]; { N / ChunkSize }]
where
N == N / ChunkSize * ChunkSize else "The size of the input array must be a multiple of the chunk size",
Splits the array into equally-sized chunks.
The chunk size is provided at compile time as a type parameter. This means that it cannot depend on a runtime value. However, it also means that it can be inferred.
Examples
let array = [1u8, 2u8, 3u8, 4u8, 5u8, 6u8];
let two_item_chunks = array.chunks::<2>();
assert two_item_chunks[0] == [1u8, 2u8];
assert two_item_chunks[1] == [3u8, 4u8];
assert two_item_chunks[2] == [5u8, 6u8];
let three_item_chunks = array.chunks::<3>();
assert three_item_chunks[0] == [1u8, 2u8, 3u8];
assert three_item_chunks[1] == [4u8, 5u8, 6u8];pub fn concat<#uint M>(self, other: [T; M]) -> [T; { M + N }]
Creates an array by concatenating the elements of two existing ones.
The result is an array whose lower elements correspond to the first input array, and its
higher elements correspond to the second one. In other words, given two arrays
[l0, l1, ...] and [r0, r1, ...], the result is [l0, l1, ..., r0, r1, ...].
Examples
let empty: [uint<8>; 0] = [];
assert [].concat([]) == empty;
assert [1u8].concat([2u8, 3u8]) == [1u8, 2u8, 3u8];fn reversed(self) -> Self
Reverses the elements of an array.
Examples
let empty: [uint<8>; 0] = [];
assert [].reversed() == empty;
assert [1u8, 2u8, 3u8].reversed() == [3u8, 2u8, 1u8];fn fold<B>(self, init: B, f: impl Fn(B, T) -> B) -> B
Folds an array into a single value using a function to assimilate elements.
Given an input array [a0, a1, a2, ...] and a function f, the output would be
f(init f(a0, f(a1, f(a2, ...)))).
As opposed to reduce, this function requires an initial value for the accumulator. This
allows the accumulator and the array elements to have a different type, and the method to
operate on empty arrays.
See also [T; N]::fold.
Examples
assert [1u8, 2u8, 3u8, 4u8].fold(0, fn |acc, val| acc +. val) == 10u8;
assert [1u8, 2u8, 3u8, 4u8].fold(true, fn |acc, val| acc && val != 4) == false;fn interleave(self, other: Self) -> [T; { 2 * N }]
Interleaves the elements of two arrays.
An array containing elements from both input arrays is built, with even positions occupied
by elements from the first array and odd positions occupied by those from the second array.
In other words, given two arrays [l0, l1, l2, ...] and [r0, r1, r2, ...], the output
would be [l0, r0, l1, r1, l2, r2, ...].
Examples
let l = [10u8, 11u8, 12u8];
let r = [20u8, 21u8, 22u8];
assert l.interleave(r) == [10u8, 20u8, 11u8, 21u8, 12u8, 22u8];
let empty: [uint<8>; 0] = [];
assert [].interleave([]) == empty;fn map<O>(self, f: impl Fn(T) -> O) -> [O; N]
Builds an array by applying a function to each element of the input array.
Examples
let array = [1u8, 2u8, 3u8, 4u8];
assert array.map(fn |x| x < 4) == [true, true, true, false];pub fn push_back(self, item: T) -> [T; { N + 1 }]
Creates a new array with item added at the end of the original array
Examples
let a = [];
let b = a.push_back(1u8);
let c = b.push_back(2u8);
let d = c.push_back(3u8);
assert b == [1u8];
assert c == [1u8, 2u8];
assert d == [1u8, 2u8, 3u8];pub fn push_front(self, item: T) -> [T; { N + 1 }]
Adds an element at the start of the array.
Examples
let a = [];
let b = a.push_front(1u8);
let c = b.push_front(2u8);
let d = c.push_front(3u8);
assert b == [1u8];
assert c == [2u8, 1u8];
assert d == [3u8, 2u8, 1u8];fn sliding_window<#uint M>(self) -> [[T; M]; { N - M + 1 }]
where
M <= N else "Window size is larger than array size",
Generates an array with the intermediate values of an sliding window over the input array.
The window size is provided at compile time as a type parameter. This means that it cannot depend on a runtime value. However, it also means that it can be inferred.
Examples
let array = [1u8, 2u8, 3u8, 4u8, 5u8];
let two_item_windows = array.sliding_window::<2>();
assert two_item_windows[0] == [1u8, 2u8];
assert two_item_windows[1] == [2u8, 3u8];
assert two_item_windows[2] == [3u8, 4u8];
assert two_item_windows[3] == [4u8, 5u8];
let three_item_windows = array.sliding_window::<3>();
assert three_item_windows[0] == [1u8, 2u8, 3u8];
assert three_item_windows[1] == [2u8, 3u8, 4u8];
assert three_item_windows[2] == [3u8, 4u8, 5u8];fn split_at<#uint K>(self) -> ([T; K], [T; { N - K }])
where
K <= N else "Split point is outside array bounds",
Splits an array into two parts.
The split point is provided at compile time as a type parameter. This means that it cannot depend on a runtime value. However, it also means that it can be inferred.
Examples
let empty: [uint<8>; 0] = [];
assert empty.split_at::<0>() == ([], []);
assert [1u8, 2u8, 3u8].split_at::<0>() == ([], [1u8, 2u8, 3u8]);
assert [1u8, 2u8, 3u8].split_at::<1>() == ([1u8], [2u8, 3u8]);
assert [1u8, 2u8, 3u8].split_at::<2>() == ([1u8, 2u8], [3u8]);
assert [1u8, 2u8, 3u8].split_at::<3>() == ([1u8, 2u8, 3u8], []);
assert [1u8, 2u8, 3u8].split_at() == ([1u8, 2u8], [3u8]);
assert [1u8, 2u8, 3u8].split_at() == ([1u8, 2u8, 3u8], []);fn zip<O>(self, other: [O; N]) -> [(T, O); N]
Pairs elements of two arrays together into a single array of tuples.
An array is produced with the same length as both inputs provided. For each array position,
the elements from both arrays are paired as a tuple and stored in the result array. In other
words, given two arrays [l0, l1, l2, ...] and [r0, r1, r2, ...], the output would be
[(l0, r0), (l1, r1), (l2, r2), ...].
Examples
let l = [10u8, 11u8, 12u8];
let r = [20u8, 21u8, 22u8];
assert l.zip(r) == [(10u8, 20u8), (11u8, 21u8), (12u8, 22u8)];
let empty: [(uint<8>, uint<8>); 0] = [];
assert [].zip([]) == empty;fn len(self) -> uint<{ }>
Returns the length of the array.
Since arrays are static, this simply returns a constant value.
let empty: [uint<8>; 0] = [];
assert empty.len() == 0;
assert [true].len() == 1;
assert [true, false].len() == 2;impl<T, #uint N> [T; N]
where
N > 0,
pub fn first(self) -> T
Retrieves the first element of the array.
Examples
assert [true].first() == true;
assert [true, false].first() == true;pub fn last(self) -> T
Retrieves the last element of the array.
Examples
assert [true].last() == true;
assert [true, false].last() == false;fn reduce(self, f: impl Fn(T, T) -> T) -> T
Reduces an array to a single value using a function to assimilate elements.
Given an input array [a0, a1, a2, ...] and a function f, the output would be
f(a0, f(a1, f(a2, ...))).
As opposed to fold, this function operates without an initial value for the accumulator by
taking the first element of the array instead. This requires the accumulator and the array
elements to have the same type, and the array to not be empty.
See also [T; N]::fold.
Examples
assert [1u8, 2u8, 3u8, 4u8].reduce(fn |a, b| a +. b) == 10u8;pub fn shift_back(self, item: T) -> Self
Shifts an element into the end of the array, dropping the first one.
Examples
let a = [1u8, 2u8, 3u8];
let b = a.shift_back(4u8);
let c = b.shift_back(5u8);
let d = c.shift_back(6u8);
assert b == [2u8, 3u8, 4u8];
assert c == [3u8, 4u8, 5u8];
assert d == [4u8, 5u8, 6u8];pub fn shift_front(self, item: T) -> Self
Shifts an element into the start of the array, dropping the last one.
Examples
let a = [3u8, 2u8, 1u8];
let b = a.shift_front(4u8);
let c = b.shift_front(5u8);
let d = c.shift_front(6u8);
assert b == [4u8, 3u8, 2u8];
assert c == [5u8, 4u8, 3u8];
assert d == [6u8, 5u8, 4u8];impl<S, T, #uint N> [(S, T); N]
fn unzip(self) -> ([S; N], [T; N])
Splits an array of pairs into a pair of arrays.
Both arrays produced have the same length as the input array. The first element of the left
array is the first element of the first tuple, the second element the first element of the
second tuple, and so on. In other words, the array [(l0, r0), (l1, r1), (l2, r2), ...] is
split into [l0, l1, l2, ...] and [r0, r1, r2, ...].
Examples
let (l, r) = [(10u8, 20u8), (11u8, 21u8), (12u8, 22u8)].unzip();
assert l == [10u8, 11u8, 12u8];
assert r == [20u8, 21u8, 22u8];
let empty: [(uint<8>, uint<8>); 0] = [];
assert empty.unzip() == ([], []);impl<T, #uint N> [inv T; N]
fn transpose(self) -> inv [T; N]
Transposes an array of inv values into an inv array.
This transformation preserves the low level signals behind the value, but presents them in
a new format that is easier to set.
Examples
let x = port;
let y = port;
let array_of_invs: [inv bool; 2] = [x.1, y.1];
let inv_array: inv [bool; 2] = array_of_invs.transpose();
set inv_array = [true, false];
assert x.0 == true;
assert y.0 == false;impl<T, #uint N, #uint M> [[T; M]; N]
fn flatten(self) -> [T; { N * M }]
Turns an array of arrays into a single array containing the same elements in the same order.
This operation only flattens one level of nesting, requiring multiple calls to flatten a deeply-nested array value.
Examples
let empty: [[uint<8>; 0]; 0] = [];
assert empty.flatten() == [];
assert [[1u8], [2u8], [3u8], [4u8]].flatten() == [1u8, 2u8, 3u8, 4u8];
assert [[[1u8], [2u8]], [[3u8], [4u8]]].flatten() == [[1u8], [2u8], [3u8], [4u8]];impl<#uint N> [bool; N]
where
N > 0,
fn reduce_and(self) -> bool
Reduces an array of bool into a single value by performing AND on all elements.
Examples
assert [true, true, true].reduce_and() == true;
assert [false, false, false].reduce_and() == false;
assert [false, true, true].reduce_and() == false;This operation is equivalent to the Verilog AND reduction operator &.
fn reduce_or(self) -> bool
Reduces an array of bool into a single value by performing OR on all elements.
Examples
assert [true, true, true].reduce_or() == true;
assert [false, false, false].reduce_or() == false;
assert [false, true, true].reduce_or() == true;This operation is equivalent to the Verilog OR reduction operator |.
fn reduce_xor(self) -> bool
Reduces an array of bool into a single value by performing XOR on all elements.
Examples
assert [true, true, true].reduce_xor() == true ^^ true ^^ true;
assert [false, false, false].reduce_xor() == false ^^ false ^^ false;
assert [false, true, true].reduce_xor() == false ^^ true ^^ true;This operation is equivalent to the Verilog OR reduction operator ^.
impl<#uint N> [bool; N]
pub fn as_int(self) -> int<N>
Casts a an array of bool to a signed integer by reinterpreting its bits.
Bits are laid out from LSB to MSB, so the first element of the array corresponds to the LSB of the input number and the last element corresponds to its MSB.
Note that bits in the literal binary representation of the number are written right-to-left, while items in the literal representation of the array are written left-to-right.
Examples
assert [true, true, true, false].as_int() == 0b0111i4;
assert [true, true, true, true].as_int() == -0b0001i4;pub fn as_uint(self) -> uint<N>
Casts an array of bool to an unsigned integer by reinterpreting its bits.
Bits are laid out from LSB to MSB, so the first element of the array corresponds to the LSB of the input number and the last element corresponds to its MSB.
Note that bits in the literal binary representation of the number are written right-to-left, while items in the literal representation of the array are written left-to-right.
Examples
assert [true, false, true, true].as_uint() == 0b1101u4;pub fn to_int(self) -> int<N>
Casts a an array of bool to a signed integer by reinterpreting its bits.
Bits are laid out from LSB to MSB, so the first element of the array corresponds to the LSB of the input number and the last element corresponds to its MSB.
Note that bits in the literal binary representation of the number are written right-to-left, while items in the literal representation of the array are written left-to-right.
Examples
assert [true, true, true, false].to_int() == 0b0111i4;
assert [true, true, true, true].to_int() == -0b0001i4;pub fn to_uint(self) -> uint<N>
Casts an array of bool to an unsigned integer by reinterpreting its bits.
Bits are laid out from LSB to MSB, so the first element of the array corresponds to the LSB of the input number and the last element corresponds to its MSB.
Note that bits in the literal binary representation of the number are written right-to-left, while items in the literal representation of the array are written left-to-right.
Examples
assert empty.to_uint() == 0u0;
assert [true, false, true, true].to_uint() == 0b1101u4;