MathGame_V2/dynamic.ml

78 lines
2.0 KiB
OCaml

exception ReturnInt of int ;;
type 'a dynamic = {
mutable len : int ;
mutable memlen : int ;
mutable tab : 'a array
} ;;
let dyn_create (elt : 'a) =
{
len = 0 ;
memlen = 16 ;
tab = Array.make 16 elt
} ;;
let dyn_mem (dyn : 'a dynamic) (id : int) =
if id < 0 || id >= dyn.len then begin
Printf.fprintf stderr "(at index %d with len %d) \n" id dyn.len;
failwith "ERROR : invalid access" ;
end;
dyn.tab.(id) ;;
let dyn_add (dyn : 'a dynamic) (elt : 'a) =
if dyn.len = dyn.memlen then begin
let _new = Array.make (2 * dyn.memlen) dyn.tab.(0) in
for i = 0 to dyn.memlen -1 do
_new.(i) <- dyn.tab.(i)
done;
dyn.tab <- _new ;
dyn.memlen <- dyn.memlen * 2 ;
end;
dyn.tab.(dyn.len) <- elt ;
dyn.len <- dyn.len +1 ;;
let dyn_remove (dyn : 'a dynamic) (elt : 'a) =
try
for i = 0 to dyn.len -1 do
if dyn.tab.(i) = elt then
raise (ReturnInt i)
done;
raise (ReturnInt (-1))
with
| ReturnInt (-1) -> ()
| ReturnInt k ->
for i = k to dyn.len -2 do
dyn.tab.(i) <- dyn.tab.(i+1)
done;
dyn.len <- dyn.len -1 ;
if (dyn.memlen >= 32) && (dyn.len * 4 <= dyn.memlen) then begin
let _new = Array.make (dyn.memlen/2) dyn.tab.(0) in
for i = 0 to dyn.len -1 do
_new.(i) <- dyn.tab.(i)
done;
dyn.tab <- _new ;
dyn.memlen <- dyn.memlen/2 ;
end ;;
let dyn_remove_id (dyn : 'a dynamic) (id : int) =
assert (id >= 0 && id < dyn.len) ;
let temp = dyn.tab.(dyn.len -1) in
dyn.tab.(dyn.len -1) <- dyn.tab.(id) ;
dyn.tab.(id) <- temp ;
dyn.len <- dyn.len - 1;
if (dyn.memlen >= 32) && (dyn.len * 4 <= dyn.memlen) then begin
let _new = Array.make (dyn.memlen/2) dyn.tab.(0) in
for i = 0 to dyn.len -1 do
_new.(i) <- dyn.tab.(i)
done;
dyn.tab <- _new ;
dyn.memlen <- dyn.memlen/2 ;
end ;;
let dyn_fold_left (f : 'b -> 'a -> 'b) (acc0 : 'b) (dyn : 'a dynamic) =
let acc = ref acc0 in
for i = 0 to dyn.len -1 do
acc := f !acc dyn.tab.(i)
done;
!acc ;;