tests for bitvectors

This commit is contained in:
Simon Cruanes 2014-06-24 18:52:38 +02:00
parent 2b15a21570
commit 1e2ac4c39b
4 changed files with 92 additions and 1 deletions

View file

@ -57,8 +57,21 @@ let create ~size default =
{ a = arr }
end
(*$T
create ~size:17 true |> cardinal = 17
create ~size:32 true |> cardinal= 32
create ~size:132 true |> cardinal = 132
create ~size:200 false |> cardinal = 0
create ~size:29 true |> to_sorted_list = CCList.range 0 28
*)
let copy bv = { a=Array.copy bv.a; }
(*$Q
(Q.list Q.small_int) (fun l -> \
let bv = of_list l in to_list bv = to_list (copy bv))
*)
let length bv = Array.length bv.a
let resize bv len =
@ -109,6 +122,11 @@ let set bv i =
let i = i - n * __width in
bv.a.(n) <- bv.a.(n) lor (1 lsl i)
(*$T
let bv = create ~size:3 false in set bv 0; get bv 0
let bv = create ~size:3 false in set bv 1; not (get bv 0)
*)
let reset bv i =
let n = i / __width in
if n >= Array.length bv.a
@ -116,6 +134,10 @@ let reset bv i =
let i = i - n * __width in
bv.a.(n) <- bv.a.(n) land (lnot (1 lsl i))
(*$T
let bv = create ~size:3 false in set bv 0; reset bv 0; not (get bv 0)
*)
let flip bv i =
let n = i / __width in
if n >= Array.length bv.a
@ -126,6 +148,10 @@ let flip bv i =
let clear bv =
Array.iteri (fun i _ -> bv.a.(i) <- 0) bv.a
(*$T
let bv = create ~size:37 true in cardinal bv = 37 && (clear bv; cardinal bv= 0)
*)
let iter bv f =
let len = Array.length bv.a in
for n = 0 to len - 1 do
@ -145,17 +171,30 @@ let iter_true bv f =
done
done
(*$T
of_list [1;5;7] |> iter_true |> CCSequence.to_list |> List.sort CCOrd.compare = [1;5;7]
*)
let to_list bv =
let l = ref [] in
iter_true bv (fun i -> l := i :: !l);
!l
let to_sorted_list bv =
List.rev (to_list bv)
let of_list l =
let size = List.fold_left max 0 l in
let bv = create ~size false in
List.iter (fun i -> set bv i) l;
bv
(*$T
of_list [1;32;64] |> CCFun.flip get 64
of_list [1;32;64] |> CCFun.flip get 32
of_list [1;31;63] |> CCFun.flip get 63
*)
exception FoundFirst of int
let first bv =
@ -165,9 +204,18 @@ let first bv =
with FoundFirst i ->
i
(*$T
of_list [50; 10; 17; 22; 3; 12] |> first = 3
*)
let filter bv p =
iter_true bv
(fun i -> if not (p i) then reset bv i)
(fun i -> if not (p i) then reset bv i)
(*$T
let bv = of_list [1;2;3;4;5;6;7] in filter bv (fun x->x mod 2=0); \
to_sorted_list bv = [2;4;6]
*)
let union_into ~into bv =
if length into < length bv
@ -182,6 +230,10 @@ let union bv1 bv2 =
union_into ~into:bv bv2;
bv
(*$T
union (of_list [1;2;3;4;5]) (of_list [7;3;5;6]) |> to_sorted_list = CCList.range 1 7
*)
let inter_into ~into bv =
let n = min (length into) (length bv) in
for i = 0 to n - 1 do
@ -199,6 +251,10 @@ let inter bv1 bv2 =
let () = inter_into ~into:bv bv1 in
bv
(*$T
inter (of_list [1;2;3;4]) (of_list [2;4;6;1]) |> to_sorted_list = [1;2;4]
*)
let select bv arr =
let l = ref [] in
begin try
@ -222,3 +278,25 @@ let selecti bv arr =
with Exit -> ()
end;
!l
(*$T
selecti (of_list [1;4;3]) [| 0;1;2;3;4;5;6;7;8 |] \
|> List.sort CCOrd.compare = [1, 1; 3,3; 4,4]
*)
type 'a sequence = ('a -> unit) -> unit
let to_seq bv k = iter_true bv k
let of_seq seq =
let l = ref [] and maxi = ref 0 in
seq (fun x -> l := x :: !l; maxi := max !maxi x);
let bv = create ~size:(!maxi+1) false in
List.iter (fun i -> set bv i) !l;
bv
(*$T
CCList.range 0 10 |> CCList.to_seq |> of_seq |> to_seq \
|> CCList.of_seq |> List.sort CCOrd.compare = CCList.range 0 10
*)

View file

@ -73,6 +73,10 @@ val iter_true : t -> (int -> unit) -> unit
val to_list : t -> int list
(** List of indexes that are true *)
val to_sorted_list : t -> int list
(** Same as {!to_list}, but also guarantees the list is sorted in
increasing order *)
val of_list : int list -> t
(** From a list of true bits *)
@ -104,3 +108,8 @@ val select : t -> 'a array -> 'a list
val selecti : t -> 'a array -> ('a * int) list
(** Same as {!select}, but selected elements are paired with their index *)
type 'a sequence = ('a -> unit) -> unit
val to_seq : t -> int sequence
val of_seq : int sequence -> t

View file

@ -30,6 +30,8 @@ let equal a b = a=b
let compare a b = Pervasives.compare a b
let negate x = not x
type 'a printer = Buffer.t -> 'a -> unit
type 'a formatter = Format.formatter -> 'a -> unit

View file

@ -32,6 +32,8 @@ val compare : t -> t -> int
val equal : t -> t -> bool
val negate : t -> t
type 'a printer = Buffer.t -> 'a -> unit
type 'a formatter = Format.formatter -> 'a -> unit