|
rpm-build |
0f2925 |
(*
|
|
rpm-build |
0f2925 |
* DynArray - Resizeable Ocaml arrays
|
|
rpm-build |
0f2925 |
* Copyright (C) 2003 Brian Hurt
|
|
rpm-build |
0f2925 |
* Copyright (C) 2003 Nicolas Cannasse
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* This library is free software; you can redistribute it and/or
|
|
rpm-build |
0f2925 |
* modify it under the terms of the GNU Lesser General Public
|
|
rpm-build |
0f2925 |
* License as published by the Free Software Foundation; either
|
|
rpm-build |
0f2925 |
* version 2.1 of the License, or (at your option) any later version,
|
|
rpm-build |
0f2925 |
* with the special exception on linking described in file LICENSE.
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* This library is distributed in the hope that it will be useful,
|
|
rpm-build |
0f2925 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rpm-build |
0f2925 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
rpm-build |
0f2925 |
* Lesser General Public License for more details.
|
|
rpm-build |
0f2925 |
*
|
|
rpm-build |
0f2925 |
* You should have received a copy of the GNU Lesser General Public
|
|
rpm-build |
0f2925 |
* License along with this library; if not, write to the Free Software
|
|
rpm-build |
0f2925 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
rpm-build |
0f2925 |
*)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type resizer_t = currslots:int -> oldlength:int -> newlength:int -> int
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type 'a intern
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
external ilen : 'a intern -> int = "%obj_size"
|
|
rpm-build |
0f2925 |
let idup (x : 'a intern) = if ilen x = 0 then x else (Obj.magic (Obj.dup (Obj.repr x)) : 'a intern)
|
|
rpm-build |
0f2925 |
let imake tag len = (Obj.magic (Obj.new_block tag len) : 'a intern)
|
|
rpm-build |
0f2925 |
external iget : 'a intern -> int -> 'a = "%obj_field"
|
|
rpm-build |
0f2925 |
external iset : 'a intern -> int -> 'a -> unit = "%obj_set_field"
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
type 'a t = {
|
|
rpm-build |
0f2925 |
mutable arr : 'a intern;
|
|
rpm-build |
0f2925 |
mutable len : int;
|
|
rpm-build |
0f2925 |
mutable resize: resizer_t;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
exception Invalid_arg of int * string * string
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let invalid_arg n f p = raise (Invalid_arg (n,f,p))
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let length d = d.len
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let exponential_resizer ~currslots ~oldlength ~newlength =
|
|
rpm-build |
0f2925 |
let rec doubler x = if x >= newlength then x else doubler (x * 2) in
|
|
rpm-build |
0f2925 |
let rec halfer x = if x / 2 < newlength then x else halfer (x / 2) in
|
|
rpm-build |
0f2925 |
if newlength = 1 then
|
|
rpm-build |
0f2925 |
1
|
|
rpm-build |
0f2925 |
else if currslots = 0 then
|
|
rpm-build |
0f2925 |
doubler 1
|
|
rpm-build |
0f2925 |
else if currslots < newlength then
|
|
rpm-build |
0f2925 |
doubler currslots
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
halfer currslots
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let step_resizer step =
|
|
rpm-build |
0f2925 |
if step <= 0 then invalid_arg step "step_resizer" "step";
|
|
rpm-build |
0f2925 |
(fun ~currslots ~oldlength ~newlength ->
|
|
rpm-build |
0f2925 |
if currslots < newlength || newlength < (currslots - step)
|
|
rpm-build |
0f2925 |
then
|
|
rpm-build |
0f2925 |
(newlength + step - (newlength mod step))
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
currslots)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let conservative_exponential_resizer ~currslots ~oldlength ~newlength =
|
|
rpm-build |
0f2925 |
let rec doubler x = if x >= newlength then x else doubler (x * 2) in
|
|
rpm-build |
0f2925 |
let rec halfer x = if x / 2 < newlength then x else halfer (x / 2) in
|
|
rpm-build |
0f2925 |
if currslots < newlength then begin
|
|
rpm-build |
0f2925 |
if newlength = 1 then
|
|
rpm-build |
0f2925 |
1
|
|
rpm-build |
0f2925 |
else if currslots = 0 then
|
|
rpm-build |
0f2925 |
doubler 1
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
doubler currslots
|
|
rpm-build |
0f2925 |
end else if oldlength < newlength then
|
|
rpm-build |
0f2925 |
halfer currslots
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
currslots
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let default_resizer = conservative_exponential_resizer
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let changelen (d : 'a t) newlen =
|
|
rpm-build |
0f2925 |
if newlen > Sys.max_array_length then invalid_arg newlen "changelen" "newlen";
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let oldsize = ilen d.arr in
|
|
rpm-build |
0f2925 |
let r = d.resize
|
|
rpm-build |
0f2925 |
~currslots:oldsize
|
|
rpm-build |
0f2925 |
~oldlength:d.len
|
|
rpm-build |
0f2925 |
~newlength:newlen
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
(* We require the size to be at least large enough to hold the number
|
|
rpm-build |
0f2925 |
* of elements we know we need!
|
|
rpm-build |
0f2925 |
* Also be sure not to exceed max_array_length
|
|
rpm-build |
0f2925 |
*)
|
|
rpm-build |
0f2925 |
let newsize = if r < newlen then newlen else min Sys.max_array_length r in
|
|
rpm-build |
0f2925 |
if newsize <> oldsize then begin
|
|
rpm-build |
0f2925 |
let newarr = imake 0 newsize in
|
|
rpm-build |
0f2925 |
let cpylen = (if newlen < d.len then newlen else d.len) in
|
|
rpm-build |
0f2925 |
for i = 0 to cpylen - 1 do
|
|
rpm-build |
0f2925 |
iset newarr i (iget d.arr i);
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
d.arr <- newarr;
|
|
rpm-build |
0f2925 |
end;
|
|
rpm-build |
0f2925 |
d.len <- newlen
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let compact d =
|
|
rpm-build |
0f2925 |
if d.len <> ilen d.arr then begin
|
|
rpm-build |
0f2925 |
let newarr = imake 0 d.len in
|
|
rpm-build |
0f2925 |
for i = 0 to d.len - 1 do
|
|
rpm-build |
0f2925 |
iset newarr i (iget d.arr i)
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
d.arr <- newarr;
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let create() =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = default_resizer;
|
|
rpm-build |
0f2925 |
len = 0;
|
|
rpm-build |
0f2925 |
arr = imake 0 0;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let make initsize =
|
|
rpm-build |
0f2925 |
if initsize < 0 then invalid_arg initsize "make" "size";
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = default_resizer;
|
|
rpm-build |
0f2925 |
len = 0;
|
|
rpm-build |
0f2925 |
arr = imake 0 initsize;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let init initlen f =
|
|
rpm-build |
0f2925 |
if initlen < 0 then invalid_arg initlen "init" "len";
|
|
rpm-build |
0f2925 |
let arr = imake 0 initlen in
|
|
rpm-build |
0f2925 |
for i = 0 to initlen-1 do
|
|
rpm-build |
0f2925 |
iset arr i (f i)
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = default_resizer;
|
|
rpm-build |
0f2925 |
len = initlen;
|
|
rpm-build |
0f2925 |
arr = arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let set_resizer d resizer =
|
|
rpm-build |
0f2925 |
d.resize <- resizer
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let get_resizer d =
|
|
rpm-build |
0f2925 |
d.resize
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let empty d =
|
|
rpm-build |
0f2925 |
d.len = 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let get d idx =
|
|
rpm-build |
0f2925 |
if idx < 0 || idx >= d.len then invalid_arg idx "get" "index";
|
|
rpm-build |
0f2925 |
iget d.arr idx
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let last d =
|
|
rpm-build |
0f2925 |
if d.len = 0 then invalid_arg 0 "last" "<array len is 0>";
|
|
rpm-build |
0f2925 |
iget d.arr (d.len - 1)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let set d idx v =
|
|
rpm-build |
0f2925 |
if idx < 0 || idx >= d.len then invalid_arg idx "set" "index";
|
|
rpm-build |
0f2925 |
iset d.arr idx v
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let insert d idx v =
|
|
rpm-build |
0f2925 |
if idx < 0 || idx > d.len then invalid_arg idx "insert" "index";
|
|
rpm-build |
0f2925 |
if d.len = ilen d.arr then changelen d (d.len + 1) else d.len <- d.len + 1;
|
|
rpm-build |
0f2925 |
if idx < d.len - 1 then begin
|
|
rpm-build |
0f2925 |
for i = d.len - 2 downto idx do
|
|
rpm-build |
0f2925 |
iset d.arr (i+1) (iget d.arr i)
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
end;
|
|
rpm-build |
0f2925 |
iset d.arr idx v
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let add d v =
|
|
rpm-build |
0f2925 |
if d.len = ilen d.arr then changelen d (d.len + 1) else d.len <- d.len + 1;
|
|
rpm-build |
0f2925 |
iset d.arr (d.len - 1) v
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let delete d idx =
|
|
rpm-build |
0f2925 |
if idx < 0 || idx >= d.len then invalid_arg idx "delete" "index";
|
|
rpm-build |
0f2925 |
let oldsize = ilen d.arr in
|
|
rpm-build |
0f2925 |
(* we don't call changelen because we want to blit *)
|
|
rpm-build |
0f2925 |
let r = d.resize
|
|
rpm-build |
0f2925 |
~currslots:oldsize
|
|
rpm-build |
0f2925 |
~oldlength:d.len
|
|
rpm-build |
0f2925 |
~newlength:(d.len - 1)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let newsize = (if r < d.len - 1 then d.len - 1 else r) in
|
|
rpm-build |
0f2925 |
if oldsize <> newsize then begin
|
|
rpm-build |
0f2925 |
let newarr = imake 0 newsize in
|
|
rpm-build |
0f2925 |
for i = 0 to idx - 1 do
|
|
rpm-build |
0f2925 |
iset newarr i (iget d.arr i);
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
for i = idx to d.len - 2 do
|
|
rpm-build |
0f2925 |
iset newarr i (iget d.arr (i+1));
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
d.arr <- newarr;
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
for i = idx to d.len - 2 do
|
|
rpm-build |
0f2925 |
iset d.arr i (iget d.arr (i+1));
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
iset d.arr (d.len - 1) (Obj.magic 0)
|
|
rpm-build |
0f2925 |
end;
|
|
rpm-build |
0f2925 |
d.len <- d.len - 1
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let delete_range d idx len =
|
|
rpm-build |
0f2925 |
if len < 0 then invalid_arg len "delete_range" "length";
|
|
rpm-build |
0f2925 |
if idx < 0 || idx + len > d.len then invalid_arg idx "delete_range" "index";
|
|
rpm-build |
0f2925 |
let oldsize = ilen d.arr in
|
|
rpm-build |
0f2925 |
(* we don't call changelen because we want to blit *)
|
|
rpm-build |
0f2925 |
let r = d.resize
|
|
rpm-build |
0f2925 |
~currslots:oldsize
|
|
rpm-build |
0f2925 |
~oldlength:d.len
|
|
rpm-build |
0f2925 |
~newlength:(d.len - len)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
let newsize = (if r < d.len - len then d.len - len else r) in
|
|
rpm-build |
0f2925 |
if oldsize <> newsize then begin
|
|
rpm-build |
0f2925 |
let newarr = imake 0 newsize in
|
|
rpm-build |
0f2925 |
for i = 0 to idx - 1 do
|
|
rpm-build |
0f2925 |
iset newarr i (iget d.arr i);
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
for i = idx to d.len - len - 1 do
|
|
rpm-build |
0f2925 |
iset newarr i (iget d.arr (i+len));
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
d.arr <- newarr;
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
for i = idx to d.len - len - 1 do
|
|
rpm-build |
0f2925 |
iset d.arr i (iget d.arr (i+len));
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
for i = d.len - len to d.len - 1 do
|
|
rpm-build |
0f2925 |
iset d.arr i (Obj.magic 0)
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
end;
|
|
rpm-build |
0f2925 |
d.len <- d.len - len
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let clear d =
|
|
rpm-build |
0f2925 |
d.len <- 0;
|
|
rpm-build |
0f2925 |
d.arr <- imake 0 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let delete_last d =
|
|
rpm-build |
0f2925 |
if d.len <= 0 then invalid_arg 0 "delete_last" "<array len is 0>";
|
|
rpm-build |
0f2925 |
(* erase for GC, in case changelen don't resize our array *)
|
|
rpm-build |
0f2925 |
iset d.arr (d.len - 1) (Obj.magic 0);
|
|
rpm-build |
0f2925 |
changelen d (d.len - 1)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let rec blit src srcidx dst dstidx len =
|
|
rpm-build |
0f2925 |
if len < 0 then invalid_arg len "blit" "len";
|
|
rpm-build |
0f2925 |
if srcidx < 0 || srcidx + len > src.len then invalid_arg srcidx "blit" "source index";
|
|
rpm-build |
0f2925 |
if dstidx < 0 || dstidx > dst.len then invalid_arg dstidx "blit" "dest index";
|
|
rpm-build |
0f2925 |
let newlen = dstidx + len in
|
|
rpm-build |
0f2925 |
if newlen > ilen dst.arr then begin
|
|
rpm-build |
0f2925 |
(* this case could be inlined so we don't blit on just-copied elements *)
|
|
rpm-build |
0f2925 |
changelen dst newlen
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
if newlen > dst.len then dst.len <- newlen;
|
|
rpm-build |
0f2925 |
end;
|
|
rpm-build |
0f2925 |
(* same array ! we need to copy in reverse order *)
|
|
rpm-build |
0f2925 |
if src.arr == dst.arr && dstidx > srcidx then
|
|
rpm-build |
0f2925 |
for i = len - 1 downto 0 do
|
|
rpm-build |
0f2925 |
iset dst.arr (dstidx+i) (iget src.arr (srcidx+i));
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
for i = 0 to len - 1 do
|
|
rpm-build |
0f2925 |
iset dst.arr (dstidx+i) (iget src.arr (srcidx+i));
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let append src dst =
|
|
rpm-build |
0f2925 |
blit src 0 dst dst.len src.len
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let to_list d =
|
|
rpm-build |
0f2925 |
let rec loop idx accum =
|
|
rpm-build |
0f2925 |
if idx < 0 then accum else loop (idx - 1) (iget d.arr idx :: accum)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop (d.len - 1) []
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let to_array d =
|
|
rpm-build |
0f2925 |
if d.len = 0 then begin
|
|
rpm-build |
0f2925 |
(* since the empty array is an atom, we don't care if float or not *)
|
|
rpm-build |
0f2925 |
[||]
|
|
rpm-build |
0f2925 |
end else begin
|
|
rpm-build |
0f2925 |
let arr = Array.make d.len (iget d.arr 0) in
|
|
rpm-build |
0f2925 |
for i = 1 to d.len - 1 do
|
|
rpm-build |
0f2925 |
Array.unsafe_set arr i (iget d.arr i)
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
arr;
|
|
rpm-build |
0f2925 |
end
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let of_list lst =
|
|
rpm-build |
0f2925 |
let size = List.length lst in
|
|
rpm-build |
0f2925 |
let arr = imake 0 size in
|
|
rpm-build |
0f2925 |
let rec loop idx = function
|
|
rpm-build |
0f2925 |
| h :: t -> iset arr idx h; loop (idx + 1) t
|
|
rpm-build |
0f2925 |
| [] -> ()
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop 0 lst;
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = default_resizer;
|
|
rpm-build |
0f2925 |
len = size;
|
|
rpm-build |
0f2925 |
arr = arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let of_array src =
|
|
rpm-build |
0f2925 |
let size = Array.length src in
|
|
rpm-build |
0f2925 |
let is_float = Obj.tag (Obj.repr src) = Obj.double_array_tag in
|
|
rpm-build |
0f2925 |
let arr = (if is_float then begin
|
|
rpm-build |
0f2925 |
let arr = imake 0 size in
|
|
rpm-build |
0f2925 |
for i = 0 to size - 1 do
|
|
rpm-build |
0f2925 |
iset arr i (Array.unsafe_get src i);
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
arr
|
|
rpm-build |
0f2925 |
end else
|
|
rpm-build |
0f2925 |
(* copy the fields *)
|
|
rpm-build |
0f2925 |
idup (Obj.magic src : 'a intern))
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = default_resizer;
|
|
rpm-build |
0f2925 |
len = size;
|
|
rpm-build |
0f2925 |
arr = arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let copy src =
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = src.resize;
|
|
rpm-build |
0f2925 |
len = src.len;
|
|
rpm-build |
0f2925 |
arr = idup src.arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let sub src start len =
|
|
rpm-build |
0f2925 |
if len < 0 then invalid_arg len "sub" "len";
|
|
rpm-build |
0f2925 |
if start < 0 || start + len > src.len then invalid_arg start "sub" "start";
|
|
rpm-build |
0f2925 |
let arr = imake 0 len in
|
|
rpm-build |
0f2925 |
for i = 0 to len - 1 do
|
|
rpm-build |
0f2925 |
iset arr i (iget src.arr (i+start));
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = src.resize;
|
|
rpm-build |
0f2925 |
len = len;
|
|
rpm-build |
0f2925 |
arr = arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let iter f d =
|
|
rpm-build |
0f2925 |
for i = 0 to d.len - 1 do
|
|
rpm-build |
0f2925 |
f (iget d.arr i)
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let iteri f d =
|
|
rpm-build |
0f2925 |
for i = 0 to d.len - 1 do
|
|
rpm-build |
0f2925 |
f i (iget d.arr i)
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let filter f d =
|
|
rpm-build |
0f2925 |
let l = d.len in
|
|
rpm-build |
0f2925 |
let a = imake 0 l in
|
|
rpm-build |
0f2925 |
let a2 = d.arr in
|
|
rpm-build |
0f2925 |
let p = ref 0 in
|
|
rpm-build |
0f2925 |
for i = 0 to l - 1 do
|
|
rpm-build |
0f2925 |
let x = iget a2 i in
|
|
rpm-build |
0f2925 |
if f x then begin
|
|
rpm-build |
0f2925 |
iset a !p x;
|
|
rpm-build |
0f2925 |
incr p;
|
|
rpm-build |
0f2925 |
end;
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
d.len <- !p;
|
|
rpm-build |
0f2925 |
d.arr <- a
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let index_of f d =
|
|
rpm-build |
0f2925 |
let rec loop i =
|
|
rpm-build |
0f2925 |
if i >= d.len then
|
|
rpm-build |
0f2925 |
raise Not_found
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
if f (iget d.arr i) then
|
|
rpm-build |
0f2925 |
i
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
loop (i+1)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let map f src =
|
|
rpm-build |
0f2925 |
let arr = imake 0 src.len in
|
|
rpm-build |
0f2925 |
for i = 0 to src.len - 1 do
|
|
rpm-build |
0f2925 |
iset arr i (f (iget src.arr i))
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = src.resize;
|
|
rpm-build |
0f2925 |
len = src.len;
|
|
rpm-build |
0f2925 |
arr = arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let mapi f src =
|
|
rpm-build |
0f2925 |
let arr = imake 0 src.len in
|
|
rpm-build |
0f2925 |
for i = 0 to src.len - 1 do
|
|
rpm-build |
0f2925 |
iset arr i (f i (iget src.arr i))
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = src.resize;
|
|
rpm-build |
0f2925 |
len = src.len;
|
|
rpm-build |
0f2925 |
arr = arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let fold_left f x a =
|
|
rpm-build |
0f2925 |
let rec loop idx x =
|
|
rpm-build |
0f2925 |
if idx >= a.len then x else loop (idx + 1) (f x (iget a.arr idx))
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop 0 x
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let fold_right f a x =
|
|
rpm-build |
0f2925 |
let rec loop idx x =
|
|
rpm-build |
0f2925 |
if idx < 0 then x
|
|
rpm-build |
0f2925 |
else loop (idx - 1) (f (iget a.arr idx) x)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop (a.len - 1) x
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let enum d =
|
|
rpm-build |
0f2925 |
let rec make start =
|
|
rpm-build |
0f2925 |
let idxref = ref 0 in
|
|
rpm-build |
0f2925 |
let next () =
|
|
rpm-build |
0f2925 |
if !idxref >= d.len then
|
|
rpm-build |
0f2925 |
raise Enum.No_more_elements
|
|
rpm-build |
0f2925 |
else
|
|
rpm-build |
0f2925 |
let retval = iget d.arr !idxref in
|
|
rpm-build |
0f2925 |
incr idxref;
|
|
rpm-build |
0f2925 |
retval
|
|
rpm-build |
0f2925 |
and count () =
|
|
rpm-build |
0f2925 |
if !idxref >= d.len then 0
|
|
rpm-build |
0f2925 |
else d.len - !idxref
|
|
rpm-build |
0f2925 |
and clone () =
|
|
rpm-build |
0f2925 |
make !idxref
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
Enum.make ~next:next ~count:count ~clone:clone
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
make 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let of_enum e =
|
|
rpm-build |
0f2925 |
if Enum.fast_count e then begin
|
|
rpm-build |
0f2925 |
let c = Enum.count e in
|
|
rpm-build |
0f2925 |
let arr = imake 0 c in
|
|
rpm-build |
0f2925 |
Enum.iteri (fun i x -> iset arr i x) e;
|
|
rpm-build |
0f2925 |
{
|
|
rpm-build |
0f2925 |
resize = default_resizer;
|
|
rpm-build |
0f2925 |
len = c;
|
|
rpm-build |
0f2925 |
arr = arr;
|
|
rpm-build |
0f2925 |
}
|
|
rpm-build |
0f2925 |
end else
|
|
rpm-build |
0f2925 |
let d = make 0 in
|
|
rpm-build |
0f2925 |
Enum.iter (add d) e;
|
|
rpm-build |
0f2925 |
d
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let unsafe_get a n =
|
|
rpm-build |
0f2925 |
iget a.arr n
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let unsafe_set a n x =
|
|
rpm-build |
0f2925 |
iset a.arr n x
|