summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/Enumeration.scala64
-rw-r--r--src/library/scala/collection/immutable/Range.scala7
-rw-r--r--src/library/scala/util/parsing/combinator/Parsers.scala14
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.")