Skip to content

Commit

Permalink
Use non-boxing forall and exists methods on strings (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyri-petrou authored Jul 9, 2023
1 parent 1d33377 commit 1f255ae
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions main/src/io/github/iltotore/iron/constraint/collection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ object collection:
.map(applyConstraint(_, constraintExpr))
.foldLeft(Expr(true))((e, t) => '{ $e && $t })

case None => '{ $expr.forall(c => ${ applyConstraint('c, constraintExpr) }) }
case None => '{ $expr.forallOptimized(c => ${ applyConstraint('c, constraintExpr) }) }

given [C1, C2](using C1 ==> C2): (ForAll[C1] ==> Exists[C2]) = Implication()
given [C1, C2](using C1 ==> C2): (ForAll[C1] ==> Last[C2]) = Implication()
Expand Down Expand Up @@ -207,7 +207,7 @@ object collection:
.map(applyConstraint(_, constraintExpr))
.foldLeft(Expr(true))((e, t) => '{ $e && $t })

case None => '{ $expr.init.forall(c => ${ applyConstraint('c, constraintExpr) }) }
case None => '{ $expr.init.forallOptimized(c => ${ applyConstraint('c, constraintExpr) }) }

given [C1, C2](using C1 ==> C2): (Init[C1] ==> Exists[C2]) = Implication()

Expand Down Expand Up @@ -244,7 +244,7 @@ object collection:
.map(applyConstraint(_, constraintExpr))
.foldLeft(Expr(true))((e, t) => '{ $e && $t })

case None => '{ $expr.tail.forall(c => ${ applyConstraint('c, constraintExpr) }) }
case None => '{ $expr.tail.forallOptimized(c => ${ applyConstraint('c, constraintExpr) }) }

given [C1, C2](using C1 ==> C2): (Tail[C1] ==> Exists[C2]) = Implication()
given [C1, C2](using C1 ==> C2): (Tail[C1] ==> Last[C2]) = Implication()
Expand Down Expand Up @@ -279,7 +279,7 @@ object collection:
.map(applyConstraint(_, constraintExpr))
.foldLeft(Expr(false))((e, t) => '{ $e || $t })

case None => '{ $expr.exists(c => ${ applyConstraint('c, constraintExpr) }) }
case None => '{ $expr.existsOptimized(c => ${ applyConstraint('c, constraintExpr) }) }

object Head:

Expand Down Expand Up @@ -338,3 +338,27 @@ object collection:
case None => '{ $expr.lastOption.exists(last => ${ applyConstraint('{ last }, constraintExpr) }) }

given [C1, C2](using C1 ==> C2): (Last[C1] ==> Exists[C2]) = Implication()

/**
* Scala's [[Function1]] doesn't have a specialization on [[Char]] arguments, which causes each char in the string to be boxed
* when calling `forall`. This trait is used as a substitute to avoid this issue.
*/
private trait EvalChar:
def apply(value: Char): Boolean

extension (s: String)
private def forallOptimized(p: EvalChar): Boolean =
var i = 0
val len = s.length
while i < len do
if !p(s.charAt(i)) then return false
i += 1
true

private def existsOptimized(p: EvalChar): Boolean =
var i = 0
val len = s.length
while i < len do
if p(s.charAt(i)) then return true
i += 1
false

0 comments on commit 1f255ae

Please sign in to comment.