2
2
** ________ ___ / / ___ Scala API **
3
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
3
** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
4
4
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5
5
** /____/\___/_/ |_/____/_/ | | **
9
package scala.collection
11
12
import mutable.ArrayBuffer
12
import annotation.migration
13
import scala.annotation.migration
13
14
import immutable.Stream
15
import scala.collection.generic.CanBuildFrom
16
import scala.annotation.unchecked.{ uncheckedVariance => uV }
15
18
/** The `Iterator` object provides various functions for creating specialized iterators.
27
/** With the advent of `TraversableOnce` and `Iterator`, it can be useful to have a builder which
28
* operates on `Iterator`s so they can be treated uniformly along with the collections.
29
* See `scala.util.Random.shuffle` for an example.
31
implicit def IteratorCanBuildFrom[A] = new TraversableOnce.BufferedCanBuildFrom[A, Iterator] {
32
def bufferToColl[B](coll: ArrayBuffer[B]) = coll.iterator
33
def traversableToColl[B](t: GenTraversable[B]) = t.toIterator
24
36
/** The iterator which produces no values. */
25
val empty = new Iterator[Nothing] {
37
val empty: Iterator[Nothing] = new AbstractIterator[Nothing] {
26
38
def hasNext: Boolean = false
27
39
def next(): Nothing = throw new NoSuchElementException("next on empty iterator")
145
157
* @param elem the element computation.
146
158
* @return the iterator containing an infinite number of results of evaluating `elem`.
148
def continually[A](elem: => A): Iterator[A] = new Iterator[A] {
160
def continually[A](elem: => A): Iterator[A] = new AbstractIterator[A] {
149
161
def hasNext = true
153
@deprecated("use `xs.iterator' or `Iterator(xs)' instead", "2.8.0")
154
def fromValues[a](xs: a*) = xs.iterator
156
/** @param xs the array of elements
157
* @see also: IndexedSeq.iterator and slice
159
@deprecated("use `xs.iterator' instead", "2.8.0")
160
def fromArray[a](xs: Array[a]): Iterator[a] =
161
fromArray(xs, 0, xs.length)
164
* @param xs the array of elements
165
* @param start the start index
166
* @param length the length
167
* @see also: IndexedSeq.iterator and slice
169
@deprecated("use `xs.slice(start, start + length).iterator' instead", "2.8.0")
170
def fromArray[a](xs: Array[a], start: Int, length: Int): Iterator[a] =
171
xs.slice(start, start + length).iterator
174
* @param n the product arity
175
* @return the iterator on `Product<n>`.
177
@deprecated("use product.productIterator instead", "2.8.0")
178
def fromProduct(n: Product): Iterator[Any] = new Iterator[Any] {
179
private var c: Int = 0
180
private val cmax = n.productArity
181
def hasNext = c < cmax
182
def next() = { val a = n productElement c; c += 1; a }
185
/** Create an iterator with elements
186
* `e<sub>n+1</sub> = step(e<sub>n</sub>)`
187
* where `e<sub>0</sub> = start`
188
* and elements are in the range between `start` (inclusive)
189
* and `end` (exclusive)
191
* @param start the start value of the iterator
192
* @param end the end value of the iterator
193
* @param step the increment function of the iterator, must be monotonically increasing or decreasing
194
* @return the iterator with values in range `[start;end)`.
196
@deprecated("use Iterator.iterate(start, end - start)(step) instead", "2.8.0")
197
def range(start: Int, end: Int, step: Int => Int) = new Iterator[Int] {
198
private val up = step(start) > start
199
private val down = step(start) < start
200
private var i = start
201
def hasNext: Boolean = (!up || i < end) && (!down || i > end)
203
if (hasNext) { val j = i; i = step(i); j }
207
/** Create an iterator with elements
208
* `e<sub>n+1</sub> = step(e<sub>n</sub>)`
209
* where `e<sub>0</sub> = start`.
211
* @param start the start value of the iterator
212
* @param step the increment function of the iterator
213
* @return the iterator starting at value `start`.
215
@deprecated("use iterate(start)(step) instead", "2.8.0")
216
def from(start: Int, step: Int => Int): Iterator[Int] = new Iterator[Int] {
217
private var i = start
218
override def hasNext: Boolean = true
219
def next(): Int = { val j = i; i = step(i); j }
222
/** Create an iterator that is the concatenation of all iterators
223
* returned by a given iterator of iterators.
224
* @param its The iterator which returns on each call to next
225
* a new iterator whose elements are to be concatenated to the result.
227
@deprecated("use its.flatten instead", "2.8.0")
228
def flatten[T](its: Iterator[Iterator[T]]): Iterator[T] = new Iterator[T] {
229
private var cur = its.next
230
def hasNext: Boolean = {
231
while (!cur.hasNext && its.hasNext) cur = its.next
235
(if (hasNext) cur else empty).next()
239
166
import Iterator.empty
407
334
* @return a new iterator that first yields the values produced by this
408
335
* iterator followed by the values produced by iterator `that`.
409
336
* @note Reuse: $consumesTwoAndProducesOneIterator
410
338
* @usecase def ++(that: => Iterator[A]): Iterator[A]
412
def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new Iterator[B] {
341
def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new AbstractIterator[B] {
413
342
// optimize a little bit to prevent n log n behavior.
414
343
private var cur : Iterator[B] = self
344
private var selfExhausted : Boolean = false
415
345
// since that is by-name, make sure it's only referenced once -
416
346
// if "val it = that" is inside the block, then hasNext on an empty
417
347
// iterator will continually reevaluate it. (ticket #3269)
418
348
lazy val it = that.toIterator
419
349
// the eq check is to avoid an infinite loop on "x ++ x"
420
def hasNext = cur.hasNext || ((cur eq self) && {
350
def hasNext = cur.hasNext || (!selfExhausted && {
464
395
def next() = if (hasNext) { hdDefined = false; hd } else empty.next()
398
/** Tests whether every element of this iterator relates to the
399
* corresponding element of another collection by satisfying a test predicate.
401
* @param that the other collection
402
* @param p the test predicate, which relates elements from both collections
403
* @tparam B the type of the elements of `that`
404
* @return `true` if both collections have the same length and
405
* `p(x, y)` is `true` for all corresponding elements `x` of this iterator
406
* and `y` of `that`, otherwise `false`
408
def corresponds[B](that: GenTraversableOnce[B])(p: (A, B) => Boolean): Boolean = {
409
val that0 = that.toIterator
410
while (hasNext && that0.hasNext)
411
if (!p(next, that0.next)) return false
413
hasNext == that0.hasNext
467
416
/** Creates an iterator over all the elements of this iterator that
468
417
* satisfy the predicate `p`. The order of the elements
743
694
* If this iterator is shorter than `that`, `thisElem` values are used to pad the result.
744
695
* If `that` is shorter than this iterator, `thatElem` values are used to pad the result.
745
696
* @note Reuse: $consumesTwoAndProducesOneIterator
746
698
* @usecase def zipAll[B](that: Iterator[B], thisElem: A, thatElem: B): Iterator[(A, B)]
748
def zipAll[B, A1 >: A, B1 >: B](that: Iterator[B], thisElem: A1, thatElem: B1) = new Iterator[(A1, B1)] {
701
def zipAll[B, A1 >: A, B1 >: B](that: Iterator[B], thisElem: A1, thatElem: B1): Iterator[(A1, B1)] = new AbstractIterator[(A1, B1)] {
749
702
def hasNext = self.hasNext || that.hasNext
750
703
def next(): (A1, B1) =
751
704
if (self.hasNext) {
1117
1075
* @param replaced The number of values in the original iterator that are replaced by the patch.
1118
1076
* @note Reuse: $consumesTwoAndProducesOneIterator
1120
def patch[B >: A](from: Int, patchElems: Iterator[B], replaced: Int) = new Iterator[B] {
1078
def patch[B >: A](from: Int, patchElems: Iterator[B], replaced: Int): Iterator[B] = new AbstractIterator[B] {
1121
1079
private var origElems = self
1122
1080
private var i = 0
1123
1081
def hasNext: Boolean =
1124
1082
if (i < from) origElems.hasNext
1125
1083
else patchElems.hasNext || origElems.hasNext
1126
1084
def next(): B = {
1085
// We have to do this *first* just in case from = 0.
1086
if (i == from) origElems = origElems drop replaced
1127
1087
val result: B =
1128
1088
if (i < from || !patchElems.hasNext) origElems.next()
1129
1089
else patchElems.next()
1131
if (i == from) origElems = origElems drop replaced
1139
1098
* Copying will stop once either the end of the current iterator is reached,
1140
1099
* or the end of the array is reached, or `len` elements have been copied.
1142
* $willNotTerminateInf
1144
1101
* @param xs the array to fill.
1145
1102
* @param start the starting index.
1146
1103
* @param len the maximal number of elements to copy.
1147
1104
* @tparam B the type of the elements of the array.
1149
1106
* @note Reuse: $consumesIterator
1150
1108
* @usecase def copyToArray(xs: Array[A], start: Int, len: Int): Unit
1111
* $willNotTerminateInf
1152
1113
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Unit = {
1114
require(start >= 0 && (start < xs.length || xs.length == 0), s"start $start out of range ${xs.length}")
1154
val end = start + math.min(len, xs.length)
1155
while (hasNext && i < end) {
1116
val end = start + math.min(len, xs.length - start)
1117
while (i < end && hasNext) {
1188
1151
* @note Reuse: $preservesIterator
1190
1153
override def toString = (if (hasNext) "non-empty" else "empty")+" iterator"
1192
/** Returns a new iterator that first yields the elements of this
1193
* iterator followed by the elements provided by iterator `that`.
1195
@deprecated("use `++`", "2.3.2")
1196
def append[B >: A](that: Iterator[B]) = self ++ that
1198
/** Returns index of the first element satisfying a predicate, or -1. */
1199
@deprecated("use `indexWhere` instead", "2.8.0")
1200
def findIndexOf(p: A => Boolean): Int = indexWhere(p)
1202
/** Returns a counted iterator from this iterator.
1204
@deprecated("use zipWithIndex in Iterator", "2.8.0")
1205
def counted = new CountedIterator[A] {
1208
def hasNext: Boolean = self.hasNext
1209
def next(): A = { cnt += 1; self.next }
1212
/** Fills the given array `xs` with the elements of
1213
* this sequence starting at position `start`. Like `copyToArray`,
1214
* but designed to accomodate IO stream operations.
1216
* '''Note:''' the array must be large enough to hold `sz` elements.
1217
* @param xs the array to fill.
1218
* @param start the starting index.
1219
* @param sz the maximum number of elements to be read.
1221
@deprecated("use copyToArray instead", "2.8.0")
1222
def readInto[B >: A](xs: Array[B], start: Int, sz: Int) {
1224
while (hasNext && i - start < sz) {
1230
@deprecated("use copyToArray instead", "2.8.0")
1231
def readInto[B >: A](xs: Array[B], start: Int) {
1232
readInto(xs, start, xs.length - start)
1235
@deprecated("use copyToArray instead", "2.8.0")
1236
def readInto[B >: A](xs: Array[B]) {
1237
readInto(xs, 0, xs.length)
1156
/** Explicit instantiation of the `Iterator` trait to reduce class file size in subclasses. */
1157
private[scala] abstract class AbstractIterator[+A] extends Iterator[A]