diff options
Diffstat (limited to 'src/library/scalax/collection/generic/covartest/IterableFactory.scala')
-rwxr-xr-x | src/library/scalax/collection/generic/covartest/IterableFactory.scala | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/library/scalax/collection/generic/covartest/IterableFactory.scala b/src/library/scalax/collection/generic/covartest/IterableFactory.scala new file mode 100755 index 0000000000..d12da89987 --- /dev/null +++ b/src/library/scalax/collection/generic/covartest/IterableFactory.scala @@ -0,0 +1,108 @@ +package scalax.collection.generic.covartest + +trait IterableFactory[CC[A] <: Iterable[A]] { + + /** Create CC collection of specified elements */ + def apply[A](args: A*): CC[A] + + protected def newBuilder[A]: Builder[CC, A] = + apply().newBuilder[A].asInstanceOf[Builder[CC, A]] + + /** Concatenate all the argument lists into a single list. + * + * @param xss the lists that are to be concatenated + * @return the concatenation of all the lists + */ + def concat[A](xss: CC[A]*): CC[A] = { + val b = newBuilder[A] + for (xs <- xss) b ++= xs + b.result + } + + /** An iterable that contains the same element a number of times + * @param n The number of elements returned + * @param elem The element returned each time + */ + def fill[A](n: Int, elem: => A): CC[A] = { + val b = newBuilder[A] + var i = 0 + while (i < n) { + b += elem + i += 1 + } + b.result + } + + def fill[A](n1: Int, n2: Int, elem: => A): CC[CC[A]] = + tabulate(n1)(_ => fill(n2, elem)) + + def fill[A](n1: Int, n2: Int, n3: Int, elem: => A): CC[CC[CC[A]]] = + tabulate(n1)(_ => fill(n2, n3, elem)) + + def tabulate[A](n: Int)(f: Int => A): CC[A] = { + val b = newBuilder[A] + var i = 0 + while (i < n) { + b += f(i) + i += 1 + } + b.result + } + + def tabulate[A](n1: Int, n2: Int)(f: (Int, Int) => A): CC[CC[A]] = + tabulate(n1)(i1 => tabulate(n2)(i2 => f(i1, i2))) + + def tabulate[A](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): CC[CC[CC[A]]] = + tabulate(n1)(i1 => tabulate(n2)(i2 => tabulate(n3)(i3 => f(i1, i2, i3)))) +// todo: go up to 5(?) + + /** Create a sequence of increasing integers in a range. + * + * @param from the start value of the sequence + * @param end the end value of the sequence + * @return the sorted list of all from `from` (inclusive) + * up to, but exclusding, `end`. + */ + def range[A](start: Int, end: Int): CC[Int] = range(start, end, 1) + + /** Create a sequence of increasing integers in a range. + * + * @param from the start value of the sequence + * @param end the end value of the sequence + * @param step the increment value of successive elements + * @return a list of values <code>from + n * step</code> for + * increasing n. If `step > 0` the sequence terminates + * with the largest value less than `end`. If `step < 0` + * the sequence terminates with the smallest value greater than `end`. + * If `step == 0`, the sequence gors on infinitely (in that + * case the `range` operation might not terminate. + */ + def range(start: Int, end: Int, step: Int): CC[Int] = { + val b = newBuilder[Int] + var i = start + while ((step <= 0 || i < end) && (step >= 0 || i > end)) { + b += i + i += step + } + b.result + } + + /** Create a sequence by repeatedly applying a given function to a start value. + * + * @param start the start value of the sequence + * @param len the length of the sequence + * @param f the function that's repeatedly applied + * @return the sequence with elements <code>(start, f(start), f(f(start)), ..., f<sup>len-1</sup>(start))</code> + */ + def iterate(start: Int, len: Int)(f: Int => Int): CC[Int] = { + val b = newBuilder[Int] + var acc = start + var i = 0 + while (i < len) { + b += acc + acc = f(acc) + i += 1 + } + b.result + } +} |