/* Ċ Ġ* ĠP _ Extract Sub tuple . kt Ċ Ġ* ĠCopyright ĠÂ© Ġ 1 9 9 3 - 2 0 2 0 , ĠThe ĠAv ail ĠFoundation , ĠLLC . Ċ Ġ* ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠRedistribution Ġand Ġuse Ġin Ġsource Ġand Ġbinary Ġforms , Ġwith Ġor Ġwithout Ċ Ġ* Ġmodification , Ġare Ġpermitted Ġprovided Ġthat Ġthe Ġfollowing Ġconditions Ġare Ġmet : Ċ Ġ* Ċ Ġ* Ġ* ĠRedistributions Ġof Ġsource Ġcode Ġmust Ġretain Ġthe Ġabove Ġcopyright Ġnotice , Ġthis Ċ Ġ* ĠĠ Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer . Ċ Ġ* Ċ Ġ* Ġ* ĠRedistributions Ġin Ġbinary Ġform Ġmust Ġreproduce Ġthe Ġabove Ġcopyright Ġnotice , Ċ Ġ* ĠĠ Ġthis Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer Ġin Ġthe Ġdocumentation Ċ Ġ* ĠĠ Ġand / or Ġother Ġmaterials Ġprovided Ġwith Ġthe Ġdistribution . Ċ Ġ* Ċ Ġ* Ġ* ĠNeither Ġthe Ġname Ġof Ġthe Ġcopyright Ġholder Ġnor Ġthe Ġnames Ġof Ġthe Ġcontributors Ċ Ġ* ĠĠ Ġmay Ġbe Ġused Ġto Ġendorse Ġor Ġpromote Ġproducts Ġderived Ġfrom Ġthis Ġsoftware Ċ Ġ* ĠĠ Ġwithout Ġspecific Ġprior Ġwritten Ġpermission . Ċ Ġ* Ċ Ġ* ĠTHIS ĠSOFTWARE ĠIS ĠPROVIDED ĠBY ĠTHE ĠCOPYRIGHT ĠHOLDERS ĠAND ĠCONTRIBUTORS Ġ" AS ĠIS " Ċ Ġ* ĠAND ĠANY ĠEXPRESS ĠOR ĠIMPLIED ĠWARRANTIES , ĠINCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠTHE Ċ Ġ* ĠIMPLIED ĠWARRANTIES ĠOF ĠMERCHANTABILITY ĠAND ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE Ċ Ġ* ĠARE ĠDISCLAIMED . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠCOPYRIGHT ĠHOLDER ĠOR ĠCONTRIBUTORS ĠBE Ċ Ġ* ĠLIABLE ĠFOR ĠANY ĠDIRECT , ĠINDIRECT , ĠINCIDENTAL , ĠSPECIAL , ĠEXEMPLARY , ĠOR Ċ Ġ* ĠCONSEQUENTIAL ĠDAMAGES Ġ( INCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠPROCUREMENT ĠOF Ċ Ġ* ĠSUBSTITUTE ĠGOODS ĠOR ĠSERVICES ; ĠLOSS ĠOF ĠUSE , ĠDATA , ĠOR ĠPROFITS ; ĠOR ĠBUSINESS Ċ Ġ* ĠINTERRUPTION ) ĠHOWEVER ĠCAUSED ĠAND ĠON ĠANY ĠTHEORY ĠOF ĠLIABILITY , ĠWHETHER ĠIN Ċ Ġ* ĠCONTRACT , ĠSTRICT ĠLIABILITY , ĠOR ĠTORT Ġ( INCLUDING ĠNEGLIGENCE ĠOR ĠOTHERWISE ) Ċ Ġ* ĠARISING ĠIN ĠANY ĠWAY ĠOUT ĠOF ĠTHE ĠUSE ĠOF ĠTHIS ĠSOFTWARE , ĠEVEN ĠIF ĠADVISED ĠOF ĠTHE Ċ Ġ* ĠPOSSIBILITY ĠOF ĠSUCH ĠDAMAGE . Ċ Ġ*/ Ċ package Ġcom . avail . interpreter . primitive . tuples Ċ Ċ import Ġcom . avail . descriptor . functions . A _ Raw Function Ċ import Ġcom . avail . descriptor . numbers . A _ Number . Companion . extract Int Ċ import Ġcom . avail . descriptor . numbers . Infinity Descriptor . Companion . positive Infinity Ċ import Ġcom . avail . descriptor . numbers . Integer Descriptor . Companion . from Int Ċ import Ġcom . avail . descriptor . sets . Set Descriptor . Companion . set Ċ import Ġcom . avail . descriptor . tuples . A _ Tuple . Companion . copy Tuple From To Can Destroy Ċ import Ġcom . avail . descriptor . tuples . A _ Tuple . Companion . tuple Size Ċ import Ġcom . avail . descriptor . tuples . Object Tuple Descriptor . Companion . tuple Ċ import Ġcom . avail . descriptor . tuples . Object Tuple Descriptor . Companion . tuple From List Ċ import Ġcom . avail . descriptor . tuples . Tuple Descriptor Ċ import Ġcom . avail . descriptor . tuples . Tuple Descriptor . Companion . empty Tuple Ċ import Ġcom . avail . descriptor . types . A _ Type Ċ import Ġcom . avail . descriptor . types . A _ Type . Companion . lower Bound Ċ import Ġcom . avail . descriptor . types . A _ Type . Companion . size Range Ċ import Ġcom . avail . descriptor . types . A _ Type . Companion . type Tuple Ċ import Ġcom . avail . descriptor . types . A _ Type . Companion . union Of Types At Through Ċ import Ġcom . avail . descriptor . types . A _ Type . Companion . upper Bound Ċ import Ġcom . avail . descriptor . types . Abstract Enumeration TypeDescriptor . Companion . enumeration With Ċ import Ġcom . avail . descriptor . types . FunctionType Descriptor . Companion . function Type Ċ import Ġcom . avail . descriptor . types . Instance TypeDescriptor . Companion . instance Type Ċ import Ġcom . avail . descriptor . types . Integer Range TypeDescriptor . Companion . integer Range Type Ċ import Ġcom . avail . descriptor . types . Integer Range TypeDescriptor . Companion . natural Numbers Ċ import Ġcom . avail . descriptor . types . Integer Range TypeDescriptor . Companion . whole Numbers Ċ import Ġcom . avail . descriptor . types . Tuple TypeDescriptor . Companion . most General Tuple Type Ċ import Ġcom . avail . descriptor . types . Tuple TypeDescriptor . Companion . tuple Type For Sizes Types Default Type Ċ import Ġcom . avail . exceptions . Avail ErrorCode . E _ SUB SCRIPT _ OUT _ OF _ BOUN DS Ċ import Ġcom . avail . interpreter . Primitive Ċ import Ġcom . avail . interpreter . Primitive . F al lib ility . Call Site Can Fail Ċ import Ġcom . avail . interpreter . Primitive . F al lib ility . Call Site Cannot Fail Ċ import Ġcom . avail . interpreter . Primitive . F al lib ility . Call Site Must Fail Ċ import Ġcom . avail . interpreter . Primitive . Flag . Can Fold Ċ import Ġcom . avail . interpreter . Primitive . Flag . Can Inline Ċ import Ġcom . avail . interpreter . execution . Interpreter Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ Ċ /** Ċ Ġ* Ġ** Primitive :** ĠExtract Ġa Ġ[ sub tuple ][ Tuple Descriptor ] Ġwith Ġthe Ġgiven Ġrange Ġof Ċ Ġ* Ġelements . Ċ Ġ*/ Ċ @ Suppress (" unused ") Ċ object ĠP _ Extract Sub tuple Ġ: ĠPrimitive ( 3 , ĠCan Fold , ĠCan Inline ) Ċ { Ċ ĉ override Ġfun Ġattempt ( interpreter : ĠInterpreter ): ĠResult Ċ ĉ { Ċĉ ĉ interpreter . check Argument Count ( 3 ) Ċĉ ĉ val Ġtuple Ġ= Ġinterpreter . argument ( 0 ) Ċĉ ĉ val Ġstart Ġ= Ġinterpreter . argument ( 1 ) Ċĉ ĉ val Ġend Ġ= Ġinterpreter . argument ( 2 ) Ċĉ ĉ if Ġ(! start . is Int Ġ|| Ġ! end . is Int ) Ċĉ ĉ { Ċĉĉ ĉ return Ġinterpreter . primitive Failure ( E _ SUB SCRIPT _ OUT _ OF _ BOUN DS ) Ċĉ ĉ } Ċĉ ĉ val Ġstart Int Ġ= Ġstart . extract Int () Ċĉ ĉ val Ġend Int Ġ= Ġend . extract Int () Ċĉ ĉ return Ġwhen Ċĉ ĉ { Ċĉĉ ĉ start Int Ġ< Ġ 1 Ġ-> Ċĉĉĉ ĉ interpreter . primitive Failure ( E _ SUB SCRIPT _ OUT _ OF _ BOUN DS ) Ċĉĉ ĉ start Int Ġ> Ġend Int Ġ+ Ġ 1 Ġ-> Ċĉĉĉ ĉ interpreter . primitive Failure ( E _ SUB SCRIPT _ OUT _ OF _ BOUN DS ) Ċĉĉ ĉ end Int Ġ> Ġtuple . tuple Size () Ġ-> Ċĉĉĉ ĉ interpreter . primitive Failure ( E _ SUB SCRIPT _ OUT _ OF _ BOUN DS ) Ċĉĉ ĉ else Ġ-> Ċĉĉĉ ĉ interpreter . primitive Success ( Ċĉĉĉĉ ĉ tuple . copy Tuple From To Can Destroy ( start Int , Ġend Int , Ġtrue )) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ override Ġfun Ġfal lib ility For Argument Types ( Ċĉ ĉ argument Types : ĠList < A _ Type > Ċ ĉ ): ĠF al lib ility Ċ ĉ { Ċĉ ĉ val Ġtuple Type Ġ= Ġargument Types [ 0 ] Ċĉ ĉ val ĠstartIndex Type Ġ= Ġargument Types [ 1 ] Ċĉ ĉ val Ġend Index Type Ġ= Ġargument Types [ 2 ] ĊĊĉ ĉ return Ġcheck F al lib ility ( Ċĉĉ ĉ tuple Type . size Range (), ĠstartIndex Type , Ġend Index Type ) Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠCheck Ġwhether Ġthe Ġgiven Ġtuple Ġsize Ġrange Ġcan Ġhave Ġa Ġslice Ġextracted Ġwith Ċĉ Ġ* Ġstart Ġand Ġend Ġindices Ġwith Ġthe Ġgiven Ġrange . Ġ ĠAnswer Ġa Ċĉ Ġ* Ġ[ Primitive . F al lib ility ] Ġthat Ġindicates Ġwhether Ġthe Ġextraction Ġwould Ċĉ Ġ* Ġalways , Ġsometimes , Ġor Ġnever Ġfail . Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġsize Range Ċĉ Ġ* ĠĠ ĠThe Ġinteger Ġrange Ġtype Ġdescribing Ġthe Ġpossible Ġtuple Ġsizes . Ċĉ Ġ* Ġ@ param ĠstartIndex Type Ċĉ Ġ* ĠĠ ĠAn Ġinteger Ġrange Ġtype Ġbounding Ġthe Ġpossible Ġslice Ġstarting Ġindex . Ċĉ Ġ* Ġ@ param Ġend Index Type Ċĉ Ġ* ĠĠ ĠAn Ġinteger Ġrange Ġtype Ġbounding Ġthe Ġpossible Ġslice Ġending Ġindex . Ċĉ Ġ* Ġ@ return Ċĉ Ġ* ĠĠ ĠThe Ġfal lib ility Ġguarantee Ġof Ġthe Ġtuple Ġextraction Ġattempt . Ċĉ Ġ*/ Ċ ĉ fun Ġcheck F al lib ility ( Ċĉ ĉ size Range : ĠA _ Type , Ċĉ ĉ startIndex Type : ĠA _ Type , Ċĉ ĉ end Index Type : ĠA _ Type Ċ ĉ ): ĠF al lib ility Ċ ĉ { Ċĉ ĉ val Ġsize Lower Ġ= Ġsize Range . lower Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) Ġreturn ĠCall Site Must Fail Ġ Ġ// ĠCall Ġcan 't Ġactually Ġhappen . Ċĉĉ ĉ extract Int () Ċĉ ĉ } Ċĉ ĉ val Ġsize Upper Ġ= Ġsize Range . upper Bound (). run Ġ{ Ċĉĉ ĉ if Ġ( is Int ) Ġextract Int () Ċĉĉ ĉ else ĠInt . MAX _ VALUE Ġ Ġ// ĠThe Ġ* actual * Ġtuple Ġis Ġconstr ained . Ċĉ ĉ } ĊĊĉ ĉ val Ġstart Lower Ġ= ĠstartIndex Type . lower Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) Ġreturn ĠCall Site Must Fail Ċĉĉ ĉ extract Int () Ċĉ ĉ } Ċĉ ĉ val Ġend Lower Ġ= Ġend Index Type . lower Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) Ġreturn ĠCall Site Must Fail Ċĉĉ ĉ extract Int () Ċĉ ĉ } Ċĉ ĉ val Ġstart Upper Ġ= ĠstartIndex Type . upper Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) Ġreturn ĠCall Site Can Fail Ċĉĉ ĉ extract Int () Ċĉ ĉ } Ċĉ ĉ val Ġend Upper Ġ= Ġend Index Type . upper Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) Ġreturn ĠCall Site Can Fail Ċĉĉ ĉ extract Int () Ċĉ ĉ } Ċĉ ĉ return Ġwhen Ċĉ ĉ { Ċĉĉ ĉ // ĠDef initely Ġa Ġde generate Ġslice . Ċĉĉ ĉ end Upper Ġ< Ġstart Lower Ġ- Ġ 1 Ġ-> ĠCall Site Must Fail Ċĉĉ ĉ // ĠDef initely Ġout - of - range . Ċĉĉ ĉ start Lower Ġ- Ġ 1 Ġ> Ġsize Upper Ġ-> ĠCall Site Must Fail Ċĉĉ ĉ // ĠAt Ġthis Ġpoint , Ġthe Ġslice Ġis Ġat Ġleast Ġpossible . Ġ ĠCheck Ġfor Ċĉĉ ĉ // Ġpossible Ġde gener acy . Ċĉĉ ĉ end Lower Ġ< Ġstart Upper Ġ- Ġ 1 Ġ-> ĠCall Site Can Fail Ċĉĉ ĉ // ĠAnd Ġcheck Ġfor Ġa Ġpossible Ġout - of - range . Ċĉĉ ĉ end Upper Ġ> Ġsize Lower Ġ-> ĠCall Site Can Fail Ċĉĉ ĉ else Ġ-> ĠCall Site Cannot Fail Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ override Ġfun ĠreturnType Gu arante edBy VM ( Ċĉ ĉ raw Function : ĠA _ Raw Function , Ċĉ ĉ argument Types : ĠList < A _ Type >): ĠA _ Type Ċ ĉ { Ċĉ ĉ val Ġtuple Type Ġ= Ġargument Types [ 0 ] Ċĉ ĉ val ĠstartIndex Type Ġ= Ġargument Types [ 1 ] Ċĉ ĉ val Ġend Index Type Ġ= Ġargument Types [ 2 ] ĊĊĉ ĉ return Ġcompute Slice Type ( tuple Type , ĠstartIndex Type , Ġend Index Type ) Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠCompute Ġthe Ġtypes Ġthat Ġcan Ġbe Ġproduced Ġby Ġextracting Ġa Ġsubrange Ġof Ġa Ċĉ Ġ* Ġtuple Ġhaving Ġthe Ġgiven Ġ[ tuple Type ], Ġstarting Ġat Ġan Ġindex Ġthat Ġfalls Ġin Ċĉ Ġ* Ġthe Ġinteger Ġrange Ġtype Ġ[ startIndex Type ], Ġand Ġending Ġat Ġan Ġindex Ġthat Ċĉ Ġ* Ġfalls Ġin Ġthe Ġinteger Ġrange Ġtype Ġ[ end Index Type ]. Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġtuple Type Ċĉ Ġ* ĠĠ ĠThe Ġtype Ġof Ġthe Ġtuple Ġbeing Ġs liced . Ċĉ Ġ* Ġ@ param ĠstartIndex Type Ċĉ Ġ* ĠĠ ĠAn Ġinteger Ġrange Ġtype Ġbounding Ġthe Ġpossible Ġslice Ġstarting Ġindex . Ċĉ Ġ* Ġ@ param Ġend Index Type Ċĉ Ġ* ĠĠ ĠAn Ġinteger Ġrange Ġtype Ġbounding Ġthe Ġpossible Ġslice Ġending Ġindex . Ċĉ Ġ* Ġ@ return Ċĉ Ġ* ĠĠ ĠThe Ġguaranteed Ġtype Ġof Ġthe Ġresulting Ġtuple , Ġin Ġthe Ġevent Ġthat Ġit 's Ċĉ Ġ* ĠĠ Ġsuccessful . Ċĉ Ġ*/ Ċ ĉ fun Ġcompute Slice Type ( Ċĉ ĉ tuple Type : ĠA _ Type , Ċĉ ĉ startIndex Type : ĠA _ Type , Ċĉ ĉ end Index Type : ĠA _ Type Ċ ĉ ): ĠA _ Type Ċ ĉ { Ċĉ ĉ // ĠPre compute Ġa Ġfallback Ġreturn Ġtype Ġfor Ġeasy Ġexits . Ċĉ ĉ val Ġfallback Ġ= Ġmost General Tuple Type () ĊĊĉ ĉ val Ġsize Range Ġ= Ġtuple Type . size Range () Ċĉ ĉ val Ġsize Upper Ġ= Ġsize Range . upper Bound (). run Ġ{ Ċĉĉ ĉ if Ġ( is Int ) Ġextract Int () Ċĉĉ ĉ else ĠInt . MAX _ VALUE Ġ Ġ// ĠIf Ġit 's Ġvery Ġlarge Ġor Ġeven Ġinfinity Ċĉ ĉ } Ċĉ ĉ val Ġstart Lower Ġ= ĠstartIndex Type . lower Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) Ġreturn Ġfallback Ċĉĉ ĉ extract Int () Ċĉ ĉ } Ċĉ ĉ val Ġstart Upper Ġ= ĠstartIndex Type . upper Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) ĠInt . MAX _ VALUE Ċĉĉ ĉ else Ġextract Int () Ċĉ ĉ } Ċĉ ĉ val Ġend Lower Ġ= Ġend Index Type . lower Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) Ġreturn Ġfallback Ċĉĉ ĉ extract Int () Ċĉ ĉ } Ċĉ ĉ val Ġend Upper Ġ= Ġend Index Type . upper Bound (). run Ġ{ Ċĉĉ ĉ if Ġ(! is Int ) ĠInt . MAX _ VALUE Ċĉĉ ĉ else Ġextract Int () Ċĉ ĉ } ĊĊĉ ĉ if Ġ( start Lower Ġ> Ġend Upper ) Ċĉ ĉ { Ċĉĉ ĉ // ĠIt 's Ġalways Ġeither Ġempty Ġor Ġde generate . Ċĉĉ ĉ return Ġinstance Type ( empty Tuple ) Ċĉ ĉ } ĊĊĉ ĉ // ĠNo Ġneed Ġto Ġcompute Ġelement Ġtypes Ġbeyond Ġthis Ġposition , Ġsince Ċĉ ĉ // Ġthey 'll Ġall Ġhave Ġthe Ġsame Ġtype . Ċĉ ĉ val Ġvariation Limit Ġ= Ċĉĉ ĉ min ( tuple Type . type Tuple (). tuple Size () Ġ+ Ġ 1 , Ġsize Upper ) ĊĊĉ ĉ // ĠThe Ġdifference Ġbetween Ġext re ma Ġfor Ġstarting Ġpositions . Ċĉ ĉ val Ġs me ar Delta Ġ= Ġstart Upper Ġ- Ġstart Lower ĊĊĉ ĉ val Ġleading Types Ġ= Ċĉĉ ĉ ( start Lower Ġ.. Ġmax ( start Lower , Ġmin ( end Upper , Ġvariation Limit ))). map Ġ{ Ċĉĉĉ ĉ tuple Type . union Of Types At Through ( Ċĉĉĉĉ ĉ it , Ċĉĉĉĉ ĉ // ĠDon 't Ġexceed Ġan Ġint . Ċĉĉĉĉ ĉ min ( Ċĉĉĉĉĉ ĉ it . to Long () Ġ+ Ġs me ar Delta , Ċĉĉĉĉĉ ĉ Int . MAX _ VALUE . to Long () Ċĉĉĉĉ ĉ ). toInt ()) Ċĉĉ ĉ } Ċĉ ĉ val Ġmin Size Ġ= Ġmax ( end Lower Ġ- Ġstart Upper Ġ+ Ġ 1 , Ġ 0 ) Ċĉ ĉ val ĠmaxSize Ġ= Ġmin ( end Upper , Ġsize Upper ) Ġ- Ġstart Lower Ġ+ Ġ 1 Ċĉ ĉ val ĠmaxSize Object Ġ= Ġwhen Ċĉ ĉ { Ċĉĉ ĉ end Upper Ġ== ĠInt . MAX _ VALUE Ġ&& Ġsize Upper Ġ== ĠInt . MAX _ VALUE Ġ-> Ċĉĉĉ ĉ positive Infinity () Ċĉĉ ĉ else Ġ-> Ġfrom Int ( maxSize ) Ċĉ ĉ } Ċĉ ĉ return Ġtuple Type For Sizes Types Default Type ( Ċĉĉ ĉ integer Range Type ( Ċĉĉĉ ĉ from Int ( min Size ), Ċĉĉĉ ĉ true , Ċĉĉĉ ĉ maxSize Object , Ċĉĉĉ ĉ maxSize Object . is Finite ), Ċĉĉ ĉ tuple From List ( leading Types ), Ċĉĉ ĉ leading Types . last ()). make Immutable () Ċ ĉ } ĊĊ ĉ override Ġfun Ġprivate BlockType Restriction (): ĠA _ Type Ġ= Ċĉ ĉ function Type ( Ċĉĉ ĉ tuple ( Ċĉĉĉ ĉ most General Tuple Type (), Ċĉĉĉ ĉ natural Numbers , Ċĉĉĉ ĉ whole Numbers Ċĉĉ ĉ ), Ċĉĉ ĉ most General Tuple Type ()) ĊĊ ĉ override Ġfun Ġprivate Failure Variable Type (): ĠA _ Type Ġ= Ċĉ ĉ enumeration With ( set ( E _ SUB SCRIPT _ OUT _ OF _ BOUN DS )) Ċ } Ċ