shared_from_iter: Add more tests.
This commit is contained in:
parent
6b8417b55c
commit
8bbf1abd0e
@ -2,6 +2,8 @@ use std::any::Any;
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::PartialEq;
|
use std::cmp::PartialEq;
|
||||||
|
use std::iter::TrustedLen;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn uninhabited() {
|
fn uninhabited() {
|
||||||
@ -85,3 +87,120 @@ fn eq() {
|
|||||||
assert!(!(x != x));
|
assert!(!(x != x));
|
||||||
assert_eq!(*x.0.borrow(), 0);
|
assert_eq!(*x.0.borrow(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Rc<T> = Arc<T>;
|
||||||
|
|
||||||
|
const SHARED_ITER_MAX: u16 = 100;
|
||||||
|
|
||||||
|
fn assert_trusted_len<I: TrustedLen>(_: &I) {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_from_iter_normal() {
|
||||||
|
// Exercise the base implementation for non-`TrustedLen` iterators.
|
||||||
|
{
|
||||||
|
// `Filter` is never `TrustedLen` since we don't
|
||||||
|
// know statically how many elements will be kept:
|
||||||
|
let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new);
|
||||||
|
|
||||||
|
// Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
|
||||||
|
let vec = iter.clone().collect::<Vec<_>>();
|
||||||
|
let rc = iter.collect::<Rc<[_]>>();
|
||||||
|
assert_eq!(&*vec, &*rc);
|
||||||
|
|
||||||
|
// Clone a bit and let these get dropped.
|
||||||
|
{
|
||||||
|
let _rc_2 = rc.clone();
|
||||||
|
let _rc_3 = rc.clone();
|
||||||
|
let _rc_4 = Rc::downgrade(&_rc_3);
|
||||||
|
}
|
||||||
|
} // Drop what hasn't been here.
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_from_iter_trustedlen_normal() {
|
||||||
|
// Exercise the `TrustedLen` implementation under normal circumstances
|
||||||
|
// where `size_hint()` matches `(_, Some(exact_len))`.
|
||||||
|
{
|
||||||
|
let iter = (0..SHARED_ITER_MAX).map(Box::new);
|
||||||
|
assert_trusted_len(&iter);
|
||||||
|
|
||||||
|
// Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
|
||||||
|
let vec = iter.clone().collect::<Vec<_>>();
|
||||||
|
let rc = iter.collect::<Rc<[_]>>();
|
||||||
|
assert_eq!(&*vec, &*rc);
|
||||||
|
assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc));
|
||||||
|
|
||||||
|
// Clone a bit and let these get dropped.
|
||||||
|
{
|
||||||
|
let _rc_2 = rc.clone();
|
||||||
|
let _rc_3 = rc.clone();
|
||||||
|
let _rc_4 = Rc::downgrade(&_rc_3);
|
||||||
|
}
|
||||||
|
} // Drop what hasn't been here.
|
||||||
|
|
||||||
|
// Try a ZST to make sure it is handled well.
|
||||||
|
{
|
||||||
|
let iter = (0..SHARED_ITER_MAX).map(|_| ());
|
||||||
|
let vec = iter.clone().collect::<Vec<_>>();
|
||||||
|
let rc = iter.collect::<Rc<[_]>>();
|
||||||
|
assert_eq!(&*vec, &*rc);
|
||||||
|
assert_eq!(0, mem::size_of_val(&*rc));
|
||||||
|
{
|
||||||
|
let _rc_2 = rc.clone();
|
||||||
|
let _rc_3 = rc.clone();
|
||||||
|
let _rc_4 = Rc::downgrade(&_rc_3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic = "I've almost got 99 problems."]
|
||||||
|
fn shared_from_iter_trustedlen_panic() {
|
||||||
|
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
||||||
|
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
|
||||||
|
let iter = (0..SHARED_ITER_MAX)
|
||||||
|
.map(|val| {
|
||||||
|
match val {
|
||||||
|
98 => panic!("I've almost got 99 problems."),
|
||||||
|
_ => Box::new(val),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assert_trusted_len(&iter);
|
||||||
|
let _ = iter.collect::<Rc<[_]>>();
|
||||||
|
|
||||||
|
panic!("I am unreachable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_from_iter_trustedlen_no_fuse() {
|
||||||
|
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
||||||
|
// `(_, Some(exact_len))` but where the iterator does not behave in a fused manner.
|
||||||
|
struct Iter(std::vec::IntoIter<Option<Box<u8>>>);
|
||||||
|
|
||||||
|
unsafe impl TrustedLen for Iter {}
|
||||||
|
|
||||||
|
impl Iterator for Iter {
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
(2, Some(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Item = Box<u8>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.0.next().flatten()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let vec = vec![
|
||||||
|
Some(Box::new(42)),
|
||||||
|
Some(Box::new(24)),
|
||||||
|
None,
|
||||||
|
Some(Box::new(12)),
|
||||||
|
];
|
||||||
|
let iter = Iter(vec.into_iter());
|
||||||
|
assert_trusted_len(&iter);
|
||||||
|
assert_eq!(
|
||||||
|
&[Box::new(42), Box::new(24)],
|
||||||
|
&*iter.collect::<Rc<[_]>>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
#![feature(box_syntax)]
|
#![feature(box_syntax)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(exact_size_is_empty)]
|
#![feature(exact_size_is_empty)]
|
||||||
|
#![feature(option_flattening)]
|
||||||
#![feature(pattern)]
|
#![feature(pattern)]
|
||||||
#![feature(repeat_generic_slice)]
|
#![feature(repeat_generic_slice)]
|
||||||
|
#![feature(trusted_len)]
|
||||||
#![feature(try_reserve)]
|
#![feature(try_reserve)]
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
#![deny(rust_2018_idioms)]
|
#![deny(rust_2018_idioms)]
|
||||||
|
@ -2,6 +2,8 @@ use std::any::Any;
|
|||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::PartialEq;
|
use std::cmp::PartialEq;
|
||||||
|
use std::mem;
|
||||||
|
use std::iter::TrustedLen;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn uninhabited() {
|
fn uninhabited() {
|
||||||
@ -85,3 +87,118 @@ fn eq() {
|
|||||||
assert!(!(x != x));
|
assert!(!(x != x));
|
||||||
assert_eq!(*x.0.borrow(), 0);
|
assert_eq!(*x.0.borrow(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SHARED_ITER_MAX: u16 = 100;
|
||||||
|
|
||||||
|
fn assert_trusted_len<I: TrustedLen>(_: &I) {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_from_iter_normal() {
|
||||||
|
// Exercise the base implementation for non-`TrustedLen` iterators.
|
||||||
|
{
|
||||||
|
// `Filter` is never `TrustedLen` since we don't
|
||||||
|
// know statically how many elements will be kept:
|
||||||
|
let iter = (0..SHARED_ITER_MAX).filter(|x| x % 2 == 0).map(Box::new);
|
||||||
|
|
||||||
|
// Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
|
||||||
|
let vec = iter.clone().collect::<Vec<_>>();
|
||||||
|
let rc = iter.collect::<Rc<[_]>>();
|
||||||
|
assert_eq!(&*vec, &*rc);
|
||||||
|
|
||||||
|
// Clone a bit and let these get dropped.
|
||||||
|
{
|
||||||
|
let _rc_2 = rc.clone();
|
||||||
|
let _rc_3 = rc.clone();
|
||||||
|
let _rc_4 = Rc::downgrade(&_rc_3);
|
||||||
|
}
|
||||||
|
} // Drop what hasn't been here.
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_from_iter_trustedlen_normal() {
|
||||||
|
// Exercise the `TrustedLen` implementation under normal circumstances
|
||||||
|
// where `size_hint()` matches `(_, Some(exact_len))`.
|
||||||
|
{
|
||||||
|
let iter = (0..SHARED_ITER_MAX).map(Box::new);
|
||||||
|
assert_trusted_len(&iter);
|
||||||
|
|
||||||
|
// Collecting into a `Vec<T>` or `Rc<[T]>` should make no difference:
|
||||||
|
let vec = iter.clone().collect::<Vec<_>>();
|
||||||
|
let rc = iter.collect::<Rc<[_]>>();
|
||||||
|
assert_eq!(&*vec, &*rc);
|
||||||
|
assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc));
|
||||||
|
|
||||||
|
// Clone a bit and let these get dropped.
|
||||||
|
{
|
||||||
|
let _rc_2 = rc.clone();
|
||||||
|
let _rc_3 = rc.clone();
|
||||||
|
let _rc_4 = Rc::downgrade(&_rc_3);
|
||||||
|
}
|
||||||
|
} // Drop what hasn't been here.
|
||||||
|
|
||||||
|
// Try a ZST to make sure it is handled well.
|
||||||
|
{
|
||||||
|
let iter = (0..SHARED_ITER_MAX).map(|_| ());
|
||||||
|
let vec = iter.clone().collect::<Vec<_>>();
|
||||||
|
let rc = iter.collect::<Rc<[_]>>();
|
||||||
|
assert_eq!(&*vec, &*rc);
|
||||||
|
assert_eq!(0, mem::size_of_val(&*rc));
|
||||||
|
{
|
||||||
|
let _rc_2 = rc.clone();
|
||||||
|
let _rc_3 = rc.clone();
|
||||||
|
let _rc_4 = Rc::downgrade(&_rc_3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic = "I've almost got 99 problems."]
|
||||||
|
fn shared_from_iter_trustedlen_panic() {
|
||||||
|
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
||||||
|
// `(_, Some(exact_len))` but where `.next()` drops before the last iteration.
|
||||||
|
let iter = (0..SHARED_ITER_MAX)
|
||||||
|
.map(|val| {
|
||||||
|
match val {
|
||||||
|
98 => panic!("I've almost got 99 problems."),
|
||||||
|
_ => Box::new(val),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assert_trusted_len(&iter);
|
||||||
|
let _ = iter.collect::<Rc<[_]>>();
|
||||||
|
|
||||||
|
panic!("I am unreachable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn shared_from_iter_trustedlen_no_fuse() {
|
||||||
|
// Exercise the `TrustedLen` implementation when `size_hint()` matches
|
||||||
|
// `(_, Some(exact_len))` but where the iterator does not behave in a fused manner.
|
||||||
|
struct Iter(std::vec::IntoIter<Option<Box<u8>>>);
|
||||||
|
|
||||||
|
unsafe impl TrustedLen for Iter {}
|
||||||
|
|
||||||
|
impl Iterator for Iter {
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
(2, Some(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
type Item = Box<u8>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.0.next().flatten()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let vec = vec![
|
||||||
|
Some(Box::new(42)),
|
||||||
|
Some(Box::new(24)),
|
||||||
|
None,
|
||||||
|
Some(Box::new(12)),
|
||||||
|
];
|
||||||
|
let iter = Iter(vec.into_iter());
|
||||||
|
assert_trusted_len(&iter);
|
||||||
|
assert_eq!(
|
||||||
|
&[Box::new(42), Box::new(24)],
|
||||||
|
&*iter.collect::<Rc<[_]>>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user