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