use crate::traits::*;
use core::iter::FusedIterator;
use core::ops::Range;
pub struct Iter<'s, S> {
seq: &'s S,
index: Range<usize>,
}
impl<'s, S> From<&'s S> for Iter<'s, S>
where
S: Sequence,
{
#[inline]
fn from(seq: &'s S) -> Self {
let index = 0..seq.len();
Self { seq, index }
}
}
impl<'s, S> Iterator for Iter<'s, S>
where
S: Sequence,
{
type Item = <S as SequenceTypes<'s>>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.seq.get(self.index.next()?)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.index.size_hint()
}
}
impl<'s, S> DoubleEndedIterator for Iter<'s, S>
where
S: Sequence,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.seq.get(self.index.next_back()?)
}
}
impl<'s, S> ExactSizeIterator for Iter<'s, S> where S: Sequence {}
impl<'s, S> FusedIterator for Iter<'s, S> where S: Sequence {}
unsafe impl<'s, S> UniqueIterator for Iter<'s, S> where S: UniqueSequence {}
pub struct IntoIter<S> {
seq: S,
index: Range<usize>,
}
impl<S> From<S> for IntoIter<S>
where
S: Sequence,
{
#[inline]
fn from(seq: S) -> Self {
let index = 0..seq.len();
Self { seq, index }
}
}
impl<S, Item> Iterator for IntoIter<S>
where
S: Sequence + for<'a> SequenceTypes<'a, Item = Item>,
{
type Item = Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.seq.get(self.index.next()?)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.index.size_hint()
}
}
impl<S, Item> DoubleEndedIterator for IntoIter<S>
where
S: Sequence + for<'a> SequenceTypes<'a, Item = Item>,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.seq.get(self.index.next_back()?)
}
}
impl<S, Item> ExactSizeIterator for IntoIter<S> where
S: Sequence + for<'a> SequenceTypes<'a, Item = Item>
{
}
impl<S, Item> FusedIterator for IntoIter<S> where
S: Sequence + for<'a> SequenceTypes<'a, Item = Item>
{
}
unsafe impl<S, Item> UniqueIterator for IntoIter<S> where
S: Sequence + for<'a> SequenceTypes<'a, Item = Item> + UniqueSequence
{
}
#[cfg(test)]
mod tests {
use super::{IntoIter, Iter};
use crate::traits::*;
struct Range4 {}
impl<'this> SequenceTypes<'this> for Range4 {
type Item = usize;
type Iter = Iter<'this, Self>;
}
impl Sequence for Range4 {
fn len(&self) -> usize {
4
}
fn get(&self, index: usize) -> Option<usize> {
(index < 4).then_some(index)
}
fn iter(&self) -> Iter<'_, Self> {
self.into()
}
}
impl IntoIterator for Range4 {
type Item = usize;
type IntoIter = IntoIter<Self>;
fn into_iter(self) -> IntoIter<Self> {
self.into()
}
}
#[test]
fn iter() {
assert!(Range4 {}.iter().eq(0..4));
}
#[test]
fn rev_iter() {
assert!(Range4 {}.iter().rev().eq(Iterator::rev(0..4)));
}
#[test]
fn iter_size_hint() {
let mut iter = Range4 {}.iter();
assert_eq!(iter.len(), 4);
iter.next();
assert_eq!(iter.len(), 3);
}
#[test]
fn into_iter() {
assert!(Range4 {}.into_iter().eq(0..4));
}
#[test]
fn rev_into_iter() {
assert!(Range4 {}.into_iter().rev().eq(Iterator::rev(0..4)));
}
#[test]
fn into_iter_size_hint() {
let mut iter = Range4 {}.into_iter();
assert_eq!(iter.len(), 4);
iter.next();
assert_eq!(iter.len(), 3);
}
}