Commit 5e63db38 authored by POTTIER Francois's avatar POTTIER Francois
Browse files

Cleaned up [Array.ml].

parent c4b0dbb3
(* Special construction for [|v1; .. ; vN|], encoded as
Array.make_from_list [v1; .. ; vN]. *)
external make_from_list : 'a list -> 'a array = "%array_make_from_list"
(* Special case for [||], needed to implement this file. *)
let make_empty () = make_from_list []
(* Alternative:
external make_empty : unit -> 'a array = "%array_make_empty"
(* This file is a copy of [array.ml], with different [external] declarations,
because:
- we must axiomatize the functions that cannot be implemented in OCaml;
- and only those.
*)
external make : int -> 'a -> 'a array = "%array_make"
(* A literal array [|v1; .. ; vN|] is encoded by CFML as
[of_list [v1; .. ; vN]].
This requires us to make [of_list] a primitive function. *)
external of_list : 'a list -> 'a array = "%array_of_list"
external length : 'a array -> int = "%array_length"
(* [unsafe_get] and [unsafe_set] intentionally omitted, at least for now. *)
external length : 'a array -> int = "%array_length"
external get : 'a array -> int -> 'a = "%array_get"
external set : 'a array -> int -> 'a -> unit = "%array_set"
external make : int -> 'a -> 'a array = "%array_make"
(* [make_float] omitted. *)
let init n f =
assert (n >= 0);
if n = 0 then make_empty() else begin
if n = 0 then of_list [] else begin
let res = make n (f 0) in
for i = 1 to pred n do
set res i (f i)
......@@ -32,22 +29,11 @@ let init n f =
end
(* Remark: might be optimized by using a sub-array to avoid initialization *)
let fill a start nb v =
assert (not (start < 0 || nb < 0 || start > length a - nb));
for i = start to pred (start + nb) do
set a i v;
done
let blit a1 start1 a2 start2 nb =
assert (not (nb < 0 || start1 < 0 || start1 > length a1 - nb
|| start2 < 0 || start2 > length a2 - nb));
for i = 0 to pred nb do
set a2 (start2 + i) (get a1 (start1 + i));
done
(* [make_matrix] omitted. *)
let copy a =
let n = length a in
if n = 0 then make_empty() else begin
if n = 0 then of_list [] else begin
let r = make (length a) (get a 0) in
for i = 0 to pred n do
set r i (get a i);
......@@ -55,10 +41,11 @@ let copy a =
r
end
(* Re-implementation of [append]. *)
let append a1 a2 =
let n1 = length a1 in
let n2 = length a2 in
if n1 = 0 && n2 = 0 then make_empty() else begin
if n1 = 0 && n2 = 0 then of_list [] else begin
let d = (if n1 <> 0 then get a1 0 else get a2 0) in
let a = make (n1+n2) d in
for i = 0 to pred n1 do
......@@ -69,48 +56,64 @@ let append a1 a2 =
done;
a
end
(* Remark: might be optimized by using a sub-array to avoid initialization *)
external sub : 'a array -> int -> int -> 'a array = "caml_array_sub"
(*
(* NOTE: Improved original code below *)
(* TODO: Do we want to expose unsafe_sub ? *)
(* Re-implementation of [concat]. *)
let concat ts =
List.fold_left append (of_list []) ts
(* Re-implementation of [sub]. *)
let sub a ofs len =
assert (not (ofs < 0 || len < 0 || ofs > length a - len));
unsafe_sub a ofs len
*)
init len (fun i -> get a (ofs + i))
let iter f a =
for i = 0 to pred (length a) do
f (get a i)
let fill a start nb v =
assert (not (start < 0 || nb < 0 || start > length a - nb));
for i = start to pred (start + nb) do
set a i v;
done
let iteri f a =
for i = 0 to pred (length a) do
f i (get a i)
(* Re-implementation of [blit]. *)
let blit a1 start1 a2 start2 nb =
assert (not (nb < 0 || start1 < 0 || start1 > length a1 - nb
|| start2 < 0 || start2 > length a2 - nb));
for i = 0 to pred nb do
set a2 (start2 + i) (get a1 (start1 + i));
done
let iter f a =
for i = 0 to pred (length a) do
f (get a i)
done
let map f a =
let n = length a in
if n = 0 then make_empty() else begin
if n = 0 then of_list [] else begin
let r = make n (f (get a 0)) in
for i = 1 to pred n do
set r i (f (get a i));
done;
r
end
(* Remark: might be optimized by using a sub-array to avoid initialization *)
let iteri f a =
for i = 0 to pred (length a) do
f i (get a i)
done
let mapi f a =
let n = length a in
if n = 0 then make_empty() else begin
if n = 0 then of_list [] else begin
let r = make n (f 0 (get a 0)) in
for i = 1 to pred n do
set r i (f i (get a i));
done;
r
end
(* Remark: might be optimized by using a sub-array to avoid initialization *)
let to_list a =
let rec tolist i res =
if i < 0 then res else tolist (i - 1) (get a i :: res) in
tolist (length a - 1) []
let fold_left f x a =
let r = ref x in
......@@ -119,14 +122,11 @@ let fold_left f x a =
done;
!r
(* TODO: add support for downto in CFML
let fold_right f a x =
let r = ref x in
for i = pred (length a) downto 0 do
r := f (get a i) !r
done;
!r
*)
(* [sort], [stable_sort], [fast_sort] omitted, for now. *)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment