#![no_std]
pub trait InitWith<T> {
fn init_with<F>(init: F) -> Self
where F: FnMut() -> T,
Self: Sized;
}
macro_rules! array_init {
{$n:expr, $init:ident, $($stack:ident,)+} => {
impl<T> InitWith<T> for [T; $n] {
fn init_with<F>(mut $init: F) -> Self
where F: FnMut() -> T
{
[$init(), $($stack()),+]
}
}
array_init!{($n - 1), $($stack,)+}
};
{$n:expr, $init:ident,} => {
impl<T> InitWith<T> for [T; $n] {
fn init_with<F>(mut $init: F) -> Self
where F: FnMut() -> T
{
[$init()]
}
}
array_init!{($n - 1)}
};
{$n:expr} => {
impl<T> InitWith<T> for [T; $n] {
fn init_with<F>(_init: F) -> Self
where F: FnMut() -> T
{
[]
}
}
};
}
array_init!{32, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init, init,}
#[cfg(test)]
mod tests {
use super::InitWith;
#[test]
fn expected() {
let val = <[i32; 3]>::init_with(|| 4);
assert_eq!(val, [4, 4, 4]);
}
}