Commits

Anonymous committed d6dd464

+ Array.GrowingArray

Comments (0)

Files changed (1)

     ;
 
 
+
+    (* GrowingArray -- module that reallocates array on demand.
+       Call [with_array requested_size user_func] to use this array.
+       Array will be resized to [default_size * 2^n] sizes on demand.
+       [user_func] may get array bigger than [requested_size].
+       After exitting [user_func] array will contain all items that
+       [user_func] left there, so they will be inaccessible for
+       garbage collection until [t 'a]-typed value is alive.
+     *)
+
+    module GrowingArray
+     :
+      sig
+        type t 'a;
+        value make :
+          int (* initial size *) ->
+          'a (* default element's value *) ->
+          t 'a
+        ;
+        value with_array :
+          int (* requested size *) ->
+          (array 'a -> 'b) ->
+          t 'a ->
+          'b
+        ;
+      end
+     =
+      struct
+
+        type t 'a =
+          { cur_size : mutable int
+          ; default_element : 'a
+          ; cur_array : mutable array 'a
+          }
+        ;
+
+        value make initial_size default_element =
+          if initial_size <= 0 || initial_size > Sys.max_array_length
+          then
+            invalid_arg "Array.GrowingArray.make: initial_size"
+          else
+            { cur_size = initial_size
+            ; default_element = default_element
+            ; cur_array = Array.make initial_size default_element
+            }
+        ;
+
+        value with_array requested_size user_func ga =
+          if requested_size < 0 || requested_size > Sys.max_array_length
+          then
+            invalid_arg "Array.GrowingArray.with_array: requested_size"
+          else
+            let arr =
+              if requested_size <= ga.cur_size
+              then
+                ga.cur_array
+              else
+                let new_size = min (2 * ga.cur_size) Sys.max_array_length in
+                let new_array = Array.make new_size ga.default_element in
+                ( ga.cur_size := new_size
+                ; ga.cur_array := new_array
+                ; new_array
+                )
+            in
+              user_func arr
+        ;
+
+      end
+    ;
   end
 ;