123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202let(/^)ab=1+(a-1)/bletreclog2=function|0|1->0|n->1+log2(n/^2)letpow2n=1lslnmoduleMake(V:Varray_sig.TIER):Varray_sig.VARRAYwithtype'aelt='aV.eltandtype'aarray='aV.array=structmoduleTier=VmoduleArray=V.Arraytype'aelt='aV.elttype'aarray='aV.arraytype'at={mutablelc:int;mutableprotected:bool;mutablesmall:'aV.t;mutablelarge:'aV.t}letlengtht=V.lengtht.small+V.lengtht.largeletlc_for=function|nwhenn<=0->1|n->log2n/^V.depthletempty()={lc=0;protected=false;small=V.create~capacity:1;large=V.empty()}letis_emptyt=V.is_emptyt.small&&V.is_emptyt.largeletmakenx=letlc=lc_fornin{lc;protected=false;small=V.make~lcnx;large=V.empty()}letinitnf=letlc=lc_fornin{lc;protected=false;small=V.init~lc~offset:0nf;large=V.empty()}letprotecttf=ift.protectedthenf()elsebegint.protected<-true;matchf()with|v->t.protected<-false;v|exceptione->t.protected<-false;raiseeendletcheck_protectiont=ift.protectedthenfailwith"Varray modification during protected traversal"letgetti=letlc=t.lcinmatchi-V.lengtht.smallwith|jwheni>=0&&j<0->V.get~lct.smalli|jwhenj>=0&&j<V.lengtht.large->V.get~lc:(lc+1)t.largej|_->invalid_arg"index out of bounds"letsettix=letlc=t.lcinmatchi-V.lengtht.smallwith|jwheni>=0&&j<0->V.set~lct.smallix|jwhenj>=0&&j<V.lengtht.large->V.set~lc:(lc+1)t.largejx|_->invalid_arg"index out of bounds"letdo_swapt=t.lc<-1+t.lc;t.small<-t.large;t.large<-V.empty()letswapt=ifV.is_emptyt.small&¬(V.is_emptyt.large)thendo_swaptletis_growingt=lengtht>=V.capacity~lc:t.lcletpow2_depth=pow2V.depthletincr_capacityt=swapt;ifis_growingtthenbeginifnot(V.is_emptyt.large)thenbeginassert(not(V.is_emptyt.small));letlc=t.lcinlettl=V.pop_back~lct.smallinletlc=t.lc+1inV.push_front~lct.largetl;ifV.is_emptyt.smallthendo_swaptendelsebeginlettl=V.pop_back~lc:t.lct.smallinletlc=1+t.lcint.large<-V.make~lc1tlendendletinsert_attix=check_protectiont;incr_capacityt;matchi-V.lengtht.smallwith|jwhenj<=0->V.insert_at~lc:t.lct.smallix;incr_capacityt|j->V.insert_at~lc:(t.lc+1)t.largejxletis_shrinkingt=lengtht*pow2_depth<V.capacity~lc:t.lcletdecr_capacityt=swapt;ifis_shrinkingtthenbeginifnot(V.is_emptyt.large)thenbeginletlc=t.lcinassert(not(V.is_full~lct.small));V.push_back~lct.small(V.pop_front~lc:(lc+1)t.large)endelseift.lc>1&¬(V.is_emptyt.small)thenbeginletlc=t.lcinlethd=V.pop_front~lct.smallinletlc=t.lc-1int.lc<-lc;t.large<-t.small;t.small<-V.make~lc1hd;endendletpop_atti=check_protectiont;decr_capacityt;matchi-V.lengtht.smallwith|jwhenj<0->letx=V.pop_at~lc:t.lct.smalliindecr_capacityt;x|j->V.pop_at~lc:(t.lc+1)t.largejletdelete_atti=ignore(pop_atti)letpush_backtx=check_protectiont;incr_capacityt;letlc=t.lcinifV.is_emptyt.largethenV.push_back~lct.smallxelseV.push_back~lc:(lc+1)t.largexletpush_fronttx=check_protectiont;incr_capacityt;letlc=t.lcinV.push_front~lct.smallx;incr_capacitytletpop_frontt=check_protectiont;decr_capacityt;letx=V.pop_front~lc:t.lct.smallindecr_capacityt;xletpop_backt=check_protectiont;decr_capacityt;ifV.is_emptyt.largethenV.pop_back~lc:t.lct.smallelseV.pop_back~lc:(t.lc+1)t.largeend