-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
LazyVal.scala
55 lines (42 loc) · 1.12 KB
/
LazyVal.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package japgolly.webapputil.general
import japgolly.univeq.UnivEq
trait LazyVal[+A] {
def value: A
def valueThreadSafe: A
override def equals(x: Any) =
x match {
case l: LazyVal[Any] => valueThreadSafe == l.valueThreadSafe
case _ => false
}
}
object LazyVal {
def apply[A](a: => A): LazyVal[A] =
new Lazy(() => a)
private final class Lazy[+A](initArg: () => A) extends LazyVal[A] {
// Don't prevent GC of initArg or waste mem propagating the ref
private[this] var init = initArg
private[this] var result: A = _
// Thread-unsafe
override def value: A = {
if (init ne null) {
try
result = init()
catch {
case t: Throwable =>
init = () => throw t
throw t
}
init = null
}
result
}
override def valueThreadSafe: A =
synchronized(value)
}
def pure[A](a: A): LazyVal[A] =
new Pure(a)
private final class Pure[+A](val value: A) extends LazyVal[A] {
override def valueThreadSafe = value
}
implicit def univEq[A]: UnivEq[LazyVal[A]] = UnivEq.force
}