1 (* Copyright (C) 1999-2007 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
8 functor ResizableArray (): RESIZABLE_ARRAY =
11 structure Array = Array
15 datatype 'a t = T of {array: 'a option Array.t ref,
18 fun getArray (T {array, ...}) = !array
19 fun lengthRef (T {length, ...}) = length
20 fun length a = ! (lengthRef a)
23 fun maxLength a = Array.length (getArray a)
24 fun minLength a = Int.quot (maxLength a, 4)
28 andalso minLength a <= length a
29 andalso length a <= maxLength a
31 fun incLength a = Int.inc (lengthRef a)
32 fun decLength a = Int.dec (lengthRef a)
33 fun maxIndex a = length a - 1
35 exception New = Array.New
38 T {array = ref (Array.new (1, NONE)),
42 if s = 0 then empty ()
43 else T {array = ref (Array.new (1, SOME x)),
48 if s = 0 then empty ()
49 else T {array = ref (Array.tabulate (s, fn i => SOME (f i))),
53 case Array.sub (getArray a, i) of
55 | NONE => Error.bug "ResizableArray.subSafe"
58 if i < length a then subSafe (a, i)
59 else Error.bug "ResizableArray.sub"
61 fun updateSafe (a, i, x) =
62 Array.update (getArray a, i, SOME x)
64 fun update (a, i, x) =
65 if i < length a then updateSafe (a, i, x)
66 else Error.bug "ResizableArray.update"
69 let val a = Array.fromList (List.map (l, SOME))
71 length = ref (Array.length a)}
78 val unsafeUpdate = update
79 val unfoldi: int * 'a * (int * 'a -> 'b * 'a) -> 'b t * 'a =
83 Array.unfoldi (n, ac, fn (i, a) =>
85 val (b, a') = f (i, a)
96 fun subOption (a, i) =
98 then Array.sub (getArray a, i)
101 fun grow (a as T {array, ...}) =
102 array := Array.tabulate (maxLength a * 2,
103 fn i => subOption (a, i))
105 fun shrink (a as T {array, ...}) =
106 array := Array.tabulate (maxLength a div 2,
107 fn i => subOption (a, i))
109 fun addToEnd (a, x) =
110 (if length a = maxLength a then grow a else ()
111 ; updateSafe (a, length a, x)
116 then Error.bug "ResizableArray.deleteLast"
117 else let val x = subSafe (a, maxIndex a)
118 in (if length a = minLength a then shrink a else ()
125 structure ResizableArray = ResizableArray ()