123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250open!ImportmoduleSexp=Sexp0moduleDefinitions=structmoduleKey=Hashtbl.KeymoduleOk_or_absent=structtypet=|Absent|Ok[@@derivingcompare~localize,enumerate,equal~localize,hash,sexp_of]letis_ok=function|Absent->false|Ok->true;;letis_absent=function|Absent->true|Ok->false;;endmoduleOk_or_duplicate=structtypet=|Duplicate|Ok[@@derivingcompare~localize,enumerate,equal~localize,hash,sexp_of]letis_ok=function|Duplicate->false|Ok->true;;letis_duplicate=function|Duplicate->true|Ok->false;;endmoduletypeAccessors=sigtype'atincludeContainer.Genericwithtype('a,_,_)t:='at(** override [Container.Generic.mem] *)valmem:'at->'a->bool(** preserves the equality function *)valcopy:'at->'atvaladd:'at->'a->unit(** Get an element, adding it if it doesn't exist. This can be useful e.g. in order to
use [Hash_set] for interning. *)valget_or_add:'at->'a->'a(** [strict_add t x] returns [Ok] if [x] was not in [t], or [Duplicate] if it was. *)valstrict_add:'at->'a->Ok_or_duplicate.t(** Like [strict_add]; returns [Ok ()] or [Error _]. *)valstrict_add_or_error:'at->'a->unitOr_error.t(** Like [strict_add]; raises on failure. *)valstrict_add_exn:'at->'a->unitvalremove:'at->'a->unit(** [strict_remove t x] returns [Ok] if [x] was in [t], or [Absent] if it was not. *)valstrict_remove:'at->'a->Ok_or_absent.t(** Like [strict_remove]; returns [Ok ()] or [Error _]. *)valstrict_remove_or_error:'at->'a->unitOr_error.t(** Like [strict_remove]; raises on failure. *)valstrict_remove_exn:'at->'a->unitvalclear:'at->unitval%templateequal:'at@m->'at@m->bool[@@modem=(local,global)]valfilter:'at->f:local_('a->bool)->'atvalfilter_inplace:'at->f:local_('a->bool)->unit(** [inter t1 t2] computes the set intersection of [t1] and [t2]. Runs in O(min(length
t1, length t2)). Behavior is undefined if [t1] and [t2] don't have the same
equality function. *)valinter:'keyt->'keyt->'keytvalunion:'at->'at->'atvalunion_in_place:dst:'at->src:'at->unitvaldiff:'at->'at->'atvalof_hashtbl_keys:('a,_)Hashtbl.t->'atvalto_hashtbl:'keyt->f:local_('key->'data)->('key,'data)Hashtbl.tvalcapacity:_t->intendtype('key,'z)create_options=('key,unit,'z)Hashtbl.create_optionstype('key,'z)create_options_without_first_class_module=('key,unit,'z)Hashtbl.create_options_without_first_class_modulemoduletypeCreators=sigtype'atvalcreate:?growth_allowed:bool(** defaults to [true] *)->?size:int(** initial size -- default 0 *)->'aKey.t@immutable->'atvalof_list:?growth_allowed:bool(** defaults to [true] *)->?size:int(** initial size -- default [List.length] *)->'aKey.t@immutable->'alist->'atvalof_array:?growth_allowed:bool(** defaults to [true] *)->?size:int(** initial size -- default [Array.length] *)->'aKey.t@immutable->'aarray->'atendmoduletypeCreators_generic=sigtype'attype'aelttype('a,'z)create_optionsvalcreate:('a,unit->'at)create_optionsvalof_list:('a,'aeltlist->'at)create_optionsvalof_array:('a,'aeltarray->'at)create_optionsendmoduletypeSexp_of_m=sigtypet[@@derivingsexp_of]endmoduletypeM_of_sexp=sigtypet[@@derivingof_sexp]includeHashtbl.Key.Swithtypet:=tendmoduletypeM_sexp_grammar=sigtypet[@@derivingsexp_grammar]endmoduletypeEqual_m=sigendmoduletypeFor_deriving=sigtype'atmoduletypeM_of_sexp=M_of_sexpmoduletypeSexp_of_m=Sexp_of_mmoduletypeEqual_m=Equal_mmoduletypeM_sexp_grammar=M_sexp_grammar(** [M] is meant to be used in combination with OCaml applicative functor types:
{[
type string_hash_set = Hash_set.M(String).t
]}
which stands for:
{[
type string_hash_set = String.t Hash_set.t
]}
The point is that [Hash_set.M(String).t] supports deriving, whereas the second
syntax doesn't (because [t_of_sexp] doesn't know what comparison/hash function to
use). *)moduleM(Elt:T.T):sigtypenonrect=Elt.ttendvalsexp_of_m__t:(moduleSexp_of_mwithtypet='elt)->'eltt->Sexp.tvalm__t_of_sexp:(moduleM_of_sexpwithtypet='elt)->Sexp.t->'elttvalm__t_sexp_grammar:(moduleM_sexp_grammarwithtypet='elt)->'elttSexplib0.Sexp_grammar.t@@portableval%templateequal_m__t:(moduleEqual_m)->'eltt@m->'eltt@m->bool[@@modem=(local,global)]endendmoduletypeHash_set=sig@@portableincludemoduletypeofstructincludeDefinitionsendtype!'at:valuemodnon_float[@@derivingsexp_of](** We use [[@@deriving sexp_of]] but not [[@@deriving sexp]] because we want people to
be explicit about the hash and comparison functions used when creating hashtables.
One can use [Hash_set.Poly.t], which does have [[@@deriving sexp]], to use
polymorphic comparison and hashing. *)includeCreatorswithtype'at:='at(** @open *)includeAccessorswithtype'at:='atwithtype'aelt:='a(** @open *)valhashable_s:'keyt->'keyKey.t(** A hash set that uses polymorphic comparison *)modulePoly:sigtypenonrec'at='at[@@derivingsexp,sexp_grammar]includeCreators_genericwithtype'at:='atwithtype'aelt='awithtype('key,'z)create_options:=('key,'z)create_options_without_first_class_moduleincludeAccessorswithtype'at:='atwithtype'aelt:='aeltendmodule%template.portableCreators(Elt:sigtype'atvalhashable:'atHashable.tend):sigvalt_of_sexp:(Sexp.t->'aElt.t)->Sexp.t->'aElt.ttincludeCreators_genericwithtype'at:='aElt.ttwithtype'aelt:='aElt.twithtype('elt,'z)create_options:=('elt,'z)create_options_without_first_class_moduleendincludeFor_derivingwithtype'at:='at(**/**)(*_ See the Jane Street Style Guide for an explanation of [Private] submodules:
https://opensource.janestreet.com/standards/#private-submodules *)modulePrivate:sigvalhashable:'at->'aHashable.tendend