diff options
author | Mathias <mathias@decodified.com> | 2017-12-14 10:55:11 +0100 |
---|---|---|
committer | Mathias <mathias@decodified.com> | 2017-12-14 11:11:25 +0100 |
commit | a2c85fe8be5dfaae8585f669ef05e072a13aa946 (patch) | |
tree | 5e1b11d48b516c65142a1f8151c80f7454cc2c56 /core/shared/src/main/scala/interface.scala | |
parent | 379f0075ca8042945d8ff89212536894a96f56a8 (diff) | |
download | magnolia-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.scala | 17 |
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) + } } |