diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/Enumeration.scala | 64 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/Range.scala | 7 | ||||
-rw-r--r-- | src/library/scala/util/parsing/combinator/Parsers.scala | 14 |
3 files changed, 70 insertions, 15 deletions
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index 07e758013c..c967a48abc 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -8,7 +8,7 @@ package scala -import scala.collection.{ mutable, immutable, generic, SetLike, AbstractSet } +import scala.collection.{ mutable, immutable, generic, SortedSetLike, AbstractSet } import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField } import scala.reflect.NameTransformer._ import java.util.regex.Pattern @@ -53,10 +53,14 @@ import java.util.regex.Pattern * @author Matthias Zenger */ @SerialVersionUID(8476000850333817230L) -abstract class Enumeration(initial: Int, names: String*) extends Serializable { +abstract class Enumeration(initial: Int, + @deprecated("Names should be specified individually or discovered via reflection", "2.10") + names: String*) extends Serializable { thisenum => def this() = this(0) + + @deprecated("Names should be specified individually or discovered via reflection", "2.10") def this(names: String*) = this(0, names: _*) /* Note that `readResolve` cannot be private, since otherwise @@ -86,7 +90,7 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { */ def values: ValueSet = { if (!vsetDefined) { - vset = new ValueSet(immutable.SortedSet.empty[Int] ++ (vmap.values map (_.id))) + vset = (ValueSet.newBuilder ++= vmap.values).result() vsetDefined = true } vset @@ -104,6 +108,10 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { * enumeration. */ private var topId = initial + /** The lowest integer amongst those used to identify values in this + * enumeration, but no higher than 0. */ + private var bottomId = if(initial < 0) initial else 0 + /** The highest integer amongst those used to identify values in this * enumeration. */ final def maxId = topId @@ -200,6 +208,9 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { case _ => false } override def hashCode: Int = id.## + + /** Create a ValueSet which contains this value and another one */ + def + (v: Value) = ValueSet(this, v) } /** A class implementing the [[scala.Enumeration.Value]] type. This class @@ -217,6 +228,7 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { vsetDefined = false nextId = i + 1 if (nextId > topId) topId = nextId + if (i < bottomId) bottomId = i def id = i override def toString() = if (name != null) name @@ -230,34 +242,56 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable { } } + /** An ordering by id for values of this set */ + object ValueOrdering extends Ordering[Value] { + def compare(x: Value, y: Value): Int = x.id - y.id + } + /** A class for sets of values. * Iterating through this set will yield values in increasing order of their ids. * - * @param ids The set of ids of values, organized as a `SortedSet`. + * @param nnIds The set of ids of values (adjusted so that the lowest value does + * not fall below zero), organized as a `BitSet`. */ - class ValueSet private[Enumeration] (val ids: immutable.SortedSet[Int]) + class ValueSet private[ValueSet] (private[this] var nnIds: immutable.BitSet) extends AbstractSet[Value] - with Set[Value] - with SetLike[Value, ValueSet] { + with immutable.SortedSet[Value] + with SortedSetLike[Value, ValueSet] + with Serializable { + + implicit def ordering: Ordering[Value] = ValueOrdering + def rangeImpl(from: Option[Value], until: Option[Value]): ValueSet = + new ValueSet(nnIds.rangeImpl(from.map(_.id - bottomId), until.map(_.id - bottomId))) override def empty = ValueSet.empty - def contains(v: Value) = ids contains (v.id) - def + (value: Value) = new ValueSet(ids + value.id) - def - (value: Value) = new ValueSet(ids - value.id) - def iterator = ids.iterator map thisenum.apply + def contains(v: Value) = nnIds contains (v.id - bottomId) + def + (value: Value) = new ValueSet(nnIds + (value.id - bottomId)) + def - (value: Value) = new ValueSet(nnIds - (value.id - bottomId)) + def iterator = nnIds.iterator map (id => thisenum.apply(id + bottomId)) override def stringPrefix = thisenum + ".ValueSet" + /** Creates a bit mask for the zero-adjusted ids in this set as a + * new array of longs */ + def toBitMask: Array[Long] = nnIds.toBitMask } - + /** A factory object for value sets */ object ValueSet { import generic.CanBuildFrom /** The empty value set */ - val empty = new ValueSet(immutable.SortedSet.empty) + val empty = new ValueSet(immutable.BitSet.empty) /** A value set consisting of given elements */ - def apply(elems: Value*): ValueSet = empty ++ elems + def apply(elems: Value*): ValueSet = (newBuilder ++= elems).result() + /** A value set containing all the values for the zero-adjusted ids + * corresponding to the bits in an array */ + def fromBitMask(elems: Array[Long]): ValueSet = new ValueSet(immutable.BitSet.fromBitMask(elems)) /** A builder object for value sets */ - def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.SetBuilder(empty) + def newBuilder: mutable.Builder[Value, ValueSet] = new mutable.Builder[Value, ValueSet] { + private[this] val b = new mutable.BitSet + def += (x: Value) = { b += (x.id - bottomId); this } + def clear() = b.clear + def result() = new ValueSet(b.toImmutable) + } /** The implicit builder for value sets */ implicit def canBuildFrom: CanBuildFrom[ValueSet, Value, ValueSet] = new CanBuildFrom[ValueSet, Value, ValueSet] { diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 47ce2f0341..3736096f36 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -211,6 +211,13 @@ extends collection.AbstractSeq[Int] final def contains(x: Int) = isWithinBoundaries(x) && ((x - start) % step == 0) + final override def sum[B >: Int](implicit num: Numeric[B]): Int = { + val len = length + if (len == 0) 0 + else if (len == 1) head + else (len.toLong * (head + last) / 2).toInt + } + override def toIterable = this override def toSeq = this diff --git a/src/library/scala/util/parsing/combinator/Parsers.scala b/src/library/scala/util/parsing/combinator/Parsers.scala index ad907f90e6..751539243b 100644 --- a/src/library/scala/util/parsing/combinator/Parsers.scala +++ b/src/library/scala/util/parsing/combinator/Parsers.scala @@ -108,6 +108,8 @@ trait Parsers { def flatMapWithNext[U](f: T => Input => ParseResult[U]): ParseResult[U] + def filterWithError(p: T => Boolean, error: T => String, position: Input): ParseResult[T] + def append[U >: T](a: => ParseResult[U]): ParseResult[U] def isEmpty = !successful @@ -137,6 +139,10 @@ trait Parsers { def flatMapWithNext[U](f: T => Input => ParseResult[U]): ParseResult[U] = f(result)(next) + def filterWithError(p: T => Boolean, error: T => String, position: Input): ParseResult[T] = + if (p(result)) this + else Failure(error(result), position) + def append[U >: T](a: => ParseResult[U]): ParseResult[U] = this def get: T = result @@ -161,6 +167,8 @@ trait Parsers { def flatMapWithNext[U](f: Nothing => Input => ParseResult[U]): ParseResult[U] = this + def filterWithError(p: Nothing => Boolean, error: Nothing => String, position: Input): ParseResult[Nothing] = this + def get: Nothing = sys.error("No result when parsing failed") } /** An extractor so `NoSuccess(msg, next)` can be used in matches. */ @@ -224,6 +232,12 @@ trait Parsers { def map[U](f: T => U): Parser[U] //= flatMap{x => success(f(x))} = Parser{ in => this(in) map(f)} + def filter(p: T => Boolean): Parser[T] + = withFilter(p) + + def withFilter(p: T => Boolean): Parser[T] + = Parser{ in => this(in) filterWithError(p, "Input doesn't match filter: "+_, in)} + // no filter yet, dealing with zero is tricky! @migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.") |