Documentation
type URange = std::ops::Range<usize>;
use super::List;

impl<T: Copy + Default, const L: usize> List<T, L> {
    pub fn default() -> Self {
        Self {
            m_size: 0,
            min_size: L / 3,
            end_index: 0,
            data: [T::default(); L],
        }
    }
    pub fn new(min_size: usize) -> Self {
        Self {
            m_size: 0,
            min_size,
            end_index: 0,
            data: [T::default(); L],
        }
    }
    pub fn size(&self) -> usize {
        return self.m_size;
    }
    pub fn at(&self, index: usize) -> &T {
        return &self.data[self.end_index + index - self.m_size];
    }

    pub fn append(&mut self, element: T) {
        if self.end_index < L {
            self.data[self.end_index] = element;
            self.end_index += 1;
        } else {
            for i in 1..self.min_size {
                self.data[i - 1] = self.data[L + i - self.min_size];
            }
            self.data[self.min_size - 1] = element;
            self.end_index = self.min_size;
        }
        if self.m_size < self.min_size {
            self.m_size += 1;
        }
    }

    pub fn as_slice(&self) -> &[T] {
        &self.data[self.end_index - self.m_size..self.end_index]
    }
    pub fn range(&self, m_range: std::ops::Range<usize>) -> &[T] {
        let tmp_range: std::ops::Range<usize> = URange {
            start: m_range.start + self.end_index - self.m_size,
            end: m_range.end + self.end_index - self.m_size,
        };
        &self.data[tmp_range]
    }
}

impl<T: Copy + Default, const L: usize> Copy for List<T, L> {}

impl<T: Clone + Default + Copy, const L: usize> Clone for List<T, L> {
    fn clone(&self) -> List<T, L> {
        List {
            m_size: self.m_size,
            min_size: self.min_size,
            end_index: self.end_index,
            data: self.data.clone(),
        }
    }
}

impl<T: Copy + Default, const L: usize> std::ops::Index<usize> for List<T, L> {
    type Output = T;
    fn index(&self, index: usize) -> &Self::Output {
        let start = self.end_index + index - self.m_size;
        return &self.data[start];
    }
}

impl<T: Copy + Default, const L: usize> std::ops::IndexMut<usize> for List<T, L> {
    //type Output = T;
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        let start = self.end_index + index - self.m_size;
        &mut self.data[start]
    }
}