Skip to content

Commit

Permalink
experiments with AnyVal
Browse files Browse the repository at this point in the history
  • Loading branch information
erikerlandson committed Dec 22, 2023
1 parent 33d6f64 commit 1c099ee
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 11 deletions.
24 changes: 20 additions & 4 deletions core/src/main/scala/coulomb/conversion/coefficients.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,15 @@ object coefficients:
inline def coefficientDouble[U1, U2]: Double = ${
meta.coefficientDouble[U1, U2]
}
inline def coefficientDoubleJ[U1, U2]: java.lang.Double = ${
meta.coefficientDoubleJ[U1, U2]
}
inline def coefficientFloat[U1, U2]: Float = ${
meta.coefficientFloat[U1, U2]
}
inline def coefficientBigDecimal[UF, UT]: BigDecimal = ${
meta.coefficientBigDecimal[UF, UT]
}

inline def coefficientNumDouble[U1, U2]: Double = ${
meta.coefficientNumDouble[U1, U2]
Expand All @@ -44,10 +50,6 @@ object coefficients:
}
inline def deltaOffsetFloat[U, B]: Float = ${ meta.deltaOffsetFloat[U, B] }

inline def coefficientBigDecimal[UF, UT]: BigDecimal = ${
meta.coefficientBigDecimal[UF, UT]
}

inline def deltaOffsetBigDecimal[U, B]: BigDecimal = ${
meta.deltaOffsetBigDecimal[U, B]
}
Expand All @@ -56,6 +58,11 @@ object coefficients:
import scala.quoted.*
import coulomb.infra.meta.{*, given}

given ctx_JavaDoubleToExpr: ToExpr[java.lang.Double] with
def apply(v: java.lang.Double)(using Quotes): Expr[java.lang.Double] =
val vd: Double = v
'{ java.lang.Double.valueOf(${Expr(vd)}) }

def coefficientRational[U1, U2](using
Quotes,
Type[U1],
Expand All @@ -74,6 +81,15 @@ object coefficients:
val c = coef(TypeRepr.of[U1], TypeRepr.of[U2])
Expr(c.toDouble)

def coefficientDoubleJ[U1, U2](using
Quotes,
Type[U1],
Type[U2]
): Expr[java.lang.Double] =
import quotes.reflect.*
val c = coef(TypeRepr.of[U1], TypeRepr.of[U2])
Expr(java.lang.Double.valueOf(c.toDouble))

def coefficientFloat[U1, U2](using
Quotes,
Type[U1],
Expand Down
85 changes: 78 additions & 7 deletions core/src/main/scala/coulomb/quantity.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
package coulomb

import scala.annotation.implicitNotFound

import spire.math.Rational

import coulomb.conversion.{ValueConversion, UnitConversion}
import coulomb.conversion.{TruncatingValueConversion, TruncatingUnitConversion}

Expand Down Expand Up @@ -115,9 +118,17 @@ inline def showUnitFull[U]: String = ${ coulomb.infra.show.showFull[U] }
* the coefficient of conversion from UF to UT If UF and UT are not
* convertible, causes a compilation failure.
*/
inline def coefficient[V, UF, UT](using vc: ValueConversion[spire.math.Rational, V]): V =
import coulomb.conversion.coefficients.coefficientRational
vc(coefficientRational[UF, UT])
inline def coefficient[V, UF, UT]: V =
import coulomb.conversion.coefficients.*
inline compiletime.erasedValue[V] match
case _: Double => coefficientDouble[UF, UT].asInstanceOf[V]
case _ =>
compiletime.summonFrom {
case vc: ValueConversion[Rational, V] =>
vc(coefficientRational[UF, UT])
case _ =>
compiletime.error("nope.")
}

package syntax {
// this has to be in a separated namespace:
Expand Down Expand Up @@ -238,10 +249,20 @@ object Quantity:
* q.toUnit[Hectare] // => compile error
* }}}
*/
inline def toUnit[U](using
conv: UnitConversion[VL, UL, U]
): Quantity[VL, U] =
conv(ql.value).withUnit[U]
inline def toUnit[U]: Quantity[VL, U] =
import coulomb.conversion.coefficients.*
inline compiletime.erasedValue[VL] match
case _: Double =>
(coefficientDouble[UL, U] * ql.value.asInstanceOf[Double])
.asInstanceOf[VL]
.withUnit[U]
case _ =>
compiletime.summonFrom {
case conv: UnitConversion[VL, UL, U] =>
conv(ql.value).withUnit[U]
case _ =>
compiletime.error("no!")
}

/**
* convert a quantity to an integer value type from a fractional type
Expand Down Expand Up @@ -657,3 +678,53 @@ object Quantity:
ord: Order[VL]
): Boolean =
ord.compare(ql.value, qr.value) >= 0

object qvcsyntax:
extension[V](v: V)
inline def asQVC[U]: QVC[V, U] =
QVC[V, U](v)

case class QVC[V, U](val value: V) extends AnyVal:
import qvcsyntax.*
inline def toUnit[UT]: QVC[V, UT] =
import coulomb.conversion.coefficients.*
inline compiletime.erasedValue[V] match
case _: Double =>
(coefficientDouble[U, UT] * value.asInstanceOf[Double])
.asInstanceOf[V]
.asQVC[UT]
case _ =>
compiletime.summonFrom {
case conv: UnitConversion[V, U, UT] =>
QVC[V, UT](conv(value))
case _ =>
compiletime.error("no!")
}

object hoohoo:
import qvcsyntax.*
val q1 = 1.0.asQVC[1000]
val q2 = q1.toUnit[1]
/*
def f(q: QVC[Double, 1000]): QVC[Double, 1] =
q.toUnit[1]
*/

object googoo:
import syntax.*
val q1 = 1.0.withUnit[1000]
val q2 = q1.toUnit[1]
//val q2 = q1.toUnit[1]

object foofoo:
import coulomb.syntax.*
import coulomb.policy.standard.given
val q1 = 1.0.withUnit[1000]
//val q2 = q1.toUnit[1]

object foofoo2:
import coulomb.syntax.*
import coulomb.policy.standard.given
val q1 = 1f.withUnit[1000]
val q2 = q1.toUnit[1]

0 comments on commit 1c099ee

Please sign in to comment.