|
rpm-build |
0f2925 |
(*
|
|
rpm-build |
0f2925 |
* ExtList - additional and modified functions for lists.
|
|
rpm-build |
0f2925 |
* Copyright (C) 2005 Richard W.M. Jones (rich @ annexia.org)
|
|
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 |
module Array = struct
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
include Array
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let rev_in_place xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
let j = ref (n-1) in
|
|
rpm-build |
0f2925 |
for i = 0 to n/2-1 do
|
|
rpm-build |
0f2925 |
let c = xs.(i) in
|
|
rpm-build |
0f2925 |
xs.(i) <- xs.(!j);
|
|
rpm-build |
0f2925 |
xs.(!j) <- c;
|
|
rpm-build |
0f2925 |
decr j
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let rev xs =
|
|
rpm-build |
0f2925 |
let ys = Array.copy xs in
|
|
rpm-build |
0f2925 |
rev_in_place ys;
|
|
rpm-build |
0f2925 |
ys
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
#if OCAML < 403
|
|
rpm-build |
0f2925 |
let for_all p xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
let rec loop i =
|
|
rpm-build |
0f2925 |
if i = n then true
|
|
rpm-build |
0f2925 |
else if p xs.(i) then loop (succ i)
|
|
rpm-build |
0f2925 |
else false
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
exception Exists
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let exists p xs =
|
|
rpm-build |
0f2925 |
try
|
|
rpm-build |
0f2925 |
for i = 0 to Array.length xs - 1 do
|
|
rpm-build |
0f2925 |
if p xs.(i) then raise Exists
|
|
rpm-build |
0f2925 |
done; false
|
|
rpm-build |
0f2925 |
with Exists -> true
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let mem a xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
let rec loop i =
|
|
rpm-build |
0f2925 |
if i = n then false
|
|
rpm-build |
0f2925 |
else if a = xs.(i) then true
|
|
rpm-build |
0f2925 |
else loop (succ i)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let memq a xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
let rec loop i =
|
|
rpm-build |
0f2925 |
if i = n then false
|
|
rpm-build |
0f2925 |
else if a == xs.(i) then true
|
|
rpm-build |
0f2925 |
else loop (succ i)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop 0
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let findi p xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
let rec loop i =
|
|
rpm-build |
0f2925 |
if i = n then raise Not_found
|
|
rpm-build |
0f2925 |
else if p xs.(i) then i
|
|
rpm-build |
0f2925 |
else loop (succ i)
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
loop 0
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let find p xs = xs.(findi p xs)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
(* Use of BitSet suggested by Brian Hurt. *)
|
|
rpm-build |
0f2925 |
let filter p xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
(* Use a bitset to store which elements will be in the final array. *)
|
|
rpm-build |
0f2925 |
let bs = BitSet.create n in
|
|
rpm-build |
0f2925 |
for i = 0 to n-1 do
|
|
rpm-build |
0f2925 |
if p xs.(i) then BitSet.set bs i
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
(* Allocate the final array and copy elements into it. *)
|
|
rpm-build |
0f2925 |
let n' = BitSet.count bs in
|
|
rpm-build |
0f2925 |
let j = ref 0 in
|
|
rpm-build |
0f2925 |
let xs' = init n'
|
|
rpm-build |
0f2925 |
(fun _ ->
|
|
rpm-build |
0f2925 |
(* Find the next set bit in the BitSet. *)
|
|
rpm-build |
0f2925 |
while not (BitSet.is_set bs !j) do incr j done;
|
|
rpm-build |
0f2925 |
let r = xs.(!j) in
|
|
rpm-build |
0f2925 |
incr j;
|
|
rpm-build |
0f2925 |
r) in
|
|
rpm-build |
0f2925 |
xs'
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let find_all = filter
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let partition p xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
(* Use a bitset to store which elements will be in which final array. *)
|
|
rpm-build |
0f2925 |
let bs = BitSet.create n in
|
|
rpm-build |
0f2925 |
for i = 0 to n-1 do
|
|
rpm-build |
0f2925 |
if p xs.(i) then BitSet.set bs i
|
|
rpm-build |
0f2925 |
done;
|
|
rpm-build |
0f2925 |
(* Allocate the final arrays and copy elements into them. *)
|
|
rpm-build |
0f2925 |
let n1 = BitSet.count bs in
|
|
rpm-build |
0f2925 |
let n2 = n - n1 in
|
|
rpm-build |
0f2925 |
let j = ref 0 in
|
|
rpm-build |
0f2925 |
let xs1 = init n1
|
|
rpm-build |
0f2925 |
(fun _ ->
|
|
rpm-build |
0f2925 |
(* Find the next set bit in the BitSet. *)
|
|
rpm-build |
0f2925 |
while not (BitSet.is_set bs !j) do incr j done;
|
|
rpm-build |
0f2925 |
let r = xs.(!j) in
|
|
rpm-build |
0f2925 |
incr j;
|
|
rpm-build |
0f2925 |
r) in
|
|
rpm-build |
0f2925 |
let j = ref 0 in
|
|
rpm-build |
0f2925 |
let xs2 = init n2
|
|
rpm-build |
0f2925 |
(fun _ ->
|
|
rpm-build |
0f2925 |
(* Find the next clear bit in the BitSet. *)
|
|
rpm-build |
0f2925 |
while BitSet.is_set bs !j do incr j done;
|
|
rpm-build |
0f2925 |
let r = xs.(!j) in
|
|
rpm-build |
0f2925 |
incr j;
|
|
rpm-build |
0f2925 |
r) in
|
|
rpm-build |
0f2925 |
xs1, xs2
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let enum xs =
|
|
rpm-build |
0f2925 |
let rec make start xs =
|
|
rpm-build |
0f2925 |
let n = length xs in
|
|
rpm-build |
0f2925 |
Enum.make
|
|
rpm-build |
0f2925 |
~next:(fun () ->
|
|
rpm-build |
0f2925 |
if !start < n then (
|
|
rpm-build |
0f2925 |
let r = xs.(!start) in
|
|
rpm-build |
0f2925 |
incr start;
|
|
rpm-build |
0f2925 |
r
|
|
rpm-build |
0f2925 |
) else
|
|
rpm-build |
0f2925 |
raise Enum.No_more_elements)
|
|
rpm-build |
0f2925 |
~count:(fun () ->
|
|
rpm-build |
0f2925 |
n - !start)
|
|
rpm-build |
0f2925 |
~clone:(fun () ->
|
|
rpm-build |
0f2925 |
let xs' = Array.sub xs !start (n - !start) in
|
|
rpm-build |
0f2925 |
make (ref 0) xs')
|
|
rpm-build |
0f2925 |
in
|
|
rpm-build |
0f2925 |
make (ref 0) xs
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let of_enum e =
|
|
rpm-build |
0f2925 |
let n = Enum.count e in
|
|
rpm-build |
0f2925 |
(* This assumes, reasonably, that init traverses the array in order. *)
|
|
rpm-build |
0f2925 |
Array.init n
|
|
rpm-build |
0f2925 |
(fun i ->
|
|
rpm-build |
0f2925 |
match Enum.get e with
|
|
rpm-build |
0f2925 |
| Some x -> x
|
|
rpm-build |
0f2925 |
| None -> assert false)
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
#if OCAML < 403
|
|
rpm-build |
0f2925 |
let iter2 f a1 a2 =
|
|
rpm-build |
0f2925 |
if Array.length a1 <> Array.length a2
|
|
rpm-build |
0f2925 |
then raise (Invalid_argument "Array.iter2");
|
|
rpm-build |
0f2925 |
for i = 0 to Array.length a1 - 1 do
|
|
rpm-build |
0f2925 |
f a1.(i) a2.(i);
|
|
rpm-build |
0f2925 |
done
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
let map2 f a1 a2 =
|
|
rpm-build |
0f2925 |
if Array.length a1 <> Array.length a2
|
|
rpm-build |
0f2925 |
then raise (Invalid_argument "Array.map2");
|
|
rpm-build |
0f2925 |
Array.init (Array.length a1) (fun i -> f a1.(i) a2.(i))
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
#if OCAML >= 403
|
|
rpm-build |
0f2925 |
#else
|
|
rpm-build |
0f2925 |
#if OCAML >= 402
|
|
rpm-build |
0f2925 |
let create_float = make_float
|
|
rpm-build |
0f2925 |
#else
|
|
rpm-build |
0f2925 |
let make_float n = make n 0.
|
|
rpm-build |
0f2925 |
let create_float = make_float
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
#endif
|
|
rpm-build |
0f2925 |
|
|
rpm-build |
0f2925 |
end
|