Created
August 14, 2020 08:32
-
-
Save j5ik2o/2ca641da698103a9cd97cd4bec2f82a5 to your computer and use it in GitHub Desktop.
This file contains 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 characters
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); | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment