]> git.lizzy.rs Git - rust.git/blob - library/core/src/iter/traits/exact_size.rs
Rollup merge of #102708 - TaKO8Ki:improve-eqeq-suggestion, r=estebank
[rust.git] / library / core / src / 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 /// # Examples
25 ///
26 /// Basic usage:
27 ///
28 /// ```
29 /// // a finite range knows exactly how many times it will iterate
30 /// let five = 0..5;
31 ///
32 /// assert_eq!(5, five.len());
33 /// ```
34 ///
35 /// In the [module-level docs], we implemented an [`Iterator`], `Counter`.
36 /// Let's implement `ExactSizeIterator` for it as well:
37 ///
38 /// [module-level docs]: crate::iter
39 ///
40 /// ```
41 /// # struct Counter {
42 /// #     count: usize,
43 /// # }
44 /// # impl Counter {
45 /// #     fn new() -> Counter {
46 /// #         Counter { count: 0 }
47 /// #     }
48 /// # }
49 /// # impl Iterator for Counter {
50 /// #     type Item = usize;
51 /// #     fn next(&mut self) -> Option<Self::Item> {
52 /// #         self.count += 1;
53 /// #         if self.count < 6 {
54 /// #             Some(self.count)
55 /// #         } else {
56 /// #             None
57 /// #         }
58 /// #     }
59 /// # }
60 /// impl ExactSizeIterator for Counter {
61 ///     // We can easily calculate the remaining number of iterations.
62 ///     fn len(&self) -> usize {
63 ///         5 - self.count
64 ///     }
65 /// }
66 ///
67 /// // And now we can use it!
68 ///
69 /// let mut counter = Counter::new();
70 ///
71 /// assert_eq!(5, counter.len());
72 /// let _ = counter.next();
73 /// assert_eq!(4, counter.len());
74 /// ```
75 #[stable(feature = "rust1", since = "1.0.0")]
76 pub trait ExactSizeIterator: Iterator {
77     /// Returns the exact remaining length of the iterator.
78     ///
79     /// The implementation ensures that the iterator will return exactly `len()`
80     /// more times a [`Some(T)`] value, before returning [`None`].
81     /// This method has a default implementation, so you usually should not
82     /// implement it directly. However, if you can provide a more efficient
83     /// implementation, you can do so. See the [trait-level] docs for an
84     /// example.
85     ///
86     /// This function has the same safety guarantees as the
87     /// [`Iterator::size_hint`] function.
88     ///
89     /// [trait-level]: ExactSizeIterator
90     /// [`Some(T)`]: Some
91     ///
92     /// # Examples
93     ///
94     /// Basic usage:
95     ///
96     /// ```
97     /// // a finite range knows exactly how many times it will iterate
98     /// let mut range = 0..5;
99     ///
100     /// assert_eq!(5, range.len());
101     /// let _ = range.next();
102     /// assert_eq!(4, range.len());
103     /// ```
104     #[inline]
105     #[stable(feature = "rust1", since = "1.0.0")]
106     fn len(&self) -> usize {
107         let (lower, upper) = self.size_hint();
108         // Note: This assertion is overly defensive, but it checks the invariant
109         // guaranteed by the trait. If this trait were rust-internal,
110         // we could use debug_assert!; assert_eq! will check all Rust user
111         // implementations too.
112         assert_eq!(upper, Some(lower));
113         lower
114     }
115
116     /// Returns `true` if the iterator is empty.
117     ///
118     /// This method has a default implementation using
119     /// [`ExactSizeIterator::len()`], so you don't need to implement it yourself.
120     ///
121     /// # Examples
122     ///
123     /// Basic usage:
124     ///
125     /// ```
126     /// #![feature(exact_size_is_empty)]
127     ///
128     /// let mut one_element = std::iter::once(0);
129     /// assert!(!one_element.is_empty());
130     ///
131     /// assert_eq!(one_element.next(), Some(0));
132     /// assert!(one_element.is_empty());
133     ///
134     /// assert_eq!(one_element.next(), None);
135     /// ```
136     #[inline]
137     #[unstable(feature = "exact_size_is_empty", issue = "35428")]
138     fn is_empty(&self) -> bool {
139         self.len() == 0
140     }
141 }
142
143 #[stable(feature = "rust1", since = "1.0.0")]
144 impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for &mut I {
145     fn len(&self) -> usize {
146         (**self).len()
147     }
148     fn is_empty(&self) -> bool {
149         (**self).is_empty()
150     }
151 }