#![no_std]
#![warn(missing_docs)]
const fn min_of_sizes(x: usize, y: usize) -> usize {
if x < y {
x
} else {
y
}
}
#[cfg(feature = "initialize")]
pub fn initialize_from<T, F, const OUTPUT_SIZE: usize>(f: F) -> [T; OUTPUT_SIZE]
where
T: Copy + Default,
F: Fn(usize) -> T,
{
let mut buffer = [T::default(); OUTPUT_SIZE];
for i in 0..OUTPUT_SIZE {
buffer[i] = f(i);
}
buffer
}
#[cfg(feature = "initialize")]
pub fn initialize_till<T, F, const OUTPUT_SIZE: usize>(
f: F,
till: T,
fill: T,
) -> ([T; OUTPUT_SIZE], usize)
where
T: Copy + PartialEq,
F: Fn(usize) -> T,
{
let mut buffer = [fill; OUTPUT_SIZE];
for i in 0..OUTPUT_SIZE {
let value = f(i);
if value == till {
return (buffer, i);
}
buffer[i] = value;
}
(buffer, OUTPUT_SIZE)
}
#[cfg(feature = "initialize")]
pub fn initialize_from_option<T, F, const OUTPUT_SIZE: usize>(
f: F,
fill: T,
) -> ([T; OUTPUT_SIZE], usize)
where
T: Copy,
F: Fn(usize) -> Option<T>,
{
let mut buffer = [fill; OUTPUT_SIZE];
for i in 0..OUTPUT_SIZE {
match f(i) {
None => return (buffer, i),
Some(value) => buffer[i] = value,
}
}
(buffer, OUTPUT_SIZE)
}
#[cfg(feature = "initialize")]
pub fn initialize_from_result<T, F, E, const OUTPUT_SIZE: usize>(
f: F,
fill: T,
) -> ([T; OUTPUT_SIZE], usize)
where
T: Copy,
F: Fn(usize) -> Result<T, E>,
{
let mut buffer = [fill; OUTPUT_SIZE];
for i in 0..OUTPUT_SIZE {
match f(i) {
Err(_) => return (buffer, i),
Ok(value) => buffer[i] = value,
}
}
(buffer, OUTPUT_SIZE)
}
#[cfg(feature = "drift")]
pub fn drift_to_end<T, const SIZE: usize>(
array: [T; SIZE],
till: usize,
margin: usize,
fill: T,
) -> [T; SIZE]
where
T: Copy,
{
let mut buffer = [fill; SIZE];
for i in 0..till {
buffer[SIZE - margin - till + i] = array[i];
}
buffer
}
#[cfg(feature = "drift")]
pub fn drift_to_begin<T, const SIZE: usize>(
array: [T; SIZE],
from: usize,
margin: usize,
fill: T,
) -> [T; SIZE]
where
T: Copy,
{
let mut buffer = [fill; SIZE];
for i in from..SIZE {
if margin + i - from >= SIZE {
break;
}
buffer[margin + i - from] = array[i];
}
buffer
}
#[cfg(feature = "resize")]
pub fn array_resize<T, const INPUT_SIZE: usize, const OUTPUT_SIZE: usize>(
array: [T; INPUT_SIZE],
fill: T,
) -> [T; OUTPUT_SIZE]
where
T: Copy,
{
let mut buffer = [fill; OUTPUT_SIZE];
for i in 0..min_of_sizes(INPUT_SIZE, OUTPUT_SIZE) {
buffer[i] = array[i];
}
buffer
}
#[cfg(feature = "superimpose")]
pub fn superimpose<T, const MAIN_SIZE: usize, const SUB_SIZE: usize>(
mut main_array: [T; MAIN_SIZE],
sub_array: [T; SUB_SIZE],
starting_from: usize,
) -> [T; MAIN_SIZE]
where
T: Copy,
{
for i in starting_from..min_of_sizes(starting_from + SUB_SIZE, MAIN_SIZE) {
main_array[i] = sub_array[i - starting_from];
}
main_array
}
#[cfg(feature = "join")]
pub fn join<T, const LEFT_SIZE: usize, const RIGHT_SIZE: usize, const RESULT_SIZE: usize>(
left: [T; LEFT_SIZE],
right: [T; RIGHT_SIZE],
fill: T,
) -> [T; RESULT_SIZE]
where
T: Copy,
{
let mut buffer = [fill; RESULT_SIZE];
for i in 0..min_of_sizes(LEFT_SIZE, RESULT_SIZE) {
buffer[i] = left[i];
}
for i in LEFT_SIZE..min_of_sizes(LEFT_SIZE + RIGHT_SIZE, RESULT_SIZE) {
if i - LEFT_SIZE >= RIGHT_SIZE {
break;
}
buffer[i] = right[i - LEFT_SIZE];
}
buffer
}
#[cfg(feature = "splice")]
pub fn splice<T, const ORIGINAL_SIZE: usize, const LEFT_SIZE: usize, const RIGHT_SIZE: usize>(
original: [T; ORIGINAL_SIZE],
fill: T,
) -> ([T; LEFT_SIZE], [T; RIGHT_SIZE])
where
T: Copy,
{
let mut left = [fill; LEFT_SIZE];
let mut right = [fill; RIGHT_SIZE];
for i in 0..min_of_sizes(LEFT_SIZE, ORIGINAL_SIZE) {
left[i] = original[i];
}
for i in LEFT_SIZE..min_of_sizes(LEFT_SIZE + RIGHT_SIZE, ORIGINAL_SIZE) {
if i - LEFT_SIZE >= RIGHT_SIZE {
break;
}
right[i - LEFT_SIZE] = original[i];
}
(left, right)
}
#[cfg(feature = "slice")]
pub fn sized_slice<T, const ORIGINAL_SIZE: usize, const SLICE_SIZE: usize>(
original: [T; ORIGINAL_SIZE],
from: usize,
till: usize,
fill: T,
) -> [T; SLICE_SIZE]
where
T: Copy,
{
let mut buffer = [fill; SLICE_SIZE];
for i in from..min_of_sizes(till, ORIGINAL_SIZE) {
if i - from >= SLICE_SIZE {
break;
}
buffer[i - from] = original[i];
}
buffer
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg(feature = "initialize")]
fn init_from() {
assert_eq!(initialize_from(|index| index), []);
assert_eq!(initialize_from(|index| index), [0, 1, 2, 3, 4]);
assert_eq!(initialize_from(|index| 2 * index), [0, 2, 4, 6, 8]);
assert_eq!(initialize_from(|_| 1), [1; 20]);
assert_eq!(initialize_from(|index| 5 + index), [5, 6, 7, 8, 9, 10]);
}
#[test]
#[cfg(feature = "initialize")]
fn init_till() {
assert_eq!(
initialize_till(|index| index, 4, 42),
([0, 1, 2, 3, 42, 42], 4)
);
assert_eq!(initialize_till(|index| index, 5, 42), ([0, 1, 2, 3, 4], 5));
assert_eq!(
initialize_till(|index| 2 * index, 8, 42),
([0, 2, 4, 6, 42], 4)
);
assert_eq!(initialize_till(|_| 1, 3, 42), ([1; 20], 20));
assert_eq!(
initialize_till(|index| 5 + index, 20, 42),
([5, 6, 7, 8, 9, 10], 6)
);
}
#[test]
#[cfg(feature = "initialize")]
fn init_from_option() {
assert_eq!(
initialize_from_option(|index| if index == 10 { None } else { Some(index) }, 42),
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 10)
);
assert_eq!(
initialize_from_option(|index| if index == 10 { None } else { Some(index) }, 42),
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 42, 42, 42, 42], 10)
);
assert_eq!(
initialize_from_option(|index| if index > 4 { None } else { Some(index) }, 42),
([0, 1, 2, 3, 4, 42, 42, 42, 42], 5)
);
}
#[test]
#[cfg(feature = "initialize")]
fn init_from_result() {
assert_eq!(
initialize_from_result(|index| if index == 10 { Err(()) } else { Ok(index) }, 42),
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 10)
);
assert_eq!(
initialize_from_result(|index| if index == 10 { Err(()) } else { Ok(index) }, 42),
([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 42, 42, 42, 42], 10)
);
assert_eq!(
initialize_from_result(|index| if index > 4 { Err(()) } else { Ok(index) }, 42),
([0, 1, 2, 3, 4, 42, 42, 42, 42], 5)
);
}
#[test]
#[cfg(feature = "drift")]
fn drift_st() {
assert_eq!(
drift_to_begin(initialize_from(|index| index), 10, 2, 42),
superimpose([42; 13], [10, 11, 12], 2)
);
assert_eq!(
drift_to_begin(initialize_from(|index| index), 10, 0, 42),
superimpose([42; 13], [10, 11, 12], 0)
);
assert_eq!(
drift_to_begin(initialize_from(|index| index), 10, 1, 42),
superimpose([42; 13], [10, 11, 12], 1)
);
}
#[test]
#[cfg(feature = "drift")]
fn drift_nd() {
assert_eq!(
drift_to_end(initialize_from(|index| index), 3, 2, 42),
[42, 42, 0, 1, 2, 42, 42]
);
assert_eq!(
drift_to_end(initialize_from(|index| index), 3, 0, 42),
[42, 42, 0, 1, 2]
);
assert_eq!(
drift_to_end(initialize_from(|index| index), 3, 1, 42),
[0, 1, 2, 42]
);
}
#[test]
#[cfg(feature = "resize")]
fn arr_resize() {
let array: [usize; 10] = initialize_from(|index| index);
assert_eq!(array_resize(array, 42), [0, 1, 2, 3, 4, 5, 6, 7]);
assert_eq!(
array_resize(array, 42),
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 42, 42]
);
}
#[test]
#[cfg(feature = "superimpose")]
fn super_impose() {
let array: [usize; 10] = initialize_from(|index| index);
assert_eq!(
superimpose(array, [0, 1, 2, 3], 4),
[0, 1, 2, 3, 0, 1, 2, 3, 8, 9]
);
assert_eq!(
superimpose(array, [0, 1, 2, 3], 8),
[0, 1, 2, 3, 4, 5, 6, 7, 0, 1]
);
assert_eq!(superimpose(array, [0, 1, 2, 3], 10), array);
assert_eq!(superimpose(array, [0, 1, 2, 3], 0), array);
}
#[test]
#[cfg(feature = "join")]
fn join_arrays() {
assert_eq!(
join([4, 5, 6, 7], [0, 1, 2, 3], 0),
[4, 5, 6, 7, 0, 1, 2, 3]
);
assert_eq!(
join([4, 5, 6, 7, 8], [0, 1, 2, 3], 0),
[4, 5, 6, 7, 8, 0, 1, 2, 3]
);
assert_eq!(
join([4, 5, 6, 7], [0, 1, 2, 3], 0),
[4, 5, 6, 7, 0, 1, 2, 3, 0]
);
}
#[test]
#[cfg(feature = "splice")]
fn splice_arrays() {
assert_eq!(
splice([4, 5, 6, 7, 0, 1, 2, 3], 0),
([4, 5, 6, 7], [0, 1, 2, 3])
);
assert_eq!(
splice([4, 5, 6, 7, 8, 0, 1, 2, 3], 0),
([4, 5, 6, 7, 8], [0, 1, 2, 3])
);
assert_eq!(
splice([4, 5, 6, 7, 0, 1, 2, 3, 0], 0),
([4, 5, 6, 7], [0, 1, 2, 3])
);
assert_eq!(
splice([4, 5, 6, 7, 0, 1, 2, 3, 0], 0),
([4, 5, 6, 7], [0, 1, 2, 3, 0, 0, 0, 0])
);
}
#[test]
#[cfg(feature = "slice")]
fn sized_slices() {
assert_eq!(
sized_slice([4, 5, 6, 7, 0, 1, 2, 3], 4, 8, 0),
([0, 1, 2, 3])
);
assert_eq!(
sized_slice([4, 5, 6, 7, 0, 1, 2, 3], 4, 10, 0),
([0, 1, 2, 3, 0, 0])
);
assert_eq!(
sized_slice([4, 5, 6, 7, 0, 1, 2, 3], 0, 10, 0),
([4, 5, 6, 7, 0, 1])
);
}
}