diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-05-14 22:00:09 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-05-14 22:00:09 +0200 |
| commit | bab03cecfeadcbc79ee2aead61c4de973e5649a0 (patch) | |
| tree | c21019d74e135ab2045e9adc8bd65bc61453d0aa /src/libstd | |
| parent | f59c71eb8ed808347c1e4245b842d673c75daeb6 (diff) | |
| parent | 3e86cf36b5114f201868bf459934fe346a76a2d4 (diff) | |
| download | rust-bab03cecfeadcbc79ee2aead61c4de973e5649a0.tar.gz rust-bab03cecfeadcbc79ee2aead61c4de973e5649a0.zip | |
Rollup merge of #60130 - khuey:efficient_last, r=sfackler
Add implementations of last in terms of next_back on a bunch of DoubleEndedIterators Provided a `DoubleEndedIterator` has finite length, `Iterator::last` is equivalent to `DoubleEndedIterator::next_back`. But searching forwards through the iterator when it's unnecessary is obviously not good for performance. I ran into this on one of the collection iterators. I tried adding appropriate overloads for a bunch of the iterator adapters like filter, map, etc, but I ran into a lot of type inference failures after doing so. The other interesting case is what to do with `Repeat`. Do we consider it part of the contract that `Iterator::last` will loop forever on it? The docs do say that the iterator will be evaluated until it returns None. This is also relevant for the adapters, it's trivially easy to observe whether a `Map` adapter invoked its closure a zillion times or just once for the last element.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/env.rs | 6 | ||||
| -rw-r--r-- | src/libstd/path.rs | 10 | ||||
| -rw-r--r-- | src/libstd/sys/unix/args.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/args.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/windows/args.rs | 2 |
5 files changed, 24 insertions, 0 deletions
diff --git a/src/libstd/env.rs b/src/libstd/env.rs index c0d0c23e469..39896ac2fcd 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -746,6 +746,10 @@ impl Iterator for Args { self.inner.next().map(|s| s.into_string().unwrap()) } fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } + #[inline] + fn last(mut self) -> Option<String> { + self.next_back() + } } #[stable(feature = "env", since = "1.0.0")] @@ -781,6 +785,8 @@ impl Iterator for ArgsOs { type Item = OsString; fn next(&mut self) -> Option<OsString> { self.inner.next() } fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() } + #[inline] + fn last(mut self) -> Option<OsString> { self.next_back() } } #[stable(feature = "env", since = "1.0.0")] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 126bc3754da..59f9e439add 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -888,6 +888,11 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option<&'a OsStr> { self.inner.next().map(Component::as_os_str) } + + #[inline] + fn last(mut self) -> Option<&'a OsStr> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -951,6 +956,11 @@ impl<'a> Iterator for Components<'a> { } None } + + #[inline] + fn last(mut self) -> Option<Self::Item> { + self.next_back() + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 18de1096df2..f0594bb21bd 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -35,6 +35,8 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option<OsString> { self.iter.next() } fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option<OsString> { self.next_back() } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs index b3c77b86995..6766099c1ec 100644 --- a/src/libstd/sys/wasm/args.rs +++ b/src/libstd/sys/wasm/args.rs @@ -37,6 +37,10 @@ impl Iterator for Args { fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() } + #[inline] + fn last(mut self) -> Option<OsString> { + self.next_back() + } } impl ExactSizeIterator for Args { diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs index b04bb484eed..744d7ec59d3 100644 --- a/src/libstd/sys/windows/args.rs +++ b/src/libstd/sys/windows/args.rs @@ -181,6 +181,8 @@ impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option<OsString> { self.parsed_args_list.next() } fn size_hint(&self) -> (usize, Option<usize>) { self.parsed_args_list.size_hint() } + #[inline] + fn last(mut self) -> Option<OsString> { self.next_back() } } impl DoubleEndedIterator for Args { |
