aboutsummaryrefslogtreecommitdiff
path: root/core/shared/src/main/scala/interface.scala
diff options
context:
space:
mode:
authorMathias <mathias@decodified.com>2017-12-14 10:55:11 +0100
committerMathias <mathias@decodified.com>2017-12-14 11:11:25 +0100
commita2c85fe8be5dfaae8585f669ef05e072a13aa946 (patch)
tree5e1b11d48b516c65142a1f8151c80f7454cc2c56 /core/shared/src/main/scala/interface.scala
parent379f0075ca8042945d8ff89212536894a96f56a8 (diff)
downloadmagnolia-a2c85fe8be5dfaae8585f669ef05e072a13aa946.tar.gz
magnolia-a2c85fe8be5dfaae8585f669ef05e072a13aa946.tar.bz2
magnolia-a2c85fe8be5dfaae8585f669ef05e072a13aa946.zip
Make `SealedTrait.dispatch` allocation-free
Diffstat (limited to 'core/shared/src/main/scala/interface.scala')
-rw-r--r--core/shared/src/main/scala/interface.scala17
1 files changed, 9 insertions, 8 deletions
diff --git a/core/shared/src/main/scala/interface.scala b/core/shared/src/main/scala/interface.scala
index 193a6f9..a4be9ab 100644
--- a/core/shared/src/main/scala/interface.scala
+++ b/core/shared/src/main/scala/interface.scala
@@ -1,6 +1,7 @@
package magnolia
import language.higherKinds
+import scala.annotation.tailrec
/** represents a subtype of a sealed trait
*
@@ -157,12 +158,12 @@ final class SealedTrait[Typeclass[_], Type](val typeName: String,
* matches
* @return the result of applying the `handle` lambda to subtype of the sealed trait which
* matches the parameter `value` */
- def dispatch[Return](value: Type)(handle: Subtype[Typeclass, Type] => Return): Return =
- subtypes
- .map { sub =>
- sub.cast.andThen { v =>
- handle(sub)
- }
- }
- .reduce(_ orElse _)(value)
+ def dispatch[Return](value: Type)(handle: Subtype[Typeclass, Type] => Return): Return = {
+ @tailrec def rec(ix: Int): Return =
+ if (ix < subtypesArray.length) {
+ val sub = subtypesArray(ix)
+ if (sub.cast.isDefinedAt(value)) handle(sub) else rec(ix + 1)
+ } else throw new IllegalArgumentException(s"The given value `$value` is not a sub type of `$typeName`")
+ rec(0)
+ }
}