core/iter/traits/exact_size.rs
1/// An iterator that knows its exact length.
2///
3/// Many [`Iterator`]s don't know how many times they will iterate, but some do.
4/// If an iterator knows how many times it can iterate, providing access to
5/// that information can be useful. For example, if you want to iterate
6/// backwards, a good start is to know where the end is.
7///
8/// When implementing an `ExactSizeIterator`, you must also implement
9/// [`Iterator`]. When doing so, the implementation of [`Iterator::size_hint`]
10/// *must* return the exact size of the iterator.
11///
12/// The [`len`] method has a default implementation, so you usually shouldn't
13/// implement it. However, you may be able to provide a more performant
14/// implementation than the default, so overriding it in this case makes sense.
15///
16/// Note that this trait is a safe trait and as such does *not* and *cannot*
17/// guarantee that the returned length is correct. This means that `unsafe`
18/// code **must not** rely on the correctness of [`Iterator::size_hint`]. The
19/// unstable and unsafe [`TrustedLen`](super::marker::TrustedLen) trait gives
20/// this additional guarantee.
21///
22/// [`len`]: ExactSizeIterator::len
23///
24/// # When *shouldn't* an adapter be `ExactSizeIterator`?
25///
26/// If an adapter makes an iterator *longer*, then it's usually incorrect for
27/// that adapter to implement `ExactSizeIterator`. The inner exact-sized
28/// iterator might already be `usize::MAX`-long, and thus the length of the
29/// longer adapted iterator would no longer be exactly representable in `usize`.
30///
31/// This is why [`Chain<A, B>`](crate::iter::Chain) isn't `ExactSizeIterator`,
32/// even when `A` and `B` are both `ExactSizeIterator`.
33///
34/// # Examples
35///
36/// Basic usage:
37///
38/// ```
39/// // a finite range knows exactly how many times it will iterate
40/// let five = 0..5;
41///
42/// assert_eq!(5, five.len());
43/// ```
44///
45/// In the [module-level docs], we implemented an [`Iterator`], `Counter`.
46/// Let's implement `ExactSizeIterator` for it as well:
47///
48/// [module-level docs]: crate::iter
49///
50/// ```
51/// # struct Counter {
52/// # count: usize,
53/// # }
54/// # impl Counter {
55/// # fn new() -> Counter {
56/// # Counter { count: 0 }
57/// # }
58/// # }
59/// # impl Iterator for Counter {
60/// # type Item = usize;
61/// # fn next(&mut self) -> Option<Self::Item> {
62/// # self.count += 1;
63/// # if self.count < 6 {
64/// # Some(self.count)
65/// # } else {
66/// # None
67/// # }
68/// # }
69/// # }
70/// impl ExactSizeIterator for Counter {
71/// // We can easily calculate the remaining number of iterations.
72/// fn len(&self) -> usize {
73/// 5 - self.count
74/// }
75/// }
76///
77/// // And now we can use it!
78///
79/// let mut counter = Counter::new();
80///
81/// assert_eq!(5, counter.len());
82/// let _ = counter.next();
83/// assert_eq!(4, counter.len());
84/// ```
85#[stable(feature = "rust1", since = "1.0.0")]
86pub trait ExactSizeIterator: Iterator {
87 /// Returns the exact remaining length of the iterator.
88 ///
89 /// The implementation ensures that the iterator will return exactly `len()`
90 /// more times a [`Some(T)`] value, before returning [`None`].
91 /// This method has a default implementation, so you usually should not
92 /// implement it directly. However, if you can provide a more efficient
93 /// implementation, you can do so. See the [trait-level] docs for an
94 /// example.
95 ///
96 /// This function has the same safety guarantees as the
97 /// [`Iterator::size_hint`] function.
98 ///
99 /// [trait-level]: ExactSizeIterator
100 /// [`Some(T)`]: Some
101 ///
102 /// # Examples
103 ///
104 /// Basic usage:
105 ///
106 /// ```
107 /// // a finite range knows exactly how many times it will iterate
108 /// let mut range = 0..5;
109 ///
110 /// assert_eq!(5, range.len());
111 /// let _ = range.next();
112 /// assert_eq!(4, range.len());
113 /// ```
114 #[inline]
115 #[stable(feature = "rust1", since = "1.0.0")]
116 #[cfg(not(feature = "ferrocene_certified"))]
117 fn len(&self) -> usize {
118 let (lower, upper) = self.size_hint();
119 // Note: This assertion is overly defensive, but it checks the invariant
120 // guaranteed by the trait. If this trait were rust-internal,
121 // we could use debug_assert!; assert_eq! will check all Rust user
122 // implementations too.
123 assert_eq!(upper, Some(lower));
124 lower
125 }
126 /// Ferrocene addition: Gate default implementation
127 #[inline]
128 #[stable(feature = "rust1", since = "1.0.0")]
129 #[cfg(feature = "ferrocene_certified")]
130 fn len(&self) -> usize;
131
132 /// Returns `true` if the iterator is empty.
133 ///
134 /// This method has a default implementation using
135 /// [`ExactSizeIterator::len()`], so you don't need to implement it yourself.
136 ///
137 /// # Examples
138 ///
139 /// Basic usage:
140 ///
141 /// ```
142 /// #![feature(exact_size_is_empty)]
143 ///
144 /// let mut one_element = std::iter::once(0);
145 /// assert!(!one_element.is_empty());
146 ///
147 /// assert_eq!(one_element.next(), Some(0));
148 /// assert!(one_element.is_empty());
149 ///
150 /// assert_eq!(one_element.next(), None);
151 /// ```
152 #[inline]
153 #[unstable(feature = "exact_size_is_empty", issue = "35428")]
154 fn is_empty(&self) -> bool {
155 self.len() == 0
156 }
157}
158
159#[stable(feature = "rust1", since = "1.0.0")]
160impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for &mut I {
161 fn len(&self) -> usize {
162 (**self).len()
163 }
164 fn is_empty(&self) -> bool {
165 (**self).is_empty()
166 }
167}