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

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

    pub fn append(&mut self, element: T) {
        if self.begin_index > 0 {
            //println!("append the data");
            self.begin_index -= 1;
            if self.m_size < self.min_size {
                self.m_size += 1;
            }
        } else {
            //println!("move the data");
            for i in 0..self.min_size {
                self.data[L - i - 1] = self.data[self.min_size - 1 - i];
            }
            self.begin_index = L - self.min_size;
        }
        self.data[self.begin_index] = element;
    }

    pub fn as_slice(&self) -> &[T] {
        &self.data[self.begin_index..self.begin_index + self.m_size]
    }
    pub fn range(&self, m_range: std::ops::Range<usize>) -> &[T] {
        let tmp_range: std::ops::Range<usize> = URange {
            start: m_range.start + self.begin_index,
            end: m_range.end + self.begin_index,
        };
        &self.data[tmp_range]
    }
}
impl<T: Copy + Default, const L: usize> Copy for TList<T, L> {}

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

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

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