NList

Struct NList 

Source
pub struct NList<T, L: PeanoInt> {
    pub node: Node<T, L>,
}
Expand description

Inline-allocated list of T which statically tracks its length using the L type parameter.

Fields§

§node: Node<T, L>

The first node in the list

Implementations§

Source§

impl<T, L: PeanoInt> NList<T, L>

Source

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

Returns a reference to the element at the index index.

Returns None if index >= self.len().

§Example
use nlist::{NList, nlist};

let list = nlist![3, 5, 8, 13];

assert_eq!(list.get(0), Some(&3));
assert_eq!(list.get(1), Some(&5));
assert_eq!(list.get(2), Some(&8));
assert_eq!(list.get(3), Some(&13));
assert_eq!(list.get(4), None);
Source

pub const fn get_mut(&mut self, index: usize) -> Option<&mut T>

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

Returns None if index >= self.len().

§Example
use nlist::{NList, nlist};

let mut list = nlist![3, 5, 8, 13];

assert_eq!(list.get_mut(0), Some(&mut 3));
assert_eq!(list.get_mut(1), Some(&mut 5));
assert_eq!(list.get_mut(2), Some(&mut 8));
assert_eq!(list.get_mut(3), Some(&mut 13));
assert_eq!(list.get_mut(4), None);
Source

pub const fn index<I>(&self) -> &T
where I: PeanoInt<IsLt<L> = Bool<true>>,

Returns a reference to the element at the I index.

§Example
use nlist::{NList, nlist, Peano};

let list = nlist![3, 5, 8, 13];

assert_eq!(list.index::<Peano!(0)>(), &3);
assert_eq!(list.index::<Peano!(1)>(), &5);
assert_eq!(list.index::<Peano!(2)>(), &8);
assert_eq!(list.index::<Peano!(3)>(), &13);

Source

pub const fn index_alt<I>( &self, i_lt_l_te: TypeEq<I::IsLt<L>, Bool<true>>, ) -> &T
where I: PeanoInt,

Alternative version of index which takes a proof of I < L as an argument.

§Example
use nlist::{NList, Peano, nlist, peano};
use nlist::peano::{PeanoInt, proofs};
use nlist::boolean::Bool;
use nlist::typewit::TypeEq;
 
let list = nlist![3, 5, 8, 13];
 
assert_eq!(at(&list, peano!(0)), (&3, &3));
assert_eq!(at(&list, peano!(1)), (&3, &5));
assert_eq!(at(&list, peano!(2)), (&5, &8));
assert_eq!(at(&list, peano!(3)), (&8, &13));
 
const fn at<T, L, At>(list: &NList<T, L>, _at: At) -> (&T, &T) 
where
    L: PeanoInt,
    At: PeanoInt<IsLt<L> = Bool<true>>,
{
    type Dist = Peano!(1);

    // passes a proof of `At < L` as argument, gets back a proof that `At - Dist < L`
    let sub_lt_l = proofs::compose_sub_lt::<At, Dist, L>(TypeEq::NEW);
     
    (
        list.index_alt::<peano::SubSat<At, Dist>>(sub_lt_l),
        list.index::<At>(),
    )
}
Source

pub const fn index_mut<I>(&mut self) -> &mut T
where I: PeanoInt<IsLt<L> = Bool<true>>,

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

§Example
use nlist::{NList, nlist, Peano};

let mut list = nlist![3, 5, 8, 13];

assert_eq!(list.index_mut::<Peano!(0)>(), &mut 3);
assert_eq!(list.index_mut::<Peano!(1)>(), &mut 5);
assert_eq!(list.index_mut::<Peano!(2)>(), &mut 8);
assert_eq!(list.index_mut::<Peano!(3)>(), &mut 13);

Source

pub const fn index_mut_alt<I>( &mut self, i_lt_l_te: TypeEq<I::IsLt<L>, Bool<true>>, ) -> &mut T
where I: PeanoInt,

Alternative version of index_mut which takes a proof of I < L as an argument.

Source§

impl<T, L: PeanoInt, L2: PeanoInt> NList<NList<T, L2>, L>

Source

pub const fn flatten(self) -> NList<T, Mul<L, L2>>

Flattens a nested list.

§Example
use nlist::{NList, Peano, nlist};

const FLATTENED: NList<u32, Peano!(6)> = 
    nlist![
        nlist![3, 5],
        nlist![8, 13],
        nlist![21, 34],
    ].flatten();

assert_eq!(FLATTENED, nlist![3, 5, 8, 13, 21, 34]);
Source§

impl<T, L: PeanoInt> NList<T, L>

Source

pub const fn split_at<At>(self) -> (NList<T, At>, NList<T, SubSat<L, At>>)
where At: PeanoInt<IsLe<L> = Bool<true>>,

Splits this list at the At index.

§Examples
§Basic usage
use nlist::{NList, Peano, nlist};

let list = nlist![3, 5, 8, 13, 21, 34];

let (before, after) = list.split_at::<Peano!(4)>();
assert_eq!(before, nlist![3, 5, 8, 13]);
assert_eq!(after, nlist![21, 34]);
Source

pub const fn split_at_alt<At>( self, at_le_l_proof: TypeEq<At::IsLe<L>, Bool<true>>, ) -> (NList<T, At>, NList<T, SubSat<L, At>>)
where At: PeanoInt,

Alternate version of split_at which takes a proof of At <= L instead of requiring it as a bound.

§Example
§Conditional splitting

This example demonstrates how split_at_alt can be used inside a generic function, only calling split_at_alt when the split index is in bounds.

use nlist::{NList, NListFn, Peano, PeanoInt, PeanoInt as PInt, nlist, peano};
 
use nlist::boolean::{Boolean, BoolWitG};
 
assert_eq!(insert_at_3(nlist![]), nlist![100, 103]);
assert_eq!(insert_at_3(nlist![3]), nlist![3, 100, 103]);
assert_eq!(insert_at_3(nlist![3, 5]), nlist![3, 5, 100, 103]);
assert_eq!(insert_at_3(nlist![3, 5, 8]), nlist![3, 5, 8, 100, 103]);
assert_eq!(insert_at_3(nlist![3, 5, 8, 13]), nlist![3, 5, 8, 100, 103, 13]);
assert_eq!(insert_at_3(nlist![3, 5, 8, 13, 21]), nlist![3, 5, 8, 100, 103, 13, 21]);
 
 
type Added = Peano!(2);
 
fn insert_at_3<L>(list: NList<u32, L>) -> NList<u32, peano::Add<L, Added>> 
where
    L: PeanoInt   
{
    let to_add = nlist![100, 103];
 
    type At = Peano!(3);
 
    let opt_te = const {
        match peano::IsLe::<At, L>::BOOL_WIT {
            BoolWitG::True(is_le_te) => 
                // `.unwrap_eq()` can only panic if this function has a bug
                Some((is_le_te, peano::eq().unwrap_eq())),
            BoolWitG::False(_) => None,
        }
    };
 
    // Because the compiler doesn't understand arithmetic properties of PeanoInt,
    // this function has to assert lengths in the above const block.
    //
    // `is_le_te`: proof that `At <= L`, which allows splitting the list at `At`.
    // 
    // `ret_len_te`: proof that the length of `before.concat(to_add).concat(after)`
    // (`At + Added + (L - At)`) is the same as the return type: (`L + Added`).
    if let Some((is_le_te, ret_len_te)) = opt_te {
        let (before, after) = list.split_at_alt::<At>(is_le_te);
         
        before.concat(to_add).concat(after).coerce_len(ret_len_te)
    } else {
        list.concat(to_add)
    }
}
Source§

impl<T, L: PeanoInt> NList<T, L>

Source

pub fn find<F>(self, f: F) -> Option<T>
where F: FnMut(&T) -> bool,

Finds the first element for which predicate(&element) returns true.

§Example
use nlist::nlist;

let list = nlist![3, 5, 8, 13];

assert_eq!(list.copy().find(|x| *x > 6), Some(8));
assert_eq!(list.copy().find(|x| *x == 10), None);
Source

pub fn find_map<F, R>(self, mapper: F) -> Option<R>
where F: FnMut(T) -> Option<R>,

Iterates the list elements, returning the first non-None return value of mapper(element).

§Alternatives

You can use the rec_find_map macro to emulate this method with a const function.

§Example
use nlist::nlist;

let list = nlist!["foo", "bar", "10", "baz", "20"];

assert_eq!(list.copy().find_map(|x| x.parse::<u8>().ok()), Some(10));
assert_eq!(list.copy().find_map(|x| x.parse::<bool>().ok()), None);
Source

pub fn position<F>(self, predicate: F) -> Option<usize>
where F: FnMut(T) -> bool,

Finds the first index for which predicate returns true.

§Example
use nlist::nlist;

let list = nlist!["hello", "hi", "goodbye", "world", "hi"];

assert_eq!(list.copy().position(|x| x == "hi"), Some(1));
assert_eq!(list.copy().position(|x| x.is_empty()), None);
Source

pub fn rfind<F>(self, f: F) -> Option<T>
where F: FnMut(&T) -> bool,

Iterates the list elements in reverse, returns the first element for which predicate(&element) returns true.

§Example
use nlist::nlist;

let list = nlist![3, 5, 8, 13, 2];

assert_eq!(list.copy().rfind(|x| *x > 6), Some(13));
assert_eq!(list.copy().rfind(|x| *x == 10), None);
Source

pub fn rfind_map<F, R>(self, mapper: F) -> Option<R>
where F: FnMut(T) -> Option<R>,

Iterates the list elements in reverse, returning the first non-None return value of mapper(element).

§Example
use nlist::nlist;

let list = nlist!["foo", "bar", "10", "baz", "20", "qux"];

assert_eq!(list.copy().rfind_map(|x| x.parse::<u8>().ok()), Some(20));
assert_eq!(list.copy().rfind_map(|x| x.parse::<bool>().ok()), None);
Source

pub fn rposition<F>(self, predicate: F) -> Option<usize>
where F: FnMut(T) -> bool,

Iterates the list elements in reverse, Finds the index of the first element for which predicate returns true.

§Example
use nlist::nlist;

let list = nlist!["hello", "hi", "goodbye", "world", "hi"];

assert_eq!(list.copy().rposition(|x| x == "hi"), Some(4));
assert_eq!(list.copy().rposition(|x| x.is_empty()), None);
Source

pub const fn reverse(self) -> NList<T, L>

Consumes and returns a reversed version of this list

§Example
use nlist::nlist;

let list = nlist![3, 5, 8, 13];

assert_eq!(list.reverse(), nlist![13, 8, 5, 3]);
Source

pub const fn concat<L2>(self, other: NList<T, L2>) -> NList<T, Add<L, L2>>
where L2: PeanoInt,

Concatenates this list with another one

§Example
use nlist::nlist;

let first = nlist![3, 5];
let second = nlist![8, 13, 21, 34];

assert_eq!(first.concat(second), nlist![3, 5, 8, 13, 21, 34]);
Source

pub const fn zip<U>(self, other: NList<U, L>) -> NList<(T, U), L>

Zips this list with another one of the same length

§Example
use nlist::nlist;

let first = nlist![3, 5, 8];
let second = nlist![13, 21, 34];

assert_eq!(first.zip(second), nlist![(3, 13), (5, 21), (8, 34)]);
Source

pub fn map<F, R>(self, f: F) -> NList<R, L>
where F: FnMut(T) -> R,

Maps the elements of this list.

§Alternatives

You can use the rec_map macro to emulate this method with a const function.

§Example
use nlist::nlist;

let list = nlist![3, 5, 8, 13];

assert_eq!(list.map(|x| x * 2), nlist![6, 10, 16, 26]);
Source

pub fn for_each<F>(self, f: F)
where F: FnMut(usize, T),

Loops over the elements in the list, along with their index.

§Alternatives

You can use the rec_for_each macro to emulate this method with a const function.

§Example
use nlist::nlist;

let list = nlist![3, 5, 8, 13];
let mut out = Vec::new();

list.for_each(|i, x| out.push((i, x)));

assert_eq!(out, vec![(0, 3), (1, 5), (2, 8), (3, 13)]);
Source

pub fn any<F>(self, predicate: F) -> bool
where F: FnMut(T) -> bool,

Returns whether predicate(elem) returns true for any element.

§Alternatives

You can use the rec_any macro to emulate this method with a const function.

§Example
use nlist::{NList, nlist};

let list = nlist![3, 5, 8, 13];

// calling `any` on an empty list always returns false
assert!(!NList::nil::<u8>().any(|_| false));

assert!(list.copy().any(|x| x % 2 == 0));
assert!(!list.copy().any(|x| x > 20));
Source

pub fn all<F>(self, predicate: F) -> bool
where F: FnMut(T) -> bool,

Returns whether predicate(&elem) returns true for all elements.

§Alternatives

You can use the rec_all macro to emulate this method with a const function.

§Example
use nlist::{NList, nlist};

let list = nlist![3, 5, 8, 13];

// calling `all` on an empty list always returns true
assert!(NList::nil::<u8>().all(|_| false));

assert!(list.copy().all(|x| x < 20));
assert!(!list.copy().all(|x| x % 2 == 0));
Source

pub fn fold<F, A>(self, initial_value: A, f: F) -> A
where F: FnMut(A, T) -> A,

Folds over this list.

§Alternatives

You can use the rec_fold macro to emulate this method with a const function.

§Example
use nlist::nlist;

let list = nlist![3, 5, 8, 13];

let res = list.fold(Vec::new(), |mut out, elem| {
    out.push(elem);
    out
});
 
assert_eq!(res, vec![3, 5, 8, 13]);
Source§

impl<T, L: PeanoInt> NList<T, PlusOne<L>>

Source

pub fn reduce<F>(self, f: F) -> T
where F: FnMut(T, T) -> T,

Equivalent to fold, where the head element is passed as the initial_value.

§Example
use nlist::nlist;

let list = nlist![3, 5, 8, 13];

assert_eq!(list.reduce(|l, r| l + r), 29);
Source§

impl NList<(), Zero>

Source

pub const fn nil<T>() -> NList<T, Zero>

Constructs an empty NList

§Example
use nlist::{NList, nlist};
 
let list = NList::nil::<u8>();
 
assert_eq!(list, nlist![]);
assert_eq!(list.into_array(), []);
 
Source§

impl<T, L: PeanoInt> NList<T, PlusOne<L>>

Source

pub const fn cons(val: T, next: NList<T, L>) -> Self

Constructs an NList with the head element, and the rest of the list.

§Example
use nlist::{NList, nlist};
 
let list_1 = NList::cons(3, NList::nil());
assert_eq!(list_1, nlist![3]);
assert_eq!(list_1.copy().into_array(), [3]);
 
let list_2 = NList::cons(5, list_1);
assert_eq!(list_2, nlist![5, 3]);
assert_eq!(list_2.copy().into_array(), [5, 3]);
 
let list_3 = NList::cons(8, list_2);
assert_eq!(list_3, nlist![8, 5, 3]);
assert_eq!(list_3.copy().into_array(), [8, 5, 3]);
Source§

impl<T, L: PeanoInt> NList<T, L>

Source

pub const fn repeat_copy(elem: T) -> Self
where T: Copy,

Constructs a list by repeating elem.

§Example
use nlist::{NList, nlist, Peano};

let nlist: NList<_, Peano!(4)> = NList::repeat_copy(3);

assert_eq!(nlist, nlist![3, 3, 3, 3]);
assert_eq!(nlist, nlist![3; 4]);
Source

pub fn from_fn<F>(f: F) -> Self
where F: FnMut(usize) -> T,

Constructs a list by calling f with the index of each element.

§Alternatives

You can use the rec_from_fn macro to emulate this function with a const function.

§Example
use nlist::{NList, nlist, Peano};

let list: NList<_, Peano!(4)> = NList::from_fn(|i| i.pow(2));

assert_eq!(list, nlist![0, 1, 4, 9]);
Source

pub const fn from_array<const N: usize>(array: [T; N]) -> Self
where Usize<N>: IntoPeano<Peano = L>, L: IntoUsize<Usize = Usize<N>>,

Constructs an NList from an array

§Example
use nlist::{NList, Peano, nlist};

const LIST: NList<u8, Peano!(5)> = NList::from_array([3, 5, 8, 13, 21]);

assert_eq!(LIST, nlist![3, 5, 8, 13, 21]);
Source§

impl<T, L> NList<T, L>
where L: PeanoInt,

Source

pub fn total_eq<L2>(&self, rhs: &NList<T, L2>) -> bool
where T: Eq, L2: PeanoInt,

Total equality comparison between NLists of potentially different lengths.

§Example
use nlist::{NList, nlist};
 
assert!(nlist![3, 5].total_eq(&nlist![3, 5]));
 
assert!(!nlist![3, 5].total_eq(&nlist![3]));
assert!(!nlist![3, 5].total_eq(&nlist![3, 0]));
assert!(!nlist![3, 5].total_eq(&nlist![3, 5, 8]));
Source§

impl<T, L> NList<T, L>
where L: PeanoInt,

Source

pub fn cmp<L2>(&self, rhs: &NList<T, L2>) -> Ordering
where T: Ord, L2: PeanoInt,

Inherent version of Ord::cmp, for comparing NLists of different lengths.

§Example
use nlist::{NList, nlist};
use core::cmp::Ordering;
 
// shorter-argument
assert_eq!(nlist![3, 5].cmp(&nlist![1]), Ordering::Greater);
assert_eq!(nlist![3, 5].cmp(&nlist![3]), Ordering::Greater);
assert_eq!(nlist![3, 5].cmp(&nlist![8]), Ordering::Less);
 
// same-length argument
assert_eq!(nlist![3, 5].cmp(&nlist![3, 1]), Ordering::Greater);
assert_eq!(nlist![3, 5].cmp(&nlist![3, 5]), Ordering::Equal);
assert_eq!(nlist![3, 5].cmp(&nlist![3, 8]), Ordering::Less);

// longer-argument
assert_eq!(nlist![3, 5].cmp(&nlist![3, 4, 0]), Ordering::Greater);
assert_eq!(nlist![3, 5].cmp(&nlist![3, 5, 0]), Ordering::Less);
assert_eq!(nlist![3, 5].cmp(&nlist![3, 6, 0]), Ordering::Less);
Source§

impl<T, L: PeanoInt> NList<T, L>

Source

pub const fn into_node(self) -> Node<T, L>

Gets the first Node of this NList by value.

Source§

impl<T, L: PeanoInt> NList<T, PlusOne<L>>

Source

pub const fn head(&self) -> &T

Returns a reference to the first element of the list

§Example
use nlist::nlist;

let list_a = nlist![3];
assert_eq!(list_a.head(), &3);

let list_b = nlist![5, 3];
assert_eq!(list_b.head(), &5);

let list_c = nlist![8, 5, 3];
assert_eq!(list_c.head(), &8);
Source

pub const fn head_mut(&mut self) -> &mut T

Returns a mutable reference ot the first element of the list

§Example
use nlist::nlist;

let mut list_a = nlist![3];
assert_eq!(list_a.head_mut(), &mut 3);

let mut list_b = nlist![5, 3];
assert_eq!(list_b.head_mut(), &mut 5);

let mut list_c = nlist![8, 5, 3];
assert_eq!(list_c.head_mut(), &mut 8);
Source

pub fn into_head(self) -> T

Returns the first element of the list by value

§Example
use nlist::nlist;

let list_a = nlist![3];
assert_eq!(list_a.into_head(), 3);

let list_b = nlist![5, 3];
assert_eq!(list_b.into_head(), 5);

let list_c = nlist![8, 5, 3];
assert_eq!(list_c.into_head(), 8);
Source

pub const fn into_head_const(self) -> T
where T: Copy,

Const alternative of into_head, returns the first element of the list by value.

§Example
use nlist::{NList, Peano, nlist};

const FIRST_A: u32 = nlist![3].into_head_const();
assert_eq!(FIRST_A, 3);

const FIRST_B: u32 = nlist![5, 3].into_head_const();
assert_eq!(FIRST_B, 5);

const FIRST_C: u32 = nlist![8, 5, 3].into_head_const();
assert_eq!(FIRST_C, 8);
Source

pub const fn tail(&self) -> &NList<T, L>

Returns a reference to the remainder of the list

§Example
use nlist::nlist;

let list_a = nlist![3];
assert_eq!(list_a.tail(), &nlist![]);

let list_b = nlist![5, 3];
assert_eq!(list_b.tail(), &nlist![3]);

let list_c = nlist![8, 5, 3];
assert_eq!(list_c.tail(), &nlist![5, 3]);
Source

pub const fn tail_mut(&mut self) -> &mut NList<T, L>

Returns a mutable reference to the remainder of the list

§Example
use nlist::nlist;

let mut list_a = nlist![3];
assert_eq!(list_a.tail_mut(), &mut nlist![]);

let mut list_b = nlist![5, 3];
assert_eq!(list_b.tail_mut(), &mut nlist![3]);

let mut list_c = nlist![8, 5, 3];
assert_eq!(list_c.tail_mut(), &mut nlist![5, 3]);
Source

pub fn into_tail(self) -> NList<T, L>

Returns the remainder of the list by value

§Example
use nlist::nlist;

let list_a = nlist![3];
assert_eq!(list_a.into_tail(), nlist![]);

let list_b = nlist![5, 3];
assert_eq!(list_b.into_tail(), nlist![3]);

let list_c = nlist![8, 5, 3];
assert_eq!(list_c.into_tail(), nlist![5, 3]);
Source

pub const fn into_tail_const(self) -> NList<T, L>
where T: Copy,

Const alternative of into_tail, returns the remainder of the list by value.

§Example
use nlist::{NList, Peano, nlist};

const LIST_A: NList<u32, Peano!(0)> = nlist![3].into_tail_const();
assert_eq!(LIST_A, nlist![]);

const LIST_B: NList<u32, Peano!(1)> = nlist![5, 3].into_tail_const();
assert_eq!(LIST_B, nlist![3]);

const LIST_C: NList<u32, Peano!(2)> = nlist![8, 5, 3].into_tail_const();
assert_eq!(LIST_C, nlist![5, 3]);
Source

pub const fn split_head(&self) -> (&T, &NList<T, L>)

Returns a pair of references to the first element and the remainder of the list

§Example
use nlist::nlist;

let list_a = nlist![3];
assert_eq!(list_a.split_head(), (&3, &nlist![]));

let list_b = nlist![5, 3];
assert_eq!(list_b.split_head(), (&5, &nlist![3]));

let list_c = nlist![8, 5, 3];
assert_eq!(list_c.split_head(), (&8, &nlist![5, 3]));
Source

pub const fn split_head_mut(&mut self) -> (&mut T, &mut NList<T, L>)

Returns a pair of mutable references to the first element and the remainder of the list

§Example
use nlist::nlist;

let mut list_a = nlist![3];
assert_eq!(list_a.split_head_mut(), (&mut 3, &mut nlist![]));

let mut list_b = nlist![5, 3];
assert_eq!(list_b.split_head_mut(), (&mut 5, &mut nlist![3]));

let mut list_c = nlist![8, 5, 3];
assert_eq!(list_c.split_head_mut(), (&mut 8, &mut nlist![5, 3]));
Source

pub const fn into_split_head(self) -> (T, NList<T, L>)

Returns a by-value pair of first element and the remainder of the list

§Example
use nlist::nlist;

let list_a = nlist![3];
assert_eq!(list_a.into_split_head(), (3, nlist![]));

let list_b = nlist![5, 3];
assert_eq!(list_b.into_split_head(), (5, nlist![3]));

let list_c = nlist![8, 5, 3];
assert_eq!(list_c.into_split_head(), (8, nlist![5, 3]));
Source

pub const fn split_head_poly<'a, P>( this: P, ) -> (HktApply<'a, P::Hkt, T>, HktApply<'a, P::Hkt, NList<T, L>>)
where P: Receiver<'a, NList<T, PlusOne<L>>>, L: PeanoInt,

Generic version of split_head that can take NList by value/reference/mutable reference, and returns the corresponding pair of (head, tail).

P and the return type can only be these:

  • If P == NList<T, PlusOne<L>>: the return type is (T, NList<T, L>)
  • If P == &'a NList<T, PlusOne<L>>: the return type is (&'a T, &'a NList<T, L>)
  • If P == &'a mut NList<T, PlusOne<L>>: the return type is (&'a mut T, &'a mut NList<T, L>)
Source§

impl<T, L: PeanoInt> NList<T, L>

Source

pub const fn len(&self) -> usize

Returns the length of the list

§Example
use nlist::{NList, nlist};

assert_eq!(NList::nil::<u32>().len(), 0);

assert_eq!(nlist![5].len(), 1);

assert_eq!(nlist![8, 5].len(), 2);
Source

pub const fn is_empty(&self) -> bool

Returns whether the list is empty

§Example
use nlist::{NList, nlist};

assert!(NList::nil::<u32>().is_empty());

assert!(!nlist![5].is_empty());

assert!(!nlist![8, 5].is_empty());
Source§

impl<T, L: PeanoInt> NList<T, L>

Source

pub fn into_vec(self) -> Vec<T>

Converts this list into a Vec

§Example
use nlist::nlist;

let list = nlist![3, 5, 8];

assert_eq!(list.into_vec(), vec![3, 5, 8]);
Source

pub const fn into_array<const N: usize>(self) -> [T; N]
where L: IntoUsize<Usize = Usize<N>>,

Converts this list into an array

§Example
use nlist::{NList, nlist, Peano};


let list: NList<&str, Peano!(4)> = nlist!["hello", "world", "foo", "bar"];

let array: [&str; 4] = list.into_array();

assert_eq!(array, ["hello", "world", "foo", "bar"])
Source

pub const fn copy(&self) -> Self
where T: Copy,

Makes a bytewise Copy of the list, element by element.

§Example
use nlist::{NList, nlist, Peano};

let list: NList<u8, Peano!(3)> = nlist![3, 5, 8];
let copy: NList<u8, Peano!(3)> = list.copy();

assert_eq!(list, nlist![3, 5, 8]);
assert_eq!(copy, nlist![3, 5, 8]);
Source

pub const fn assert_copy_drop(self)
where T: Copy,

Helper method for dropping NList in a const context where T: Copy.

Source

pub const fn assert_copy(self) -> ManuallyDrop<Self>
where T: Copy,

Helper method for conditionally consuming NList of Copy elements in a const context.

Source

pub const fn each_ref(&self) -> NList<&T, L>

Gets a list of references to each element of this list.

§Example
use nlist::{NList, nlist, Peano};

let list: NList<u8, Peano!(3)> = nlist![3, 5, 8];

let refs: NList<&u8, Peano!(3)> = list.each_ref();
assert_eq!(refs, nlist![&3, &5, &8]);
Source

pub const fn each_mut(&mut self) -> NList<&mut T, L>

Gets a list of mutable references to each element of this list.

§Example
use nlist::{NList, nlist, Peano};

let mut list: NList<u8, Peano!(3)> = nlist![3, 5, 8];

let muts: NList<&mut u8, Peano!(3)> = list.each_mut();
assert_eq!(muts, nlist![&3, &5, &8]);
Source§

impl<T, L: PeanoInt> NList<T, L>

Source

pub const fn len_proof(&self) -> PeanoWit<L>

Alternate way to get PeanoWit for L

Source

pub const fn coerce_len<L2: PeanoInt>( self, len_te: TypeEq<L, L2>, ) -> NList<T, L2>

Given a proof that L == L2, coerces NList<T, L> to NList<T, L2>

§Example

Emulating specialization over list length, the function behaves differently for length 3 and 5 than with other lengths.

use nlist::{NList, Peano, PeanoInt, nlist, peano};
use nlist::typewit::TypeCmp;
 
pub const fn make_list<L: PeanoInt>() -> NList<usize, L> {
    if let TypeCmp::Eq(len3_te) = peano::eq::<Peano!(3), L>() {
        // len3_te is a proof that `Peano!(3) == L`
        // which allows us to coerce `NList<T, Peano!(3)>` to `NList<T, L>`
        nlist![3, 5, 8].coerce_len(len3_te)
    } else if let TypeCmp::Eq(len5_te) = peano::eq::<Peano!(5), L>() {
        // len5_te is a proof that `Peano!(5) == L`
        nlist![3, 5, 8, 13, 21].coerce_len(len5_te)
    } else {
        NList::repeat_copy(L::USIZE)
    }
}
 
assert_eq!(make_list::<Peano!(0)>(), nlist![]);
assert_eq!(make_list::<Peano!(1)>(), nlist![1]);
assert_eq!(make_list::<Peano!(2)>(), nlist![2, 2]);
assert_eq!(make_list::<Peano!(3)>(), nlist![3, 5, 8]);
assert_eq!(make_list::<Peano!(4)>(), nlist![4, 4, 4, 4]);
assert_eq!(make_list::<Peano!(5)>(), nlist![3, 5, 8, 13, 21]);
assert_eq!(make_list::<Peano!(6)>(), nlist![6, 6, 6, 6, 6, 6]);
 
 
Source

pub const fn as_coerce_len<L2: PeanoInt>( &self, len_te: TypeEq<L, L2>, ) -> &NList<T, L2>

Given a proof that L == L2, coerces &NList<T, L> to &NList<T, L2>

Source

pub const fn as_mut_coerce_len<L2>( &mut self, len_te: TypeEq<L, L2>, ) -> &mut NList<T, L2>
where L2: PeanoInt,

Given a proof that L == L2, coerces &mut NList<T, L> to &mut NList<T, L2>

Source

pub const fn coerce_len_poly<'a, P, L2>( this: P, len_te: TypeEq<L, L2>, ) -> HktApply<'a, P::Hkt, NList<T, L2>>
where P: Receiver<'a, NList<T, L>>, L2: PeanoInt,

Generic version of coerce_len that can take NList by value/reference/mutable reference, and returns the corresponding value/reference/mutable of an NList with that length.

P and the return type can only be these:

  • If P == NList<T, L>: the return type is NList<T, L2>
  • If P == &'a NList<T, L>: the return type is &'a NList<T, L2>
  • If P == &'a mut NList<T, L>: the return type is &'a mut NList<T, L2>

Trait Implementations§

Source§

impl<T, L> Clone for NList<T, L>
where T: Clone, L: PeanoInt,

Copy can’t be implemented for NList, you can however use the copy method.

Source§

fn clone(&self) -> Self

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, L> Debug for NList<T, L>
where T: Debug, L: PeanoInt,

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<T, L> Default for NList<T, L>
where T: Default, L: PeanoInt,

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T, const N: usize> From<[T; N]> for NList<T, FromUsize<N>>
where Usize<N>: IntoPeano,

Source§

fn from(list: [T; N]) -> NList<T, FromUsize<N>>

Converts to this type from the input type.
Source§

impl<T, L, const N: usize> From<NList<T, L>> for [T; N]
where L: IntoUsize<Usize = Usize<N>>,

Source§

fn from(list: NList<T, L>) -> [T; N]

Converts to this type from the input type.
Source§

impl<T, L> Hash for NList<T, L>
where T: Hash, L: PeanoInt,

Source§

fn hash<H: Hasher>(&self, hasher: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<T, L> Ord for NList<T, L>
where T: Ord, L: PeanoInt,

For calling cmp on NLists of different lengths, there is an inherent cmp method.

Source§

fn cmp(&self, rhs: &NList<T, L>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl<T, U, L, L2> PartialEq<NList<U, L2>> for NList<T, L>
where T: PartialEq<U>, L: PeanoInt, L2: PeanoInt,

Source§

fn eq(&self, rhs: &NList<U, L2>) -> bool

Tests for self and other values to be equal, and is used by ==.
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, U, L, L2> PartialOrd<NList<U, L2>> for NList<T, L>
where T: PartialOrd<U>, L: PeanoInt, L2: PeanoInt,

Source§

fn partial_cmp(&self, rhs: &NList<U, L2>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

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

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

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

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

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

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

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

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T, L> Eq for NList<T, L>
where T: Eq, L: PeanoInt,

Auto Trait Implementations§

§

impl<T, L> Freeze for NList<T, L>
where <<L as PeanoInt>::IsZero as Boolean>::IfTrue<Nil<T, L>, Cons<T, L>>: Freeze,

§

impl<T, L> RefUnwindSafe for NList<T, L>
where <<L as PeanoInt>::IsZero as Boolean>::IfTrue<Nil<T, L>, Cons<T, L>>: RefUnwindSafe,

§

impl<T, L> Send for NList<T, L>
where <<L as PeanoInt>::IsZero as Boolean>::IfTrue<Nil<T, L>, Cons<T, L>>: Send,

§

impl<T, L> Sync for NList<T, L>
where <<L as PeanoInt>::IsZero as Boolean>::IfTrue<Nil<T, L>, Cons<T, L>>: Sync,

§

impl<T, L> Unpin for NList<T, L>
where <<L as PeanoInt>::IsZero as Boolean>::IfTrue<Nil<T, L>, Cons<T, L>>: Unpin,

§

impl<T, L> UnwindSafe for NList<T, L>
where <<L as PeanoInt>::IsZero as Boolean>::IfTrue<Nil<T, L>, Cons<T, L>>: 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, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

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

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
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<'a, T> Receiver<'a, T> for T
where T: 'a,

Source§

type Hkt = ValueHkt<'a>

Marker type for abstractly representing values/references/mutable references
Source§

const RECEIVER_WIT: ReceiverWit<'a, Self, T> = _

Witness for whether Self is a T,&'a T, or &'a mut T.
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, 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.