From 4c8ce48a15c88715955e56c9c35959d9dffad5ec Mon Sep 17 00:00:00 2001 From: VillSnow Date: Sun, 21 Jun 2020 13:52:26 +0900 Subject: [PATCH] Add partition_point --- src/libcore/slice/mod.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 21ba2b5abcf..fe472092b10 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2663,6 +2663,44 @@ impl [T] { { self.iter().is_sorted_by_key(f) } + + /// Returns index of partition point according to the given predicate, + /// such that all those that return true precede the index and + /// such that all those that return false succeed the index. + /// + /// 'self' must be partitioned. + /// + /// # Examples + /// + /// ``` + /// #![feature(partition_point)] + /// + /// let v = [1, 2, 3, 3, 5, 6, 7]; + /// let i = xs.partition_point(|&x| x < 5); + /// + /// assert_eq!(i, 4); + /// assert!(xs[..i].iter().all(|&x| x < 5)); + /// assert!(xs[i..].iter().all(|&x| !(x < 5))); + /// ``` + #[unstable(feature = "partition_point", reason = "new API", issue = "99999")] + pub fn partition_point

(&self, mut pred: P) -> usize + where + P: FnMut(&T) -> bool, + { + let mut left = 0; + let mut right = self.len(); + + while left != right { + let mid = left + (right - left) / 2; + let value = unsafe { self.get_unchecked(mid) }; + if pred(value) { + left = mid + 1; + } else { + right = mid; + } + } + return left; + } } #[lang = "slice_u8"]