@@ -129,6 +129,12 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
129129 hd
130130 }
131131
132+ override def knownSize = {
133+ val thisSize = self.knownSize
134+ if (thisSize >= 0 && hdDefined) thisSize + 1
135+ else thisSize
136+ }
137+
132138 def hasNext =
133139 hdDefined || self.hasNext
134140
@@ -278,22 +284,25 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
278284 * all elements of this $coll followed by the minimal number of occurrences of `elem` so
279285 * that the resulting collection has a length of at least `len`.
280286 */
281- def padTo [B >: A ](len : Int , elem : B ): Iterator [B ] = {
282- val it = this
283- new AbstractIterator [B ] {
284- private [this ] var i = 0
287+ def padTo [B >: A ](len : Int , elem : B ): Iterator [B ] = new AbstractIterator [B ] {
288+ private [this ] var i = 0
285289
286- def next (): B = {
287- val b =
288- if (it.hasNext) it.next()
289- else if (i < len) elem
290- else Iterator .empty.next()
291- i += 1
292- b
293- }
290+ override def knownSize : Int = {
291+ val thisSize = self.knownSize
292+ if (thisSize < 0 ) - 1
293+ else thisSize max (len - i)
294+ }
294295
295- def hasNext : Boolean = it.hasNext || i < len
296+ def next (): B = {
297+ val b =
298+ if (self.hasNext) self.next()
299+ else if (i < len) elem
300+ else Iterator .empty.next()
301+ i += 1
302+ b
296303 }
304+
305+ def hasNext : Boolean = self.hasNext || i < len
297306 }
298307
299308 /** Partitions this iterator in two iterators according to a predicate.
@@ -369,6 +378,12 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
369378 // and then that will be modified to iterate through the collection
370379 private [this ] var current : Iterator [B ] =
371380 new AbstractIterator [B ] {
381+ override def knownSize = {
382+ val thisSize = self.knownSize
383+
384+ if (thisSize < 0 ) - 1
385+ else thisSize + 1
386+ }
372387 def hasNext : Boolean = true
373388 def next (): B = {
374389 // Here we change our self-reference to a new iterator that iterates through `self`
@@ -379,10 +394,12 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
379394 acc
380395 }
381396 def hasNext : Boolean = self.hasNext
397+ override def knownSize = self.knownSize
382398 }
383399 z
384400 }
385401 }
402+ override def knownSize = current.knownSize
386403 def next (): B = current.next()
387404 def hasNext : Boolean = current.hasNext
388405 }
@@ -551,6 +568,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
551568 }
552569
553570 def map [B ](f : A => B ): Iterator [B ] = new AbstractIterator [B ] {
571+ override def knownSize = self.knownSize
554572 def hasNext = self.hasNext
555573 def next () = f(self.next())
556574 }
@@ -773,12 +791,19 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
773791
774792 def zip [B ](that : IterableOnce [B ]): Iterator [(A , B )] = new AbstractIterator [(A , B )] {
775793 val thatIterator = that.iterator
794+ override def knownSize = self.knownSize min thatIterator.knownSize
776795 def hasNext = self.hasNext && thatIterator.hasNext
777796 def next () = (self.next(), thatIterator.next())
778797 }
779798
780799 def zipAll [A1 >: A , B ](that : IterableOnce [B ], thisElem : A1 , thatElem : B ): Iterator [(A1 , B )] = new AbstractIterator [(A1 , B )] {
781800 val thatIterator = that.iterator
801+ override def knownSize = {
802+ val thisSize = self.knownSize
803+ val thatSize = thatIterator.knownSize
804+ if (thisSize < 0 || thatSize < 0 ) - 1
805+ else thisSize max thatSize
806+ }
782807 def hasNext = self.hasNext || thatIterator.hasNext
783808 def next (): (A1 , B ) = {
784809 val next1 = self.hasNext
@@ -790,6 +815,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
790815
791816 def zipWithIndex : Iterator [(A , Int )] = new AbstractIterator [(A , Int )] {
792817 var idx = 0
818+ override def knownSize = self.knownSize
793819 def hasNext = self.hasNext
794820 def next () = {
795821 val ret = (self.next(), idx)
@@ -825,6 +851,13 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
825851 val gap = new scala.collection.mutable.Queue [A ]
826852 var ahead : Iterator [A ] = null
827853 class Partner extends AbstractIterator [A ] {
854+ override def knownSize : Int = self.synchronized {
855+ val thisSize = self.knownSize
856+
857+ if (this eq ahead) thisSize
858+ else if (thisSize < 0 || gap.knownSize < 0 ) - 1
859+ else thisSize + gap.knownSize
860+ }
828861 def hasNext : Boolean = self.synchronized {
829862 (this ne ahead) && ! gap.isEmpty || self.hasNext
830863 }
@@ -958,6 +991,7 @@ object Iterator extends IterableFactory[Iterator] {
958991 */
959992 override def fill [A ](len : Int )(elem : => A ): Iterator [A ] = new AbstractIterator [A ] {
960993 private [this ] var i = 0
994+ override def knownSize : Int = (len - i) max 0
961995 def hasNext : Boolean = i < len
962996 def next (): A =
963997 if (hasNext) { i += 1 ; elem }
@@ -972,6 +1006,7 @@ object Iterator extends IterableFactory[Iterator] {
9721006 */
9731007 override def tabulate [A ](end : Int )(f : Int => A ): Iterator [A ] = new AbstractIterator [A ] {
9741008 private [this ] var i = 0
1009+ override def knownSize : Int = (end - i) max 0
9751010 def hasNext : Boolean = i < end
9761011 def next (): A =
9771012 if (hasNext) { val result = f(i); i += 1 ; result }
@@ -1016,6 +1051,12 @@ object Iterator extends IterableFactory[Iterator] {
10161051 if (step == 0 ) throw new IllegalArgumentException (" zero step" )
10171052 private [this ] var i = start
10181053 private [this ] var hasOverflowed = false
1054+ override def knownSize : Int = {
1055+ val size = math.ceil((end.toLong - i.toLong) / step.toDouble)
1056+ if (size < 0 ) 0
1057+ else if (size > Int .MaxValue ) - 1
1058+ else size.toInt
1059+ }
10191060 def hasNext : Boolean = {
10201061 (step <= 0 || i < end) && (step >= 0 || i > end) && ! hasOverflowed
10211062 }
@@ -1161,6 +1202,15 @@ object Iterator extends IterableFactory[Iterator] {
11611202 } else
11621203 dropping = 0
11631204 }
1205+ override def knownSize : Int = {
1206+ val size = underlying.knownSize
1207+ if (size < 0 ) - 1
1208+ else {
1209+ val dropSize = 0 max (size - dropping)
1210+ if (unbounded) dropSize
1211+ else remaining min dropSize
1212+ }
1213+ }
11641214 def hasNext = { skip(); remaining != 0 && underlying.hasNext }
11651215 def next () = {
11661216 skip()
0 commit comments