mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 11:45:31 -05:00
tests for bitvectors
This commit is contained in:
parent
2b15a21570
commit
1e2ac4c39b
4 changed files with 92 additions and 1 deletions
78
core/CCBV.ml
78
core/CCBV.ml
|
|
@ -57,8 +57,21 @@ let create ~size default =
|
||||||
{ a = arr }
|
{ a = arr }
|
||||||
end
|
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; }
|
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 length bv = Array.length bv.a
|
||||||
|
|
||||||
let resize bv len =
|
let resize bv len =
|
||||||
|
|
@ -109,6 +122,11 @@ let set bv i =
|
||||||
let i = i - n * __width in
|
let i = i - n * __width in
|
||||||
bv.a.(n) <- bv.a.(n) lor (1 lsl i)
|
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 reset bv i =
|
||||||
let n = i / __width in
|
let n = i / __width in
|
||||||
if n >= Array.length bv.a
|
if n >= Array.length bv.a
|
||||||
|
|
@ -116,6 +134,10 @@ let reset bv i =
|
||||||
let i = i - n * __width in
|
let i = i - n * __width in
|
||||||
bv.a.(n) <- bv.a.(n) land (lnot (1 lsl i))
|
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 flip bv i =
|
||||||
let n = i / __width in
|
let n = i / __width in
|
||||||
if n >= Array.length bv.a
|
if n >= Array.length bv.a
|
||||||
|
|
@ -126,6 +148,10 @@ let flip bv i =
|
||||||
let clear bv =
|
let clear bv =
|
||||||
Array.iteri (fun i _ -> bv.a.(i) <- 0) bv.a
|
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 iter bv f =
|
||||||
let len = Array.length bv.a in
|
let len = Array.length bv.a in
|
||||||
for n = 0 to len - 1 do
|
for n = 0 to len - 1 do
|
||||||
|
|
@ -145,17 +171,30 @@ let iter_true bv f =
|
||||||
done
|
done
|
||||||
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 to_list bv =
|
||||||
let l = ref [] in
|
let l = ref [] in
|
||||||
iter_true bv (fun i -> l := i :: !l);
|
iter_true bv (fun i -> l := i :: !l);
|
||||||
!l
|
!l
|
||||||
|
|
||||||
|
let to_sorted_list bv =
|
||||||
|
List.rev (to_list bv)
|
||||||
|
|
||||||
let of_list l =
|
let of_list l =
|
||||||
let size = List.fold_left max 0 l in
|
let size = List.fold_left max 0 l in
|
||||||
let bv = create ~size false in
|
let bv = create ~size false in
|
||||||
List.iter (fun i -> set bv i) l;
|
List.iter (fun i -> set bv i) l;
|
||||||
bv
|
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
|
exception FoundFirst of int
|
||||||
|
|
||||||
let first bv =
|
let first bv =
|
||||||
|
|
@ -165,10 +204,19 @@ let first bv =
|
||||||
with FoundFirst i ->
|
with FoundFirst i ->
|
||||||
i
|
i
|
||||||
|
|
||||||
|
(*$T
|
||||||
|
of_list [50; 10; 17; 22; 3; 12] |> first = 3
|
||||||
|
*)
|
||||||
|
|
||||||
let filter bv p =
|
let filter bv p =
|
||||||
iter_true bv
|
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 =
|
let union_into ~into bv =
|
||||||
if length into < length bv
|
if length into < length bv
|
||||||
then resize into (length bv);
|
then resize into (length bv);
|
||||||
|
|
@ -182,6 +230,10 @@ let union bv1 bv2 =
|
||||||
union_into ~into:bv bv2;
|
union_into ~into:bv bv2;
|
||||||
bv
|
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 inter_into ~into bv =
|
||||||
let n = min (length into) (length bv) in
|
let n = min (length into) (length bv) in
|
||||||
for i = 0 to n - 1 do
|
for i = 0 to n - 1 do
|
||||||
|
|
@ -199,6 +251,10 @@ let inter bv1 bv2 =
|
||||||
let () = inter_into ~into:bv bv1 in
|
let () = inter_into ~into:bv bv1 in
|
||||||
bv
|
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 select bv arr =
|
||||||
let l = ref [] in
|
let l = ref [] in
|
||||||
begin try
|
begin try
|
||||||
|
|
@ -222,3 +278,25 @@ let selecti bv arr =
|
||||||
with Exit -> ()
|
with Exit -> ()
|
||||||
end;
|
end;
|
||||||
!l
|
!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
|
||||||
|
*)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,10 @@ val iter_true : t -> (int -> unit) -> unit
|
||||||
val to_list : t -> int list
|
val to_list : t -> int list
|
||||||
(** List of indexes that are true *)
|
(** 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
|
val of_list : int list -> t
|
||||||
(** From a list of true bits *)
|
(** 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
|
val selecti : t -> 'a array -> ('a * int) list
|
||||||
(** Same as {!select}, but selected elements are paired with their index *)
|
(** 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
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ let equal a b = a=b
|
||||||
|
|
||||||
let compare a b = Pervasives.compare a b
|
let compare a b = Pervasives.compare a b
|
||||||
|
|
||||||
|
let negate x = not x
|
||||||
|
|
||||||
type 'a printer = Buffer.t -> 'a -> unit
|
type 'a printer = Buffer.t -> 'a -> unit
|
||||||
type 'a formatter = Format.formatter -> 'a -> unit
|
type 'a formatter = Format.formatter -> 'a -> unit
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ val compare : t -> t -> int
|
||||||
|
|
||||||
val equal : t -> t -> bool
|
val equal : t -> t -> bool
|
||||||
|
|
||||||
|
val negate : t -> t
|
||||||
|
|
||||||
type 'a printer = Buffer.t -> 'a -> unit
|
type 'a printer = Buffer.t -> 'a -> unit
|
||||||
type 'a formatter = Format.formatter -> 'a -> unit
|
type 'a formatter = Format.formatter -> 'a -> unit
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue