@@ -20,6 +20,7 @@ import scala.language.implicitConversions
20
20
import scala .math .{Numeric , Ordering }
21
21
import scala .reflect .ClassTag
22
22
import scala .runtime .AbstractFunction2
23
+ import language .experimental .captureChecking
23
24
24
25
/**
25
26
* A template trait for collections which can be traversed either once only
@@ -42,8 +43,10 @@ import scala.runtime.AbstractFunction2
42
43
* @define coll collection
43
44
*/
44
45
trait IterableOnce [+ A ] extends Any {
46
+ this : IterableOnce [A ]^ =>
47
+
45
48
/** Iterator can be used only once */
46
- def iterator : Iterator [A ]
49
+ def iterator : Iterator [A ]^ { this }
47
50
48
51
/** Returns a [[scala.collection.Stepper ]] for the elements of this collection.
49
52
*
@@ -65,9 +68,9 @@ trait IterableOnce[+A] extends Any {
65
68
* allow creating parallel streams, whereas bare Steppers can be converted only to sequential
66
69
* streams.
67
70
*/
68
- def stepper [S <: Stepper [_]](implicit shape : StepperShape [A , S ]): S = {
71
+ def stepper [S <: Stepper [_]^ { this } ](implicit shape : StepperShape [A , S ]): S = {
69
72
import convert .impl ._
70
- val s = shape.shape match {
73
+ val s : Any = shape.shape match {
71
74
case StepperShape .IntShape => new IntIteratorStepper (iterator.asInstanceOf [Iterator [Int ]])
72
75
case StepperShape .LongShape => new LongIteratorStepper (iterator.asInstanceOf [Iterator [Long ]])
73
76
case StepperShape .DoubleShape => new DoubleIteratorStepper (iterator.asInstanceOf [Iterator [Double ]])
@@ -84,7 +87,7 @@ trait IterableOnce[+A] extends Any {
84
87
85
88
final class IterableOnceExtensionMethods [A ](private val it : IterableOnce [A ]) extends AnyVal {
86
89
@ 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)
88
91
89
92
@ deprecated(" Use .iterator.reduceLeftOption(...) instead" , " 2.13.0" )
90
93
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
102
105
def reduceRight (f : (A , A ) => A ): A = it.iterator.reduceRight(f)
103
106
104
107
@ 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)
106
109
107
110
@ deprecated(" Use .iterator.reduceLeft(...) instead" , " 2.13.0" )
108
111
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
120
123
def reduceOption (f : (A , A ) => A ): Option [A ] = it.iterator.reduceOption(f)
121
124
122
125
@ 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)
124
127
125
128
@ deprecated(" Use .iterator.size instead" , " 2.13.0" )
126
129
def size : Int = it.iterator.size
@@ -132,7 +135,7 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
132
135
def collectFirst [B ](f : PartialFunction [A , B ]): Option [B ] = it.iterator.collectFirst(f)
133
136
134
137
@ 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)
136
139
137
140
@ deprecated(" Use .iterator.exists(...) instead" , " 2.13.0" )
138
141
def exists (f : A => Boolean ): Boolean = it.iterator.exists(f)
@@ -238,13 +241,13 @@ final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) ext
238
241
@ `inline` def : \ [B ](z : B )(op : (A , B ) => B ): B = foldRight[B ](z)(op)
239
242
240
243
@ 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 {
242
245
case it : Iterable [A ] => it.map(f)
243
246
case _ => it.iterator.map(f)
244
247
}
245
248
246
249
@ 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 {
248
251
case it : Iterable [A ] => it.flatMap(f)
249
252
case _ => it.iterator.flatMap(f)
250
253
}
@@ -315,9 +318,11 @@ object IterableOnce {
315
318
* @define coll collection
316
319
*
317
320
*/
318
- trait IterableOnceOps [+ A , + CC [_], + C ] extends Any { this : IterableOnce [A ] =>
321
+ trait IterableOnceOps [+ A , + CC [_], + C ] extends Any { this : IterableOnce [A ]^ =>
319
322
// ///////////////////////////////////////////////////////////// Abstract methods that must be implemented
320
323
324
+ import IterableOnceOps .Maximized
325
+
321
326
/** Produces a $coll containing cumulative results of applying the
322
327
* operator going left to right, including the initial value.
323
328
*
@@ -329,23 +334,23 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
329
334
* @param op the binary operator applied to the intermediate result and the element
330
335
* @return collection with intermediate results
331
336
*/
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}
333
338
334
339
/** Selects all elements of this $coll which satisfy a predicate.
335
340
*
336
341
* @param p the predicate used to test elements.
337
342
* @return a new $coll consisting of all elements of this $coll that satisfy the given
338
343
* predicate `p`. The order of the elements is preserved.
339
344
*/
340
- def filter (p : A => Boolean ): C
345
+ def filter (p : A => Boolean ): C ^ { this , p}
341
346
342
347
/** Selects all elements of this $coll which do not satisfy a predicate.
343
348
*
344
349
* @param pred the predicate used to test elements.
345
350
* @return a new $coll consisting of all elements of this $coll that do not satisfy the given
346
351
* predicate `pred`. Their order may not be preserved.
347
352
*/
348
- def filterNot (pred : A => Boolean ): C
353
+ def filterNot (p : A => Boolean ): C ^ { this , p}
349
354
350
355
/** Selects the first ''n'' elements.
351
356
* $orderDependent
@@ -354,15 +359,15 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
354
359
* or else the whole $coll, if it has less than `n` elements.
355
360
* If `n` is negative, returns an empty $coll.
356
361
*/
357
- def take (n : Int ): C
362
+ def take (n : Int ): C ^ { this }
358
363
359
364
/** Takes longest prefix of elements that satisfy a predicate.
360
365
* $orderDependent
361
366
* @param p The predicate used to test elements.
362
367
* @return the longest prefix of this $coll whose elements all satisfy
363
368
* the predicate `p`.
364
369
*/
365
- def takeWhile (p : A => Boolean ): C
370
+ def takeWhile (p : A => Boolean ): C ^ { this , p}
366
371
367
372
/** Selects all elements except first ''n'' ones.
368
373
* $orderDependent
@@ -371,15 +376,15 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
371
376
* empty $coll, if this $coll has less than `n` elements.
372
377
* If `n` is negative, don't drop any elements.
373
378
*/
374
- def drop (n : Int ): C
379
+ def drop (n : Int ): C ^ { this }
375
380
376
381
/** Drops longest prefix of elements that satisfy a predicate.
377
382
* $orderDependent
378
383
* @param p The predicate used to test elements.
379
384
* @return the longest suffix of this $coll whose first element
380
385
* does not satisfy the predicate `p`.
381
386
*/
382
- def dropWhile (p : A => Boolean ): C
387
+ def dropWhile (p : A => Boolean ): C ^ { this , p}
383
388
384
389
/** Selects an interval of elements. The returned $coll is made up
385
390
* of all elements `x` which satisfy the invariant:
@@ -394,7 +399,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
394
399
* index `from` extending up to (but not including) index `until`
395
400
* of this $coll.
396
401
*/
397
- def slice (from : Int , until : Int ): C
402
+ def slice (from : Int , until : Int ): C ^ { this }
398
403
399
404
/** Builds a new $coll by applying a function to all elements of this $coll.
400
405
*
@@ -403,7 +408,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
403
408
* @return a new $coll resulting from applying the given function
404
409
* `f` to each element of this $coll and collecting the results.
405
410
*/
406
- def map [B ](f : A => B ): CC [B ]
411
+ def map [B ](f : A => B ): CC [B ]^ { this , f}
407
412
408
413
/** Builds a new $coll by applying a function to all elements of this $coll
409
414
* and using the elements of the resulting collections.
@@ -436,7 +441,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
436
441
* @return a new $coll resulting from applying the given collection-valued function
437
442
* `f` to each element of this $coll and concatenating the results.
438
443
*/
439
- def flatMap [B ](f : A => IterableOnce [B ]): CC [B ]
444
+ def flatMap [B ](f : A => IterableOnce [B ]): CC [B ]^ { this , f}
440
445
441
446
/** Converts this $coll of iterable collections into
442
447
* a $coll formed by the elements of these iterable
@@ -464,7 +469,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
464
469
* type of this $coll is an `Iterable`.
465
470
* @return a new $coll resulting from concatenating all element ${coll}s.
466
471
*/
467
- def flatten [B ](implicit asIterable : A = > IterableOnce [B ]): CC [B ]
472
+ def flatten [B ](implicit asIterable : A - > IterableOnce [B ]): CC [B ]^ { this }
468
473
469
474
/** Builds a new $coll by applying a partial function to all elements of this $coll
470
475
* on which the function is defined.
@@ -475,7 +480,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
475
480
* `pf` to each element on which it is defined and collecting the results.
476
481
* The order of the elements is preserved.
477
482
*/
478
- def collect [B ](pf : PartialFunction [A , B ]): CC [B ]
483
+ def collect [B ](pf : PartialFunction [A , B ]^ ): CC [B ]^ { this , pf}
479
484
480
485
/** Zips this $coll with its indices.
481
486
*
@@ -484,7 +489,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
484
489
* @example
485
490
* `List("a", "b", "c").zipWithIndex == List(("a", 0), ("b", 1), ("c", 2))`
486
491
*/
487
- def zipWithIndex : CC [(A @ uncheckedVariance, Int )]
492
+ def zipWithIndex : CC [(A @ uncheckedVariance, Int )]^ { this }
488
493
489
494
/** Splits this $coll into a prefix/suffix pair according to a predicate.
490
495
*
@@ -497,7 +502,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
497
502
* @return a pair consisting of the longest prefix of this $coll whose
498
503
* elements all satisfy `p`, and the rest of this $coll.
499
504
*/
500
- def span (p : A => Boolean ): (C , C )
505
+ def span (p : A => Boolean ): (C ^ { this , p}, C ^ { this , p} )
501
506
502
507
/** Splits this $coll into a prefix/suffix pair at a given position.
503
508
*
@@ -509,7 +514,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
509
514
* @return a pair of ${coll}s consisting of the first `n`
510
515
* elements of this $coll, and the other elements.
511
516
*/
512
- def splitAt (n : Int ): (C , C ) = {
517
+ def splitAt (n : Int ): (C ^ { this } , C ^ { this } ) = {
513
518
class Spanner extends runtime.AbstractFunction1 [A , Boolean ] {
514
519
var i = 0
515
520
def apply (a : A ) = i < n && { i += 1 ; true }
@@ -527,7 +532,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
527
532
* @tparam U the return type of f
528
533
* @return The same logical collection as this
529
534
*/
530
- def tapEach [U ](f : A => U ): C
535
+ def tapEach [U ](f : A => U ): C ^ { this , f}
531
536
532
537
// ///////////////////////////////////////////////////////////// Concrete methods based on iterator
533
538
@@ -802,7 +807,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
802
807
case _ => Some (reduceLeft(op))
803
808
}
804
809
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 ] = {
806
811
if (it.hasNext) {
807
812
var acc : B = it.next()
808
813
while (it.hasNext)
@@ -1041,35 +1046,12 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
1041
1046
* @return the first element of this $coll with the largest value measured by function f
1042
1047
* with respect to the ordering `cmp`.
1043
1048
*/
1044
- def maxBy [B ](f : A = > B )(implicit ord : Ordering [B ]): A =
1049
+ def maxBy [B ](f : A - > B )(implicit ord : Ordering [B ]): A =
1045
1050
knownSize match {
1046
1051
case 0 => throw new UnsupportedOperationException (" empty.maxBy" )
1047
1052
case _ => foldLeft(new Maximized [A , B ](" maxBy" )(f)(ord.gt))((m, a) => m(m, a)).result
1048
1053
}
1049
1054
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
-
1073
1055
/** Finds the first element which yields the largest value measured by function f.
1074
1056
*
1075
1057
* $willNotTerminateInf
@@ -1080,7 +1062,7 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
1080
1062
* @return an option value containing the first element of this $coll with the
1081
1063
* largest value measured by function f with respect to the ordering `cmp`.
1082
1064
*/
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 ] =
1084
1066
knownSize match {
1085
1067
case 0 => None
1086
1068
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] =>
1097
1079
* @return the first element of this $coll with the smallest value measured by function f
1098
1080
* with respect to the ordering `cmp`.
1099
1081
*/
1100
- def minBy [B ](f : A = > B )(implicit ord : Ordering [B ]): A =
1082
+ def minBy [B ](f : A - > B )(implicit ord : Ordering [B ]): A =
1101
1083
knownSize match {
1102
1084
case 0 => throw new UnsupportedOperationException (" empty.minBy" )
1103
1085
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] =>
1114
1096
* with the smallest value measured by function f
1115
1097
* with respect to the ordering `cmp`.
1116
1098
*/
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 ] =
1118
1100
knownSize match {
1119
1101
case 0 => None
1120
1102
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] =>
1310
1292
def to [C1 ](factory : Factory [A , C1 ]): C1 = factory.fromSpecific(this )
1311
1293
1312
1294
@ 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
1314
1296
1315
1297
def toList : immutable.List [A ] = immutable.List .from(this )
1316
1298
@@ -1352,3 +1334,31 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
1352
1334
xs
1353
1335
}
1354
1336
}
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