diff options
author | Paul Phillips <paulp@improving.org> | 2010-06-04 18:34:02 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-06-04 18:34:02 +0000 |
commit | da5910c7c622fc248fe525f5c03b1dee6be384b5 (patch) | |
tree | 966214d469ea0ecbd0370b18ab96af1d211a9af1 /src/library | |
parent | 245ec93fb132d2597a05d7ae9e081cd1adf356a3 (diff) | |
download | scala-da5910c7c622fc248fe525f5c03b1dee6be384b5.tar.gz scala-da5910c7c622fc248fe525f5c03b1dee6be384b5.tar.bz2 scala-da5910c7c622fc248fe525f5c03b1dee6be384b5.zip |
Fix for init-order caused NPE in NumericRange.
ran across some tortured logic trying to accomodate the long abandoned
idea of having 5 != 5L, so simplified the contains method. Closes #3518,
no review.
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/collection/immutable/NumericRange.scala | 45 |
1 files changed, 17 insertions, 28 deletions
diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index db44e9ffa0..b8bd5bd20e 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -40,8 +40,8 @@ import generic._ abstract class NumericRange[T] (val start: T, val end: T, val step: T, val isInclusive: Boolean) (implicit num: Integral[T]) -extends IndexedSeq[T] -{ +extends IndexedSeq[T] { + /** Note that NumericRange must be invariant so that constructs * such as * @@ -122,18 +122,6 @@ extends IndexedSeq[T] else start + (fromInt(idx) * step) } - // a well-typed contains method. - def containsTyped(x: T): Boolean = { - def divides(d: T, by: T) = equiv(d % by, zero) - - limitTest(x) || ( - if (step > zero) - (start <= x) && (x < end) && divides(x - start, step) - else - (start >= x) && (x > end) && divides(start - x, step) - ) - } - // Motivated by the desire for Double ranges with BigDecimal precision, // we need some way to map a Range and get another Range. This can't be // done in any fully general way because Ranges are not arbitrary @@ -165,7 +153,7 @@ extends IndexedSeq[T] if (isInclusive) NumericRange.inclusive(start, end, step) else NumericRange(start, end, step) - private val underlyingRange: NumericRange[T] = self + private lazy val underlyingRange: NumericRange[T] = self override def foreach[U](f: A => U) { underlyingRange foreach (x => f(fm(x))) } override def isEmpty = underlyingRange.isEmpty override def apply(idx: Int): A = fm(underlyingRange(idx)) @@ -173,20 +161,21 @@ extends IndexedSeq[T] } } - // The contains situation makes for some interesting code. - // I am not aware of any way to avoid a cast somewhere, because - // contains must take an Any. + // a well-typed contains method. + def containsTyped(x: T): Boolean = { + def divides(d: T, by: T) = equiv(d % by, zero) + + limitTest(x) || ( + if (step > zero) + (start <= x) && (x < end) && divides(x - start, step) + else + (start >= x) && (x > end) && divides(start - x, step) + ) + } + override def contains(x: Any): Boolean = - try { - // if we don't verify that x == typedX, then a range - // of e.g. Longs will appear to contain an Int because - // the cast will perform the conversion. (As of this writing - // it is anticipated that in scala 2.8, 5L != 5 although - // this is not yet implemented.) - val typedX = x.asInstanceOf[T] - containsTyped(typedX) && (x == typedX) - } - catch { case _: ClassCastException => super.contains(x) } + try containsTyped(x.asInstanceOf[T]) + catch { case _: ClassCastException => false } override lazy val hashCode = super.hashCode() override def equals(other: Any) = other match { |