]> git.proxmox.com Git - rustc.git/blame - library/core/src/iter/traits/exact_size.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / library / core / src / iter / traits / exact_size.rs
CommitLineData
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")]
74pub 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")]
141impl<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}