Skip to content

Instantly share code, notes, and snippets.

@j5ik2o
Created August 14, 2020 08:32
Show Gist options
  • Save j5ik2o/2ca641da698103a9cd97cd4bec2f82a5 to your computer and use it in GitHub Desktop.
Save j5ik2o/2ca641da698103a9cd97cd4bec2f82a5 to your computer and use it in GitHub Desktop.
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