123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899(** Imperative set-like data structure.
There are a few differences from simple sets:
- Duplicates are allowed.
- It doesn't require anything (hashable, comparable) of elements in the bag.
- Addition and removal are constant time operations.
It is an error to modify a bag ([add], [remove], [remove_one], ...) during iteration
([fold], [iter], ...). *)open!ImportmoduletypeS=sigmoduleElt:sigtype'atvalequal:'at->'at->boolvalsexp_of_t:('a->Sexp.t)->'at->Sexp.tvalvalue:'at->'aendtype'at[@@derivingsexp](** Much of a bag's interface comes from the generic {!Base.Container} module. *)includeContainer.S1withtype'at:='atincludeInvariant.S1withtype'at:='at(** [create ()] returns an empty bag. *)valcreate:unit->'at(** [add t v] adds [v] to the bag [t], returning an element that can
later be removed from the bag. [add] runs in constant time. *)valadd:'at->'a->'aElt.tvaladd_unit:'at->'a->unit(** [mem_elt t elt] returns whether or not [elt] is in [t]. It is like [mem] (included
from [Container]), but it takes an ['a Elt.t] instead of an ['a] and runs in constant
time instead of linear time. *)valmem_elt:'at->'aElt.t->bool(** [remove t elt] removes [elt] from the bag [t], raising an exception if [elt]
is not in the bag. [remove] runs in constant time. *)valremove:'at->'aElt.t->unit(** [choose t] returns some element in the bag. *)valchoose:'at->'aElt.toption(** [remove_one t] removes some element from the bag, and returns its value.
[remove_one] runs in constant time. *)valremove_one:'at->'aoption(** [clear t] removes all elements from the bag. [clear] runs in constant time. *)valclear:'at->unit(** [filter_inplace t ~f] removes all the elements from [t] that don't satisfy [f]. *)valfilter_inplace:'at->f:('a->bool)->unit(** [iter_elt t ~f] calls [f] on each element of the bag. *)valiter_elt:'at->f:('aElt.t->unit)->unit(** [find_elt t ~f] returns the first element in the bag satisfying [f], returning [None]
if none is found. *)valfind_elt:'at->f:('a->bool)->'aElt.toption(** [until_empty t f] repeatedly removes values [v] from [t], running [f v] on each one,
until [t] is empty. Running [f] may add elements to [t] if it wants. *)valuntil_empty:'at->('a->unit)->unit(** [transfer ~src ~dst] moves all of the elements from [src] to [dst] in constant
time. *)valtransfer:src:'at->dst:'at->unitvalof_list:'alist->'atvalelts:'at->'aElt.tlist(** [unchecked_iter t ~f] behaves like [iter t ~f] except that [f] is allowed to modify
[t]. Elements added by [f] may or may not be visited; elements removed by [f] that
have not been visited will not be visited. It is an (undetected) error to delete the
current element. *)valunchecked_iter:'at->f:('a->unit)->unitendmoduletypeBag=sig(** The module type of the Bag module.
Example usage:
{[
module My_bag : Bag.S = Bag
]}
Now [My_bag.Elt.t] can't be used with any other [Bag.t] type.
*)moduletypeS=SincludeSend