Created
August 14, 2020 08:32
-
-
Save j5ik2o/2ca641da698103a9cd97cd4bec2f82a5 to your computer and use it in GitHub Desktop.
Revisions
-
j5ik2o created this gist
Aug 14, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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); // } }