@@ -20,6 +20,7 @@ import scala.language.implicitConversions
2020import scala .math .{Numeric , Ordering }
2121import scala .reflect .ClassTag
2222import scala .runtime .AbstractFunction2
23+ import language .experimental .captureChecking
2324
2425/**
2526 * A template trait for collections which can be traversed either once only
@@ -42,8 +43,10 @@ import scala.runtime.AbstractFunction2
4243 * @define coll collection
4344 */
4445trait IterableOnce [+ A ] extends Any {
46+ this : IterableOnce [A ]^ =>
47+
4548 /** Iterator can be used only once */
46- def iterator : Iterator [A ]
49+ def iterator : Iterator [A ]^ { this }
4750
4851 /** Returns a [[scala.collection.Stepper ]] for the elements of this collection.
4952 *
@@ -65,9 +68,9 @@ trait IterableOnce[+A] extends Any {
6568 * allow creating parallel streams, whereas bare Steppers can be converted only to sequential
6669 * streams.
6770 */
68- def stepper [S <: Stepper [_]](implicit shape : StepperShape [A , S ]): S = {
71+ def stepper [S <: Stepper [_]^ { this } ](implicit shape : StepperShape [A , S ]): S = {
6972 import convert .impl ._
70- val s = shape.shape match {
73+ val s : Any = shape.shape match {
7174 case StepperShape .IntShape => new IntIteratorStepper (iterator.asInstanceOf [Iterator [Int ]])
7275 case StepperShape .LongShape => new LongIteratorStepper (iterator.asInstanceOf [Iterator [Long ]])
7376 case StepperShape .DoubleShape => new DoubleIteratorStepper (iterator.asInstanceOf [Iterator [Double ]])
@@ -84,7 +87,7 @@ trait IterableOnce[+A] extends Any {
8487
8588final class IterableOnceExtensionMethods [A ](private val it : IterableOnce [A ]) extends AnyVal {
8689 @ deprecated(" Use .iterator.withFilter(...) instead" , " 2.13.0" )
87- def withFilter (f : A => Boolean ): Iterator [A ] = it.iterator.withFilter(f)
90+ def withFilter (f : A => Boolean ): Iterator [A ]^ {f} = it.iterator.withFilter(f)
8891
8992 @ deprecated(" Use .iterator.reduceLeftOption(...) instead" , " 2.13.0" )
9093 def reduceLeftOption (f : (A , A ) => A ): Option [A ] = it.iterator.reduceLeftOption(f)
@@ -102,7 +105,7 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
102105 def reduceRight (f : (A , A ) => A ): A = it.iterator.reduceRight(f)
103106
104107 @ deprecated(" Use .iterator.maxBy(...) instead" , " 2.13.0" )
105- def maxBy [B ](f : A = > B )(implicit cmp : Ordering [B ]): A = it.iterator.maxBy(f)
108+ def maxBy [B ](f : A - > B )(implicit cmp : Ordering [B ]): A = it.iterator.maxBy(f)
106109
107110 @ deprecated(" Use .iterator.reduceLeft(...) instead" , " 2.13.0" )
108111 def reduceLeft (f : (A , A ) => A ): A = it.iterator.reduceLeft(f)
@@ -120,7 +123,7 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
120123 def reduceOption (f : (A , A ) => A ): Option [A ] = it.iterator.reduceOption(f)
121124
122125 @ deprecated(" Use .iterator.minBy(...) instead" , " 2.13.0" )
123- def minBy [B ](f : A = > B )(implicit cmp : Ordering [B ]): A = it.iterator.minBy(f)
126+ def minBy [B ](f : A - > B )(implicit cmp : Ordering [B ]): A = it.iterator.minBy(f)
124127
125128 @ deprecated(" Use .iterator.size instead" , " 2.13.0" )
126129 def size : Int = it.iterator.size
@@ -132,7 +135,7 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
132135 def collectFirst [B ](f : PartialFunction [A , B ]): Option [B ] = it.iterator.collectFirst(f)
133136
134137 @ deprecated(" Use .iterator.filter(...) instead" , " 2.13.0" )
135- def filter (f : A => Boolean ): Iterator [A ] = it.iterator.filter(f)
138+ def filter (f : A => Boolean ): Iterator [A ]^ {f} = it.iterator.filter(f)
136139
137140 @ deprecated(" Use .iterator.exists(...) instead" , " 2.13.0" )
138141 def exists (f : A => Boolean ): Boolean = it.iterator.exists(f)
@@ -238,13 +241,13 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
238241 @ `inline` def : \ [B ](z : B )(op : (A , B ) => B ): B = foldRight[B ](z)(op)
239242
240243 @ deprecated(" Use .iterator.map instead or consider requiring an Iterable" , " 2.13.0" )
241- def map [B ](f : A => B ): IterableOnce [B ] = it match {
244+ def map [B ](f : A => B ): IterableOnce [B ]^ {f} = it match {
242245 case it : Iterable [A ] => it.map(f)
243246 case _ => it.iterator.map(f)
244247 }
245248
246249 @ deprecated(" Use .iterator.flatMap instead or consider requiring an Iterable" , " 2.13.0" )
247- def flatMap [B ](f : A => IterableOnce [B ]): IterableOnce [B ] = it match {
250+ def flatMap [B ](f : A => IterableOnce [B ]): IterableOnce [B ]^ {f} = it match {
248251 case it : Iterable [A ] => it.flatMap(f)
249252 case _ => it.iterator.flatMap(f)
250253 }
@@ -315,9 +318,11 @@ object IterableOnce {
315318 * @define coll collection
316319 *
317320 */
318- trait IterableOnceOps [+ A , + CC [_], + C ] extends Any { this : IterableOnce [A ] =>
321+ trait IterableOnceOps [+ A , + CC [_], + C ] extends Any { this : IterableOnce [A ]^ =>
319322 // ///////////////////////////////////////////////////////////// Abstract methods that must be implemented
320323
324+ import IterableOnceOps .Maximized
325+
321326 /** Produces a $coll containing cumulative results of applying the
322327 * operator going left to right, including the initial value.
323328 *
@@ -329,23 +334,23 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
329334 * @param op the binary operator applied to the intermediate result and the element
330335 * @return collection with intermediate results
331336 */
332- def scanLeft [B ](z : B )(op : (B , A ) => B ): CC [B ]
337+ def scanLeft [B ](z : B )(op : (B , A ) => B ): CC [B ]^ { this , op}
333338
334339 /** Selects all elements of this $coll which satisfy a predicate.
335340 *
336341 * @param p the predicate used to test elements.
337342 * @return a new $coll consisting of all elements of this $coll that satisfy the given
338343 * predicate `p`. The order of the elements is preserved.
339344 */
340- def filter (p : A => Boolean ): C
345+ def filter (p : A => Boolean ): C ^ { this , p}
341346
342347 /** Selects all elements of this $coll which do not satisfy a predicate.
343348 *
344349 * @param pred the predicate used to test elements.
345350 * @return a new $coll consisting of all elements of this $coll that do not satisfy the given
346351 * predicate `pred`. Their order may not be preserved.
347352 */
348- def filterNot (pred : A => Boolean ): C
353+ def filterNot (p : A => Boolean ): C ^ { this , p}
349354
350355 /** Selects the first ''n'' elements.
351356 * $orderDependent
@@ -354,15 +359,15 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
354359 * or else the whole $coll, if it has less than `n` elements.
355360 * If `n` is negative, returns an empty $coll.
356361 */
357- def take (n : Int ): C
362+ def take (n : Int ): C ^ { this }
358363
359364 /** Takes longest prefix of elements that satisfy a predicate.
360365 * $orderDependent
361366 * @param p The predicate used to test elements.
362367 * @return the longest prefix of this $coll whose elements all satisfy
363368 * the predicate `p`.
364369 */
365- def takeWhile (p : A => Boolean ): C
370+ def takeWhile (p : A => Boolean ): C ^ { this , p}
366371
367372 /** Selects all elements except first ''n'' ones.
368373 * $orderDependent
@@ -371,15 +376,15 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
371376 * empty $coll, if this $coll has less than `n` elements.
372377 * If `n` is negative, don't drop any elements.
373378 */
374- def drop (n : Int ): C
379+ def drop (n : Int ): C ^ { this }
375380
376381 /** Drops longest prefix of elements that satisfy a predicate.
377382 * $orderDependent
378383 * @param p The predicate used to test elements.
379384 * @return the longest suffix of this $coll whose first element
380385 * does not satisfy the predicate `p`.
381386 */
382- def dropWhile (p : A => Boolean ): C
387+ def dropWhile (p : A => Boolean ): C ^ { this , p}
383388
384389 /** Selects an interval of elements. The returned $coll is made up
385390 * of all elements `x` which satisfy the invariant:
@@ -394,7 +399,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
394399 * index `from` extending up to (but not including) index `until`
395400 * of this $coll.
396401 */
397- def slice (from : Int , until : Int ): C
402+ def slice (from : Int , until : Int ): C ^ { this }
398403
399404 /** Builds a new $coll by applying a function to all elements of this $coll.
400405 *
@@ -403,7 +408,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
403408 * @return a new $coll resulting from applying the given function
404409 * `f` to each element of this $coll and collecting the results.
405410 */
406- def map [B ](f : A => B ): CC [B ]
411+ def map [B ](f : A => B ): CC [B ]^ { this , f}
407412
408413 /** Builds a new $coll by applying a function to all elements of this $coll
409414 * and using the elements of the resulting collections.
@@ -436,7 +441,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
436441 * @return a new $coll resulting from applying the given collection-valued function
437442 * `f` to each element of this $coll and concatenating the results.
438443 */
439- def flatMap [B ](f : A => IterableOnce [B ]): CC [B ]
444+ def flatMap [B ](f : A => IterableOnce [B ]): CC [B ]^ { this , f}
440445
441446 /** Converts this $coll of iterable collections into
442447 * a $coll formed by the elements of these iterable
@@ -464,7 +469,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
464469 * type of this $coll is an `Iterable`.
465470 * @return a new $coll resulting from concatenating all element ${coll}s.
466471 */
467- def flatten [B ](implicit asIterable : A = > IterableOnce [B ]): CC [B ]
472+ def flatten [B ](implicit asIterable : A - > IterableOnce [B ]): CC [B ]^ { this }
468473
469474 /** Builds a new $coll by applying a partial function to all elements of this $coll
470475 * on which the function is defined.
@@ -475,7 +480,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
475480 * `pf` to each element on which it is defined and collecting the results.
476481 * The order of the elements is preserved.
477482 */
478- def collect [B ](pf : PartialFunction [A , B ]): CC [B ]
483+ def collect [B ](pf : PartialFunction [A , B ]^ ): CC [B ]^ { this , pf}
479484
480485 /** Zips this $coll with its indices.
481486 *
@@ -484,7 +489,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
484489 * @example
485490 * `List("a", "b", "c").zipWithIndex == List(("a", 0), ("b", 1), ("c", 2))`
486491 */
487- def zipWithIndex : CC [(A @ uncheckedVariance, Int )]
492+ def zipWithIndex : CC [(A @ uncheckedVariance, Int )]^ { this }
488493
489494 /** Splits this $coll into a prefix/suffix pair according to a predicate.
490495 *
@@ -497,7 +502,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
497502 * @return a pair consisting of the longest prefix of this $coll whose
498503 * elements all satisfy `p`, and the rest of this $coll.
499504 */
500- def span (p : A => Boolean ): (C , C )
505+ def span (p : A => Boolean ): (C ^ { this , p}, C ^ { this , p} )
501506
502507 /** Splits this $coll into a prefix/suffix pair at a given position.
503508 *
@@ -509,7 +514,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
509514 * @return a pair of ${coll}s consisting of the first `n`
510515 * elements of this $coll, and the other elements.
511516 */
512- def splitAt (n : Int ): (C , C ) = {
517+ def splitAt (n : Int ): (C ^ { this } , C ^ { this } ) = {
513518 class Spanner extends runtime.AbstractFunction1 [A , Boolean ] {
514519 var i = 0
515520 def apply (a : A ) = i < n && { i += 1 ; true }
@@ -527,7 +532,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
527532 * @tparam U the return type of f
528533 * @return The same logical collection as this
529534 */
530- def tapEach [U ](f : A => U ): C
535+ def tapEach [U ](f : A => U ): C ^ { this , f}
531536
532537 // ///////////////////////////////////////////////////////////// Concrete methods based on iterator
533538
@@ -802,7 +807,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
802807 case _ => Some (reduceLeft(op))
803808 }
804809 private final def reduceLeftOptionIterator [B >: A ](op : (B , A ) => B ): Option [B ] = reduceOptionIterator[A , B ](iterator)(op)
805- private final def reduceOptionIterator [X >: A , B >: X ](it : Iterator [X ])(op : (B , X ) => B ): Option [B ] = {
810+ private final def reduceOptionIterator [X >: A , B >: X ](it : Iterator [X ]^ )(op : (B , X ) => B ): Option [B ] = {
806811 if (it.hasNext) {
807812 var acc : B = it.next()
808813 while (it.hasNext)
@@ -1041,35 +1046,12 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
10411046 * @return the first element of this $coll with the largest value measured by function f
10421047 * with respect to the ordering `cmp`.
10431048 */
1044- def maxBy [B ](f : A = > B )(implicit ord : Ordering [B ]): A =
1049+ def maxBy [B ](f : A - > B )(implicit ord : Ordering [B ]): A =
10451050 knownSize match {
10461051 case 0 => throw new UnsupportedOperationException (" empty.maxBy" )
10471052 case _ => foldLeft(new Maximized [A , B ](" maxBy" )(f)(ord.gt))((m, a) => m(m, a)).result
10481053 }
10491054
1050- private class Maximized [X , B ](descriptor : String )(f : X => B )(cmp : (B , B ) => Boolean ) extends AbstractFunction2 [Maximized [X , B ], X , Maximized [X , B ]] {
1051- var maxElem : X = null .asInstanceOf [X ]
1052- var maxF : B = null .asInstanceOf [B ]
1053- var nonEmpty = false
1054- def toOption : Option [X ] = if (nonEmpty) Some (maxElem) else None
1055- def result : X = if (nonEmpty) maxElem else throw new UnsupportedOperationException (s " empty. $descriptor" )
1056- def apply (m : Maximized [X , B ], a : X ): Maximized [X , B ] =
1057- if (m.nonEmpty) {
1058- val fa = f(a)
1059- if (cmp(fa, maxF)) {
1060- maxF = fa
1061- maxElem = a
1062- }
1063- m
1064- }
1065- else {
1066- m.nonEmpty = true
1067- m.maxElem = a
1068- m.maxF = f(a)
1069- m
1070- }
1071- }
1072-
10731055 /** Finds the first element which yields the largest value measured by function f.
10741056 *
10751057 * $willNotTerminateInf
@@ -1080,7 +1062,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
10801062 * @return an option value containing the first element of this $coll with the
10811063 * largest value measured by function f with respect to the ordering `cmp`.
10821064 */
1083- def maxByOption [B ](f : A = > B )(implicit ord : Ordering [B ]): Option [A ] =
1065+ def maxByOption [B ](f : A - > B )(implicit ord : Ordering [B ]): Option [A ] =
10841066 knownSize match {
10851067 case 0 => None
10861068 case _ => foldLeft(new Maximized [A , B ](" maxBy" )(f)(ord.gt))((m, a) => m(m, a)).toOption
@@ -1097,7 +1079,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
10971079 * @return the first element of this $coll with the smallest value measured by function f
10981080 * with respect to the ordering `cmp`.
10991081 */
1100- def minBy [B ](f : A = > B )(implicit ord : Ordering [B ]): A =
1082+ def minBy [B ](f : A - > B )(implicit ord : Ordering [B ]): A =
11011083 knownSize match {
11021084 case 0 => throw new UnsupportedOperationException (" empty.minBy" )
11031085 case _ => foldLeft(new Maximized [A , B ](" minBy" )(f)(ord.lt))((m, a) => m(m, a)).result
@@ -1114,7 +1096,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
11141096 * with the smallest value measured by function f
11151097 * with respect to the ordering `cmp`.
11161098 */
1117- def minByOption [B ](f : A = > B )(implicit ord : Ordering [B ]): Option [A ] =
1099+ def minByOption [B ](f : A - > B )(implicit ord : Ordering [B ]): Option [A ] =
11181100 knownSize match {
11191101 case 0 => None
11201102 case _ => foldLeft(new Maximized [A , B ](" minBy" )(f)(ord.lt))((m, a) => m(m, a)).toOption
@@ -1310,7 +1292,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
13101292 def to [C1 ](factory : Factory [A , C1 ]): C1 = factory.fromSpecific(this )
13111293
13121294 @ deprecated(" Use .iterator instead of .toIterator" , " 2.13.0" )
1313- @ `inline` final def toIterator : Iterator [A ] = iterator
1295+ @ `inline` final def toIterator : Iterator [A ]^ { this } = iterator
13141296
13151297 def toList : immutable.List [A ] = immutable.List .from(this )
13161298
@@ -1352,3 +1334,31 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
13521334 xs
13531335 }
13541336}
1337+
1338+ object IterableOnceOps :
1339+
1340+ // Moved out of trait IterableOnceOps to here, since universal traits cannot
1341+ // have nested classes in Scala 3
1342+ private class Maximized [X , B ](descriptor : String )(f : X -> B )(cmp : (B , B ) -> Boolean ) extends AbstractFunction2 [Maximized [X , B ], X , Maximized [X , B ]] {
1343+ var maxElem : X = null .asInstanceOf [X ]
1344+ var maxF : B = null .asInstanceOf [B ]
1345+ var nonEmpty = false
1346+ def toOption : Option [X ] = if (nonEmpty) Some (maxElem) else None
1347+ def result : X = if (nonEmpty) maxElem else throw new UnsupportedOperationException (s " empty. $descriptor" )
1348+ def apply (m : Maximized [X , B ], a : X ): Maximized [X , B ] =
1349+ if (m.nonEmpty) {
1350+ val fa = f(a)
1351+ if (cmp(fa, maxF)) {
1352+ maxF = fa
1353+ maxElem = a
1354+ }
1355+ m
1356+ }
1357+ else {
1358+ m.nonEmpty = true
1359+ m.maxElem = a
1360+ m.maxF = f(a)
1361+ m
1362+ }
1363+ }
1364+ end IterableOnceOps
0 commit comments