diff --git a/shared/src/main/scala/squants/Dimensionless.scala b/shared/src/main/scala/squants/Dimensionless.scala index 0a77b1cd..f11d9dd2 100644 --- a/shared/src/main/scala/squants/Dimensionless.scala +++ b/shared/src/main/scala/squants/Dimensionless.scala @@ -8,7 +8,7 @@ package squants -import squants.time.{ Frequency, Hertz, TimeIntegral } +import squants.time.{Frequency, Hertz, TimeIntegral} /** * Represents a quantity of some thing for which there is no dimension. @@ -30,8 +30,10 @@ final class Dimensionless private (val value: Double, val unit: DimensionlessUni protected def timeDerived = Hertz(toEach) protected[squants] def time = Seconds(1) - def *(that: Dimensionless) = Each(this.toEach * that.toEach) - def *(that: Quantity[_]) = that * this.toEach + def *(that: Dimensionless) = Each(toEach * that.toEach) + def *(that: Quantity[_]) = that * toEach + + def +(that: Double): Dimensionless = this + Each(that) def toPercent = to(Percent) def toEach = to(Each) @@ -110,6 +112,8 @@ object DimensionlessConversions { lazy val thousand = Each(1e3) lazy val million = Each(1e6) + import scala.language.implicitConversions + implicit class DimensionlessConversions[A](n: A)(implicit num: Numeric[A]) { def percent = Percent(n) def each = Each(n) @@ -123,11 +127,19 @@ object DimensionlessConversions { def thousand = Each(num.toDouble(n) * 1e3) def million = Each(num.toDouble(n) * 1e6) } + /** + * Provides an implicit conversion from Dimensionless to Double, allowing a Dimensionless value + * to be used anywhere a Double (or similar primitive) is required + * + * @param d Dimensionless + * @return + */ + implicit def dimensionlessToDouble(d: Dimensionless): Double = d.toEach implicit object DimensionlessNumeric extends AbstractQuantityNumeric[Dimensionless](Dimensionless.primaryUnit) { /** * Dimensionless quantities support the times operation. - * This method overrides the default [[squants.AbstractQuantityNumeric.times]] which thrown an exception + * This method overrides the default [[squants.AbstractQuantityNumeric.times]] which throws an exception * * @param x Dimensionless * @param y Dimensionless diff --git a/shared/src/test/scala/squants/DimensionlessSpec.scala b/shared/src/test/scala/squants/DimensionlessSpec.scala index 0a0310d1..c08a6506 100644 --- a/shared/src/test/scala/squants/DimensionlessSpec.scala +++ b/shared/src/test/scala/squants/DimensionlessSpec.scala @@ -8,7 +8,7 @@ package squants -import org.scalatest.{ FlatSpec, Matchers } +import org.scalatest.{FlatSpec, Matchers} import squants.time.Hertz /** @@ -55,11 +55,15 @@ class DimensionlessSpec extends FlatSpec with Matchers { Gross(1).toString(Gross) should be("1.0 gr") } - it should "return another Dimensionless when multiplied by a Dimensionless" in { + it should "return another Dimensionless when multiplied by a Dimensionless" in { Each(2) * Dozen(1) should be(Dozen(2)) Dozen(5) * Percent(10) should be(Each(6)) } + it should "return another Dimensionless when added to a Double" in { + Each(10) + 10.22 should be(Each(20.22)) + } + it should "return a Frequency when divided by Time" in { Each(60) / Seconds(1) should be(Hertz(60)) } @@ -100,6 +104,15 @@ class DimensionlessSpec extends FlatSpec with Matchers { coefficient.million should be(Each(coefficient * 1e6)) } + it should "provide an implicit conversion to Double" in { + import DimensionlessConversions._ + + 10 + 5.each should be(15d) + 100 - 1.dozen should be(88d) + 100 * 15.percent should be(15) + 12000 / 1.dozen should be(1000d) + } + it should "provide Numeric support" in { import DimensionlessConversions.DimensionlessNumeric