123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373open!Importopen!Stdlib.Int64moduleSexp=Sexp0moduleT=structmoduleT0=structtypet=int64[@@derivingglobalize,hash,of_sexp~unboxed,sexp_grammar]let%template[@alloca=(heap,stack)]to_string=(Integer_to_string.int64_to_string[@alloca]);;typeunboxed=int64#letbox=Basement.Primitives.box_int64endincludeT0include%templateInt_string_conversions.Make_unboxed[@kindbits64](T0)lethashable:tHashable.t={hash;compare;sexp_of_t}letcompare=Int64_replace_polymorphic_compare.compareexternalformat:string->local_int64->string@@portable="caml_int64_format"externalof_string:local_string->(int64[@unboxed])@@portable="caml_int64_of_string""caml_int64_of_string_unboxed"letof_string_opts=trySome(of_strings)with|Failure_->None;;endincludeTinclude%templateComparator.Make[@modalityportable](T)letnum_bits=64letfloat_lower_bound=Float0.lower_bound_for_intnum_bitsletfloat_upper_bound=Float0.upper_bound_for_intnum_bitsletnum_bits=of_intnum_bitsexternalfloat_of_bits:local_t->float@@portable="caml_int64_float_of_bits""caml_int64_float_of_bits_unboxed"[@@unboxed][@@noalloc][@@builtin]externalbits_of_float:local_float->t@@portable="caml_int64_bits_of_float""caml_int64_bits_of_float_unboxed"[@@unboxed][@@noalloc][@@builtin]externalshift_right_logical:local_t->int->t@@portable="%int64_lsr"externalshift_right:local_t->int->t@@portable="%int64_asr"externalshift_left:local_t->int->t@@portable="%int64_lsl"externalbit_xor:local_t->local_t->t@@portable="%int64_xor"externalbit_or:local_t->local_t->t@@portable="%int64_or"externalbit_and:local_t->local_t->t@@portable="%int64_and"letbit_notn=bit_xorn(-1L)letmin_value=min_intletmax_value=max_intletabs=absletabs_localn=exclave_ifInt64_replace_polymorphic_compare.(n>=0L)thennelsenegn;;letpow=Int_math.Private.int64_powexternalrem:local_t->local_t->t@@portable="%int64_mod"letminus_one=minus_oneletone=oneletzero=zeroexternalto_float:local_t->float@@portable="caml_int64_to_float""caml_int64_to_float_unboxed"[@@unboxed][@@noalloc][@@builtin]externalof_float_unchecked:local_float->t@@portable="caml_int64_of_float""caml_int64_of_float_unboxed"[@@unboxed][@@noalloc][@@builtin]letof_floatf=ifFloat_replace_polymorphic_compare.(>=)ffloat_lower_bound&&Float_replace_polymorphic_compare.(<=)ffloat_upper_boundthenof_float_uncheckedfelsePrintf.invalid_argf"Int64.of_float: argument (%f) is out of range or NaN"(Float0.boxf)();;(* Not eta-expanding here can lead to less allocations: the function call sites can avoid
boxing the int64s more often. *)let(**)=powexternalbswap64:local_t->(t[@local_opt])@@portable="%bswap_int64"let[@inlinealways]bswap16x=shift_right_logical(bswap64x)48let[@inlinealways]bswap32x=(* This is strictly better than coercing to an int32 to perform byteswap. Coercing from
an int32 will add unnecessary shift operations to sign extend the number
appropriately.
*)shift_right_logical(bswap64x)32;;let[@inlinealways]bswap48x=shift_right_logical(bswap64x)16include%templateComparable.With_zero[@modalityportable](structincludeTletzero=zeroend)(* Open replace_polymorphic_compare after including functor instantiations so they do not
shadow its definitions. This is here so that efficient versions of the comparison
functions are available within this module. *)openInt64_replace_polymorphic_compareletinvariant(_:t)=()letbetweent~low~high=low<=t&&t<=highletclamp_uncheckedt~min:min_~max:max_=mintmax_|>maxmin_letclamp_exnt~min~max=assert(min<=max);clamp_uncheckedt~min~max;;letclampt~min~max=ifmin>maxthenOr_error.error_s(Sexp.message"clamp requires [min <= max]"["min",T.sexp_of_tmin;"max",T.sexp_of_tmax])elseOk(clamp_uncheckedt~min~max);;letincrr=r:=add!roneletdecrr=r:=sub!roneexternalof_int64:(t[@local_opt])->(t[@local_opt])@@portable="%identity"letto_int64t=tletof_int64_exnt=tletto_local_int64t=tletof_local_int64_exnt=tletpopcount=Popcount.int64_popcountmoduleConv=Int_conversionsexternalto_int_trunc:local_t->int@@portable="%int64_to_int"externalto_int32_trunc:local_t->(int32[@local_opt])@@portable="%int64_to_int32"externalto_nativeint_trunc:local_t->(nativeint[@local_opt])@@portable="%int64_to_nativeint"externalof_int:int->(t[@local_opt])@@portable="%int64_of_int"externalof_int32:local_int32->(t[@local_opt])@@portable="%int64_of_int32"letof_int_exn=of_intletto_int=Conv.int64_to_intletto_int_exn=Conv.int64_to_int_exnletof_int32_exn=of_int32letof_local_int32_exn=of_int32letto_int32=Conv.int64_to_int32letto_local_int32_exn=Conv.int64_to_int32_exnletto_int32_exnt=globalize_int32(to_local_int32_exnt)[@nontail]externalof_nativeint:local_nativeint->(t[@local_opt])@@portable="%int64_of_nativeint"letof_nativeint_exn=of_nativeintletof_local_nativeint_exn=of_nativeintletto_nativeint=Conv.int64_to_nativeintletto_local_nativeint_exn=Conv.int64_to_nativeint_exnletto_nativeint_exnt=globalize_nativeint(to_local_nativeint_exnt)[@nontail]modulePre_O=structexternal(+):local_t->local_t->(t[@local_opt])@@portable="%int64_add"external(-):local_t->local_t->(t[@local_opt])@@portable="%int64_sub"external(*):local_t->local_t->(t[@local_opt])@@portable="%int64_mul"external(/):local_t->local_t->(t[@local_opt])@@portable="%int64_div"external(~-):local_t->(t[@local_opt])@@portable="%int64_neg"let(**)=(**)includeInt64_replace_polymorphic_compareletabs=absletabs_local=abs_localexternalneg:local_t->(t[@local_opt])@@portable="%int64_neg"letzero=zeroletof_int_exn=of_int_exnendmoduleO=structincludePre_OincludeInt_math.Make(structtypenonrect=tletglobalize=globalizeincludePre_Oletrem=remletto_float=to_floatletof_float=of_floatletof_string=T.of_stringletto_string=T.to_stringend)external(land):local_t->local_t->(t[@local_opt])@@portable="%int64_and"external(lor):local_t->local_t->(t[@local_opt])@@portable="%int64_or"external(lxor):local_t->local_t->(t[@local_opt])@@portable="%int64_xor"letlnot=bit_notexternal(lsl):local_t->int->(t[@local_opt])@@portable="%int64_lsl"external(asr):local_t->local_int->(t[@local_opt])@@portable="%int64_asr"external(lsr):local_t->local_int->(t[@local_opt])@@portable="%int64_lsr"endincludeOletpredn=n-1Lletsuccn=n+1LmodulePow2=structopenOletraise_s=Error.raise_sletnon_positive_argument()=Printf.invalid_argf"argument must be strictly positive"();;(** "ceiling power of 2" - Least power of 2 greater than or equal to x. *)letceil_pow2x=ifx<=0Lthennon_positive_argument();letx=x-1Linletx=xlor(xlsr1)inletx=xlor(xlsr2)inletx=xlor(xlsr4)inletx=xlor(xlsr8)inletx=xlor(xlsr16)inletx=xlor(xlsr32)inx+1L;;(** "floor power of 2" - Largest power of 2 less than or equal to x. *)letfloor_pow2x=ifx<=0Lthennon_positive_argument();letx=xlor(xlsr1)inletx=xlor(xlsr2)inletx=xlor(xlsr4)inletx=xlor(xlsr8)inletx=xlor(xlsr16)inletx=xlor(xlsr32)inx-(xlsr1);;letis_pow2x=ifx<=0Lthennon_positive_argument();xland(x-1L)=0L;;letclz=Ocaml_intrinsics_kernel.Int64.count_leading_zerosletctz=Ocaml_intrinsics_kernel.Int64.count_trailing_zeros(** Hacker's Delight Second Edition p106 *)letfloor_log2i=ifi<=0Lthenraise_s(Sexp.message"[Int64.floor_log2] got invalid input"["",sexp_of_int64(globalizei)]);num_bits-1L-clzi;;(** Hacker's Delight Second Edition p106 *)letceil_log2i=ifi<=0Lthenraise_s(Sexp.message"[Int64.ceil_log2] got invalid input"["",sexp_of_int64(globalizei)]);ifi=1Lthen0Lelse(leti=i-1Linnum_bits-clzi);;endincludePow2includeInt_string_conversions.Make_hex(structtypet=int64[@@derivingcompare~localize,hash]letzero=zeroletneg=neglet(<)=(<)letto_stringi=format"%Lx"iletof_strings=Stdlib.Scanf.sscanfs"%Lx"Fn.idletmodule_name="Base.Int64.Hex"end)includeInt_string_conversions.Make_binary(structtypet=int64[@@derivingcompare~localize,equal~localize,hash]let(land)=(land)let(lsr)=(lsr)letclz=clzletnum_bits=num_bitsletone=oneletto_int_trunc=to_int_truncletzero=zerolet(-)=O.(-)end)include%templatePretty_printer.Register[@modalityportable](structtypenonrect=tletto_string=to_stringletmodule_name="Base.Int64"end)(* [Int64] and [Int64.O] agree value-wise *)moduleSummable=structtypenonrect=tletzero=zerolet[@inline](+)xy=x+ylet[@inline](-)xy=x-yend(* Include type-specific [Replace_polymorphic_compare] at the end, after including functor
application that could shadow its definitions. This is here so that efficient versions
of the comparison functions are exported by this module. *)includeInt64_replace_polymorphic_compare