123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238(* This file is free software, part of containers. See file "license" for more details. *)(** {1 Mutable Set} *)type'asequence=('a->unit)->unittype'aprinter=Format.formatter->'a->unitmoduletypeS=sigtypettypeeltvalcreate:int->t(** [create n] makes a new set with the given capacity [n] *)valsingleton:elt->t(** [singleton x] is the singleton [{x}] *)valclear:t->unit(** [clear s] removes all elements from [s] *)valcopy:t->t(** Fresh copy *)valcopy_into:into:t->t->unit(** [copy_into ~into s] copies all elements of [s] into [into] *)valinsert:t->elt->unit(** [insert s x] adds [x] into [s] *)valremove:t->elt->unit(** Remove the element, if it were in there *)valcardinal:t->int(** [cardinal s] returns the number of elements in [s] *)valmem:t->elt->bool(** [mem s x] returns [true] iff [x] is in [s] *)valfind_exn:t->elt->elt(** [find_exn s x] returns [y] if [x] and [y] are equal, and [mem s y].
@raise Not_found if [x] not in [s] *)valfind:t->elt->eltoption(** Safe version of {!find_exn} *)valinter:t->t->t(** [inter a b] returns [a ∩ b] *)valinter_mut:into:t->t->unit(** [inter_mut ~into a] changes [into] into [a ∩ into] *)valunion:t->t->t(** [union a b] returns [a ∪ b] *)valunion_mut:into:t->t->unit(** [union_mut ~into a] changes [into] into [a ∪ into] *)valdiff:t->t->t(** [diff a b] returns [a - b] *)valsubset:t->t->bool(** [subset a b] returns [true] if all elements of [a] are in [b] *)valequal:t->t->bool(** [equal a b] is extensional equality ([a] and [b] have the same elements) *)valfor_all:(elt->bool)->t->boolvalexists:(elt->bool)->t->boolvaliter:(elt->unit)->t->unit(** Iterate on values *)valfold:('a->elt->'a)->'a->t->'a(** Fold on values *)valelements:t->eltlist(** List of elements *)valof_list:eltlist->tvalto_seq:t->eltsequencevalof_seq:eltsequence->tvaladd_seq:t->eltsequence->unitvalpp:?sep:string->eltprinter->tprinter(** [pp pp_elt] returns a set printer, given a printer for
individual elements *)endmoduletypeELEMENT=sigtypetvalequal:t->t->boolvalhash:t->int(** Positive value *)endmoduleMake(E:ELEMENT):Swithtypeelt=E.t=structmoduleTbl=Hashtbl.Make(E)typeelt=E.ttypet=eltTbl.t(* map [x -> x], for find *)letcreate=Tbl.createletsingletonx=lets=create8inTbl.replacesxx;sletclear=Tbl.clearletcopy=Tbl.copyletcopy_into~intos=Tbl.iter(funx_->Tbl.replaceintoxx)sletinsertsx=Tbl.replacesxxletremove=Tbl.removeletcardinal=Tbl.length(*$T
let module IS = Make(CCInt) in \
IS.cardinal (IS.create 10) = 0
*)letmem=Tbl.memletfind_exn=Tbl.findletfindsx=trySome(Tbl.findsx)withNot_found->None(*$T
let module IS = Make(CCInt) in IS.find (IS.of_list [1;2;3]) 3 = Some 3
let module IS = Make(CCInt) in IS.find (IS.of_list [1;2;3]) 5 = None
*)letiterfs=Tbl.iter(funx_->fx)sletfoldfaccs=Tbl.fold(funx_acc->faccx)saccletinterab=letres=create(min(cardinala)(cardinalb))initer(funx->ifmemaxtheninsertresx)b;res(*$T
let module IS = Make(CCInt) in \
IS.(equal (inter (of_list [1;2;3]) (of_list [2;5;4])) (of_list [2]))
*)letinter_mut~intoa=iter(funx->ifnot(memax)thenremoveintox)intoletunionab=letres=copyaincopy_into~into:resb;res(*$T
let module IS = Make(CCInt) in \
IS.(equal (union (of_list [1;2;3]) (of_list [2;5;4])) (of_list [1;2;3;4;5]))
*)letunion_mut~intoa=copy_into~intoaletdiffab=letres=copyainiter(funx->removeresx)b;res(*$T
let module IS = Make(CCInt) in \
IS.(equal (diff (of_list [1;2;3]) (of_list [2;4;5])) (of_list [1;3]))
*)exceptionFastExitletfor_allps=tryTbl.iter(funx_->ifnot(px)thenraiseFastExit)s;truewithFastExit->falseletexistsps=tryTbl.iter(funx_->ifpxthenraiseFastExit)s;falsewithFastExit->trueletsubsetab=for_all(funx->membx)aletequalab=subsetab&&subsetbaletelementss=Tbl.fold(funx_acc->x::acc)s[]letof_listl=letres=create(List.lengthl)inList.iter(insertres)l;resletto_seqsyield=iteryieldsletadd_seqsseq=seq(inserts)letof_seqseq=lets=create32inseq(inserts);sletpp?(sep=",")pp_xouts=Format.pp_print_stringout"{";letfirst=reftrueinTbl.iter(funx_->if!firstthenfirst:=falseelse(Format.pp_print_stringoutsep;Format.pp_print_cutout(););pp_xoutx)s;Format.pp_print_stringout"}"end