Skip to content

Instantly share code, notes, and snippets.

@j5ik2o
Created August 14, 2020 08:32
Show Gist options
  • Select an option

  • Save j5ik2o/2ca641da698103a9cd97cd4bec2f82a5 to your computer and use it in GitHub Desktop.

Select an option

Save j5ik2o/2ca641da698103a9cd97cd4bec2f82a5 to your computer and use it in GitHub Desktop.

Revisions

  1. j5ik2o created this gist Aug 14, 2020.
    140 changes: 140 additions & 0 deletions ToyVec.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,140 @@
    pub struct ToyVec<T> {
    elements: Box<[T]>,
    len: usize,
    }

    pub struct Iter<'vec, T> {
    // 参照型のフィールドにはライフタイム指定子
    elements: &'vec Box<[T]>,
    len: usize,
    pos: usize,
    }

    impl<'vec, T> Iterator for Iter<'vec, T> {
    type Item = &'vec T;

    fn next(&mut self) -> Option<Self::Item> {
    if self.pos >= self.len {
    None
    } else {
    let res = Some(&self.elements[self.pos]);
    self.pos += 1;
    res
    }
    }
    }

    impl<'vec, T: Default> IntoIterator for &'vec ToyVec<T> {
    type Item = &'vec T;
    type IntoIter = Iter<'vec, T>;

    fn into_iter(self) -> Self::IntoIter {
    self.iter()
    }
    }


    impl<T: Default> ToyVec<T> {
    pub fn iter<'vec>(&'vec self) -> Iter<'vec, T> {
    Iter {
    elements: &self.elements,
    len: self.len,
    pos: 0
    }
    }
    pub fn new() -> Self {
    Self::with_capacity(0)
    }

    pub fn with_capacity(capacity: usize) -> Self {
    Self {
    elements: Self::allocate_in_heap(capacity),
    len: 0,
    }
    }

    fn allocate_in_heap(size: usize) -> Box<[T]> {
    std::iter::repeat_with(Default::default)
    .take(size)
    .collect::<Vec<_>>()
    .into_boxed_slice()
    }

    pub fn len(&self) -> usize {
    self.len
    }

    pub fn capacity(&self) -> usize {
    self.elements.len()
    }

    pub fn push(&mut self, element: T) {
    if self.len == self.capacity() {
    self.grow();
    }
    self.elements[self.len] = element;
    self.len += 1;
    }

    pub fn get(&self, index: usize) -> Option<&T> {
    if index < self.len {
    Some(&self.elements[index])
    } else {
    None
    }
    }

    pub fn get_or<'a, 'b>(&'a self, index: usize, default: &'b T) -> &'a T
    where
    'b: 'a
    {
    self.get(index).unwrap_or(default)
    }

    pub fn pop(&mut self) -> Option<T> {
    if self.len == 0 {
    None
    } else {
    self.len -= 1;
    let elm = std::mem::replace(&mut self.elements[self.len], Default::default());
    Some(elm)
    }
    }

    // pub fn take(&mut self) -> Option<T> {
    //
    // }
    //
    // pub fn replace(&mut self, value: T)-> Option<T> {
    //
    // }

    fn grow(&mut self) {
    if self.capacity() == 0 {
    self.elements = Self::allocate_in_heap(1);
    } else {
    let new_elements = Self::allocate_in_heap(self.capacity() * 2);
    // 新しい要素をself.elementsに置き換える。この時点で2倍の要素数になる
    let old_elements = std::mem::replace(&mut self.elements, new_elements);
    // into_iterでムーブする
    for (i, elm) in old_elements.into_vec().into_iter().enumerate() {
    self.elements[i] = elm;
    }
    }
    }
    }

    fn main() {
    let mut v = ToyVec::new();
    v.push("Java Finch".to_string());
    v.push("Budgerigar".to_string());
    let mut iter = v.iter();
    iter.next();
    iter.next();
    let a = iter.next();
    println!("{:?}", a);
    v.push("Budgerigar2".to_string());
    // for msg in &v {
    // println!("{:?}", msg);
    // }
    }