123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198(* This file is free software, part of containers. See file "license" for more details. *)includeInt64letmin:t->t->t=Stdlib.minletmax:t->t->t=Stdlib.maxletsigni=compareizero(* use FNV:
https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function *)lethash_to_int64(n:t)=letoffset_basis=0xcbf29ce484222325Linletprime=0x100000001b3Linleth=refoffset_basisinfork=0to7doh:=mul!hprime;(* h := h xor (k-th byte of n) *)h:=logxor!h(logand(shift_rightn(k*8))0xffL)done;logand!hmax_intlet[@inline]hash(n:t):int=to_int(hash_to_int64n)landStdlib.max_int(* see {!CCInt.popcount} for more details *)let[@inline]popcount(b:t):int=letm1=0x5555555555555555Linletm2=0x3333333333333333Linletm4=0x0f0f0f0f0f0f0f0fLinletb=subb(logand(shift_right_logicalb1)m1)inletb=add(logandbm2)(logand(shift_right_logicalb2)m2)inletb=logand(addb(shift_right_logicalb4))m4inletb=addb(shift_right_logicalb8)inletb=addb(shift_right_logicalb16)inletb=addb(shift_right_logicalb32)inletb=logandb0x7fLinto_intbletpowab=letrecauxacc=function|1L->acc|n->ifequal(remn2L)zerothenaux(mulaccacc)(divn2L)elsemulacc(aux(mulaccacc)(divn2L))inmatchbwith|0L->ifequala0Lthenraise(Invalid_argument"pow: undefined value 0^0")else1L|bwhencompareb0L<0->raise(Invalid_argument"pow: can't raise int to negative power")|b->auxabletfloor_divan=ifcomparea0L<0&&comparen0L>=0thensub(div(adda1L)n)1Lelseifcomparea0L>0&&comparen0L<0thensub(div(suba1L)n)1Lelsedivantype'aprinter=Format.formatter->'a->unittype'arandom_gen=Random.State.t->'atype'aiter=('a->unit)->unitletrangeijyield=letrecupijyield=ifequalijthenyieldielse(yieldi;up(addi1L)jyield)anddownijyield=ifequalijthenyieldielse(yieldi;down(subi1L)jyield)inifcompareij<=0thenupijyieldelsedownijyieldletrange'ijyield=ifcompareij<0thenrangei(subj1L)yieldelseifequalijthen()elserangei(addj1L)yieldletrange_by~stepijyield=letrecrangeijyield=ifequalijthenyieldielse(yieldi;range(addistep)jyield)inifequalstep0Lthenraise(Invalid_argument"CCInt64.range_by")elseififcomparestep0L>0thencompareij>0elsecompareij<0then()elserangei(add(mul(div(subji)step)step)i)yieldletrandomnst=Random.State.int64stnletrandom_small=random100Lletrandom_rangeijst=addi(random(subji)st)(** {2 Conversion} *)letof_string_exn=of_stringletof_stringx=trySome(of_string_exnx)withFailure_->Noneletof_string_opt=of_stringletmost_significant_bit=logxor(neg1L)(shift_right_logical(neg1L)1)typeoutput=char->unit(* abstract printer *)letto_binary_gen(out:output)n=letn=ifcomparen0L<0then(out'-';negn)elseninout'0';out'b';letrecloopstartedbitn=ifequalbit0Lthen(ifnotstartedthenout'0')else(letb=logandnbitinifequalb0Lthen(ifstartedthenout'0';loopstarted(shift_right_logicalbit1)n)else(out'1';looptrue(shift_right_logicalbit1)n))inloopfalsemost_significant_bitnletto_string_binaryn=letbuf=Buffer.create16into_binary_gen(Buffer.add_charbuf)n;Buffer.contentsbuf(** {2 Printing} *)letppoutn=Format.pp_print_stringout(to_stringn)letpp_binaryoutn=to_binary_gen(Format.pp_print_charout)n(** {2 Infix Operators} *)moduleInfix=structlet(+)=addlet(-)=sublet(~-)=neglet(*)=mullet(/)=divlet(**)=powlet(--)=rangelet(--^)=range'let(mod)=remlet(land)=logandlet(lor)=logorlet(lxor)=logxorletlnot=lognotlet(lsl)=shift_leftlet(lsr)=shift_right_logicallet(asr)=shift_rightlet(=)=equallet(<>)=Stdlib.(<>)let(<)=Stdlib.(<)let(<=)=Stdlib.(<=)let(>)=Stdlib.(>)let(>=)=Stdlib.(>=)endincludeInfix