mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2026-01-21 16:56:39 -05:00
wip: convert tests into testlib
This commit is contained in:
parent
91ddccc782
commit
1111c0fa9a
29 changed files with 997 additions and 1056 deletions
311
src/data/CCBV.ml
311
src/data/CCBV.ml
|
|
@ -4,10 +4,6 @@
|
|||
(* TODO: move to [bytes] and replace all [mod] and [/] with bitshifts
|
||||
because width_=8 *)
|
||||
|
||||
(*$inject
|
||||
let ppli = CCFormat.(Dump.list int)
|
||||
*)
|
||||
|
||||
let width_ = Sys.word_size - 1
|
||||
|
||||
(** We use OCamls ints to store the bits. We index them from the
|
||||
|
|
@ -62,25 +58,8 @@ let create ~size default =
|
|||
{ a; size }
|
||||
)
|
||||
|
||||
(*$Q
|
||||
(Q.pair Q.small_int Q.bool) (fun (size, b) -> create ~size b |> length = size)
|
||||
*)
|
||||
|
||||
(*$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 = { bv with 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 capacity bv = width_ * Array.length bv.a
|
||||
|
||||
let cardinal bv =
|
||||
|
|
@ -93,10 +72,6 @@ let cardinal bv =
|
|||
!n
|
||||
)
|
||||
|
||||
(*$Q
|
||||
Q.small_int (fun size -> create ~size true |> cardinal = size)
|
||||
*)
|
||||
|
||||
let really_resize_ bv ~desired ~current size =
|
||||
let a' = Array.make desired 0 in
|
||||
Array.blit bv.a 0 a' 0 current;
|
||||
|
|
@ -127,15 +102,6 @@ let resize bv size =
|
|||
then ()
|
||||
else grow_ bv size
|
||||
|
||||
(*$R
|
||||
let bv1 = CCBV.create ~size:87 true in
|
||||
assert_equal ~printer:string_of_int 87 (CCBV.cardinal bv1);
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.small_int (fun n -> CCBV.cardinal (CCBV.create ~size:n true) = n)
|
||||
*)
|
||||
|
||||
let is_empty bv =
|
||||
try
|
||||
for i = 0 to Array.length bv.a - 1 do
|
||||
|
|
@ -153,22 +119,6 @@ let get bv i =
|
|||
then (Array.unsafe_get bv.a n) land (1 lsl i) <> 0
|
||||
else false
|
||||
|
||||
(*$R
|
||||
let bv = CCBV.create ~size:99 false in
|
||||
assert_bool "32 must be false" (not (CCBV.get bv 32));
|
||||
assert_bool "88 must be false" (not (CCBV.get bv 88));
|
||||
assert_bool "5 must be false" (not (CCBV.get bv 5));
|
||||
CCBV.set bv 32;
|
||||
CCBV.set bv 88;
|
||||
CCBV.set bv 5;
|
||||
assert_bool "32 must be true" (CCBV.get bv 32);
|
||||
assert_bool "88 must be true" (CCBV.get bv 88);
|
||||
assert_bool "5 must be true" (CCBV.get bv 5);
|
||||
assert_bool "33 must be false" (not (CCBV.get bv 33));
|
||||
assert_bool "44 must be false" (not (CCBV.get bv 44));
|
||||
assert_bool "1 must be false" (not (CCBV.get bv 1));
|
||||
*)
|
||||
|
||||
let set bv i =
|
||||
if i < 0 then invalid_arg "set: negative index"
|
||||
else (
|
||||
|
|
@ -178,11 +128,6 @@ let set bv i =
|
|||
Array.unsafe_set bv.a n ((Array.unsafe_get bv.a n) lor (1 lsl j))
|
||||
)
|
||||
|
||||
(*$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 =
|
||||
if i < 0 then invalid_arg "reset: negative index"
|
||||
else (
|
||||
|
|
@ -192,10 +137,6 @@ let reset bv i =
|
|||
Array.unsafe_set bv.a n ((Array.unsafe_get bv.a n) land (lnot (1 lsl j)))
|
||||
)
|
||||
|
||||
(*$T
|
||||
let bv = create ~size:3 false in set bv 0; reset bv 0; not (get bv 0)
|
||||
*)
|
||||
|
||||
let flip bv i =
|
||||
if i < 0 then invalid_arg "reset: negative index"
|
||||
else (
|
||||
|
|
@ -205,48 +146,13 @@ let flip bv i =
|
|||
Array.unsafe_set bv.a n ((Array.unsafe_get bv.a n) lxor (1 lsl j))
|
||||
)
|
||||
|
||||
(*$R
|
||||
let bv = of_list [1;10; 11; 30] in
|
||||
flip bv 10;
|
||||
assert_equal ~printer:Q.Print.(list int) [1;11;30] (to_sorted_list bv);
|
||||
assert_equal ~printer:Q.Print.bool false (get bv 10);
|
||||
flip bv 10;
|
||||
assert_equal ~printer:Q.Print.bool true (get bv 10);
|
||||
flip bv 5;
|
||||
assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30] (to_sorted_list bv);
|
||||
assert_equal ~printer:Q.Print.bool true (get bv 5);
|
||||
flip bv 100;
|
||||
assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30;100] (to_sorted_list bv);
|
||||
assert_equal ~printer:Q.Print.bool true (get bv 100);
|
||||
*)
|
||||
|
||||
let clear bv =
|
||||
Array.fill bv.a 0 (Array.length bv.a) 0
|
||||
|
||||
(*$T
|
||||
let bv = create ~size:37 true in cardinal bv = 37 && (clear bv; cardinal bv= 0)
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let bv = CCBV.of_list [1; 5; 200] in
|
||||
assert_equal ~printer:string_of_int 3 (CCBV.cardinal bv);
|
||||
CCBV.clear bv;
|
||||
assert_equal ~printer:string_of_int 0 (CCBV.cardinal bv);
|
||||
assert_bool "must be empty" (CCBV.is_empty bv);
|
||||
*)
|
||||
|
||||
let equal x y : bool =
|
||||
x.size = y.size &&
|
||||
x.a = y.a
|
||||
|
||||
(*$T
|
||||
equal (of_list [1; 3; 4]) (of_list [1; 3; 4])
|
||||
equal (empty()) (empty())
|
||||
not (equal (empty ()) (of_list [1]))
|
||||
not (equal (empty ()) (of_list [2; 5]))
|
||||
not (equal (of_list [1;3]) (of_list [2; 3]))
|
||||
*)
|
||||
|
||||
let iter bv f =
|
||||
let len = array_length_of_size bv.size in
|
||||
assert (len <= Array.length bv.a);
|
||||
|
|
@ -267,95 +173,14 @@ let iter bv f =
|
|||
done
|
||||
)
|
||||
|
||||
(*$R
|
||||
List.iter
|
||||
(fun size ->
|
||||
let bv = create ~size false in
|
||||
set bv 5;
|
||||
let n = ref 0 in
|
||||
iter bv (fun i b -> incr n; assert_equal b (i=5));
|
||||
assert_bool "exactly size" (!n = size))
|
||||
[30; 100; 255; 256;10_000]
|
||||
*)
|
||||
|
||||
(*$inject
|
||||
let iter_zip s k = s (fun x y -> k(x,y))
|
||||
*)
|
||||
|
||||
(*$= & ~printer:Q.Print.(list (pair int bool))
|
||||
[] (iter (create ~size:0 false) |> iter_zip |> Iter.to_list)
|
||||
[0, false; 1, true; 2, false] \
|
||||
(iter (let bv = create ~size:3 false in set bv 1; bv) |> iter_zip |> Iter.to_list)
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.(small_int) (fun n -> \
|
||||
assert (n >= 0); \
|
||||
let bv = create ~size:n true in \
|
||||
let l = iter bv |> iter_zip |> Iter.to_list in \
|
||||
List.length l = n && List.for_all (fun (_,b) -> b) l)
|
||||
*)
|
||||
|
||||
let[@inline] iter_true bv f =
|
||||
iter bv (fun i b -> if b then f i else ())
|
||||
|
||||
(*$T
|
||||
of_list [1;5;7] |> iter_true |> Iter.to_list |> List.sort CCOrd.compare = [1;5;7]
|
||||
*)
|
||||
|
||||
(*$inject
|
||||
let _gen = Q.Gen.(map of_list (list nat))
|
||||
let _pp bv = Q.Print.(list string) (List.map string_of_int (to_list bv))
|
||||
let _small bv = length bv
|
||||
|
||||
let gen_bv = Q.make ~small:_small ~print:_pp _gen
|
||||
*)
|
||||
|
||||
(*$QR
|
||||
gen_bv (fun bv ->
|
||||
let l' = Iter.to_rev_list (CCBV.iter_true bv) in
|
||||
let bv' = CCBV.of_list l' in
|
||||
CCBV.cardinal bv = CCBV.cardinal bv'
|
||||
)
|
||||
*)
|
||||
|
||||
let to_list bv =
|
||||
let l = ref [] in
|
||||
iter_true bv (fun i -> l := i :: !l);
|
||||
!l
|
||||
|
||||
(*$R
|
||||
let bv = CCBV.of_list [1; 5; 156; 0; 222] in
|
||||
assert_equal ~printer:string_of_int 5 (CCBV.cardinal bv);
|
||||
CCBV.set bv 201;
|
||||
assert_equal ~printer:string_of_int 6 (CCBV.cardinal bv);
|
||||
let l = CCBV.to_list bv in
|
||||
let l = List.sort compare l in
|
||||
assert_equal [0;1;5;156;201;222] l;
|
||||
*)
|
||||
|
||||
(*$= & ~printer:(CCFormat.to_string ppli)
|
||||
[1;2;3;4;64;130] (of_list [1;2;3;4;64;130] |> to_sorted_list)
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.(small_list small_nat) (fun l -> \
|
||||
let l = List.sort_uniq CCOrd.compare l in \
|
||||
let l2 = of_list l |> to_sorted_list in \
|
||||
if l=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l ppli l2)
|
||||
Q.(small_list small_nat) (fun l -> \
|
||||
let bv = of_list l in \
|
||||
let l1 = bv |> to_sorted_list in \
|
||||
let l2 = \
|
||||
(CCList.init (length bv) (get bv) |> List.mapi (fun i b->i,b) \
|
||||
|>CCList.filter_map (function (i,true) -> Some i| _ ->None)) in \
|
||||
if l1=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l1 ppli l2)
|
||||
*)
|
||||
|
||||
(*$= & ~cmp:equal ~printer:(CCFormat.to_string pp)
|
||||
(of_list [0]) (let bv=empty() in set bv 0; bv)
|
||||
*)
|
||||
|
||||
let to_sorted_list bv =
|
||||
List.rev (to_list bv)
|
||||
|
||||
|
|
@ -366,12 +191,6 @@ let of_list l =
|
|||
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_exn bv =
|
||||
|
|
@ -385,19 +204,10 @@ let first bv =
|
|||
try Some (first_exn bv)
|
||||
with Not_found -> None
|
||||
|
||||
(*$T
|
||||
of_list [50; 10; 17; 22; 3; 12] |> first = Some 3
|
||||
*)
|
||||
|
||||
let filter bv p =
|
||||
iter_true bv
|
||||
(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 negate_self b =
|
||||
let len = Array.length b.a in
|
||||
for n = 0 to len - 1 do
|
||||
|
|
@ -408,10 +218,6 @@ let negate_self b =
|
|||
let l = Array.length b.a - 1 in
|
||||
Array.unsafe_set b.a l (lsb_masks_.(r) land (Array.unsafe_get b.a l))
|
||||
|
||||
(*$= & ~printer:(CCFormat.to_string ppli)
|
||||
[0;3;4;6] (let v = of_list [1;2;5;7;] in negate_self v; to_sorted_list v)
|
||||
*)
|
||||
|
||||
let negate b =
|
||||
let a = Array.map (lnot) b.a in
|
||||
let r = b.size mod width_ in
|
||||
|
|
@ -421,10 +227,6 @@ let negate b =
|
|||
);
|
||||
{ a ; size = b.size }
|
||||
|
||||
(*$Q
|
||||
Q.small_int (fun size -> create ~size false |> negate |> cardinal = size)
|
||||
*)
|
||||
|
||||
let union_into_no_resize_ ~into bv =
|
||||
assert (Array.length into.a >= Array.length bv.a);
|
||||
for i = 0 to Array.length bv.a - 1 do
|
||||
|
|
@ -452,47 +254,6 @@ let union b1 b2 =
|
|||
into
|
||||
)
|
||||
|
||||
(*$R
|
||||
let bv1 = CCBV.of_list [1;2;3;4] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
let bv = CCBV.union bv1 bv2 in
|
||||
let l = List.sort compare (CCBV.to_list bv) in
|
||||
assert_equal ~printer:(CCFormat.(to_string (Dump.list int)))
|
||||
[1;2;3;4;200] l;
|
||||
()
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let bv1 = CCBV.of_list [1;2;3;4;64;130] in
|
||||
let bv2 = CCBV.of_list [4;64;3;120] in
|
||||
let bv = CCBV.union bv1 bv2 in
|
||||
assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp)
|
||||
(of_list [1;2;3;4;64;120;130]) bv;
|
||||
()
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let bv1 = CCBV.of_list [1;2;3;4] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
let bv = CCBV.union bv1 bv2 in
|
||||
assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp)
|
||||
(of_list [1;2;3;4;200]) bv;
|
||||
()
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let v1 = CCBV.empty () in
|
||||
let () = CCBV.set v1 64 in
|
||||
let v2 = CCBV.diff (CCBV.empty ()) (CCBV.empty ()) in
|
||||
let v3 = CCBV.union v1 v2 in
|
||||
assert_equal ~printer:(CCFormat.to_string pp) ~cmp:CCBV.equal v1 v3
|
||||
*)
|
||||
|
||||
(*$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_no_resize_ ~into bv =
|
||||
assert (Array.length into.a <= Array.length bv.a);
|
||||
for i = 0 to (Array.length into.a) - 1 do
|
||||
|
|
@ -518,28 +279,6 @@ let inter b1 b2 =
|
|||
into
|
||||
)
|
||||
|
||||
(*$T
|
||||
inter (of_list [1;2;3;4]) (of_list [2;4;6;1]) |> to_sorted_list = [1;2;4]
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let bv1 = CCBV.of_list [1;2;3;4;200;201] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
let bv = CCBV.inter bv1 bv2 in
|
||||
let l = List.sort compare (CCBV.to_list bv) in
|
||||
assert_equal ~printer:(CCFormat.(to_string (Dump.list int)))
|
||||
[3;4;200] l;
|
||||
()
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let bv1 = CCBV.of_list [1;2;3;4] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
CCBV.inter_into ~into:bv1 bv2;
|
||||
let l = List.sort compare (CCBV.to_list bv1) in
|
||||
assert_equal [3;4] l;
|
||||
*)
|
||||
|
||||
(* Underlying size depends on the 'in_' set for diff, so we don't change
|
||||
it's size! *)
|
||||
let diff_into ~into bv =
|
||||
|
|
@ -554,21 +293,6 @@ let diff in_ not_in =
|
|||
diff_into ~into not_in;
|
||||
into
|
||||
|
||||
(*$T
|
||||
diff (of_list [1;2;3]) (of_list [1;2;3]) |> to_list = [];
|
||||
diff (of_list [1;2;3]) (of_list [1;2;3;4]) |> to_list = [];
|
||||
diff (of_list [1;2;3;4]) (of_list [1;2;3]) |> to_list = [4];
|
||||
diff (of_list [1;2;3]) (of_list [1;2;3;400]) |> to_list = [];
|
||||
diff (of_list [1;2;3;400]) (of_list [1;2;3]) |> to_list = [400];
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let v1 = CCBV.empty () in
|
||||
set v1 65;
|
||||
let v2 = CCBV.diff v1 v1 in
|
||||
assert_bool (CCFormat.asprintf "bv: %a" pp v2) (CCBV.is_empty v2)
|
||||
*)
|
||||
|
||||
let select bv arr =
|
||||
let l = ref [] in
|
||||
begin try
|
||||
|
|
@ -581,13 +305,6 @@ let select bv arr =
|
|||
end;
|
||||
!l
|
||||
|
||||
(*$R
|
||||
let bv = CCBV.of_list [1;2;5;400] in
|
||||
let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in
|
||||
let l = List.sort compare (CCBV.select bv arr) in
|
||||
assert_equal ["b"; "c"; "f"] l;
|
||||
*)
|
||||
|
||||
let selecti bv arr =
|
||||
let l = ref [] in
|
||||
begin try
|
||||
|
|
@ -600,29 +317,10 @@ let selecti bv arr =
|
|||
end;
|
||||
!l
|
||||
|
||||
(*$R
|
||||
let bv = CCBV.of_list [1;2;5;400] in
|
||||
let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in
|
||||
let l = List.sort compare (CCBV.selecti bv arr) in
|
||||
assert_equal [("b",1); ("c",2); ("f",5)] l;
|
||||
*)
|
||||
|
||||
(*$= & ~printer:Q.Print.(list (pair int int))
|
||||
[1,1; 3,3; 4,4] (selecti (of_list [1;4;3]) [| 0;1;2;3;4;5;6;7;8 |] \
|
||||
|> List.sort CCOrd.compare)
|
||||
*)
|
||||
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
let to_iter bv k = iter_true bv k
|
||||
|
||||
(*$Q
|
||||
Q.(small_int) (fun i -> \
|
||||
let i = max 1 i in \
|
||||
let bv = create ~size:i true in \
|
||||
i = (to_iter bv |> Iter.length))
|
||||
*)
|
||||
|
||||
let of_iter seq =
|
||||
let l = ref [] and maxi = ref 0 in
|
||||
seq (fun x -> l := x :: !l; maxi := max !maxi x);
|
||||
|
|
@ -630,11 +328,6 @@ let of_iter seq =
|
|||
List.iter (fun i -> set bv i) !l;
|
||||
bv
|
||||
|
||||
(*$T
|
||||
CCList.range 0 10 |> CCList.to_iter |> of_iter |> to_iter \
|
||||
|> CCList.of_iter |> List.sort CCOrd.compare = CCList.range 0 10
|
||||
*)
|
||||
|
||||
let pp out bv =
|
||||
Format.pp_print_string out "bv {";
|
||||
iter bv
|
||||
|
|
@ -643,8 +336,4 @@ let pp out bv =
|
|||
);
|
||||
Format.pp_print_string out "}"
|
||||
|
||||
(*$= & ~printer:CCFun.id
|
||||
"bv {00001}" (CCFormat.to_string pp (of_list [4]))
|
||||
*)
|
||||
|
||||
let __to_word_l bv = Array.to_list bv.a
|
||||
|
|
|
|||
|
|
@ -117,17 +117,3 @@ module Make(L : OrderedType)(R : OrderedType) = struct
|
|||
|
||||
let to_iter m yield = MapL.iter (fun k v -> yield (k,v)) m.left
|
||||
end
|
||||
|
||||
(*$inject
|
||||
open Containers
|
||||
module M = Make(Int)(String)
|
||||
|
||||
*)
|
||||
|
||||
(*$=
|
||||
2 (M.of_list [1,"1"; 2, "2"] |> M.cardinal)
|
||||
"1" (M.of_list [1,"1"; 2, "2"] |> M.find_left 1)
|
||||
"2" (M.of_list [1,"1"; 2, "2"] |> M.find_left 2)
|
||||
1 (M.of_list [1,"1"; 2, "2"] |> M.find_right "1")
|
||||
2 (M.of_list [1,"1"; 2, "2"] |> M.find_right "2")
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -7,59 +7,6 @@ exception Frozen
|
|||
|
||||
let max_width = Sys.word_size - 2
|
||||
|
||||
(*$R
|
||||
let module B = CCBitField.Make(struct end) in
|
||||
let x = B.mk_field () in
|
||||
let y = B.mk_field () in
|
||||
let z = B.mk_field () in
|
||||
|
||||
let f = B.empty |> B.set x true |> B.set y true in
|
||||
|
||||
assert_bool "z_false" (not (B.get z f)) ;
|
||||
|
||||
assert_bool "z_true" (f |> B.set z true |> B.get z);
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let module B = CCBitField.Make(struct end) in
|
||||
let _ = B.mk_field () in
|
||||
B.freeze();
|
||||
assert_bool "must raise"
|
||||
(try ignore (B.mk_field()); false with Frozen -> true);
|
||||
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let module B = CCBitField.Make(struct end) in
|
||||
|
||||
let x = B.mk_field () in
|
||||
let y = B.mk_field () in
|
||||
let z = B.mk_field () in
|
||||
let u = B.mk_field () in
|
||||
B.freeze();
|
||||
|
||||
let f = B.empty
|
||||
|> B.set y true
|
||||
|> B.set z true
|
||||
in
|
||||
|
||||
assert_equal ~printer:CCInt.to_string 6 (f :> int) ;
|
||||
|
||||
assert_equal false (B.get x f) ;
|
||||
assert_equal true (B.get y f) ;
|
||||
assert_equal true (B.get z f);
|
||||
|
||||
let f' = B.set u true f in
|
||||
|
||||
assert_equal false (B.get x f') ;
|
||||
assert_equal true (B.get y f') ;
|
||||
assert_equal true (B.get z f');
|
||||
assert_equal true (B.get u f');
|
||||
|
||||
()
|
||||
*)
|
||||
|
||||
|
||||
module type S = sig
|
||||
type t = private int
|
||||
(** Generative type of bitfields. Each instantiation of the functor
|
||||
|
|
@ -94,13 +41,6 @@ let rec all_bits_ acc w =
|
|||
let acc = acc lor (1 lsl w-1) in
|
||||
all_bits_ acc (w-1)
|
||||
|
||||
(*$T
|
||||
all_bits_ 0 1 = 1
|
||||
all_bits_ 0 2 = 3
|
||||
all_bits_ 0 3 = 7
|
||||
all_bits_ 0 4 = 15
|
||||
*)
|
||||
|
||||
(* increment and return previous value *)
|
||||
let get_then_incr n =
|
||||
let x = !n in
|
||||
|
|
|
|||
|
|
@ -55,20 +55,6 @@ let with_cache_rec ?(cb=default_callback_) c f =
|
|||
let rec f' x = with_cache ~cb c (f f') x in
|
||||
f'
|
||||
|
||||
(*$R
|
||||
let c = unbounded ~eq:Int64.equal 256 in
|
||||
let fib = with_cache_rec c
|
||||
(fun self n -> match n with
|
||||
| 1L | 2L -> 1L
|
||||
| _ -> CCInt64.(self (n-1L) + self (n-2L))
|
||||
)
|
||||
in
|
||||
assert_equal 55L (fib 10L);
|
||||
assert_equal 832040L (fib 30L);
|
||||
assert_equal 12586269025L (fib 50L);
|
||||
assert_equal 190392490709135L (fib 70L)
|
||||
*)
|
||||
|
||||
let size c = c.size ()
|
||||
|
||||
let iter c f = c.iter f
|
||||
|
|
@ -311,36 +297,6 @@ let lru (type a) ~eq ?(hash=default_hash_) size =
|
|||
iter=L.iter c;
|
||||
}
|
||||
|
||||
(*$T
|
||||
let eq (i1,_)(i2,_) = i1=i2 and hash (i,_) = CCInt.hash i in \
|
||||
let c = lru ~eq ~hash 2 in \
|
||||
ignore (with_cache c CCFun.id (1, true)); \
|
||||
ignore (with_cache c CCFun.id (1, false)); \
|
||||
with_cache c CCFun.id (1, false) = (1, true)
|
||||
*)
|
||||
|
||||
(*$T
|
||||
let f = (let r = ref 0 in fun _ -> incr r; !r) in \
|
||||
let c = lru ~eq:CCInt.equal 2 in \
|
||||
let res1 = with_cache c f 1 in \
|
||||
let res2 = with_cache c f 2 in \
|
||||
let res3 = with_cache c f 3 in \
|
||||
let res1_bis = with_cache c f 1 in \
|
||||
res1 <> res2 && res2 <> res3 && res3 <> res1_bis && res1_bis <> res1
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let f = (let r = ref 0 in fun _ -> incr r; !r) in
|
||||
let c = lru ~eq:CCEqual.unit 2 in
|
||||
let x = with_cache c f () in
|
||||
assert_equal 1 x;
|
||||
assert_equal 1 (size c);
|
||||
clear c ;
|
||||
assert_equal 0 (size c);
|
||||
let y = with_cache c f () in
|
||||
assert_equal 2 y ;
|
||||
*)
|
||||
|
||||
module UNBOUNDED(X:HASH) = struct
|
||||
module H = Hashtbl.Make(X)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,24 +27,6 @@ type 'a t = {
|
|||
}
|
||||
(** The deque, a double linked list of cells *)
|
||||
|
||||
(*$inject
|
||||
let plist l = CCFormat.(to_string (list int)) l
|
||||
let pint i = string_of_int i
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let q = create () in
|
||||
add_iter_back q Iter.(3 -- 5);
|
||||
assert_equal [3;4;5] (to_list q);
|
||||
add_iter_front q Iter.(of_list [2;1]);
|
||||
assert_equal [1;2;3;4;5] (to_list q);
|
||||
push_front q 0;
|
||||
assert_equal [0;1;2;3;4;5] (to_list q);
|
||||
assert_equal 5 (take_back q);
|
||||
assert_equal 0 (take_front q);
|
||||
assert_equal 4 (length q);
|
||||
*)
|
||||
|
||||
exception Empty
|
||||
|
||||
let create () =
|
||||
|
|
@ -55,15 +37,6 @@ let clear q =
|
|||
q.size <- 0;
|
||||
()
|
||||
|
||||
(*$R
|
||||
let q = of_iter Iter.(1 -- 100) in
|
||||
assert_equal 100 (length q);
|
||||
clear q;
|
||||
assert_equal 0 (length q);
|
||||
assert_raises Empty (fun () -> peek_front q);
|
||||
assert_raises Empty (fun () -> peek_back q);
|
||||
*)
|
||||
|
||||
let incr_size_ d = d.size <- d.size + 1
|
||||
let decr_size_ d = d.size <- d.size - 1
|
||||
|
||||
|
|
@ -121,24 +94,6 @@ let peek_front d = match peek_front_opt d with
|
|||
| None -> raise Empty
|
||||
| Some x -> x
|
||||
|
||||
(*$T
|
||||
of_list [1;2;3] |> peek_front = 1
|
||||
try (ignore (of_list [] |> peek_front); false) with Empty -> true
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let d = of_iter Iter.(1 -- 10) in
|
||||
let printer = pint in
|
||||
OUnit2.assert_equal ~printer 1 (peek_front d);
|
||||
push_front d 42;
|
||||
OUnit2.assert_equal ~printer 42 (peek_front d);
|
||||
OUnit2.assert_equal ~printer 42 (take_front d);
|
||||
OUnit2.assert_equal ~printer 1 (take_front d);
|
||||
OUnit2.assert_equal ~printer 2 (take_front d);
|
||||
OUnit2.assert_equal ~printer 3 (take_front d);
|
||||
OUnit2.assert_equal ~printer 10 (peek_back d);
|
||||
*)
|
||||
|
||||
let peek_back_opt d =
|
||||
match d.cur with
|
||||
| Empty -> None
|
||||
|
|
@ -151,23 +106,6 @@ let peek_back_opt d =
|
|||
let peek_back d = match peek_back_opt d with
|
||||
| None -> raise Empty
|
||||
| Some x -> x
|
||||
(*$T
|
||||
of_list [1;2;3] |> peek_back = 3
|
||||
try (ignore (of_list [] |> peek_back); false) with Empty -> true
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let d = of_iter Iter.(1 -- 10) in
|
||||
let printer = pint in
|
||||
OUnit2.assert_equal ~printer 1 (peek_front d);
|
||||
push_back d 42;
|
||||
OUnit2.assert_equal ~printer 42 (peek_back d);
|
||||
OUnit2.assert_equal ~printer 42 (take_back d);
|
||||
OUnit2.assert_equal ~printer 10 (take_back d);
|
||||
OUnit2.assert_equal ~printer 9 (take_back d);
|
||||
OUnit2.assert_equal ~printer 8 (take_back d);
|
||||
OUnit2.assert_equal ~printer 1 (peek_front d);
|
||||
*)
|
||||
|
||||
let take_back_node_ n = match n.cell with
|
||||
| One x -> (true, x)
|
||||
|
|
@ -203,22 +141,11 @@ let take_back d = match take_back_opt d with
|
|||
| None -> raise Empty
|
||||
| Some x -> x
|
||||
|
||||
(*$T
|
||||
let q = of_list [1] in take_back q = 1 && to_list q = []
|
||||
let q = of_list [1;2] in take_back q = 2 && to_list q = [1]
|
||||
let q = of_list [1;2;3] in take_back q = 3 && to_list q = [1;2]
|
||||
let q = of_list [1;2;3;4;5;6;7;] in take_back q = 7 && to_list q = [1;2;3;4;5;6]
|
||||
*)
|
||||
|
||||
let take_front_node_ n = match n.cell with
|
||||
| One x -> (true, x)
|
||||
| Two (x,y) -> n.cell <- One y; (false, x)
|
||||
| Three (x,y,z) -> n.cell <- Two (y,z); (false, x)
|
||||
|
||||
(*$T
|
||||
let q = of_list [1;2;3] in take_front q = 1 && to_list q = [2;3]
|
||||
*)
|
||||
|
||||
let take_front_opt d =
|
||||
match d.cur with
|
||||
| Empty -> None
|
||||
|
|
@ -247,16 +174,8 @@ let take_front d = match take_front_opt d with
|
|||
|
||||
let remove_back d = ignore (take_back_opt d)
|
||||
|
||||
(*$T remove_back
|
||||
let q = of_list [1;2;3;4;5;6;7] in remove_back q; to_list q = [1;2;3;4;5;6]
|
||||
*)
|
||||
|
||||
let remove_front d = ignore (take_front_opt d)
|
||||
|
||||
(*$T remove_front
|
||||
let q = of_list [1;2;3;4;5;6;7] in remove_front q; to_list q = [2;3;4;5;6;7]
|
||||
*)
|
||||
|
||||
let update_front d f =
|
||||
match d.cur with
|
||||
| Empty -> ()
|
||||
|
|
@ -285,23 +204,6 @@ let update_front d f =
|
|||
| Some x -> cur.cell <- Three (x,y,z)
|
||||
end
|
||||
|
||||
(*$T update_front
|
||||
let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> None); to_list q = [2;3;4;5;6;7]
|
||||
let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> Some 9); to_list q = [9;2;3;4;5;6;7]
|
||||
*)
|
||||
(*$Q update_front
|
||||
Q.(list int) (fun l -> \
|
||||
let q = of_list l in \
|
||||
update_front q (fun _ -> None); \
|
||||
let output_list = if l = [] then [] else List.tl l in \
|
||||
to_list q = output_list)
|
||||
Q.(list int) (fun l -> \
|
||||
let q = of_list l in \
|
||||
update_front q (fun x -> Some (x + 42)); \
|
||||
let output_list = if l = [] then [] else List.((hd l + 42)::(tl l)) in \
|
||||
to_list q = output_list)
|
||||
*)
|
||||
|
||||
let update_back d f =
|
||||
match d.cur with
|
||||
| Empty -> ()
|
||||
|
|
@ -326,23 +228,6 @@ let update_back d f =
|
|||
| Some z -> n.cell <- Three (x,y,z)
|
||||
end
|
||||
|
||||
(*$T update_back
|
||||
let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> None); to_list q = [1;2;3;4;5;6]
|
||||
let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> Some 9); to_list q = [1;2;3;4;5;6;9]
|
||||
*)
|
||||
(*$Q update_back
|
||||
Q.(list int) (fun l -> \
|
||||
let q = of_list l in \
|
||||
update_back q (fun _ -> None); \
|
||||
let output_list = if l = [] then [] else List.(rev l |> tl) in \
|
||||
(to_list q |> List.rev) = output_list)
|
||||
Q.(list int) (fun l -> \
|
||||
let q = of_list l in \
|
||||
update_back q (fun x -> Some (x + 42)); \
|
||||
let output_list = if l = [] then [] else List.(rev l |> fun l -> (hd l + 42)::(tl l)) in \
|
||||
(to_list q |> List.rev) = output_list)
|
||||
*)
|
||||
|
||||
let iter f d =
|
||||
let rec iter f ~first n =
|
||||
begin match n.cell with
|
||||
|
|
@ -357,29 +242,10 @@ let iter f d =
|
|||
| Node cur ->
|
||||
iter f ~first:cur cur
|
||||
|
||||
(*$T
|
||||
let n = ref 0 in iter (fun _ -> incr n) (of_list [1;2;3]); !n = 3
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let d = of_iter Iter.(1 -- 5) in
|
||||
let s = Iter.from_iter (fun k -> iter k d) in
|
||||
let l = Iter.to_list s in
|
||||
OUnit2.assert_equal ~printer:plist [1;2;3;4;5] l;
|
||||
*)
|
||||
|
||||
let append_front ~into q = iter (push_front into) q
|
||||
|
||||
let append_back ~into q = iter (push_back into) q
|
||||
|
||||
(*$R
|
||||
let q = of_list [3;4] in
|
||||
append_front ~into:q (of_list [2;1]);
|
||||
assert_equal [1;2;3;4] (to_list q);
|
||||
append_back ~into:q (of_list [5;6]);
|
||||
assert_equal [1;2;3;4;5;6] (to_list q);
|
||||
*)
|
||||
|
||||
let fold f acc d =
|
||||
let rec aux ~first f acc n =
|
||||
let acc = match n.cell with
|
||||
|
|
@ -394,26 +260,8 @@ let fold f acc d =
|
|||
| Node cur ->
|
||||
aux ~first:cur f acc cur
|
||||
|
||||
(*$T
|
||||
fold (+) 0 (of_list [1;2;3]) = 6
|
||||
fold (fun acc x -> x::acc) [] (of_list [1;2;3]) = [3;2;1]
|
||||
*)
|
||||
|
||||
let length d = d.size
|
||||
|
||||
(*$Q
|
||||
Q.(list int) (fun l -> \
|
||||
let q = of_list l in \
|
||||
append_front ~into:q (of_list l); \
|
||||
append_back ~into:q (of_list l); \
|
||||
length q = 3 * List.length l)
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let d = of_iter Iter.(1 -- 10) in
|
||||
OUnit2.assert_equal ~printer:pint 10 (length d)
|
||||
*)
|
||||
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
type 'a gen = unit -> 'a option
|
||||
|
||||
|
|
@ -421,14 +269,6 @@ let add_iter_back q seq = seq (fun x -> push_back q x)
|
|||
|
||||
let add_iter_front q seq = seq (fun x -> push_front q x)
|
||||
|
||||
(*$R
|
||||
let q = of_list [4;5] in
|
||||
add_iter_front q Iter.(of_list [3;2;1]);
|
||||
assert_equal [1;2;3;4;5] (to_list q);
|
||||
add_iter_back q Iter.(of_list [6;7]);
|
||||
assert_equal [1;2;3;4;5;6;7] (to_list q);
|
||||
*)
|
||||
|
||||
let of_iter seq =
|
||||
let deque = create () in
|
||||
seq (fun x -> push_back deque x);
|
||||
|
|
@ -436,24 +276,11 @@ let of_iter seq =
|
|||
|
||||
let to_iter d k = iter k d
|
||||
|
||||
(*$Q
|
||||
Q.(list int) (fun l -> \
|
||||
Iter.of_list l |> of_iter |> to_iter |> Iter.to_list = l)
|
||||
*)
|
||||
|
||||
let of_list l =
|
||||
let q = create() in
|
||||
List.iter (push_back q) l;
|
||||
q
|
||||
|
||||
(*$R
|
||||
let q = of_list [1;2;3] in
|
||||
assert_equal 1 (take_front q);
|
||||
assert_equal 3 (take_back q);
|
||||
assert_equal 2 (take_front q);
|
||||
assert_equal true (is_empty q)
|
||||
*)
|
||||
|
||||
let to_rev_list q = fold (fun l x -> x::l) [] q
|
||||
|
||||
let to_list q = List.rev (to_rev_list q)
|
||||
|
|
@ -546,37 +373,11 @@ let filter_in_place (d:_ t) f : unit =
|
|||
cur.cell <- c;
|
||||
loop ~stop_at:cur cur.next
|
||||
|
||||
(*$R
|
||||
let q = of_list [1;2;3;4;5;6] in
|
||||
filter_in_place q (fun x -> x mod 2 = 0);
|
||||
assert_equal [2;4;6] (to_list q)
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let q = of_list [2;1;4;6;10;20] in
|
||||
filter_in_place q (fun x -> x mod 2 = 0);
|
||||
assert_equal [2;4;6;10;20] (to_list q)
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.(list small_nat) (fun l -> \
|
||||
let f = fun x -> x mod 2=0 in \
|
||||
let q = of_list l in \
|
||||
(filter_in_place q f; to_list q) = (List.filter f l))
|
||||
*)
|
||||
|
||||
let filter f q =
|
||||
let q' = create() in
|
||||
iter (fun x -> if f x then push_back q' x) q;
|
||||
q'
|
||||
|
||||
(*$Q
|
||||
Q.(list small_nat) (fun l -> \
|
||||
let f = fun x -> x mod 2=0 in \
|
||||
let q = filter f (of_list l) in \
|
||||
(to_list q) = (List.filter f l))
|
||||
*)
|
||||
|
||||
let filter_map f q =
|
||||
let q' = create() in
|
||||
iter (fun x -> match f x with None -> () | Some y -> push_back q' y) q;
|
||||
|
|
@ -613,35 +414,12 @@ let to_gen q =
|
|||
in
|
||||
next
|
||||
|
||||
(*$T
|
||||
of_list [1;2;3] |> to_gen |> of_gen |> to_list = [1;2;3]
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.(list int) (fun l -> \
|
||||
of_list l |> to_gen |> of_gen |> to_list = l)
|
||||
*)
|
||||
|
||||
(* naive implem of copy, for now *)
|
||||
let copy d =
|
||||
let d' = create () in
|
||||
iter (fun x -> push_back d' x) d;
|
||||
d'
|
||||
|
||||
(*$R
|
||||
let q = of_list [1;2;3;4] in
|
||||
assert_equal 4 (length q);
|
||||
let q' = copy q in
|
||||
let cmp = equal ~eq:CCInt.equal in
|
||||
assert_equal 4 (length q');
|
||||
assert_equal ~cmp q q';
|
||||
push_front q 0;
|
||||
assert_bool "not equal" (not (cmp q q'));
|
||||
assert_equal 5 (length q);
|
||||
push_front q' 0;
|
||||
assert_equal ~cmp q q'
|
||||
*)
|
||||
|
||||
let equal ~eq a b =
|
||||
let rec aux eq a b = match a() , b() with
|
||||
| None, None -> true
|
||||
|
|
@ -660,12 +438,6 @@ let compare ~cmp a b =
|
|||
if c=0 then aux cmp a b else c
|
||||
in aux cmp (to_gen a) (to_gen b)
|
||||
|
||||
(*$Q
|
||||
Q.(pair (list int) (list int)) (fun (l1,l2) -> \
|
||||
CCOrd.equiv (compare ~cmp:Stdlib.compare (of_list l1) (of_list l2)) \
|
||||
(CCList.compare Stdlib.compare l1 l2))
|
||||
*)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
|
||||
let pp pp_x out d =
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ module type S = sig
|
|||
?printer:('a -> string) -> ?cmp:('a -> 'a -> bool) ->
|
||||
'a -> 'a -> unit
|
||||
|
||||
val assert_bool : string -> bool -> unit
|
||||
|
||||
val assert_failure : string -> 'a
|
||||
|
||||
val assert_raises : (exn -> bool) -> (unit -> 'b) -> unit
|
||||
|
|
@ -142,6 +144,11 @@ module Make_test(X:sig val file: string end) = struct
|
|||
failwith @@ spf "not equal: lhs=%s, rhs=%s" (p x) (p y)
|
||||
)
|
||||
|
||||
let assert_bool what b =
|
||||
if not b then (
|
||||
failwith what
|
||||
)
|
||||
|
||||
let assert_failure s = failwith s
|
||||
|
||||
let assert_raises check f =
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ module type S = sig
|
|||
?printer:('a -> string) -> ?cmp:('a -> 'a -> bool) ->
|
||||
'a -> 'a -> unit
|
||||
|
||||
val assert_bool : string -> bool -> unit
|
||||
|
||||
val assert_failure : string -> 'a
|
||||
|
||||
val assert_raises : (exn -> bool) -> (unit -> 'b) -> unit
|
||||
|
|
|
|||
|
|
@ -62,20 +62,6 @@ let take q =
|
|||
Condition.broadcast q.cond;
|
||||
x)
|
||||
|
||||
(*$R
|
||||
let q = create 1 in
|
||||
let t1 = CCThread.spawn (fun () -> push q 1; push q 2) in
|
||||
let t2 = CCThread.spawn (fun () -> push q 3; push q 4) in
|
||||
let l = CCLock.create [] in
|
||||
let t3 = CCThread.spawn (fun () -> for i = 1 to 4 do
|
||||
let x = take q in
|
||||
CCLock.update l (fun l -> x :: l)
|
||||
done)
|
||||
in
|
||||
Thread.join t1; Thread.join t2; Thread.join t3;
|
||||
assert_equal [1;2;3;4] (List.sort Stdlib.compare (CCLock.get l))
|
||||
*)
|
||||
|
||||
let push_list q l =
|
||||
(* push elements until it's not possible.
|
||||
Assumes the lock is acquired. *)
|
||||
|
|
@ -131,35 +117,6 @@ let take_list q n =
|
|||
in
|
||||
aux [] q n
|
||||
|
||||
(*$R
|
||||
let n = 1000 in
|
||||
let lists = [| CCList.(1 -- n) ; CCList.(n+1 -- 2*n); CCList.(2*n+1 -- 3*n) |] in
|
||||
let q = create 2 in
|
||||
let senders = CCThread.Arr.spawn 3
|
||||
(fun i ->
|
||||
if i=1
|
||||
then push_list q lists.(i) (* test push_list *)
|
||||
else List.iter (push q) lists.(i)
|
||||
)
|
||||
in
|
||||
let res = CCLock.create [] in
|
||||
let receivers = CCThread.Arr.spawn 3
|
||||
(fun i ->
|
||||
if i=1 then
|
||||
let l = take_list q n in
|
||||
CCLock.update res (fun acc -> l @ acc)
|
||||
else
|
||||
for _j = 1 to n do
|
||||
let x = take q in
|
||||
CCLock.update res (fun acc -> x::acc)
|
||||
done
|
||||
)
|
||||
in
|
||||
CCThread.Arr.join senders; CCThread.Arr.join receivers;
|
||||
let l = CCLock.get res |> List.sort Stdlib.compare in
|
||||
assert_equal CCList.(1 -- 3*n) l
|
||||
*)
|
||||
|
||||
let try_take q =
|
||||
with_lock_ q
|
||||
(fun () ->
|
||||
|
|
|
|||
|
|
@ -25,16 +25,6 @@ let with_lock l f =
|
|||
Mutex.unlock l.mutex;
|
||||
raise e
|
||||
|
||||
(*$R
|
||||
let l = create 0 in
|
||||
let try_incr l =
|
||||
update l (fun x -> Thread.yield(); x+1)
|
||||
in
|
||||
for i = 1 to 10 do ignore (Thread.create try_incr l) done;
|
||||
Thread.delay 0.10 ;
|
||||
assert_equal 10 (get l)
|
||||
*)
|
||||
|
||||
let try_with_lock l f =
|
||||
if Mutex.try_lock l.mutex
|
||||
then
|
||||
|
|
@ -64,35 +54,11 @@ let with_lock_as_ref l ~f =
|
|||
Mutex.unlock l.mutex;
|
||||
raise e
|
||||
|
||||
(*$R
|
||||
let l = create 0 in
|
||||
let test_it l =
|
||||
with_lock_as_ref l
|
||||
~f:(fun r ->
|
||||
(* increment and decrement *)
|
||||
for j = 0 to 100 do
|
||||
let x = LockRef.get r in
|
||||
LockRef.set r (x+10);
|
||||
if j mod 5=0 then Thread.yield ();
|
||||
let y = LockRef.get r in
|
||||
LockRef.set r (y - 10);
|
||||
done
|
||||
)
|
||||
in
|
||||
for i = 1 to 100 do ignore (Thread.create test_it l) done;
|
||||
Thread.delay 0.10;
|
||||
assert_equal 0 (get l)
|
||||
*)
|
||||
|
||||
let mutex l = l.mutex
|
||||
|
||||
let update l f =
|
||||
with_lock l (fun x -> l.content <- f x)
|
||||
|
||||
(*$T
|
||||
let l = create 5 in update l (fun x->x+1); get l = 6
|
||||
*)
|
||||
|
||||
let update_map l f =
|
||||
with_lock l
|
||||
(fun x ->
|
||||
|
|
@ -100,10 +66,6 @@ let update_map l f =
|
|||
l.content <- x';
|
||||
y)
|
||||
|
||||
(*$T
|
||||
let l = create 5 in update_map l (fun x->x+1, string_of_int x) = "5" && get l = 6
|
||||
*)
|
||||
|
||||
let get l =
|
||||
Mutex.lock l.mutex;
|
||||
let x = l.content in
|
||||
|
|
@ -115,28 +77,10 @@ let set l x =
|
|||
l.content <- x;
|
||||
Mutex.unlock l.mutex
|
||||
|
||||
(*$T
|
||||
let l = create 0 in set l 4; get l = 4
|
||||
let l = create 0 in set l 4; set l 5; get l = 5
|
||||
*)
|
||||
|
||||
let incr l = update l Stdlib.succ
|
||||
|
||||
let decr l = update l Stdlib.pred
|
||||
|
||||
|
||||
(*$R
|
||||
let l = create 0 in
|
||||
let a = Array.init 100 (fun _ -> Thread.create (fun _ -> incr l) ()) in
|
||||
Array.iter Thread.join a;
|
||||
assert_equal ~printer:CCInt.to_string 100 (get l)
|
||||
*)
|
||||
|
||||
(*$T
|
||||
let l = create 0 in incr l ; get l = 1
|
||||
let l = create 0 in decr l ; get l = ~-1
|
||||
*)
|
||||
|
||||
let incr_then_get l =
|
||||
Mutex.lock l.mutex;
|
||||
l.content <- l.content + 1;
|
||||
|
|
@ -165,13 +109,6 @@ let get_then_decr l =
|
|||
Mutex.unlock l.mutex;
|
||||
x
|
||||
|
||||
(*$T
|
||||
let l = create 0 in 1 = incr_then_get l && 1 = get l
|
||||
let l = create 0 in 0 = get_then_incr l && 1 = get l
|
||||
let l = create 10 in 9 = decr_then_get l && 9 = get l
|
||||
let l = create 10 in 10 = get_then_decr l && 9 = get l
|
||||
*)
|
||||
|
||||
let get_then_set l =
|
||||
Mutex.lock l.mutex;
|
||||
let x = l.content in
|
||||
|
|
|
|||
|
|
@ -15,13 +15,6 @@ end
|
|||
|
||||
exception Stopped
|
||||
|
||||
(*$inject
|
||||
module P = Make(struct let max_size = 30 end)
|
||||
module P2 = Make(struct let max_size = 15 end)
|
||||
module Fut = P.Fut
|
||||
module Fut2 = P2.Fut
|
||||
*)
|
||||
|
||||
(** {2 Thread pool} *)
|
||||
module Make(P : PARAM) = struct
|
||||
type job =
|
||||
|
|
@ -293,38 +286,6 @@ module Make(P : PARAM) = struct
|
|||
|
||||
let make f = make1 f ()
|
||||
|
||||
(*$R
|
||||
List.iter
|
||||
(fun n ->
|
||||
let l = Iter.(1 -- n) |> Iter.to_list in
|
||||
let l = List.rev_map (fun i ->
|
||||
Fut.make
|
||||
(fun () ->
|
||||
Thread.delay 0.01;
|
||||
1
|
||||
)) l in
|
||||
let l' = List.map Fut.get l in
|
||||
OUnit2.assert_equal n (List.fold_left (+) 0 l');
|
||||
)
|
||||
[ 10; 300; ]
|
||||
*)
|
||||
|
||||
(*$R
|
||||
List.iter
|
||||
(fun n ->
|
||||
let l = Iter.(1 -- n) |> Iter.to_list in
|
||||
let l = List.rev_map (fun i ->
|
||||
Fut2.make
|
||||
(fun () ->
|
||||
Thread.delay 0.01;
|
||||
1
|
||||
)) l in
|
||||
let l' = List.map Fut2.get l in
|
||||
OUnit2.assert_equal n (List.fold_left (+) 0 l');
|
||||
)
|
||||
[ 10; 300; ]
|
||||
*)
|
||||
|
||||
|
||||
let make2 f x y =
|
||||
let cell = create_cell() in
|
||||
|
|
@ -439,27 +400,6 @@ module Make(P : PARAM) = struct
|
|||
|
||||
let app_async f x = app_ ~async:true f x
|
||||
|
||||
(*$R
|
||||
let a = Fut.make (fun () -> 1) in
|
||||
let b = Fut.return 42 in
|
||||
let c = Fut.monoid_product CCPair.make a b in
|
||||
OUnit2.assert_equal (1,42) (Fut.get c)
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let a = Fut.make (fun () -> 1) in
|
||||
let b = Fut.make (fun () -> 42) in
|
||||
let c = Fut.monoid_product CCPair.make a b in
|
||||
OUnit2.assert_equal (1,42) (Fut.get c)
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let a = Fut.make (fun () -> 1) in
|
||||
let b = Fut.map succ @@ Fut.make (fun () -> 41) in
|
||||
let c = Fut.monoid_product CCPair.make a b in
|
||||
OUnit2.assert_equal (1,42) (Fut.get c)
|
||||
*)
|
||||
|
||||
let monoid_product f x y = match x, y with
|
||||
| Return x, Return y -> Return (f x y)
|
||||
| FailNow e, _
|
||||
|
|
@ -568,96 +508,6 @@ module Make(P : PARAM) = struct
|
|||
sequence_ (L_ l)
|
||||
(fun () -> List.rev_map get_nolock_ l)
|
||||
|
||||
(*$=
|
||||
[2;3] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) [1;2])
|
||||
[] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) [])
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut.make (fun () -> Thread.delay 0.1; x*10))
|
||||
|> Fut.sequence_l
|
||||
|> Fut.map (List.fold_left (+) 0)
|
||||
in
|
||||
let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in
|
||||
OUnit2.assert_equal expected (Fut.get l')
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let l = CCList.(1 -- 100_000) in
|
||||
let l' = l
|
||||
|> CCList.map
|
||||
(fun x -> Fut.make (fun () -> 1))
|
||||
|> Fut.sequence_l
|
||||
|> Fut.map (List.fold_left (+) 0)
|
||||
in
|
||||
let expected = 100_000 in
|
||||
OUnit2.assert_equal expected (Fut.get l')
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x))
|
||||
|> Fut.sequence_l
|
||||
|> Fut.map (List.fold_left (+) 0)
|
||||
in
|
||||
OUnit2.assert_raises Exit (fun () -> Fut.get l')
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in
|
||||
let l =
|
||||
CCList.(1--10_000)
|
||||
|> List.rev_map
|
||||
(fun x-> Fut.make (fun () -> Thread.yield(); fib (x mod 20)))
|
||||
|> Fut.(map_l (fun x->x>|= fun x->x+1))
|
||||
in
|
||||
OUnit2.assert_bool "not done" (Fut.state l = Waiting);
|
||||
let l' = Fut.get l in
|
||||
OUnit2.assert_equal 10_000 (List.length l');
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut2.make (fun () -> Thread.delay 0.1; x*10))
|
||||
|> Fut2.sequence_l
|
||||
|> Fut2.map (List.fold_left (+) 0)
|
||||
in
|
||||
let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in
|
||||
OUnit2.assert_equal expected (Fut2.get l')
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut2.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x))
|
||||
|> Fut2.sequence_l
|
||||
|> Fut2.map (List.fold_left (+) 0)
|
||||
in
|
||||
OUnit2.assert_raises Exit (fun () -> Fut2.get l')
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in
|
||||
let l =
|
||||
CCList.(1--10_000)
|
||||
|> List.rev_map
|
||||
(fun x-> Fut2.make (fun () -> Thread.yield(); fib (x mod 20)))
|
||||
|> Fut2.(map_l (fun x->x>|= fun x->x+1))
|
||||
in
|
||||
OUnit2.assert_bool "not done" (Fut2.state l = Waiting);
|
||||
let l' = Fut2.get l in
|
||||
OUnit2.assert_equal 10_000 (List.length l');
|
||||
*)
|
||||
|
||||
|
||||
let choose_
|
||||
: type a. a t array_or_list -> a t
|
||||
= fun aol ->
|
||||
|
|
@ -682,28 +532,6 @@ module Make(P : PARAM) = struct
|
|||
|
||||
let sleep time = make1 Thread.delay time
|
||||
|
||||
(*$R
|
||||
let start = Unix.gettimeofday () in
|
||||
let pause = 0.2 and n = 10 in
|
||||
let l = CCList.(1 -- n)
|
||||
|> List.map (fun _ -> Fut.make (fun () -> Thread.delay pause))
|
||||
in
|
||||
List.iter Fut.get l;
|
||||
let stop = Unix.gettimeofday () in
|
||||
OUnit2.assert_bool "some_parallelism" (stop -. start < float_of_int n *. pause);
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let start = Unix.gettimeofday () in
|
||||
let pause = 0.2 and n = 10 in
|
||||
let l = CCList.(1 -- n)
|
||||
|> List.map (fun _ -> Fut2.make (fun () -> Thread.delay pause))
|
||||
in
|
||||
List.iter Fut2.get l;
|
||||
let stop = Unix.gettimeofday () in
|
||||
OUnit2.assert_bool "some_parallelism" (stop -. start < float_of_int n *. pause);
|
||||
*)
|
||||
|
||||
module Infix = struct
|
||||
let (>>=) x f = flat_map f x
|
||||
let (>>) a f = and_then a f
|
||||
|
|
|
|||
|
|
@ -40,18 +40,6 @@ let release m t =
|
|||
release_once_locked_ m t;
|
||||
()
|
||||
|
||||
(*$R
|
||||
let s = create 1 in
|
||||
let r = CCLock.create false in
|
||||
let _ = Thread.create (fun s -> acquire 5 s; CCLock.set r true) s in
|
||||
Thread.yield ();
|
||||
assert_equal false (CCLock.get r);
|
||||
release 4 s;
|
||||
Thread.delay 0.2;
|
||||
assert_equal true (CCLock.get r);
|
||||
assert_equal 0 (get s)
|
||||
*)
|
||||
|
||||
let with_acquire ~n t ~f =
|
||||
acquire n t;
|
||||
try
|
||||
|
|
@ -62,22 +50,6 @@ let with_acquire ~n t ~f =
|
|||
release n t;
|
||||
raise e
|
||||
|
||||
(*$R
|
||||
let s = create 5 in
|
||||
let n = CCLock.create 0 in
|
||||
let a = Array.init 100 (fun i ->
|
||||
Thread.create (fun _ ->
|
||||
for _i = 1 to 100 do
|
||||
with_acquire ~n:(1 + (i mod 5)) s
|
||||
~f:(fun () -> Thread.yield(); CCLock.incr n)
|
||||
done)
|
||||
())
|
||||
in
|
||||
Array.iter Thread.join a;
|
||||
assert_equal ~printer:CCInt.to_string 5 (get s);
|
||||
assert_equal ~printer:CCInt.to_string 10_000 (CCLock.get n)
|
||||
*)
|
||||
|
||||
let wait_until_at_least ~n t ~f =
|
||||
Mutex.lock t.mutex;
|
||||
while t.n < n do
|
||||
|
|
@ -86,33 +58,3 @@ let wait_until_at_least ~n t ~f =
|
|||
assert (t.n >= n);
|
||||
Mutex.unlock t.mutex;
|
||||
f ()
|
||||
|
||||
(*$R
|
||||
let output s = () in
|
||||
let s = create 2 in
|
||||
let res = CCLock.create false in
|
||||
let id = Thread.create
|
||||
(fun () ->
|
||||
output "start";
|
||||
wait_until_at_least ~n:5 s
|
||||
~f:(fun () ->
|
||||
assert (get s >= 5);
|
||||
output "modify now";
|
||||
CCLock.set res true)
|
||||
) ()
|
||||
in
|
||||
output "launched thread";
|
||||
Thread.yield();
|
||||
assert_bool "start" (not (CCLock.get res));
|
||||
output "release 2";
|
||||
release 2 s;
|
||||
Thread.yield();
|
||||
assert_bool "after release 2" (not (CCLock.get res));
|
||||
output "release 1";
|
||||
release 1 s;
|
||||
(* should work now *)
|
||||
Thread.delay 0.2;
|
||||
Thread.join id;
|
||||
output "check";
|
||||
assert_bool "after release 1" (CCLock.get res)
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -28,14 +28,6 @@ module Arr = struct
|
|||
let join a = Array.iter Thread.join a
|
||||
end
|
||||
|
||||
(*$R
|
||||
let l = CCLock.create 0 in
|
||||
let a = Arr.spawn 101 (fun i -> CCLock.update l ((+) i)) in
|
||||
Arr.join a;
|
||||
let n = Iter.(1 -- 100 |> fold (+) 0) in
|
||||
assert_equal ~printer:CCInt.to_string n (CCLock.get l)
|
||||
*)
|
||||
|
||||
module Barrier = struct
|
||||
type t = {
|
||||
lock: Mutex.t;
|
||||
|
|
@ -71,15 +63,3 @@ module Barrier = struct
|
|||
|
||||
let activated b = with_lock_ b (fun () -> b.activated)
|
||||
end
|
||||
|
||||
(*$R
|
||||
let b = Barrier.create () in
|
||||
let res = CCLock.create 0 in
|
||||
let t1 = spawn (fun _ -> Barrier.wait b; CCLock.incr res)
|
||||
and t2 = spawn (fun _ -> Barrier.wait b; CCLock.incr res) in
|
||||
Thread.delay 0.2;
|
||||
assert_equal 0 (CCLock.get res);
|
||||
Barrier.activate b;
|
||||
Thread.join t1; Thread.join t2;
|
||||
assert_equal 2 (CCLock.get res)
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
|
||||
(* This file is free software, part of containers. See file "license" for more details. *)
|
||||
|
||||
(** {1 Event timer} *)
|
||||
|
||||
type job =
|
||||
| Job : float * (unit -> 'a) -> job
|
||||
|
||||
|
|
@ -153,27 +149,6 @@ let every ?delay timer d ~f =
|
|||
| None -> run()
|
||||
| Some d -> after timer d ~f:run
|
||||
|
||||
(*$R
|
||||
let start = Unix.gettimeofday() in
|
||||
let timer = create() in
|
||||
let res = CCLock.create 0 in
|
||||
let sem = CCSemaphore.create 1 in
|
||||
CCSemaphore.acquire 1 sem;
|
||||
let stop = ref 0. in
|
||||
every timer 0.1
|
||||
~f:(fun () ->
|
||||
if CCLock.incr_then_get res > 5 then (
|
||||
stop := Unix.gettimeofday();
|
||||
CCSemaphore.release 1 sem;
|
||||
raise ExitEvery
|
||||
));
|
||||
CCSemaphore.acquire 1 sem; (* wait *)
|
||||
OUnit2.assert_equal ~printer:CCInt.to_string 6 (CCLock.get res);
|
||||
OUnit2.assert_bool "delay >= 0.5" (!stop -. start >= 0.49999);
|
||||
OUnit2.assert_bool "delay < 2." (!stop -. start < 2.);
|
||||
*)
|
||||
(* NOTE: could be tighter bounds, but travis' mac OS seems to be dog slow. *)
|
||||
|
||||
let active timer = not timer.stop
|
||||
|
||||
(** Stop the given timer, cancelling pending tasks *)
|
||||
|
|
@ -188,18 +163,3 @@ let stop timer =
|
|||
awaken_ timer;
|
||||
)
|
||||
)
|
||||
|
||||
(*$R
|
||||
(* scenario: n := 1; n := n*4 ; n := n+2; res := n *)
|
||||
let timer = create () in
|
||||
let n = CCLock.create 1 in
|
||||
let res = CCLock.create 0 in
|
||||
after timer 0.3
|
||||
~f:(fun () -> CCLock.update n (fun x -> x+2));
|
||||
ignore (Thread.create
|
||||
(fun _ -> Thread.delay 0.4; CCLock.set res (CCLock.get n)) ());
|
||||
after timer 0.1
|
||||
~f:(fun () -> CCLock.update n (fun x -> x * 4));
|
||||
Thread.delay 0.6 ;
|
||||
OUnit2.assert_equal ~printer:Q.Print.int 6 (CCLock.get res);
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
(* This file is free software, part of containers. See file "license" for more details. *)
|
||||
|
||||
(** {1 Event timer}
|
||||
(** Event timer
|
||||
|
||||
Used to be part of [CCFuture].
|
||||
@since 0.16 *)
|
||||
|
|
|
|||
5
tests/data/dune
Normal file
5
tests/data/dune
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
(test
|
||||
(name t)
|
||||
(flags :standard -strict-sequence -warn-error -a+8 -open CCShims_)
|
||||
(modes native)
|
||||
(libraries containers containers-data containers_testlib iter))
|
||||
8
tests/data/t.ml
Normal file
8
tests/data/t.ml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
Containers_testlib.run_all ~descr:"containers-data" [
|
||||
T_bv.Test.get();
|
||||
T_bijection.Test.get();
|
||||
T_bitfield.Test.get();
|
||||
T_cache.Test.get();
|
||||
T_deque.Test.get();
|
||||
];;
|
||||
13
tests/data/t_bijection.ml
Normal file
13
tests/data/t_bijection.ml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCBijection;;
|
||||
|
||||
module M = Make(Int)(String);;
|
||||
|
||||
|
||||
eq 2 (M.of_list [1,"1"; 2, "2"] |> M.cardinal);;
|
||||
eq "1" (M.of_list [1,"1"; 2, "2"] |> M.find_left 1);;
|
||||
eq "2" (M.of_list [1,"1"; 2, "2"] |> M.find_left 2);;
|
||||
eq 1 (M.of_list [1,"1"; 2, "2"] |> M.find_right "1");;
|
||||
eq 2 (M.of_list [1,"1"; 2, "2"] |> M.find_right "2");;
|
||||
59
tests/data/t_bitfield.ml
Normal file
59
tests/data/t_bitfield.ml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCBitField;;
|
||||
|
||||
t @@ fun () ->
|
||||
let module B = CCBitField.Make(struct end) in
|
||||
let x = B.mk_field () in
|
||||
let y = B.mk_field () in
|
||||
let z = B.mk_field () in
|
||||
|
||||
let f = B.empty |> B.set x true |> B.set y true in
|
||||
|
||||
assert_bool "z_false" (not (B.get z f)) ;
|
||||
|
||||
assert_bool "z_true" (f |> B.set z true |> B.get z);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let module B = CCBitField.Make(struct end) in
|
||||
let _ = B.mk_field () in
|
||||
B.freeze();
|
||||
assert_bool "must raise"
|
||||
(try ignore (B.mk_field()); false with Frozen -> true);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let module B = CCBitField.Make(struct end) in
|
||||
|
||||
let x = B.mk_field () in
|
||||
let y = B.mk_field () in
|
||||
let z = B.mk_field () in
|
||||
let u = B.mk_field () in
|
||||
B.freeze();
|
||||
|
||||
let f = B.empty
|
||||
|> B.set y true
|
||||
|> B.set z true
|
||||
in
|
||||
|
||||
assert_equal ~printer:CCInt.to_string 6 (f :> int) ;
|
||||
|
||||
assert_equal false (B.get x f) ;
|
||||
assert_equal true (B.get y f) ;
|
||||
assert_equal true (B.get z f);
|
||||
|
||||
let f' = B.set u true f in
|
||||
|
||||
assert_equal false (B.get x f') ;
|
||||
assert_equal true (B.get y f') ;
|
||||
assert_equal true (B.get z f');
|
||||
assert_equal true (B.get u f');
|
||||
true;;
|
||||
|
||||
t @@ fun () -> all_bits_ 0 1 = 1;;
|
||||
t @@ fun () -> all_bits_ 0 2 = 3;;
|
||||
t @@ fun () -> all_bits_ 0 3 = 7;;
|
||||
t @@ fun () -> all_bits_ 0 4 = 15;;
|
||||
249
tests/data/t_bv.ml
Normal file
249
tests/data/t_bv.ml
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCBV;;
|
||||
|
||||
let ppli = CCFormat.(Dump.list int);;
|
||||
|
||||
q (Q.pair Q.small_int Q.bool) (fun (size, b) -> create ~size b |> length = size);;
|
||||
|
||||
t @@ fun () -> create ~size:17 true |> cardinal = 17;;
|
||||
t @@ fun () -> create ~size:32 true |> cardinal = 32;;
|
||||
t @@ fun () -> create ~size:132 true |> cardinal = 132;;
|
||||
t @@ fun () -> create ~size:200 false |> cardinal = 0;;
|
||||
t @@ fun () -> create ~size:29 true |> to_sorted_list = CCList.range 0 28;;
|
||||
|
||||
q (Q.list Q.small_int) (fun l ->
|
||||
let bv = of_list l in to_list bv = to_list (copy bv));;
|
||||
|
||||
q Q.small_int (fun size -> create ~size true |> cardinal = size);;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv1 = CCBV.create ~size:87 true in
|
||||
assert_equal ~printer:string_of_int 87 (CCBV.cardinal bv1);
|
||||
true;;
|
||||
|
||||
q Q.small_int (fun n -> CCBV.cardinal (CCBV.create ~size:n true) = n);;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv = CCBV.create ~size:99 false in
|
||||
assert_bool "32 must be false" (not (CCBV.get bv 32));
|
||||
assert_bool "88 must be false" (not (CCBV.get bv 88));
|
||||
assert_bool "5 must be false" (not (CCBV.get bv 5));
|
||||
CCBV.set bv 32;
|
||||
CCBV.set bv 88;
|
||||
CCBV.set bv 5;
|
||||
assert_bool "32 must be true" (CCBV.get bv 32);
|
||||
assert_bool "88 must be true" (CCBV.get bv 88);
|
||||
assert_bool "5 must be true" (CCBV.get bv 5);
|
||||
assert_bool "33 must be false" (not (CCBV.get bv 33));
|
||||
assert_bool "44 must be false" (not (CCBV.get bv 44));
|
||||
assert_bool "1 must be false" (not (CCBV.get bv 1));
|
||||
true;;
|
||||
|
||||
t @@ fun () -> let bv = create ~size:3 false in set bv 0; get bv 0;;
|
||||
t @@ fun () -> let bv = create ~size:3 false in set bv 1; not (get bv 0);;
|
||||
t @@ fun () -> let bv = create ~size:3 false in set bv 0; reset bv 0; not (get bv 0);;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv = of_list [1;10; 11; 30] in
|
||||
flip bv 10;
|
||||
assert_equal ~printer:Q.Print.(list int) [1;11;30] (to_sorted_list bv);
|
||||
assert_equal ~printer:Q.Print.bool false (get bv 10);
|
||||
flip bv 10;
|
||||
assert_equal ~printer:Q.Print.bool true (get bv 10);
|
||||
flip bv 5;
|
||||
assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30] (to_sorted_list bv);
|
||||
assert_equal ~printer:Q.Print.bool true (get bv 5);
|
||||
flip bv 100;
|
||||
assert_equal ~printer:Q.Print.(list int) [1;5;10;11;30;100] (to_sorted_list bv);
|
||||
assert_equal ~printer:Q.Print.bool true (get bv 100);
|
||||
true;;
|
||||
|
||||
t @@ fun () -> let bv = create ~size:37 true in cardinal bv = 37 && (clear bv; cardinal bv= 0);;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv = CCBV.of_list [1; 5; 200] in
|
||||
assert_equal ~printer:string_of_int 3 (CCBV.cardinal bv);
|
||||
CCBV.clear bv;
|
||||
assert_equal ~printer:string_of_int 0 (CCBV.cardinal bv);
|
||||
assert_bool "must be empty" (CCBV.is_empty bv);
|
||||
true;;
|
||||
|
||||
t @@ fun () -> equal (of_list [1; 3; 4]) (of_list [1; 3; 4]);;
|
||||
t @@ fun () -> equal (empty()) (empty());;
|
||||
t @@ fun () -> not (equal (empty ()) (of_list [1]));;
|
||||
t @@ fun () -> not (equal (empty ()) (of_list [2; 5]));;
|
||||
t @@ fun () -> not (equal (of_list [1;3]) (of_list [2; 3]));;
|
||||
|
||||
t @@ fun () ->
|
||||
List.iter
|
||||
(fun size ->
|
||||
let bv = create ~size false in
|
||||
set bv 5;
|
||||
let n = ref 0 in
|
||||
iter bv (fun i b -> incr n; assert_equal b (i=5));
|
||||
assert_bool "exactly size" (!n = size))
|
||||
[30; 100; 255; 256;10_000];
|
||||
true;;
|
||||
|
||||
let iter_zip s k = s (fun x y -> k(x,y));;
|
||||
|
||||
let eq' = eq ~printer:Q.Print.(list (pair int bool)) ;;
|
||||
eq' [] (iter (create ~size:0 false) |> iter_zip |> Iter.to_list);;
|
||||
eq' [0, false; 1, true; 2, false]
|
||||
(iter (let bv = create ~size:3 false in set bv 1; bv) |> iter_zip |> Iter.to_list);;
|
||||
|
||||
q Q.(small_int) (fun n ->
|
||||
assert (n >= 0);
|
||||
let bv = create ~size:n true in
|
||||
let l = iter bv |> iter_zip |> Iter.to_list in
|
||||
List.length l = n && List.for_all (fun (_,b) -> b) l);;
|
||||
|
||||
t @@ fun () -> of_list [1;5;7] |> iter_true |> Iter.to_list |> List.sort CCOrd.poly = [1;5;7];;
|
||||
|
||||
let _gen = Q.Gen.(map of_list (list nat))
|
||||
let _pp bv = Q.Print.(list string) (List.map string_of_int (to_list bv))
|
||||
let _small bv = length bv
|
||||
|
||||
let gen_bv = Q.make ~small:_small ~print:_pp _gen;;
|
||||
|
||||
q gen_bv (fun bv ->
|
||||
let l' = Iter.to_rev_list (CCBV.iter_true bv) in
|
||||
let bv' = CCBV.of_list l' in
|
||||
CCBV.cardinal bv = CCBV.cardinal bv'
|
||||
);;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv = CCBV.of_list [1; 5; 156; 0; 222] in
|
||||
assert_equal ~printer:string_of_int 5 (CCBV.cardinal bv);
|
||||
CCBV.set bv 201;
|
||||
assert_equal ~printer:string_of_int 6 (CCBV.cardinal bv);
|
||||
let l = CCBV.to_list bv in
|
||||
let l = List.sort compare l in
|
||||
assert_equal [0;1;5;156;201;222] l;
|
||||
true;;
|
||||
|
||||
eq ~printer:(CCFormat.to_string ppli)
|
||||
[1;2;3;4;64;130] (of_list [1;2;3;4;64;130] |> to_sorted_list);;
|
||||
|
||||
q Q.(small_list small_nat) (fun l ->
|
||||
let l = List.sort_uniq CCOrd.poly l in
|
||||
let l2 = of_list l |> to_sorted_list in
|
||||
if l=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l ppli l2);;
|
||||
q Q.(small_list small_nat) (fun l ->
|
||||
let bv = of_list l in
|
||||
let l1 = bv |> to_sorted_list in
|
||||
let l2 =
|
||||
(CCList.init (length bv) (get bv) |> List.mapi (fun i b->i,b)
|
||||
|>CCList.filter_map (function (i,true) -> Some i| _ ->None)) in
|
||||
if l1=l2 then true else Q.Test.fail_reportf "l1=%a, l2=%a" ppli l1 ppli l2) ;;
|
||||
|
||||
eq ~cmp:equal ~printer:(CCFormat.to_string pp)
|
||||
(of_list [0]) (let bv=empty() in set bv 0; bv);;
|
||||
|
||||
t @@ fun () -> of_list [1;32;64] |> CCFun.flip get 64;;
|
||||
t @@ fun () -> of_list [1;32;64] |> CCFun.flip get 32;;
|
||||
t @@ fun () -> of_list [1;31;63] |> CCFun.flip get 63;;
|
||||
t @@ fun () -> of_list [50; 10; 17; 22; 3; 12] |> first = Some 3;;
|
||||
t @@ fun () -> 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];;
|
||||
|
||||
eq ~printer:(CCFormat.to_string ppli)
|
||||
[0;3;4;6] (let v = of_list [1;2;5;7;] in negate_self v; to_sorted_list v);;
|
||||
|
||||
q Q.small_int (fun size -> create ~size false |> negate |> cardinal = size);;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv1 = CCBV.of_list [1;2;3;4] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
let bv = CCBV.union bv1 bv2 in
|
||||
let l = List.sort compare (CCBV.to_list bv) in
|
||||
assert_equal ~printer:(CCFormat.(to_string (Dump.list int)))
|
||||
[1;2;3;4;200] l;
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv1 = CCBV.of_list [1;2;3;4;64;130] in
|
||||
let bv2 = CCBV.of_list [4;64;3;120] in
|
||||
let bv = CCBV.union bv1 bv2 in
|
||||
assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp)
|
||||
(of_list [1;2;3;4;64;120;130]) bv;
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv1 = CCBV.of_list [1;2;3;4] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
let bv = CCBV.union bv1 bv2 in
|
||||
assert_equal ~cmp:equal ~printer:(CCFormat.to_string pp)
|
||||
(of_list [1;2;3;4;200]) bv;
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let v1 = CCBV.empty () in
|
||||
let () = CCBV.set v1 64 in
|
||||
let v2 = CCBV.diff (CCBV.empty ()) (CCBV.empty ()) in
|
||||
let v3 = CCBV.union v1 v2 in
|
||||
assert_equal ~printer:(CCFormat.to_string pp) ~cmp:CCBV.equal v1 v3;
|
||||
true;;
|
||||
|
||||
t @@ fun () -> union (of_list [1;2;3;4;5]) (of_list [7;3;5;6]) |> to_sorted_list = CCList.range 1 7;;
|
||||
t @@ fun () -> inter (of_list [1;2;3;4]) (of_list [2;4;6;1]) |> to_sorted_list = [1;2;4];;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv1 = CCBV.of_list [1;2;3;4;200;201] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
let bv = CCBV.inter bv1 bv2 in
|
||||
let l = List.sort compare (CCBV.to_list bv) in
|
||||
assert_equal ~printer:(CCFormat.(to_string (Dump.list int)))
|
||||
[3;4;200] l;
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv1 = CCBV.of_list [1;2;3;4] in
|
||||
let bv2 = CCBV.of_list [4;200;3] in
|
||||
CCBV.inter_into ~into:bv1 bv2;
|
||||
let l = List.sort compare (CCBV.to_list bv1) in
|
||||
assert_equal [3;4] l;
|
||||
true;;
|
||||
|
||||
t @@ fun () -> diff (of_list [1;2;3]) (of_list [1;2;3]) |> to_list = [];;
|
||||
t @@ fun () -> diff (of_list [1;2;3]) (of_list [1;2;3;4]) |> to_list = [];;
|
||||
t @@ fun () -> diff (of_list [1;2;3;4]) (of_list [1;2;3]) |> to_list = [4];;
|
||||
t @@ fun () -> diff (of_list [1;2;3]) (of_list [1;2;3;400]) |> to_list = [];;
|
||||
t @@ fun () -> diff (of_list [1;2;3;400]) (of_list [1;2;3]) |> to_list = [400];;
|
||||
|
||||
t @@ fun () ->
|
||||
let v1 = CCBV.empty () in
|
||||
set v1 65;
|
||||
let v2 = CCBV.diff v1 v1 in
|
||||
CCBV.is_empty v2 ;;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv = CCBV.of_list [1;2;5;400] in
|
||||
let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in
|
||||
let l = List.sort compare (CCBV.select bv arr) in
|
||||
assert_equal ["b"; "c"; "f"] l;
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let bv = CCBV.of_list [1;2;5;400] in
|
||||
let arr = [|"a"; "b"; "c"; "d"; "e"; "f"|] in
|
||||
let l = List.sort compare (CCBV.selecti bv arr) in
|
||||
assert_equal [("b",1); ("c",2); ("f",5)] l;
|
||||
true;;
|
||||
|
||||
eq ~printer:Q.Print.(list (pair int int))
|
||||
[1,1; 3,3; 4,4] (selecti (of_list [1;4;3]) [| 0;1;2;3;4;5;6;7;8 |]
|
||||
|> List.sort CCOrd.poly);;
|
||||
|
||||
q Q.(small_int) (fun i ->
|
||||
let i = max 1 i in
|
||||
let bv = create ~size:i true in
|
||||
i = (to_iter bv |> Iter.length));;
|
||||
|
||||
t @@ fun () -> CCList.range 0 10 |> CCList.to_iter |> of_iter |> to_iter
|
||||
|> CCList.of_iter |> List.sort CCOrd.poly = CCList.range 0 10;;
|
||||
|
||||
eq ~printer:CCFun.id
|
||||
"bv {00001}" (CCFormat.to_string pp (of_list [4]));;
|
||||
47
tests/data/t_cache.ml
Normal file
47
tests/data/t_cache.ml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCCache;;
|
||||
|
||||
t @@ fun () ->
|
||||
let c = unbounded ~eq:Int64.equal 256 in
|
||||
let fib = with_cache_rec c
|
||||
(fun self n -> match n with
|
||||
| 1L | 2L -> 1L
|
||||
| _ -> CCInt64.(self (n-1L) + self (n-2L))
|
||||
)
|
||||
in
|
||||
assert_equal 55L (fib 10L);
|
||||
assert_equal 832040L (fib 30L);
|
||||
assert_equal 12586269025L (fib 50L);
|
||||
assert_equal 190392490709135L (fib 70L);
|
||||
true;;
|
||||
|
||||
|
||||
t @@ fun () ->
|
||||
let eq (i1,_)(i2,_) = i1=i2 and hash (i,_) = CCInt.hash i in
|
||||
let c = lru ~eq ~hash 2 in
|
||||
ignore (with_cache c CCFun.id (1, true));
|
||||
ignore (with_cache c CCFun.id (1, false));
|
||||
with_cache c CCFun.id (1, false) = (1, true);;
|
||||
|
||||
t @@ fun () ->
|
||||
let f = (let r = ref 0 in fun _ -> incr r; !r) in
|
||||
let c = lru ~eq:CCInt.equal 2 in
|
||||
let res1 = with_cache c f 1 in
|
||||
let res2 = with_cache c f 2 in
|
||||
let res3 = with_cache c f 3 in
|
||||
let res1_bis = with_cache c f 1 in
|
||||
res1 <> res2 && res2 <> res3 && res3 <> res1_bis && res1_bis <> res1;;
|
||||
|
||||
t @@ fun () ->
|
||||
let f = (let r = ref 0 in fun _ -> incr r; !r) in
|
||||
let c = lru ~eq:CCEqual.unit 2 in
|
||||
let x = with_cache c f () in
|
||||
assert_equal 1 x;
|
||||
assert_equal 1 (size c);
|
||||
clear c ;
|
||||
assert_equal 0 (size c);
|
||||
let y = with_cache c f () in
|
||||
assert_equal 2 y;
|
||||
true;;
|
||||
193
tests/data/t_deque.ml
Normal file
193
tests/data/t_deque.ml
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCDeque;;
|
||||
|
||||
let plist l = CCFormat.(to_string (list int)) l
|
||||
let pint i = string_of_int i;;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = create () in
|
||||
add_iter_back q Iter.(3 -- 5);
|
||||
assert_equal [3;4;5] (to_list q);
|
||||
add_iter_front q Iter.(of_list [2;1]);
|
||||
assert_equal [1;2;3;4;5] (to_list q);
|
||||
push_front q 0;
|
||||
assert_equal [0;1;2;3;4;5] (to_list q);
|
||||
assert_equal 5 (take_back q);
|
||||
assert_equal 0 (take_front q);
|
||||
assert_equal 4 (length q);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = of_iter Iter.(1 -- 100) in
|
||||
assert_equal 100 (length q);
|
||||
clear q;
|
||||
assert_equal 0 (length q);
|
||||
assert_raises ((=)Empty) (fun () -> peek_front q);
|
||||
assert_raises ((=)Empty) (fun () -> peek_back q);
|
||||
true;;
|
||||
|
||||
t @@ fun () -> of_list [1;2;3] |> peek_front = 1;;
|
||||
t @@ fun () -> try (ignore (of_list [] |> peek_front); false) with Empty -> true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let d = of_iter Iter.(1 -- 10) in
|
||||
let printer = pint in
|
||||
assert_equal ~printer 1 (peek_front d);
|
||||
push_front d 42;
|
||||
assert_equal ~printer 42 (peek_front d);
|
||||
assert_equal ~printer 42 (take_front d);
|
||||
assert_equal ~printer 1 (take_front d);
|
||||
assert_equal ~printer 2 (take_front d);
|
||||
assert_equal ~printer 3 (take_front d);
|
||||
assert_equal ~printer 10 (peek_back d);
|
||||
true;;
|
||||
|
||||
t @@ fun () -> of_list [1;2;3] |> peek_back = 3;;
|
||||
t @@ fun () -> try (ignore (of_list [] |> peek_back); false) with Empty -> true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let d = of_iter Iter.(1 -- 10) in
|
||||
let printer = pint in
|
||||
assert_equal ~printer 1 (peek_front d);
|
||||
push_back d 42;
|
||||
assert_equal ~printer 42 (peek_back d);
|
||||
assert_equal ~printer 42 (take_back d);
|
||||
assert_equal ~printer 10 (take_back d);
|
||||
assert_equal ~printer 9 (take_back d);
|
||||
assert_equal ~printer 8 (take_back d);
|
||||
assert_equal ~printer 1 (peek_front d);
|
||||
true;;
|
||||
|
||||
t @@ fun () -> let q = of_list [1] in take_back q = 1 && to_list q = [];;
|
||||
t @@ fun () -> let q = of_list [1;2] in take_back q = 2 && to_list q = [1];;
|
||||
t @@ fun () -> let q = of_list [1;2;3] in take_back q = 3 && to_list q = [1;2];;
|
||||
t @@ fun () -> let q = of_list [1;2;3;4;5;6;7;] in take_back q = 7 && to_list q = [1;2;3;4;5;6];;
|
||||
|
||||
t @@ fun () -> let q = of_list [1;2;3] in take_front q = 1 && to_list q = [2;3];;
|
||||
t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in remove_back q; to_list q = [1;2;3;4;5;6];;
|
||||
t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in remove_front q; to_list q = [2;3;4;5;6;7];;
|
||||
t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> None); to_list q = [2;3;4;5;6;7];;
|
||||
t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_front q (fun _ -> Some 9); to_list q = [9;2;3;4;5;6;7];;
|
||||
|
||||
q Q.(list int) (fun l ->
|
||||
let q = of_list l in
|
||||
update_front q (fun _ -> None);
|
||||
let output_list = if l = [] then [] else List.tl l in
|
||||
to_list q = output_list) ;;
|
||||
q Q.(list int) (fun l ->
|
||||
let q = of_list l in
|
||||
update_front q (fun x -> Some (x + 42));
|
||||
let output_list = if l = [] then [] else List.((hd l + 42)::(tl l)) in
|
||||
to_list q = output_list) ;;
|
||||
|
||||
t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> None); to_list q = [1;2;3;4;5;6];;
|
||||
t @@ fun () -> let q = of_list [1;2;3;4;5;6;7] in update_back q (fun _ -> Some 9); to_list q = [1;2;3;4;5;6;9];;
|
||||
|
||||
q Q.(list int) (fun l ->
|
||||
let q = of_list l in
|
||||
update_back q (fun _ -> None);
|
||||
let output_list = if l = [] then [] else List.(rev l |> tl) in
|
||||
(to_list q |> List.rev) = output_list);;
|
||||
q Q.(list int) (fun l ->
|
||||
let q = of_list l in
|
||||
update_back q (fun x -> Some (x + 42));
|
||||
let output_list = if l = [] then [] else List.(rev l |> fun l -> (hd l + 42)::(tl l)) in
|
||||
(to_list q |> List.rev) = output_list);;
|
||||
|
||||
t @@ fun () -> let n = ref 0 in iter (fun _ -> incr n) (of_list [1;2;3]); !n = 3;;
|
||||
|
||||
t @@ fun () ->
|
||||
let d = of_iter Iter.(1 -- 5) in
|
||||
let s = Iter.from_iter (fun k -> iter k d) in
|
||||
let l = Iter.to_list s in
|
||||
assert_equal ~printer:plist [1;2;3;4;5] l;
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = of_list [3;4] in
|
||||
append_front ~into:q (of_list [2;1]);
|
||||
assert_equal [1;2;3;4] (to_list q);
|
||||
append_back ~into:q (of_list [5;6]);
|
||||
assert_equal [1;2;3;4;5;6] (to_list q);
|
||||
true;;
|
||||
|
||||
t @@ fun () -> fold (+) 0 (of_list [1;2;3]) = 6;;
|
||||
t @@ fun () -> fold (fun acc x -> x::acc) [] (of_list [1;2;3]) = [3;2;1];;
|
||||
|
||||
q Q.(list int) (fun l ->
|
||||
let q = of_list l in
|
||||
append_front ~into:q (of_list l);
|
||||
append_back ~into:q (of_list l);
|
||||
length q = 3 * List.length l);;
|
||||
|
||||
|
||||
t @@ fun () ->
|
||||
let d = of_iter Iter.(1 -- 10) in
|
||||
assert_equal ~printer:pint 10 (length d);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = of_list [4;5] in
|
||||
add_iter_front q Iter.(of_list [3;2;1]);
|
||||
assert_equal [1;2;3;4;5] (to_list q);
|
||||
add_iter_back q Iter.(of_list [6;7]);
|
||||
assert_equal [1;2;3;4;5;6;7] (to_list q);
|
||||
true;;
|
||||
|
||||
q Q.(list int) (fun l ->
|
||||
Iter.of_list l |> of_iter |> to_iter |> Iter.to_list = l);;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = of_list [1;2;3] in
|
||||
assert_equal 1 (take_front q);
|
||||
assert_equal 3 (take_back q);
|
||||
assert_equal 2 (take_front q);
|
||||
assert_equal true (is_empty q);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = of_list [1;2;3;4;5;6] in
|
||||
filter_in_place q (fun x -> x mod 2 = 0);
|
||||
assert_equal [2;4;6] (to_list q);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = of_list [2;1;4;6;10;20] in
|
||||
filter_in_place q (fun x -> x mod 2 = 0);
|
||||
assert_equal [2;4;6;10;20] (to_list q);
|
||||
true;;
|
||||
|
||||
q Q.(list small_nat) (fun l ->
|
||||
let f = fun x -> x mod 2=0 in
|
||||
let q = of_list l in
|
||||
(filter_in_place q f; to_list q) = (List.filter f l));;
|
||||
|
||||
q Q.(list small_nat) (fun l ->
|
||||
let f = fun x -> x mod 2=0 in
|
||||
let q = filter f (of_list l) in
|
||||
(to_list q) = (List.filter f l));;
|
||||
|
||||
t @@ fun () -> of_list [1;2;3] |> to_gen |> of_gen |> to_list = [1;2;3];;
|
||||
|
||||
q Q.(list int) (fun l ->
|
||||
of_list l |> to_gen |> of_gen |> to_list = l);;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = of_list [1;2;3;4] in
|
||||
assert_equal 4 (length q);
|
||||
let q' = copy q in
|
||||
let cmp = equal ~eq:CCInt.equal in
|
||||
assert_equal 4 (length q');
|
||||
assert_equal ~cmp q q';
|
||||
push_front q 0;
|
||||
assert_bool "not equal" (not (cmp q q'));
|
||||
assert_equal 5 (length q);
|
||||
push_front q' 0;
|
||||
assert_equal ~cmp q q';
|
||||
true;;
|
||||
|
||||
q Q.(pair (list int) (list int)) (fun (l1,l2) ->
|
||||
CCOrd.equiv (compare ~cmp:Stdlib.compare (of_list l1) (of_list l2))
|
||||
(CCList.compare Stdlib.compare l1 l2));;
|
||||
5
tests/thread/dune
Normal file
5
tests/thread/dune
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
(test
|
||||
(name t)
|
||||
(flags :standard -strict-sequence -warn-error -a+8 -open CCShims_)
|
||||
(modes native)
|
||||
(libraries containers containers-thread containers_testlib iter threads))
|
||||
9
tests/thread/t.ml
Normal file
9
tests/thread/t.ml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
Containers_testlib.run_all ~descr:"containers-thread" [
|
||||
T_bq.Test.get();
|
||||
T_lock.Test.get();
|
||||
T_pool.Test.get();
|
||||
T_semaphore.Test.get();
|
||||
T_thread.Test.get();
|
||||
T_timer.Test.get();
|
||||
];;
|
||||
47
tests/thread/t_bq.ml
Normal file
47
tests/thread/t_bq.ml
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCBlockingQueue;;
|
||||
|
||||
t @@ fun () ->
|
||||
let q = create 1 in
|
||||
let t1 = CCThread.spawn (fun () -> push q 1; push q 2) in
|
||||
let t2 = CCThread.spawn (fun () -> push q 3; push q 4) in
|
||||
let l = CCLock.create [] in
|
||||
let t3 = CCThread.spawn (fun () -> for _i = 1 to 4 do
|
||||
let x = take q in
|
||||
CCLock.update l (fun l -> x :: l)
|
||||
done)
|
||||
in
|
||||
Thread.join t1; Thread.join t2; Thread.join t3;
|
||||
assert_equal [1;2;3;4] (List.sort Stdlib.compare (CCLock.get l));
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let n = 1000 in
|
||||
let lists = [| CCList.(1 -- n) ; CCList.(n+1 -- 2*n); CCList.(2*n+1 -- 3*n) |] in
|
||||
let q = create 2 in
|
||||
let senders = CCThread.Arr.spawn 3
|
||||
(fun i ->
|
||||
if i=1
|
||||
then push_list q lists.(i) (* test push_list *)
|
||||
else List.iter (push q) lists.(i)
|
||||
)
|
||||
in
|
||||
let res = CCLock.create [] in
|
||||
let receivers = CCThread.Arr.spawn 3
|
||||
(fun i ->
|
||||
if i=1 then
|
||||
let l = take_list q n in
|
||||
CCLock.update res (fun acc -> l @ acc)
|
||||
else
|
||||
for _j = 1 to n do
|
||||
let x = take q in
|
||||
CCLock.update res (fun acc -> x::acc)
|
||||
done
|
||||
)
|
||||
in
|
||||
CCThread.Arr.join senders; CCThread.Arr.join receivers;
|
||||
let l = CCLock.get res |> List.sort Stdlib.compare in
|
||||
assert_equal CCList.(1 -- 3*n) l;
|
||||
true
|
||||
53
tests/thread/t_lock.ml
Normal file
53
tests/thread/t_lock.ml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test;;
|
||||
open CCLock;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = create 0 in
|
||||
let try_incr l =
|
||||
update l (fun x -> Thread.yield(); x+1)
|
||||
in
|
||||
for _i = 1 to 10 do ignore (Thread.create try_incr l) done;
|
||||
Thread.delay 0.10 ;
|
||||
assert_equal 10 (get l);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = create 0 in
|
||||
let test_it l =
|
||||
with_lock_as_ref l
|
||||
~f:(fun r ->
|
||||
(* increment and decrement *)
|
||||
for j = 0 to 100 do
|
||||
let x = LockRef.get r in
|
||||
LockRef.set r (x+10);
|
||||
if j mod 5=0 then Thread.yield ();
|
||||
let y = LockRef.get r in
|
||||
LockRef.set r (y - 10);
|
||||
done
|
||||
)
|
||||
in
|
||||
for _i = 1 to 100 do ignore (Thread.create test_it l) done;
|
||||
Thread.delay 0.10;
|
||||
0 =get l;;
|
||||
|
||||
t @@ fun () -> let l = create 5 in update l (fun x->x+1); get l = 6;;
|
||||
t @@ fun () -> let l = create 5 in update_map l (fun x->x+1, string_of_int x) = "5" && get l = 6;;
|
||||
t @@ fun () -> let l = create 0 in set l 4; get l = 4;;
|
||||
t @@ fun () -> let l = create 0 in set l 4; set l 5; get l = 5;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = create 0 in
|
||||
let a = Array.init 100 (fun _ -> Thread.create (fun _ -> incr l) ()) in
|
||||
Array.iter Thread.join a;
|
||||
assert_equal ~printer:CCInt.to_string 100 (get l);
|
||||
true;;
|
||||
|
||||
t @@ fun () -> let l = create 0 in incr l ; get l = 1;;
|
||||
t @@ fun () -> let l = create 0 in decr l ; get l = ~-1;;
|
||||
t @@ fun () -> let l = create 0 in 1 = incr_then_get l && 1 = get l;;
|
||||
t @@ fun () -> let l = create 0 in 0 = get_then_incr l && 1 = get l;;
|
||||
t @@ fun () -> let l = create 10 in 9 = decr_then_get l && 9 = get l;;
|
||||
t @@ fun () -> let l = create 10 in 10 = get_then_decr l && 9 = get l;;
|
||||
171
tests/thread/t_pool.ml
Normal file
171
tests/thread/t_pool.ml
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCPool;;
|
||||
|
||||
module P = Make(struct let max_size = 30 end)
|
||||
module P2 = Make(struct let max_size = 15 end)
|
||||
module Fut = P.Fut
|
||||
module Fut2 = P2.Fut;;
|
||||
|
||||
t @@ fun () ->
|
||||
List.iter
|
||||
(fun n ->
|
||||
let l = Iter.(1 -- n) |> Iter.to_list in
|
||||
let l = List.rev_map (fun _i ->
|
||||
Fut.make
|
||||
(fun () ->
|
||||
Thread.delay 0.01;
|
||||
1
|
||||
)) l in
|
||||
let l' = List.map Fut.get l in
|
||||
assert_equal n (List.fold_left (+) 0 l');
|
||||
)
|
||||
[ 10; 300; ];
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
List.iter
|
||||
(fun n ->
|
||||
let l = Iter.(1 -- n) |> Iter.to_list in
|
||||
let l = List.rev_map (fun _i ->
|
||||
Fut2.make
|
||||
(fun () ->
|
||||
Thread.delay 0.01;
|
||||
1
|
||||
)) l in
|
||||
let l' = List.map Fut2.get l in
|
||||
assert_equal n (List.fold_left (+) 0 l');
|
||||
)
|
||||
[ 10; 300; ];
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let a = Fut.make (fun () -> 1) in
|
||||
let b = Fut.return 42 in
|
||||
let c = Fut.monoid_product CCPair.make a b in
|
||||
assert_equal (1,42) (Fut.get c);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let a = Fut.make (fun () -> 1) in
|
||||
let b = Fut.make (fun () -> 42) in
|
||||
let c = Fut.monoid_product CCPair.make a b in
|
||||
assert_equal (1,42) (Fut.get c);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let a = Fut.make (fun () -> 1) in
|
||||
let b = Fut.map succ @@ Fut.make (fun () -> 41) in
|
||||
let c = Fut.monoid_product CCPair.make a b in
|
||||
assert_equal (1,42) (Fut.get c);
|
||||
true;;
|
||||
|
||||
eq [2;3] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) [1;2]);;
|
||||
eq [] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x+1)) []);;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut.make (fun () -> Thread.delay 0.1; x*10))
|
||||
|> Fut.sequence_l
|
||||
|> Fut.map (List.fold_left (+) 0)
|
||||
in
|
||||
let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in
|
||||
assert_equal expected (Fut.get l');
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = CCList.(1 -- 100_000) in
|
||||
let l' = l
|
||||
|> CCList.map
|
||||
(fun _x -> Fut.make (fun () -> 1))
|
||||
|> Fut.sequence_l
|
||||
|> Fut.map (List.fold_left (+) 0)
|
||||
in
|
||||
let expected = 100_000 in
|
||||
assert_equal expected (Fut.get l');
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x))
|
||||
|> Fut.sequence_l
|
||||
|> Fut.map (List.fold_left (+) 0)
|
||||
in
|
||||
assert_raises ((=)Exit) (fun () -> Fut.get l');
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in
|
||||
let l =
|
||||
CCList.(1--10_000)
|
||||
|> List.rev_map
|
||||
(fun x-> Fut.make (fun () -> Thread.yield(); fib (x mod 20)))
|
||||
|> Fut.(map_l (fun x->x>|= fun x->x+1))
|
||||
in
|
||||
assert (Fut.state l = Waiting);
|
||||
let l' = Fut.get l in
|
||||
assert_equal 10_000 (List.length l');
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut2.make (fun () -> Thread.delay 0.1; x*10))
|
||||
|> Fut2.sequence_l
|
||||
|> Fut2.map (List.fold_left (+) 0)
|
||||
in
|
||||
let expected = List.fold_left (fun acc x -> acc + 10 * x) 0 l in
|
||||
assert_equal expected (Fut2.get l');
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = CCList.(1 -- 50) in
|
||||
let l' = l
|
||||
|> List.map
|
||||
(fun x -> Fut2.make (fun () -> Thread.delay 0.1; if x = 5 then raise Exit; x))
|
||||
|> Fut2.sequence_l
|
||||
|> Fut2.map (List.fold_left (+) 0)
|
||||
in
|
||||
assert_raises ((=)Exit) (fun () -> Fut2.get l');
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let rec fib x = if x<2 then 1 else fib (x-1)+fib(x-2) in
|
||||
let l =
|
||||
CCList.(1--10_000)
|
||||
|> List.rev_map
|
||||
(fun x-> Fut2.make (fun () -> Thread.yield(); fib (x mod 20)))
|
||||
|> Fut2.(map_l (fun x->x>|= fun x->x+1))
|
||||
in
|
||||
assert (Fut2.state l = Waiting);
|
||||
let l' = Fut2.get l in
|
||||
assert_equal 10_000 (List.length l');
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let start = Unix.gettimeofday () in
|
||||
let pause = 0.2 and n = 10 in
|
||||
let l = CCList.(1 -- n)
|
||||
|> List.map (fun _ -> Fut.make (fun () -> Thread.delay pause))
|
||||
in
|
||||
List.iter Fut.get l;
|
||||
let stop = Unix.gettimeofday () in
|
||||
assert (stop -. start < float_of_int n *. pause);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let start = Unix.gettimeofday () in
|
||||
let pause = 0.2 and n = 10 in
|
||||
let l = CCList.(1 -- n)
|
||||
|> List.map (fun _ -> Fut2.make (fun () -> Thread.delay pause))
|
||||
in
|
||||
List.iter Fut2.get l;
|
||||
let stop = Unix.gettimeofday () in
|
||||
assert (stop -. start < float_of_int n *. pause);
|
||||
true;;
|
||||
62
tests/thread/t_semaphore.ml
Normal file
62
tests/thread/t_semaphore.ml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCSemaphore;;
|
||||
|
||||
t @@ fun () ->
|
||||
let s = create 1 in
|
||||
let r = CCLock.create false in
|
||||
let _ = Thread.create (fun s -> acquire 5 s; CCLock.set r true) s in
|
||||
Thread.yield ();
|
||||
assert_equal false (CCLock.get r);
|
||||
release 4 s;
|
||||
Thread.delay 0.2;
|
||||
assert_equal true (CCLock.get r);
|
||||
assert_equal 0 (get s);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let s = create 5 in
|
||||
let n = CCLock.create 0 in
|
||||
let a = Array.init 100 (fun i ->
|
||||
Thread.create (fun _ ->
|
||||
for _i = 1 to 100 do
|
||||
with_acquire ~n:(1 + (i mod 5)) s
|
||||
~f:(fun () -> Thread.yield(); CCLock.incr n)
|
||||
done)
|
||||
())
|
||||
in
|
||||
Array.iter Thread.join a;
|
||||
assert_equal ~printer:CCInt.to_string 5 (get s);
|
||||
assert_equal ~printer:CCInt.to_string 10_000 (CCLock.get n);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let output _s = () in
|
||||
let s = create 2 in
|
||||
let res = CCLock.create false in
|
||||
let id = Thread.create
|
||||
(fun () ->
|
||||
output "start";
|
||||
wait_until_at_least ~n:5 s
|
||||
~f:(fun () ->
|
||||
assert (get s >= 5);
|
||||
output "modify now";
|
||||
CCLock.set res true)
|
||||
) ()
|
||||
in
|
||||
output "launched thread";
|
||||
Thread.yield();
|
||||
assert (not (CCLock.get res));
|
||||
output "release 2";
|
||||
release 2 s;
|
||||
Thread.yield();
|
||||
assert (not (CCLock.get res));
|
||||
output "release 1";
|
||||
release 1 s;
|
||||
(* should work now *)
|
||||
Thread.delay 0.2;
|
||||
Thread.join id;
|
||||
output "check";
|
||||
assert (CCLock.get res);
|
||||
true;;
|
||||
24
tests/thread/t_thread.ml
Normal file
24
tests/thread/t_thread.ml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCThread;;
|
||||
|
||||
t @@ fun () ->
|
||||
let l = CCLock.create 0 in
|
||||
let a = Arr.spawn 101 (fun i -> CCLock.update l ((+) i)) in
|
||||
Arr.join a;
|
||||
let n = Iter.(1 -- 100 |> fold (+) 0) in
|
||||
assert_equal ~printer:CCInt.to_string n (CCLock.get l);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
let b = Barrier.create () in
|
||||
let res = CCLock.create 0 in
|
||||
let t1 = spawn (fun _ -> Barrier.wait b; CCLock.incr res)
|
||||
and t2 = spawn (fun _ -> Barrier.wait b; CCLock.incr res) in
|
||||
Thread.delay 0.2;
|
||||
assert_equal 0 (CCLock.get res);
|
||||
Barrier.activate b;
|
||||
Thread.join t1; Thread.join t2;
|
||||
assert_equal 2 (CCLock.get res);
|
||||
true;;
|
||||
42
tests/thread/t_timer.ml
Normal file
42
tests/thread/t_timer.ml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
module Test = (val Containers_testlib.make ~__FILE__())
|
||||
open Test
|
||||
open CCTimer;;
|
||||
|
||||
|
||||
(* NOTE: could be tighter bounds, but travis' mac OS seems to be dog slow. *)
|
||||
|
||||
t @@ fun () ->
|
||||
let start = Unix.gettimeofday() in
|
||||
let timer = create() in
|
||||
let res = CCLock.create 0 in
|
||||
let sem = CCSemaphore.create 1 in
|
||||
CCSemaphore.acquire 1 sem;
|
||||
let stop = ref 0. in
|
||||
every timer 0.1
|
||||
~f:(fun () ->
|
||||
if CCLock.incr_then_get res > 5 then (
|
||||
stop := Unix.gettimeofday();
|
||||
CCSemaphore.release 1 sem;
|
||||
raise ExitEvery
|
||||
));
|
||||
CCSemaphore.acquire 1 sem; (* wait *)
|
||||
assert_equal ~printer:CCInt.to_string 6 (CCLock.get res);
|
||||
assert (!stop -. start >= 0.49999);
|
||||
assert (!stop -. start < 2.);
|
||||
true;;
|
||||
|
||||
t @@ fun () ->
|
||||
(* scenario: n := 1; n := n*4 ; n := n+2; res := n *)
|
||||
let timer = create () in
|
||||
let n = CCLock.create 1 in
|
||||
let res = CCLock.create 0 in
|
||||
after timer 0.3
|
||||
~f:(fun () -> CCLock.update n (fun x -> x+2));
|
||||
ignore (Thread.create
|
||||
(fun _ -> Thread.delay 0.4; CCLock.set res (CCLock.get n)) ());
|
||||
after timer 0.1
|
||||
~f:(fun () -> CCLock.update n (fun x -> x * 4));
|
||||
Thread.delay 0.6 ;
|
||||
assert_equal ~printer:Q.Print.int 6 (CCLock.get res);
|
||||
true;;
|
||||
Loading…
Add table
Reference in a new issue