]>
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 | /// | |
6a06907d XL |
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 | /// | |
1b1a35ee | 22 | /// [`len`]: ExactSizeIterator::len |
9fa01778 XL |
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 | /// | |
29967ef6 XL |
35 | /// In the [module-level docs], we implemented an [`Iterator`], `Counter`. |
36 | /// Let's implement `ExactSizeIterator` for it as well: | |
9fa01778 | 37 | /// |
29967ef6 | 38 | /// [module-level docs]: crate::iter |
9fa01778 XL |
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; | |
532ac7d7 | 51 | /// # fn next(&mut self) -> Option<Self::Item> { |
9fa01778 XL |
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 counter = Counter::new(); | |
70 | /// | |
71 | /// assert_eq!(5, counter.len()); | |
72 | /// ``` | |
73 | #[stable(feature = "rust1", since = "1.0.0")] | |
74 | pub trait ExactSizeIterator: Iterator { | |
74b04a01 | 75 | /// Returns the exact length of the iterator. |
9fa01778 | 76 | /// |
74b04a01 | 77 | /// The implementation ensures that the iterator will return exactly `len()` |
1b1a35ee | 78 | /// more times a [`Some(T)`] value, before returning [`None`]. |
9fa01778 XL |
79 | /// This method has a default implementation, so you usually should not |
80 | /// implement it directly. However, if you can provide a more efficient | |
81 | /// implementation, you can do so. See the [trait-level] docs for an | |
82 | /// example. | |
83 | /// | |
1b1a35ee XL |
84 | /// This function has the same safety guarantees as the |
85 | /// [`Iterator::size_hint`] function. | |
9fa01778 | 86 | /// |
1b1a35ee XL |
87 | /// [trait-level]: ExactSizeIterator |
88 | /// [`Some(T)`]: Some | |
9fa01778 XL |
89 | /// |
90 | /// # Examples | |
91 | /// | |
92 | /// Basic usage: | |
93 | /// | |
94 | /// ``` | |
95 | /// // a finite range knows exactly how many times it will iterate | |
96 | /// let five = 0..5; | |
97 | /// | |
98 | /// assert_eq!(5, five.len()); | |
99 | /// ``` | |
5869c6ff | 100 | #[doc(alias = "length")] |
9fa01778 XL |
101 | #[inline] |
102 | #[stable(feature = "rust1", since = "1.0.0")] | |
103 | fn len(&self) -> usize { | |
104 | let (lower, upper) = self.size_hint(); | |
105 | // Note: This assertion is overly defensive, but it checks the invariant | |
106 | // guaranteed by the trait. If this trait were rust-internal, | |
107 | // we could use debug_assert!; assert_eq! will check all Rust user | |
108 | // implementations too. | |
109 | assert_eq!(upper, Some(lower)); | |
110 | lower | |
111 | } | |
112 | ||
113 | /// Returns `true` if the iterator is empty. | |
114 | /// | |
1b1a35ee XL |
115 | /// This method has a default implementation using |
116 | /// [`ExactSizeIterator::len()`], so you don't need to implement it yourself. | |
9fa01778 XL |
117 | /// |
118 | /// # Examples | |
119 | /// | |
120 | /// Basic usage: | |
121 | /// | |
122 | /// ``` | |
123 | /// #![feature(exact_size_is_empty)] | |
124 | /// | |
125 | /// let mut one_element = std::iter::once(0); | |
126 | /// assert!(!one_element.is_empty()); | |
127 | /// | |
128 | /// assert_eq!(one_element.next(), Some(0)); | |
129 | /// assert!(one_element.is_empty()); | |
130 | /// | |
131 | /// assert_eq!(one_element.next(), None); | |
132 | /// ``` | |
133 | #[inline] | |
134 | #[unstable(feature = "exact_size_is_empty", issue = "35428")] | |
135 | fn is_empty(&self) -> bool { | |
136 | self.len() == 0 | |
137 | } | |
138 | } | |
139 | ||
140 | #[stable(feature = "rust1", since = "1.0.0")] | |
141 | impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for &mut I { | |
142 | fn len(&self) -> usize { | |
143 | (**self).len() | |
144 | } | |
145 | fn is_empty(&self) -> bool { | |
146 | (**self).is_empty() | |
147 | } | |
148 | } |