]> git.proxmox.com Git - rustc.git/blame - library/core/src/iter/traits/exact_size.rs
New upstream version 1.50.0+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///
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")]
68pub 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")]
134impl<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}