123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436type('a,-'p)t={mutabledata:'aarray;mutablelength:int}let[@inline]array_uninitn=Array.maken(Obj.magic0)let[@inline]make_unsafecapacitylength={data=array_uninitcapacity;length}let[@inline]make?capacity:(c=0)()=ifc<0thenraise(Invalid_argument"Negative capacity")elsemake_unsafec0letas_read_onlyv=(v:>('a,[`R])t)letas_write_onlyv=(v:>('a,[`W])t)let[@inline]lengthv=v.lengthlet[@inline]capacityv=Array.lengthv.datalet[@inline]clearv=v.data<-[||];v.length<-0let[@inline]getvi=ifi<0||i>=v.lengththenraise(Invalid_argument"Index out of range")elsev.data.(i)let[@inline]setvia=ifi<0||i>=v.lengththenraise(Invalid_argument"Index out of range")elsev.data.(i)<-alettry_getvi=ifi<0||i>=v.lengththenNoneelseSomev.data.(i)let[@inline]try_setvia=i>=0&&i<v.length&&(v.data.(i)<-a;true)letreservecv=letold_c=capacityvinifc>old_cthen(* Formula taken from ocaml-containers CCVector implementation: https://github.com/c-cube/ocaml-containers/blob/69cd3ca78d60fbcb9aa2e6e63d92015af1f54941/src/core/CCVector.ml#L45 *)letnew_c=ref(old_c+(old_clsr1)+2)inwhile!new_c<cdonew_c:=!new_c+(!new_clsr1)+2done;letdata=array_uninit!new_cinArray.blitv.data0data0v.length;v.data<-datalet[@inline]shrink_to_fitv=ifcapacityv>v.lengththenletdata=array_uninitv.lengthinArray.blitv.data0data0v.length;v.data<-datalet[@inline]pushav=letold_length=v.lengthinletnew_length=old_length+1inreservenew_lengthv;v.length<-new_length;v.data.(old_length)<-alet[@inline]try_popv=ifv.length=0thenNoneelseletlast=v.length-1inleta=v.data.(last)inv.data.(last)<-Obj.magic0;v.length<-last;Somealet[@inline]popv=matchtry_popvwith|None->raise(Invalid_argument"Empty vector")|Somea->alet[@inline]singletona={data=[|a|];length=1}lettry_findfv=letrecgoi=ifi=v.lengththenNoneelseleta=v.data.(i)iniffathenSomeaelsego(i+1)ingo0let[@inline]findfv=matchtry_findfvwith|None->raiseNot_found|Somea->alettry_insert_atiav=ifi<0||i>v.lengththenfalseelseletnew_length=v.length+1inreservenew_lengthv;Array.blitv.dataiv.data(i+1)(v.length-i);v.data.(i)<-a;v.length<-new_length;truelet[@inline]insert_atiav=ifnot(try_insert_atiav)thenraise(Invalid_argument"Index out of range")lettry_remove_ativ=ifi<0||i>=v.lengththenNoneelseleta=v.data.(i)inArray.blitv.data(i+1)v.datai(v.length-i-1);v.length<-v.length-1;v.data.(v.length)<-Obj.magic0;Somealet[@inline]remove_ativ=matchtry_remove_ativwith|None->raise(Invalid_argument"Index out of range")|Somea->aletmapfv=letv2=make_unsafev.lengthv.lengthinfori=0tov.length-1dov2.data.(i)<-fv.data.(i)done;v2letmapifv=letv2=make_unsafev.lengthv.lengthinfori=0tov.length-1dov2.data.(i)<-fiv.data.(i)done;v2letmap_in_placefv=fori=0tov.length-1dov.data.(i)<-fv.data.(i)doneletmap2fv1v2=lettotal_length=v1.length*v2.lengthinletv=make_unsafetotal_lengthtotal_lengthinletidx=ref0infori=0tov1.length-1doforj=0tov2.length-1dov.data.(!idx)<-fv1.data.(i)v2.data.(j);incridxdonedone;vlet[@inline]applyfv=map2(@@)fvletflattenvs=lettotal_length=ref0infori=0tovs.length-1dototal_length:=!total_length+vs.data.(i).lengthdone;letvec=make_unsafe!total_length!total_lengthinletidx=ref0infori=0tovs.length-1doletv=vs.data.(i)inArray.blitv.data0vec.data!idxv.length;idx:=!idx+v.lengthdone;veclet[@inline]append_in_placevv2=lettotal_length=v.length+v2.lengthinreservetotal_lengthv;Array.blitv2.data0v.datav.lengthv2.length;v.length<-total_lengthletflat_mapfv=letv2=make_unsafev.length0infori=0tov.length-1doappend_in_placev2(fv.data.(i))done;v2let[@inline]cartesian_productab=map2(funab->a,b)abletiterfv=fori=0tov.length-1dofv.data.(i)doneletiterifv=fori=0tov.length-1dofiv.data.(i)doneletfilterfv=letv2=make_unsafev.length0inletl=ref0infori=0tov.length-1doleta=v.data.(i)iniffathen(v2.data.(!l)<-a;incrl)done;v2.length<-!l;v2letfilterifv=letv2=make_unsafev.length0inletl=ref0infori=0tov.length-1doleta=v.data.(i)iniffiathen(v2.data.(!l)<-a;incrl)done;v2.length<-!l;v2letfilter_in_placefv=letold_length=v.lengthinletl=ref0infori=0toold_length-1doleta=v.data.(i)iniffathen(v.data.(!l)<-a;incrl)done;Array.fillv.data!l(old_length-!l)(Obj.magic0);v.length<-!llet[@inline]of_array_unsafea={data=a;length=Array.lengtha}let[@inline]to_array_unsafev=v.datalet[@inline]of_arraya=of_array_unsafe(Array.copya)let[@inline]to_arrayv=Array.subv.data0v.lengthlet[@inline]of_listl=of_array_unsafe(Array.of_listl)letto_listv=letrecgoacc=function|-1->acc|i->go(v.data.(i)::acc)(i-1)ingo[](v.length-1)let[@inline]copyv=of_array_unsafe(to_arrayv)let[@inline]appendvv2=letv'=copyvinappend_in_placev'v2;v'letrev_in_placev=letrecgoij=ifi<jthenlettmp=v.data.(i)inv.data.(i)<-v.data.(j);v.data.(j)<-tmp;go(i+1)(j-1)ingo0(v.length-1)let[@inline]revv=letv'=copyvinrev_in_placev';v'let[@inline]existsfv=letrecgoi=i<v.length&&(fv.data.(i)||go(i+1))ingo0let[@inline]for_allfv=letrecgoi=i=v.length||(fv.data.(i)&&go(i+1))ingo0let[@inline]meme=exists((=)e)let[@inline]memqe=exists((==)e)letfold_leftfzv=letrecgoacci=ifi=v.lengththenaccelsego(faccv.data.(i))(i+1)ingoz0letfold_rightfvz=letrecgoacci=ifi<=0thenaccelsego(fv.data.(i)acc)(i-1)ingoz(v.length-1)letzip_withfv1v2=letmin_length=minv1.lengthv2.lengthinletv=make_unsafemin_lengthmin_lengthinfori=0tomin_length-1dov.data.(i)<-fv1.data.(i)v2.data.(i)done;vlet[@inline]zipv1v2=zip_with(funab->(a,b))v1v2let[@inline]sort_byfv=shrink_to_fitv;Array.fast_sortfv.datalet[@inline]sortv=sort_bycomparevlet[@inline]equal_byfab=ifa.length<>b.lengththenfalseelseletrecgoi=i=a.length||(fa.data.(i)b.data.(i)&&go(i+1))ingo0let[@inline]equalab=equal_by(=)abletcompare_byfab=letmin_l,min_l_ord=matcha.length-b.lengthwith|0->a.length,0|lwhenl<0->a.length,-1|_->b.length,1inletrecgoi=ifi=min_lthenmin_l_ordelseletord=fa.data.(i)b.data.(i)iniford<>0thenordelsego(i+1)ingo0let[@inline]compareab=compare_bycompareabletpretty_printfmtv=ifv.length=0then"[]"elseletbuf=Buffer.create2inBuffer.add_charbuf'[';Buffer.add_stringbuf(fmtv.data.(0));fori=1tov.length-1doBuffer.add_stringbuf"; ";Buffer.add_stringbuf(fmtv.data.(i))done;Buffer.add_charbuf']';Buffer.contentsbuflet[@inline]rangestartend'=letl=(abs(end'-start)+1)inletd=ifstart<=end'then1else-1inof_array_unsafe(Array.initl(funi->start+i*d))moduleInfix=structlet(.![])=getlet(.![]<-)=setlet(.?[])=try_getlet(.?[]<-)=try_setlet[@inline](let+)vf=mapfvlet(and+)=cartesian_productlet[@inline](let*)vf=flat_mapfvlet(and*)=cartesian_productlet(@)=appendlet(=|<)=maplet[@inline](>|=)vf=f=|<vlet(<$>)=maplet(<*>)=applylet(=<<)=flat_maplet(>>=)vf=f=<<vlet(--)=rangeend