@@ -2,7 +2,6 @@ package strawman.collections
22
33import Predef .{augmentString => _ , wrapString => _ , _ }
44import scala .reflect .ClassTag
5- import collection .mutable .ListBuffer
65
76/** A strawman architecture for new collections. It contains some
87 * example collection classes and methods with the intent to expose
@@ -36,11 +35,11 @@ object CollectionStrawMan1 {
3635 }
3736
3837 /** Base trait for generic collections */
39- trait Iterable [+ IA ] extends HasIterator [IA ] with FromIterator [Iterable ]
38+ trait Iterable [+ A ] extends HasIterator [A ] with FromIterator [Iterable ]
4039
4140 /** Base trait for sequence collections */
42- trait Seq [+ AA ] extends Iterable [AA ] with FromIterator [Seq ] {
43- def apply (i : Int ): AA
41+ trait Seq [+ A ] extends Iterable [A ] with FromIterator [Seq ] {
42+ def apply (i : Int ): A
4443 def length : Int
4544 }
4645
@@ -53,6 +52,7 @@ object CollectionStrawMan1 {
5352 def foldLeft [B ](z : B )(op : (B , A ) => B ): B = iterator.foldLeft(z)(op)
5453 def foldRight [B ](z : B )(op : (A , B ) => B ): B = iterator.foldRight(z)(op)
5554 def indexWhere (p : A => Boolean ): Int = iterator.indexWhere(p)
55+ def isEmpty : Boolean = ! iterator.hasNext
5656 def head : A = iterator.next
5757 def view : View [A ] = new View (iterator)
5858 def collect [C [X ] <: Iterable [X ]](fi : FromIterator [C ]): C [A ] = fi.fromIterator(iterator)
@@ -134,7 +134,13 @@ object CollectionStrawMan1 {
134134 def tail = xs
135135 }
136136
137- case object List extends IterableFactory [List ] {
137+ case object Nil extends List [Nothing ] {
138+ def isEmpty = true
139+ def head = ???
140+ def tail = ???
141+ }
142+
143+ object List extends IterableFactory [List ] {
138144 def fromIterator [B ](it : Iterator [B ]): List [B ] = it match {
139145 case it : ListIterator [B ] => it.toList
140146 case _ => if (it.hasNext) Cons (it.next, fromIterator(it)) else Nil
@@ -148,50 +154,62 @@ object CollectionStrawMan1 {
148154 def toList = current
149155 }
150156
151- case object Nil extends List [Nothing ] {
152- def isEmpty = true
153- def head = ???
154- def tail = ???
155- }
156-
157157 /** Concrete collection type: ArrayBuffer */
158- class ArrayBuffer [A ] private (initElems : Array [AnyRef ], initLen : Int = 0 ) extends Seq [A ] with FromIterator [ArrayBuffer ] {
159- def this () = this (new Array [AnyRef ](16 ))
158+ class ArrayBuffer [A ] private (initElems : Array [AnyRef ], initLength : Int ) extends Seq [A ] with FromIterator [ArrayBuffer ] {
159+ def this () = this (new Array [AnyRef ](16 ), 0 )
160160 private var elems : Array [AnyRef ] = initElems
161- private var len = 0
162- def apply (i : Int ) = elems(i).asInstanceOf [A ]
163- def length = len
164- def iterator = new RandomAccessIterator [A ] {
165- override val knownLength = len
166- def apply (n : Int ) = elems(n).asInstanceOf [A ]
167- }
161+ private var start = 0
162+ private var limit = initLength
163+ def apply (i : Int ) = elems(start + i).asInstanceOf [A ]
164+ def length = limit - start
165+ def iterator = new ArrayBufferIterator [A ](elems, start, length)
168166 def fromIterator [B ](it : Iterator [B ]): ArrayBuffer [B ] =
169167 ArrayBuffer .fromIterator(it)
170168 def += (elem : A ): this .type = {
171- if (len == elems.length) {
172- val newelems = new Array [AnyRef ](len * 2 )
173- Array .copy(elems, 0 , newelems, 0 , len)
174- elems = newelems
169+ if (limit == elems.length) {
170+ if (start > 0 ) {
171+ Array .copy(elems, start, elems, 0 , length)
172+ limit -= start
173+ start = 0
174+ }
175+ else {
176+ val newelems = new Array [AnyRef ](limit * 2 )
177+ Array .copy(elems, 0 , newelems, 0 , limit)
178+ elems = newelems
179+ }
175180 }
176- elems(len ) = elem.asInstanceOf [AnyRef ]
177- len += 1
181+ elems(limit ) = elem.asInstanceOf [AnyRef ]
182+ limit += 1
178183 this
179184 }
180- override def toString = elems.take(len).deep.toString
185+ def trimStart (n : Int ): Unit = start += (n max 0 )
186+ override def toString = s " ArrayBuffer( ${elems.slice(start, limit).mkString(" , " )}) "
181187 }
182188
183189 object ArrayBuffer extends IterableFactory [ArrayBuffer ] {
184- def fromIterator [B ](it : Iterator [B ]): ArrayBuffer [B ] =
185- if (it.knownLength == 0 ) {
186- val elems = new Array [AnyRef ](it.knownLength)
190+ def fromIterator [B ](it : Iterator [B ]): ArrayBuffer [B ] = it match {
191+ case Iterator .Concat (fst : ArrayBufferIterator [_], snd : ArrayBufferIterator [_]) =>
192+ val elems = new Array [AnyRef ](fst.remaining + snd.remaining)
193+ Array .copy(fst.elems, fst.start, elems, 0 , fst.remaining)
194+ Array .copy(snd.elems, snd.start, elems, fst.remaining, snd.remaining)
195+ new ArrayBuffer (elems, elems.length)
196+ case it @ Iterator .Partition (underlying, _, buf, _) =>
197+ while (underlying.hasNext) it.distribute()
198+ buf.asInstanceOf [ArrayBuffer [B ]]
199+ case it if it.remaining >= 0 =>
200+ val elems = new Array [AnyRef ](it.remaining)
187201 for (i <- 0 until elems.length) elems(i) = it.next.asInstanceOf [AnyRef ]
188- new ArrayBuffer (elems)
189- }
190- else {
202+ new ArrayBuffer [B ](elems, elems.length)
203+ case _ =>
191204 val buf = new ArrayBuffer [B ]
192205 while (it.hasNext) buf += it.next
193206 buf
194- }
207+ }
208+ }
209+
210+ class ArrayBufferIterator [A ](val elems : Array [AnyRef ], initStart : Int , length : Int ) extends RandomAccessIterator [A ] {
211+ val limit = length
212+ def apply (n : Int ) = elems(initStart + n).asInstanceOf [A ]
195213 }
196214
197215 /** Concrete collection type: View */
@@ -219,7 +237,7 @@ object CollectionStrawMan1 {
219237 /** Concrete collection type: String */
220238 implicit class StringOps (val s : String ) extends AnyVal with Ops [Char ] {
221239 def iterator : Iterator [Char ] = new RandomAccessIterator [Char ] {
222- override val knownLength = s.length
240+ override val limit = s.length
223241 def apply (n : Int ) = s.charAt(n)
224242 }
225243 }
@@ -281,7 +299,7 @@ object CollectionStrawMan1 {
281299 def flatMap [B ](f : A => CanIterate [B ]): Iterator [B ] = Iterator .FlatMap (this , f)
282300 def ++ [B >: A ](xs : CanIterate [B ]): Iterator [B ] = Iterator .Concat (this , xs.iterator)
283301 def partition (p : A => Boolean ): (Iterator [A ], Iterator [A ]) = {
284- val lookaheadTrue, lookaheadFalse = new ListBuffer [A ]
302+ val lookaheadTrue, lookaheadFalse = new ArrayBuffer [A ]
285303 (Iterator .Partition (this , p, lookaheadTrue, lookaheadFalse),
286304 Iterator .Partition [A ](this , ! p(_), lookaheadFalse, lookaheadTrue))
287305 }
@@ -292,26 +310,34 @@ object CollectionStrawMan1 {
292310 while (hasNext) elems = Cons (next, elems)
293311 elems.iterator
294312 }
313+
314+ /** If this iterator results from applying a transfomation to another iterator,
315+ * that other iterator, otherwise the iterator itself.
316+ */
295317 def underlying : Iterator [_] = this
296- def knownLength = - 1
318+
319+ /** If the number of elements still to be returned by this iterator is known,
320+ * that number, otherwise -1.
321+ */
322+ def remaining = - 1
297323 }
298324
299325 object Iterator {
300326 val empty : Iterator [Nothing ] = new Iterator [Nothing ] {
301327 def hasNext = false
302328 def next = ???
303- override val knownLength = 0
329+ override def remaining = 0
304330 }
305331 def apply [A ](xs : A * ): Iterator [A ] = new RandomAccessIterator [A ] {
306- override val knownLength = xs.length
332+ override val limit = xs.length
307333 def apply (n : Int ) = xs(n)
308334 }
309335 def nextOnEmpty = throw new NoSuchElementException (" next on empty iterator" )
310336
311337 case class Map [A , B ](override val underlying : Iterator [A ], f : A => B ) extends Iterator [B ] {
312338 def hasNext = underlying.hasNext
313339 def next = f(underlying.next)
314- override val knownLength = underlying.knownLength
340+ override def remaining = underlying.remaining
315341 }
316342 case class FlatMap [A , B ](override val underlying : Iterator [A ], f : A => CanIterate [B ]) extends Iterator [B ] {
317343 private var myCurrent : Iterator [B ] = Iterator .empty
@@ -331,19 +357,18 @@ object CollectionStrawMan1 {
331357 }
332358 def hasNext = current.hasNext
333359 def next = current.next
334- override val knownLength =
335- if (underlying.knownLength > 0 && other.knownLength > 0 )
336- underlying.knownLength + other.knownLength
360+ override def remaining =
361+ if (underlying.remaining >= 0 && other.remaining >= 0 )
362+ underlying.remaining + other.remaining
337363 else - 1
338364 }
339- case class Partition [A ](override val underlying : Iterator [A ], p : A => Boolean , lookahead : ListBuffer [A ], dual : ListBuffer [A ]) extends Iterator [A ] {
365+ case class Partition [A ](override val underlying : Iterator [A ], p : A => Boolean , lookahead : ArrayBuffer [A ], dual : ArrayBuffer [A ]) extends Iterator [A ] {
366+ def distribute () = {
367+ val elem = underlying.next
368+ (if (p(elem)) lookahead else dual) += elem
369+ }
340370 final def hasNext : Boolean =
341- lookahead.nonEmpty ||
342- underlying.hasNext && {
343- val elem = underlying.next
344- (if (p(elem)) lookahead else dual) += elem
345- hasNext
346- }
371+ ! lookahead.isEmpty || underlying.hasNext && { distribute(); hasNext }
347372 final def next =
348373 if (hasNext) {
349374 val r = lookahead.head
@@ -356,27 +381,27 @@ object CollectionStrawMan1 {
356381 def hasNext : Boolean = underlying.hasNext && (
357382 toSkip == 0 || { underlying.next; toSkip -= 1 ; hasNext })
358383 def next = if (hasNext) underlying.next else nextOnEmpty
359- override val knownLength = (underlying.knownLength - n ) max - 1
384+ override def remaining = (underlying.remaining - toSkip ) max - 1
360385 }
361386 case class Zip [A , B ](override val underlying : Iterator [A ], other : Iterator [B ]) extends Iterator [(A , B )] {
362387 def hasNext = underlying.hasNext && other.hasNext
363388 def next = (underlying.next, other.next)
364- override val knownLength = underlying.knownLength min other.knownLength
389+ override def remaining = underlying.remaining min other.remaining
365390 }
366- class Reverse [A ](underlying : RandomAccessIterator [A ]) extends RandomAccessIterator [A ] {
367- override val knownLength = underlying.knownLength
368- def apply ( n : Int ) = underlying.apply(knownLength - 1 - n)
391+ case class Reverse [A ](override val underlying : RandomAccessIterator [A ]) extends RandomAccessIterator [A ] {
392+ def apply ( n : Int ) = underlying.apply(underlying.limit - 1 - n)
393+ def limit = underlying.remaining
369394 }
370395 }
371396
372397 trait RandomAccessIterator [+ A ] extends Iterator [A ] { self =>
373398 def apply (n : Int ): A
374- def knownLength : Int
375- def length : Int = knownLength
376- private var cur = 0
377- def hasNext = cur < knownLength
378- def next : A = { val r = this (cur ); cur += 1 ; r }
379- override def drop (n : Int ): Iterator [A ] = { cur += (n max 0 ); this }
399+ def limit : Int
400+ var start = 0
401+ override def remaining = (limit - start) max 0
402+ def hasNext = start < limit
403+ def next : A = { val r = this (start ); start += 1 ; r }
404+ override def drop (n : Int ): Iterator [A ] = { start += (n max 0 ); this }
380405 override def reverse : Iterator [A ] = new Iterator .Reverse (this )
381406 }
382407}
0 commit comments