dynamic_list/list/
traits.rs

1use crate::{list::Node, Empty, Index, Length, NotEmpty};
2use std::ops::Sub;
3use typenum::{Bit, NonZero, Sub1, UInt, Unsigned, B1, U0};
4
5/// # Safety
6/// You should not need to ever use it directly.
7///
8/// If you call this method manually this could lead to a double free error.
9pub unsafe trait DropValue {
10    /// # Safety
11    /// This method recursively drops all the values from the heap. Therfore multiple calls to this
12    /// method could lead to errors.
13    unsafe fn drop_values(&mut self) {}
14}
15unsafe impl DropValue for Empty {}
16unsafe impl<V, N: DropValue> DropValue for Node<V, N> {
17    unsafe fn drop_values(&mut self) {
18        drop(Box::from_raw(self.value.cast_mut()));
19        self.next.drop_values()
20    }
21}
22
23pub trait ListAppend {
24    type Output<T>: DropValue;
25
26    fn append<T>(self, value: *const T) -> Self::Output<T>;
27}
28impl<V> ListAppend for Node<V> {
29    type Output<T> = Node<V, Node<T>>;
30
31    #[inline]
32    fn append<T>(self, value: *const T) -> Self::Output<T> {
33        Node {
34            value: self.value,
35            next: Node::new(value),
36        }
37    }
38}
39impl<V, N: ListAppend + DropValue> ListAppend for Node<V, N> {
40    type Output<T> = Node<V, N::Output<T>>;
41
42    #[inline]
43    fn append<T>(self, value: *const T) -> Self::Output<T> {
44        Node {
45            value: self.value,
46            next: self.next.append(value),
47        }
48    }
49}
50
51// INDEX:
52// Case: Fount element
53impl<V, N> Index<U0> for Node<V, N> {
54    type Output<'a> = &'a V where Self: 'a;
55
56    fn index(&self) -> Self::Output<'_> {
57        self.value()
58    }
59}
60// Case: There still index remaining but we arrived to last element
61impl<V, U: Unsigned, B: Bit> Index<UInt<U, B>> for Node<V>
62where
63    UInt<U, B>: NonZero,
64{
65    type Output<'a> = Empty where Self: 'a;
66
67    fn index(&self) -> Self::Output<'_> {
68        Empty
69    }
70}
71// Case: Generic search recursive search for element when not in last node
72impl<V, U, B, N> Index<UInt<U, B>> for Node<V, N>
73where
74    U: Unsigned,
75    B: Bit,
76    N: NotEmpty + Index<Sub1<UInt<U, B>>>,
77    UInt<U, B>: NonZero + Sub<B1>,
78{
79    type Output<'a> = N::Output<'a> where Self: 'a;
80
81    fn index(&self) -> Self::Output<'_> {
82        self.next.index()
83    }
84}
85
86impl<V, N: Length> Length for Node<V, N> {
87    const SIZE: usize = 1 + N::SIZE;
88}
89
90impl<V> NotEmpty for Node<V> {}
91impl<V, N: NotEmpty> NotEmpty for Node<V, N> {}