@@ -116,14 +116,17 @@ object CollectionStrawMan6 extends LowPriority {
116
116
trait Iterable [+ A ] extends IterableOnce [A ] with IterableLike [A , Iterable ] {
117
117
/** The collection itself */
118
118
protected def coll : this .type = this
119
- }
119
+ }
120
120
121
- /** Base trait for sequence collections */
122
- trait Seq [+ A ] extends Iterable [A ] with SeqLike [A , Seq ] {
123
- def apply (i : Int ): A
121
+ /** A trait representing indexable collections with finite length */
122
+ trait ArrayLike [+ A ] extends Any {
124
123
def length : Int
124
+ def apply (i : Int ): A
125
125
}
126
126
127
+ /** Base trait for sequence collections */
128
+ trait Seq [+ A ] extends Iterable [A ] with SeqLike [A , Seq ] with ArrayLike [A ]
129
+
127
130
/** Base trait for linearly accessed sequences that have efficient `head` and
128
131
* `tail` operations.
129
132
* Known subclasses: List, LazyList
@@ -156,6 +159,8 @@ object CollectionStrawMan6 extends LowPriority {
156
159
}
157
160
}
158
161
162
+ type IndexedSeq [+ A ] = Seq [A ] { def view : IndexedView [A ] }
163
+
159
164
/** Base trait for strict collections that can be built using a builder.
160
165
* @param A the element type of the collection
161
166
* @param Repr the type of the underlying collection
@@ -593,6 +598,7 @@ object CollectionStrawMan6 extends LowPriority {
593
598
}
594
599
595
600
class ArrayBufferView [A ](val elems : Array [AnyRef ], val start : Int , val end : Int ) extends IndexedView [A ] {
601
+ def length = end - start
596
602
def apply (n : Int ) = elems(start + n).asInstanceOf [A ]
597
603
override def className = " ArrayBufferView"
598
604
}
@@ -656,7 +662,8 @@ object CollectionStrawMan6 extends LowPriority {
656
662
extends AnyVal with IterableOps [Char ]
657
663
with SeqMonoTransforms [Char , String ]
658
664
with IterablePolyTransforms [Char , List ]
659
- with Buildable [Char , String ] {
665
+ with Buildable [Char , String ]
666
+ with ArrayLike [Char ] {
660
667
661
668
protected def coll = new StringView (s)
662
669
def iterator = coll.iterator
@@ -671,6 +678,9 @@ object CollectionStrawMan6 extends LowPriority {
671
678
672
679
protected [this ] def newBuilder = new StringBuilder
673
680
681
+ def length = s.length
682
+ def apply (i : Int ) = s.charAt(i)
683
+
674
684
override def knownSize = s.length
675
685
676
686
override def className = " String"
@@ -720,8 +730,7 @@ object CollectionStrawMan6 extends LowPriority {
720
730
}
721
731
722
732
case class StringView (s : String ) extends IndexedView [Char ] {
723
- val start = 0
724
- val end = s.length
733
+ def length = s.length
725
734
def apply (n : Int ) = s.charAt(n)
726
735
override def className = " StringView"
727
736
}
@@ -731,11 +740,15 @@ object CollectionStrawMan6 extends LowPriority {
731
740
implicit class ArrayOps [A ](val xs : Array [A ])
732
741
extends AnyVal with IterableOps [A ]
733
742
with SeqMonoTransforms [A , Array [A ]]
734
- with Buildable [A , Array [A ]] {
743
+ with Buildable [A , Array [A ]]
744
+ with ArrayLike [A ] {
735
745
736
746
protected def coll = new ArrayView (xs)
737
747
def iterator = coll.iterator
738
748
749
+ def length = xs.length
750
+ def apply (i : Int ) = xs.apply(i)
751
+
739
752
override def view = new ArrayView (xs)
740
753
741
754
def elemTag : ClassTag [A ] = ClassTag (xs.getClass.getComponentType)
@@ -757,8 +770,7 @@ object CollectionStrawMan6 extends LowPriority {
757
770
}
758
771
759
772
case class ArrayView [A ](xs : Array [A ]) extends IndexedView [A ] {
760
- val start = 0
761
- val end = xs.length
773
+ def length = xs.length
762
774
def apply (n : Int ) = xs(n)
763
775
override def className = " ArrayView"
764
776
}
@@ -822,15 +834,17 @@ object CollectionStrawMan6 extends LowPriority {
822
834
/** A view that drops leading elements of the underlying collection. */
823
835
case class Drop [A ](underlying : Iterable [A ], n : Int ) extends View [A ] {
824
836
def iterator = underlying.iterator.drop(n)
837
+ protected val normN = n max 0
825
838
override def knownSize =
826
- if (underlying.knownSize >= 0 ) underlying.knownSize - n max 0 else - 1
839
+ if (underlying.knownSize >= 0 ) ( underlying.knownSize - normN) max 0 else - 1
827
840
}
828
841
829
842
/** A view that takes leading elements of the underlying collection. */
830
843
case class Take [A ](underlying : Iterable [A ], n : Int ) extends View [A ] {
831
844
def iterator = underlying.iterator.take(n)
845
+ protected val normN = n max 0
832
846
override def knownSize =
833
- if (underlying.knownSize >= 0 ) underlying.knownSize min n else - 1
847
+ if (underlying.knownSize >= 0 ) underlying.knownSize min normN else - 1
834
848
}
835
849
836
850
/** A view that maps elements of the underlying collection. */
@@ -872,29 +886,51 @@ object CollectionStrawMan6 extends LowPriority {
872
886
}
873
887
874
888
/** View defined in terms of indexing a range */
875
- trait IndexedView [+ A ] extends View [A ] { self =>
876
- def start : Int
877
- def end : Int
878
- def apply (i : Int ): A
889
+ trait IndexedView [+ A ] extends View [A ] with ArrayLike [A ] {
879
890
880
891
def iterator : Iterator [A ] = new Iterator [A ] {
881
- private var current = start
882
- def hasNext = current < end
892
+ private var current = 0
893
+ def hasNext = current < length
883
894
def next : A = {
884
895
val r = apply(current)
885
896
current += 1
886
897
r
887
898
}
888
899
}
889
900
890
- def reverse = new IndexedView [A ] {
891
- def start = self.start
892
- def end = self.end
893
- def apply (i : Int ) = self.apply(end - 1 - i)
901
+ override def take (n : Int ): IndexedView [A ] = new IndexedView .Take (this , n)
902
+ override def drop (n : Int ): IndexedView [A ] = new IndexedView .Drop (this , n)
903
+ override def map [B ](f : A => B ): IndexedView [B ] = new IndexedView .Map (this , f)
904
+ def reverse : IndexedView [A ] = new IndexedView .Reverse (this )
905
+ }
906
+
907
+ object IndexedView {
908
+
909
+ class Take [A ](underlying : IndexedView [A ], n : Int )
910
+ extends View .Take (underlying, n) with IndexedView [A ] {
911
+ override def iterator = super .iterator
912
+ def length = underlying.length min normN
913
+ def apply (i : Int ) = underlying.apply(i)
894
914
}
895
915
896
- def length = end - start max 0
897
- override def knownSize = length
916
+ class Drop [A ](underlying : IndexedView [A ], n : Int )
917
+ extends View .Take (underlying, n) with IndexedView [A ] {
918
+ override def iterator = super .iterator
919
+ def length = (underlying.length - normN) max 0
920
+ def apply (i : Int ) = underlying.apply(i + normN)
921
+ }
922
+
923
+ class Map [A , B ](underlying : IndexedView [A ], f : A => B )
924
+ extends View .Map (underlying, f) with IndexedView [B ] {
925
+ override def iterator = super .iterator
926
+ def length = underlying.length
927
+ def apply (n : Int ) = f(underlying.apply(n))
928
+ }
929
+
930
+ case class Reverse [A ](underlying : IndexedView [A ]) extends IndexedView [A ] {
931
+ def length = underlying.length
932
+ def apply (i : Int ) = underlying.apply(length - 1 - i)
933
+ }
898
934
}
899
935
900
936
/* ---------- Iterators ---------------------------------------------------*/
@@ -1002,8 +1038,7 @@ object CollectionStrawMan6 extends LowPriority {
1002
1038
def next = throw new NoSuchElementException (" next on empty iterator" )
1003
1039
}
1004
1040
def apply [A ](xs : A * ): Iterator [A ] = new IndexedView [A ] {
1005
- val start = 0
1006
- val end = xs.length
1041
+ val length = xs.length
1007
1042
def apply (n : Int ) = xs(n)
1008
1043
}.iterator
1009
1044
}
0 commit comments