Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / mlton / env / poly-cache-ref.fun
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 *
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
6 *)
7
8functor PolyCache(): POLY_CACHE =
9struct
10
11datatype ('a, 'b) t = T of {equal: ('a * 'a) -> bool,
12 elts: ('a * 'b ref) list ref}
13
14fun fromList
15
16fun new equal = T{equal = equal, elts = ref []}
17
18fun all(T{elts, ...}) = List.map(!elts, fn (x, y) => (x, !y))
19
20fun peekR(T{equal, elts = ref l}, x) =
21 case List.keepFirst(l, fn (x', _) => equal(x, x')) of
22 NONE => NONE
23 | SOME(_, y) => SOME y
24
25fun peek(c, x) =
26 case peekR(c, x) of
27 NONE => NONE
28 | SOME r => SOME(!r)
29
30fun lookup cx = Option.project(peek cx)
31
32fun addNew(T{elts = r as ref l, ...}, x, y) =
33 r := (x, ref y) :: l
34
35fun set(c, x, y) =
36 case peekR(c, x) of
37 NONE => addNew(c, x, y)
38 | SOME r => r := y
39
40fun getOrAdd(c, x, th) =
41 case peek(c, x) of
42 NONE => let val y = th()
43 in addNew(c, x, y) ; y
44 end
45 | SOME y => y
46
47fun eq(T{elts=r, ...}, T{elts=r', ...}) = r = r'
48
49end
50
51structure PolyCache = PolyCache()