From 1bff4c20da9e36b293fb0fabb3e9ff815b24cf0c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 25 Oct 2018 20:46:53 +0200 Subject: [PATCH 1/3] add Iterator::single. --- src/libcore/iter/iterator.rs | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 5b6d9e2033caa..15c4997ac9898 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1875,6 +1875,50 @@ pub trait Iterator { }).break_value() } + /// Extracts the single remaining element out of the iterator. + /// + /// [`next()`]: #method.next + /// [`by_ref()`]: #method.by_ref + /// [`Some(x)`]: ../../std/option/enum.Option.html#variant.Some + /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// + /// If [`next()`] will return [`Some(x)`] the first time, and then return + /// [`None`] the next time around, then `single()` will return `Some(x)`. + /// If there are no elements to extract or if there more than one, + /// then the iterator will will return `None`. + /// + /// This method takes ownership of the iterator it is called on. + /// If you want to retain ownership, call [`by_ref()`] on the iterator + /// first before calling `single()`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ```rust + /// #![feature(iterator_single)] + /// + /// assert_eq!(&[].iter().single(), None); + /// assert_eq!(&[42].iter().single(), Some(42)); + /// assert_eq!(&[42, 24].iter().single(), None); + /// assert_eq!(&[42, 24, 0].iter().single(), None); + /// ``` + /// + /// # Invariants + /// + /// If `count()` does not panic and returns `1`, then `single()` will + /// return `Some(element)`. Otherwise, `single()` will return `None`. + #[inline] + #[unstable(feature = "iterator_single", issue = "55354")] + fn single(mut self) -> Option where Self: Sized { + if let x@Some(_) = self.next() { + if let None = self.next() { + return x + } + } + None + } + /// Searches for an element in an iterator, returning its index. /// /// `position()` takes a closure that returns `true` or `false`. It applies From 93834df722258e335e2aa1a26f37db981f2a3410 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 25 Oct 2018 22:38:42 +0200 Subject: [PATCH 2/3] Iterator::single: fix docs. --- src/libcore/iter/iterator.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 15c4997ac9898..fdfaf79d4335b 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1898,10 +1898,15 @@ pub trait Iterator { /// ```rust /// #![feature(iterator_single)] /// - /// assert_eq!(&[].iter().single(), None); - /// assert_eq!(&[42].iter().single(), Some(42)); - /// assert_eq!(&[42, 24].iter().single(), None); - /// assert_eq!(&[42, 24, 0].iter().single(), None); + /// let zero: [u8; 0] = []; + /// let one: [u8; 1] = [42]; + /// let two: [u8; 2] = [42, 24]; + /// let three: [u8; 3] = [42, 24, 0]; + /// + /// assert_eq!(zero.iter().single(), None); + /// assert_eq!(one.iter().single(), Some(42)); + /// assert_eq!(two.iter().single(), None); + /// assert_eq!(three.iter().single(), None); /// ``` /// /// # Invariants From dd95f2359dd1ab1f08d2b017a620f6f1bee88a7d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Fri, 26 Oct 2018 00:04:58 +0200 Subject: [PATCH 3/3] Iterator::single: fix-2 docs. --- src/libcore/iter/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index fdfaf79d4335b..eb23b8d7fe1f5 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -1904,7 +1904,7 @@ pub trait Iterator { /// let three: [u8; 3] = [42, 24, 0]; /// /// assert_eq!(zero.iter().single(), None); - /// assert_eq!(one.iter().single(), Some(42)); + /// assert_eq!(one.iter().single(), Some(&42)); /// assert_eq!(two.iter().single(), None); /// assert_eq!(three.iter().single(), None); /// ```