123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108openBasemoduleObj=Stdlib.ObjmoduleObj_local=Base.Exported_for_specific_uses.Obj_localtype+'at(* This [Obj.magic] is OK because we never allow user code access to [none] (except via
[unsafe_value]). We disallow [_ Uopt.t Uopt.t], so there is no chance of confusing
[none] with [some none]. And [float Uopt.t array] is similarly disallowed. *)letnone:_t=Obj.magic"Uopt.none"let[@inline]some(x:'a)=letr:'at=Obj.magicxinifphys_equalrnonethenfailwith"Uopt.some Uopt.none";r;;let[@inline]some_local(typea)(x:a):at=letr:at=Obj_local.magicxinifphys_equalrnonethenfailwith"Uopt.Local.some Uopt.none";r;;letunsafe_value:'at->'a=Obj.magicletunsafe_value_local:'at->'a=Obj_local.magiclet[@inline]is_nonet=phys_equaltnonelet[@inline]is_somet=not(is_nonet)let[@inline]invariantinvariant_at=ifis_somettheninvariant_a(unsafe_valuet)let[@inline]value_exnt=ifis_nonetthenfailwith"Uopt.value_exn"elseunsafe_valuetlet[@inline]valuet~default=Bool.select(is_nonet)default(unsafe_valuet)let[@inline]value_localt~default=Bool.select(is_nonet)default(unsafe_value_localt);;let[@inline]some_ifcondx=Bool.selectcond(somex)nonelet[@inline]some_if_localcondx=Bool.selectcond(some_localx)none(* [to_option] prioritizes not allocating in the [None] case. Allocation is far cheaper
for [to_option_local], so it instead prioritizes minimizing unpredictable branches. *)let[@inline]to_optiont=ifis_nonetthenNoneelseSome(unsafe_valuet)let[@inline]to_option_localt=Bool.select(is_nonet)None(Some(unsafe_value_localt));;let[@inline]of_option_localopt=matchoptwith|None->none|Somex->some_localx;;let[@inline]of_optionopt=matchoptwith|None->none|Somea->somea;;(* Note [sexp_of_t] and [t_of_sexp] must remain stable; see [Uopt_core.Stable]. *)includeSexpable.Of_sexpable1(Option)(structtypenonrec'at='atletto_sexpable=to_optionletof_sexpable=of_optionend)moduleOptional_syntax=structmoduleOptional_syntax=structletis_none=is_noneletunsafe_value=unsafe_valueendendmoduleLocal=structletsome=some_localletunsafe_value=unsafe_value_localletvalue=value_localletsome_if=some_if_localletto_option=to_option_localletof_option=of_option_localmoduleOptional_syntax=structmoduleOptional_syntax=structletis_none=is_noneletunsafe_value=unsafe_value_localendendendletglobalizeglobalize_at=match%optional.Localtwith|None->none|Somex->some(globalize_ax);;let%test_module_=(modulestructlet%test_unit("using the same sentinel value"[@tags"no-js"])=matchsome"Uopt.none"with|(_:stringt)->failwith"should not have gotten to this point"|exception_->();;end);;