From 54f11240b701f7d4031c3d1545232ebad4436c15 Mon Sep 17 00:00:00 2001 From: Lukas Kalbertodt Date: Mon, 17 Dec 2018 15:54:19 +0100 Subject: [PATCH] Override `Iterator::is_sorted_by` in `slice::Iter` impl Additionally, the root implementation was changed a bit: it now uses `all` instead of coding that logic manually. To avoid duplicate code, the inherent `[T]::is_sorted_by` method now calls `self.iter().is_sorted_by(...)`. This should always be inlined and not result in overhead. --- src/libcore/slice/mod.rs | 35 ++++++++++++------- .../feature-gates/feature-gate-is_sorted.rs | 10 ------ .../feature-gate-is_sorted.stderr | 8 ++--- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 11ce8115d309..df4d97ee6a44 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2293,16 +2293,7 @@ impl [T] { where F: FnMut(&T, &T) -> Option { - for pair in self.windows(2) { - if compare(&pair[0], &pair[1]) - .map(|o| o == Ordering::Greater) - .unwrap_or(true) - { - return false; - } - } - - true + self.iter().is_sorted_by(|a, b| compare(*a, *b)) } /// Checks if the elements of this slice are sorted using the given key extraction function. @@ -2853,7 +2844,13 @@ macro_rules! len { // The shared definition of the `Iter` and `IterMut` iterators macro_rules! iterator { - (struct $name:ident -> $ptr:ty, $elem:ty, $raw_mut:tt, $( $mut_:tt )*) => { + ( + struct $name:ident -> $ptr:ty, + $elem:ty, + $raw_mut:tt, + {$( $mut_:tt )*}, + {$($extra:tt)*} + ) => { impl<'a, T> $name<'a, T> { // Helper function for creating a slice from the iterator. #[inline(always)] @@ -3030,6 +3027,8 @@ macro_rules! iterator { i }) } + + $($extra)* } #[stable(feature = "rust1", since = "1.0.0")] @@ -3167,7 +3166,17 @@ impl<'a, T> Iter<'a, T> { } } -iterator!{struct Iter -> *const T, &'a T, const, /* no mut */} +iterator!{struct Iter -> *const T, &'a T, const, {/* no mut */}, { + fn is_sorted_by(self, mut compare: F) -> bool + where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option, + { + self.as_slice().windows(2).all(|w| { + compare(&&w[0], &&w[1]).map(|o| o != Ordering::Greater).unwrap_or(false) + }) + } +}} #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Iter<'_, T> { @@ -3268,7 +3277,7 @@ impl<'a, T> IterMut<'a, T> { } } -iterator!{struct IterMut -> *mut T, &'a mut T, mut, mut} +iterator!{struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}} /// An internal abstraction over the splitting iterators, so that /// splitn, splitn_mut etc can be implemented once. diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs index f44e74838ed2..432ead65b172 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.rs +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs @@ -1,13 +1,3 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - fn main() { // Assert `Iterator` methods are feature gated assert!([1, 2, 2, 9].iter().is_sorted()); diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr index 873cee533705..8230c1e3a38d 100644 --- a/src/test/ui/feature-gates/feature-gate-is_sorted.stderr +++ b/src/test/ui/feature-gates/feature-gate-is_sorted.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:13:33 + --> $DIR/feature-gate-is_sorted.rs:3:33 | LL | assert!([1, 2, 2, 9].iter().is_sorted()); | ^^^^^^^^^ @@ -7,7 +7,7 @@ LL | assert!([1, 2, 2, 9].iter().is_sorted()); = help: add #![feature(is_sorted)] to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:15:39 + --> $DIR/feature-gate-is_sorted.rs:5:39 | LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); | ^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs())); = help: add #![feature(is_sorted)] to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:19:26 + --> $DIR/feature-gate-is_sorted.rs:9:26 | LL | assert!([1, 2, 2, 9].is_sorted()); | ^^^^^^^^^ @@ -23,7 +23,7 @@ LL | assert!([1, 2, 2, 9].is_sorted()); = help: add #![feature(is_sorted)] to the crate attributes to enable error[E0658]: use of unstable library feature 'is_sorted': new API (see issue #53485) - --> $DIR/feature-gate-is_sorted.rs:21:32 + --> $DIR/feature-gate-is_sorted.rs:11:32 | LL | assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs())); | ^^^^^^^^^^^^^^^^