Commit | Line | Data |
---|---|---|
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 | ||
8 | functor PolyCache(): POLY_CACHE = | |
9 | struct | |
10 | ||
11 | datatype ('a, 'b) t = T of {equal: ('a * 'a) -> bool, | |
12 | elts: ('a * 'b ref) list ref} | |
13 | ||
14 | fun fromList | |
15 | ||
16 | fun new equal = T{equal = equal, elts = ref []} | |
17 | ||
18 | fun all(T{elts, ...}) = List.map(!elts, fn (x, y) => (x, !y)) | |
19 | ||
20 | fun 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 | ||
25 | fun peek(c, x) = | |
26 | case peekR(c, x) of | |
27 | NONE => NONE | |
28 | | SOME r => SOME(!r) | |
29 | ||
30 | fun lookup cx = Option.project(peek cx) | |
31 | ||
32 | fun addNew(T{elts = r as ref l, ...}, x, y) = | |
33 | r := (x, ref y) :: l | |
34 | ||
35 | fun set(c, x, y) = | |
36 | case peekR(c, x) of | |
37 | NONE => addNew(c, x, y) | |
38 | | SOME r => r := y | |
39 | ||
40 | fun 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 | ||
47 | fun eq(T{elts=r, ...}, T{elts=r', ...}) = r = r' | |
48 | ||
49 | end | |
50 | ||
51 | structure PolyCache = PolyCache() |