1234567891011121314151617181920212223242526272829303132333435363738394041424344(** Storage implementation.
There is a singleton storage for a given program, responsible for providing
ambient context to the rest of the program. *)typet={name:string;get_context:unit->Context.t;with_context:'a.Context.t->(unit->'a)->'a;}(** Storage type *)(** Name of the storage implementation. *)let[@inline]nameself=self.name(** Get the context from the current storage, or [Hmap.empty] if there is no
ambient context. *)let[@inline]get_contextself=self.get_context()(** [with_context storage ctx f] calls [f()] in an ambient context in which
[get_context()] will return [ctx]. Once [f()] returns, the storage is reset
to its previous value. *)let[@inline]with_contextselfctxf=self.with_contextctxf(** Get the ambient context and then look up [k] in it *)let[@inline]getself(k:'aContext.key):'aoption=Hmap.findk(get_contextself)(** [with_key_bound_to storage k v f] calls [f()] in a context updated to have
[k] map to [v]. *)letwith_key_bound_toselfkvf=letctx=get_contextselfinletnew_ctx=Hmap.addkvctxinself.with_contextnew_ctxf(** [with_key_unbound storage k f] calls [f()] in a context updated to have [k]
bound to no value. *)letwith_key_unboundselfkf=letctx=get_contextselfinifHmap.memkctxthen(letnew_ctx=Hmap.remkctxinself.with_contextnew_ctxf)elsef()