
.psp-std_2.11.0.6.1.source-code.AtomicView.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of psp-std_2.11 Show documentation
Show all versions of psp-std_2.11 Show documentation
psp's non-standard standard library
The newest version!
package psp
package std
import api._, all._, StdEq._, StdShow._, Unsafe.inheritedShow
import lowlevel.CircularBuffer
sealed abstract class AtomicView[A, Repr] extends IBaseView[A, Repr] {
type This <: AtomicView[A, Repr]
def foreachSlice(range: VindexRange)(f: A => Unit): Unit
}
object FlattenSlice {
def unapply[A, Repr](xs: BaseView[A, Repr]): Option[(BaseView[A, Repr], VindexRange)] = xs match {
case xs: DirectView[_, _] => Some(xs -> xs.size.indices)
case Mapped(xs, f) => unapply(xs) map { case (xs, range) => (xs map f, range) }
case Dropped(xs, Size.Zero) => unapply(xs)
case DroppedR(xs, Size.Zero) => unapply(xs)
case Taken(xs, Size.Zero) => Some(emptyValue)
case TakenR(xs, Size.Zero) => Some(emptyValue)
case DroppedR(xs, n) => unapply(xs) map { case (xs, range) => (xs, range dropRight n) }
case TakenR(xs, n) => unapply(xs) map { case (xs, range) => (xs, range takeRight n) }
case Dropped(xs, n) => unapply(xs) map { case (xs, range) => (xs, range drop n) }
case Taken(xs, n) => unapply(xs) map { case (xs, range) => (xs, range take n) }
case _ => xs.size matchOpt { case x: Precise => xs -> x.indices }
}
}
final class StreamView[A, Repr](underlying: jStream[A]) extends AtomicView[A, Repr] {
type This = StreamView[A, Repr]
lazy val size: Precise = Size(underlying.count)
@inline def foreach(f: A => Unit): Unit = underlying.iterator foreach f
def foreachSlice(range: VindexRange)(f: A => Unit): Unit = underlying slice range foreach f
}
final class LinearView[A, Repr](underlying: Each[A]) extends AtomicView[A, Repr] {
type This = LinearView[A, Repr]
def size: Size = underlying.size
@inline def foreach(f: A => Unit): Unit = underlying foreach f
def foreachSlice(range: VindexRange)(f: A => Unit): Unit = {
if (range.isEmpty) return
val start = range.head.get
val last = range.last.get
var current = 0L
underlying foreach { x =>
if (start <= current && current <= last) f(x)
current += 1
if (current > last) return
}
}
}
final class DirectView[A, Repr](underlying: Direct[A]) extends AtomicView[A, Repr] {
type This = DirectView[A, Repr]
def size: Precise = underlying.size
def elemAt(i: Vindex): A = underlying(i)
def foreach(f: A => Unit): Unit = size.indices foreach (i => f(elemAt(i)))
def foreachSlice(range: VindexRange)(f: A => Unit): Unit = size.indices slice range foreach (i => f(elemAt(i)))
}
sealed trait BaseView[+A, Repr] extends AnyRef with View[A] with ops.ViewOps[A] {
def foreach(f: A => Unit): Unit
def toEach: Each[A] = Each(foreach)
type This <: BaseView[A, Repr]
type MapTo[+X] = BaseView[X, Repr]
def xs: this.type = this
final def collect[B](pf: A ?=> B): MapTo[B] = Collected(this, pf)
final def drop(n: Precise): MapTo[A] = Dropped(this, n)
final def dropRight(n: Precise): MapTo[A] = DroppedR(this, n)
final def dropWhile(p: ToBool[A]): MapTo[A] = DropWhile(this, p)
final def flatMap[B](f: A => Foreach[B]): MapTo[B] = FlatMapped(this, f)
final def map[B](f: A => B): MapTo[B] = Mapped(this, f)
final def take(n: Precise): MapTo[A] = Taken(this, n)
final def takeRight(n: Precise): MapTo[A] = TakenR(this, n)
final def takeWhile(p: ToBool[A]): MapTo[A] = TakenWhile(this, p)
final def withFilter(p: ToBool[A]): MapTo[A] = Filtered(this, p)
final def force[That](implicit z: Builds[A, That]): That = z build this
final def build(implicit z: Builds[A, Repr]): Repr = force[Repr]
}
sealed trait IBaseView[A, Repr] extends BaseView[A, Repr] with IView[A] {
final def join(that: IView[A]): IView[A] = Joined(this, that)
final def span(p: ToBool[A]): Split[A] = Split(takeWhile(p), dropWhile(p))
final def partition(p: ToBool[A]): Split[A] = Split(withFilter(p), withFilter(!p))
}
sealed abstract class CompositeView[A, B, Repr](val description: Doc, val sizeEffect: ToSelf[Size]) extends IBaseView[B, Repr] {
def prev: View[A]
def size = sizeEffect(prev.size)
final def foreach(f: B => Unit): Unit = {
def loop[C](xs: View[C])(f: C => Unit): Unit = {
type Pred = (ToBool[C] @unchecked) // silencing patmat warnings
xs match {
case FlattenSlice(xs, range) => foreachSlice(xs, range, f)
case Mapped(xs, g) => loop(xs)(g andThen f)
case FlatMapped(xs, g) => loop(xs)(x => g(x) foreach f)
case Filtered(xs, p: Pred) => loop(xs)(x => if (p(x)) f(x))
case TakenWhile(xs, p: Pred) => foreachTakeWhile(xs, f, p)
case DropWhile(xs, p: Pred) => foreachDropWhile(xs, f, p)
case Collected(xs, pf) => loop(xs)(x => if (pf isDefinedAt x) f(pf(x)))
case Joined(xs, ys) => loop(xs)(f) ; loop(ys)(f)
case DroppedR(xs, n: Precise) => foreachDropRight(xs, f, n)
case TakenR(xs, n: Precise) => foreachTakeRight(xs, f, n)
case Dropped(xs, Finite(n)) => foreachSlice(xs, Index(n) until Index(MaxLong), f)
case Taken(xs, n: Precise) => foreachSlice(xs, n.indices, f)
case xs: View[_] => xs foreach f
case _ => abort(pp"Unexpected view class ${xs.shortClass}")
}
}
if (!size.isZero)
loop(this)(f)
}
private def foreachTakeWhile[A](xs: Each[A], f: A => Unit, p: ToBool[A]): Int = {
var taken = 0
xs foreach { x =>
if (p(x)) sideEffect(f(x), taken += 1)
else return taken
}
taken
}
private def foreachDropWhile[A](xs: Each[A], f: A => Unit, p: ToBool[A]): Int = {
var dropping = true
var dropped = 0
xs foreach { x =>
if (dropping && p(x)) dropped += 1
else {
if (dropping) dropping = false
f(x)
}
}
dropped
}
private def foreachTakeRight[A](xs: Each[A], f: A => Unit, n: Precise): Unit = (
if (n > 0)
(CircularBuffer[A](n) ++= xs) foreach f
)
private def foreachDropRight[A](xs: Each[A], f: A => Unit, n: Precise): Unit = (
if (n.isZero)
xs foreach f
else
xs.foldl(CircularBuffer[A](n))((buf, x) => if (buf.isFull) sideEffect(buf, f(buf push x)) else buf += x)
)
private def foreachSlice[A](xs: View[A], range: VindexRange, f: A => Unit): Unit = xs match {
case Mapped(prev, g) => foreachSlice(prev, range, g andThen f)
case _ => xs.foreachSlice(range)(f)
}
}
final case class Joined [A, Repr](prev: IBaseView[A, Repr], ys: IView[A]) extends CompositeView[A, A, Repr](pp"++ $ys", _ + ys.size)
final case class Filtered [A , Repr](prev: BaseView[A, Repr], p: ToBool[A]) extends CompositeView[A, A, Repr](pp"filter $p", _.atMost)
final case class Dropped [A , Repr](prev: BaseView[A, Repr], n: Precise) extends CompositeView[A, A, Repr](pp"drop $n", _ - n)
final case class DroppedR [A , Repr](prev: BaseView[A, Repr], n: Precise) extends CompositeView[A, A, Repr](pp"dropR $n", _ - n)
final case class Taken [A , Repr](prev: BaseView[A, Repr], n: Precise) extends CompositeView[A, A, Repr](pp"take $n", _ min n)
final case class TakenR [A , Repr](prev: BaseView[A, Repr], n: Precise) extends CompositeView[A, A, Repr](pp"takeR $n", _ min n)
final case class TakenWhile [A , Repr](prev: BaseView[A, Repr], p: ToBool[A]) extends CompositeView[A, A, Repr](pp"takeW $p", _.atMost)
final case class DropWhile [A , Repr](prev: BaseView[A, Repr], p: ToBool[A]) extends CompositeView[A, A, Repr](pp"dropW $p", _.atMost)
final case class Mapped [A, B, Repr](prev: BaseView[A, Repr], f: A => B) extends CompositeView[A, B, Repr](pp"map $f", x => x)
final case class FlatMapped [A, B, Repr](prev: BaseView[A, Repr], f: A => Foreach[B]) extends CompositeView[A, B, Repr](pp"flatMap $f", x => if (x.isZero) x else Size.Unknown)
final case class Collected [A, B, Repr](prev: BaseView[A, Repr], pf: A ?=> B) extends CompositeView[A, B, Repr](pp"collect $pf", _.atMost)
© 2015 - 2025 Weber Informatics LLC | Privacy Policy