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