1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
//! Base iterator traits. cfg_if! { if #[cfg(feature = "std")] { use std::iter::FromIterator; } else { use core::iter::FromIterator; } } use refs::{Ref, RefMut}; /// A trait for iterable collections which contain data of a given type. /// /// In most cases, you shouldn't implement this trait directly; instead, you should implement /// `IntoIterator`, which will in turn implement this trait. /// /// The only exception is dynamically-sized types, which cannot implement `IntoIterator`. Instead, /// you should implement this trait to indicate what type of data is inside the collection. pub trait HasData { /// The type of the data inside this collection. type Item; } impl<T: IntoIterator> HasData for T { type Item = <T as IntoIterator>::Item; } /// A trait for collections which can be iterated by reference. /// /// In most cases, you shouldn't implement this trait directly; instead, you should implement /// `IntoIterator` for a reference of this type, which will in turn implement this trait. pub trait Iter<'a>: 'a + HasData { /// Type of the references to the data in the collection. /// /// Although this might just be `&'a Item`, it can also be more complicated. For example, an /// iterator with `Item = (usize, T)` might use `(usize, &'a T)` for this instead. /// /// For more information, see the `Ref` trait. type ItemRef: Ref<'a, Self::Item>; /// Type of the iterator over references. type IterRef: Iterator<Item = Self::ItemRef>; /// Constructs an iterator over references to the data in this collection. fn iter(&'a self) -> Self::IterRef; } impl<'a, T: 'a + HasData> Iter<'a> for T where &'a T: IntoIterator, <&'a T as IntoIterator>::Item: Ref<'a, T::Item>, { type ItemRef = <&'a Self as IntoIterator>::Item; type IterRef = <&'a Self as IntoIterator>::IntoIter; fn iter(&'a self) -> Self::IterRef { self.into_iter() } } /// A trait for collections which can be iterated by mutable reference. /// /// In most cases, you shouldn't implement this trait directly; instead, you should implement /// `IntoIterator` for a mutable reference of this type, which will in turn implement this trait. pub trait IterMut<'a>: Iter<'a> { /// Type of the mutable references to the data in the collection. /// /// Although this might just be `&'a Item`, it can also be more complicated. For example, an /// iterator with `Item = (usize, T)` might use `(usize, &'a mut T)` for this instead. /// /// For more information, see the `RefMut` trait. type ItemMut: RefMut<'a, Self::Item>; /// Type of the iterator over mutable references. type IterMut: Iterator<Item = Self::ItemMut>; /// Constructs an iterator over mutable references to the data in this collection. fn iter_mut(&'a mut self) -> Self::IterMut; } impl<'a, T: 'a + Iter<'a>> IterMut<'a> for T where &'a mut T: IntoIterator, <&'a mut T as IntoIterator>::Item: RefMut<'a, T::Item>, { type ItemMut = <&'a mut Self as IntoIterator>::Item; type IterMut = <&'a mut Self as IntoIterator>::IntoIter; fn iter_mut(&'a mut self) -> Self::IterMut { self.into_iter() } } /// A trait for collections which can be converted to and from iterators over data. pub trait IterOwned : HasData + IntoIterator<Item = <Self as HasData>::Item> + FromIterator<<Self as HasData>::Item> + Extend<<Self as HasData>::Item> {} impl<T> IterOwned for T where T: HasData, T: IntoIterator<Item = <T as HasData>::Item>, T: FromIterator<<T as HasData>::Item>, T: Extend<<T as HasData>::Item>, {}