Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Double and Dimensionless interoperability #267

Merged
merged 6 commits into from
Jun 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions shared/src/main/scala/squants/Dimensionless.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down
17 changes: 15 additions & 2 deletions shared/src/test/scala/squants/DimensionlessSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

package squants

import org.scalatest.{ FlatSpec, Matchers }
import org.scalatest.{FlatSpec, Matchers}
import squants.time.Hertz

/**
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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

Expand Down