123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151(* This file is free software, part of Archsat. See file "LICENSE" for more details. *)(* Heterogeneous Maps,
implementation taken from containers, see data.CCMixmap *)(* Mixmap Implementation (from containers) *)(* ************************************************************************ *)(* Implementation taken from containers. *)type'binjection={get:(unit->unit)->'boption;set:'b->(unit->unit);}letcreate_inj()=letr=refNoneinletgetf=r:=None;f();!randsetv=(fun()->r:=Somev)in{get;set}moduletypeS=sigtypekeytypet(** A map containing values of different types, indexed by {!key}. *)valempty:t(** Empty map *)valget:inj:'ainjection->key->t->'aoption(** Get the value corresponding to this key, if it exists and
belongs to the same key *)valadd:inj:'ainjection->key->'a->t->t(** Bind the key to the value, using [inj] *)valfind:inj:'ainjection->key->t->'a(** Find the value for the given key, which must be of the right type.
@raise Not_found if either the key is not found, or if its value
doesn't belong to the right type *)valcardinal:t->int(** Number of bindings *)valremove:key->t->t(** Remove the binding for this key *)valmem:inj:_injection->key->t->bool(** Is the given key in the map, with the right type? *)valiter_keys:f:(key->unit)->t->unit(** Iterate on the keys of this map *)valfold_keys:f:('a->key->'a)->x:'a->t->'a(** Fold over the keys *)(** {2 Iterators} *)type'aiter=('a->unit)->unitvalkeys_iter:t->keyiter(** All the keys *)valbindings_of:inj:'ainjection->t->(key*'a)iter(** All the bindings that come from the corresponding injection *)typevalue=|Value:('ainjection->'aoption)->valuevalbindings:t->(key*value)iter(** Iterate on all bindings *)endmoduletypeORD=sigtypetvalcompare:t->t->intendmoduleMake(X:ORD):Swithtypekey=X.t=structmoduleM=Map.Make(X)typekey=X.ttypet=(unit->unit)M.tletempty=M.emptyletfind~injxmap=matchinj.get(M.findxmap)with|None->raiseNot_found|Somev->vletget~injxmap=tryinj.get(M.findxmap)withNot_found->Noneletadd~injxymap=M.addx(inj.sety)mapletcardinal=M.cardinalletremove=M.removeletis_some=function|None->false|Some_->trueletmem~injxmap=tryis_some(inj.get(M.findxmap))withNot_found->falseletiter_keys~fmap=M.iter(funx_->fx)mapletfold_keys~f~xmap=M.fold(funx_acc->faccx)mapx(** {2 Iterators} *)type'aiter=('a->unit)->unitletkeys_itermapyield=M.iter(funx_->yieldx)mapletbindings_of~injmapyield=M.iter(funkvalue->matchinj.getvaluewith|None->()|Somev->yield(k,v))maptypevalue=|Value:('binjection->'boption)->valueletbindingsmapyield=M.iter(funxy->yield(x,Value(funinj->inj.gety)))mapend