::std::

Primitive array

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<T, #uint N> inv [T; N]
fn transpose(self) -> [inv T; N]

Transposes an inv array into an array of inv values.

This transformation preserves the low level signals behind the value, but presents them in a new format that is easier to destructure.

Examples

let a = port();
let inv_array: inv [bool; 2] = a.1;
let array_of_invs: [inv bool; 2] = inv_array.transpose();
set array_of_invs[0] = true;
set array_of_invs[1] = false;
assert a.0 == [true, 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]];

Trait Implementations

impl<T: Default, #uint N> Default for [T; N]
fn hacky_default(self) -> Self
impl<T: Data, #uint N> Data for [T; N]
impl<T: Copy, #uint N> Copy for [T; N]
impl<#uint N, T: PartialEq> PartialEq for [T; N]
fn eq(self, rhs: Self) -> bool
fn ne(self, rhs: Self) -> bool