array_iterator 1.8.0

Owning iterators based on arrays.
Documentation
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

fn collect<T>(a: impl crate::Array<T>) -> Vec<T> {
	crate::ArrayIterator::new(a).collect()
}

#[test]
fn it_works() {
	assert_eq!(&collect([1, 2, 3]), &[1, 2, 3]);
	assert_eq!(&collect(
		[
			"foo".to_string(),
			"bar".to_string()]),
		&[
			"foo",
			"bar"]);
}

#[test]
fn no_leaks() {
	let i = std::rc::Rc::new(1);
	assert_eq!(&collect([i.clone(), i.clone()]), &[i.clone(), i.clone()]);
	assert_eq!(std::rc::Rc::strong_count(&i), 1);
}

#[test]
fn no_leaks_partial() {
	let i = std::rc::Rc::new(2);
	let mut iter = crate::ArrayIterator::new([
		i.clone(),
		i.clone(),
		i.clone(),
		i.clone(),
		i.clone(),
		i.clone(),
	]);
	
	assert_eq!(std::rc::Rc::strong_count(&i), 7);
	assert_eq!(iter.next(), Some(i.clone()));
	assert_eq!(std::rc::Rc::strong_count(&i), 6);
	assert_eq!(iter.next(), Some(i.clone()));

	std::mem::drop(iter);

	assert_eq!(std::rc::Rc::strong_count(&i), 1);
}

#[test]
fn interative_destruction() {
	let i = std::rc::Rc::new(2);
	let mut iter = crate::ArrayIterator::new([
		i.clone(),
		i.clone(),
		i.clone(),
		i.clone(),
		i.clone(),
		i.clone(),
	]);
	
	assert_eq!(std::rc::Rc::strong_count(&i), 7);
	assert_eq!(iter.next(), Some(i.clone()));
	assert_eq!(std::rc::Rc::strong_count(&i), 6);
	assert_eq!(iter.next(), Some(i.clone()));
	assert_eq!(std::rc::Rc::strong_count(&i), 5);
	assert_eq!(iter.next(), Some(i.clone()));
	assert_eq!(std::rc::Rc::strong_count(&i), 4);
	assert_eq!(iter.next(), Some(i.clone()));
	assert_eq!(std::rc::Rc::strong_count(&i), 3);
	assert_eq!(iter.next(), Some(i.clone()));
	assert_eq!(std::rc::Rc::strong_count(&i), 2);
	assert_eq!(iter.next(), Some(i.clone()));
	assert_eq!(std::rc::Rc::strong_count(&i), 1);

	assert_eq!(iter.next(), None);
	assert_eq!(iter.next(), None);
	assert_eq!(iter.next(), None);
	assert_eq!(iter.next(), None);
}

#[test]
fn len() {
	assert_eq!(crate::ArrayIterator::<(), [(); 0]>::new([]).size_hint(), (0, Some(0)));
	assert_eq!(crate::ArrayIterator::new([1]).size_hint(), (1, Some(1)));
	assert_eq!(crate::ArrayIterator::new([1, 2, 3, 4]).size_hint(), (4, Some(4)));
}

#[test]
fn size_hint_iter() {
	let mut iter = crate::ArrayIterator::new([1, 2, 3, 4]);
	
	assert_eq!(iter.size_hint(), (4, Some(4)));
	assert_eq!(iter.next(), Some(1));
	assert_eq!(iter.size_hint(), (3, Some(3)));
	assert_eq!(iter.next(), Some(2));
	assert_eq!(iter.size_hint(), (2, Some(2)));
	assert_eq!(iter.next(), Some(3));
	assert_eq!(iter.size_hint(), (1, Some(1)));
	assert_eq!(iter.next(), Some(4));
	assert_eq!(iter.size_hint(), (0, Some(0)));
	assert_eq!(iter.next(), None);
	assert_eq!(iter.size_hint(), (0, Some(0)));
}

#[test]
fn test_clone() {
	let mut iter1 = crate::ArrayIterator::new([
		Box::new(1),
		Box::new(2),
		Box::new(3),
		Box::new(4),
		Box::new(5),
	]);

	assert_eq!(iter1.next(), Some(Box::new(1)));
	assert_eq!(iter1.next(), Some(Box::new(2)));

	let mut iter2 = iter1.clone();
	assert_eq!(iter1.next(), Some(Box::new(3)));
	assert_eq!(iter2.next(), Some(Box::new(3)));
	assert_eq!(iter1.next(), Some(Box::new(4)));
	assert_eq!(iter2.next(), Some(Box::new(4)));
}

#[test]
fn test_double_ended() {
	let mut iter1 = crate::ArrayIterator::new([
		Box::new(1),
		Box::new(2),
		Box::new(3),
		Box::new(4),
		Box::new(5),
	]);

	assert_eq!(iter1.next(), Some(Box::new(1)));
	assert_eq!(iter1.next_back(), Some(Box::new(5)));
	assert_eq!(iter1.next(), Some(Box::new(2)));
	assert_eq!(iter1.next_back(), Some(Box::new(4)));
	assert_eq!(iter1.next_back(), Some(Box::new(3)));
	assert_eq!(iter1.next(), None);
	assert_eq!(iter1.next_back(), None);
	assert_eq!(iter1.next(), None);
	assert_eq!(iter1.next_back(), None);
}