entt.hpp 3.1 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073730747307573076730777307873079730807308173082730837308473085730867308773088730897309073091730927309373094730957309673097730987309973100731017310273103731047310573106731077310873109731107311173112731137311473115731167311773118731197312073121731227312373124731257312673127731287312973130731317313273133731347313573136731377313873139731407314173142731437314473145731467314773148731497315073151731527315373154731557315673157731587315973160731617316273163731647316573166731677316873169731707317173172731737317473175731767317773178731797318073181731827318373184731857318673187731887318973190731917319273193731947319573196731977319873199732007320173202732037320473205732067320773208732097321073211732127321373214732157321673217732187321973220732217322273223732247322573226732277322873229732307323173232732337323473235732367323773238732397324073241732427324373244732457324673247732487324973250732517325273253732547325573256732577325873259732607326173262732637326473265732667326773268732697327073271732727327373274732757327673277732787327973280732817328273283732847328573286732877328873289732907329173292732937329473295732967329773298732997330073301733027330373304733057330673307733087330973310733117331273313733147331573316733177331873319733207332173322733237332473325733267332773328733297333073331733327333373334733357333673337733387333973340733417334273343733447334573346733477334873349733507335173352733537335473355733567335773358733597336073361733627336373364733657336673367733687336973370733717337273373733747337573376733777337873379733807338173382733837338473385733867338773388733897339073391733927339373394733957339673397733987339973400734017340273403734047340573406734077340873409734107341173412734137341473415734167341773418734197342073421734227342373424734257342673427734287342973430734317343273433734347343573436734377343873439734407344173442734437344473445734467344773448734497345073451734527345373454734557345673457734587345973460734617346273463734647346573466734677346873469734707347173472734737347473475734767347773478734797348073481734827348373484734857348673487734887348973490734917349273493734947349573496734977349873499735007350173502735037350473505735067350773508735097351073511735127351373514735157351673517735187351973520735217352273523735247352573526735277352873529735307353173532735337353473535735367353773538735397354073541735427354373544735457354673547735487354973550735517355273553735547355573556735577355873559735607356173562735637356473565735667356773568735697357073571735727357373574735757357673577735787357973580735817358273583735847358573586735877358873589735907359173592735937359473595735967359773598735997360073601736027360373604736057360673607736087360973610736117361273613736147361573616736177361873619736207362173622736237362473625736267362773628736297363073631736327363373634736357363673637736387363973640736417364273643736447364573646736477364873649736507365173652736537365473655736567365773658736597366073661736627366373664736657366673667736687366973670736717367273673736747367573676736777367873679736807368173682736837368473685736867368773688736897369073691736927369373694736957369673697736987369973700737017370273703737047370573706737077370873709737107371173712737137371473715737167371773718737197372073721737227372373724737257372673727737287372973730737317373273733737347373573736737377373873739737407374173742737437374473745737467374773748737497375073751737527375373754737557375673757737587375973760737617376273763737647376573766737677376873769737707377173772737737377473775737767377773778737797378073781737827378373784737857378673787737887378973790737917379273793737947379573796737977379873799738007380173802738037380473805738067380773808738097381073811738127381373814738157381673817738187381973820738217382273823738247382573826738277382873829738307383173832738337383473835738367383773838738397384073841738427384373844738457384673847738487384973850738517385273853738547385573856738577385873859738607386173862738637386473865738667386773868738697387073871738727387373874738757387673877738787387973880738817388273883738847388573886738877388873889738907389173892738937389473895738967389773898738997390073901739027390373904739057390673907739087390973910739117391273913739147391573916739177391873919739207392173922739237392473925739267392773928739297393073931739327393373934739357393673937739387393973940739417394273943739447394573946739477394873949739507395173952739537395473955739567395773958739597396073961739627396373964739657396673967739687396973970739717397273973739747397573976739777397873979739807398173982739837398473985739867398773988739897399073991739927399373994739957399673997739987399974000740017400274003740047400574006740077400874009740107401174012740137401474015740167401774018740197402074021740227402374024740257402674027740287402974030740317403274033740347403574036740377403874039740407404174042740437404474045740467404774048740497405074051740527405374054740557405674057740587405974060740617406274063740647406574066740677406874069740707407174072740737407474075740767407774078740797408074081740827408374084740857408674087740887408974090740917409274093740947409574096740977409874099741007410174102741037410474105741067410774108741097411074111741127411374114741157411674117741187411974120741217412274123741247412574126741277412874129741307413174132741337413474135741367413774138741397414074141741427414374144741457414674147741487414974150741517415274153741547415574156741577415874159741607416174162741637416474165741667416774168741697417074171741727417374174741757417674177741787417974180741817418274183741847418574186741877418874189741907419174192741937419474195741967419774198741997420074201742027420374204742057420674207742087420974210742117421274213742147421574216742177421874219742207422174222742237422474225742267422774228742297423074231742327423374234742357423674237742387423974240742417424274243742447424574246742477424874249742507425174252742537425474255742567425774258742597426074261742627426374264742657426674267742687426974270742717427274273742747427574276742777427874279742807428174282742837428474285742867428774288742897429074291742927429374294742957429674297742987429974300743017430274303743047430574306743077430874309743107431174312743137431474315743167431774318743197432074321743227432374324743257432674327743287432974330743317433274333743347433574336743377433874339743407434174342743437434474345743467434774348743497435074351743527435374354743557435674357743587435974360743617436274363743647436574366743677436874369743707437174372743737437474375743767437774378743797438074381743827438374384743857438674387743887438974390743917439274393743947439574396743977439874399744007440174402744037440474405744067440774408744097441074411744127441374414744157441674417744187441974420744217442274423744247442574426744277442874429744307443174432744337443474435744367443774438744397444074441744427444374444744457444674447744487444974450744517445274453744547445574456744577445874459744607446174462744637446474465744667446774468744697447074471744727447374474744757447674477744787447974480744817448274483744847448574486744877448874489744907449174492744937449474495744967449774498744997450074501745027450374504745057450674507745087450974510745117451274513745147451574516745177451874519745207452174522745237452474525745267452774528745297453074531745327453374534745357453674537745387453974540745417454274543745447454574546745477454874549745507455174552745537455474555745567455774558745597456074561745627456374564745657456674567745687456974570745717457274573745747457574576745777457874579745807458174582745837458474585745867458774588745897459074591745927459374594745957459674597745987459974600746017460274603746047460574606746077460874609746107461174612746137461474615746167461774618746197462074621746227462374624746257462674627746287462974630746317463274633746347463574636746377463874639746407464174642746437464474645746467464774648746497465074651746527465374654746557465674657746587465974660746617466274663746647466574666746677466874669746707467174672746737467474675746767467774678746797468074681746827468374684746857468674687746887468974690746917469274693746947469574696746977469874699747007470174702747037470474705747067470774708747097471074711747127471374714747157471674717747187471974720747217472274723747247472574726747277472874729747307473174732747337473474735747367473774738747397474074741747427474374744747457474674747747487474974750747517475274753747547475574756747577475874759747607476174762747637476474765747667476774768747697477074771747727477374774747757477674777747787477974780747817478274783747847478574786747877478874789747907479174792747937479474795747967479774798747997480074801748027480374804748057480674807748087480974810748117481274813748147481574816748177481874819748207482174822748237482474825748267482774828748297483074831748327483374834748357483674837748387483974840748417484274843748447484574846748477484874849748507485174852748537485474855748567485774858748597486074861748627486374864748657486674867748687486974870748717487274873748747487574876748777487874879748807488174882748837488474885748867488774888748897489074891748927489374894748957489674897748987489974900749017490274903749047490574906749077490874909749107491174912749137491474915749167491774918749197492074921749227492374924749257492674927749287492974930749317493274933749347493574936749377493874939749407494174942749437494474945749467494774948749497495074951749527495374954749557495674957749587495974960749617496274963749647496574966749677496874969749707497174972749737497474975749767497774978749797498074981749827498374984749857498674987749887498974990749917499274993749947499574996749977499874999750007500175002750037500475005750067500775008750097501075011750127501375014750157501675017750187501975020750217502275023750247502575026750277502875029750307503175032750337503475035750367503775038750397504075041750427504375044750457504675047750487504975050750517505275053750547505575056750577505875059750607506175062750637506475065750667506775068750697507075071750727507375074750757507675077750787507975080750817508275083750847508575086750877508875089750907509175092750937509475095750967509775098750997510075101751027510375104751057510675107751087510975110751117511275113751147511575116751177511875119751207512175122751237512475125751267512775128751297513075131751327513375134751357513675137751387513975140751417514275143751447514575146751477514875149751507515175152751537515475155751567515775158751597516075161751627516375164751657516675167751687516975170751717517275173751747517575176751777517875179751807518175182751837518475185751867518775188751897519075191751927519375194751957519675197751987519975200752017520275203752047520575206752077520875209752107521175212752137521475215752167521775218752197522075221752227522375224752257522675227752287522975230752317523275233752347523575236752377523875239752407524175242752437524475245752467524775248752497525075251752527525375254752557525675257752587525975260752617526275263752647526575266752677526875269752707527175272752737527475275752767527775278752797528075281752827528375284752857528675287752887528975290752917529275293752947529575296752977529875299753007530175302753037530475305753067530775308753097531075311753127531375314753157531675317753187531975320753217532275323753247532575326753277532875329753307533175332753337533475335753367533775338753397534075341753427534375344753457534675347753487534975350753517535275353753547535575356753577535875359753607536175362753637536475365753667536775368753697537075371753727537375374753757537675377753787537975380753817538275383753847538575386753877538875389753907539175392753937539475395753967539775398753997540075401754027540375404754057540675407754087540975410754117541275413754147541575416754177541875419754207542175422754237542475425754267542775428754297543075431754327543375434754357543675437754387543975440754417544275443754447544575446754477544875449754507545175452754537545475455754567545775458754597546075461754627546375464754657546675467754687546975470754717547275473754747547575476754777547875479754807548175482754837548475485754867548775488754897549075491754927549375494754957549675497754987549975500755017550275503755047550575506755077550875509755107551175512755137551475515755167551775518755197552075521755227552375524755257552675527755287552975530755317553275533755347553575536755377553875539755407554175542755437554475545755467554775548755497555075551755527555375554755557555675557755587555975560755617556275563755647556575566755677556875569755707557175572755737557475575755767557775578755797558075581755827558375584755857558675587755887558975590755917559275593755947559575596755977559875599756007560175602756037560475605756067560775608756097561075611756127561375614756157561675617756187561975620756217562275623756247562575626756277562875629756307563175632756337563475635756367563775638756397564075641756427564375644756457564675647756487564975650756517565275653756547565575656756577565875659756607566175662756637566475665756667566775668756697567075671756727567375674756757567675677756787567975680756817568275683756847568575686756877568875689756907569175692756937569475695756967569775698756997570075701757027570375704757057570675707757087570975710757117571275713757147571575716757177571875719757207572175722757237572475725757267572775728757297573075731757327573375734757357573675737757387573975740757417574275743757447574575746757477574875749757507575175752757537575475755757567575775758757597576075761757627576375764757657576675767757687576975770757717577275773757747577575776757777577875779757807578175782757837578475785757867578775788757897579075791757927579375794757957579675797757987579975800758017580275803758047580575806758077580875809758107581175812758137581475815758167581775818758197582075821758227582375824758257582675827758287582975830758317583275833758347583575836758377583875839758407584175842758437584475845758467584775848758497585075851758527585375854758557585675857758587585975860758617586275863758647586575866758677586875869758707587175872758737587475875758767587775878758797588075881758827588375884758857588675887758887588975890758917589275893758947589575896758977589875899759007590175902759037590475905759067590775908759097591075911759127591375914759157591675917759187591975920759217592275923759247592575926759277592875929759307593175932759337593475935759367593775938759397594075941759427594375944759457594675947759487594975950759517595275953759547595575956759577595875959759607596175962759637596475965759667596775968759697597075971759727597375974759757597675977759787597975980759817598275983759847598575986759877598875989759907599175992759937599475995759967599775998759997600076001760027600376004760057600676007760087600976010760117601276013760147601576016760177601876019760207602176022760237602476025760267602776028760297603076031760327603376034760357603676037760387603976040760417604276043760447604576046760477604876049760507605176052760537605476055760567605776058760597606076061760627606376064760657606676067760687606976070760717607276073760747607576076760777607876079760807608176082760837608476085760867608776088760897609076091760927609376094760957609676097760987609976100761017610276103761047610576106761077610876109761107611176112761137611476115761167611776118761197612076121761227612376124761257612676127761287612976130761317613276133761347613576136761377613876139761407614176142761437614476145761467614776148761497615076151761527615376154761557615676157761587615976160761617616276163761647616576166761677616876169761707617176172761737617476175761767617776178761797618076181761827618376184761857618676187761887618976190761917619276193761947619576196761977619876199762007620176202762037620476205762067620776208762097621076211762127621376214762157621676217762187621976220762217622276223762247622576226762277622876229762307623176232762337623476235762367623776238762397624076241762427624376244762457624676247762487624976250762517625276253762547625576256762577625876259762607626176262762637626476265762667626776268762697627076271762727627376274762757627676277762787627976280762817628276283762847628576286762877628876289762907629176292762937629476295762967629776298762997630076301763027630376304763057630676307763087630976310763117631276313763147631576316763177631876319763207632176322763237632476325763267632776328763297633076331763327633376334763357633676337763387633976340763417634276343763447634576346763477634876349763507635176352763537635476355763567635776358763597636076361763627636376364763657636676367763687636976370763717637276373763747637576376763777637876379763807638176382763837638476385763867638776388763897639076391763927639376394763957639676397763987639976400764017640276403764047640576406764077640876409764107641176412764137641476415764167641776418764197642076421764227642376424764257642676427764287642976430764317643276433764347643576436764377643876439764407644176442764437644476445764467644776448764497645076451764527645376454764557645676457764587645976460764617646276463764647646576466764677646876469764707647176472764737647476475764767647776478764797648076481764827648376484764857648676487764887648976490764917649276493764947649576496764977649876499765007650176502765037650476505765067650776508765097651076511765127651376514765157651676517765187651976520765217652276523765247652576526765277652876529765307653176532765337653476535765367653776538765397654076541765427654376544765457654676547765487654976550765517655276553765547655576556765577655876559765607656176562765637656476565765667656776568765697657076571765727657376574765757657676577765787657976580765817658276583765847658576586765877658876589765907659176592765937659476595765967659776598765997660076601766027660376604766057660676607766087660976610766117661276613766147661576616766177661876619766207662176622766237662476625766267662776628766297663076631766327663376634766357663676637766387663976640766417664276643766447664576646766477664876649766507665176652766537665476655766567665776658766597666076661766627666376664766657666676667766687666976670766717667276673766747667576676766777667876679766807668176682766837668476685766867668776688766897669076691766927669376694766957669676697766987669976700767017670276703767047670576706767077670876709767107671176712767137671476715767167671776718767197672076721767227672376724767257672676727767287672976730767317673276733767347673576736767377673876739767407674176742767437674476745767467674776748767497675076751767527675376754767557675676757767587675976760767617676276763767647676576766767677676876769767707677176772767737677476775767767677776778767797678076781767827678376784767857678676787767887678976790767917679276793767947679576796767977679876799768007680176802768037680476805768067680776808768097681076811768127681376814768157681676817768187681976820768217682276823768247682576826768277682876829768307683176832768337683476835768367683776838768397684076841768427684376844768457684676847768487684976850768517685276853768547685576856768577685876859768607686176862768637686476865768667686776868768697687076871768727687376874768757687676877768787687976880768817688276883768847688576886768877688876889768907689176892768937689476895768967689776898768997690076901769027690376904769057690676907769087690976910769117691276913769147691576916769177691876919769207692176922769237692476925769267692776928769297693076931769327693376934769357693676937769387693976940769417694276943769447694576946769477694876949769507695176952769537695476955769567695776958769597696076961769627696376964769657696676967769687696976970769717697276973769747697576976769777697876979769807698176982769837698476985769867698776988769897699076991769927699376994769957699676997769987699977000770017700277003770047700577006770077700877009770107701177012770137701477015770167701777018770197702077021770227702377024770257702677027770287702977030770317703277033770347703577036770377703877039770407704177042770437704477045770467704777048770497705077051770527705377054770557705677057770587705977060770617706277063770647706577066770677706877069770707707177072770737707477075770767707777078770797708077081770827708377084770857708677087770887708977090770917709277093770947709577096770977709877099771007710177102771037710477105771067710777108771097711077111771127711377114771157711677117771187711977120771217712277123771247712577126771277712877129771307713177132771337713477135771367713777138771397714077141771427714377144771457714677147771487714977150771517715277153771547715577156771577715877159771607716177162771637716477165771667716777168771697717077171771727717377174771757717677177771787717977180771817718277183771847718577186771877718877189771907719177192771937719477195771967719777198771997720077201772027720377204772057720677207772087720977210772117721277213772147721577216772177721877219772207722177222772237722477225772267722777228772297723077231772327723377234772357723677237772387723977240772417724277243772447724577246772477724877249772507725177252772537725477255772567725777258772597726077261772627726377264772657726677267772687726977270772717727277273772747727577276772777727877279772807728177282772837728477285772867728777288772897729077291772927729377294772957729677297772987729977300773017730277303773047730577306773077730877309773107731177312773137731477315773167731777318773197732077321773227732377324773257732677327773287732977330773317733277333773347733577336773377733877339773407734177342773437734477345773467734777348773497735077351773527735377354773557735677357773587735977360773617736277363773647736577366773677736877369773707737177372773737737477375773767737777378773797738077381773827738377384773857738677387773887738977390773917739277393773947739577396773977739877399774007740177402774037740477405774067740777408774097741077411774127741377414774157741677417774187741977420774217742277423774247742577426774277742877429774307743177432774337743477435774367743777438774397744077441774427744377444774457744677447774487744977450774517745277453774547745577456774577745877459774607746177462774637746477465774667746777468774697747077471774727747377474774757747677477774787747977480774817748277483774847748577486774877748877489774907749177492774937749477495774967749777498774997750077501775027750377504775057750677507775087750977510775117751277513775147751577516775177751877519775207752177522775237752477525775267752777528775297753077531775327753377534775357753677537775387753977540775417754277543775447754577546775477754877549775507755177552775537755477555775567755777558775597756077561775627756377564775657756677567775687756977570775717757277573775747757577576775777757877579775807758177582775837758477585775867758777588775897759077591775927759377594775957759677597775987759977600776017760277603776047760577606776077760877609776107761177612776137761477615776167761777618776197762077621776227762377624776257762677627776287762977630776317763277633776347763577636776377763877639776407764177642776437764477645776467764777648776497765077651776527765377654776557765677657776587765977660776617766277663776647766577666776677766877669776707767177672776737767477675776767767777678776797768077681776827768377684776857768677687776887768977690776917769277693776947769577696776977769877699777007770177702777037770477705777067770777708777097771077711777127771377714777157771677717777187771977720777217772277723777247772577726777277772877729777307773177732777337773477735777367773777738777397774077741777427774377744777457774677747777487774977750777517775277753777547775577756777577775877759777607776177762777637776477765777667776777768777697777077771777727777377774777757777677777777787777977780777817778277783777847778577786777877778877789777907779177792777937779477795777967779777798777997780077801778027780377804778057780677807778087780977810778117781277813778147781577816778177781877819778207782177822778237782477825778267782777828778297783077831778327783377834778357783677837778387783977840778417784277843778447784577846778477784877849778507785177852778537785477855778567785777858778597786077861778627786377864778657786677867778687786977870778717787277873778747787577876778777787877879778807788177882778837788477885778867788777888778897789077891778927789377894778957789677897778987789977900779017790277903779047790577906779077790877909779107791177912779137791477915779167791777918779197792077921779227792377924779257792677927779287792977930779317793277933779347793577936779377793877939779407794177942779437794477945779467794777948779497795077951779527795377954779557795677957779587795977960779617796277963779647796577966779677796877969779707797177972779737797477975779767797777978779797798077981779827798377984779857798677987779887798977990779917799277993779947799577996779977799877999780007800178002780037800478005780067800778008780097801078011780127801378014780157801678017780187801978020780217802278023780247802578026780277802878029780307803178032780337803478035780367803778038780397804078041780427804378044780457804678047780487804978050780517805278053780547805578056780577805878059780607806178062780637806478065780667806778068780697807078071780727807378074780757807678077780787807978080780817808278083780847808578086780877808878089780907809178092780937809478095780967809778098780997810078101781027810378104781057810678107781087810978110781117811278113781147811578116781177811878119781207812178122781237812478125781267812778128781297813078131781327813378134781357813678137781387813978140781417814278143781447814578146781477814878149781507815178152781537815478155781567815778158781597816078161781627816378164781657816678167781687816978170781717817278173781747817578176781777817878179781807818178182781837818478185781867818778188781897819078191781927819378194781957819678197781987819978200782017820278203782047820578206782077820878209782107821178212782137821478215782167821778218782197822078221782227822378224782257822678227782287822978230782317823278233782347823578236782377823878239782407824178242782437824478245782467824778248782497825078251782527825378254782557825678257782587825978260782617826278263782647826578266782677826878269782707827178272782737827478275782767827778278782797828078281782827828378284782857828678287782887828978290782917829278293782947829578296782977829878299783007830178302783037830478305783067830778308783097831078311783127831378314783157831678317783187831978320783217832278323783247832578326783277832878329783307833178332783337833478335783367833778338783397834078341783427834378344783457834678347783487834978350783517835278353783547835578356783577835878359783607836178362783637836478365783667836778368783697837078371783727837378374783757837678377783787837978380783817838278383783847838578386783877838878389783907839178392783937839478395783967839778398783997840078401784027840378404784057840678407784087840978410784117841278413784147841578416784177841878419784207842178422784237842478425784267842778428784297843078431784327843378434784357843678437784387843978440784417844278443784447844578446784477844878449784507845178452784537845478455784567845778458784597846078461784627846378464784657846678467784687846978470784717847278473784747847578476784777847878479784807848178482784837848478485784867848778488784897849078491784927849378494784957849678497784987849978500785017850278503785047850578506785077850878509785107851178512785137851478515785167851778518785197852078521785227852378524785257852678527785287852978530785317853278533785347853578536785377853878539785407854178542785437854478545785467854778548785497855078551785527855378554785557855678557785587855978560785617856278563785647856578566785677856878569785707857178572785737857478575785767857778578785797858078581785827858378584785857858678587785887858978590785917859278593785947859578596785977859878599786007860178602786037860478605786067860778608786097861078611786127861378614786157861678617786187861978620786217862278623786247862578626786277862878629786307863178632786337863478635786367863778638786397864078641786427864378644786457864678647786487864978650786517865278653786547865578656786577865878659786607866178662786637866478665786667866778668786697867078671786727867378674786757867678677786787867978680786817868278683786847868578686786877868878689786907869178692786937869478695786967869778698786997870078701787027870378704787057870678707787087870978710787117871278713787147871578716787177871878719787207872178722787237872478725787267872778728787297873078731787327873378734787357873678737787387873978740787417874278743787447874578746787477874878749787507875178752787537875478755787567875778758787597876078761787627876378764787657876678767787687876978770787717877278773787747877578776787777877878779787807878178782787837878478785787867878778788787897879078791787927879378794787957879678797787987879978800788017880278803788047880578806788077880878809788107881178812788137881478815788167881778818788197882078821788227882378824788257882678827788287882978830788317883278833788347883578836788377883878839788407884178842788437884478845788467884778848788497885078851788527885378854788557885678857788587885978860788617886278863788647886578866788677886878869788707887178872788737887478875788767887778878788797888078881788827888378884788857888678887788887888978890788917889278893788947889578896788977889878899789007890178902789037890478905789067890778908789097891078911789127891378914789157891678917789187891978920789217892278923789247892578926789277892878929789307893178932789337893478935789367893778938789397894078941789427894378944789457894678947789487894978950789517895278953789547895578956789577895878959789607896178962789637896478965789667896778968789697897078971789727897378974789757897678977789787897978980789817898278983789847898578986789877898878989789907899178992789937899478995789967899778998789997900079001790027900379004790057900679007790087900979010790117901279013790147901579016790177901879019790207902179022790237902479025790267902779028790297903079031790327903379034790357903679037790387903979040790417904279043790447904579046790477904879049790507905179052790537905479055790567905779058790597906079061790627906379064790657906679067790687906979070790717907279073790747907579076790777907879079790807908179082790837908479085790867908779088790897909079091790927909379094790957909679097790987909979100791017910279103791047910579106791077910879109791107911179112791137911479115791167911779118791197912079121791227912379124791257912679127791287912979130791317913279133791347913579136791377913879139791407914179142791437914479145791467914779148791497915079151791527915379154791557915679157791587915979160791617916279163791647916579166791677916879169791707917179172791737917479175791767917779178791797918079181791827918379184791857918679187791887918979190791917919279193791947919579196791977919879199792007920179202792037920479205792067920779208792097921079211792127921379214792157921679217792187921979220792217922279223792247922579226792277922879229792307923179232792337923479235792367923779238792397924079241792427924379244792457924679247792487924979250792517925279253792547925579256792577925879259792607926179262792637926479265792667926779268792697927079271792727927379274792757927679277792787927979280792817928279283792847928579286792877928879289792907929179292792937929479295792967929779298792997930079301793027930379304793057930679307793087930979310793117931279313793147931579316793177931879319793207932179322793237932479325793267932779328793297933079331793327933379334793357933679337793387933979340793417934279343793447934579346793477934879349793507935179352793537935479355793567935779358793597936079361793627936379364793657936679367793687936979370793717937279373793747937579376793777937879379793807938179382793837938479385793867938779388793897939079391793927939379394793957939679397793987939979400794017940279403794047940579406794077940879409794107941179412794137941479415794167941779418794197942079421794227942379424794257942679427794287942979430794317943279433794347943579436794377943879439794407944179442794437944479445794467944779448794497945079451794527945379454794557945679457794587945979460794617946279463794647946579466794677946879469794707947179472794737947479475794767947779478794797948079481794827948379484794857948679487794887948979490794917949279493794947949579496794977949879499795007950179502795037950479505795067950779508795097951079511795127951379514795157951679517795187951979520795217952279523795247952579526795277952879529795307953179532795337953479535795367953779538795397954079541795427954379544795457954679547795487954979550795517955279553795547955579556795577955879559795607956179562795637956479565795667956779568795697957079571795727957379574795757957679577795787957979580795817958279583795847958579586795877958879589795907959179592795937959479595795967959779598795997960079601796027960379604796057960679607796087960979610796117961279613796147961579616796177961879619796207962179622796237962479625796267962779628796297963079631796327963379634796357963679637796387963979640796417964279643796447964579646796477964879649796507965179652796537965479655796567965779658796597966079661796627966379664796657966679667796687966979670796717967279673796747967579676796777967879679796807968179682796837968479685796867968779688796897969079691796927969379694796957969679697796987969979700797017970279703797047970579706797077970879709797107971179712797137971479715797167971779718797197972079721797227972379724797257972679727797287972979730797317973279733797347973579736797377973879739797407974179742797437974479745797467974779748797497975079751797527975379754797557975679757797587975979760797617976279763797647976579766797677976879769797707977179772797737977479775797767977779778797797978079781797827978379784797857978679787797887978979790797917979279793797947979579796797977979879799798007980179802798037980479805798067980779808798097981079811798127981379814798157981679817798187981979820798217982279823798247982579826798277982879829798307983179832798337983479835798367983779838798397984079841798427984379844798457984679847798487984979850798517985279853798547985579856798577985879859798607986179862798637986479865798667986779868798697987079871798727987379874798757987679877798787987979880798817988279883798847988579886798877988879889798907989179892798937989479895798967989779898798997990079901799027990379904799057990679907799087990979910799117991279913799147991579916799177991879919799207992179922799237992479925799267992779928799297993079931799327993379934799357993679937799387993979940799417994279943799447994579946799477994879949799507995179952799537995479955799567995779958799597996079961799627996379964799657996679967799687996979970799717997279973799747997579976799777997879979799807998179982799837998479985799867998779988799897999079991799927999379994799957999679997799987999980000800018000280003800048000580006800078000880009800108001180012800138001480015800168001780018800198002080021800228002380024800258002680027800288002980030800318003280033800348003580036800378003880039800408004180042800438004480045800468004780048800498005080051800528005380054800558005680057800588005980060800618006280063800648006580066800678006880069800708007180072800738007480075800768007780078800798008080081800828008380084800858008680087800888008980090800918009280093800948009580096800978009880099801008010180102801038010480105801068010780108801098011080111801128011380114801158011680117801188011980120801218012280123801248012580126801278012880129801308013180132801338013480135801368013780138801398014080141801428014380144801458014680147801488014980150801518015280153801548015580156801578015880159801608016180162801638016480165801668016780168801698017080171801728017380174801758017680177801788017980180801818018280183801848018580186801878018880189801908019180192801938019480195801968019780198801998020080201802028020380204802058020680207802088020980210802118021280213802148021580216802178021880219802208022180222802238022480225802268022780228802298023080231802328023380234802358023680237802388023980240802418024280243802448024580246802478024880249802508025180252802538025480255802568025780258802598026080261802628026380264802658026680267802688026980270802718027280273802748027580276802778027880279802808028180282802838028480285802868028780288802898029080291802928029380294802958029680297802988029980300803018030280303803048030580306803078030880309803108031180312803138031480315803168031780318803198032080321803228032380324803258032680327803288032980330803318033280333803348033580336803378033880339803408034180342803438034480345803468034780348803498035080351803528035380354803558035680357803588035980360803618036280363803648036580366803678036880369803708037180372803738037480375803768037780378803798038080381803828038380384803858038680387803888038980390803918039280393803948039580396803978039880399804008040180402804038040480405804068040780408804098041080411804128041380414804158041680417804188041980420804218042280423804248042580426804278042880429804308043180432804338043480435804368043780438804398044080441804428044380444804458044680447804488044980450804518045280453804548045580456804578045880459804608046180462804638046480465804668046780468804698047080471804728047380474804758047680477804788047980480804818048280483804848048580486804878048880489804908049180492804938049480495804968049780498804998050080501805028050380504805058050680507805088050980510805118051280513805148051580516805178051880519805208052180522805238052480525805268052780528805298053080531805328053380534805358053680537805388053980540805418054280543805448054580546805478054880549805508055180552805538055480555805568055780558805598056080561805628056380564805658056680567805688056980570805718057280573805748057580576805778057880579805808058180582805838058480585805868058780588805898059080591805928059380594805958059680597805988059980600806018060280603806048060580606806078060880609806108061180612806138061480615806168061780618806198062080621806228062380624806258062680627806288062980630806318063280633806348063580636806378063880639806408064180642806438064480645806468064780648806498065080651806528065380654806558065680657806588065980660806618066280663806648066580666806678066880669806708067180672806738067480675806768067780678806798068080681806828068380684806858068680687806888068980690806918069280693806948069580696806978069880699807008070180702807038070480705807068070780708807098071080711807128071380714807158071680717807188071980720807218072280723807248072580726807278072880729807308073180732807338073480735807368073780738807398074080741807428074380744807458074680747807488074980750807518075280753807548075580756807578075880759807608076180762807638076480765807668076780768807698077080771807728077380774807758077680777807788077980780807818078280783807848078580786807878078880789807908079180792807938079480795807968079780798807998080080801808028080380804808058080680807808088080980810808118081280813808148081580816808178081880819808208082180822808238082480825808268082780828808298083080831808328083380834808358083680837808388083980840808418084280843808448084580846808478084880849808508085180852808538085480855808568085780858808598086080861808628086380864808658086680867808688086980870808718087280873808748087580876808778087880879808808088180882808838088480885808868088780888808898089080891808928089380894808958089680897808988089980900809018090280903809048090580906809078090880909809108091180912809138091480915809168091780918809198092080921809228092380924809258092680927809288092980930809318093280933809348093580936809378093880939809408094180942809438094480945809468094780948809498095080951809528095380954809558095680957809588095980960809618096280963809648096580966809678096880969809708097180972809738097480975809768097780978809798098080981809828098380984809858098680987809888098980990809918099280993809948099580996809978099880999810008100181002810038100481005810068100781008810098101081011810128101381014810158101681017810188101981020810218102281023810248102581026810278102881029810308103181032810338103481035810368103781038810398104081041810428104381044810458104681047810488104981050810518105281053810548105581056810578105881059810608106181062810638106481065810668106781068810698107081071810728107381074810758107681077810788107981080810818108281083810848108581086810878108881089810908109181092810938109481095810968109781098810998110081101811028110381104811058110681107811088110981110811118111281113811148111581116811178111881119811208112181122811238112481125811268112781128811298113081131811328113381134811358113681137811388113981140811418114281143811448114581146811478114881149811508115181152811538115481155811568115781158811598116081161811628116381164811658116681167811688116981170811718117281173811748117581176811778117881179811808118181182811838118481185811868118781188811898119081191811928119381194811958119681197811988119981200812018120281203812048120581206812078120881209812108121181212812138121481215812168121781218812198122081221812228122381224812258122681227812288122981230812318123281233812348123581236812378123881239812408124181242812438124481245812468124781248812498125081251812528125381254812558125681257812588125981260812618126281263812648126581266812678126881269812708127181272812738127481275812768127781278812798128081281812828128381284812858128681287812888128981290812918129281293812948129581296812978129881299813008130181302813038130481305813068130781308813098131081311813128131381314813158131681317813188131981320813218132281323813248132581326813278132881329813308133181332813338133481335813368133781338813398134081341813428134381344813458134681347813488134981350813518135281353813548135581356813578135881359813608136181362813638136481365813668136781368813698137081371813728137381374813758137681377813788137981380813818138281383813848138581386813878138881389813908139181392813938139481395813968139781398813998140081401814028140381404814058140681407814088140981410814118141281413814148141581416814178141881419814208142181422814238142481425814268142781428814298143081431814328143381434814358143681437814388143981440814418144281443814448144581446814478144881449814508145181452814538145481455814568145781458814598146081461814628146381464814658146681467814688146981470814718147281473814748147581476814778147881479814808148181482814838148481485814868148781488814898149081491814928149381494814958149681497814988149981500815018150281503815048150581506815078150881509815108151181512815138151481515815168151781518815198152081521815228152381524815258152681527815288152981530815318153281533815348153581536815378153881539815408154181542815438154481545815468154781548815498155081551815528155381554815558155681557815588155981560815618156281563815648156581566815678156881569815708157181572815738157481575815768157781578815798158081581815828158381584815858158681587815888158981590815918159281593815948159581596815978159881599816008160181602816038160481605816068160781608816098161081611816128161381614816158161681617816188161981620816218162281623816248162581626816278162881629816308163181632816338163481635816368163781638816398164081641816428164381644816458164681647816488164981650816518165281653816548165581656816578165881659816608166181662816638166481665816668166781668816698167081671816728167381674816758167681677816788167981680816818168281683816848168581686816878168881689816908169181692816938169481695816968169781698816998170081701817028170381704817058170681707817088170981710817118171281713817148171581716817178171881719817208172181722817238172481725817268172781728817298173081731817328173381734817358173681737817388173981740817418174281743817448174581746817478174881749817508175181752817538175481755817568175781758817598176081761817628176381764817658176681767817688176981770817718177281773817748177581776817778177881779817808178181782817838178481785817868178781788817898179081791817928179381794817958179681797817988179981800818018180281803818048180581806818078180881809818108181181812818138181481815818168181781818818198182081821818228182381824818258182681827818288182981830818318183281833818348183581836818378183881839818408184181842818438184481845818468184781848818498185081851818528185381854818558185681857818588185981860818618186281863818648186581866818678186881869818708187181872818738187481875818768187781878818798188081881818828188381884818858188681887818888188981890818918189281893818948189581896818978189881899819008190181902819038190481905819068190781908819098191081911819128191381914819158191681917819188191981920819218192281923819248192581926819278192881929819308193181932819338193481935819368193781938819398194081941819428194381944819458194681947819488194981950819518195281953819548195581956819578195881959819608196181962819638196481965819668196781968819698197081971819728197381974819758197681977819788197981980819818198281983819848198581986819878198881989819908199181992819938199481995819968199781998819998200082001820028200382004820058200682007820088200982010820118201282013820148201582016820178201882019820208202182022820238202482025820268202782028820298203082031820328203382034820358203682037820388203982040820418204282043820448204582046820478204882049820508205182052820538205482055820568205782058820598206082061820628206382064820658206682067820688206982070820718207282073820748207582076820778207882079820808208182082820838208482085820868208782088820898209082091820928209382094820958209682097820988209982100821018210282103821048210582106821078210882109821108211182112821138211482115821168211782118821198212082121821228212382124821258212682127821288212982130821318213282133821348213582136821378213882139821408214182142821438214482145821468214782148821498215082151821528215382154821558215682157821588215982160821618216282163821648216582166821678216882169821708217182172821738217482175821768217782178821798218082181821828218382184821858218682187821888218982190821918219282193821948219582196821978219882199822008220182202822038220482205822068220782208822098221082211822128221382214822158221682217822188221982220822218222282223822248222582226822278222882229822308223182232822338223482235822368223782238822398224082241822428224382244822458224682247822488224982250822518225282253822548225582256822578225882259822608226182262822638226482265822668226782268822698227082271822728227382274822758227682277822788227982280822818228282283822848228582286822878228882289822908229182292822938229482295822968229782298822998230082301823028230382304823058230682307823088230982310823118231282313823148231582316823178231882319823208232182322823238232482325823268232782328823298233082331823328233382334823358233682337823388233982340823418234282343823448234582346823478234882349823508235182352823538235482355823568235782358823598236082361823628236382364823658236682367823688236982370823718237282373823748237582376823778237882379823808238182382823838238482385823868238782388823898239082391823928239382394823958239682397823988239982400824018240282403824048240582406824078240882409824108241182412824138241482415824168241782418824198242082421824228242382424824258242682427824288242982430824318243282433824348243582436824378243882439824408244182442824438244482445824468244782448824498245082451824528245382454824558245682457824588245982460824618246282463824648246582466824678246882469824708247182472824738247482475824768247782478824798248082481824828248382484824858248682487824888248982490824918249282493824948249582496824978249882499825008250182502825038250482505825068250782508825098251082511825128251382514825158251682517825188251982520825218252282523825248252582526825278252882529825308253182532825338253482535825368253782538825398254082541825428254382544825458254682547825488254982550825518255282553825548255582556825578255882559825608256182562825638256482565825668256782568825698257082571825728257382574825758257682577825788257982580825818258282583825848258582586825878258882589825908259182592825938259482595825968259782598825998260082601826028260382604826058260682607826088260982610826118261282613826148261582616826178261882619826208262182622826238262482625826268262782628826298263082631826328263382634826358263682637826388263982640826418264282643826448264582646826478264882649826508265182652826538265482655826568265782658826598266082661826628266382664826658266682667826688266982670826718267282673826748267582676826778267882679826808268182682826838268482685826868268782688826898269082691826928269382694826958269682697826988269982700827018270282703827048270582706827078270882709827108271182712827138271482715827168271782718827198272082721827228272382724827258272682727827288272982730827318273282733827348273582736827378273882739827408274182742827438274482745827468274782748827498275082751827528275382754827558275682757827588275982760827618276282763827648276582766827678276882769827708277182772827738277482775827768277782778827798278082781827828278382784827858278682787827888278982790827918279282793827948279582796827978279882799828008280182802828038280482805828068280782808828098281082811828128281382814828158281682817828188281982820828218282282823828248282582826828278282882829828308283182832828338283482835828368283782838828398284082841828428284382844828458284682847828488284982850828518285282853828548285582856828578285882859828608286182862828638286482865828668286782868828698287082871828728287382874828758287682877828788287982880828818288282883828848288582886828878288882889828908289182892828938289482895828968289782898828998290082901829028290382904829058290682907829088290982910829118291282913829148291582916829178291882919829208292182922829238292482925829268292782928829298293082931829328293382934829358293682937829388293982940829418294282943829448294582946829478294882949829508295182952829538295482955829568295782958829598296082961829628296382964829658296682967829688296982970829718297282973829748297582976829778297882979829808298182982829838298482985829868298782988829898299082991829928299382994829958299682997829988299983000830018300283003830048300583006830078300883009830108301183012830138301483015830168301783018830198302083021830228302383024830258302683027830288302983030830318303283033830348303583036830378303883039830408304183042830438304483045830468304783048830498305083051830528305383054830558305683057830588305983060830618306283063830648306583066830678306883069830708307183072830738307483075830768307783078830798308083081830828308383084830858308683087830888308983090830918309283093830948309583096830978309883099831008310183102831038310483105831068310783108831098311083111831128311383114831158311683117831188311983120831218312283123831248312583126831278312883129831308313183132831338313483135831368313783138831398314083141831428314383144831458314683147831488314983150831518315283153831548315583156831578315883159831608316183162831638316483165831668316783168831698317083171831728317383174831758317683177831788317983180831818318283183831848318583186831878318883189831908319183192831938319483195831968319783198831998320083201832028320383204832058320683207832088320983210832118321283213832148321583216832178321883219832208322183222832238322483225832268322783228832298323083231832328323383234832358323683237832388323983240832418324283243832448324583246832478324883249832508325183252832538325483255832568325783258832598326083261832628326383264832658326683267832688326983270832718327283273832748327583276832778327883279832808328183282832838328483285832868328783288832898329083291832928329383294832958329683297832988329983300833018330283303833048330583306833078330883309833108331183312833138331483315833168331783318833198332083321833228332383324833258332683327833288332983330833318333283333833348333583336833378333883339833408334183342833438334483345833468334783348833498335083351833528335383354833558335683357833588335983360833618336283363833648336583366833678336883369833708337183372833738337483375833768337783378833798338083381833828338383384833858338683387833888338983390833918339283393833948339583396833978339883399834008340183402834038340483405834068340783408834098341083411834128341383414834158341683417834188341983420834218342283423834248342583426834278342883429834308343183432834338343483435834368343783438834398344083441834428344383444834458344683447834488344983450834518345283453834548345583456834578345883459834608346183462834638346483465834668346783468834698347083471834728347383474834758347683477834788347983480834818348283483834848348583486834878348883489834908349183492834938349483495834968349783498834998350083501835028350383504835058350683507835088350983510835118351283513835148351583516835178351883519835208352183522835238352483525835268352783528835298353083531835328353383534835358353683537835388353983540835418354283543835448354583546835478354883549835508355183552835538355483555835568355783558835598356083561835628356383564835658356683567835688356983570835718357283573835748357583576835778357883579835808358183582835838358483585835868358783588835898359083591835928359383594835958359683597835988359983600836018360283603836048360583606836078360883609836108361183612836138361483615836168361783618836198362083621836228362383624836258362683627836288362983630836318363283633836348363583636836378363883639836408364183642836438364483645836468364783648836498365083651836528365383654836558365683657836588365983660836618366283663836648366583666836678366883669836708367183672836738367483675836768367783678836798368083681836828368383684836858368683687836888368983690836918369283693836948369583696836978369883699837008370183702837038370483705837068370783708837098371083711837128371383714837158371683717837188371983720837218372283723837248372583726837278372883729837308373183732837338373483735837368373783738837398374083741837428374383744837458374683747837488374983750837518375283753837548375583756837578375883759837608376183762837638376483765837668376783768837698377083771837728377383774837758377683777837788377983780837818378283783837848378583786837878378883789837908379183792837938379483795837968379783798837998380083801838028380383804838058380683807838088380983810838118381283813838148381583816838178381883819838208382183822838238382483825838268382783828838298383083831838328383383834838358383683837838388383983840838418384283843838448384583846838478384883849838508385183852838538385483855838568385783858838598386083861838628386383864838658386683867838688386983870838718387283873838748387583876838778387883879838808388183882838838388483885838868388783888838898389083891838928389383894838958389683897838988389983900839018390283903839048390583906839078390883909839108391183912839138391483915839168391783918839198392083921839228392383924839258392683927839288392983930839318393283933839348393583936839378393883939839408394183942839438394483945839468394783948839498395083951839528395383954839558395683957839588395983960839618396283963839648396583966839678396883969839708397183972839738397483975839768397783978839798398083981839828398383984839858398683987839888398983990839918399283993839948399583996839978399883999840008400184002840038400484005840068400784008840098401084011840128401384014840158401684017840188401984020840218402284023840248402584026840278402884029840308403184032840338403484035840368403784038840398404084041840428404384044840458404684047840488404984050840518405284053840548405584056840578405884059840608406184062840638406484065840668406784068840698407084071840728407384074840758407684077840788407984080840818408284083840848408584086840878408884089840908409184092840938409484095840968409784098840998410084101841028410384104841058410684107841088410984110841118411284113841148411584116841178411884119841208412184122841238412484125841268412784128841298413084131841328413384134841358413684137841388413984140841418414284143841448414584146841478414884149841508415184152841538415484155841568415784158841598416084161841628416384164841658416684167841688416984170841718417284173841748417584176841778417884179841808418184182841838418484185841868418784188841898419084191841928419384194841958419684197841988419984200842018420284203842048420584206842078420884209842108421184212842138421484215842168421784218842198422084221842228422384224842258422684227842288422984230842318423284233842348423584236842378423884239842408424184242842438424484245842468424784248842498425084251842528425384254842558425684257842588425984260842618426284263842648426584266842678426884269842708427184272842738427484275842768427784278842798428084281842828428384284842858428684287842888428984290842918429284293842948429584296842978429884299843008430184302843038430484305843068430784308843098431084311843128431384314843158431684317843188431984320843218432284323843248432584326843278432884329843308433184332843338433484335843368433784338843398434084341843428434384344843458434684347843488434984350843518435284353843548435584356843578435884359843608436184362843638436484365843668436784368843698437084371843728437384374843758437684377843788437984380843818438284383843848438584386843878438884389843908439184392843938439484395843968439784398843998440084401844028440384404844058440684407844088440984410844118441284413844148441584416844178441884419844208442184422844238442484425844268442784428844298443084431844328443384434844358443684437844388443984440844418444284443844448444584446844478444884449844508445184452844538445484455844568445784458844598446084461844628446384464844658446684467844688446984470844718447284473844748447584476844778447884479844808448184482844838448484485844868448784488844898449084491844928449384494844958449684497844988449984500845018450284503845048450584506845078450884509845108451184512845138451484515845168451784518845198452084521845228452384524845258452684527845288452984530845318453284533845348453584536845378453884539845408454184542845438454484545845468454784548845498455084551845528455384554845558455684557845588455984560845618456284563845648456584566845678456884569845708457184572845738457484575845768457784578845798458084581845828458384584845858458684587845888458984590845918459284593845948459584596845978459884599846008460184602846038460484605846068460784608846098461084611846128461384614846158461684617846188461984620846218462284623846248462584626846278462884629846308463184632846338463484635846368463784638846398464084641846428464384644846458464684647846488464984650846518465284653846548465584656846578465884659846608466184662846638466484665846668466784668846698467084671846728467384674846758467684677846788467984680846818468284683846848468584686846878468884689846908469184692846938469484695846968469784698846998470084701847028470384704847058470684707847088470984710847118471284713847148471584716847178471884719847208472184722847238472484725847268472784728847298473084731847328473384734847358473684737847388473984740847418474284743847448474584746847478474884749847508475184752847538475484755847568475784758847598476084761847628476384764847658476684767847688476984770847718477284773847748477584776847778477884779847808478184782847838478484785847868478784788847898479084791847928479384794847958479684797847988479984800848018480284803848048480584806848078480884809848108481184812848138481484815848168481784818848198482084821848228482384824848258482684827848288482984830848318483284833848348483584836848378483884839848408484184842848438484484845848468484784848848498485084851848528485384854848558485684857848588485984860848618486284863848648486584866848678486884869848708487184872848738487484875848768487784878848798488084881848828488384884848858488684887848888488984890848918489284893848948489584896848978489884899849008490184902849038490484905849068490784908849098491084911849128491384914849158491684917849188491984920849218492284923849248492584926849278492884929849308493184932849338493484935849368493784938849398494084941849428494384944849458494684947849488494984950849518495284953849548495584956849578495884959849608496184962849638496484965849668496784968849698497084971849728497384974849758497684977849788497984980849818498284983849848498584986849878498884989849908499184992849938499484995849968499784998849998500085001850028500385004850058500685007850088500985010850118501285013850148501585016850178501885019850208502185022850238502485025850268502785028850298503085031850328503385034850358503685037850388503985040850418504285043850448504585046850478504885049850508505185052850538505485055850568505785058850598506085061850628506385064850658506685067850688506985070850718507285073850748507585076850778507885079850808508185082850838508485085850868508785088850898509085091850928509385094850958509685097850988509985100851018510285103851048510585106851078510885109851108511185112851138511485115851168511785118851198512085121851228512385124851258512685127851288512985130851318513285133851348513585136851378513885139851408514185142851438514485145851468514785148851498515085151851528515385154851558515685157851588515985160851618516285163851648516585166851678516885169851708517185172851738517485175851768517785178851798518085181851828518385184851858518685187851888518985190851918519285193851948519585196851978519885199852008520185202852038520485205852068520785208852098521085211852128521385214852158521685217852188521985220852218522285223852248522585226852278522885229852308523185232852338523485235852368523785238852398524085241852428524385244852458524685247852488524985250852518525285253852548525585256852578525885259852608526185262852638526485265852668526785268852698527085271852728527385274852758527685277852788527985280852818528285283852848528585286852878528885289852908529185292852938529485295852968529785298852998530085301853028530385304853058530685307853088530985310853118531285313853148531585316853178531885319853208532185322853238532485325853268532785328853298533085331853328533385334853358533685337853388533985340853418534285343853448534585346853478534885349853508535185352853538535485355853568535785358853598536085361853628536385364853658536685367853688536985370853718537285373853748537585376853778537885379853808538185382853838538485385853868538785388853898539085391853928539385394853958539685397853988539985400854018540285403854048540585406854078540885409854108541185412854138541485415854168541785418854198542085421854228542385424854258542685427854288542985430854318543285433854348543585436854378543885439854408544185442854438544485445854468544785448854498545085451854528545385454854558545685457854588545985460854618546285463854648546585466854678546885469854708547185472854738547485475854768547785478854798548085481854828548385484854858548685487854888548985490854918549285493854948549585496854978549885499855008550185502855038550485505855068550785508855098551085511855128551385514855158551685517855188551985520855218552285523855248552585526855278552885529855308553185532855338553485535855368553785538855398554085541855428554385544855458554685547855488554985550855518555285553855548555585556855578555885559855608556185562855638556485565855668556785568855698557085571855728557385574855758557685577855788557985580855818558285583855848558585586855878558885589855908559185592855938559485595855968559785598855998560085601856028560385604856058560685607856088560985610856118561285613856148561585616856178561885619856208562185622856238562485625856268562785628856298563085631856328563385634856358563685637856388563985640856418564285643856448564585646856478564885649856508565185652856538565485655856568565785658856598566085661856628566385664856658566685667856688566985670856718567285673856748567585676856778567885679856808568185682856838568485685856868568785688856898569085691856928569385694856958569685697856988569985700857018570285703857048570585706857078570885709857108571185712857138571485715857168571785718857198572085721857228572385724857258572685727857288572985730857318573285733857348573585736857378573885739857408574185742857438574485745857468574785748857498575085751857528575385754857558575685757857588575985760857618576285763857648576585766857678576885769857708577185772857738577485775857768577785778857798578085781857828578385784857858578685787857888578985790857918579285793857948579585796857978579885799858008580185802858038580485805858068580785808858098581085811858128581385814858158581685817858188581985820858218582285823858248582585826858278582885829858308583185832858338583485835858368583785838858398584085841858428584385844858458584685847858488584985850858518585285853858548585585856858578585885859858608586185862858638586485865858668586785868858698587085871858728587385874858758587685877858788587985880858818588285883858848588585886858878588885889858908589185892858938589485895858968589785898858998590085901859028590385904859058590685907859088590985910859118591285913859148591585916859178591885919859208592185922859238592485925859268592785928859298593085931859328593385934859358593685937859388593985940859418594285943859448594585946859478594885949859508595185952859538595485955859568595785958859598596085961859628596385964859658596685967859688596985970859718597285973859748597585976859778597885979859808598185982859838598485985859868598785988859898599085991859928599385994859958599685997859988599986000860018600286003860048600586006860078600886009860108601186012860138601486015860168601786018860198602086021860228602386024860258602686027860288602986030860318603286033860348603586036860378603886039860408604186042860438604486045860468604786048860498605086051860528605386054860558605686057860588605986060860618606286063860648606586066860678606886069860708607186072860738607486075860768607786078860798608086081860828608386084860858608686087860888608986090860918609286093860948609586096860978609886099861008610186102861038610486105861068610786108861098611086111861128611386114861158611686117861188611986120861218612286123861248612586126861278612886129861308613186132861338613486135861368613786138861398614086141861428614386144861458614686147861488614986150861518615286153861548615586156861578615886159861608616186162861638616486165861668616786168861698617086171861728617386174861758617686177861788617986180861818618286183861848618586186861878618886189861908619186192861938619486195861968619786198861998620086201862028620386204862058620686207862088620986210862118621286213862148621586216862178621886219862208622186222862238622486225862268622786228862298623086231862328623386234862358623686237862388623986240862418624286243862448624586246862478624886249862508625186252862538625486255862568625786258862598626086261862628626386264862658626686267862688626986270862718627286273862748627586276862778627886279862808628186282862838628486285862868628786288862898629086291862928629386294862958629686297862988629986300863018630286303863048630586306863078630886309863108631186312863138631486315863168631786318863198632086321863228632386324863258632686327863288632986330863318633286333863348633586336863378633886339863408634186342863438634486345863468634786348863498635086351863528635386354863558635686357863588635986360863618636286363863648636586366863678636886369863708637186372863738637486375863768637786378863798638086381863828638386384863858638686387863888638986390863918639286393863948639586396863978639886399864008640186402864038640486405864068640786408864098641086411864128641386414864158641686417864188641986420864218642286423864248642586426864278642886429864308643186432864338643486435864368643786438864398644086441864428644386444864458644686447864488644986450864518645286453864548645586456864578645886459864608646186462864638646486465864668646786468864698647086471864728647386474864758647686477864788647986480864818648286483864848648586486864878648886489864908649186492864938649486495864968649786498864998650086501865028650386504865058650686507865088650986510865118651286513865148651586516865178651886519865208652186522865238652486525865268652786528865298653086531865328653386534865358653686537865388653986540865418654286543865448654586546865478654886549865508655186552865538655486555865568655786558865598656086561865628656386564865658656686567865688656986570865718657286573865748657586576865778657886579865808658186582865838658486585865868658786588865898659086591865928659386594865958659686597865988659986600866018660286603866048660586606866078660886609866108661186612866138661486615866168661786618866198662086621866228662386624866258662686627866288662986630866318663286633866348663586636866378663886639866408664186642866438664486645866468664786648866498665086651866528665386654866558665686657866588665986660866618666286663866648666586666866678666886669866708667186672866738667486675866768667786678866798668086681866828668386684866858668686687866888668986690866918669286693866948669586696866978669886699867008670186702867038670486705867068670786708867098671086711867128671386714867158671686717867188671986720867218672286723867248672586726867278672886729867308673186732867338673486735867368673786738867398674086741867428674386744867458674686747867488674986750867518675286753867548675586756867578675886759867608676186762867638676486765867668676786768867698677086771867728677386774867758677686777867788677986780867818678286783867848678586786867878678886789867908679186792867938679486795867968679786798867998680086801868028680386804868058680686807868088680986810868118681286813868148681586816868178681886819868208682186822868238682486825868268682786828868298683086831868328683386834868358683686837868388683986840868418684286843868448684586846868478684886849868508685186852868538685486855868568685786858868598686086861868628686386864868658686686867868688686986870868718687286873868748687586876868778687886879868808688186882868838688486885868868688786888868898689086891868928689386894868958689686897868988689986900869018690286903869048690586906869078690886909869108691186912869138691486915869168691786918869198692086921869228692386924869258692686927869288692986930869318693286933869348693586936869378693886939869408694186942869438694486945869468694786948869498695086951869528695386954869558695686957869588695986960869618696286963869648696586966869678696886969869708697186972869738697486975869768697786978869798698086981869828698386984869858698686987869888698986990869918699286993869948699586996869978699886999870008700187002870038700487005870068700787008870098701087011870128701387014870158701687017870188701987020870218702287023870248702587026870278702887029870308703187032870338703487035870368703787038870398704087041870428704387044870458704687047870488704987050870518705287053870548705587056870578705887059870608706187062870638706487065870668706787068870698707087071870728707387074870758707687077870788707987080870818708287083870848708587086870878708887089870908709187092870938709487095870968709787098870998710087101871028710387104871058710687107871088710987110871118711287113871148711587116871178711887119871208712187122871238712487125871268712787128871298713087131871328713387134871358713687137871388713987140871418714287143871448714587146871478714887149871508715187152871538715487155871568715787158871598716087161871628716387164871658716687167871688716987170871718717287173871748717587176871778717887179871808718187182871838718487185871868718787188871898719087191871928719387194871958719687197871988719987200872018720287203872048720587206872078720887209872108721187212872138721487215872168721787218872198722087221872228722387224872258722687227872288722987230872318723287233872348723587236872378723887239872408724187242872438724487245872468724787248872498725087251872528725387254872558725687257872588725987260872618726287263872648726587266872678726887269872708727187272872738727487275872768727787278872798728087281872828728387284872858728687287872888728987290872918729287293872948729587296872978729887299873008730187302873038730487305873068730787308873098731087311873128731387314873158731687317873188731987320873218732287323873248732587326873278732887329873308733187332873338733487335873368733787338873398734087341873428734387344873458734687347873488734987350873518735287353873548735587356873578735887359873608736187362873638736487365873668736787368873698737087371873728737387374873758737687377873788737987380873818738287383873848738587386873878738887389873908739187392873938739487395873968739787398873998740087401874028740387404874058740687407874088740987410874118741287413874148741587416874178741887419874208742187422874238742487425874268742787428874298743087431874328743387434874358743687437874388743987440874418744287443874448744587446874478744887449874508745187452874538745487455874568745787458874598746087461874628746387464874658746687467874688746987470874718747287473874748747587476874778747887479874808748187482874838748487485874868748787488874898749087491874928749387494874958749687497874988749987500875018750287503875048750587506875078750887509875108751187512875138751487515875168751787518875198752087521875228752387524875258752687527875288752987530875318753287533875348753587536875378753887539875408754187542875438754487545875468754787548875498755087551875528755387554875558755687557875588755987560875618756287563875648756587566875678756887569875708757187572875738757487575875768757787578875798758087581875828758387584875858758687587875888758987590875918759287593875948759587596875978759887599876008760187602876038760487605876068760787608876098761087611876128761387614876158761687617876188761987620876218762287623876248762587626876278762887629876308763187632876338763487635876368763787638876398764087641876428764387644876458764687647876488764987650876518765287653876548765587656876578765887659876608766187662876638766487665876668766787668876698767087671876728767387674876758767687677876788767987680876818768287683876848768587686876878768887689876908769187692876938769487695876968769787698876998770087701877028770387704877058770687707877088770987710877118771287713877148771587716877178771887719877208772187722877238772487725877268772787728877298773087731877328773387734877358773687737877388773987740877418774287743877448774587746877478774887749877508775187752877538775487755877568775787758877598776087761877628776387764877658776687767877688776987770877718777287773877748777587776877778777887779877808778187782877838778487785877868778787788877898779087791877928779387794877958779687797877988779987800878018780287803878048780587806878078780887809878108781187812878138781487815878168781787818878198782087821878228782387824878258782687827878288782987830878318783287833878348783587836878378783887839878408784187842878438784487845878468784787848878498785087851878528785387854878558785687857878588785987860878618786287863878648786587866878678786887869878708787187872878738787487875878768787787878878798788087881878828788387884878858788687887878888788987890878918789287893878948789587896878978789887899879008790187902879038790487905879068790787908879098791087911879128791387914879158791687917879188791987920879218792287923879248792587926879278792887929879308793187932879338793487935879368793787938879398794087941879428794387944879458794687947879488794987950879518795287953879548795587956879578795887959879608796187962879638796487965879668796787968879698797087971879728797387974879758797687977879788797987980879818798287983879848798587986879878798887989879908799187992879938799487995879968799787998879998800088001880028800388004880058800688007880088800988010880118801288013880148801588016880178801888019880208802188022880238802488025880268802788028880298803088031880328803388034880358803688037880388803988040880418804288043880448804588046880478804888049880508805188052880538805488055880568805788058880598806088061880628806388064880658806688067880688806988070880718807288073880748807588076880778807888079880808808188082880838808488085880868808788088880898809088091880928809388094880958809688097880988809988100881018810288103881048810588106881078810888109881108811188112881138811488115881168811788118881198812088121881228812388124881258812688127881288812988130881318813288133881348813588136881378813888139881408814188142881438814488145881468814788148881498815088151881528815388154881558815688157881588815988160881618816288163881648816588166881678816888169881708817188172881738817488175881768817788178881798818088181881828818388184881858818688187881888818988190881918819288193881948819588196881978819888199882008820188202882038820488205882068820788208882098821088211882128821388214882158821688217882188821988220882218822288223882248822588226882278822888229882308823188232882338823488235882368823788238882398824088241882428824388244882458824688247882488824988250882518825288253882548825588256882578825888259882608826188262882638826488265882668826788268882698827088271882728827388274882758827688277882788827988280882818828288283882848828588286882878828888289882908829188292882938829488295882968829788298882998830088301883028830388304883058830688307883088830988310883118831288313883148831588316883178831888319883208832188322883238832488325883268832788328883298833088331883328833388334883358833688337883388833988340883418834288343883448834588346883478834888349883508835188352883538835488355883568835788358883598836088361883628836388364883658836688367883688836988370883718837288373883748837588376883778837888379883808838188382883838838488385883868838788388883898839088391883928839388394883958839688397883988839988400884018840288403884048840588406884078840888409884108841188412884138841488415884168841788418884198842088421884228842388424884258842688427884288842988430884318843288433884348843588436884378843888439884408844188442884438844488445884468844788448884498845088451884528845388454884558845688457884588845988460884618846288463884648846588466884678846888469884708847188472884738847488475884768847788478884798848088481884828848388484884858848688487884888848988490884918849288493884948849588496884978849888499885008850188502885038850488505885068850788508885098851088511885128851388514885158851688517885188851988520885218852288523885248852588526885278852888529885308853188532885338853488535885368853788538885398854088541885428854388544885458854688547885488854988550885518855288553885548855588556885578855888559885608856188562885638856488565885668856788568885698857088571885728857388574885758857688577885788857988580885818858288583885848858588586885878858888589885908859188592885938859488595885968859788598885998860088601886028860388604886058860688607886088860988610886118861288613886148861588616886178861888619886208862188622886238862488625886268862788628886298863088631886328863388634886358863688637886388863988640886418864288643886448864588646886478864888649886508865188652886538865488655886568865788658886598866088661886628866388664886658866688667886688866988670886718867288673886748867588676886778867888679886808868188682886838868488685886868868788688886898869088691886928869388694886958869688697886988869988700887018870288703887048870588706887078870888709887108871188712887138871488715887168871788718887198872088721887228872388724887258872688727887288872988730887318873288733887348873588736887378873888739887408874188742887438874488745887468874788748887498875088751887528875388754887558875688757887588875988760887618876288763887648876588766887678876888769887708877188772887738877488775887768877788778887798878088781887828878388784887858878688787887888878988790887918879288793887948879588796887978879888799888008880188802888038880488805888068880788808888098881088811888128881388814888158881688817888188881988820888218882288823888248882588826888278882888829888308883188832888338883488835888368883788838888398884088841888428884388844888458884688847888488884988850888518885288853888548885588856888578885888859888608886188862888638886488865888668886788868888698887088871888728887388874888758887688877888788887988880888818888288883888848888588886888878888888889888908889188892888938889488895888968889788898888998890088901889028890388904889058890688907889088890988910889118891288913889148891588916889178891888919889208892188922889238892488925889268892788928889298893088931889328893388934889358893688937889388893988940889418894288943889448894588946889478894888949889508895188952889538895488955889568895788958889598896088961889628896388964889658896688967889688896988970889718897288973889748897588976889778897888979889808898188982889838898488985889868898788988889898899088991889928899388994889958899688997889988899989000890018900289003890048900589006890078900889009890108901189012890138901489015890168901789018890198902089021890228902389024890258902689027890288902989030890318903289033890348903589036890378903889039890408904189042890438904489045890468904789048890498905089051890528905389054890558905689057890588905989060890618906289063890648906589066890678906889069890708907189072890738907489075890768907789078890798908089081890828908389084890858908689087890888908989090890918909289093890948909589096890978909889099891008910189102891038910489105891068910789108891098911089111891128911389114891158911689117891188911989120891218912289123891248912589126891278912889129891308913189132891338913489135891368913789138891398914089141891428914389144891458914689147891488914989150891518915289153891548915589156891578915889159891608916189162891638916489165891668916789168891698917089171891728917389174891758917689177891788917989180891818918289183891848918589186891878918889189891908919189192891938919489195891968919789198891998920089201892028920389204892058920689207892088920989210892118921289213892148921589216892178921889219892208922189222892238922489225892268922789228892298923089231892328923389234892358923689237892388923989240892418924289243892448924589246892478924889249892508925189252892538925489255892568925789258892598926089261892628926389264892658926689267892688926989270892718927289273892748927589276892778927889279892808928189282892838928489285892868928789288892898929089291892928929389294892958929689297892988929989300893018930289303893048930589306893078930889309893108931189312893138931489315893168931789318893198932089321893228932389324893258932689327893288932989330893318933289333893348933589336893378933889339893408934189342893438934489345893468934789348893498935089351893528935389354893558935689357893588935989360893618936289363893648936589366893678936889369893708937189372893738937489375893768937789378893798938089381893828938389384893858938689387893888938989390893918939289393893948939589396893978939889399894008940189402894038940489405894068940789408894098941089411894128941389414894158941689417894188941989420894218942289423894248942589426894278942889429894308943189432894338943489435894368943789438894398944089441894428944389444894458944689447894488944989450894518945289453894548945589456894578945889459894608946189462894638946489465894668946789468894698947089471894728947389474894758947689477894788947989480894818948289483894848948589486894878948889489894908949189492894938949489495894968949789498894998950089501895028950389504895058950689507895088950989510895118951289513895148951589516895178951889519895208952189522895238952489525895268952789528895298953089531895328953389534895358953689537895388953989540895418954289543895448954589546895478954889549895508955189552895538955489555895568955789558895598956089561895628956389564895658956689567895688956989570895718957289573895748957589576895778957889579895808958189582895838958489585895868958789588895898959089591895928959389594895958959689597895988959989600896018960289603896048960589606896078960889609896108961189612896138961489615896168961789618896198962089621896228962389624896258962689627896288962989630896318963289633896348963589636896378963889639896408964189642896438964489645896468964789648896498965089651896528965389654896558965689657896588965989660896618966289663896648966589666896678966889669896708967189672896738967489675896768967789678896798968089681896828968389684896858968689687896888968989690896918969289693896948969589696896978969889699897008970189702897038970489705897068970789708897098971089711897128971389714897158971689717897188971989720897218972289723897248972589726897278972889729897308973189732897338973489735897368973789738897398974089741897428974389744897458974689747897488974989750897518975289753897548975589756897578975889759897608976189762897638976489765897668976789768897698977089771897728977389774897758977689777897788977989780897818978289783897848978589786897878978889789897908979189792897938979489795897968979789798897998980089801898028980389804898058980689807898088980989810898118981289813898148981589816898178981889819898208982189822898238982489825898268982789828898298983089831898328983389834898358983689837898388983989840898418984289843898448984589846898478984889849898508985189852898538985489855898568985789858898598986089861898628986389864898658986689867898688986989870898718987289873898748987589876898778987889879898808988189882898838988489885898868988789888898898989089891898928989389894898958989689897898988989989900899018990289903899048990589906899078990889909899108991189912899138991489915899168991789918899198992089921899228992389924899258992689927899288992989930899318993289933899348993589936899378993889939899408994189942899438994489945899468994789948899498995089951899528995389954899558995689957899588995989960899618996289963899648996589966899678996889969899708997189972899738997489975899768997789978899798998089981899828998389984899858998689987899888998989990899918999289993899948999589996899978999889999900009000190002900039000490005900069000790008900099001090011900129001390014900159001690017900189001990020900219002290023900249002590026900279002890029900309003190032900339003490035900369003790038900399004090041900429004390044900459004690047900489004990050900519005290053900549005590056900579005890059900609006190062900639006490065900669006790068900699007090071900729007390074900759007690077900789007990080900819008290083900849008590086900879008890089900909009190092900939009490095900969009790098900999010090101901029010390104901059010690107901089010990110901119011290113901149011590116901179011890119901209012190122901239012490125901269012790128901299013090131901329013390134901359013690137901389013990140901419014290143901449014590146901479014890149901509015190152901539015490155901569015790158901599016090161901629016390164901659016690167901689016990170901719017290173901749017590176901779017890179901809018190182901839018490185901869018790188901899019090191901929019390194901959019690197901989019990200902019020290203902049020590206902079020890209902109021190212902139021490215902169021790218902199022090221902229022390224902259022690227902289022990230902319023290233902349023590236902379023890239902409024190242902439024490245902469024790248902499025090251902529025390254902559025690257902589025990260902619026290263902649026590266902679026890269902709027190272902739027490275902769027790278902799028090281902829028390284902859028690287902889028990290902919029290293902949029590296902979029890299903009030190302903039030490305903069030790308903099031090311903129031390314903159031690317903189031990320903219032290323903249032590326903279032890329903309033190332903339033490335903369033790338903399034090341903429034390344903459034690347903489034990350903519035290353903549035590356903579035890359903609036190362903639036490365903669036790368903699037090371903729037390374903759037690377903789037990380903819038290383903849038590386903879038890389903909039190392903939039490395903969039790398903999040090401904029040390404904059040690407904089040990410904119041290413904149041590416904179041890419904209042190422904239042490425904269042790428904299043090431904329043390434904359043690437904389043990440904419044290443904449044590446904479044890449904509045190452904539045490455904569045790458904599046090461904629046390464904659046690467904689046990470904719047290473904749047590476904779047890479904809048190482904839048490485904869048790488904899049090491904929049390494904959049690497904989049990500905019050290503905049050590506905079050890509905109051190512905139051490515905169051790518905199052090521905229052390524905259052690527905289052990530905319053290533905349053590536905379053890539905409054190542905439054490545905469054790548905499055090551905529055390554905559055690557905589055990560905619056290563905649056590566905679056890569905709057190572905739057490575905769057790578905799058090581905829058390584905859058690587905889058990590905919059290593905949059590596905979059890599906009060190602906039060490605906069060790608906099061090611906129061390614906159061690617906189061990620906219062290623906249062590626906279062890629906309063190632906339063490635906369063790638906399064090641906429064390644906459064690647906489064990650906519065290653906549065590656906579065890659906609066190662906639066490665906669066790668906699067090671906729067390674906759067690677906789067990680906819068290683906849068590686906879068890689906909069190692906939069490695906969069790698906999070090701907029070390704907059070690707907089070990710907119071290713907149071590716907179071890719907209072190722907239072490725907269072790728907299073090731907329073390734907359073690737907389073990740907419074290743907449074590746907479074890749907509075190752907539075490755907569075790758907599076090761907629076390764907659076690767907689076990770907719077290773907749077590776907779077890779907809078190782907839078490785907869078790788907899079090791907929079390794907959079690797907989079990800908019080290803908049080590806908079080890809908109081190812908139081490815908169081790818908199082090821908229082390824908259082690827908289082990830908319083290833908349083590836908379083890839908409084190842908439084490845908469084790848908499085090851908529085390854908559085690857908589085990860908619086290863908649086590866908679086890869908709087190872908739087490875908769087790878908799088090881908829088390884908859088690887908889088990890908919089290893908949089590896908979089890899909009090190902909039090490905909069090790908909099091090911909129091390914909159091690917909189091990920909219092290923909249092590926909279092890929909309093190932909339093490935909369093790938909399094090941909429094390944909459094690947909489094990950909519095290953909549095590956909579095890959909609096190962909639096490965909669096790968909699097090971909729097390974909759097690977909789097990980909819098290983909849098590986909879098890989909909099190992909939099490995909969099790998909999100091001910029100391004910059100691007910089100991010910119101291013910149101591016910179101891019910209102191022910239102491025910269102791028910299103091031910329103391034910359103691037910389103991040910419104291043910449104591046910479104891049910509105191052910539105491055910569105791058910599106091061910629106391064910659106691067910689106991070910719107291073910749107591076910779107891079910809108191082910839108491085910869108791088910899109091091910929109391094910959109691097910989109991100911019110291103911049110591106911079110891109911109111191112911139111491115911169111791118911199112091121911229112391124911259112691127911289112991130911319113291133911349113591136911379113891139911409114191142911439114491145911469114791148911499115091151911529115391154911559115691157911589115991160911619116291163911649116591166911679116891169911709117191172911739117491175911769117791178911799118091181911829118391184911859118691187911889118991190911919119291193911949119591196911979119891199912009120191202912039120491205912069120791208912099121091211912129121391214912159121691217912189121991220912219122291223912249122591226912279122891229912309123191232912339123491235912369123791238912399124091241912429124391244912459124691247912489124991250912519125291253912549125591256912579125891259912609126191262912639126491265912669126791268912699127091271912729127391274912759127691277912789127991280912819128291283912849128591286912879128891289912909129191292912939129491295912969129791298912999130091301913029130391304913059130691307913089130991310913119131291313913149131591316913179131891319913209132191322913239132491325913269132791328913299133091331913329133391334913359133691337913389133991340913419134291343913449134591346913479134891349913509135191352913539135491355913569135791358913599136091361913629136391364913659136691367913689136991370913719137291373913749137591376913779137891379913809138191382913839138491385913869138791388913899139091391913929139391394913959139691397913989139991400914019140291403914049140591406914079140891409914109141191412914139141491415914169141791418914199142091421914229142391424914259142691427914289142991430914319143291433914349143591436914379143891439914409144191442914439144491445914469144791448914499145091451914529145391454914559145691457914589145991460914619146291463914649146591466914679146891469914709147191472914739147491475914769147791478914799148091481914829148391484914859148691487914889148991490914919149291493914949149591496914979149891499915009150191502915039150491505915069150791508915099151091511915129151391514915159151691517915189151991520915219152291523915249152591526915279152891529915309153191532915339153491535915369153791538915399154091541915429154391544915459154691547915489154991550915519155291553915549155591556915579155891559915609156191562915639156491565915669156791568915699157091571915729157391574915759157691577915789157991580915819158291583915849158591586915879158891589915909159191592915939159491595915969159791598915999160091601916029160391604916059160691607916089160991610916119161291613916149161591616916179161891619916209162191622916239162491625916269162791628916299163091631916329163391634916359163691637916389163991640916419164291643916449164591646916479164891649916509165191652916539165491655916569165791658916599166091661916629166391664916659166691667916689166991670916719167291673916749167591676916779167891679916809168191682916839168491685916869168791688916899169091691916929169391694916959169691697916989169991700917019170291703917049170591706917079170891709917109171191712917139171491715917169171791718917199172091721917229172391724917259172691727917289172991730917319173291733917349173591736917379173891739917409174191742917439174491745917469174791748917499175091751917529175391754917559175691757917589175991760917619176291763917649176591766917679176891769917709177191772917739177491775917769177791778917799178091781917829178391784917859178691787917889178991790917919179291793917949179591796917979179891799918009180191802918039180491805918069180791808918099181091811918129181391814918159181691817918189181991820918219182291823918249182591826918279182891829918309183191832918339183491835918369183791838918399184091841918429184391844918459184691847918489184991850918519185291853918549185591856918579185891859918609186191862918639186491865918669186791868918699187091871918729187391874918759187691877918789187991880918819188291883918849188591886918879188891889918909189191892918939189491895918969189791898918999190091901919029190391904919059190691907919089190991910919119191291913919149191591916919179191891919919209192191922919239192491925919269192791928919299193091931919329193391934919359193691937919389193991940919419194291943919449194591946919479194891949919509195191952919539195491955919569195791958919599196091961919629196391964919659196691967919689196991970919719197291973919749197591976919779197891979919809198191982919839198491985919869198791988919899199091991919929199391994919959199691997919989199992000920019200292003920049200592006920079200892009920109201192012920139201492015920169201792018920199202092021920229202392024920259202692027920289202992030920319203292033920349203592036920379203892039920409204192042920439204492045920469204792048920499205092051920529205392054920559205692057920589205992060920619206292063920649206592066920679206892069920709207192072920739207492075920769207792078920799208092081920829208392084920859208692087920889208992090920919209292093920949209592096920979209892099921009210192102921039210492105921069210792108921099211092111921129211392114921159211692117921189211992120921219212292123921249212592126921279212892129921309213192132921339213492135921369213792138921399214092141921429214392144921459214692147921489214992150921519215292153921549215592156921579215892159921609216192162921639216492165921669216792168921699217092171921729217392174921759217692177921789217992180921819218292183921849218592186921879218892189921909219192192921939219492195921969219792198921999220092201922029220392204922059220692207922089220992210922119221292213922149221592216922179221892219922209222192222922239222492225922269222792228922299223092231922329223392234922359223692237922389223992240922419224292243922449224592246922479224892249922509225192252922539225492255922569225792258922599226092261922629226392264922659226692267922689226992270922719227292273922749227592276922779227892279922809228192282922839228492285922869228792288922899229092291922929229392294922959229692297922989229992300923019230292303923049230592306923079230892309923109231192312923139231492315923169231792318923199232092321923229232392324923259232692327923289232992330923319233292333923349233592336923379233892339923409234192342923439234492345923469234792348923499235092351923529235392354923559235692357923589235992360923619236292363923649236592366923679236892369923709237192372923739237492375923769237792378923799238092381923829238392384923859238692387923889238992390923919239292393923949239592396923979239892399924009240192402924039240492405924069240792408924099241092411924129241392414924159241692417924189241992420924219242292423924249242592426924279242892429924309243192432924339243492435924369243792438924399244092441924429244392444924459244692447924489244992450924519245292453924549245592456924579245892459924609246192462924639246492465924669246792468924699247092471924729247392474924759247692477924789247992480924819248292483924849248592486924879248892489924909249192492924939249492495924969249792498924999250092501925029250392504925059250692507925089250992510925119251292513925149251592516925179251892519925209252192522925239252492525925269252792528925299253092531925329253392534925359253692537925389253992540925419254292543925449254592546925479254892549925509255192552925539255492555925569255792558925599256092561925629256392564925659256692567925689256992570925719257292573925749257592576925779257892579925809258192582925839258492585925869258792588925899259092591925929259392594925959259692597925989259992600926019260292603926049260592606926079260892609926109261192612926139261492615926169261792618926199262092621926229262392624926259262692627926289262992630926319263292633926349263592636926379263892639926409264192642926439264492645926469264792648926499265092651926529265392654926559265692657926589265992660926619266292663926649266592666926679266892669926709267192672926739267492675926769267792678926799268092681926829268392684926859268692687926889268992690926919269292693926949269592696926979269892699927009270192702927039270492705927069270792708927099271092711927129271392714927159271692717927189271992720927219272292723927249272592726927279272892729927309273192732927339273492735927369273792738927399274092741927429274392744927459274692747927489274992750927519275292753927549275592756927579275892759927609276192762927639276492765927669276792768927699277092771927729277392774927759277692777927789277992780927819278292783927849278592786927879278892789927909279192792927939279492795927969279792798927999280092801928029280392804928059280692807928089280992810928119281292813928149281592816928179281892819928209282192822928239282492825928269282792828928299283092831928329283392834928359283692837928389283992840928419284292843928449284592846928479284892849928509285192852928539285492855928569285792858928599286092861928629286392864928659286692867928689286992870928719287292873928749287592876928779287892879928809288192882928839288492885928869288792888928899289092891928929289392894928959289692897928989289992900929019290292903929049290592906929079290892909929109291192912929139291492915929169291792918929199292092921929229292392924929259292692927929289292992930929319293292933929349293592936929379293892939929409294192942929439294492945929469294792948929499295092951929529295392954929559295692957929589295992960929619296292963929649296592966929679296892969929709297192972929739297492975929769297792978929799298092981929829298392984929859298692987929889298992990929919299292993929949299592996929979299892999930009300193002930039300493005930069300793008930099301093011930129301393014930159301693017930189301993020930219302293023930249302593026930279302893029930309303193032930339303493035930369303793038930399304093041930429304393044930459304693047930489304993050930519305293053930549305593056930579305893059930609306193062930639306493065930669306793068930699307093071930729307393074930759307693077930789307993080930819308293083930849308593086930879308893089930909309193092930939309493095930969309793098930999310093101931029310393104931059310693107931089310993110931119311293113931149311593116931179311893119931209312193122931239312493125931269312793128931299313093131931329313393134931359313693137931389313993140931419314293143931449314593146931479314893149931509315193152931539315493155931569315793158931599316093161931629316393164931659316693167931689316993170931719317293173931749317593176931779317893179931809318193182931839318493185931869318793188931899319093191931929319393194931959319693197931989319993200932019320293203932049320593206932079320893209932109321193212932139321493215932169321793218932199322093221932229322393224932259322693227932289322993230932319323293233932349323593236932379323893239932409324193242932439324493245932469324793248932499325093251932529325393254932559325693257932589325993260932619326293263932649326593266932679326893269932709327193272932739327493275932769327793278932799328093281932829328393284932859328693287932889328993290932919329293293932949329593296932979329893299933009330193302933039330493305933069330793308933099331093311933129331393314933159331693317933189331993320933219332293323933249332593326933279332893329933309333193332933339333493335933369333793338933399334093341933429334393344933459334693347933489334993350933519335293353933549335593356933579335893359933609336193362933639336493365933669336793368933699337093371933729337393374933759337693377933789337993380933819338293383933849338593386933879338893389933909339193392933939339493395933969339793398933999340093401934029340393404934059340693407934089340993410934119341293413934149341593416934179341893419934209342193422934239342493425934269342793428934299343093431934329343393434934359343693437934389343993440934419344293443934449344593446934479344893449934509345193452934539345493455934569345793458934599346093461934629346393464934659346693467934689346993470934719347293473934749347593476934779347893479934809348193482934839348493485934869348793488934899349093491934929349393494934959349693497934989349993500935019350293503935049350593506935079350893509935109351193512935139351493515935169351793518935199352093521935229352393524935259352693527935289352993530935319353293533935349353593536935379353893539935409354193542935439354493545935469354793548935499355093551935529355393554935559355693557935589355993560935619356293563935649356593566935679356893569935709357193572935739357493575935769357793578935799358093581935829358393584935859358693587935889358993590935919359293593935949359593596935979359893599936009360193602936039360493605936069360793608936099361093611936129361393614936159361693617936189361993620936219362293623936249362593626936279362893629936309363193632936339363493635936369363793638936399364093641936429364393644936459364693647936489364993650936519365293653936549365593656936579365893659936609366193662936639366493665936669366793668936699367093671936729367393674936759367693677936789367993680936819368293683936849368593686936879368893689936909369193692936939369493695936969369793698936999370093701937029370393704937059370693707937089370993710937119371293713937149371593716937179371893719937209372193722937239372493725937269372793728937299373093731937329373393734937359373693737937389373993740937419374293743937449374593746937479374893749937509375193752937539375493755937569375793758937599376093761937629376393764937659376693767937689376993770937719377293773937749377593776937779377893779937809378193782937839378493785937869378793788937899379093791937929379393794937959379693797937989379993800938019380293803938049380593806938079380893809938109381193812938139381493815938169381793818938199382093821938229382393824938259382693827938289382993830938319383293833938349383593836938379383893839938409384193842938439384493845938469384793848938499385093851938529385393854938559385693857938589385993860938619386293863938649386593866938679386893869938709387193872938739387493875938769387793878938799388093881938829388393884938859388693887938889388993890938919389293893938949389593896938979389893899939009390193902939039390493905939069390793908939099391093911939129391393914939159391693917939189391993920939219392293923939249392593926939279392893929939309393193932939339393493935939369393793938939399394093941939429394393944939459394693947939489394993950939519395293953939549395593956939579395893959939609396193962939639396493965939669396793968939699397093971939729397393974939759397693977939789397993980939819398293983939849398593986939879398893989939909399193992939939399493995939969399793998939999400094001940029400394004940059400694007940089400994010940119401294013940149401594016940179401894019940209402194022940239402494025940269402794028940299403094031940329403394034940359403694037940389403994040940419404294043940449404594046940479404894049940509405194052940539405494055940569405794058940599406094061940629406394064940659406694067940689406994070940719407294073940749407594076940779407894079940809408194082940839408494085940869408794088940899409094091940929409394094940959409694097940989409994100941019410294103941049410594106941079410894109941109411194112941139411494115941169411794118941199412094121941229412394124941259412694127941289412994130941319413294133941349413594136941379413894139941409414194142941439414494145941469414794148941499415094151941529415394154941559415694157941589415994160941619416294163941649416594166941679416894169941709417194172941739417494175941769417794178941799418094181941829418394184941859418694187941889418994190941919419294193941949419594196941979419894199942009420194202942039420494205942069420794208942099421094211942129421394214942159421694217942189421994220942219422294223942249422594226942279422894229942309423194232942339423494235942369423794238942399424094241942429424394244942459424694247942489424994250942519425294253942549425594256942579425894259942609426194262942639426494265942669426794268942699427094271942729427394274942759427694277942789427994280942819428294283942849428594286942879428894289942909429194292942939429494295942969429794298942999430094301943029430394304943059430694307943089430994310943119431294313943149431594316943179431894319943209432194322943239432494325943269432794328943299433094331943329433394334943359433694337943389433994340943419434294343943449434594346943479434894349943509435194352943539435494355943569435794358943599436094361943629436394364943659436694367943689436994370943719437294373943749437594376943779437894379943809438194382943839438494385943869438794388943899439094391943929439394394943959439694397943989439994400944019440294403944049440594406944079440894409944109441194412944139441494415944169441794418944199442094421944229442394424944259442694427944289442994430944319443294433944349443594436944379443894439944409444194442944439444494445944469444794448944499445094451944529445394454944559445694457944589445994460944619446294463944649446594466944679446894469944709447194472944739447494475944769447794478944799448094481944829448394484944859448694487944889448994490944919449294493944949449594496944979449894499945009450194502945039450494505945069450794508945099451094511945129451394514945159451694517945189451994520945219452294523945249452594526945279452894529945309453194532945339453494535945369453794538945399454094541945429454394544945459454694547945489454994550945519455294553945549455594556945579455894559945609456194562945639456494565945669456794568945699457094571945729457394574945759457694577945789457994580945819458294583945849458594586945879458894589945909459194592945939459494595945969459794598945999460094601946029460394604946059460694607946089460994610946119461294613946149461594616946179461894619946209462194622946239462494625946269462794628946299463094631946329463394634946359463694637946389463994640946419464294643946449464594646946479464894649946509465194652946539465494655946569465794658946599466094661946629466394664946659466694667946689466994670946719467294673946749467594676946779467894679946809468194682946839468494685946869468794688946899469094691946929469394694946959469694697946989469994700947019470294703947049470594706947079470894709947109471194712947139471494715947169471794718947199472094721947229472394724947259472694727947289472994730947319473294733947349473594736947379473894739947409474194742947439474494745947469474794748947499475094751947529475394754947559475694757947589475994760947619476294763947649476594766947679476894769947709477194772947739477494775947769477794778947799478094781947829478394784947859478694787947889478994790947919479294793947949479594796947979479894799948009480194802948039480494805948069480794808948099481094811948129481394814948159481694817948189481994820948219482294823948249482594826948279482894829948309483194832948339483494835948369483794838948399484094841948429484394844948459484694847948489484994850948519485294853948549485594856948579485894859948609486194862948639486494865948669486794868948699487094871948729487394874948759487694877948789487994880948819488294883948849488594886948879488894889948909489194892948939489494895948969489794898948999490094901949029490394904949059490694907949089490994910949119491294913949149491594916949179491894919949209492194922949239492494925949269492794928949299493094931949329493394934949359493694937949389493994940949419494294943949449494594946949479494894949949509495194952949539495494955949569495794958949599496094961949629496394964949659496694967949689496994970949719497294973949749497594976949779497894979949809498194982949839498494985949869498794988949899499094991949929499394994949959499694997949989499995000950019500295003950049500595006950079500895009950109501195012950139501495015950169501795018950199502095021950229502395024950259502695027950289502995030950319503295033950349503595036950379503895039950409504195042950439504495045950469504795048950499505095051950529505395054950559505695057950589505995060950619506295063950649506595066950679506895069950709507195072950739507495075950769507795078950799508095081950829508395084950859508695087950889508995090950919509295093950949509595096950979509895099951009510195102951039510495105951069510795108951099511095111951129511395114951159511695117951189511995120951219512295123951249512595126951279512895129951309513195132951339513495135951369513795138951399514095141951429514395144951459514695147951489514995150951519515295153951549515595156951579515895159951609516195162951639516495165951669516795168951699517095171951729517395174951759517695177951789517995180951819518295183951849518595186951879518895189951909519195192951939519495195951969519795198951999520095201952029520395204952059520695207952089520995210952119521295213952149521595216952179521895219952209522195222952239522495225952269522795228952299523095231952329523395234952359523695237952389523995240952419524295243952449524595246952479524895249952509525195252952539525495255952569525795258952599526095261952629526395264952659526695267952689526995270952719527295273952749527595276952779527895279952809528195282952839528495285952869528795288952899529095291952929529395294952959529695297952989529995300953019530295303953049530595306953079530895309953109531195312953139531495315953169531795318953199532095321953229532395324953259532695327953289532995330953319533295333953349533595336953379533895339953409534195342953439534495345953469534795348953499535095351953529535395354953559535695357953589535995360953619536295363953649536595366953679536895369953709537195372953739537495375953769537795378953799538095381953829538395384953859538695387953889538995390953919539295393953949539595396953979539895399954009540195402954039540495405954069540795408954099541095411954129541395414954159541695417954189541995420954219542295423954249542595426954279542895429954309543195432954339543495435954369543795438954399544095441954429544395444954459544695447954489544995450954519545295453954549545595456954579545895459954609546195462954639546495465954669546795468954699547095471954729547395474954759547695477954789547995480954819548295483954849548595486954879548895489954909549195492954939549495495954969549795498954999550095501955029550395504955059550695507955089550995510955119551295513955149551595516955179551895519955209552195522955239552495525955269552795528955299553095531955329553395534955359553695537955389553995540955419554295543955449554595546955479554895549955509555195552955539555495555955569555795558955599556095561955629556395564955659556695567955689556995570955719557295573955749557595576955779557895579955809558195582955839558495585955869558795588955899559095591955929559395594955959559695597955989559995600956019560295603956049560595606956079560895609956109561195612956139561495615956169561795618956199562095621956229562395624956259562695627956289562995630956319563295633956349563595636956379563895639956409564195642956439564495645956469564795648956499565095651956529565395654956559565695657956589565995660956619566295663956649566595666956679566895669956709567195672956739567495675956769567795678956799568095681956829568395684956859568695687956889568995690956919569295693956949569595696956979569895699957009570195702957039570495705957069570795708957099571095711957129571395714957159571695717957189571995720957219572295723957249572595726957279572895729957309573195732957339573495735957369573795738957399574095741957429574395744957459574695747957489574995750957519575295753957549575595756957579575895759957609576195762957639576495765957669576795768957699577095771957729577395774957759577695777957789577995780957819578295783957849578595786957879578895789957909579195792957939579495795957969579795798957999580095801958029580395804958059580695807958089580995810958119581295813958149581595816958179581895819958209582195822958239582495825958269582795828958299583095831958329583395834958359583695837958389583995840958419584295843958449584595846958479584895849958509585195852958539585495855958569585795858958599586095861958629586395864958659586695867958689586995870958719587295873958749587595876958779587895879958809588195882958839588495885958869588795888958899589095891958929589395894958959589695897958989589995900959019590295903
  1. /*! @brief `EnTT` default namespace. */
  2. namespace entt {}
  3. // IWYU pragma: begin_exports
  4. // #include "config/config.h"
  5. #ifndef ENTT_CONFIG_CONFIG_H
  6. #define ENTT_CONFIG_CONFIG_H
  7. // #include "version.h"
  8. #ifndef ENTT_CONFIG_VERSION_H
  9. #define ENTT_CONFIG_VERSION_H
  10. // #include "macro.h"
  11. #ifndef ENTT_CONFIG_MACRO_H
  12. #define ENTT_CONFIG_MACRO_H
  13. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  14. #define ENTT_STR(arg) #arg
  15. #define ENTT_XSTR(arg) ENTT_STR(arg)
  16. // NOLINTEND(cppcoreguidelines-macro-usage)
  17. #endif
  18. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  19. #define ENTT_VERSION_MAJOR 3
  20. #define ENTT_VERSION_MINOR 16
  21. #define ENTT_VERSION_PATCH 0
  22. #define ENTT_VERSION \
  23. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  24. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  25. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  26. #endif
  27. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  28. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  29. # define ENTT_CONSTEXPR
  30. # define ENTT_THROW throw
  31. # define ENTT_TRY try
  32. # define ENTT_CATCH catch(...)
  33. #else
  34. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  35. # define ENTT_THROW
  36. # define ENTT_TRY if(true)
  37. # define ENTT_CATCH if(false)
  38. #endif
  39. #if __has_include(<version>)
  40. # include <version>
  41. #
  42. # if defined(__cpp_consteval)
  43. # define ENTT_CONSTEVAL consteval
  44. # endif
  45. #endif
  46. #ifndef ENTT_CONSTEVAL
  47. # define ENTT_CONSTEVAL constexpr
  48. #endif
  49. #ifdef ENTT_USE_ATOMIC
  50. # include <atomic>
  51. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  52. #else
  53. # define ENTT_MAYBE_ATOMIC(Type) Type
  54. #endif
  55. #ifndef ENTT_ID_TYPE
  56. # include <cstdint>
  57. # define ENTT_ID_TYPE std::uint32_t
  58. #else
  59. # include <cstdint> // provides coverage for types in the std namespace
  60. #endif
  61. #ifndef ENTT_SPARSE_PAGE
  62. # define ENTT_SPARSE_PAGE 4096
  63. #endif
  64. #ifndef ENTT_PACKED_PAGE
  65. # define ENTT_PACKED_PAGE 1024
  66. #endif
  67. #ifdef ENTT_DISABLE_ASSERT
  68. # undef ENTT_ASSERT
  69. # define ENTT_ASSERT(condition, msg) (void(0))
  70. #elif !defined ENTT_ASSERT
  71. # include <cassert>
  72. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  73. #endif
  74. #ifdef ENTT_DISABLE_ASSERT
  75. # undef ENTT_ASSERT_CONSTEXPR
  76. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  77. #elif !defined ENTT_ASSERT_CONSTEXPR
  78. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  79. #endif
  80. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  81. #ifdef ENTT_NO_ETO
  82. # define ENTT_ETO_TYPE(Type) void
  83. #else
  84. # define ENTT_ETO_TYPE(Type) Type
  85. #endif
  86. #ifdef ENTT_NO_MIXIN
  87. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  88. #else
  89. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  90. #endif
  91. #ifdef ENTT_STANDARD_CPP
  92. # define ENTT_NONSTD false
  93. #else
  94. # define ENTT_NONSTD true
  95. # if defined __clang__ || defined __GNUC__
  96. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  97. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  98. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  99. # elif defined _MSC_VER
  100. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  101. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  102. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  103. # endif
  104. #endif
  105. #ifndef ENTT_EXPORT
  106. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  107. # define ENTT_EXPORT __declspec(dllexport)
  108. # define ENTT_IMPORT __declspec(dllimport)
  109. # define ENTT_HIDDEN
  110. # elif defined __GNUC__ && __GNUC__ >= 4
  111. # define ENTT_EXPORT __attribute__((visibility("default")))
  112. # define ENTT_IMPORT __attribute__((visibility("default")))
  113. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  114. # else /* Unsupported compiler */
  115. # define ENTT_EXPORT
  116. # define ENTT_IMPORT
  117. # define ENTT_HIDDEN
  118. # endif
  119. #endif
  120. #ifndef ENTT_API
  121. # if defined ENTT_API_EXPORT
  122. # define ENTT_API ENTT_EXPORT
  123. # elif defined ENTT_API_IMPORT
  124. # define ENTT_API ENTT_IMPORT
  125. # else /* No API */
  126. # define ENTT_API
  127. # endif
  128. #endif
  129. #if defined _MSC_VER
  130. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  131. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  132. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  133. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  134. #endif
  135. // NOLINTEND(cppcoreguidelines-macro-usage)
  136. #endif
  137. // #include "config/macro.h"
  138. #ifndef ENTT_CONFIG_MACRO_H
  139. #define ENTT_CONFIG_MACRO_H
  140. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  141. #define ENTT_STR(arg) #arg
  142. #define ENTT_XSTR(arg) ENTT_STR(arg)
  143. // NOLINTEND(cppcoreguidelines-macro-usage)
  144. #endif
  145. // #include "config/version.h"
  146. #ifndef ENTT_CONFIG_VERSION_H
  147. #define ENTT_CONFIG_VERSION_H
  148. // #include "macro.h"
  149. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  150. #define ENTT_VERSION_MAJOR 3
  151. #define ENTT_VERSION_MINOR 16
  152. #define ENTT_VERSION_PATCH 0
  153. #define ENTT_VERSION \
  154. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  155. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  156. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  157. #endif
  158. // #include "container/dense_map.hpp"
  159. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  160. #define ENTT_CONTAINER_DENSE_MAP_HPP
  161. #include <cmath>
  162. #include <cstddef>
  163. #include <functional>
  164. #include <iterator>
  165. #include <limits>
  166. #include <memory>
  167. #include <tuple>
  168. #include <type_traits>
  169. #include <utility>
  170. #include <vector>
  171. // #include "../config/config.h"
  172. #ifndef ENTT_CONFIG_CONFIG_H
  173. #define ENTT_CONFIG_CONFIG_H
  174. // #include "version.h"
  175. #ifndef ENTT_CONFIG_VERSION_H
  176. #define ENTT_CONFIG_VERSION_H
  177. // #include "macro.h"
  178. #ifndef ENTT_CONFIG_MACRO_H
  179. #define ENTT_CONFIG_MACRO_H
  180. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  181. #define ENTT_STR(arg) #arg
  182. #define ENTT_XSTR(arg) ENTT_STR(arg)
  183. // NOLINTEND(cppcoreguidelines-macro-usage)
  184. #endif
  185. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  186. #define ENTT_VERSION_MAJOR 3
  187. #define ENTT_VERSION_MINOR 16
  188. #define ENTT_VERSION_PATCH 0
  189. #define ENTT_VERSION \
  190. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  191. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  192. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  193. #endif
  194. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  195. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  196. # define ENTT_CONSTEXPR
  197. # define ENTT_THROW throw
  198. # define ENTT_TRY try
  199. # define ENTT_CATCH catch(...)
  200. #else
  201. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  202. # define ENTT_THROW
  203. # define ENTT_TRY if(true)
  204. # define ENTT_CATCH if(false)
  205. #endif
  206. #if __has_include(<version>)
  207. # include <version>
  208. #
  209. # if defined(__cpp_consteval)
  210. # define ENTT_CONSTEVAL consteval
  211. # endif
  212. #endif
  213. #ifndef ENTT_CONSTEVAL
  214. # define ENTT_CONSTEVAL constexpr
  215. #endif
  216. #ifdef ENTT_USE_ATOMIC
  217. # include <atomic>
  218. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  219. #else
  220. # define ENTT_MAYBE_ATOMIC(Type) Type
  221. #endif
  222. #ifndef ENTT_ID_TYPE
  223. # include <cstdint>
  224. # define ENTT_ID_TYPE std::uint32_t
  225. #else
  226. # include <cstdint> // provides coverage for types in the std namespace
  227. #endif
  228. #ifndef ENTT_SPARSE_PAGE
  229. # define ENTT_SPARSE_PAGE 4096
  230. #endif
  231. #ifndef ENTT_PACKED_PAGE
  232. # define ENTT_PACKED_PAGE 1024
  233. #endif
  234. #ifdef ENTT_DISABLE_ASSERT
  235. # undef ENTT_ASSERT
  236. # define ENTT_ASSERT(condition, msg) (void(0))
  237. #elif !defined ENTT_ASSERT
  238. # include <cassert>
  239. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  240. #endif
  241. #ifdef ENTT_DISABLE_ASSERT
  242. # undef ENTT_ASSERT_CONSTEXPR
  243. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  244. #elif !defined ENTT_ASSERT_CONSTEXPR
  245. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  246. #endif
  247. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  248. #ifdef ENTT_NO_ETO
  249. # define ENTT_ETO_TYPE(Type) void
  250. #else
  251. # define ENTT_ETO_TYPE(Type) Type
  252. #endif
  253. #ifdef ENTT_NO_MIXIN
  254. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  255. #else
  256. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  257. #endif
  258. #ifdef ENTT_STANDARD_CPP
  259. # define ENTT_NONSTD false
  260. #else
  261. # define ENTT_NONSTD true
  262. # if defined __clang__ || defined __GNUC__
  263. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  264. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  265. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  266. # elif defined _MSC_VER
  267. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  268. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  269. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  270. # endif
  271. #endif
  272. #ifndef ENTT_EXPORT
  273. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  274. # define ENTT_EXPORT __declspec(dllexport)
  275. # define ENTT_IMPORT __declspec(dllimport)
  276. # define ENTT_HIDDEN
  277. # elif defined __GNUC__ && __GNUC__ >= 4
  278. # define ENTT_EXPORT __attribute__((visibility("default")))
  279. # define ENTT_IMPORT __attribute__((visibility("default")))
  280. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  281. # else /* Unsupported compiler */
  282. # define ENTT_EXPORT
  283. # define ENTT_IMPORT
  284. # define ENTT_HIDDEN
  285. # endif
  286. #endif
  287. #ifndef ENTT_API
  288. # if defined ENTT_API_EXPORT
  289. # define ENTT_API ENTT_EXPORT
  290. # elif defined ENTT_API_IMPORT
  291. # define ENTT_API ENTT_IMPORT
  292. # else /* No API */
  293. # define ENTT_API
  294. # endif
  295. #endif
  296. #if defined _MSC_VER
  297. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  298. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  299. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  300. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  301. #endif
  302. // NOLINTEND(cppcoreguidelines-macro-usage)
  303. #endif
  304. // #include "../core/bit.hpp"
  305. #ifndef ENTT_CORE_BIT_HPP
  306. #define ENTT_CORE_BIT_HPP
  307. #include <cstddef>
  308. #include <limits>
  309. #include <type_traits>
  310. // #include "../config/config.h"
  311. #ifndef ENTT_CONFIG_CONFIG_H
  312. #define ENTT_CONFIG_CONFIG_H
  313. // #include "version.h"
  314. #ifndef ENTT_CONFIG_VERSION_H
  315. #define ENTT_CONFIG_VERSION_H
  316. // #include "macro.h"
  317. #ifndef ENTT_CONFIG_MACRO_H
  318. #define ENTT_CONFIG_MACRO_H
  319. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  320. #define ENTT_STR(arg) #arg
  321. #define ENTT_XSTR(arg) ENTT_STR(arg)
  322. // NOLINTEND(cppcoreguidelines-macro-usage)
  323. #endif
  324. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  325. #define ENTT_VERSION_MAJOR 3
  326. #define ENTT_VERSION_MINOR 16
  327. #define ENTT_VERSION_PATCH 0
  328. #define ENTT_VERSION \
  329. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  330. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  331. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  332. #endif
  333. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  334. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  335. # define ENTT_CONSTEXPR
  336. # define ENTT_THROW throw
  337. # define ENTT_TRY try
  338. # define ENTT_CATCH catch(...)
  339. #else
  340. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  341. # define ENTT_THROW
  342. # define ENTT_TRY if(true)
  343. # define ENTT_CATCH if(false)
  344. #endif
  345. #if __has_include(<version>)
  346. # include <version>
  347. #
  348. # if defined(__cpp_consteval)
  349. # define ENTT_CONSTEVAL consteval
  350. # endif
  351. #endif
  352. #ifndef ENTT_CONSTEVAL
  353. # define ENTT_CONSTEVAL constexpr
  354. #endif
  355. #ifdef ENTT_USE_ATOMIC
  356. # include <atomic>
  357. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  358. #else
  359. # define ENTT_MAYBE_ATOMIC(Type) Type
  360. #endif
  361. #ifndef ENTT_ID_TYPE
  362. # include <cstdint>
  363. # define ENTT_ID_TYPE std::uint32_t
  364. #else
  365. # include <cstdint> // provides coverage for types in the std namespace
  366. #endif
  367. #ifndef ENTT_SPARSE_PAGE
  368. # define ENTT_SPARSE_PAGE 4096
  369. #endif
  370. #ifndef ENTT_PACKED_PAGE
  371. # define ENTT_PACKED_PAGE 1024
  372. #endif
  373. #ifdef ENTT_DISABLE_ASSERT
  374. # undef ENTT_ASSERT
  375. # define ENTT_ASSERT(condition, msg) (void(0))
  376. #elif !defined ENTT_ASSERT
  377. # include <cassert>
  378. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  379. #endif
  380. #ifdef ENTT_DISABLE_ASSERT
  381. # undef ENTT_ASSERT_CONSTEXPR
  382. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  383. #elif !defined ENTT_ASSERT_CONSTEXPR
  384. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  385. #endif
  386. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  387. #ifdef ENTT_NO_ETO
  388. # define ENTT_ETO_TYPE(Type) void
  389. #else
  390. # define ENTT_ETO_TYPE(Type) Type
  391. #endif
  392. #ifdef ENTT_NO_MIXIN
  393. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  394. #else
  395. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  396. #endif
  397. #ifdef ENTT_STANDARD_CPP
  398. # define ENTT_NONSTD false
  399. #else
  400. # define ENTT_NONSTD true
  401. # if defined __clang__ || defined __GNUC__
  402. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  403. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  404. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  405. # elif defined _MSC_VER
  406. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  407. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  408. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  409. # endif
  410. #endif
  411. #ifndef ENTT_EXPORT
  412. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  413. # define ENTT_EXPORT __declspec(dllexport)
  414. # define ENTT_IMPORT __declspec(dllimport)
  415. # define ENTT_HIDDEN
  416. # elif defined __GNUC__ && __GNUC__ >= 4
  417. # define ENTT_EXPORT __attribute__((visibility("default")))
  418. # define ENTT_IMPORT __attribute__((visibility("default")))
  419. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  420. # else /* Unsupported compiler */
  421. # define ENTT_EXPORT
  422. # define ENTT_IMPORT
  423. # define ENTT_HIDDEN
  424. # endif
  425. #endif
  426. #ifndef ENTT_API
  427. # if defined ENTT_API_EXPORT
  428. # define ENTT_API ENTT_EXPORT
  429. # elif defined ENTT_API_IMPORT
  430. # define ENTT_API ENTT_IMPORT
  431. # else /* No API */
  432. # define ENTT_API
  433. # endif
  434. #endif
  435. #if defined _MSC_VER
  436. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  437. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  438. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  439. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  440. #endif
  441. // NOLINTEND(cppcoreguidelines-macro-usage)
  442. #endif
  443. namespace entt {
  444. /**
  445. * @brief Returns the number of set bits in a value (waiting for C++20 and
  446. * `std::popcount`).
  447. * @tparam Type Unsigned integer type.
  448. * @param value A value of unsigned integer type.
  449. * @return The number of set bits in the value.
  450. */
  451. template<typename Type>
  452. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  453. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  454. }
  455. /**
  456. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  457. * `std::has_single_bit`).
  458. * @tparam Type Unsigned integer type.
  459. * @param value A value of unsigned integer type.
  460. * @return True if the value is a power of two, false otherwise.
  461. */
  462. template<typename Type>
  463. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  464. return value && ((value & (value - 1)) == 0);
  465. }
  466. /**
  467. * @brief Computes the smallest power of two greater than or equal to a value
  468. * (waiting for C++20 and `std::bit_ceil`).
  469. * @tparam Type Unsigned integer type.
  470. * @param value A value of unsigned integer type.
  471. * @return The smallest power of two greater than or equal to the given value.
  472. */
  473. template<typename Type>
  474. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  475. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  476. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  477. Type curr = value - (value != 0u);
  478. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  479. curr |= (curr >> next);
  480. }
  481. return ++curr;
  482. }
  483. /**
  484. * @brief Fast module utility function (powers of two only).
  485. * @tparam Type Unsigned integer type.
  486. * @param value A value of unsigned integer type.
  487. * @param mod _Modulus_, it must be a power of two.
  488. * @return The common remainder.
  489. */
  490. template<typename Type>
  491. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  492. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  493. return static_cast<Type>(value & (mod - 1u));
  494. }
  495. } // namespace entt
  496. #endif
  497. // #include "../core/compressed_pair.hpp"
  498. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  499. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  500. #include <cstddef>
  501. #include <tuple>
  502. #include <type_traits>
  503. #include <utility>
  504. // #include "fwd.hpp"
  505. #ifndef ENTT_CORE_FWD_HPP
  506. #define ENTT_CORE_FWD_HPP
  507. #include <cstddef>
  508. #include <cstdint>
  509. // #include "../config/config.h"
  510. namespace entt {
  511. /*! @brief Possible modes of an any object. */
  512. enum class any_policy : std::uint8_t {
  513. /*! @brief Default mode, no element available. */
  514. empty,
  515. /*! @brief Owning mode, dynamically allocated element. */
  516. dynamic,
  517. /*! @brief Owning mode, embedded element. */
  518. embedded,
  519. /*! @brief Aliasing mode, non-const reference. */
  520. ref,
  521. /*! @brief Const aliasing mode, const reference. */
  522. cref
  523. };
  524. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  525. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  526. class basic_any;
  527. /*! @brief Alias declaration for type identifiers. */
  528. using id_type = ENTT_ID_TYPE;
  529. /*! @brief Alias declaration for the most common use case. */
  530. using any = basic_any<>;
  531. template<typename, typename>
  532. class compressed_pair;
  533. template<typename>
  534. class basic_hashed_string;
  535. /*! @brief Aliases for common character types. */
  536. using hashed_string = basic_hashed_string<char>;
  537. /*! @brief Aliases for common character types. */
  538. using hashed_wstring = basic_hashed_string<wchar_t>;
  539. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  540. struct type_info;
  541. } // namespace entt
  542. #endif
  543. // #include "type_traits.hpp"
  544. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  545. #define ENTT_CORE_TYPE_TRAITS_HPP
  546. #include <cstddef>
  547. #include <iterator>
  548. #include <tuple>
  549. #include <type_traits>
  550. #include <utility>
  551. // #include "../config/config.h"
  552. // #include "fwd.hpp"
  553. namespace entt {
  554. /**
  555. * @brief Utility class to disambiguate overloaded functions.
  556. * @tparam N Number of choices available.
  557. */
  558. template<std::size_t N>
  559. struct choice_t
  560. // unfortunately, doxygen cannot parse such a construct
  561. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  562. {};
  563. /*! @copybrief choice_t */
  564. template<>
  565. struct choice_t<0> {};
  566. /**
  567. * @brief Variable template for the choice trick.
  568. * @tparam N Number of choices available.
  569. */
  570. template<std::size_t N>
  571. inline constexpr choice_t<N> choice{};
  572. /**
  573. * @brief Identity type trait.
  574. *
  575. * Useful to establish non-deduced contexts in template argument deduction
  576. * (waiting for C++20) or to provide types through function arguments.
  577. *
  578. * @tparam Type A type.
  579. */
  580. template<typename Type>
  581. struct type_identity {
  582. /*! @brief Identity type. */
  583. using type = Type;
  584. };
  585. /**
  586. * @brief Helper type.
  587. * @tparam Type A type.
  588. */
  589. template<typename Type>
  590. using type_identity_t = typename type_identity<Type>::type;
  591. /**
  592. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  593. * @tparam Type The type of which to return the size.
  594. */
  595. template<typename Type, typename = void>
  596. struct size_of: std::integral_constant<std::size_t, 0u> {};
  597. /*! @copydoc size_of */
  598. template<typename Type>
  599. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  600. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  601. : std::integral_constant<std::size_t, sizeof(Type)> {};
  602. /**
  603. * @brief Helper variable template.
  604. * @tparam Type The type of which to return the size.
  605. */
  606. template<typename Type>
  607. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  608. /**
  609. * @brief Using declaration to be used to _repeat_ the same type a number of
  610. * times equal to the size of a given parameter pack.
  611. * @tparam Type A type to repeat.
  612. */
  613. template<typename Type, typename>
  614. using unpack_as_type = Type;
  615. /**
  616. * @brief Helper variable template to be used to _repeat_ the same value a
  617. * number of times equal to the size of a given parameter pack.
  618. * @tparam Value A value to repeat.
  619. */
  620. template<auto Value, typename>
  621. inline constexpr auto unpack_as_value = Value;
  622. /**
  623. * @brief Wraps a static constant.
  624. * @tparam Value A static constant.
  625. */
  626. template<auto Value>
  627. using integral_constant = std::integral_constant<decltype(Value), Value>;
  628. /**
  629. * @brief Alias template to facilitate the creation of named values.
  630. * @tparam Value A constant value at least convertible to `id_type`.
  631. */
  632. template<id_type Value>
  633. using tag = integral_constant<Value>;
  634. /**
  635. * @brief A class to use to push around lists of types, nothing more.
  636. * @tparam Type Types provided by the type list.
  637. */
  638. template<typename... Type>
  639. struct type_list {
  640. /*! @brief Type list type. */
  641. using type = type_list;
  642. /*! @brief Compile-time number of elements in the type list. */
  643. static constexpr auto size = sizeof...(Type);
  644. };
  645. /*! @brief Primary template isn't defined on purpose. */
  646. template<std::size_t, typename>
  647. struct type_list_element;
  648. /**
  649. * @brief Provides compile-time indexed access to the types of a type list.
  650. * @tparam Index Index of the type to return.
  651. * @tparam First First type provided by the type list.
  652. * @tparam Other Other types provided by the type list.
  653. */
  654. template<std::size_t Index, typename First, typename... Other>
  655. struct type_list_element<Index, type_list<First, Other...>>
  656. : type_list_element<Index - 1u, type_list<Other...>> {};
  657. /**
  658. * @brief Provides compile-time indexed access to the types of a type list.
  659. * @tparam First First type provided by the type list.
  660. * @tparam Other Other types provided by the type list.
  661. */
  662. template<typename First, typename... Other>
  663. struct type_list_element<0u, type_list<First, Other...>> {
  664. /*! @brief Searched type. */
  665. using type = First;
  666. };
  667. /**
  668. * @brief Helper type.
  669. * @tparam Index Index of the type to return.
  670. * @tparam List Type list to search into.
  671. */
  672. template<std::size_t Index, typename List>
  673. using type_list_element_t = typename type_list_element<Index, List>::type;
  674. /*! @brief Primary template isn't defined on purpose. */
  675. template<typename, typename>
  676. struct type_list_index;
  677. /**
  678. * @brief Provides compile-time type access to the types of a type list.
  679. * @tparam Type Type to look for and for which to return the index.
  680. * @tparam First First type provided by the type list.
  681. * @tparam Other Other types provided by the type list.
  682. */
  683. template<typename Type, typename First, typename... Other>
  684. struct type_list_index<Type, type_list<First, Other...>> {
  685. /*! @brief Unsigned integer type. */
  686. using value_type = std::size_t;
  687. /*! @brief Compile-time position of the given type in the sublist. */
  688. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  689. };
  690. /**
  691. * @brief Provides compile-time type access to the types of a type list.
  692. * @tparam Type Type to look for and for which to return the index.
  693. * @tparam Other Other types provided by the type list.
  694. */
  695. template<typename Type, typename... Other>
  696. struct type_list_index<Type, type_list<Type, Other...>> {
  697. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  698. /*! @brief Unsigned integer type. */
  699. using value_type = std::size_t;
  700. /*! @brief Compile-time position of the given type in the sublist. */
  701. static constexpr value_type value = 0u;
  702. };
  703. /**
  704. * @brief Provides compile-time type access to the types of a type list.
  705. * @tparam Type Type to look for and for which to return the index.
  706. */
  707. template<typename Type>
  708. struct type_list_index<Type, type_list<>> {
  709. /*! @brief Unsigned integer type. */
  710. using value_type = std::size_t;
  711. /*! @brief Compile-time position of the given type in the sublist. */
  712. static constexpr value_type value = 0u;
  713. };
  714. /**
  715. * @brief Helper variable template.
  716. * @tparam List Type list.
  717. * @tparam Type Type to look for and for which to return the index.
  718. */
  719. template<typename Type, typename List>
  720. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  721. /**
  722. * @brief Concatenates multiple type lists.
  723. * @tparam Type Types provided by the first type list.
  724. * @tparam Other Types provided by the second type list.
  725. * @return A type list composed by the types of both the type lists.
  726. */
  727. template<typename... Type, typename... Other>
  728. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  729. return {};
  730. }
  731. /*! @brief Primary template isn't defined on purpose. */
  732. template<typename...>
  733. struct type_list_cat;
  734. /*! @brief Concatenates multiple type lists. */
  735. template<>
  736. struct type_list_cat<> {
  737. /*! @brief A type list composed by the types of all the type lists. */
  738. using type = type_list<>;
  739. };
  740. /**
  741. * @brief Concatenates multiple type lists.
  742. * @tparam Type Types provided by the first type list.
  743. * @tparam Other Types provided by the second type list.
  744. * @tparam List Other type lists, if any.
  745. */
  746. template<typename... Type, typename... Other, typename... List>
  747. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  748. /*! @brief A type list composed by the types of all the type lists. */
  749. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  750. };
  751. /**
  752. * @brief Concatenates multiple type lists.
  753. * @tparam Type Types provided by the type list.
  754. */
  755. template<typename... Type>
  756. struct type_list_cat<type_list<Type...>> {
  757. /*! @brief A type list composed by the types of all the type lists. */
  758. using type = type_list<Type...>;
  759. };
  760. /**
  761. * @brief Helper type.
  762. * @tparam List Type lists to concatenate.
  763. */
  764. template<typename... List>
  765. using type_list_cat_t = typename type_list_cat<List...>::type;
  766. /*! @cond TURN_OFF_DOXYGEN */
  767. namespace internal {
  768. template<typename...>
  769. struct type_list_unique;
  770. template<typename First, typename... Other, typename... Type>
  771. struct type_list_unique<type_list<First, Other...>, Type...>
  772. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  773. template<typename... Type>
  774. struct type_list_unique<type_list<>, Type...> {
  775. using type = type_list<Type...>;
  776. };
  777. } // namespace internal
  778. /*! @endcond */
  779. /**
  780. * @brief Removes duplicates types from a type list.
  781. * @tparam List Type list.
  782. */
  783. template<typename List>
  784. struct type_list_unique {
  785. /*! @brief A type list without duplicate types. */
  786. using type = typename internal::type_list_unique<List>::type;
  787. };
  788. /**
  789. * @brief Helper type.
  790. * @tparam List Type list.
  791. */
  792. template<typename List>
  793. using type_list_unique_t = typename type_list_unique<List>::type;
  794. /**
  795. * @brief Provides the member constant `value` to true if a type list contains a
  796. * given type, false otherwise.
  797. * @tparam List Type list.
  798. * @tparam Type Type to look for.
  799. */
  800. template<typename List, typename Type>
  801. struct type_list_contains;
  802. /**
  803. * @copybrief type_list_contains
  804. * @tparam Type Types provided by the type list.
  805. * @tparam Other Type to look for.
  806. */
  807. template<typename... Type, typename Other>
  808. struct type_list_contains<type_list<Type...>, Other>
  809. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  810. /**
  811. * @brief Helper variable template.
  812. * @tparam List Type list.
  813. * @tparam Type Type to look for.
  814. */
  815. template<typename List, typename Type>
  816. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  817. /*! @brief Primary template isn't defined on purpose. */
  818. template<typename...>
  819. struct type_list_diff;
  820. /**
  821. * @brief Computes the difference between two type lists.
  822. * @tparam Type Types provided by the first type list.
  823. * @tparam Other Types provided by the second type list.
  824. */
  825. template<typename... Type, typename... Other>
  826. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  827. /*! @brief A type list that is the difference between the two type lists. */
  828. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  829. };
  830. /**
  831. * @brief Helper type.
  832. * @tparam List Type lists between which to compute the difference.
  833. */
  834. template<typename... List>
  835. using type_list_diff_t = typename type_list_diff<List...>::type;
  836. /*! @brief Primary template isn't defined on purpose. */
  837. template<typename, template<typename...> class>
  838. struct type_list_transform;
  839. /**
  840. * @brief Applies a given _function_ to a type list and generate a new list.
  841. * @tparam Type Types provided by the type list.
  842. * @tparam Op Unary operation as template class with a type member named `type`.
  843. */
  844. template<typename... Type, template<typename...> class Op>
  845. struct type_list_transform<type_list<Type...>, Op> {
  846. /*! @brief Resulting type list after applying the transform function. */
  847. // NOLINTNEXTLINE(modernize-type-traits)
  848. using type = type_list<typename Op<Type>::type...>;
  849. };
  850. /**
  851. * @brief Helper type.
  852. * @tparam List Type list.
  853. * @tparam Op Unary operation as template class with a type member named `type`.
  854. */
  855. template<typename List, template<typename...> class Op>
  856. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  857. /**
  858. * @brief A class to use to push around lists of constant values, nothing more.
  859. * @tparam Value Values provided by the value list.
  860. */
  861. template<auto... Value>
  862. struct value_list {
  863. /*! @brief Value list type. */
  864. using type = value_list;
  865. /*! @brief Compile-time number of elements in the value list. */
  866. static constexpr auto size = sizeof...(Value);
  867. };
  868. /*! @brief Primary template isn't defined on purpose. */
  869. template<std::size_t, typename>
  870. struct value_list_element;
  871. /**
  872. * @brief Provides compile-time indexed access to the values of a value list.
  873. * @tparam Index Index of the value to return.
  874. * @tparam Value First value provided by the value list.
  875. * @tparam Other Other values provided by the value list.
  876. */
  877. template<std::size_t Index, auto Value, auto... Other>
  878. struct value_list_element<Index, value_list<Value, Other...>>
  879. : value_list_element<Index - 1u, value_list<Other...>> {};
  880. /**
  881. * @brief Provides compile-time indexed access to the types of a type list.
  882. * @tparam Value First value provided by the value list.
  883. * @tparam Other Other values provided by the value list.
  884. */
  885. template<auto Value, auto... Other>
  886. struct value_list_element<0u, value_list<Value, Other...>> {
  887. /*! @brief Searched type. */
  888. using type = decltype(Value);
  889. /*! @brief Searched value. */
  890. static constexpr auto value = Value;
  891. };
  892. /**
  893. * @brief Helper type.
  894. * @tparam Index Index of the type to return.
  895. * @tparam List Value list to search into.
  896. */
  897. template<std::size_t Index, typename List>
  898. using value_list_element_t = typename value_list_element<Index, List>::type;
  899. /**
  900. * @brief Helper type.
  901. * @tparam Index Index of the value to return.
  902. * @tparam List Value list to search into.
  903. */
  904. template<std::size_t Index, typename List>
  905. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  906. /*! @brief Primary template isn't defined on purpose. */
  907. template<auto, typename>
  908. struct value_list_index;
  909. /**
  910. * @brief Provides compile-time type access to the values of a value list.
  911. * @tparam Value Value to look for and for which to return the index.
  912. * @tparam First First value provided by the value list.
  913. * @tparam Other Other values provided by the value list.
  914. */
  915. template<auto Value, auto First, auto... Other>
  916. struct value_list_index<Value, value_list<First, Other...>> {
  917. /*! @brief Unsigned integer type. */
  918. using value_type = std::size_t;
  919. /*! @brief Compile-time position of the given value in the sublist. */
  920. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  921. };
  922. /**
  923. * @brief Provides compile-time type access to the values of a value list.
  924. * @tparam Value Value to look for and for which to return the index.
  925. * @tparam Other Other values provided by the value list.
  926. */
  927. template<auto Value, auto... Other>
  928. struct value_list_index<Value, value_list<Value, Other...>> {
  929. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  930. /*! @brief Unsigned integer type. */
  931. using value_type = std::size_t;
  932. /*! @brief Compile-time position of the given value in the sublist. */
  933. static constexpr value_type value = 0u;
  934. };
  935. /**
  936. * @brief Provides compile-time type access to the values of a value list.
  937. * @tparam Value Value to look for and for which to return the index.
  938. */
  939. template<auto Value>
  940. struct value_list_index<Value, value_list<>> {
  941. /*! @brief Unsigned integer type. */
  942. using value_type = std::size_t;
  943. /*! @brief Compile-time position of the given type in the sublist. */
  944. static constexpr value_type value = 0u;
  945. };
  946. /**
  947. * @brief Helper variable template.
  948. * @tparam List Value list.
  949. * @tparam Value Value to look for and for which to return the index.
  950. */
  951. template<auto Value, typename List>
  952. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  953. /**
  954. * @brief Concatenates multiple value lists.
  955. * @tparam Value Values provided by the first value list.
  956. * @tparam Other Values provided by the second value list.
  957. * @return A value list composed by the values of both the value lists.
  958. */
  959. template<auto... Value, auto... Other>
  960. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  961. return {};
  962. }
  963. /*! @brief Primary template isn't defined on purpose. */
  964. template<typename...>
  965. struct value_list_cat;
  966. /*! @brief Concatenates multiple value lists. */
  967. template<>
  968. struct value_list_cat<> {
  969. /*! @brief A value list composed by the values of all the value lists. */
  970. using type = value_list<>;
  971. };
  972. /**
  973. * @brief Concatenates multiple value lists.
  974. * @tparam Value Values provided by the first value list.
  975. * @tparam Other Values provided by the second value list.
  976. * @tparam List Other value lists, if any.
  977. */
  978. template<auto... Value, auto... Other, typename... List>
  979. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  980. /*! @brief A value list composed by the values of all the value lists. */
  981. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  982. };
  983. /**
  984. * @brief Concatenates multiple value lists.
  985. * @tparam Value Values provided by the value list.
  986. */
  987. template<auto... Value>
  988. struct value_list_cat<value_list<Value...>> {
  989. /*! @brief A value list composed by the values of all the value lists. */
  990. using type = value_list<Value...>;
  991. };
  992. /**
  993. * @brief Helper type.
  994. * @tparam List Value lists to concatenate.
  995. */
  996. template<typename... List>
  997. using value_list_cat_t = typename value_list_cat<List...>::type;
  998. /*! @brief Primary template isn't defined on purpose. */
  999. template<typename>
  1000. struct value_list_unique;
  1001. /**
  1002. * @brief Removes duplicates values from a value list.
  1003. * @tparam Value One of the values provided by the given value list.
  1004. * @tparam Other The other values provided by the given value list.
  1005. */
  1006. template<auto Value, auto... Other>
  1007. struct value_list_unique<value_list<Value, Other...>> {
  1008. /*! @brief A value list without duplicate types. */
  1009. using type = std::conditional_t<
  1010. ((Value == Other) || ...),
  1011. typename value_list_unique<value_list<Other...>>::type,
  1012. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  1013. };
  1014. /*! @brief Removes duplicates values from a value list. */
  1015. template<>
  1016. struct value_list_unique<value_list<>> {
  1017. /*! @brief A value list without duplicate types. */
  1018. using type = value_list<>;
  1019. };
  1020. /**
  1021. * @brief Helper type.
  1022. * @tparam Type A value list.
  1023. */
  1024. template<typename Type>
  1025. using value_list_unique_t = typename value_list_unique<Type>::type;
  1026. /**
  1027. * @brief Provides the member constant `value` to true if a value list contains
  1028. * a given value, false otherwise.
  1029. * @tparam List Value list.
  1030. * @tparam Value Value to look for.
  1031. */
  1032. template<typename List, auto Value>
  1033. struct value_list_contains;
  1034. /**
  1035. * @copybrief value_list_contains
  1036. * @tparam Value Values provided by the value list.
  1037. * @tparam Other Value to look for.
  1038. */
  1039. template<auto... Value, auto Other>
  1040. struct value_list_contains<value_list<Value...>, Other>
  1041. : std::bool_constant<((Value == Other) || ...)> {};
  1042. /**
  1043. * @brief Helper variable template.
  1044. * @tparam List Value list.
  1045. * @tparam Value Value to look for.
  1046. */
  1047. template<typename List, auto Value>
  1048. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  1049. /*! @brief Primary template isn't defined on purpose. */
  1050. template<typename...>
  1051. struct value_list_diff;
  1052. /**
  1053. * @brief Computes the difference between two value lists.
  1054. * @tparam Value Values provided by the first value list.
  1055. * @tparam Other Values provided by the second value list.
  1056. */
  1057. template<auto... Value, auto... Other>
  1058. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  1059. /*! @brief A value list that is the difference between the two value lists. */
  1060. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  1061. };
  1062. /**
  1063. * @brief Helper type.
  1064. * @tparam List Value lists between which to compute the difference.
  1065. */
  1066. template<typename... List>
  1067. using value_list_diff_t = typename value_list_diff<List...>::type;
  1068. /*! @brief Same as std::is_invocable, but with tuples. */
  1069. template<typename, typename>
  1070. struct is_applicable: std::false_type {};
  1071. /**
  1072. * @copybrief is_applicable
  1073. * @tparam Func A valid function type.
  1074. * @tparam Tuple Tuple-like type.
  1075. * @tparam Args The list of arguments to use to probe the function type.
  1076. */
  1077. template<typename Func, template<typename...> class Tuple, typename... Args>
  1078. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  1079. /**
  1080. * @copybrief is_applicable
  1081. * @tparam Func A valid function type.
  1082. * @tparam Tuple Tuple-like type.
  1083. * @tparam Args The list of arguments to use to probe the function type.
  1084. */
  1085. template<typename Func, template<typename...> class Tuple, typename... Args>
  1086. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  1087. /**
  1088. * @brief Helper variable template.
  1089. * @tparam Func A valid function type.
  1090. * @tparam Args The list of arguments to use to probe the function type.
  1091. */
  1092. template<typename Func, typename Args>
  1093. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  1094. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  1095. template<typename, typename, typename>
  1096. struct is_applicable_r: std::false_type {};
  1097. /**
  1098. * @copybrief is_applicable_r
  1099. * @tparam Ret The type to which the return type of the function should be
  1100. * convertible.
  1101. * @tparam Func A valid function type.
  1102. * @tparam Args The list of arguments to use to probe the function type.
  1103. */
  1104. template<typename Ret, typename Func, typename... Args>
  1105. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  1106. /**
  1107. * @brief Helper variable template.
  1108. * @tparam Ret The type to which the return type of the function should be
  1109. * convertible.
  1110. * @tparam Func A valid function type.
  1111. * @tparam Args The list of arguments to use to probe the function type.
  1112. */
  1113. template<typename Ret, typename Func, typename Args>
  1114. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  1115. /**
  1116. * @brief Provides the member constant `value` to true if a given type is
  1117. * complete, false otherwise.
  1118. * @tparam Type The type to test.
  1119. */
  1120. template<typename Type, typename = void>
  1121. struct is_complete: std::false_type {};
  1122. /*! @copydoc is_complete */
  1123. template<typename Type>
  1124. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  1125. /**
  1126. * @brief Helper variable template.
  1127. * @tparam Type The type to test.
  1128. */
  1129. template<typename Type>
  1130. inline constexpr bool is_complete_v = is_complete<Type>::value;
  1131. /**
  1132. * @brief Provides the member constant `value` to true if a given type is an
  1133. * iterator, false otherwise.
  1134. * @tparam Type The type to test.
  1135. */
  1136. template<typename Type, typename = void>
  1137. struct is_iterator: std::false_type {};
  1138. /*! @cond TURN_OFF_DOXYGEN */
  1139. namespace internal {
  1140. template<typename, typename = void>
  1141. struct has_iterator_category: std::false_type {};
  1142. template<typename Type>
  1143. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  1144. } // namespace internal
  1145. /*! @endcond */
  1146. /*! @copydoc is_iterator */
  1147. template<typename Type>
  1148. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  1149. : internal::has_iterator_category<Type> {};
  1150. /**
  1151. * @brief Helper variable template.
  1152. * @tparam Type The type to test.
  1153. */
  1154. template<typename Type>
  1155. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  1156. /**
  1157. * @brief Provides the member constant `value` to true if a given type is both
  1158. * an empty and non-final class, false otherwise.
  1159. * @tparam Type The type to test
  1160. */
  1161. template<typename Type>
  1162. struct is_ebco_eligible
  1163. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  1164. /**
  1165. * @brief Helper variable template.
  1166. * @tparam Type The type to test.
  1167. */
  1168. template<typename Type>
  1169. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  1170. /**
  1171. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  1172. * is valid and denotes a type, false otherwise.
  1173. * @tparam Type The type to test.
  1174. */
  1175. template<typename Type, typename = void>
  1176. struct is_transparent: std::false_type {};
  1177. /*! @copydoc is_transparent */
  1178. template<typename Type>
  1179. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  1180. /**
  1181. * @brief Helper variable template.
  1182. * @tparam Type The type to test.
  1183. */
  1184. template<typename Type>
  1185. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  1186. /*! @cond TURN_OFF_DOXYGEN */
  1187. namespace internal {
  1188. template<typename, typename = void>
  1189. struct has_tuple_size_value: std::false_type {};
  1190. template<typename Type>
  1191. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  1192. template<typename, typename = void>
  1193. struct has_value_type: std::false_type {};
  1194. template<typename Type>
  1195. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  1196. template<typename>
  1197. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  1198. template<typename Type, std::size_t... Index>
  1199. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  1200. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  1201. }
  1202. template<typename>
  1203. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  1204. return false;
  1205. }
  1206. template<typename Type>
  1207. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  1208. return true;
  1209. }
  1210. template<typename Type>
  1211. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  1212. // NOLINTBEGIN(modernize-use-transparent-functors)
  1213. if constexpr(std::is_array_v<Type>) {
  1214. return false;
  1215. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  1216. if constexpr(has_tuple_size_value<Type>::value) {
  1217. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  1218. } else {
  1219. return maybe_equality_comparable<Type>(0);
  1220. }
  1221. } else if constexpr(has_value_type<Type>::value) {
  1222. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  1223. return maybe_equality_comparable<Type>(0);
  1224. } else {
  1225. return false;
  1226. }
  1227. } else {
  1228. return maybe_equality_comparable<Type>(0);
  1229. }
  1230. // NOLINTEND(modernize-use-transparent-functors)
  1231. }
  1232. } // namespace internal
  1233. /*! @endcond */
  1234. /**
  1235. * @brief Provides the member constant `value` to true if a given type is
  1236. * equality comparable, false otherwise.
  1237. * @tparam Type The type to test.
  1238. */
  1239. template<typename Type>
  1240. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  1241. /*! @copydoc is_equality_comparable */
  1242. template<typename Type>
  1243. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  1244. /**
  1245. * @brief Helper variable template.
  1246. * @tparam Type The type to test.
  1247. */
  1248. template<typename Type>
  1249. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  1250. /**
  1251. * @brief Transcribes the constness of a type to another type.
  1252. * @tparam To The type to which to transcribe the constness.
  1253. * @tparam From The type from which to transcribe the constness.
  1254. */
  1255. template<typename To, typename From>
  1256. struct constness_as {
  1257. /*! @brief The type resulting from the transcription of the constness. */
  1258. using type = std::remove_const_t<To>;
  1259. };
  1260. /*! @copydoc constness_as */
  1261. template<typename To, typename From>
  1262. struct constness_as<To, const From> {
  1263. /*! @brief The type resulting from the transcription of the constness. */
  1264. using type = const To;
  1265. };
  1266. /**
  1267. * @brief Alias template to facilitate the transcription of the constness.
  1268. * @tparam To The type to which to transcribe the constness.
  1269. * @tparam From The type from which to transcribe the constness.
  1270. */
  1271. template<typename To, typename From>
  1272. using constness_as_t = typename constness_as<To, From>::type;
  1273. /**
  1274. * @brief Extracts the class of a non-static member object or function.
  1275. * @tparam Member A pointer to a non-static member object or function.
  1276. */
  1277. template<typename Member>
  1278. class member_class {
  1279. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  1280. template<typename Class, typename Ret, typename... Args>
  1281. static Class *clazz(Ret (Class::*)(Args...));
  1282. template<typename Class, typename Ret, typename... Args>
  1283. static Class *clazz(Ret (Class::*)(Args...) const);
  1284. template<typename Class, typename Type>
  1285. static Class *clazz(Type Class::*);
  1286. public:
  1287. /*! @brief The class of the given non-static member object or function. */
  1288. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  1289. };
  1290. /**
  1291. * @brief Helper type.
  1292. * @tparam Member A pointer to a non-static member object or function.
  1293. */
  1294. template<typename Member>
  1295. using member_class_t = typename member_class<Member>::type;
  1296. /**
  1297. * @brief Extracts the n-th argument of a _callable_ type.
  1298. * @tparam Index The index of the argument to extract.
  1299. * @tparam Candidate A valid _callable_ type.
  1300. */
  1301. template<std::size_t Index, typename Candidate>
  1302. class nth_argument {
  1303. template<typename Ret, typename... Args>
  1304. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  1305. template<typename Ret, typename Class, typename... Args>
  1306. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  1307. template<typename Ret, typename Class, typename... Args>
  1308. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  1309. template<typename Type, typename Class>
  1310. static constexpr type_list<Type> pick_up(Type Class ::*);
  1311. template<typename Type>
  1312. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  1313. public:
  1314. /*! @brief N-th argument of the _callable_ type. */
  1315. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  1316. };
  1317. /**
  1318. * @brief Helper type.
  1319. * @tparam Index The index of the argument to extract.
  1320. * @tparam Candidate A valid function, member function or data member type.
  1321. */
  1322. template<std::size_t Index, typename Candidate>
  1323. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  1324. } // namespace entt
  1325. template<typename... Type>
  1326. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  1327. template<std::size_t Index, typename... Type>
  1328. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  1329. template<auto... Value>
  1330. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  1331. template<std::size_t Index, auto... Value>
  1332. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  1333. #endif
  1334. namespace entt {
  1335. /*! @cond TURN_OFF_DOXYGEN */
  1336. namespace internal {
  1337. template<typename Type, std::size_t, typename = void>
  1338. struct compressed_pair_element {
  1339. using reference = Type &;
  1340. using const_reference = const Type &;
  1341. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  1342. // NOLINTNEXTLINE(modernize-use-equals-default)
  1343. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  1344. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  1345. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  1346. : value{std::forward<Arg>(arg)} {}
  1347. template<typename... Args, std::size_t... Index>
  1348. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  1349. : value{std::forward<Args>(std::get<Index>(args))...} {}
  1350. [[nodiscard]] constexpr reference get() noexcept {
  1351. return value;
  1352. }
  1353. [[nodiscard]] constexpr const_reference get() const noexcept {
  1354. return value;
  1355. }
  1356. private:
  1357. Type value{};
  1358. };
  1359. template<typename Type, std::size_t Tag>
  1360. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  1361. using reference = Type &;
  1362. using const_reference = const Type &;
  1363. using base_type = Type;
  1364. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  1365. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  1366. : base_type{} {}
  1367. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  1368. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  1369. : base_type{std::forward<Arg>(arg)} {}
  1370. template<typename... Args, std::size_t... Index>
  1371. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  1372. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  1373. [[nodiscard]] constexpr reference get() noexcept {
  1374. return *this;
  1375. }
  1376. [[nodiscard]] constexpr const_reference get() const noexcept {
  1377. return *this;
  1378. }
  1379. };
  1380. } // namespace internal
  1381. /*! @endcond */
  1382. /**
  1383. * @brief A compressed pair.
  1384. *
  1385. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  1386. * reduce its final size to a minimum.
  1387. *
  1388. * @tparam First The type of the first element that the pair stores.
  1389. * @tparam Second The type of the second element that the pair stores.
  1390. */
  1391. template<typename First, typename Second>
  1392. class compressed_pair final
  1393. : internal::compressed_pair_element<First, 0u>,
  1394. internal::compressed_pair_element<Second, 1u> {
  1395. using first_base = internal::compressed_pair_element<First, 0u>;
  1396. using second_base = internal::compressed_pair_element<Second, 1u>;
  1397. public:
  1398. /*! @brief The type of the first element that the pair stores. */
  1399. using first_type = First;
  1400. /*! @brief The type of the second element that the pair stores. */
  1401. using second_type = Second;
  1402. /**
  1403. * @brief Default constructor, conditionally enabled.
  1404. *
  1405. * This constructor is only available when the types that the pair stores
  1406. * are both at least default constructible.
  1407. *
  1408. * @tparam Dummy Dummy template parameter used for internal purposes.
  1409. */
  1410. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  1411. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  1412. : first_base{},
  1413. second_base{} {}
  1414. /**
  1415. * @brief Copy constructor.
  1416. * @param other The instance to copy from.
  1417. */
  1418. constexpr compressed_pair(const compressed_pair &other) = default;
  1419. /**
  1420. * @brief Move constructor.
  1421. * @param other The instance to move from.
  1422. */
  1423. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  1424. /**
  1425. * @brief Constructs a pair from its values.
  1426. * @tparam Arg Type of value to use to initialize the first element.
  1427. * @tparam Other Type of value to use to initialize the second element.
  1428. * @param arg Value to use to initialize the first element.
  1429. * @param other Value to use to initialize the second element.
  1430. */
  1431. template<typename Arg, typename Other>
  1432. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  1433. : first_base{std::forward<Arg>(arg)},
  1434. second_base{std::forward<Other>(other)} {}
  1435. /**
  1436. * @brief Constructs a pair by forwarding the arguments to its parts.
  1437. * @tparam Args Types of arguments to use to initialize the first element.
  1438. * @tparam Other Types of arguments to use to initialize the second element.
  1439. * @param args Arguments to use to initialize the first element.
  1440. * @param other Arguments to use to initialize the second element.
  1441. */
  1442. template<typename... Args, typename... Other>
  1443. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  1444. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  1445. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  1446. /*! @brief Default destructor. */
  1447. ~compressed_pair() = default;
  1448. /**
  1449. * @brief Copy assignment operator.
  1450. * @param other The instance to copy from.
  1451. * @return This compressed pair object.
  1452. */
  1453. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  1454. /**
  1455. * @brief Move assignment operator.
  1456. * @param other The instance to move from.
  1457. * @return This compressed pair object.
  1458. */
  1459. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  1460. /**
  1461. * @brief Returns the first element that a pair stores.
  1462. * @return The first element that a pair stores.
  1463. */
  1464. [[nodiscard]] constexpr first_type &first() noexcept {
  1465. return static_cast<first_base &>(*this).get();
  1466. }
  1467. /*! @copydoc first */
  1468. [[nodiscard]] constexpr const first_type &first() const noexcept {
  1469. return static_cast<const first_base &>(*this).get();
  1470. }
  1471. /**
  1472. * @brief Returns the second element that a pair stores.
  1473. * @return The second element that a pair stores.
  1474. */
  1475. [[nodiscard]] constexpr second_type &second() noexcept {
  1476. return static_cast<second_base &>(*this).get();
  1477. }
  1478. /*! @copydoc second */
  1479. [[nodiscard]] constexpr const second_type &second() const noexcept {
  1480. return static_cast<const second_base &>(*this).get();
  1481. }
  1482. /**
  1483. * @brief Swaps two compressed pair objects.
  1484. * @param other The compressed pair to swap with.
  1485. */
  1486. constexpr void swap(compressed_pair &other) noexcept {
  1487. using std::swap;
  1488. swap(first(), other.first());
  1489. swap(second(), other.second());
  1490. }
  1491. /**
  1492. * @brief Extracts an element from the compressed pair.
  1493. * @tparam Index An integer value that is either 0 or 1.
  1494. * @return Returns a reference to the first element if `Index` is 0 and a
  1495. * reference to the second element if `Index` is 1.
  1496. */
  1497. template<std::size_t Index>
  1498. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  1499. if constexpr(Index == 0u) {
  1500. return first();
  1501. } else {
  1502. static_assert(Index == 1u, "Index out of bounds");
  1503. return second();
  1504. }
  1505. }
  1506. /*! @copydoc get */
  1507. template<std::size_t Index>
  1508. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  1509. if constexpr(Index == 0u) {
  1510. return first();
  1511. } else {
  1512. static_assert(Index == 1u, "Index out of bounds");
  1513. return second();
  1514. }
  1515. }
  1516. };
  1517. /**
  1518. * @brief Deduction guide.
  1519. * @tparam Type Type of value to use to initialize the first element.
  1520. * @tparam Other Type of value to use to initialize the second element.
  1521. */
  1522. template<typename Type, typename Other>
  1523. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  1524. /**
  1525. * @brief Swaps two compressed pair objects.
  1526. * @tparam First The type of the first element that the pairs store.
  1527. * @tparam Second The type of the second element that the pairs store.
  1528. * @param lhs A valid compressed pair object.
  1529. * @param rhs A valid compressed pair object.
  1530. */
  1531. template<typename First, typename Second>
  1532. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  1533. lhs.swap(rhs);
  1534. }
  1535. } // namespace entt
  1536. namespace std {
  1537. /**
  1538. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  1539. * @tparam First The type of the first element that the pair stores.
  1540. * @tparam Second The type of the second element that the pair stores.
  1541. */
  1542. template<typename First, typename Second>
  1543. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  1544. /**
  1545. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  1546. * @tparam Index The index of the type to return.
  1547. * @tparam First The type of the first element that the pair stores.
  1548. * @tparam Second The type of the second element that the pair stores.
  1549. */
  1550. template<size_t Index, typename First, typename Second>
  1551. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  1552. static_assert(Index < 2u, "Index out of bounds");
  1553. };
  1554. } // namespace std
  1555. #endif
  1556. // #include "../core/iterator.hpp"
  1557. #ifndef ENTT_CORE_ITERATOR_HPP
  1558. #define ENTT_CORE_ITERATOR_HPP
  1559. #include <iterator>
  1560. #include <memory>
  1561. #include <type_traits>
  1562. #include <utility>
  1563. namespace entt {
  1564. /**
  1565. * @brief Helper type to use as pointer with input iterators.
  1566. * @tparam Type of wrapped value.
  1567. */
  1568. template<typename Type>
  1569. struct input_iterator_pointer final {
  1570. /*! @brief Value type. */
  1571. using value_type = Type;
  1572. /*! @brief Pointer type. */
  1573. using pointer = Type *;
  1574. /*! @brief Reference type. */
  1575. using reference = Type &;
  1576. /**
  1577. * @brief Constructs a proxy object by move.
  1578. * @param val Value to use to initialize the proxy object.
  1579. */
  1580. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  1581. : value{std::move(val)} {}
  1582. /**
  1583. * @brief Access operator for accessing wrapped values.
  1584. * @return A pointer to the wrapped value.
  1585. */
  1586. [[nodiscard]] constexpr pointer operator->() noexcept {
  1587. return std::addressof(value);
  1588. }
  1589. /**
  1590. * @brief Dereference operator for accessing wrapped values.
  1591. * @return A reference to the wrapped value.
  1592. */
  1593. [[nodiscard]] constexpr reference operator*() noexcept {
  1594. return value;
  1595. }
  1596. private:
  1597. Type value;
  1598. };
  1599. /**
  1600. * @brief Plain iota iterator (waiting for C++20).
  1601. * @tparam Type Value type.
  1602. */
  1603. template<typename Type>
  1604. class iota_iterator final {
  1605. static_assert(std::is_integral_v<Type>, "Not an integral type");
  1606. public:
  1607. /*! @brief Value type, likely an integral one. */
  1608. using value_type = Type;
  1609. /*! @brief Invalid pointer type. */
  1610. using pointer = void;
  1611. /*! @brief Non-reference type, same as value type. */
  1612. using reference = value_type;
  1613. /*! @brief Difference type. */
  1614. using difference_type = std::ptrdiff_t;
  1615. /*! @brief Iterator category. */
  1616. using iterator_category = std::input_iterator_tag;
  1617. /*! @brief Default constructor. */
  1618. constexpr iota_iterator() noexcept
  1619. : current{} {}
  1620. /**
  1621. * @brief Constructs an iota iterator from a given value.
  1622. * @param init The initial value assigned to the iota iterator.
  1623. */
  1624. constexpr iota_iterator(const value_type init) noexcept
  1625. : current{init} {}
  1626. /**
  1627. * @brief Pre-increment operator.
  1628. * @return This iota iterator.
  1629. */
  1630. constexpr iota_iterator &operator++() noexcept {
  1631. return ++current, *this;
  1632. }
  1633. /**
  1634. * @brief Post-increment operator.
  1635. * @return This iota iterator.
  1636. */
  1637. constexpr iota_iterator operator++(int) noexcept {
  1638. const iota_iterator orig = *this;
  1639. return ++(*this), orig;
  1640. }
  1641. /**
  1642. * @brief Dereference operator.
  1643. * @return The underlying value.
  1644. */
  1645. [[nodiscard]] constexpr reference operator*() const noexcept {
  1646. return current;
  1647. }
  1648. private:
  1649. value_type current;
  1650. };
  1651. /**
  1652. * @brief Comparison operator.
  1653. * @tparam Type Value type of the iota iterator.
  1654. * @param lhs A properly initialized iota iterator.
  1655. * @param rhs A properly initialized iota iterator.
  1656. * @return True if the two iterators are identical, false otherwise.
  1657. */
  1658. template<typename Type>
  1659. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  1660. return *lhs == *rhs;
  1661. }
  1662. /**
  1663. * @brief Comparison operator.
  1664. * @tparam Type Value type of the iota iterator.
  1665. * @param lhs A properly initialized iota iterator.
  1666. * @param rhs A properly initialized iota iterator.
  1667. * @return True if the two iterators differ, false otherwise.
  1668. */
  1669. template<typename Type>
  1670. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  1671. return !(lhs == rhs);
  1672. }
  1673. /**
  1674. * @brief Utility class to create an iterable object from a pair of iterators.
  1675. * @tparam It Type of iterator.
  1676. * @tparam Sentinel Type of sentinel.
  1677. */
  1678. template<typename It, typename Sentinel = It>
  1679. struct iterable_adaptor final {
  1680. /*! @brief Value type. */
  1681. using value_type = typename std::iterator_traits<It>::value_type;
  1682. /*! @brief Iterator type. */
  1683. using iterator = It;
  1684. /*! @brief Sentinel type. */
  1685. using sentinel = Sentinel;
  1686. /*! @brief Default constructor. */
  1687. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  1688. : first{},
  1689. last{} {}
  1690. /**
  1691. * @brief Creates an iterable object from a pair of iterators.
  1692. * @param from Begin iterator.
  1693. * @param to End iterator.
  1694. */
  1695. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  1696. : first{std::move(from)},
  1697. last{std::move(to)} {}
  1698. /**
  1699. * @brief Returns an iterator to the beginning.
  1700. * @return An iterator to the first element of the range.
  1701. */
  1702. [[nodiscard]] constexpr iterator begin() const noexcept {
  1703. return first;
  1704. }
  1705. /**
  1706. * @brief Returns an iterator to the end.
  1707. * @return An iterator to the element following the last element of the
  1708. * range.
  1709. */
  1710. [[nodiscard]] constexpr sentinel end() const noexcept {
  1711. return last;
  1712. }
  1713. /*! @copydoc begin */
  1714. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  1715. return begin();
  1716. }
  1717. /*! @copydoc end */
  1718. [[nodiscard]] constexpr sentinel cend() const noexcept {
  1719. return end();
  1720. }
  1721. private:
  1722. It first;
  1723. Sentinel last;
  1724. };
  1725. } // namespace entt
  1726. #endif
  1727. // #include "../core/memory.hpp"
  1728. #ifndef ENTT_CORE_MEMORY_HPP
  1729. #define ENTT_CORE_MEMORY_HPP
  1730. #include <cstddef>
  1731. #include <memory>
  1732. #include <tuple>
  1733. #include <type_traits>
  1734. #include <utility>
  1735. // #include "../config/config.h"
  1736. namespace entt {
  1737. /**
  1738. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  1739. * @tparam Type Pointer type.
  1740. * @param ptr Fancy or raw pointer.
  1741. * @return A raw pointer that represents the address of the original pointer.
  1742. */
  1743. template<typename Type>
  1744. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  1745. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  1746. return ptr;
  1747. } else {
  1748. return to_address(std::forward<Type>(ptr).operator->());
  1749. }
  1750. }
  1751. /**
  1752. * @brief Utility function to design allocation-aware containers.
  1753. * @tparam Allocator Type of allocator.
  1754. * @param lhs A valid allocator.
  1755. * @param rhs Another valid allocator.
  1756. */
  1757. template<typename Allocator>
  1758. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  1759. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  1760. lhs = rhs;
  1761. }
  1762. }
  1763. /**
  1764. * @brief Utility function to design allocation-aware containers.
  1765. * @tparam Allocator Type of allocator.
  1766. * @param lhs A valid allocator.
  1767. * @param rhs Another valid allocator.
  1768. */
  1769. template<typename Allocator>
  1770. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  1771. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  1772. lhs = std::move(rhs);
  1773. }
  1774. }
  1775. /**
  1776. * @brief Utility function to design allocation-aware containers.
  1777. * @tparam Allocator Type of allocator.
  1778. * @param lhs A valid allocator.
  1779. * @param rhs Another valid allocator.
  1780. */
  1781. template<typename Allocator>
  1782. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  1783. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  1784. using std::swap;
  1785. swap(lhs, rhs);
  1786. } else {
  1787. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  1788. }
  1789. }
  1790. /**
  1791. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  1792. * @tparam Allocator Type of allocator used to manage memory and elements.
  1793. */
  1794. template<typename Allocator>
  1795. struct allocation_deleter: private Allocator {
  1796. /*! @brief Allocator type. */
  1797. using allocator_type = Allocator;
  1798. /*! @brief Pointer type. */
  1799. using pointer = typename std::allocator_traits<Allocator>::pointer;
  1800. /**
  1801. * @brief Inherited constructors.
  1802. * @param alloc The allocator to use.
  1803. */
  1804. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  1805. : Allocator{alloc} {}
  1806. /**
  1807. * @brief Destroys the pointed object and deallocates its memory.
  1808. * @param ptr A valid pointer to an object of the given type.
  1809. */
  1810. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  1811. using alloc_traits = std::allocator_traits<Allocator>;
  1812. alloc_traits::destroy(*this, to_address(ptr));
  1813. alloc_traits::deallocate(*this, ptr, 1u);
  1814. }
  1815. };
  1816. /**
  1817. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  1818. * @tparam Type Type of object to allocate for and to construct.
  1819. * @tparam Allocator Type of allocator used to manage memory and elements.
  1820. * @tparam Args Types of arguments to use to construct the object.
  1821. * @param allocator The allocator to use.
  1822. * @param args Parameters to use to construct the object.
  1823. * @return A properly initialized unique pointer with a custom deleter.
  1824. */
  1825. template<typename Type, typename Allocator, typename... Args>
  1826. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  1827. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  1828. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  1829. using allocator_type = typename alloc_traits::allocator_type;
  1830. allocator_type alloc{allocator};
  1831. auto ptr = alloc_traits::allocate(alloc, 1u);
  1832. ENTT_TRY {
  1833. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  1834. }
  1835. ENTT_CATCH {
  1836. alloc_traits::deallocate(alloc, ptr, 1u);
  1837. ENTT_THROW;
  1838. }
  1839. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  1840. }
  1841. /*! @cond TURN_OFF_DOXYGEN */
  1842. namespace internal {
  1843. template<typename Type>
  1844. struct uses_allocator_construction {
  1845. template<typename Allocator, typename... Params>
  1846. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  1847. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  1848. return std::forward_as_tuple(std::forward<Params>(params)...);
  1849. } else {
  1850. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  1851. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  1852. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  1853. } else {
  1854. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  1855. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  1856. }
  1857. }
  1858. }
  1859. };
  1860. template<typename Type, typename Other>
  1861. struct uses_allocator_construction<std::pair<Type, Other>> {
  1862. using type = std::pair<Type, Other>;
  1863. template<typename Allocator, typename First, typename Second>
  1864. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  1865. return std::make_tuple(
  1866. std::piecewise_construct,
  1867. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  1868. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  1869. }
  1870. template<typename Allocator>
  1871. static constexpr auto args(const Allocator &allocator) noexcept {
  1872. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  1873. }
  1874. template<typename Allocator, typename First, typename Second>
  1875. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  1876. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  1877. }
  1878. template<typename Allocator, typename First, typename Second>
  1879. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  1880. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  1881. }
  1882. template<typename Allocator, typename First, typename Second>
  1883. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  1884. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  1885. }
  1886. };
  1887. } // namespace internal
  1888. /*! @endcond */
  1889. /**
  1890. * @brief Uses-allocator construction utility (waiting for C++20).
  1891. *
  1892. * Primarily intended for internal use. Prepares the argument list needed to
  1893. * create an object of a given type by means of uses-allocator construction.
  1894. *
  1895. * @tparam Type Type to return arguments for.
  1896. * @tparam Allocator Type of allocator used to manage memory and elements.
  1897. * @tparam Args Types of arguments to use to construct the object.
  1898. * @param allocator The allocator to use.
  1899. * @param args Parameters to use to construct the object.
  1900. * @return The arguments needed to create an object of the given type.
  1901. */
  1902. template<typename Type, typename Allocator, typename... Args>
  1903. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  1904. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  1905. }
  1906. /**
  1907. * @brief Uses-allocator construction utility (waiting for C++20).
  1908. *
  1909. * Primarily intended for internal use. Creates an object of a given type by
  1910. * means of uses-allocator construction.
  1911. *
  1912. * @tparam Type Type of object to create.
  1913. * @tparam Allocator Type of allocator used to manage memory and elements.
  1914. * @tparam Args Types of arguments to use to construct the object.
  1915. * @param allocator The allocator to use.
  1916. * @param args Parameters to use to construct the object.
  1917. * @return A newly created object of the given type.
  1918. */
  1919. template<typename Type, typename Allocator, typename... Args>
  1920. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  1921. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  1922. }
  1923. /**
  1924. * @brief Uses-allocator construction utility (waiting for C++20).
  1925. *
  1926. * Primarily intended for internal use. Creates an object of a given type by
  1927. * means of uses-allocator construction at an uninitialized memory location.
  1928. *
  1929. * @tparam Type Type of object to create.
  1930. * @tparam Allocator Type of allocator used to manage memory and elements.
  1931. * @tparam Args Types of arguments to use to construct the object.
  1932. * @param value Memory location in which to place the object.
  1933. * @param allocator The allocator to use.
  1934. * @param args Parameters to use to construct the object.
  1935. * @return A pointer to the newly created object of the given type.
  1936. */
  1937. template<typename Type, typename Allocator, typename... Args>
  1938. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  1939. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  1940. }
  1941. } // namespace entt
  1942. #endif
  1943. // #include "../core/type_traits.hpp"
  1944. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  1945. #define ENTT_CORE_TYPE_TRAITS_HPP
  1946. #include <cstddef>
  1947. #include <iterator>
  1948. #include <tuple>
  1949. #include <type_traits>
  1950. #include <utility>
  1951. // #include "../config/config.h"
  1952. // #include "fwd.hpp"
  1953. namespace entt {
  1954. /**
  1955. * @brief Utility class to disambiguate overloaded functions.
  1956. * @tparam N Number of choices available.
  1957. */
  1958. template<std::size_t N>
  1959. struct choice_t
  1960. // unfortunately, doxygen cannot parse such a construct
  1961. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  1962. {};
  1963. /*! @copybrief choice_t */
  1964. template<>
  1965. struct choice_t<0> {};
  1966. /**
  1967. * @brief Variable template for the choice trick.
  1968. * @tparam N Number of choices available.
  1969. */
  1970. template<std::size_t N>
  1971. inline constexpr choice_t<N> choice{};
  1972. /**
  1973. * @brief Identity type trait.
  1974. *
  1975. * Useful to establish non-deduced contexts in template argument deduction
  1976. * (waiting for C++20) or to provide types through function arguments.
  1977. *
  1978. * @tparam Type A type.
  1979. */
  1980. template<typename Type>
  1981. struct type_identity {
  1982. /*! @brief Identity type. */
  1983. using type = Type;
  1984. };
  1985. /**
  1986. * @brief Helper type.
  1987. * @tparam Type A type.
  1988. */
  1989. template<typename Type>
  1990. using type_identity_t = typename type_identity<Type>::type;
  1991. /**
  1992. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  1993. * @tparam Type The type of which to return the size.
  1994. */
  1995. template<typename Type, typename = void>
  1996. struct size_of: std::integral_constant<std::size_t, 0u> {};
  1997. /*! @copydoc size_of */
  1998. template<typename Type>
  1999. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  2000. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  2001. : std::integral_constant<std::size_t, sizeof(Type)> {};
  2002. /**
  2003. * @brief Helper variable template.
  2004. * @tparam Type The type of which to return the size.
  2005. */
  2006. template<typename Type>
  2007. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  2008. /**
  2009. * @brief Using declaration to be used to _repeat_ the same type a number of
  2010. * times equal to the size of a given parameter pack.
  2011. * @tparam Type A type to repeat.
  2012. */
  2013. template<typename Type, typename>
  2014. using unpack_as_type = Type;
  2015. /**
  2016. * @brief Helper variable template to be used to _repeat_ the same value a
  2017. * number of times equal to the size of a given parameter pack.
  2018. * @tparam Value A value to repeat.
  2019. */
  2020. template<auto Value, typename>
  2021. inline constexpr auto unpack_as_value = Value;
  2022. /**
  2023. * @brief Wraps a static constant.
  2024. * @tparam Value A static constant.
  2025. */
  2026. template<auto Value>
  2027. using integral_constant = std::integral_constant<decltype(Value), Value>;
  2028. /**
  2029. * @brief Alias template to facilitate the creation of named values.
  2030. * @tparam Value A constant value at least convertible to `id_type`.
  2031. */
  2032. template<id_type Value>
  2033. using tag = integral_constant<Value>;
  2034. /**
  2035. * @brief A class to use to push around lists of types, nothing more.
  2036. * @tparam Type Types provided by the type list.
  2037. */
  2038. template<typename... Type>
  2039. struct type_list {
  2040. /*! @brief Type list type. */
  2041. using type = type_list;
  2042. /*! @brief Compile-time number of elements in the type list. */
  2043. static constexpr auto size = sizeof...(Type);
  2044. };
  2045. /*! @brief Primary template isn't defined on purpose. */
  2046. template<std::size_t, typename>
  2047. struct type_list_element;
  2048. /**
  2049. * @brief Provides compile-time indexed access to the types of a type list.
  2050. * @tparam Index Index of the type to return.
  2051. * @tparam First First type provided by the type list.
  2052. * @tparam Other Other types provided by the type list.
  2053. */
  2054. template<std::size_t Index, typename First, typename... Other>
  2055. struct type_list_element<Index, type_list<First, Other...>>
  2056. : type_list_element<Index - 1u, type_list<Other...>> {};
  2057. /**
  2058. * @brief Provides compile-time indexed access to the types of a type list.
  2059. * @tparam First First type provided by the type list.
  2060. * @tparam Other Other types provided by the type list.
  2061. */
  2062. template<typename First, typename... Other>
  2063. struct type_list_element<0u, type_list<First, Other...>> {
  2064. /*! @brief Searched type. */
  2065. using type = First;
  2066. };
  2067. /**
  2068. * @brief Helper type.
  2069. * @tparam Index Index of the type to return.
  2070. * @tparam List Type list to search into.
  2071. */
  2072. template<std::size_t Index, typename List>
  2073. using type_list_element_t = typename type_list_element<Index, List>::type;
  2074. /*! @brief Primary template isn't defined on purpose. */
  2075. template<typename, typename>
  2076. struct type_list_index;
  2077. /**
  2078. * @brief Provides compile-time type access to the types of a type list.
  2079. * @tparam Type Type to look for and for which to return the index.
  2080. * @tparam First First type provided by the type list.
  2081. * @tparam Other Other types provided by the type list.
  2082. */
  2083. template<typename Type, typename First, typename... Other>
  2084. struct type_list_index<Type, type_list<First, Other...>> {
  2085. /*! @brief Unsigned integer type. */
  2086. using value_type = std::size_t;
  2087. /*! @brief Compile-time position of the given type in the sublist. */
  2088. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  2089. };
  2090. /**
  2091. * @brief Provides compile-time type access to the types of a type list.
  2092. * @tparam Type Type to look for and for which to return the index.
  2093. * @tparam Other Other types provided by the type list.
  2094. */
  2095. template<typename Type, typename... Other>
  2096. struct type_list_index<Type, type_list<Type, Other...>> {
  2097. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  2098. /*! @brief Unsigned integer type. */
  2099. using value_type = std::size_t;
  2100. /*! @brief Compile-time position of the given type in the sublist. */
  2101. static constexpr value_type value = 0u;
  2102. };
  2103. /**
  2104. * @brief Provides compile-time type access to the types of a type list.
  2105. * @tparam Type Type to look for and for which to return the index.
  2106. */
  2107. template<typename Type>
  2108. struct type_list_index<Type, type_list<>> {
  2109. /*! @brief Unsigned integer type. */
  2110. using value_type = std::size_t;
  2111. /*! @brief Compile-time position of the given type in the sublist. */
  2112. static constexpr value_type value = 0u;
  2113. };
  2114. /**
  2115. * @brief Helper variable template.
  2116. * @tparam List Type list.
  2117. * @tparam Type Type to look for and for which to return the index.
  2118. */
  2119. template<typename Type, typename List>
  2120. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  2121. /**
  2122. * @brief Concatenates multiple type lists.
  2123. * @tparam Type Types provided by the first type list.
  2124. * @tparam Other Types provided by the second type list.
  2125. * @return A type list composed by the types of both the type lists.
  2126. */
  2127. template<typename... Type, typename... Other>
  2128. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  2129. return {};
  2130. }
  2131. /*! @brief Primary template isn't defined on purpose. */
  2132. template<typename...>
  2133. struct type_list_cat;
  2134. /*! @brief Concatenates multiple type lists. */
  2135. template<>
  2136. struct type_list_cat<> {
  2137. /*! @brief A type list composed by the types of all the type lists. */
  2138. using type = type_list<>;
  2139. };
  2140. /**
  2141. * @brief Concatenates multiple type lists.
  2142. * @tparam Type Types provided by the first type list.
  2143. * @tparam Other Types provided by the second type list.
  2144. * @tparam List Other type lists, if any.
  2145. */
  2146. template<typename... Type, typename... Other, typename... List>
  2147. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  2148. /*! @brief A type list composed by the types of all the type lists. */
  2149. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  2150. };
  2151. /**
  2152. * @brief Concatenates multiple type lists.
  2153. * @tparam Type Types provided by the type list.
  2154. */
  2155. template<typename... Type>
  2156. struct type_list_cat<type_list<Type...>> {
  2157. /*! @brief A type list composed by the types of all the type lists. */
  2158. using type = type_list<Type...>;
  2159. };
  2160. /**
  2161. * @brief Helper type.
  2162. * @tparam List Type lists to concatenate.
  2163. */
  2164. template<typename... List>
  2165. using type_list_cat_t = typename type_list_cat<List...>::type;
  2166. /*! @cond TURN_OFF_DOXYGEN */
  2167. namespace internal {
  2168. template<typename...>
  2169. struct type_list_unique;
  2170. template<typename First, typename... Other, typename... Type>
  2171. struct type_list_unique<type_list<First, Other...>, Type...>
  2172. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  2173. template<typename... Type>
  2174. struct type_list_unique<type_list<>, Type...> {
  2175. using type = type_list<Type...>;
  2176. };
  2177. } // namespace internal
  2178. /*! @endcond */
  2179. /**
  2180. * @brief Removes duplicates types from a type list.
  2181. * @tparam List Type list.
  2182. */
  2183. template<typename List>
  2184. struct type_list_unique {
  2185. /*! @brief A type list without duplicate types. */
  2186. using type = typename internal::type_list_unique<List>::type;
  2187. };
  2188. /**
  2189. * @brief Helper type.
  2190. * @tparam List Type list.
  2191. */
  2192. template<typename List>
  2193. using type_list_unique_t = typename type_list_unique<List>::type;
  2194. /**
  2195. * @brief Provides the member constant `value` to true if a type list contains a
  2196. * given type, false otherwise.
  2197. * @tparam List Type list.
  2198. * @tparam Type Type to look for.
  2199. */
  2200. template<typename List, typename Type>
  2201. struct type_list_contains;
  2202. /**
  2203. * @copybrief type_list_contains
  2204. * @tparam Type Types provided by the type list.
  2205. * @tparam Other Type to look for.
  2206. */
  2207. template<typename... Type, typename Other>
  2208. struct type_list_contains<type_list<Type...>, Other>
  2209. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  2210. /**
  2211. * @brief Helper variable template.
  2212. * @tparam List Type list.
  2213. * @tparam Type Type to look for.
  2214. */
  2215. template<typename List, typename Type>
  2216. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  2217. /*! @brief Primary template isn't defined on purpose. */
  2218. template<typename...>
  2219. struct type_list_diff;
  2220. /**
  2221. * @brief Computes the difference between two type lists.
  2222. * @tparam Type Types provided by the first type list.
  2223. * @tparam Other Types provided by the second type list.
  2224. */
  2225. template<typename... Type, typename... Other>
  2226. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  2227. /*! @brief A type list that is the difference between the two type lists. */
  2228. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  2229. };
  2230. /**
  2231. * @brief Helper type.
  2232. * @tparam List Type lists between which to compute the difference.
  2233. */
  2234. template<typename... List>
  2235. using type_list_diff_t = typename type_list_diff<List...>::type;
  2236. /*! @brief Primary template isn't defined on purpose. */
  2237. template<typename, template<typename...> class>
  2238. struct type_list_transform;
  2239. /**
  2240. * @brief Applies a given _function_ to a type list and generate a new list.
  2241. * @tparam Type Types provided by the type list.
  2242. * @tparam Op Unary operation as template class with a type member named `type`.
  2243. */
  2244. template<typename... Type, template<typename...> class Op>
  2245. struct type_list_transform<type_list<Type...>, Op> {
  2246. /*! @brief Resulting type list after applying the transform function. */
  2247. // NOLINTNEXTLINE(modernize-type-traits)
  2248. using type = type_list<typename Op<Type>::type...>;
  2249. };
  2250. /**
  2251. * @brief Helper type.
  2252. * @tparam List Type list.
  2253. * @tparam Op Unary operation as template class with a type member named `type`.
  2254. */
  2255. template<typename List, template<typename...> class Op>
  2256. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  2257. /**
  2258. * @brief A class to use to push around lists of constant values, nothing more.
  2259. * @tparam Value Values provided by the value list.
  2260. */
  2261. template<auto... Value>
  2262. struct value_list {
  2263. /*! @brief Value list type. */
  2264. using type = value_list;
  2265. /*! @brief Compile-time number of elements in the value list. */
  2266. static constexpr auto size = sizeof...(Value);
  2267. };
  2268. /*! @brief Primary template isn't defined on purpose. */
  2269. template<std::size_t, typename>
  2270. struct value_list_element;
  2271. /**
  2272. * @brief Provides compile-time indexed access to the values of a value list.
  2273. * @tparam Index Index of the value to return.
  2274. * @tparam Value First value provided by the value list.
  2275. * @tparam Other Other values provided by the value list.
  2276. */
  2277. template<std::size_t Index, auto Value, auto... Other>
  2278. struct value_list_element<Index, value_list<Value, Other...>>
  2279. : value_list_element<Index - 1u, value_list<Other...>> {};
  2280. /**
  2281. * @brief Provides compile-time indexed access to the types of a type list.
  2282. * @tparam Value First value provided by the value list.
  2283. * @tparam Other Other values provided by the value list.
  2284. */
  2285. template<auto Value, auto... Other>
  2286. struct value_list_element<0u, value_list<Value, Other...>> {
  2287. /*! @brief Searched type. */
  2288. using type = decltype(Value);
  2289. /*! @brief Searched value. */
  2290. static constexpr auto value = Value;
  2291. };
  2292. /**
  2293. * @brief Helper type.
  2294. * @tparam Index Index of the type to return.
  2295. * @tparam List Value list to search into.
  2296. */
  2297. template<std::size_t Index, typename List>
  2298. using value_list_element_t = typename value_list_element<Index, List>::type;
  2299. /**
  2300. * @brief Helper type.
  2301. * @tparam Index Index of the value to return.
  2302. * @tparam List Value list to search into.
  2303. */
  2304. template<std::size_t Index, typename List>
  2305. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  2306. /*! @brief Primary template isn't defined on purpose. */
  2307. template<auto, typename>
  2308. struct value_list_index;
  2309. /**
  2310. * @brief Provides compile-time type access to the values of a value list.
  2311. * @tparam Value Value to look for and for which to return the index.
  2312. * @tparam First First value provided by the value list.
  2313. * @tparam Other Other values provided by the value list.
  2314. */
  2315. template<auto Value, auto First, auto... Other>
  2316. struct value_list_index<Value, value_list<First, Other...>> {
  2317. /*! @brief Unsigned integer type. */
  2318. using value_type = std::size_t;
  2319. /*! @brief Compile-time position of the given value in the sublist. */
  2320. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  2321. };
  2322. /**
  2323. * @brief Provides compile-time type access to the values of a value list.
  2324. * @tparam Value Value to look for and for which to return the index.
  2325. * @tparam Other Other values provided by the value list.
  2326. */
  2327. template<auto Value, auto... Other>
  2328. struct value_list_index<Value, value_list<Value, Other...>> {
  2329. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  2330. /*! @brief Unsigned integer type. */
  2331. using value_type = std::size_t;
  2332. /*! @brief Compile-time position of the given value in the sublist. */
  2333. static constexpr value_type value = 0u;
  2334. };
  2335. /**
  2336. * @brief Provides compile-time type access to the values of a value list.
  2337. * @tparam Value Value to look for and for which to return the index.
  2338. */
  2339. template<auto Value>
  2340. struct value_list_index<Value, value_list<>> {
  2341. /*! @brief Unsigned integer type. */
  2342. using value_type = std::size_t;
  2343. /*! @brief Compile-time position of the given type in the sublist. */
  2344. static constexpr value_type value = 0u;
  2345. };
  2346. /**
  2347. * @brief Helper variable template.
  2348. * @tparam List Value list.
  2349. * @tparam Value Value to look for and for which to return the index.
  2350. */
  2351. template<auto Value, typename List>
  2352. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  2353. /**
  2354. * @brief Concatenates multiple value lists.
  2355. * @tparam Value Values provided by the first value list.
  2356. * @tparam Other Values provided by the second value list.
  2357. * @return A value list composed by the values of both the value lists.
  2358. */
  2359. template<auto... Value, auto... Other>
  2360. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  2361. return {};
  2362. }
  2363. /*! @brief Primary template isn't defined on purpose. */
  2364. template<typename...>
  2365. struct value_list_cat;
  2366. /*! @brief Concatenates multiple value lists. */
  2367. template<>
  2368. struct value_list_cat<> {
  2369. /*! @brief A value list composed by the values of all the value lists. */
  2370. using type = value_list<>;
  2371. };
  2372. /**
  2373. * @brief Concatenates multiple value lists.
  2374. * @tparam Value Values provided by the first value list.
  2375. * @tparam Other Values provided by the second value list.
  2376. * @tparam List Other value lists, if any.
  2377. */
  2378. template<auto... Value, auto... Other, typename... List>
  2379. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  2380. /*! @brief A value list composed by the values of all the value lists. */
  2381. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  2382. };
  2383. /**
  2384. * @brief Concatenates multiple value lists.
  2385. * @tparam Value Values provided by the value list.
  2386. */
  2387. template<auto... Value>
  2388. struct value_list_cat<value_list<Value...>> {
  2389. /*! @brief A value list composed by the values of all the value lists. */
  2390. using type = value_list<Value...>;
  2391. };
  2392. /**
  2393. * @brief Helper type.
  2394. * @tparam List Value lists to concatenate.
  2395. */
  2396. template<typename... List>
  2397. using value_list_cat_t = typename value_list_cat<List...>::type;
  2398. /*! @brief Primary template isn't defined on purpose. */
  2399. template<typename>
  2400. struct value_list_unique;
  2401. /**
  2402. * @brief Removes duplicates values from a value list.
  2403. * @tparam Value One of the values provided by the given value list.
  2404. * @tparam Other The other values provided by the given value list.
  2405. */
  2406. template<auto Value, auto... Other>
  2407. struct value_list_unique<value_list<Value, Other...>> {
  2408. /*! @brief A value list without duplicate types. */
  2409. using type = std::conditional_t<
  2410. ((Value == Other) || ...),
  2411. typename value_list_unique<value_list<Other...>>::type,
  2412. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  2413. };
  2414. /*! @brief Removes duplicates values from a value list. */
  2415. template<>
  2416. struct value_list_unique<value_list<>> {
  2417. /*! @brief A value list without duplicate types. */
  2418. using type = value_list<>;
  2419. };
  2420. /**
  2421. * @brief Helper type.
  2422. * @tparam Type A value list.
  2423. */
  2424. template<typename Type>
  2425. using value_list_unique_t = typename value_list_unique<Type>::type;
  2426. /**
  2427. * @brief Provides the member constant `value` to true if a value list contains
  2428. * a given value, false otherwise.
  2429. * @tparam List Value list.
  2430. * @tparam Value Value to look for.
  2431. */
  2432. template<typename List, auto Value>
  2433. struct value_list_contains;
  2434. /**
  2435. * @copybrief value_list_contains
  2436. * @tparam Value Values provided by the value list.
  2437. * @tparam Other Value to look for.
  2438. */
  2439. template<auto... Value, auto Other>
  2440. struct value_list_contains<value_list<Value...>, Other>
  2441. : std::bool_constant<((Value == Other) || ...)> {};
  2442. /**
  2443. * @brief Helper variable template.
  2444. * @tparam List Value list.
  2445. * @tparam Value Value to look for.
  2446. */
  2447. template<typename List, auto Value>
  2448. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  2449. /*! @brief Primary template isn't defined on purpose. */
  2450. template<typename...>
  2451. struct value_list_diff;
  2452. /**
  2453. * @brief Computes the difference between two value lists.
  2454. * @tparam Value Values provided by the first value list.
  2455. * @tparam Other Values provided by the second value list.
  2456. */
  2457. template<auto... Value, auto... Other>
  2458. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  2459. /*! @brief A value list that is the difference between the two value lists. */
  2460. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  2461. };
  2462. /**
  2463. * @brief Helper type.
  2464. * @tparam List Value lists between which to compute the difference.
  2465. */
  2466. template<typename... List>
  2467. using value_list_diff_t = typename value_list_diff<List...>::type;
  2468. /*! @brief Same as std::is_invocable, but with tuples. */
  2469. template<typename, typename>
  2470. struct is_applicable: std::false_type {};
  2471. /**
  2472. * @copybrief is_applicable
  2473. * @tparam Func A valid function type.
  2474. * @tparam Tuple Tuple-like type.
  2475. * @tparam Args The list of arguments to use to probe the function type.
  2476. */
  2477. template<typename Func, template<typename...> class Tuple, typename... Args>
  2478. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  2479. /**
  2480. * @copybrief is_applicable
  2481. * @tparam Func A valid function type.
  2482. * @tparam Tuple Tuple-like type.
  2483. * @tparam Args The list of arguments to use to probe the function type.
  2484. */
  2485. template<typename Func, template<typename...> class Tuple, typename... Args>
  2486. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  2487. /**
  2488. * @brief Helper variable template.
  2489. * @tparam Func A valid function type.
  2490. * @tparam Args The list of arguments to use to probe the function type.
  2491. */
  2492. template<typename Func, typename Args>
  2493. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  2494. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  2495. template<typename, typename, typename>
  2496. struct is_applicable_r: std::false_type {};
  2497. /**
  2498. * @copybrief is_applicable_r
  2499. * @tparam Ret The type to which the return type of the function should be
  2500. * convertible.
  2501. * @tparam Func A valid function type.
  2502. * @tparam Args The list of arguments to use to probe the function type.
  2503. */
  2504. template<typename Ret, typename Func, typename... Args>
  2505. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  2506. /**
  2507. * @brief Helper variable template.
  2508. * @tparam Ret The type to which the return type of the function should be
  2509. * convertible.
  2510. * @tparam Func A valid function type.
  2511. * @tparam Args The list of arguments to use to probe the function type.
  2512. */
  2513. template<typename Ret, typename Func, typename Args>
  2514. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  2515. /**
  2516. * @brief Provides the member constant `value` to true if a given type is
  2517. * complete, false otherwise.
  2518. * @tparam Type The type to test.
  2519. */
  2520. template<typename Type, typename = void>
  2521. struct is_complete: std::false_type {};
  2522. /*! @copydoc is_complete */
  2523. template<typename Type>
  2524. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  2525. /**
  2526. * @brief Helper variable template.
  2527. * @tparam Type The type to test.
  2528. */
  2529. template<typename Type>
  2530. inline constexpr bool is_complete_v = is_complete<Type>::value;
  2531. /**
  2532. * @brief Provides the member constant `value` to true if a given type is an
  2533. * iterator, false otherwise.
  2534. * @tparam Type The type to test.
  2535. */
  2536. template<typename Type, typename = void>
  2537. struct is_iterator: std::false_type {};
  2538. /*! @cond TURN_OFF_DOXYGEN */
  2539. namespace internal {
  2540. template<typename, typename = void>
  2541. struct has_iterator_category: std::false_type {};
  2542. template<typename Type>
  2543. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  2544. } // namespace internal
  2545. /*! @endcond */
  2546. /*! @copydoc is_iterator */
  2547. template<typename Type>
  2548. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  2549. : internal::has_iterator_category<Type> {};
  2550. /**
  2551. * @brief Helper variable template.
  2552. * @tparam Type The type to test.
  2553. */
  2554. template<typename Type>
  2555. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  2556. /**
  2557. * @brief Provides the member constant `value` to true if a given type is both
  2558. * an empty and non-final class, false otherwise.
  2559. * @tparam Type The type to test
  2560. */
  2561. template<typename Type>
  2562. struct is_ebco_eligible
  2563. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  2564. /**
  2565. * @brief Helper variable template.
  2566. * @tparam Type The type to test.
  2567. */
  2568. template<typename Type>
  2569. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  2570. /**
  2571. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  2572. * is valid and denotes a type, false otherwise.
  2573. * @tparam Type The type to test.
  2574. */
  2575. template<typename Type, typename = void>
  2576. struct is_transparent: std::false_type {};
  2577. /*! @copydoc is_transparent */
  2578. template<typename Type>
  2579. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  2580. /**
  2581. * @brief Helper variable template.
  2582. * @tparam Type The type to test.
  2583. */
  2584. template<typename Type>
  2585. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  2586. /*! @cond TURN_OFF_DOXYGEN */
  2587. namespace internal {
  2588. template<typename, typename = void>
  2589. struct has_tuple_size_value: std::false_type {};
  2590. template<typename Type>
  2591. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  2592. template<typename, typename = void>
  2593. struct has_value_type: std::false_type {};
  2594. template<typename Type>
  2595. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  2596. template<typename>
  2597. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  2598. template<typename Type, std::size_t... Index>
  2599. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  2600. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  2601. }
  2602. template<typename>
  2603. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  2604. return false;
  2605. }
  2606. template<typename Type>
  2607. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  2608. return true;
  2609. }
  2610. template<typename Type>
  2611. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  2612. // NOLINTBEGIN(modernize-use-transparent-functors)
  2613. if constexpr(std::is_array_v<Type>) {
  2614. return false;
  2615. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  2616. if constexpr(has_tuple_size_value<Type>::value) {
  2617. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  2618. } else {
  2619. return maybe_equality_comparable<Type>(0);
  2620. }
  2621. } else if constexpr(has_value_type<Type>::value) {
  2622. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  2623. return maybe_equality_comparable<Type>(0);
  2624. } else {
  2625. return false;
  2626. }
  2627. } else {
  2628. return maybe_equality_comparable<Type>(0);
  2629. }
  2630. // NOLINTEND(modernize-use-transparent-functors)
  2631. }
  2632. } // namespace internal
  2633. /*! @endcond */
  2634. /**
  2635. * @brief Provides the member constant `value` to true if a given type is
  2636. * equality comparable, false otherwise.
  2637. * @tparam Type The type to test.
  2638. */
  2639. template<typename Type>
  2640. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  2641. /*! @copydoc is_equality_comparable */
  2642. template<typename Type>
  2643. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  2644. /**
  2645. * @brief Helper variable template.
  2646. * @tparam Type The type to test.
  2647. */
  2648. template<typename Type>
  2649. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  2650. /**
  2651. * @brief Transcribes the constness of a type to another type.
  2652. * @tparam To The type to which to transcribe the constness.
  2653. * @tparam From The type from which to transcribe the constness.
  2654. */
  2655. template<typename To, typename From>
  2656. struct constness_as {
  2657. /*! @brief The type resulting from the transcription of the constness. */
  2658. using type = std::remove_const_t<To>;
  2659. };
  2660. /*! @copydoc constness_as */
  2661. template<typename To, typename From>
  2662. struct constness_as<To, const From> {
  2663. /*! @brief The type resulting from the transcription of the constness. */
  2664. using type = const To;
  2665. };
  2666. /**
  2667. * @brief Alias template to facilitate the transcription of the constness.
  2668. * @tparam To The type to which to transcribe the constness.
  2669. * @tparam From The type from which to transcribe the constness.
  2670. */
  2671. template<typename To, typename From>
  2672. using constness_as_t = typename constness_as<To, From>::type;
  2673. /**
  2674. * @brief Extracts the class of a non-static member object or function.
  2675. * @tparam Member A pointer to a non-static member object or function.
  2676. */
  2677. template<typename Member>
  2678. class member_class {
  2679. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  2680. template<typename Class, typename Ret, typename... Args>
  2681. static Class *clazz(Ret (Class::*)(Args...));
  2682. template<typename Class, typename Ret, typename... Args>
  2683. static Class *clazz(Ret (Class::*)(Args...) const);
  2684. template<typename Class, typename Type>
  2685. static Class *clazz(Type Class::*);
  2686. public:
  2687. /*! @brief The class of the given non-static member object or function. */
  2688. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  2689. };
  2690. /**
  2691. * @brief Helper type.
  2692. * @tparam Member A pointer to a non-static member object or function.
  2693. */
  2694. template<typename Member>
  2695. using member_class_t = typename member_class<Member>::type;
  2696. /**
  2697. * @brief Extracts the n-th argument of a _callable_ type.
  2698. * @tparam Index The index of the argument to extract.
  2699. * @tparam Candidate A valid _callable_ type.
  2700. */
  2701. template<std::size_t Index, typename Candidate>
  2702. class nth_argument {
  2703. template<typename Ret, typename... Args>
  2704. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  2705. template<typename Ret, typename Class, typename... Args>
  2706. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  2707. template<typename Ret, typename Class, typename... Args>
  2708. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  2709. template<typename Type, typename Class>
  2710. static constexpr type_list<Type> pick_up(Type Class ::*);
  2711. template<typename Type>
  2712. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  2713. public:
  2714. /*! @brief N-th argument of the _callable_ type. */
  2715. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  2716. };
  2717. /**
  2718. * @brief Helper type.
  2719. * @tparam Index The index of the argument to extract.
  2720. * @tparam Candidate A valid function, member function or data member type.
  2721. */
  2722. template<std::size_t Index, typename Candidate>
  2723. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  2724. } // namespace entt
  2725. template<typename... Type>
  2726. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  2727. template<std::size_t Index, typename... Type>
  2728. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  2729. template<auto... Value>
  2730. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  2731. template<std::size_t Index, auto... Value>
  2732. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  2733. #endif
  2734. // #include "fwd.hpp"
  2735. #ifndef ENTT_CONTAINER_FWD_HPP
  2736. #define ENTT_CONTAINER_FWD_HPP
  2737. #include <functional>
  2738. #include <memory>
  2739. #include <utility>
  2740. #include <vector>
  2741. namespace entt {
  2742. template<
  2743. typename Key,
  2744. typename Type,
  2745. typename = std::hash<Key>,
  2746. typename = std::equal_to<>,
  2747. typename = std::allocator<std::pair<const Key, Type>>>
  2748. class dense_map;
  2749. template<
  2750. typename Type,
  2751. typename = std::hash<Type>,
  2752. typename = std::equal_to<>,
  2753. typename = std::allocator<Type>>
  2754. class dense_set;
  2755. template<typename...>
  2756. class basic_table;
  2757. /**
  2758. * @brief Alias declaration for the most common use case.
  2759. * @tparam Type Element types.
  2760. */
  2761. template<typename... Type>
  2762. using table = basic_table<std::vector<Type>...>;
  2763. } // namespace entt
  2764. #endif
  2765. namespace entt {
  2766. /*! @cond TURN_OFF_DOXYGEN */
  2767. namespace internal {
  2768. static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  2769. template<typename Key, typename Type>
  2770. struct dense_map_node final {
  2771. using value_type = std::pair<Key, Type>;
  2772. template<typename... Args>
  2773. dense_map_node(const std::size_t pos, Args &&...args)
  2774. : next{pos},
  2775. element{std::forward<Args>(args)...} {}
  2776. template<typename Allocator, typename... Args>
  2777. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  2778. : next{pos},
  2779. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  2780. template<typename Allocator>
  2781. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  2782. : next{other.next},
  2783. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  2784. template<typename Allocator>
  2785. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  2786. : next{other.next},
  2787. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  2788. std::size_t next;
  2789. value_type element;
  2790. };
  2791. template<typename It>
  2792. class dense_map_iterator final {
  2793. template<typename>
  2794. friend class dense_map_iterator;
  2795. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  2796. using second_type = decltype((std::declval<It>()->element.second));
  2797. public:
  2798. using value_type = std::pair<first_type, second_type>;
  2799. using pointer = input_iterator_pointer<value_type>;
  2800. using reference = value_type;
  2801. using difference_type = std::ptrdiff_t;
  2802. using iterator_category = std::input_iterator_tag;
  2803. using iterator_concept = std::random_access_iterator_tag;
  2804. constexpr dense_map_iterator() noexcept
  2805. : it{} {}
  2806. constexpr dense_map_iterator(const It iter) noexcept
  2807. : it{iter} {}
  2808. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  2809. constexpr dense_map_iterator(const dense_map_iterator<Other> &other) noexcept
  2810. : it{other.it} {}
  2811. constexpr dense_map_iterator &operator++() noexcept {
  2812. return ++it, *this;
  2813. }
  2814. constexpr dense_map_iterator operator++(int) noexcept {
  2815. const dense_map_iterator orig = *this;
  2816. return ++(*this), orig;
  2817. }
  2818. constexpr dense_map_iterator &operator--() noexcept {
  2819. return --it, *this;
  2820. }
  2821. constexpr dense_map_iterator operator--(int) noexcept {
  2822. const dense_map_iterator orig = *this;
  2823. return operator--(), orig;
  2824. }
  2825. constexpr dense_map_iterator &operator+=(const difference_type value) noexcept {
  2826. it += value;
  2827. return *this;
  2828. }
  2829. constexpr dense_map_iterator operator+(const difference_type value) const noexcept {
  2830. dense_map_iterator copy = *this;
  2831. return (copy += value);
  2832. }
  2833. constexpr dense_map_iterator &operator-=(const difference_type value) noexcept {
  2834. return (*this += -value);
  2835. }
  2836. constexpr dense_map_iterator operator-(const difference_type value) const noexcept {
  2837. return (*this + -value);
  2838. }
  2839. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  2840. return {it[value].element.first, it[value].element.second};
  2841. }
  2842. [[nodiscard]] constexpr pointer operator->() const noexcept {
  2843. return operator*();
  2844. }
  2845. [[nodiscard]] constexpr reference operator*() const noexcept {
  2846. return operator[](0);
  2847. }
  2848. template<typename Lhs, typename Rhs>
  2849. friend constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  2850. template<typename Lhs, typename Rhs>
  2851. friend constexpr bool operator==(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  2852. template<typename Lhs, typename Rhs>
  2853. friend constexpr bool operator<(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  2854. private:
  2855. It it;
  2856. };
  2857. template<typename Lhs, typename Rhs>
  2858. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  2859. return lhs.it - rhs.it;
  2860. }
  2861. template<typename Lhs, typename Rhs>
  2862. [[nodiscard]] constexpr bool operator==(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  2863. return lhs.it == rhs.it;
  2864. }
  2865. template<typename Lhs, typename Rhs>
  2866. [[nodiscard]] constexpr bool operator!=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  2867. return !(lhs == rhs);
  2868. }
  2869. template<typename Lhs, typename Rhs>
  2870. [[nodiscard]] constexpr bool operator<(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  2871. return lhs.it < rhs.it;
  2872. }
  2873. template<typename Lhs, typename Rhs>
  2874. [[nodiscard]] constexpr bool operator>(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  2875. return rhs < lhs;
  2876. }
  2877. template<typename Lhs, typename Rhs>
  2878. [[nodiscard]] constexpr bool operator<=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  2879. return !(lhs > rhs);
  2880. }
  2881. template<typename Lhs, typename Rhs>
  2882. [[nodiscard]] constexpr bool operator>=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  2883. return !(lhs < rhs);
  2884. }
  2885. template<typename It>
  2886. class dense_map_local_iterator final {
  2887. template<typename>
  2888. friend class dense_map_local_iterator;
  2889. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  2890. using second_type = decltype((std::declval<It>()->element.second));
  2891. public:
  2892. using value_type = std::pair<first_type, second_type>;
  2893. using pointer = input_iterator_pointer<value_type>;
  2894. using reference = value_type;
  2895. using difference_type = std::ptrdiff_t;
  2896. using iterator_category = std::input_iterator_tag;
  2897. using iterator_concept = std::forward_iterator_tag;
  2898. constexpr dense_map_local_iterator() noexcept = default;
  2899. constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept
  2900. : it{iter},
  2901. offset{pos} {}
  2902. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  2903. constexpr dense_map_local_iterator(const dense_map_local_iterator<Other> &other) noexcept
  2904. : it{other.it},
  2905. offset{other.offset} {}
  2906. constexpr dense_map_local_iterator &operator++() noexcept {
  2907. return (offset = it[static_cast<typename It::difference_type>(offset)].next), *this;
  2908. }
  2909. constexpr dense_map_local_iterator operator++(int) noexcept {
  2910. const dense_map_local_iterator orig = *this;
  2911. return ++(*this), orig;
  2912. }
  2913. [[nodiscard]] constexpr pointer operator->() const noexcept {
  2914. return operator*();
  2915. }
  2916. [[nodiscard]] constexpr reference operator*() const noexcept {
  2917. const auto idx = static_cast<typename It::difference_type>(offset);
  2918. return {it[idx].element.first, it[idx].element.second};
  2919. }
  2920. [[nodiscard]] constexpr std::size_t index() const noexcept {
  2921. return offset;
  2922. }
  2923. private:
  2924. It it{};
  2925. std::size_t offset{dense_map_placeholder_position};
  2926. };
  2927. template<typename Lhs, typename Rhs>
  2928. [[nodiscard]] constexpr bool operator==(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  2929. return lhs.index() == rhs.index();
  2930. }
  2931. template<typename Lhs, typename Rhs>
  2932. [[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  2933. return !(lhs == rhs);
  2934. }
  2935. } // namespace internal
  2936. /*! @endcond */
  2937. /**
  2938. * @brief Associative container for key-value pairs with unique keys.
  2939. *
  2940. * Internally, elements are organized into buckets. Which bucket an element is
  2941. * placed into depends entirely on the hash of its key. Keys with the same hash
  2942. * code appear in the same bucket.
  2943. *
  2944. * @tparam Key Key type of the associative container.
  2945. * @tparam Type Mapped type of the associative container.
  2946. * @tparam Hash Type of function to use to hash the keys.
  2947. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  2948. * @tparam Allocator Type of allocator used to manage memory and elements.
  2949. */
  2950. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  2951. class dense_map {
  2952. static constexpr float default_threshold = 0.875f;
  2953. static constexpr std::size_t minimum_capacity = 8u;
  2954. static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position;
  2955. using node_type = internal::dense_map_node<Key, Type>;
  2956. using alloc_traits = std::allocator_traits<Allocator>;
  2957. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  2958. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  2959. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  2960. template<typename Other>
  2961. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept {
  2962. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  2963. return fast_mod(static_cast<size_type>(sparse.second()(key)), bucket_count());
  2964. }
  2965. template<typename Other>
  2966. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) {
  2967. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  2968. if(packed.second()(packed.first()[offset].element.first, key)) {
  2969. return begin() + static_cast<typename iterator::difference_type>(offset);
  2970. }
  2971. }
  2972. return end();
  2973. }
  2974. template<typename Other>
  2975. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const {
  2976. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  2977. if(packed.second()(packed.first()[offset].element.first, key)) {
  2978. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  2979. }
  2980. }
  2981. return cend();
  2982. }
  2983. template<typename Other, typename... Args>
  2984. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  2985. const auto index = key_to_bucket(key);
  2986. if(auto it = constrained_find(key, index); it != end()) {
  2987. return std::make_pair(it, false);
  2988. }
  2989. packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward<Other>(key)), std::forward_as_tuple(std::forward<Args>(args)...));
  2990. sparse.first()[index] = packed.first().size() - 1u;
  2991. rehash_if_required();
  2992. return std::make_pair(--end(), true);
  2993. }
  2994. template<typename Other, typename Arg>
  2995. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  2996. const auto index = key_to_bucket(key);
  2997. if(auto it = constrained_find(key, index); it != end()) {
  2998. it->second = std::forward<Arg>(value);
  2999. return std::make_pair(it, false);
  3000. }
  3001. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  3002. sparse.first()[index] = packed.first().size() - 1u;
  3003. rehash_if_required();
  3004. return std::make_pair(--end(), true);
  3005. }
  3006. void move_and_pop(const std::size_t pos) {
  3007. if(const auto last = size() - 1u; pos != last) {
  3008. size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)];
  3009. packed.first()[pos] = std::move(packed.first().back());
  3010. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  3011. *curr = pos;
  3012. }
  3013. packed.first().pop_back();
  3014. }
  3015. void rehash_if_required() {
  3016. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  3017. rehash(bc * 2u);
  3018. }
  3019. }
  3020. public:
  3021. /*! @brief Allocator type. */
  3022. using allocator_type = Allocator;
  3023. /*! @brief Key type of the container. */
  3024. using key_type = Key;
  3025. /*! @brief Mapped type of the container. */
  3026. using mapped_type = Type;
  3027. /*! @brief Key-value type of the container. */
  3028. using value_type = std::pair<const Key, Type>;
  3029. /*! @brief Unsigned integer type. */
  3030. using size_type = std::size_t;
  3031. /*! @brief Signed integer type. */
  3032. using difference_type = std::ptrdiff_t;
  3033. /*! @brief Type of function to use to hash the keys. */
  3034. using hasher = Hash;
  3035. /*! @brief Type of function to use to compare the keys for equality. */
  3036. using key_equal = KeyEqual;
  3037. /*! @brief Input iterator type. */
  3038. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  3039. /*! @brief Constant input iterator type. */
  3040. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  3041. /*! @brief Input iterator type. */
  3042. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  3043. /*! @brief Constant input iterator type. */
  3044. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  3045. /*! @brief Default constructor. */
  3046. dense_map()
  3047. : dense_map{minimum_capacity} {}
  3048. /**
  3049. * @brief Constructs an empty container with a given allocator.
  3050. * @param allocator The allocator to use.
  3051. */
  3052. explicit dense_map(const allocator_type &allocator)
  3053. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  3054. /**
  3055. * @brief Constructs an empty container with a given allocator and user
  3056. * supplied minimal number of buckets.
  3057. * @param cnt Minimal number of buckets.
  3058. * @param allocator The allocator to use.
  3059. */
  3060. dense_map(const size_type cnt, const allocator_type &allocator)
  3061. : dense_map{cnt, hasher{}, key_equal{}, allocator} {}
  3062. /**
  3063. * @brief Constructs an empty container with a given allocator, hash
  3064. * function and user supplied minimal number of buckets.
  3065. * @param cnt Minimal number of buckets.
  3066. * @param hash Hash function to use.
  3067. * @param allocator The allocator to use.
  3068. */
  3069. dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  3070. : dense_map{cnt, hash, key_equal{}, allocator} {}
  3071. /**
  3072. * @brief Constructs an empty container with a given allocator, hash
  3073. * function, compare function and user supplied minimal number of buckets.
  3074. * @param cnt Minimal number of buckets.
  3075. * @param hash Hash function to use.
  3076. * @param equal Compare function to use.
  3077. * @param allocator The allocator to use.
  3078. */
  3079. explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  3080. : sparse{allocator, hash},
  3081. packed{allocator, equal} {
  3082. rehash(cnt);
  3083. }
  3084. /*! @brief Default copy constructor. */
  3085. dense_map(const dense_map &) = default;
  3086. /**
  3087. * @brief Allocator-extended copy constructor.
  3088. * @param other The instance to copy from.
  3089. * @param allocator The allocator to use.
  3090. */
  3091. dense_map(const dense_map &other, const allocator_type &allocator)
  3092. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  3093. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  3094. threshold{other.threshold} {}
  3095. /*! @brief Default move constructor. */
  3096. dense_map(dense_map &&) noexcept = default;
  3097. /**
  3098. * @brief Allocator-extended move constructor.
  3099. * @param other The instance to move from.
  3100. * @param allocator The allocator to use.
  3101. */
  3102. dense_map(dense_map &&other, const allocator_type &allocator)
  3103. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  3104. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  3105. threshold{other.threshold} {}
  3106. /*! @brief Default destructor. */
  3107. ~dense_map() = default;
  3108. /**
  3109. * @brief Default copy assignment operator.
  3110. * @return This container.
  3111. */
  3112. dense_map &operator=(const dense_map &) = default;
  3113. /**
  3114. * @brief Default move assignment operator.
  3115. * @return This container.
  3116. */
  3117. dense_map &operator=(dense_map &&) noexcept = default;
  3118. /**
  3119. * @brief Exchanges the contents with those of a given container.
  3120. * @param other Container to exchange the content with.
  3121. */
  3122. void swap(dense_map &other) noexcept {
  3123. using std::swap;
  3124. swap(sparse, other.sparse);
  3125. swap(packed, other.packed);
  3126. swap(threshold, other.threshold);
  3127. }
  3128. /**
  3129. * @brief Returns the associated allocator.
  3130. * @return The associated allocator.
  3131. */
  3132. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  3133. return sparse.first().get_allocator();
  3134. }
  3135. /**
  3136. * @brief Returns an iterator to the beginning.
  3137. *
  3138. * If the array is empty, the returned iterator will be equal to `end()`.
  3139. *
  3140. * @return An iterator to the first instance of the internal array.
  3141. */
  3142. [[nodiscard]] const_iterator cbegin() const noexcept {
  3143. return packed.first().begin();
  3144. }
  3145. /*! @copydoc cbegin */
  3146. [[nodiscard]] const_iterator begin() const noexcept {
  3147. return cbegin();
  3148. }
  3149. /*! @copydoc begin */
  3150. [[nodiscard]] iterator begin() noexcept {
  3151. return packed.first().begin();
  3152. }
  3153. /**
  3154. * @brief Returns an iterator to the end.
  3155. * @return An iterator to the element following the last instance of the
  3156. * internal array.
  3157. */
  3158. [[nodiscard]] const_iterator cend() const noexcept {
  3159. return packed.first().end();
  3160. }
  3161. /*! @copydoc cend */
  3162. [[nodiscard]] const_iterator end() const noexcept {
  3163. return cend();
  3164. }
  3165. /*! @copydoc end */
  3166. [[nodiscard]] iterator end() noexcept {
  3167. return packed.first().end();
  3168. }
  3169. /**
  3170. * @brief Checks whether a container is empty.
  3171. * @return True if the container is empty, false otherwise.
  3172. */
  3173. [[nodiscard]] bool empty() const noexcept {
  3174. return packed.first().empty();
  3175. }
  3176. /**
  3177. * @brief Returns the number of elements in a container.
  3178. * @return Number of elements in a container.
  3179. */
  3180. [[nodiscard]] size_type size() const noexcept {
  3181. return packed.first().size();
  3182. }
  3183. /**
  3184. * @brief Returns the maximum possible number of elements.
  3185. * @return Maximum possible number of elements.
  3186. */
  3187. [[nodiscard]] size_type max_size() const noexcept {
  3188. return packed.first().max_size();
  3189. }
  3190. /*! @brief Clears the container. */
  3191. void clear() noexcept {
  3192. sparse.first().clear();
  3193. packed.first().clear();
  3194. rehash(0u);
  3195. }
  3196. /**
  3197. * @brief Inserts an element into the container, if the key does not exist.
  3198. * @param value A key-value pair eventually convertible to the value type.
  3199. * @return A pair consisting of an iterator to the inserted element (or to
  3200. * the element that prevented the insertion) and a bool denoting whether the
  3201. * insertion took place.
  3202. */
  3203. std::pair<iterator, bool> insert(const value_type &value) {
  3204. return insert_or_do_nothing(value.first, value.second);
  3205. }
  3206. /*! @copydoc insert */
  3207. std::pair<iterator, bool> insert(value_type &&value) {
  3208. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  3209. }
  3210. /**
  3211. * @copydoc insert
  3212. * @tparam Arg Type of the key-value pair to insert into the container.
  3213. */
  3214. template<typename Arg>
  3215. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  3216. insert(Arg &&value) {
  3217. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  3218. }
  3219. /**
  3220. * @brief Inserts elements into the container, if their keys do not exist.
  3221. * @tparam It Type of input iterator.
  3222. * @param first An iterator to the first element of the range of elements.
  3223. * @param last An iterator past the last element of the range of elements.
  3224. */
  3225. template<typename It>
  3226. void insert(It first, It last) {
  3227. for(; first != last; ++first) {
  3228. insert(*first);
  3229. }
  3230. }
  3231. /**
  3232. * @brief Inserts an element into the container or assigns to the current
  3233. * element if the key already exists.
  3234. * @tparam Arg Type of the value to insert or assign.
  3235. * @param key A key used both to look up and to insert if not found.
  3236. * @param value A value to insert or assign.
  3237. * @return A pair consisting of an iterator to the element and a bool
  3238. * denoting whether the insertion took place.
  3239. */
  3240. template<typename Arg>
  3241. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  3242. return insert_or_overwrite(key, std::forward<Arg>(value));
  3243. }
  3244. /*! @copydoc insert_or_assign */
  3245. template<typename Arg>
  3246. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  3247. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  3248. }
  3249. /**
  3250. * @brief Constructs an element in-place, if the key does not exist.
  3251. *
  3252. * The element is also constructed when the container already has the key,
  3253. * in which case the newly constructed object is destroyed immediately.
  3254. *
  3255. * @tparam Args Types of arguments to forward to the constructor of the
  3256. * element.
  3257. * @param args Arguments to forward to the constructor of the element.
  3258. * @return A pair consisting of an iterator to the inserted element (or to
  3259. * the element that prevented the insertion) and a bool denoting whether the
  3260. * insertion took place.
  3261. */
  3262. template<typename... Args>
  3263. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  3264. if constexpr(sizeof...(Args) == 0u) {
  3265. return insert_or_do_nothing(key_type{});
  3266. } else if constexpr(sizeof...(Args) == 1u) {
  3267. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  3268. } else if constexpr(sizeof...(Args) == 2u) {
  3269. return insert_or_do_nothing(std::forward<Args>(args)...);
  3270. } else {
  3271. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  3272. const auto index = key_to_bucket(node.element.first);
  3273. if(auto it = constrained_find(node.element.first, index); it != end()) {
  3274. packed.first().pop_back();
  3275. return std::make_pair(it, false);
  3276. }
  3277. std::swap(node.next, sparse.first()[index]);
  3278. rehash_if_required();
  3279. return std::make_pair(--end(), true);
  3280. }
  3281. }
  3282. /**
  3283. * @brief Inserts in-place if the key does not exist, does nothing if the
  3284. * key exists.
  3285. * @tparam Args Types of arguments to forward to the constructor of the
  3286. * element.
  3287. * @param key A key used both to look up and to insert if not found.
  3288. * @param args Arguments to forward to the constructor of the element.
  3289. * @return A pair consisting of an iterator to the inserted element (or to
  3290. * the element that prevented the insertion) and a bool denoting whether the
  3291. * insertion took place.
  3292. */
  3293. template<typename... Args>
  3294. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  3295. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  3296. }
  3297. /*! @copydoc try_emplace */
  3298. template<typename... Args>
  3299. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  3300. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  3301. }
  3302. /**
  3303. * @brief Removes an element from a given position.
  3304. * @param pos An iterator to the element to remove.
  3305. * @return An iterator following the removed element.
  3306. */
  3307. iterator erase(const_iterator pos) {
  3308. const auto diff = pos - cbegin();
  3309. erase(pos->first);
  3310. return begin() + diff;
  3311. }
  3312. /**
  3313. * @brief Removes the given elements from a container.
  3314. * @param first An iterator to the first element of the range of elements.
  3315. * @param last An iterator past the last element of the range of elements.
  3316. * @return An iterator following the last removed element.
  3317. */
  3318. iterator erase(const_iterator first, const_iterator last) {
  3319. const auto dist = first - cbegin();
  3320. for(auto from = last - cbegin(); from != dist; --from) {
  3321. erase(packed.first()[static_cast<size_type>(from) - 1u].element.first);
  3322. }
  3323. return (begin() + dist);
  3324. }
  3325. /**
  3326. * @brief Removes the element associated with a given key.
  3327. * @param key A key value of an element to remove.
  3328. * @return Number of elements removed (either 0 or 1).
  3329. */
  3330. size_type erase(const key_type &key) {
  3331. for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) {
  3332. if(packed.second()(packed.first()[*curr].element.first, key)) {
  3333. const auto index = *curr;
  3334. *curr = packed.first()[*curr].next;
  3335. move_and_pop(index);
  3336. return 1u;
  3337. }
  3338. }
  3339. return 0u;
  3340. }
  3341. /**
  3342. * @brief Accesses a given element with bounds checking.
  3343. * @param key A key of an element to find.
  3344. * @return A reference to the mapped value of the requested element.
  3345. */
  3346. [[nodiscard]] mapped_type &at(const key_type &key) {
  3347. auto it = find(key);
  3348. ENTT_ASSERT(it != end(), "Invalid key");
  3349. return it->second;
  3350. }
  3351. /*! @copydoc at */
  3352. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  3353. auto it = find(key);
  3354. ENTT_ASSERT(it != cend(), "Invalid key");
  3355. return it->second;
  3356. }
  3357. /**
  3358. * @brief Accesses a given element with bounds checking.
  3359. * @tparam Other Type of the key of an element to find.
  3360. * @param key A key of an element to find.
  3361. * @return A reference to the mapped value of the requested element.
  3362. */
  3363. template<typename Other>
  3364. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type const &>>
  3365. at(const Other &key) const {
  3366. auto it = find(key);
  3367. ENTT_ASSERT(it != cend(), "Invalid key");
  3368. return it->second;
  3369. }
  3370. /*! @copydoc at */
  3371. template<typename Other>
  3372. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type &>>
  3373. at(const Other &key) {
  3374. auto it = find(key);
  3375. ENTT_ASSERT(it != end(), "Invalid key");
  3376. return it->second;
  3377. }
  3378. /**
  3379. * @brief Accesses or inserts a given element.
  3380. * @param key A key of an element to find or insert.
  3381. * @return A reference to the mapped value of the requested element.
  3382. */
  3383. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  3384. return insert_or_do_nothing(key).first->second;
  3385. }
  3386. /**
  3387. * @brief Accesses or inserts a given element.
  3388. * @param key A key of an element to find or insert.
  3389. * @return A reference to the mapped value of the requested element.
  3390. */
  3391. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  3392. return insert_or_do_nothing(std::move(key)).first->second;
  3393. }
  3394. /**
  3395. * @brief Returns the number of elements matching a key (either 1 or 0).
  3396. * @param key Key value of an element to search for.
  3397. * @return Number of elements matching the key (either 1 or 0).
  3398. */
  3399. [[nodiscard]] size_type count(const key_type &key) const {
  3400. return find(key) != end();
  3401. }
  3402. /**
  3403. * @brief Returns the number of elements matching a key (either 1 or 0).
  3404. * @tparam Other Type of the key value of an element to search for.
  3405. * @param key Key value of an element to search for.
  3406. * @return Number of elements matching the key (either 1 or 0).
  3407. */
  3408. template<typename Other>
  3409. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  3410. count(const Other &key) const {
  3411. return find(key) != end();
  3412. }
  3413. /**
  3414. * @brief Finds an element with a given key.
  3415. * @param key Key value of an element to search for.
  3416. * @return An iterator to an element with the given key. If no such element
  3417. * is found, a past-the-end iterator is returned.
  3418. */
  3419. [[nodiscard]] iterator find(const key_type &key) {
  3420. return constrained_find(key, key_to_bucket(key));
  3421. }
  3422. /*! @copydoc find */
  3423. [[nodiscard]] const_iterator find(const key_type &key) const {
  3424. return constrained_find(key, key_to_bucket(key));
  3425. }
  3426. /**
  3427. * @brief Finds an element with a key that compares _equivalent_ to a given
  3428. * key.
  3429. * @tparam Other Type of the key value of an element to search for.
  3430. * @param key Key value of an element to search for.
  3431. * @return An iterator to an element with the given key. If no such element
  3432. * is found, a past-the-end iterator is returned.
  3433. */
  3434. template<typename Other>
  3435. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  3436. find(const Other &key) {
  3437. return constrained_find(key, key_to_bucket(key));
  3438. }
  3439. /*! @copydoc find */
  3440. template<typename Other>
  3441. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  3442. find(const Other &key) const {
  3443. return constrained_find(key, key_to_bucket(key));
  3444. }
  3445. /**
  3446. * @brief Returns a range containing all elements with a given key.
  3447. * @param key Key value of an element to search for.
  3448. * @return A pair of iterators pointing to the first element and past the
  3449. * last element of the range.
  3450. */
  3451. [[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
  3452. const auto it = find(key);
  3453. return {it, it + !(it == end())};
  3454. }
  3455. /*! @copydoc equal_range */
  3456. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
  3457. const auto it = find(key);
  3458. return {it, it + !(it == cend())};
  3459. }
  3460. /**
  3461. * @brief Returns a range containing all elements that compare _equivalent_
  3462. * to a given key.
  3463. * @tparam Other Type of an element to search for.
  3464. * @param key Key value of an element to search for.
  3465. * @return A pair of iterators pointing to the first element and past the
  3466. * last element of the range.
  3467. */
  3468. template<typename Other>
  3469. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  3470. equal_range(const Other &key) {
  3471. const auto it = find(key);
  3472. return {it, it + !(it == end())};
  3473. }
  3474. /*! @copydoc equal_range */
  3475. template<typename Other>
  3476. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  3477. equal_range(const Other &key) const {
  3478. const auto it = find(key);
  3479. return {it, it + !(it == cend())};
  3480. }
  3481. /**
  3482. * @brief Checks if the container contains an element with a given key.
  3483. * @param key Key value of an element to search for.
  3484. * @return True if there is such an element, false otherwise.
  3485. */
  3486. [[nodiscard]] bool contains(const key_type &key) const {
  3487. return (find(key) != cend());
  3488. }
  3489. /**
  3490. * @brief Checks if the container contains an element with a key that
  3491. * compares _equivalent_ to a given value.
  3492. * @tparam Other Type of the key value of an element to search for.
  3493. * @param key Key value of an element to search for.
  3494. * @return True if there is such an element, false otherwise.
  3495. */
  3496. template<typename Other>
  3497. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  3498. contains(const Other &key) const {
  3499. return (find(key) != cend());
  3500. }
  3501. /**
  3502. * @brief Returns an iterator to the beginning of a given bucket.
  3503. * @param index An index of a bucket to access.
  3504. * @return An iterator to the beginning of the given bucket.
  3505. */
  3506. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  3507. return {packed.first().begin(), sparse.first()[index]};
  3508. }
  3509. /**
  3510. * @brief Returns an iterator to the beginning of a given bucket.
  3511. * @param index An index of a bucket to access.
  3512. * @return An iterator to the beginning of the given bucket.
  3513. */
  3514. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  3515. return cbegin(index);
  3516. }
  3517. /**
  3518. * @brief Returns an iterator to the beginning of a given bucket.
  3519. * @param index An index of a bucket to access.
  3520. * @return An iterator to the beginning of the given bucket.
  3521. */
  3522. [[nodiscard]] local_iterator begin(const size_type index) {
  3523. return {packed.first().begin(), sparse.first()[index]};
  3524. }
  3525. /**
  3526. * @brief Returns an iterator to the end of a given bucket.
  3527. * @param index An index of a bucket to access.
  3528. * @return An iterator to the end of the given bucket.
  3529. */
  3530. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  3531. return {};
  3532. }
  3533. /**
  3534. * @brief Returns an iterator to the end of a given bucket.
  3535. * @param index An index of a bucket to access.
  3536. * @return An iterator to the end of the given bucket.
  3537. */
  3538. [[nodiscard]] const_local_iterator end(const size_type index) const {
  3539. return cend(index);
  3540. }
  3541. /**
  3542. * @brief Returns an iterator to the end of a given bucket.
  3543. * @param index An index of a bucket to access.
  3544. * @return An iterator to the end of the given bucket.
  3545. */
  3546. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  3547. return {};
  3548. }
  3549. /**
  3550. * @brief Returns the number of buckets.
  3551. * @return The number of buckets.
  3552. */
  3553. [[nodiscard]] size_type bucket_count() const {
  3554. return sparse.first().size();
  3555. }
  3556. /**
  3557. * @brief Returns the maximum number of buckets.
  3558. * @return The maximum number of buckets.
  3559. */
  3560. [[nodiscard]] size_type max_bucket_count() const {
  3561. return sparse.first().max_size();
  3562. }
  3563. /**
  3564. * @brief Returns the number of elements in a given bucket.
  3565. * @param index The index of the bucket to examine.
  3566. * @return The number of elements in the given bucket.
  3567. */
  3568. [[nodiscard]] size_type bucket_size(const size_type index) const {
  3569. return static_cast<size_type>(std::distance(begin(index), end(index)));
  3570. }
  3571. /**
  3572. * @brief Returns the bucket for a given key.
  3573. * @param key The value of the key to examine.
  3574. * @return The bucket for the given key.
  3575. */
  3576. [[nodiscard]] size_type bucket(const key_type &key) const {
  3577. return key_to_bucket(key);
  3578. }
  3579. /**
  3580. * @brief Returns the average number of elements per bucket.
  3581. * @return The average number of elements per bucket.
  3582. */
  3583. [[nodiscard]] float load_factor() const {
  3584. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  3585. }
  3586. /**
  3587. * @brief Returns the maximum average number of elements per bucket.
  3588. * @return The maximum average number of elements per bucket.
  3589. */
  3590. [[nodiscard]] float max_load_factor() const {
  3591. return threshold;
  3592. }
  3593. /**
  3594. * @brief Sets the desired maximum average number of elements per bucket.
  3595. * @param value A desired maximum average number of elements per bucket.
  3596. */
  3597. void max_load_factor(const float value) {
  3598. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  3599. threshold = value;
  3600. rehash(0u);
  3601. }
  3602. /**
  3603. * @brief Reserves at least the specified number of buckets and regenerates
  3604. * the hash table.
  3605. * @param cnt New number of buckets.
  3606. */
  3607. void rehash(const size_type cnt) {
  3608. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  3609. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  3610. value = value > cap ? value : cap;
  3611. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  3612. sparse.first().resize(sz);
  3613. for(auto &&elem: sparse.first()) {
  3614. elem = placeholder_position;
  3615. }
  3616. for(size_type pos{}, last = size(); pos < last; ++pos) {
  3617. const auto index = key_to_bucket(packed.first()[pos].element.first);
  3618. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  3619. }
  3620. }
  3621. }
  3622. /**
  3623. * @brief Reserves space for at least the specified number of elements and
  3624. * regenerates the hash table.
  3625. * @param cnt New number of elements.
  3626. */
  3627. void reserve(const size_type cnt) {
  3628. packed.first().reserve(cnt);
  3629. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  3630. }
  3631. /**
  3632. * @brief Returns the function used to hash the keys.
  3633. * @return The function used to hash the keys.
  3634. */
  3635. [[nodiscard]] hasher hash_function() const {
  3636. return sparse.second();
  3637. }
  3638. /**
  3639. * @brief Returns the function used to compare keys for equality.
  3640. * @return The function used to compare keys for equality.
  3641. */
  3642. [[nodiscard]] key_equal key_eq() const {
  3643. return packed.second();
  3644. }
  3645. private:
  3646. compressed_pair<sparse_container_type, hasher> sparse;
  3647. compressed_pair<packed_container_type, key_equal> packed;
  3648. float threshold{default_threshold};
  3649. };
  3650. } // namespace entt
  3651. /*! @cond TURN_OFF_DOXYGEN */
  3652. namespace std {
  3653. template<typename Key, typename Value, typename Allocator>
  3654. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  3655. : std::true_type {};
  3656. } // namespace std
  3657. /*! @endcond */
  3658. #endif
  3659. // #include "container/dense_set.hpp"
  3660. #ifndef ENTT_CONTAINER_DENSE_SET_HPP
  3661. #define ENTT_CONTAINER_DENSE_SET_HPP
  3662. #include <cmath>
  3663. #include <cstddef>
  3664. #include <functional>
  3665. #include <iterator>
  3666. #include <limits>
  3667. #include <memory>
  3668. #include <tuple>
  3669. #include <type_traits>
  3670. #include <utility>
  3671. #include <vector>
  3672. // #include "../config/config.h"
  3673. // #include "../core/bit.hpp"
  3674. // #include "../core/compressed_pair.hpp"
  3675. // #include "../core/type_traits.hpp"
  3676. // #include "fwd.hpp"
  3677. namespace entt {
  3678. /*! @cond TURN_OFF_DOXYGEN */
  3679. namespace internal {
  3680. static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  3681. template<typename It>
  3682. class dense_set_iterator final {
  3683. template<typename>
  3684. friend class dense_set_iterator;
  3685. public:
  3686. using value_type = typename It::value_type::second_type;
  3687. using pointer = const value_type *;
  3688. using reference = const value_type &;
  3689. using difference_type = std::ptrdiff_t;
  3690. using iterator_category = std::random_access_iterator_tag;
  3691. constexpr dense_set_iterator() noexcept
  3692. : it{} {}
  3693. constexpr dense_set_iterator(const It iter) noexcept
  3694. : it{iter} {}
  3695. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  3696. constexpr dense_set_iterator(const dense_set_iterator<Other> &other) noexcept
  3697. : it{other.it} {}
  3698. constexpr dense_set_iterator &operator++() noexcept {
  3699. return ++it, *this;
  3700. }
  3701. constexpr dense_set_iterator operator++(int) noexcept {
  3702. const dense_set_iterator orig = *this;
  3703. return ++(*this), orig;
  3704. }
  3705. constexpr dense_set_iterator &operator--() noexcept {
  3706. return --it, *this;
  3707. }
  3708. constexpr dense_set_iterator operator--(int) noexcept {
  3709. const dense_set_iterator orig = *this;
  3710. return operator--(), orig;
  3711. }
  3712. constexpr dense_set_iterator &operator+=(const difference_type value) noexcept {
  3713. it += value;
  3714. return *this;
  3715. }
  3716. constexpr dense_set_iterator operator+(const difference_type value) const noexcept {
  3717. dense_set_iterator copy = *this;
  3718. return (copy += value);
  3719. }
  3720. constexpr dense_set_iterator &operator-=(const difference_type value) noexcept {
  3721. return (*this += -value);
  3722. }
  3723. constexpr dense_set_iterator operator-(const difference_type value) const noexcept {
  3724. return (*this + -value);
  3725. }
  3726. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  3727. return it[value].second;
  3728. }
  3729. [[nodiscard]] constexpr pointer operator->() const noexcept {
  3730. return std::addressof(operator[](0));
  3731. }
  3732. [[nodiscard]] constexpr reference operator*() const noexcept {
  3733. return operator[](0);
  3734. }
  3735. template<typename Lhs, typename Rhs>
  3736. friend constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  3737. template<typename Lhs, typename Rhs>
  3738. friend constexpr bool operator==(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  3739. template<typename Lhs, typename Rhs>
  3740. friend constexpr bool operator<(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  3741. private:
  3742. It it;
  3743. };
  3744. template<typename Lhs, typename Rhs>
  3745. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  3746. return lhs.it - rhs.it;
  3747. }
  3748. template<typename Lhs, typename Rhs>
  3749. [[nodiscard]] constexpr bool operator==(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  3750. return lhs.it == rhs.it;
  3751. }
  3752. template<typename Lhs, typename Rhs>
  3753. [[nodiscard]] constexpr bool operator!=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  3754. return !(lhs == rhs);
  3755. }
  3756. template<typename Lhs, typename Rhs>
  3757. [[nodiscard]] constexpr bool operator<(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  3758. return lhs.it < rhs.it;
  3759. }
  3760. template<typename Lhs, typename Rhs>
  3761. [[nodiscard]] constexpr bool operator>(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  3762. return rhs < lhs;
  3763. }
  3764. template<typename Lhs, typename Rhs>
  3765. [[nodiscard]] constexpr bool operator<=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  3766. return !(lhs > rhs);
  3767. }
  3768. template<typename Lhs, typename Rhs>
  3769. [[nodiscard]] constexpr bool operator>=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  3770. return !(lhs < rhs);
  3771. }
  3772. template<typename It>
  3773. class dense_set_local_iterator final {
  3774. template<typename>
  3775. friend class dense_set_local_iterator;
  3776. public:
  3777. using value_type = typename It::value_type::second_type;
  3778. using pointer = const value_type *;
  3779. using reference = const value_type &;
  3780. using difference_type = std::ptrdiff_t;
  3781. using iterator_category = std::forward_iterator_tag;
  3782. constexpr dense_set_local_iterator() noexcept = default;
  3783. constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept
  3784. : it{iter},
  3785. offset{pos} {}
  3786. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  3787. constexpr dense_set_local_iterator(const dense_set_local_iterator<Other> &other) noexcept
  3788. : it{other.it},
  3789. offset{other.offset} {}
  3790. constexpr dense_set_local_iterator &operator++() noexcept {
  3791. return offset = it[static_cast<typename It::difference_type>(offset)].first, *this;
  3792. }
  3793. constexpr dense_set_local_iterator operator++(int) noexcept {
  3794. const dense_set_local_iterator orig = *this;
  3795. return ++(*this), orig;
  3796. }
  3797. [[nodiscard]] constexpr pointer operator->() const noexcept {
  3798. return std::addressof(it[static_cast<typename It::difference_type>(offset)].second);
  3799. }
  3800. [[nodiscard]] constexpr reference operator*() const noexcept {
  3801. return *operator->();
  3802. }
  3803. [[nodiscard]] constexpr std::size_t index() const noexcept {
  3804. return offset;
  3805. }
  3806. private:
  3807. It it{};
  3808. std::size_t offset{dense_set_placeholder_position};
  3809. };
  3810. template<typename Lhs, typename Rhs>
  3811. [[nodiscard]] constexpr bool operator==(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  3812. return lhs.index() == rhs.index();
  3813. }
  3814. template<typename Lhs, typename Rhs>
  3815. [[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  3816. return !(lhs == rhs);
  3817. }
  3818. } // namespace internal
  3819. /*! @endcond */
  3820. /**
  3821. * @brief Associative container for unique objects of a given type.
  3822. *
  3823. * Internally, elements are organized into buckets. Which bucket an element is
  3824. * placed into depends entirely on its hash. Elements with the same hash code
  3825. * appear in the same bucket.
  3826. *
  3827. * @tparam Type Value type of the associative container.
  3828. * @tparam Hash Type of function to use to hash the values.
  3829. * @tparam KeyEqual Type of function to use to compare the values for equality.
  3830. * @tparam Allocator Type of allocator used to manage memory and elements.
  3831. */
  3832. template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
  3833. class dense_set {
  3834. static constexpr float default_threshold = 0.875f;
  3835. static constexpr std::size_t minimum_capacity = 8u;
  3836. static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position;
  3837. using node_type = std::pair<std::size_t, Type>;
  3838. using alloc_traits = std::allocator_traits<Allocator>;
  3839. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  3840. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  3841. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  3842. template<typename Other>
  3843. [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept {
  3844. return fast_mod(static_cast<size_type>(sparse.second()(value)), bucket_count());
  3845. }
  3846. template<typename Other>
  3847. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) {
  3848. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  3849. if(packed.second()(packed.first()[offset].second, value)) {
  3850. return begin() + static_cast<typename iterator::difference_type>(offset);
  3851. }
  3852. }
  3853. return end();
  3854. }
  3855. template<typename Other>
  3856. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const {
  3857. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  3858. if(packed.second()(packed.first()[offset].second, value)) {
  3859. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  3860. }
  3861. }
  3862. return cend();
  3863. }
  3864. template<typename Other>
  3865. [[nodiscard]] auto insert_or_do_nothing(Other &&value) {
  3866. const auto index = value_to_bucket(value);
  3867. if(auto it = constrained_find(value, index); it != end()) {
  3868. return std::make_pair(it, false);
  3869. }
  3870. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(value));
  3871. sparse.first()[index] = packed.first().size() - 1u;
  3872. rehash_if_required();
  3873. return std::make_pair(--end(), true);
  3874. }
  3875. void move_and_pop(const std::size_t pos) {
  3876. if(const auto last = size() - 1u; pos != last) {
  3877. size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)];
  3878. packed.first()[pos] = std::move(packed.first().back());
  3879. for(; *curr != last; curr = &packed.first()[*curr].first) {}
  3880. *curr = pos;
  3881. }
  3882. packed.first().pop_back();
  3883. }
  3884. void rehash_if_required() {
  3885. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  3886. rehash(bc * 2u);
  3887. }
  3888. }
  3889. public:
  3890. /*! @brief Allocator type. */
  3891. using allocator_type = Allocator;
  3892. /*! @brief Key type of the container. */
  3893. using key_type = Type;
  3894. /*! @brief Value type of the container. */
  3895. using value_type = Type;
  3896. /*! @brief Unsigned integer type. */
  3897. using size_type = std::size_t;
  3898. /*! @brief Signed integer type. */
  3899. using difference_type = std::ptrdiff_t;
  3900. /*! @brief Type of function to use to hash the elements. */
  3901. using hasher = Hash;
  3902. /*! @brief Type of function to use to compare the elements for equality. */
  3903. using key_equal = KeyEqual;
  3904. /*! @brief Random access iterator type. */
  3905. using iterator = internal::dense_set_iterator<typename packed_container_type::iterator>;
  3906. /*! @brief Constant random access iterator type. */
  3907. using const_iterator = internal::dense_set_iterator<typename packed_container_type::const_iterator>;
  3908. /*! @brief Reverse iterator type. */
  3909. using reverse_iterator = std::reverse_iterator<iterator>;
  3910. /*! @brief Constant reverse iterator type. */
  3911. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  3912. /*! @brief Forward iterator type. */
  3913. using local_iterator = internal::dense_set_local_iterator<typename packed_container_type::iterator>;
  3914. /*! @brief Constant forward iterator type. */
  3915. using const_local_iterator = internal::dense_set_local_iterator<typename packed_container_type::const_iterator>;
  3916. /*! @brief Default constructor. */
  3917. dense_set()
  3918. : dense_set{minimum_capacity} {}
  3919. /**
  3920. * @brief Constructs an empty container with a given allocator.
  3921. * @param allocator The allocator to use.
  3922. */
  3923. explicit dense_set(const allocator_type &allocator)
  3924. : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  3925. /**
  3926. * @brief Constructs an empty container with a given allocator and user
  3927. * supplied minimal number of buckets.
  3928. * @param cnt Minimal number of buckets.
  3929. * @param allocator The allocator to use.
  3930. */
  3931. dense_set(const size_type cnt, const allocator_type &allocator)
  3932. : dense_set{cnt, hasher{}, key_equal{}, allocator} {}
  3933. /**
  3934. * @brief Constructs an empty container with a given allocator, hash
  3935. * function and user supplied minimal number of buckets.
  3936. * @param cnt Minimal number of buckets.
  3937. * @param hash Hash function to use.
  3938. * @param allocator The allocator to use.
  3939. */
  3940. dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  3941. : dense_set{cnt, hash, key_equal{}, allocator} {}
  3942. /**
  3943. * @brief Constructs an empty container with a given allocator, hash
  3944. * function, compare function and user supplied minimal number of buckets.
  3945. * @param cnt Minimal number of buckets.
  3946. * @param hash Hash function to use.
  3947. * @param equal Compare function to use.
  3948. * @param allocator The allocator to use.
  3949. */
  3950. explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  3951. : sparse{allocator, hash},
  3952. packed{allocator, equal} {
  3953. rehash(cnt);
  3954. }
  3955. /*! @brief Default copy constructor. */
  3956. dense_set(const dense_set &) = default;
  3957. /**
  3958. * @brief Allocator-extended copy constructor.
  3959. * @param other The instance to copy from.
  3960. * @param allocator The allocator to use.
  3961. */
  3962. dense_set(const dense_set &other, const allocator_type &allocator)
  3963. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  3964. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  3965. threshold{other.threshold} {}
  3966. /*! @brief Default move constructor. */
  3967. dense_set(dense_set &&) noexcept = default;
  3968. /**
  3969. * @brief Allocator-extended move constructor.
  3970. * @param other The instance to move from.
  3971. * @param allocator The allocator to use.
  3972. */
  3973. dense_set(dense_set &&other, const allocator_type &allocator)
  3974. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  3975. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  3976. threshold{other.threshold} {}
  3977. /*! @brief Default destructor. */
  3978. ~dense_set() = default;
  3979. /**
  3980. * @brief Default copy assignment operator.
  3981. * @return This container.
  3982. */
  3983. dense_set &operator=(const dense_set &) = default;
  3984. /**
  3985. * @brief Default move assignment operator.
  3986. * @return This container.
  3987. */
  3988. dense_set &operator=(dense_set &&) noexcept = default;
  3989. /**
  3990. * @brief Exchanges the contents with those of a given container.
  3991. * @param other Container to exchange the content with.
  3992. */
  3993. void swap(dense_set &other) noexcept {
  3994. using std::swap;
  3995. swap(sparse, other.sparse);
  3996. swap(packed, other.packed);
  3997. swap(threshold, other.threshold);
  3998. }
  3999. /**
  4000. * @brief Returns the associated allocator.
  4001. * @return The associated allocator.
  4002. */
  4003. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  4004. return sparse.first().get_allocator();
  4005. }
  4006. /**
  4007. * @brief Returns an iterator to the beginning.
  4008. *
  4009. * If the array is empty, the returned iterator will be equal to `end()`.
  4010. *
  4011. * @return An iterator to the first instance of the internal array.
  4012. */
  4013. [[nodiscard]] const_iterator cbegin() const noexcept {
  4014. return packed.first().begin();
  4015. }
  4016. /*! @copydoc cbegin */
  4017. [[nodiscard]] const_iterator begin() const noexcept {
  4018. return cbegin();
  4019. }
  4020. /*! @copydoc begin */
  4021. [[nodiscard]] iterator begin() noexcept {
  4022. return packed.first().begin();
  4023. }
  4024. /**
  4025. * @brief Returns an iterator to the end.
  4026. * @return An iterator to the element following the last instance of the
  4027. * internal array.
  4028. */
  4029. [[nodiscard]] const_iterator cend() const noexcept {
  4030. return packed.first().end();
  4031. }
  4032. /*! @copydoc cend */
  4033. [[nodiscard]] const_iterator end() const noexcept {
  4034. return cend();
  4035. }
  4036. /*! @copydoc end */
  4037. [[nodiscard]] iterator end() noexcept {
  4038. return packed.first().end();
  4039. }
  4040. /**
  4041. * @brief Returns a reverse iterator to the beginning.
  4042. *
  4043. * If the array is empty, the returned iterator will be equal to `rend()`.
  4044. *
  4045. * @return An iterator to the first instance of the reversed internal array.
  4046. */
  4047. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  4048. return std::make_reverse_iterator(cend());
  4049. }
  4050. /*! @copydoc crbegin */
  4051. [[nodiscard]] const_reverse_iterator rbegin() const noexcept {
  4052. return crbegin();
  4053. }
  4054. /*! @copydoc rbegin */
  4055. [[nodiscard]] reverse_iterator rbegin() noexcept {
  4056. return std::make_reverse_iterator(end());
  4057. }
  4058. /**
  4059. * @brief Returns a reverse iterator to the end.
  4060. * @return An iterator to the element following the last instance of the
  4061. * reversed internal array.
  4062. */
  4063. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  4064. return std::make_reverse_iterator(cbegin());
  4065. }
  4066. /*! @copydoc crend */
  4067. [[nodiscard]] const_reverse_iterator rend() const noexcept {
  4068. return crend();
  4069. }
  4070. /*! @copydoc rend */
  4071. [[nodiscard]] reverse_iterator rend() noexcept {
  4072. return std::make_reverse_iterator(begin());
  4073. }
  4074. /**
  4075. * @brief Checks whether a container is empty.
  4076. * @return True if the container is empty, false otherwise.
  4077. */
  4078. [[nodiscard]] bool empty() const noexcept {
  4079. return packed.first().empty();
  4080. }
  4081. /**
  4082. * @brief Returns the number of elements in a container.
  4083. * @return Number of elements in a container.
  4084. */
  4085. [[nodiscard]] size_type size() const noexcept {
  4086. return packed.first().size();
  4087. }
  4088. /**
  4089. * @brief Returns the maximum possible number of elements.
  4090. * @return Maximum possible number of elements.
  4091. */
  4092. [[nodiscard]] size_type max_size() const noexcept {
  4093. return packed.first().max_size();
  4094. }
  4095. /*! @brief Clears the container. */
  4096. void clear() noexcept {
  4097. sparse.first().clear();
  4098. packed.first().clear();
  4099. rehash(0u);
  4100. }
  4101. /**
  4102. * @brief Inserts an element into the container, if it does not exist.
  4103. * @param value An element to insert into the container.
  4104. * @return A pair consisting of an iterator to the inserted element (or to
  4105. * the element that prevented the insertion) and a bool denoting whether the
  4106. * insertion took place.
  4107. */
  4108. std::pair<iterator, bool> insert(const value_type &value) {
  4109. return insert_or_do_nothing(value);
  4110. }
  4111. /*! @copydoc insert */
  4112. std::pair<iterator, bool> insert(value_type &&value) {
  4113. return insert_or_do_nothing(std::move(value));
  4114. }
  4115. /**
  4116. * @brief Inserts elements into the container, if they do not exist.
  4117. * @tparam It Type of input iterator.
  4118. * @param first An iterator to the first element of the range of elements.
  4119. * @param last An iterator past the last element of the range of elements.
  4120. */
  4121. template<typename It>
  4122. void insert(It first, It last) {
  4123. for(; first != last; ++first) {
  4124. insert(*first);
  4125. }
  4126. }
  4127. /**
  4128. * @brief Constructs an element in-place, if it does not exist.
  4129. *
  4130. * The element is also constructed when the container already has the key,
  4131. * in which case the newly constructed object is destroyed immediately.
  4132. *
  4133. * @tparam Args Types of arguments to forward to the constructor of the
  4134. * element.
  4135. * @param args Arguments to forward to the constructor of the element.
  4136. * @return A pair consisting of an iterator to the inserted element (or to
  4137. * the element that prevented the insertion) and a bool denoting whether the
  4138. * insertion took place.
  4139. */
  4140. template<typename... Args>
  4141. std::pair<iterator, bool> emplace(Args &&...args) {
  4142. if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v<std::decay_t<Args>, value_type>)) {
  4143. return insert_or_do_nothing(std::forward<Args>(args)...);
  4144. } else {
  4145. auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward<Args>(args)...));
  4146. const auto index = value_to_bucket(node.second);
  4147. if(auto it = constrained_find(node.second, index); it != end()) {
  4148. packed.first().pop_back();
  4149. return std::make_pair(it, false);
  4150. }
  4151. std::swap(node.first, sparse.first()[index]);
  4152. rehash_if_required();
  4153. return std::make_pair(--end(), true);
  4154. }
  4155. }
  4156. /**
  4157. * @brief Removes an element from a given position.
  4158. * @param pos An iterator to the element to remove.
  4159. * @return An iterator following the removed element.
  4160. */
  4161. iterator erase(const_iterator pos) {
  4162. const auto diff = pos - cbegin();
  4163. erase(*pos);
  4164. return begin() + diff;
  4165. }
  4166. /**
  4167. * @brief Removes the given elements from a container.
  4168. * @param first An iterator to the first element of the range of elements.
  4169. * @param last An iterator past the last element of the range of elements.
  4170. * @return An iterator following the last removed element.
  4171. */
  4172. iterator erase(const_iterator first, const_iterator last) {
  4173. const auto dist = first - cbegin();
  4174. for(auto from = last - cbegin(); from != dist; --from) {
  4175. erase(packed.first()[static_cast<size_type>(from) - 1u].second);
  4176. }
  4177. return (begin() + dist);
  4178. }
  4179. /**
  4180. * @brief Removes the element associated with a given value.
  4181. * @param value Value of an element to remove.
  4182. * @return Number of elements removed (either 0 or 1).
  4183. */
  4184. size_type erase(const value_type &value) {
  4185. for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) {
  4186. if(packed.second()(packed.first()[*curr].second, value)) {
  4187. const auto index = *curr;
  4188. *curr = packed.first()[*curr].first;
  4189. move_and_pop(index);
  4190. return 1u;
  4191. }
  4192. }
  4193. return 0u;
  4194. }
  4195. /**
  4196. * @brief Returns the number of elements matching a value (either 1 or 0).
  4197. * @param key Key value of an element to search for.
  4198. * @return Number of elements matching the key (either 1 or 0).
  4199. */
  4200. [[nodiscard]] size_type count(const value_type &key) const {
  4201. return find(key) != end();
  4202. }
  4203. /**
  4204. * @brief Returns the number of elements matching a key (either 1 or 0).
  4205. * @tparam Other Type of the key value of an element to search for.
  4206. * @param key Key value of an element to search for.
  4207. * @return Number of elements matching the key (either 1 or 0).
  4208. */
  4209. template<typename Other>
  4210. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  4211. count(const Other &key) const {
  4212. return find(key) != end();
  4213. }
  4214. /**
  4215. * @brief Finds an element with a given value.
  4216. * @param value Value of an element to search for.
  4217. * @return An iterator to an element with the given value. If no such
  4218. * element is found, a past-the-end iterator is returned.
  4219. */
  4220. [[nodiscard]] iterator find(const value_type &value) {
  4221. return constrained_find(value, value_to_bucket(value));
  4222. }
  4223. /*! @copydoc find */
  4224. [[nodiscard]] const_iterator find(const value_type &value) const {
  4225. return constrained_find(value, value_to_bucket(value));
  4226. }
  4227. /**
  4228. * @brief Finds an element that compares _equivalent_ to a given value.
  4229. * @tparam Other Type of an element to search for.
  4230. * @param value Value of an element to search for.
  4231. * @return An iterator to an element with the given value. If no such
  4232. * element is found, a past-the-end iterator is returned.
  4233. */
  4234. template<typename Other>
  4235. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  4236. find(const Other &value) {
  4237. return constrained_find(value, value_to_bucket(value));
  4238. }
  4239. /*! @copydoc find */
  4240. template<typename Other>
  4241. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  4242. find(const Other &value) const {
  4243. return constrained_find(value, value_to_bucket(value));
  4244. }
  4245. /**
  4246. * @brief Returns a range containing all elements with a given value.
  4247. * @param value Value of an element to search for.
  4248. * @return A pair of iterators pointing to the first element and past the
  4249. * last element of the range.
  4250. */
  4251. [[nodiscard]] std::pair<iterator, iterator> equal_range(const value_type &value) {
  4252. const auto it = find(value);
  4253. return {it, it + !(it == end())};
  4254. }
  4255. /*! @copydoc equal_range */
  4256. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const value_type &value) const {
  4257. const auto it = find(value);
  4258. return {it, it + !(it == cend())};
  4259. }
  4260. /**
  4261. * @brief Returns a range containing all elements that compare _equivalent_
  4262. * to a given value.
  4263. * @tparam Other Type of an element to search for.
  4264. * @param value Value of an element to search for.
  4265. * @return A pair of iterators pointing to the first element and past the
  4266. * last element of the range.
  4267. */
  4268. template<typename Other>
  4269. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  4270. equal_range(const Other &value) {
  4271. const auto it = find(value);
  4272. return {it, it + !(it == end())};
  4273. }
  4274. /*! @copydoc equal_range */
  4275. template<typename Other>
  4276. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  4277. equal_range(const Other &value) const {
  4278. const auto it = find(value);
  4279. return {it, it + !(it == cend())};
  4280. }
  4281. /**
  4282. * @brief Checks if the container contains an element with a given value.
  4283. * @param value Value of an element to search for.
  4284. * @return True if there is such an element, false otherwise.
  4285. */
  4286. [[nodiscard]] bool contains(const value_type &value) const {
  4287. return (find(value) != cend());
  4288. }
  4289. /**
  4290. * @brief Checks if the container contains an element that compares
  4291. * _equivalent_ to a given value.
  4292. * @tparam Other Type of an element to search for.
  4293. * @param value Value of an element to search for.
  4294. * @return True if there is such an element, false otherwise.
  4295. */
  4296. template<typename Other>
  4297. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  4298. contains(const Other &value) const {
  4299. return (find(value) != cend());
  4300. }
  4301. /**
  4302. * @brief Returns an iterator to the beginning of a given bucket.
  4303. * @param index An index of a bucket to access.
  4304. * @return An iterator to the beginning of the given bucket.
  4305. */
  4306. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  4307. return {packed.first().begin(), sparse.first()[index]};
  4308. }
  4309. /**
  4310. * @brief Returns an iterator to the beginning of a given bucket.
  4311. * @param index An index of a bucket to access.
  4312. * @return An iterator to the beginning of the given bucket.
  4313. */
  4314. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  4315. return cbegin(index);
  4316. }
  4317. /**
  4318. * @brief Returns an iterator to the beginning of a given bucket.
  4319. * @param index An index of a bucket to access.
  4320. * @return An iterator to the beginning of the given bucket.
  4321. */
  4322. [[nodiscard]] local_iterator begin(const size_type index) {
  4323. return {packed.first().begin(), sparse.first()[index]};
  4324. }
  4325. /**
  4326. * @brief Returns an iterator to the end of a given bucket.
  4327. * @param index An index of a bucket to access.
  4328. * @return An iterator to the end of the given bucket.
  4329. */
  4330. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  4331. return {};
  4332. }
  4333. /**
  4334. * @brief Returns an iterator to the end of a given bucket.
  4335. * @param index An index of a bucket to access.
  4336. * @return An iterator to the end of the given bucket.
  4337. */
  4338. [[nodiscard]] const_local_iterator end(const size_type index) const {
  4339. return cend(index);
  4340. }
  4341. /**
  4342. * @brief Returns an iterator to the end of a given bucket.
  4343. * @param index An index of a bucket to access.
  4344. * @return An iterator to the end of the given bucket.
  4345. */
  4346. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  4347. return {};
  4348. }
  4349. /**
  4350. * @brief Returns the number of buckets.
  4351. * @return The number of buckets.
  4352. */
  4353. [[nodiscard]] size_type bucket_count() const {
  4354. return sparse.first().size();
  4355. }
  4356. /**
  4357. * @brief Returns the maximum number of buckets.
  4358. * @return The maximum number of buckets.
  4359. */
  4360. [[nodiscard]] size_type max_bucket_count() const {
  4361. return sparse.first().max_size();
  4362. }
  4363. /**
  4364. * @brief Returns the number of elements in a given bucket.
  4365. * @param index The index of the bucket to examine.
  4366. * @return The number of elements in the given bucket.
  4367. */
  4368. [[nodiscard]] size_type bucket_size(const size_type index) const {
  4369. return static_cast<size_type>(std::distance(begin(index), end(index)));
  4370. }
  4371. /**
  4372. * @brief Returns the bucket for a given element.
  4373. * @param value The value of the element to examine.
  4374. * @return The bucket for the given element.
  4375. */
  4376. [[nodiscard]] size_type bucket(const value_type &value) const {
  4377. return value_to_bucket(value);
  4378. }
  4379. /**
  4380. * @brief Returns the average number of elements per bucket.
  4381. * @return The average number of elements per bucket.
  4382. */
  4383. [[nodiscard]] float load_factor() const {
  4384. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  4385. }
  4386. /**
  4387. * @brief Returns the maximum average number of elements per bucket.
  4388. * @return The maximum average number of elements per bucket.
  4389. */
  4390. [[nodiscard]] float max_load_factor() const {
  4391. return threshold;
  4392. }
  4393. /**
  4394. * @brief Sets the desired maximum average number of elements per bucket.
  4395. * @param value A desired maximum average number of elements per bucket.
  4396. */
  4397. void max_load_factor(const float value) {
  4398. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  4399. threshold = value;
  4400. rehash(0u);
  4401. }
  4402. /**
  4403. * @brief Reserves at least the specified number of buckets and regenerates
  4404. * the hash table.
  4405. * @param cnt New number of buckets.
  4406. */
  4407. void rehash(const size_type cnt) {
  4408. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  4409. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  4410. value = value > cap ? value : cap;
  4411. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  4412. sparse.first().resize(sz);
  4413. for(auto &&elem: sparse.first()) {
  4414. elem = placeholder_position;
  4415. }
  4416. for(size_type pos{}, last = size(); pos < last; ++pos) {
  4417. const auto index = value_to_bucket(packed.first()[pos].second);
  4418. packed.first()[pos].first = std::exchange(sparse.first()[index], pos);
  4419. }
  4420. }
  4421. }
  4422. /**
  4423. * @brief Reserves space for at least the specified number of elements and
  4424. * regenerates the hash table.
  4425. * @param cnt New number of elements.
  4426. */
  4427. void reserve(const size_type cnt) {
  4428. packed.first().reserve(cnt);
  4429. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  4430. }
  4431. /**
  4432. * @brief Returns the function used to hash the elements.
  4433. * @return The function used to hash the elements.
  4434. */
  4435. [[nodiscard]] hasher hash_function() const {
  4436. return sparse.second();
  4437. }
  4438. /**
  4439. * @brief Returns the function used to compare elements for equality.
  4440. * @return The function used to compare elements for equality.
  4441. */
  4442. [[nodiscard]] key_equal key_eq() const {
  4443. return packed.second();
  4444. }
  4445. private:
  4446. compressed_pair<sparse_container_type, hasher> sparse;
  4447. compressed_pair<packed_container_type, key_equal> packed;
  4448. float threshold{default_threshold};
  4449. };
  4450. } // namespace entt
  4451. #endif
  4452. // #include "container/table.hpp"
  4453. #ifndef ENTT_CONTAINER_TABLE_HPP
  4454. #define ENTT_CONTAINER_TABLE_HPP
  4455. #include <cstddef>
  4456. #include <iterator>
  4457. #include <tuple>
  4458. #include <type_traits>
  4459. #include <utility>
  4460. // #include "../config/config.h"
  4461. // #include "../core/iterator.hpp"
  4462. // #include "fwd.hpp"
  4463. namespace entt {
  4464. /*! @cond TURN_OFF_DOXYGEN */
  4465. namespace internal {
  4466. template<typename... It>
  4467. class table_iterator {
  4468. template<typename...>
  4469. friend class table_iterator;
  4470. public:
  4471. using value_type = decltype(std::forward_as_tuple(*std::declval<It>()...));
  4472. using pointer = input_iterator_pointer<value_type>;
  4473. using reference = value_type;
  4474. using difference_type = std::ptrdiff_t;
  4475. using iterator_category = std::input_iterator_tag;
  4476. using iterator_concept = std::random_access_iterator_tag;
  4477. constexpr table_iterator() noexcept
  4478. : it{} {}
  4479. constexpr table_iterator(It... from) noexcept
  4480. : it{from...} {}
  4481. template<typename... Other, typename = std::enable_if_t<(std::is_constructible_v<It, Other> && ...)>>
  4482. constexpr table_iterator(const table_iterator<Other...> &other) noexcept
  4483. : table_iterator{std::get<Other>(other.it)...} {}
  4484. constexpr table_iterator &operator++() noexcept {
  4485. return (++std::get<It>(it), ...), *this;
  4486. }
  4487. constexpr table_iterator operator++(int) noexcept {
  4488. const table_iterator orig = *this;
  4489. return ++(*this), orig;
  4490. }
  4491. constexpr table_iterator &operator--() noexcept {
  4492. return (--std::get<It>(it), ...), *this;
  4493. }
  4494. constexpr table_iterator operator--(int) noexcept {
  4495. const table_iterator orig = *this;
  4496. return operator--(), orig;
  4497. }
  4498. constexpr table_iterator &operator+=(const difference_type value) noexcept {
  4499. return ((std::get<It>(it) += value), ...), *this;
  4500. }
  4501. constexpr table_iterator operator+(const difference_type value) const noexcept {
  4502. table_iterator copy = *this;
  4503. return (copy += value);
  4504. }
  4505. constexpr table_iterator &operator-=(const difference_type value) noexcept {
  4506. return (*this += -value);
  4507. }
  4508. constexpr table_iterator operator-(const difference_type value) const noexcept {
  4509. return (*this + -value);
  4510. }
  4511. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  4512. return std::forward_as_tuple(std::get<It>(it)[value]...);
  4513. }
  4514. [[nodiscard]] constexpr pointer operator->() const noexcept {
  4515. return {operator[](0)};
  4516. }
  4517. [[nodiscard]] constexpr reference operator*() const noexcept {
  4518. return operator[](0);
  4519. }
  4520. template<typename... Lhs, typename... Rhs>
  4521. friend constexpr std::ptrdiff_t operator-(const table_iterator<Lhs...> &, const table_iterator<Rhs...> &) noexcept;
  4522. template<typename... Lhs, typename... Rhs>
  4523. friend constexpr bool operator==(const table_iterator<Lhs...> &, const table_iterator<Rhs...> &) noexcept;
  4524. template<typename... Lhs, typename... Rhs>
  4525. friend constexpr bool operator<(const table_iterator<Lhs...> &, const table_iterator<Rhs...> &) noexcept;
  4526. private:
  4527. std::tuple<It...> it;
  4528. };
  4529. template<typename... Lhs, typename... Rhs>
  4530. [[nodiscard]] constexpr std::ptrdiff_t operator-(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
  4531. return std::get<0>(lhs.it) - std::get<0>(rhs.it);
  4532. }
  4533. template<typename... Lhs, typename... Rhs>
  4534. [[nodiscard]] constexpr bool operator==(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
  4535. return std::get<0>(lhs.it) == std::get<0>(rhs.it);
  4536. }
  4537. template<typename... Lhs, typename... Rhs>
  4538. [[nodiscard]] constexpr bool operator!=(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
  4539. return !(lhs == rhs);
  4540. }
  4541. template<typename... Lhs, typename... Rhs>
  4542. [[nodiscard]] constexpr bool operator<(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
  4543. return std::get<0>(lhs.it) < std::get<0>(rhs.it);
  4544. }
  4545. template<typename... Lhs, typename... Rhs>
  4546. [[nodiscard]] constexpr bool operator>(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
  4547. return rhs < lhs;
  4548. }
  4549. template<typename... Lhs, typename... Rhs>
  4550. [[nodiscard]] constexpr bool operator<=(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
  4551. return !(lhs > rhs);
  4552. }
  4553. template<typename... Lhs, typename... Rhs>
  4554. [[nodiscard]] constexpr bool operator>=(const table_iterator<Lhs...> &lhs, const table_iterator<Rhs...> &rhs) noexcept {
  4555. return !(lhs < rhs);
  4556. }
  4557. } // namespace internal
  4558. /*! @endcond */
  4559. /**
  4560. * @brief Basic table implementation.
  4561. *
  4562. * Internal data structures arrange elements to maximize performance. There are
  4563. * no guarantees that objects are returned in the insertion order when iterate
  4564. * a table. Do not make assumption on the order in any case.
  4565. *
  4566. * @tparam Container Sequence container row types.
  4567. */
  4568. template<typename... Container>
  4569. class basic_table {
  4570. using container_type = std::tuple<Container...>;
  4571. public:
  4572. /*! @brief Unsigned integer type. */
  4573. using size_type = std::size_t;
  4574. /*! @brief Signed integer type. */
  4575. using difference_type = std::ptrdiff_t;
  4576. /*! @brief Input iterator type. */
  4577. using iterator = internal::table_iterator<typename Container::iterator...>;
  4578. /*! @brief Constant input iterator type. */
  4579. using const_iterator = internal::table_iterator<typename Container::const_iterator...>;
  4580. /*! @brief Reverse iterator type. */
  4581. using reverse_iterator = internal::table_iterator<typename Container::reverse_iterator...>;
  4582. /*! @brief Constant reverse iterator type. */
  4583. using const_reverse_iterator = internal::table_iterator<typename Container::const_reverse_iterator...>;
  4584. /*! @brief Default constructor. */
  4585. basic_table()
  4586. : payload{} {
  4587. }
  4588. /**
  4589. * @brief Copy constructs the underlying containers.
  4590. * @param container The containers to copy from.
  4591. */
  4592. explicit basic_table(const Container &...container) noexcept
  4593. : payload{container...} {
  4594. ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
  4595. }
  4596. /**
  4597. * @brief Move constructs the underlying containers.
  4598. * @param container The containers to move from.
  4599. */
  4600. explicit basic_table(Container &&...container) noexcept
  4601. : payload{std::move(container)...} {
  4602. ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
  4603. }
  4604. /*! @brief Default copy constructor, deleted on purpose. */
  4605. basic_table(const basic_table &) = delete;
  4606. /**
  4607. * @brief Move constructor.
  4608. * @param other The instance to move from.
  4609. */
  4610. basic_table(basic_table &&other) noexcept
  4611. : payload{std::move(other.payload)} {}
  4612. /**
  4613. * @brief Constructs the underlying containers using a given allocator.
  4614. * @tparam Allocator Type of allocator.
  4615. * @param allocator A valid allocator.
  4616. */
  4617. template<typename Allocator>
  4618. explicit basic_table(const Allocator &allocator)
  4619. : payload{Container{allocator}...} {}
  4620. /**
  4621. * @brief Copy constructs the underlying containers using a given allocator.
  4622. * @tparam Allocator Type of allocator.
  4623. * @param container The containers to copy from.
  4624. * @param allocator A valid allocator.
  4625. */
  4626. template<class Allocator>
  4627. basic_table(const Container &...container, const Allocator &allocator) noexcept
  4628. : payload{Container{container, allocator}...} {
  4629. ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
  4630. }
  4631. /**
  4632. * @brief Move constructs the underlying containers using a given allocator.
  4633. * @tparam Allocator Type of allocator.
  4634. * @param container The containers to move from.
  4635. * @param allocator A valid allocator.
  4636. */
  4637. template<class Allocator>
  4638. basic_table(Container &&...container, const Allocator &allocator) noexcept
  4639. : payload{Container{std::move(container), allocator}...} {
  4640. ENTT_ASSERT((((std::get<Container>(payload).size() * sizeof...(Container)) == (std::get<Container>(payload).size() + ...)) && ...), "Unexpected container size");
  4641. }
  4642. /**
  4643. * @brief Allocator-extended move constructor.
  4644. * @tparam Allocator Type of allocator.
  4645. * @param other The instance to move from.
  4646. * @param allocator The allocator to use.
  4647. */
  4648. template<class Allocator>
  4649. basic_table(basic_table &&other, const Allocator &allocator)
  4650. : payload{Container{std::move(std::get<Container>(other.payload)), allocator}...} {}
  4651. /*! @brief Default destructor. */
  4652. ~basic_table() = default;
  4653. /**
  4654. * @brief Default copy assignment operator, deleted on purpose.
  4655. * @return This container.
  4656. */
  4657. basic_table &operator=(const basic_table &) = delete;
  4658. /**
  4659. * @brief Move assignment operator.
  4660. * @param other The instance to move from.
  4661. * @return This container.
  4662. */
  4663. basic_table &operator=(basic_table &&other) noexcept {
  4664. swap(other);
  4665. return *this;
  4666. }
  4667. /**
  4668. * @brief Exchanges the contents with those of a given table.
  4669. * @param other Table to exchange the content with.
  4670. */
  4671. void swap(basic_table &other) noexcept {
  4672. using std::swap;
  4673. swap(payload, other.payload);
  4674. }
  4675. /**
  4676. * @brief Increases the capacity of a table.
  4677. *
  4678. * If the new capacity is greater than the current capacity, new storage is
  4679. * allocated, otherwise the method does nothing.
  4680. *
  4681. * @param cap Desired capacity.
  4682. */
  4683. void reserve(const size_type cap) {
  4684. (std::get<Container>(payload).reserve(cap), ...);
  4685. }
  4686. /**
  4687. * @brief Returns the number of rows that a table has currently allocated
  4688. * space for.
  4689. * @return Capacity of the table.
  4690. */
  4691. [[nodiscard]] size_type capacity() const noexcept {
  4692. return std::get<0>(payload).capacity();
  4693. }
  4694. /*! @brief Requests the removal of unused capacity. */
  4695. void shrink_to_fit() {
  4696. (std::get<Container>(payload).shrink_to_fit(), ...);
  4697. }
  4698. /**
  4699. * @brief Returns the number of rows in a table.
  4700. * @return Number of rows.
  4701. */
  4702. [[nodiscard]] size_type size() const noexcept {
  4703. return std::get<0>(payload).size();
  4704. }
  4705. /**
  4706. * @brief Checks whether a table is empty.
  4707. * @return True if the table is empty, false otherwise.
  4708. */
  4709. [[nodiscard]] bool empty() const noexcept {
  4710. return std::get<0>(payload).empty();
  4711. }
  4712. /**
  4713. * @brief Returns an iterator to the beginning.
  4714. *
  4715. * If the table is empty, the returned iterator will be equal to `end()`.
  4716. *
  4717. * @return An iterator to the first row of the table.
  4718. */
  4719. [[nodiscard]] const_iterator cbegin() const noexcept {
  4720. return {std::get<Container>(payload).cbegin()...};
  4721. }
  4722. /*! @copydoc cbegin */
  4723. [[nodiscard]] const_iterator begin() const noexcept {
  4724. return cbegin();
  4725. }
  4726. /*! @copydoc begin */
  4727. [[nodiscard]] iterator begin() noexcept {
  4728. return {std::get<Container>(payload).begin()...};
  4729. }
  4730. /**
  4731. * @brief Returns an iterator to the end.
  4732. * @return An iterator to the element following the last row of the table.
  4733. */
  4734. [[nodiscard]] const_iterator cend() const noexcept {
  4735. return {std::get<Container>(payload).cend()...};
  4736. }
  4737. /*! @copydoc cend */
  4738. [[nodiscard]] const_iterator end() const noexcept {
  4739. return cend();
  4740. }
  4741. /*! @copydoc end */
  4742. [[nodiscard]] iterator end() noexcept {
  4743. return {std::get<Container>(payload).end()...};
  4744. }
  4745. /**
  4746. * @brief Returns a reverse iterator to the beginning.
  4747. *
  4748. * If the table is empty, the returned iterator will be equal to `rend()`.
  4749. *
  4750. * @return An iterator to the first row of the reversed table.
  4751. */
  4752. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  4753. return {std::get<Container>(payload).crbegin()...};
  4754. }
  4755. /*! @copydoc crbegin */
  4756. [[nodiscard]] const_reverse_iterator rbegin() const noexcept {
  4757. return crbegin();
  4758. }
  4759. /*! @copydoc rbegin */
  4760. [[nodiscard]] reverse_iterator rbegin() noexcept {
  4761. return {std::get<Container>(payload).rbegin()...};
  4762. }
  4763. /**
  4764. * @brief Returns a reverse iterator to the end.
  4765. * @return An iterator to the element following the last row of the reversed
  4766. * table.
  4767. */
  4768. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  4769. return {std::get<Container>(payload).crend()...};
  4770. }
  4771. /*! @copydoc crend */
  4772. [[nodiscard]] const_reverse_iterator rend() const noexcept {
  4773. return crend();
  4774. }
  4775. /*! @copydoc rend */
  4776. [[nodiscard]] reverse_iterator rend() noexcept {
  4777. return {std::get<Container>(payload).rend()...};
  4778. }
  4779. /**
  4780. * @brief Appends a row to the end of a table.
  4781. * @tparam Args Types of arguments to use to construct the row data.
  4782. * @param args Parameters to use to construct the row data.
  4783. * @return A reference to the newly created row data.
  4784. */
  4785. template<typename... Args>
  4786. std::tuple<typename Container::value_type &...> emplace(Args &&...args) {
  4787. if constexpr(sizeof...(Args) == 0u) {
  4788. return std::forward_as_tuple(std::get<Container>(payload).emplace_back()...);
  4789. } else {
  4790. return std::forward_as_tuple(std::get<Container>(payload).emplace_back(std::forward<Args>(args))...);
  4791. }
  4792. }
  4793. /**
  4794. * @brief Removes a row from a table.
  4795. * @param pos An iterator to the row to remove.
  4796. * @return An iterator following the removed row.
  4797. */
  4798. iterator erase(const_iterator pos) {
  4799. const auto diff = pos - begin();
  4800. return {std::get<Container>(payload).erase(std::get<Container>(payload).begin() + diff)...};
  4801. }
  4802. /**
  4803. * @brief Removes a row from a table.
  4804. * @param pos Index of the row to remove.
  4805. */
  4806. void erase(const size_type pos) {
  4807. ENTT_ASSERT(pos < size(), "Index out of bounds");
  4808. erase(begin() + static_cast<difference_type>(pos));
  4809. }
  4810. /**
  4811. * @brief Returns the row data at specified location.
  4812. * @param pos The row for which to return the data.
  4813. * @return The row data at specified location.
  4814. */
  4815. [[nodiscard]] std::tuple<const typename Container::value_type &...> operator[](const size_type pos) const {
  4816. ENTT_ASSERT(pos < size(), "Index out of bounds");
  4817. return std::forward_as_tuple(std::get<Container>(payload)[pos]...);
  4818. }
  4819. /*! @copydoc operator[] */
  4820. [[nodiscard]] std::tuple<typename Container::value_type &...> operator[](const size_type pos) {
  4821. ENTT_ASSERT(pos < size(), "Index out of bounds");
  4822. return std::forward_as_tuple(std::get<Container>(payload)[pos]...);
  4823. }
  4824. /*! @brief Clears a table. */
  4825. void clear() {
  4826. (std::get<Container>(payload).clear(), ...);
  4827. }
  4828. private:
  4829. container_type payload;
  4830. };
  4831. } // namespace entt
  4832. /*! @cond TURN_OFF_DOXYGEN */
  4833. namespace std {
  4834. template<typename... Container, typename Allocator>
  4835. struct uses_allocator<entt::basic_table<Container...>, Allocator>
  4836. : std::bool_constant<(std::uses_allocator_v<Container, Allocator> && ...)> {};
  4837. } // namespace std
  4838. /*! @endcond */
  4839. #endif
  4840. // #include "core/algorithm.hpp"
  4841. #ifndef ENTT_CORE_ALGORITHM_HPP
  4842. #define ENTT_CORE_ALGORITHM_HPP
  4843. #include <algorithm>
  4844. #include <functional>
  4845. #include <iterator>
  4846. #include <utility>
  4847. #include <vector>
  4848. // #include "utility.hpp"
  4849. #ifndef ENTT_CORE_UTILITY_HPP
  4850. #define ENTT_CORE_UTILITY_HPP
  4851. #include <type_traits>
  4852. #include <utility>
  4853. namespace entt {
  4854. /*! @brief Identity function object (waiting for C++20). */
  4855. struct identity {
  4856. /*! @brief Indicates that this is a transparent function object. */
  4857. using is_transparent = void;
  4858. /**
  4859. * @brief Returns its argument unchanged.
  4860. * @tparam Type Type of the argument.
  4861. * @param value The actual argument.
  4862. * @return The submitted value as-is.
  4863. */
  4864. template<typename Type>
  4865. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  4866. return std::forward<Type>(value);
  4867. }
  4868. };
  4869. /**
  4870. * @brief Constant utility to disambiguate overloaded members of a class.
  4871. * @tparam Type Type of the desired overload.
  4872. * @tparam Class Type of class to which the member belongs.
  4873. * @param member A valid pointer to a member.
  4874. * @return Pointer to the member.
  4875. */
  4876. template<typename Type, typename Class>
  4877. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  4878. return member;
  4879. }
  4880. /**
  4881. * @brief Constant utility to disambiguate overloaded functions.
  4882. * @tparam Func Function type of the desired overload.
  4883. * @param func A valid pointer to a function.
  4884. * @return Pointer to the function.
  4885. */
  4886. template<typename Func>
  4887. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  4888. return func;
  4889. }
  4890. /**
  4891. * @brief Helper type for visitors.
  4892. * @tparam Func Types of function objects.
  4893. */
  4894. template<typename... Func>
  4895. struct overloaded: Func... {
  4896. using Func::operator()...;
  4897. };
  4898. /**
  4899. * @brief Deduction guide.
  4900. * @tparam Func Types of function objects.
  4901. */
  4902. template<typename... Func>
  4903. overloaded(Func...) -> overloaded<Func...>;
  4904. /**
  4905. * @brief Basic implementation of a y-combinator.
  4906. * @tparam Func Type of a potentially recursive function.
  4907. */
  4908. template<typename Func>
  4909. struct y_combinator {
  4910. /**
  4911. * @brief Constructs a y-combinator from a given function.
  4912. * @param recursive A potentially recursive function.
  4913. */
  4914. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  4915. : func{std::move(recursive)} {}
  4916. /**
  4917. * @brief Invokes a y-combinator and therefore its underlying function.
  4918. * @tparam Args Types of arguments to use to invoke the underlying function.
  4919. * @param args Parameters to use to invoke the underlying function.
  4920. * @return Return value of the underlying function, if any.
  4921. */
  4922. template<typename... Args>
  4923. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  4924. return func(*this, std::forward<Args>(args)...);
  4925. }
  4926. /*! @copydoc operator()() */
  4927. template<typename... Args>
  4928. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  4929. return func(*this, std::forward<Args>(args)...);
  4930. }
  4931. private:
  4932. Func func;
  4933. };
  4934. } // namespace entt
  4935. #endif
  4936. namespace entt {
  4937. /**
  4938. * @brief Function object to wrap `std::sort` in a class type.
  4939. *
  4940. * Unfortunately, `std::sort` cannot be passed as template argument to a class
  4941. * template or a function template.<br/>
  4942. * This class fills the gap by wrapping some flavors of `std::sort` in a
  4943. * function object.
  4944. */
  4945. struct std_sort {
  4946. /**
  4947. * @brief Sorts the elements in a range.
  4948. *
  4949. * Sorts the elements in a range using the given binary comparison function.
  4950. *
  4951. * @tparam It Type of random access iterator.
  4952. * @tparam Compare Type of comparison function object.
  4953. * @tparam Args Types of arguments to forward to the sort function.
  4954. * @param first An iterator to the first element of the range to sort.
  4955. * @param last An iterator past the last element of the range to sort.
  4956. * @param compare A valid comparison function object.
  4957. * @param args Arguments to forward to the sort function, if any.
  4958. */
  4959. template<typename It, typename Compare = std::less<>, typename... Args>
  4960. void operator()(It first, It last, Compare compare = Compare{}, Args &&...args) const {
  4961. std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
  4962. }
  4963. };
  4964. /*! @brief Function object for performing insertion sort. */
  4965. struct insertion_sort {
  4966. /**
  4967. * @brief Sorts the elements in a range.
  4968. *
  4969. * Sorts the elements in a range using the given binary comparison function.
  4970. *
  4971. * @tparam It Type of random access iterator.
  4972. * @tparam Compare Type of comparison function object.
  4973. * @param first An iterator to the first element of the range to sort.
  4974. * @param last An iterator past the last element of the range to sort.
  4975. * @param compare A valid comparison function object.
  4976. */
  4977. template<typename It, typename Compare = std::less<>>
  4978. void operator()(It first, It last, Compare compare = Compare{}) const {
  4979. if(first < last) {
  4980. for(auto it = first + 1; it < last; ++it) {
  4981. auto value = std::move(*it);
  4982. auto pre = it;
  4983. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  4984. for(; pre > first && compare(value, *(pre - 1)); --pre) {
  4985. *pre = std::move(*(pre - 1));
  4986. }
  4987. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  4988. *pre = std::move(value);
  4989. }
  4990. }
  4991. }
  4992. };
  4993. /**
  4994. * @brief Function object for performing LSD radix sort.
  4995. * @tparam Bit Number of bits processed per pass.
  4996. * @tparam N Maximum number of bits to sort.
  4997. */
  4998. template<std::size_t Bit, std::size_t N>
  4999. struct radix_sort {
  5000. static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass");
  5001. /**
  5002. * @brief Sorts the elements in a range.
  5003. *
  5004. * Sorts the elements in a range using the given _getter_ to access the
  5005. * actual data to be sorted.
  5006. *
  5007. * This implementation is inspired by the online book
  5008. * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort).
  5009. *
  5010. * @tparam It Type of random access iterator.
  5011. * @tparam Getter Type of _getter_ function object.
  5012. * @param first An iterator to the first element of the range to sort.
  5013. * @param last An iterator past the last element of the range to sort.
  5014. * @param getter A valid _getter_ function object.
  5015. */
  5016. template<typename It, typename Getter = identity>
  5017. void operator()(It first, It last, Getter getter = Getter{}) const {
  5018. if(first < last) {
  5019. constexpr auto passes = N / Bit;
  5020. using value_type = typename std::iterator_traits<It>::value_type;
  5021. using difference_type = typename std::iterator_traits<It>::difference_type;
  5022. std::vector<value_type> aux(static_cast<std::size_t>(std::distance(first, last)));
  5023. auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
  5024. constexpr auto mask = (1 << Bit) - 1;
  5025. constexpr auto buckets = 1 << Bit;
  5026. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays, misc-const-correctness)
  5027. std::size_t count[buckets]{};
  5028. for(auto it = from; it != to; ++it) {
  5029. ++count[(getter(*it) >> start) & mask];
  5030. }
  5031. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  5032. std::size_t index[buckets]{};
  5033. for(std::size_t pos{}, end = buckets - 1u; pos < end; ++pos) {
  5034. index[pos + 1u] = index[pos] + count[pos];
  5035. }
  5036. for(auto it = from; it != to; ++it) {
  5037. const auto pos = index[(getter(*it) >> start) & mask]++;
  5038. out[static_cast<difference_type>(pos)] = std::move(*it);
  5039. }
  5040. };
  5041. for(std::size_t pass = 0; pass < (passes & ~1u); pass += 2) {
  5042. part(first, last, aux.begin(), pass * Bit);
  5043. part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
  5044. }
  5045. if constexpr(passes & 1) {
  5046. part(first, last, aux.begin(), (passes - 1) * Bit);
  5047. std::move(aux.begin(), aux.end(), first);
  5048. }
  5049. }
  5050. }
  5051. };
  5052. } // namespace entt
  5053. #endif
  5054. // #include "core/any.hpp"
  5055. #ifndef ENTT_CORE_ANY_HPP
  5056. #define ENTT_CORE_ANY_HPP
  5057. #include <cstddef>
  5058. #include <memory>
  5059. #include <type_traits>
  5060. #include <utility>
  5061. // #include "../config/config.h"
  5062. #ifndef ENTT_CONFIG_CONFIG_H
  5063. #define ENTT_CONFIG_CONFIG_H
  5064. // #include "version.h"
  5065. #ifndef ENTT_CONFIG_VERSION_H
  5066. #define ENTT_CONFIG_VERSION_H
  5067. // #include "macro.h"
  5068. #ifndef ENTT_CONFIG_MACRO_H
  5069. #define ENTT_CONFIG_MACRO_H
  5070. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  5071. #define ENTT_STR(arg) #arg
  5072. #define ENTT_XSTR(arg) ENTT_STR(arg)
  5073. // NOLINTEND(cppcoreguidelines-macro-usage)
  5074. #endif
  5075. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  5076. #define ENTT_VERSION_MAJOR 3
  5077. #define ENTT_VERSION_MINOR 16
  5078. #define ENTT_VERSION_PATCH 0
  5079. #define ENTT_VERSION \
  5080. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  5081. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  5082. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  5083. #endif
  5084. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  5085. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  5086. # define ENTT_CONSTEXPR
  5087. # define ENTT_THROW throw
  5088. # define ENTT_TRY try
  5089. # define ENTT_CATCH catch(...)
  5090. #else
  5091. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  5092. # define ENTT_THROW
  5093. # define ENTT_TRY if(true)
  5094. # define ENTT_CATCH if(false)
  5095. #endif
  5096. #if __has_include(<version>)
  5097. # include <version>
  5098. #
  5099. # if defined(__cpp_consteval)
  5100. # define ENTT_CONSTEVAL consteval
  5101. # endif
  5102. #endif
  5103. #ifndef ENTT_CONSTEVAL
  5104. # define ENTT_CONSTEVAL constexpr
  5105. #endif
  5106. #ifdef ENTT_USE_ATOMIC
  5107. # include <atomic>
  5108. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  5109. #else
  5110. # define ENTT_MAYBE_ATOMIC(Type) Type
  5111. #endif
  5112. #ifndef ENTT_ID_TYPE
  5113. # include <cstdint>
  5114. # define ENTT_ID_TYPE std::uint32_t
  5115. #else
  5116. # include <cstdint> // provides coverage for types in the std namespace
  5117. #endif
  5118. #ifndef ENTT_SPARSE_PAGE
  5119. # define ENTT_SPARSE_PAGE 4096
  5120. #endif
  5121. #ifndef ENTT_PACKED_PAGE
  5122. # define ENTT_PACKED_PAGE 1024
  5123. #endif
  5124. #ifdef ENTT_DISABLE_ASSERT
  5125. # undef ENTT_ASSERT
  5126. # define ENTT_ASSERT(condition, msg) (void(0))
  5127. #elif !defined ENTT_ASSERT
  5128. # include <cassert>
  5129. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  5130. #endif
  5131. #ifdef ENTT_DISABLE_ASSERT
  5132. # undef ENTT_ASSERT_CONSTEXPR
  5133. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  5134. #elif !defined ENTT_ASSERT_CONSTEXPR
  5135. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  5136. #endif
  5137. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  5138. #ifdef ENTT_NO_ETO
  5139. # define ENTT_ETO_TYPE(Type) void
  5140. #else
  5141. # define ENTT_ETO_TYPE(Type) Type
  5142. #endif
  5143. #ifdef ENTT_NO_MIXIN
  5144. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  5145. #else
  5146. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  5147. #endif
  5148. #ifdef ENTT_STANDARD_CPP
  5149. # define ENTT_NONSTD false
  5150. #else
  5151. # define ENTT_NONSTD true
  5152. # if defined __clang__ || defined __GNUC__
  5153. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  5154. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  5155. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  5156. # elif defined _MSC_VER
  5157. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  5158. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  5159. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  5160. # endif
  5161. #endif
  5162. #ifndef ENTT_EXPORT
  5163. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  5164. # define ENTT_EXPORT __declspec(dllexport)
  5165. # define ENTT_IMPORT __declspec(dllimport)
  5166. # define ENTT_HIDDEN
  5167. # elif defined __GNUC__ && __GNUC__ >= 4
  5168. # define ENTT_EXPORT __attribute__((visibility("default")))
  5169. # define ENTT_IMPORT __attribute__((visibility("default")))
  5170. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  5171. # else /* Unsupported compiler */
  5172. # define ENTT_EXPORT
  5173. # define ENTT_IMPORT
  5174. # define ENTT_HIDDEN
  5175. # endif
  5176. #endif
  5177. #ifndef ENTT_API
  5178. # if defined ENTT_API_EXPORT
  5179. # define ENTT_API ENTT_EXPORT
  5180. # elif defined ENTT_API_IMPORT
  5181. # define ENTT_API ENTT_IMPORT
  5182. # else /* No API */
  5183. # define ENTT_API
  5184. # endif
  5185. #endif
  5186. #if defined _MSC_VER
  5187. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  5188. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  5189. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  5190. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  5191. #endif
  5192. // NOLINTEND(cppcoreguidelines-macro-usage)
  5193. #endif
  5194. // #include "fwd.hpp"
  5195. #ifndef ENTT_CORE_FWD_HPP
  5196. #define ENTT_CORE_FWD_HPP
  5197. #include <cstddef>
  5198. #include <cstdint>
  5199. // #include "../config/config.h"
  5200. namespace entt {
  5201. /*! @brief Possible modes of an any object. */
  5202. enum class any_policy : std::uint8_t {
  5203. /*! @brief Default mode, no element available. */
  5204. empty,
  5205. /*! @brief Owning mode, dynamically allocated element. */
  5206. dynamic,
  5207. /*! @brief Owning mode, embedded element. */
  5208. embedded,
  5209. /*! @brief Aliasing mode, non-const reference. */
  5210. ref,
  5211. /*! @brief Const aliasing mode, const reference. */
  5212. cref
  5213. };
  5214. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  5215. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  5216. class basic_any;
  5217. /*! @brief Alias declaration for type identifiers. */
  5218. using id_type = ENTT_ID_TYPE;
  5219. /*! @brief Alias declaration for the most common use case. */
  5220. using any = basic_any<>;
  5221. template<typename, typename>
  5222. class compressed_pair;
  5223. template<typename>
  5224. class basic_hashed_string;
  5225. /*! @brief Aliases for common character types. */
  5226. using hashed_string = basic_hashed_string<char>;
  5227. /*! @brief Aliases for common character types. */
  5228. using hashed_wstring = basic_hashed_string<wchar_t>;
  5229. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  5230. struct type_info;
  5231. } // namespace entt
  5232. #endif
  5233. // #include "type_info.hpp"
  5234. #ifndef ENTT_CORE_TYPE_INFO_HPP
  5235. #define ENTT_CORE_TYPE_INFO_HPP
  5236. #include <string_view>
  5237. #include <type_traits>
  5238. #include <utility>
  5239. // #include "../config/config.h"
  5240. // #include "fwd.hpp"
  5241. // #include "hashed_string.hpp"
  5242. #ifndef ENTT_CORE_HASHED_STRING_HPP
  5243. #define ENTT_CORE_HASHED_STRING_HPP
  5244. #include <cstddef>
  5245. #include <cstdint>
  5246. // #include "fwd.hpp"
  5247. namespace entt {
  5248. /*! @cond TURN_OFF_DOXYGEN */
  5249. namespace internal {
  5250. template<typename = id_type>
  5251. struct fnv_1a_params;
  5252. template<>
  5253. struct fnv_1a_params<std::uint32_t> {
  5254. static constexpr auto offset = 2166136261;
  5255. static constexpr auto prime = 16777619;
  5256. };
  5257. template<>
  5258. struct fnv_1a_params<std::uint64_t> {
  5259. static constexpr auto offset = 14695981039346656037ull;
  5260. static constexpr auto prime = 1099511628211ull;
  5261. };
  5262. template<typename Char>
  5263. struct basic_hashed_string {
  5264. using value_type = Char;
  5265. using size_type = std::size_t;
  5266. using hash_type = id_type;
  5267. const value_type *repr{};
  5268. hash_type hash{fnv_1a_params<>::offset};
  5269. size_type length{};
  5270. };
  5271. } // namespace internal
  5272. /*! @endcond */
  5273. /**
  5274. * @brief Zero overhead unique identifier.
  5275. *
  5276. * A hashed string is a compile-time tool that allows users to use
  5277. * human-readable identifiers in the codebase while using their numeric
  5278. * counterparts at runtime.<br/>
  5279. * Because of that, a hashed string can also be used in constant expressions if
  5280. * required.
  5281. *
  5282. * @warning
  5283. * This class doesn't take ownership of user-supplied strings nor does it make a
  5284. * copy of them.
  5285. *
  5286. * @tparam Char Character type.
  5287. */
  5288. template<typename Char>
  5289. class basic_hashed_string: internal::basic_hashed_string<Char> {
  5290. using base_type = internal::basic_hashed_string<Char>;
  5291. using params = internal::fnv_1a_params<>;
  5292. struct const_wrapper {
  5293. // non-explicit constructor on purpose
  5294. constexpr const_wrapper(const typename base_type::value_type *str) noexcept
  5295. : repr{str} {}
  5296. const typename base_type::value_type *repr;
  5297. };
  5298. public:
  5299. /*! @brief Character type. */
  5300. using value_type = typename base_type::value_type;
  5301. /*! @brief Unsigned integer type. */
  5302. using size_type = typename base_type::size_type;
  5303. /*! @brief Unsigned integer type. */
  5304. using hash_type = typename base_type::hash_type;
  5305. /**
  5306. * @brief Returns directly the numeric representation of a string view.
  5307. * @param str Human-readable identifier.
  5308. * @param len Length of the string to hash.
  5309. * @return The numeric representation of the string.
  5310. */
  5311. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
  5312. return basic_hashed_string{str, len};
  5313. }
  5314. /**
  5315. * @brief Returns directly the numeric representation of a string.
  5316. * @tparam N Number of characters of the identifier.
  5317. * @param str Human-readable identifier.
  5318. * @return The numeric representation of the string.
  5319. */
  5320. template<std::size_t N>
  5321. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  5322. [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept {
  5323. return basic_hashed_string{str};
  5324. }
  5325. /**
  5326. * @brief Returns directly the numeric representation of a string.
  5327. * @param wrapper Helps achieving the purpose by relying on overloading.
  5328. * @return The numeric representation of the string.
  5329. */
  5330. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
  5331. return basic_hashed_string{wrapper};
  5332. }
  5333. /*! @brief Constructs an empty hashed string. */
  5334. constexpr basic_hashed_string() noexcept
  5335. : basic_hashed_string{nullptr, 0u} {}
  5336. /**
  5337. * @brief Constructs a hashed string from a string view.
  5338. * @param str Human-readable identifier.
  5339. * @param len Length of the string to hash.
  5340. */
  5341. constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
  5342. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  5343. : base_type{str} {
  5344. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  5345. for(; base_type::length < len; ++base_type::length) {
  5346. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  5347. }
  5348. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  5349. }
  5350. /**
  5351. * @brief Constructs a hashed string from an array of const characters.
  5352. * @tparam N Number of characters of the identifier.
  5353. * @param str Human-readable identifier.
  5354. */
  5355. template<std::size_t N>
  5356. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  5357. ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept
  5358. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  5359. : base_type{str} {
  5360. for(; str[base_type::length]; ++base_type::length) {
  5361. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  5362. }
  5363. }
  5364. /**
  5365. * @brief Explicit constructor on purpose to avoid constructing a hashed
  5366. * string directly from a `const value_type *`.
  5367. *
  5368. * @warning
  5369. * The lifetime of the string is not extended nor is it copied.
  5370. *
  5371. * @param wrapper Helps achieving the purpose by relying on overloading.
  5372. */
  5373. explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
  5374. : base_type{wrapper.repr} {
  5375. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  5376. for(; wrapper.repr[base_type::length]; ++base_type::length) {
  5377. base_type::hash = (base_type::hash ^ static_cast<id_type>(wrapper.repr[base_type::length])) * params::prime;
  5378. }
  5379. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  5380. }
  5381. /**
  5382. * @brief Returns the size of a hashed string.
  5383. * @return The size of the hashed string.
  5384. */
  5385. [[nodiscard]] constexpr size_type size() const noexcept {
  5386. return base_type::length;
  5387. }
  5388. /**
  5389. * @brief Returns the human-readable representation of a hashed string.
  5390. * @return The string used to initialize the hashed string.
  5391. */
  5392. [[nodiscard]] constexpr const value_type *data() const noexcept {
  5393. return base_type::repr;
  5394. }
  5395. /**
  5396. * @brief Returns the numeric representation of a hashed string.
  5397. * @return The numeric representation of the hashed string.
  5398. */
  5399. [[nodiscard]] constexpr hash_type value() const noexcept {
  5400. return base_type::hash;
  5401. }
  5402. /*! @copydoc data */
  5403. [[nodiscard]] explicit constexpr operator const value_type *() const noexcept {
  5404. return data();
  5405. }
  5406. /**
  5407. * @brief Returns the numeric representation of a hashed string.
  5408. * @return The numeric representation of the hashed string.
  5409. */
  5410. [[nodiscard]] constexpr operator hash_type() const noexcept {
  5411. return value();
  5412. }
  5413. };
  5414. /**
  5415. * @brief Deduction guide.
  5416. * @tparam Char Character type.
  5417. * @param str Human-readable identifier.
  5418. * @param len Length of the string to hash.
  5419. */
  5420. template<typename Char>
  5421. basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string<Char>;
  5422. /**
  5423. * @brief Deduction guide.
  5424. * @tparam Char Character type.
  5425. * @tparam N Number of characters of the identifier.
  5426. * @param str Human-readable identifier.
  5427. */
  5428. template<typename Char, std::size_t N>
  5429. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  5430. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  5431. /**
  5432. * @brief Compares two hashed strings.
  5433. * @tparam Char Character type.
  5434. * @param lhs A valid hashed string.
  5435. * @param rhs A valid hashed string.
  5436. * @return True if the two hashed strings are identical, false otherwise.
  5437. */
  5438. template<typename Char>
  5439. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  5440. return lhs.value() == rhs.value();
  5441. }
  5442. /**
  5443. * @brief Compares two hashed strings.
  5444. * @tparam Char Character type.
  5445. * @param lhs A valid hashed string.
  5446. * @param rhs A valid hashed string.
  5447. * @return True if the two hashed strings differ, false otherwise.
  5448. */
  5449. template<typename Char>
  5450. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  5451. return !(lhs == rhs);
  5452. }
  5453. /**
  5454. * @brief Compares two hashed strings.
  5455. * @tparam Char Character type.
  5456. * @param lhs A valid hashed string.
  5457. * @param rhs A valid hashed string.
  5458. * @return True if the first element is less than the second, false otherwise.
  5459. */
  5460. template<typename Char>
  5461. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  5462. return lhs.value() < rhs.value();
  5463. }
  5464. /**
  5465. * @brief Compares two hashed strings.
  5466. * @tparam Char Character type.
  5467. * @param lhs A valid hashed string.
  5468. * @param rhs A valid hashed string.
  5469. * @return True if the first element is less than or equal to the second, false
  5470. * otherwise.
  5471. */
  5472. template<typename Char>
  5473. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  5474. return !(rhs < lhs);
  5475. }
  5476. /**
  5477. * @brief Compares two hashed strings.
  5478. * @tparam Char Character type.
  5479. * @param lhs A valid hashed string.
  5480. * @param rhs A valid hashed string.
  5481. * @return True if the first element is greater than the second, false
  5482. * otherwise.
  5483. */
  5484. template<typename Char>
  5485. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  5486. return rhs < lhs;
  5487. }
  5488. /**
  5489. * @brief Compares two hashed strings.
  5490. * @tparam Char Character type.
  5491. * @param lhs A valid hashed string.
  5492. * @param rhs A valid hashed string.
  5493. * @return True if the first element is greater than or equal to the second,
  5494. * false otherwise.
  5495. */
  5496. template<typename Char>
  5497. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  5498. return !(lhs < rhs);
  5499. }
  5500. inline namespace literals {
  5501. /**
  5502. * @brief User defined literal for hashed strings.
  5503. * @param str The literal without its suffix.
  5504. * @return A properly initialized hashed string.
  5505. */
  5506. [[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept {
  5507. return hashed_string{str};
  5508. }
  5509. /**
  5510. * @brief User defined literal for hashed wstrings.
  5511. * @param str The literal without its suffix.
  5512. * @return A properly initialized hashed wstring.
  5513. */
  5514. [[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept {
  5515. return hashed_wstring{str};
  5516. }
  5517. } // namespace literals
  5518. } // namespace entt
  5519. #endif
  5520. namespace entt {
  5521. /*! @cond TURN_OFF_DOXYGEN */
  5522. namespace internal {
  5523. struct ENTT_API type_index final {
  5524. [[nodiscard]] static id_type next() noexcept {
  5525. static ENTT_MAYBE_ATOMIC(id_type) value{};
  5526. return value++;
  5527. }
  5528. };
  5529. template<typename Type>
  5530. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  5531. #if defined ENTT_PRETTY_FUNCTION
  5532. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  5533. #else
  5534. return "";
  5535. #endif
  5536. }
  5537. template<typename Type>
  5538. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  5539. #if defined ENTT_PRETTY_FUNCTION
  5540. const std::string_view full_name{pretty_function<Type>()};
  5541. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  5542. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  5543. return value;
  5544. #else
  5545. return std::string_view{};
  5546. #endif
  5547. }
  5548. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  5549. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  5550. constexpr auto value = stripped_type_name<Type>();
  5551. return value;
  5552. }
  5553. template<typename Type>
  5554. [[nodiscard]] std::string_view type_name(char) noexcept {
  5555. static const auto value = stripped_type_name<Type>();
  5556. return value;
  5557. }
  5558. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  5559. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  5560. constexpr auto stripped = stripped_type_name<Type>();
  5561. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  5562. return value;
  5563. }
  5564. template<typename Type>
  5565. [[nodiscard]] id_type type_hash(char) noexcept {
  5566. static const auto value = [](const auto stripped) {
  5567. return hashed_string::value(stripped.data(), stripped.size());
  5568. }(stripped_type_name<Type>());
  5569. return value;
  5570. }
  5571. } // namespace internal
  5572. /*! @endcond */
  5573. /**
  5574. * @brief Type sequential identifier.
  5575. * @tparam Type Type for which to generate a sequential identifier.
  5576. */
  5577. template<typename Type, typename = void>
  5578. struct ENTT_API type_index final {
  5579. /**
  5580. * @brief Returns the sequential identifier of a given type.
  5581. * @return The sequential identifier of a given type.
  5582. */
  5583. [[nodiscard]] static id_type value() noexcept {
  5584. static const id_type value = internal::type_index::next();
  5585. return value;
  5586. }
  5587. /*! @copydoc value */
  5588. [[nodiscard]] constexpr operator id_type() const noexcept {
  5589. return value();
  5590. }
  5591. };
  5592. /**
  5593. * @brief Type hash.
  5594. * @tparam Type Type for which to generate a hash value.
  5595. */
  5596. template<typename Type, typename = void>
  5597. struct type_hash final {
  5598. /**
  5599. * @brief Returns the numeric representation of a given type.
  5600. * @return The numeric representation of the given type.
  5601. */
  5602. #if defined ENTT_PRETTY_FUNCTION
  5603. [[nodiscard]] static constexpr id_type value() noexcept {
  5604. return internal::type_hash<Type>(0);
  5605. #else
  5606. [[nodiscard]] static constexpr id_type value() noexcept {
  5607. return type_index<Type>::value();
  5608. #endif
  5609. }
  5610. /*! @copydoc value */
  5611. [[nodiscard]] constexpr operator id_type() const noexcept {
  5612. return value();
  5613. }
  5614. };
  5615. /**
  5616. * @brief Type name.
  5617. * @tparam Type Type for which to generate a name.
  5618. */
  5619. template<typename Type, typename = void>
  5620. struct type_name final {
  5621. /**
  5622. * @brief Returns the name of a given type.
  5623. * @return The name of the given type.
  5624. */
  5625. [[nodiscard]] static constexpr std::string_view value() noexcept {
  5626. return internal::type_name<Type>(0);
  5627. }
  5628. /*! @copydoc value */
  5629. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  5630. return value();
  5631. }
  5632. };
  5633. /*! @brief Implementation specific information about a type. */
  5634. struct type_info final {
  5635. /**
  5636. * @brief Constructs a type info object for a given type.
  5637. * @tparam Type Type for which to construct a type info object.
  5638. */
  5639. template<typename Type>
  5640. // NOLINTBEGIN(modernize-use-transparent-functors)
  5641. constexpr type_info(std::in_place_type_t<Type>) noexcept
  5642. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  5643. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  5644. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  5645. // NOLINTEND(modernize-use-transparent-functors)
  5646. /**
  5647. * @brief Type index.
  5648. * @return Type index.
  5649. */
  5650. [[nodiscard]] constexpr id_type index() const noexcept {
  5651. return seq;
  5652. }
  5653. /**
  5654. * @brief Type hash.
  5655. * @return Type hash.
  5656. */
  5657. [[nodiscard]] constexpr id_type hash() const noexcept {
  5658. return identifier;
  5659. }
  5660. /**
  5661. * @brief Type name.
  5662. * @return Type name.
  5663. */
  5664. [[nodiscard]] constexpr std::string_view name() const noexcept {
  5665. return alias;
  5666. }
  5667. private:
  5668. id_type seq;
  5669. id_type identifier;
  5670. std::string_view alias;
  5671. };
  5672. /**
  5673. * @brief Compares the contents of two type info objects.
  5674. * @param lhs A type info object.
  5675. * @param rhs A type info object.
  5676. * @return True if the two type info objects are identical, false otherwise.
  5677. */
  5678. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  5679. return lhs.hash() == rhs.hash();
  5680. }
  5681. /**
  5682. * @brief Compares the contents of two type info objects.
  5683. * @param lhs A type info object.
  5684. * @param rhs A type info object.
  5685. * @return True if the two type info objects differ, false otherwise.
  5686. */
  5687. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  5688. return !(lhs == rhs);
  5689. }
  5690. /**
  5691. * @brief Compares two type info objects.
  5692. * @param lhs A valid type info object.
  5693. * @param rhs A valid type info object.
  5694. * @return True if the first element is less than the second, false otherwise.
  5695. */
  5696. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  5697. return lhs.index() < rhs.index();
  5698. }
  5699. /**
  5700. * @brief Compares two type info objects.
  5701. * @param lhs A valid type info object.
  5702. * @param rhs A valid type info object.
  5703. * @return True if the first element is less than or equal to the second, false
  5704. * otherwise.
  5705. */
  5706. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  5707. return !(rhs < lhs);
  5708. }
  5709. /**
  5710. * @brief Compares two type info objects.
  5711. * @param lhs A valid type info object.
  5712. * @param rhs A valid type info object.
  5713. * @return True if the first element is greater than the second, false
  5714. * otherwise.
  5715. */
  5716. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  5717. return rhs < lhs;
  5718. }
  5719. /**
  5720. * @brief Compares two type info objects.
  5721. * @param lhs A valid type info object.
  5722. * @param rhs A valid type info object.
  5723. * @return True if the first element is greater than or equal to the second,
  5724. * false otherwise.
  5725. */
  5726. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  5727. return !(lhs < rhs);
  5728. }
  5729. /**
  5730. * @brief Returns the type info object associated to a given type.
  5731. *
  5732. * The returned element refers to an object with static storage duration.<br/>
  5733. * The type doesn't need to be a complete type. If the type is a reference, the
  5734. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  5735. * are ignored.
  5736. *
  5737. * @tparam Type Type for which to generate a type info object.
  5738. * @return A reference to a properly initialized type info object.
  5739. */
  5740. template<typename Type>
  5741. [[nodiscard]] const type_info &type_id() noexcept {
  5742. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  5743. static const type_info instance{std::in_place_type<Type>};
  5744. return instance;
  5745. } else {
  5746. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  5747. }
  5748. }
  5749. /*! @copydoc type_id */
  5750. template<typename Type>
  5751. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  5752. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  5753. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  5754. }
  5755. } // namespace entt
  5756. #endif
  5757. // #include "type_traits.hpp"
  5758. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  5759. #define ENTT_CORE_TYPE_TRAITS_HPP
  5760. #include <cstddef>
  5761. #include <iterator>
  5762. #include <tuple>
  5763. #include <type_traits>
  5764. #include <utility>
  5765. // #include "../config/config.h"
  5766. // #include "fwd.hpp"
  5767. namespace entt {
  5768. /**
  5769. * @brief Utility class to disambiguate overloaded functions.
  5770. * @tparam N Number of choices available.
  5771. */
  5772. template<std::size_t N>
  5773. struct choice_t
  5774. // unfortunately, doxygen cannot parse such a construct
  5775. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  5776. {};
  5777. /*! @copybrief choice_t */
  5778. template<>
  5779. struct choice_t<0> {};
  5780. /**
  5781. * @brief Variable template for the choice trick.
  5782. * @tparam N Number of choices available.
  5783. */
  5784. template<std::size_t N>
  5785. inline constexpr choice_t<N> choice{};
  5786. /**
  5787. * @brief Identity type trait.
  5788. *
  5789. * Useful to establish non-deduced contexts in template argument deduction
  5790. * (waiting for C++20) or to provide types through function arguments.
  5791. *
  5792. * @tparam Type A type.
  5793. */
  5794. template<typename Type>
  5795. struct type_identity {
  5796. /*! @brief Identity type. */
  5797. using type = Type;
  5798. };
  5799. /**
  5800. * @brief Helper type.
  5801. * @tparam Type A type.
  5802. */
  5803. template<typename Type>
  5804. using type_identity_t = typename type_identity<Type>::type;
  5805. /**
  5806. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  5807. * @tparam Type The type of which to return the size.
  5808. */
  5809. template<typename Type, typename = void>
  5810. struct size_of: std::integral_constant<std::size_t, 0u> {};
  5811. /*! @copydoc size_of */
  5812. template<typename Type>
  5813. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  5814. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  5815. : std::integral_constant<std::size_t, sizeof(Type)> {};
  5816. /**
  5817. * @brief Helper variable template.
  5818. * @tparam Type The type of which to return the size.
  5819. */
  5820. template<typename Type>
  5821. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  5822. /**
  5823. * @brief Using declaration to be used to _repeat_ the same type a number of
  5824. * times equal to the size of a given parameter pack.
  5825. * @tparam Type A type to repeat.
  5826. */
  5827. template<typename Type, typename>
  5828. using unpack_as_type = Type;
  5829. /**
  5830. * @brief Helper variable template to be used to _repeat_ the same value a
  5831. * number of times equal to the size of a given parameter pack.
  5832. * @tparam Value A value to repeat.
  5833. */
  5834. template<auto Value, typename>
  5835. inline constexpr auto unpack_as_value = Value;
  5836. /**
  5837. * @brief Wraps a static constant.
  5838. * @tparam Value A static constant.
  5839. */
  5840. template<auto Value>
  5841. using integral_constant = std::integral_constant<decltype(Value), Value>;
  5842. /**
  5843. * @brief Alias template to facilitate the creation of named values.
  5844. * @tparam Value A constant value at least convertible to `id_type`.
  5845. */
  5846. template<id_type Value>
  5847. using tag = integral_constant<Value>;
  5848. /**
  5849. * @brief A class to use to push around lists of types, nothing more.
  5850. * @tparam Type Types provided by the type list.
  5851. */
  5852. template<typename... Type>
  5853. struct type_list {
  5854. /*! @brief Type list type. */
  5855. using type = type_list;
  5856. /*! @brief Compile-time number of elements in the type list. */
  5857. static constexpr auto size = sizeof...(Type);
  5858. };
  5859. /*! @brief Primary template isn't defined on purpose. */
  5860. template<std::size_t, typename>
  5861. struct type_list_element;
  5862. /**
  5863. * @brief Provides compile-time indexed access to the types of a type list.
  5864. * @tparam Index Index of the type to return.
  5865. * @tparam First First type provided by the type list.
  5866. * @tparam Other Other types provided by the type list.
  5867. */
  5868. template<std::size_t Index, typename First, typename... Other>
  5869. struct type_list_element<Index, type_list<First, Other...>>
  5870. : type_list_element<Index - 1u, type_list<Other...>> {};
  5871. /**
  5872. * @brief Provides compile-time indexed access to the types of a type list.
  5873. * @tparam First First type provided by the type list.
  5874. * @tparam Other Other types provided by the type list.
  5875. */
  5876. template<typename First, typename... Other>
  5877. struct type_list_element<0u, type_list<First, Other...>> {
  5878. /*! @brief Searched type. */
  5879. using type = First;
  5880. };
  5881. /**
  5882. * @brief Helper type.
  5883. * @tparam Index Index of the type to return.
  5884. * @tparam List Type list to search into.
  5885. */
  5886. template<std::size_t Index, typename List>
  5887. using type_list_element_t = typename type_list_element<Index, List>::type;
  5888. /*! @brief Primary template isn't defined on purpose. */
  5889. template<typename, typename>
  5890. struct type_list_index;
  5891. /**
  5892. * @brief Provides compile-time type access to the types of a type list.
  5893. * @tparam Type Type to look for and for which to return the index.
  5894. * @tparam First First type provided by the type list.
  5895. * @tparam Other Other types provided by the type list.
  5896. */
  5897. template<typename Type, typename First, typename... Other>
  5898. struct type_list_index<Type, type_list<First, Other...>> {
  5899. /*! @brief Unsigned integer type. */
  5900. using value_type = std::size_t;
  5901. /*! @brief Compile-time position of the given type in the sublist. */
  5902. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  5903. };
  5904. /**
  5905. * @brief Provides compile-time type access to the types of a type list.
  5906. * @tparam Type Type to look for and for which to return the index.
  5907. * @tparam Other Other types provided by the type list.
  5908. */
  5909. template<typename Type, typename... Other>
  5910. struct type_list_index<Type, type_list<Type, Other...>> {
  5911. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  5912. /*! @brief Unsigned integer type. */
  5913. using value_type = std::size_t;
  5914. /*! @brief Compile-time position of the given type in the sublist. */
  5915. static constexpr value_type value = 0u;
  5916. };
  5917. /**
  5918. * @brief Provides compile-time type access to the types of a type list.
  5919. * @tparam Type Type to look for and for which to return the index.
  5920. */
  5921. template<typename Type>
  5922. struct type_list_index<Type, type_list<>> {
  5923. /*! @brief Unsigned integer type. */
  5924. using value_type = std::size_t;
  5925. /*! @brief Compile-time position of the given type in the sublist. */
  5926. static constexpr value_type value = 0u;
  5927. };
  5928. /**
  5929. * @brief Helper variable template.
  5930. * @tparam List Type list.
  5931. * @tparam Type Type to look for and for which to return the index.
  5932. */
  5933. template<typename Type, typename List>
  5934. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  5935. /**
  5936. * @brief Concatenates multiple type lists.
  5937. * @tparam Type Types provided by the first type list.
  5938. * @tparam Other Types provided by the second type list.
  5939. * @return A type list composed by the types of both the type lists.
  5940. */
  5941. template<typename... Type, typename... Other>
  5942. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  5943. return {};
  5944. }
  5945. /*! @brief Primary template isn't defined on purpose. */
  5946. template<typename...>
  5947. struct type_list_cat;
  5948. /*! @brief Concatenates multiple type lists. */
  5949. template<>
  5950. struct type_list_cat<> {
  5951. /*! @brief A type list composed by the types of all the type lists. */
  5952. using type = type_list<>;
  5953. };
  5954. /**
  5955. * @brief Concatenates multiple type lists.
  5956. * @tparam Type Types provided by the first type list.
  5957. * @tparam Other Types provided by the second type list.
  5958. * @tparam List Other type lists, if any.
  5959. */
  5960. template<typename... Type, typename... Other, typename... List>
  5961. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  5962. /*! @brief A type list composed by the types of all the type lists. */
  5963. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  5964. };
  5965. /**
  5966. * @brief Concatenates multiple type lists.
  5967. * @tparam Type Types provided by the type list.
  5968. */
  5969. template<typename... Type>
  5970. struct type_list_cat<type_list<Type...>> {
  5971. /*! @brief A type list composed by the types of all the type lists. */
  5972. using type = type_list<Type...>;
  5973. };
  5974. /**
  5975. * @brief Helper type.
  5976. * @tparam List Type lists to concatenate.
  5977. */
  5978. template<typename... List>
  5979. using type_list_cat_t = typename type_list_cat<List...>::type;
  5980. /*! @cond TURN_OFF_DOXYGEN */
  5981. namespace internal {
  5982. template<typename...>
  5983. struct type_list_unique;
  5984. template<typename First, typename... Other, typename... Type>
  5985. struct type_list_unique<type_list<First, Other...>, Type...>
  5986. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  5987. template<typename... Type>
  5988. struct type_list_unique<type_list<>, Type...> {
  5989. using type = type_list<Type...>;
  5990. };
  5991. } // namespace internal
  5992. /*! @endcond */
  5993. /**
  5994. * @brief Removes duplicates types from a type list.
  5995. * @tparam List Type list.
  5996. */
  5997. template<typename List>
  5998. struct type_list_unique {
  5999. /*! @brief A type list without duplicate types. */
  6000. using type = typename internal::type_list_unique<List>::type;
  6001. };
  6002. /**
  6003. * @brief Helper type.
  6004. * @tparam List Type list.
  6005. */
  6006. template<typename List>
  6007. using type_list_unique_t = typename type_list_unique<List>::type;
  6008. /**
  6009. * @brief Provides the member constant `value` to true if a type list contains a
  6010. * given type, false otherwise.
  6011. * @tparam List Type list.
  6012. * @tparam Type Type to look for.
  6013. */
  6014. template<typename List, typename Type>
  6015. struct type_list_contains;
  6016. /**
  6017. * @copybrief type_list_contains
  6018. * @tparam Type Types provided by the type list.
  6019. * @tparam Other Type to look for.
  6020. */
  6021. template<typename... Type, typename Other>
  6022. struct type_list_contains<type_list<Type...>, Other>
  6023. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  6024. /**
  6025. * @brief Helper variable template.
  6026. * @tparam List Type list.
  6027. * @tparam Type Type to look for.
  6028. */
  6029. template<typename List, typename Type>
  6030. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  6031. /*! @brief Primary template isn't defined on purpose. */
  6032. template<typename...>
  6033. struct type_list_diff;
  6034. /**
  6035. * @brief Computes the difference between two type lists.
  6036. * @tparam Type Types provided by the first type list.
  6037. * @tparam Other Types provided by the second type list.
  6038. */
  6039. template<typename... Type, typename... Other>
  6040. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  6041. /*! @brief A type list that is the difference between the two type lists. */
  6042. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  6043. };
  6044. /**
  6045. * @brief Helper type.
  6046. * @tparam List Type lists between which to compute the difference.
  6047. */
  6048. template<typename... List>
  6049. using type_list_diff_t = typename type_list_diff<List...>::type;
  6050. /*! @brief Primary template isn't defined on purpose. */
  6051. template<typename, template<typename...> class>
  6052. struct type_list_transform;
  6053. /**
  6054. * @brief Applies a given _function_ to a type list and generate a new list.
  6055. * @tparam Type Types provided by the type list.
  6056. * @tparam Op Unary operation as template class with a type member named `type`.
  6057. */
  6058. template<typename... Type, template<typename...> class Op>
  6059. struct type_list_transform<type_list<Type...>, Op> {
  6060. /*! @brief Resulting type list after applying the transform function. */
  6061. // NOLINTNEXTLINE(modernize-type-traits)
  6062. using type = type_list<typename Op<Type>::type...>;
  6063. };
  6064. /**
  6065. * @brief Helper type.
  6066. * @tparam List Type list.
  6067. * @tparam Op Unary operation as template class with a type member named `type`.
  6068. */
  6069. template<typename List, template<typename...> class Op>
  6070. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  6071. /**
  6072. * @brief A class to use to push around lists of constant values, nothing more.
  6073. * @tparam Value Values provided by the value list.
  6074. */
  6075. template<auto... Value>
  6076. struct value_list {
  6077. /*! @brief Value list type. */
  6078. using type = value_list;
  6079. /*! @brief Compile-time number of elements in the value list. */
  6080. static constexpr auto size = sizeof...(Value);
  6081. };
  6082. /*! @brief Primary template isn't defined on purpose. */
  6083. template<std::size_t, typename>
  6084. struct value_list_element;
  6085. /**
  6086. * @brief Provides compile-time indexed access to the values of a value list.
  6087. * @tparam Index Index of the value to return.
  6088. * @tparam Value First value provided by the value list.
  6089. * @tparam Other Other values provided by the value list.
  6090. */
  6091. template<std::size_t Index, auto Value, auto... Other>
  6092. struct value_list_element<Index, value_list<Value, Other...>>
  6093. : value_list_element<Index - 1u, value_list<Other...>> {};
  6094. /**
  6095. * @brief Provides compile-time indexed access to the types of a type list.
  6096. * @tparam Value First value provided by the value list.
  6097. * @tparam Other Other values provided by the value list.
  6098. */
  6099. template<auto Value, auto... Other>
  6100. struct value_list_element<0u, value_list<Value, Other...>> {
  6101. /*! @brief Searched type. */
  6102. using type = decltype(Value);
  6103. /*! @brief Searched value. */
  6104. static constexpr auto value = Value;
  6105. };
  6106. /**
  6107. * @brief Helper type.
  6108. * @tparam Index Index of the type to return.
  6109. * @tparam List Value list to search into.
  6110. */
  6111. template<std::size_t Index, typename List>
  6112. using value_list_element_t = typename value_list_element<Index, List>::type;
  6113. /**
  6114. * @brief Helper type.
  6115. * @tparam Index Index of the value to return.
  6116. * @tparam List Value list to search into.
  6117. */
  6118. template<std::size_t Index, typename List>
  6119. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  6120. /*! @brief Primary template isn't defined on purpose. */
  6121. template<auto, typename>
  6122. struct value_list_index;
  6123. /**
  6124. * @brief Provides compile-time type access to the values of a value list.
  6125. * @tparam Value Value to look for and for which to return the index.
  6126. * @tparam First First value provided by the value list.
  6127. * @tparam Other Other values provided by the value list.
  6128. */
  6129. template<auto Value, auto First, auto... Other>
  6130. struct value_list_index<Value, value_list<First, Other...>> {
  6131. /*! @brief Unsigned integer type. */
  6132. using value_type = std::size_t;
  6133. /*! @brief Compile-time position of the given value in the sublist. */
  6134. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  6135. };
  6136. /**
  6137. * @brief Provides compile-time type access to the values of a value list.
  6138. * @tparam Value Value to look for and for which to return the index.
  6139. * @tparam Other Other values provided by the value list.
  6140. */
  6141. template<auto Value, auto... Other>
  6142. struct value_list_index<Value, value_list<Value, Other...>> {
  6143. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  6144. /*! @brief Unsigned integer type. */
  6145. using value_type = std::size_t;
  6146. /*! @brief Compile-time position of the given value in the sublist. */
  6147. static constexpr value_type value = 0u;
  6148. };
  6149. /**
  6150. * @brief Provides compile-time type access to the values of a value list.
  6151. * @tparam Value Value to look for and for which to return the index.
  6152. */
  6153. template<auto Value>
  6154. struct value_list_index<Value, value_list<>> {
  6155. /*! @brief Unsigned integer type. */
  6156. using value_type = std::size_t;
  6157. /*! @brief Compile-time position of the given type in the sublist. */
  6158. static constexpr value_type value = 0u;
  6159. };
  6160. /**
  6161. * @brief Helper variable template.
  6162. * @tparam List Value list.
  6163. * @tparam Value Value to look for and for which to return the index.
  6164. */
  6165. template<auto Value, typename List>
  6166. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  6167. /**
  6168. * @brief Concatenates multiple value lists.
  6169. * @tparam Value Values provided by the first value list.
  6170. * @tparam Other Values provided by the second value list.
  6171. * @return A value list composed by the values of both the value lists.
  6172. */
  6173. template<auto... Value, auto... Other>
  6174. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  6175. return {};
  6176. }
  6177. /*! @brief Primary template isn't defined on purpose. */
  6178. template<typename...>
  6179. struct value_list_cat;
  6180. /*! @brief Concatenates multiple value lists. */
  6181. template<>
  6182. struct value_list_cat<> {
  6183. /*! @brief A value list composed by the values of all the value lists. */
  6184. using type = value_list<>;
  6185. };
  6186. /**
  6187. * @brief Concatenates multiple value lists.
  6188. * @tparam Value Values provided by the first value list.
  6189. * @tparam Other Values provided by the second value list.
  6190. * @tparam List Other value lists, if any.
  6191. */
  6192. template<auto... Value, auto... Other, typename... List>
  6193. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  6194. /*! @brief A value list composed by the values of all the value lists. */
  6195. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  6196. };
  6197. /**
  6198. * @brief Concatenates multiple value lists.
  6199. * @tparam Value Values provided by the value list.
  6200. */
  6201. template<auto... Value>
  6202. struct value_list_cat<value_list<Value...>> {
  6203. /*! @brief A value list composed by the values of all the value lists. */
  6204. using type = value_list<Value...>;
  6205. };
  6206. /**
  6207. * @brief Helper type.
  6208. * @tparam List Value lists to concatenate.
  6209. */
  6210. template<typename... List>
  6211. using value_list_cat_t = typename value_list_cat<List...>::type;
  6212. /*! @brief Primary template isn't defined on purpose. */
  6213. template<typename>
  6214. struct value_list_unique;
  6215. /**
  6216. * @brief Removes duplicates values from a value list.
  6217. * @tparam Value One of the values provided by the given value list.
  6218. * @tparam Other The other values provided by the given value list.
  6219. */
  6220. template<auto Value, auto... Other>
  6221. struct value_list_unique<value_list<Value, Other...>> {
  6222. /*! @brief A value list without duplicate types. */
  6223. using type = std::conditional_t<
  6224. ((Value == Other) || ...),
  6225. typename value_list_unique<value_list<Other...>>::type,
  6226. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  6227. };
  6228. /*! @brief Removes duplicates values from a value list. */
  6229. template<>
  6230. struct value_list_unique<value_list<>> {
  6231. /*! @brief A value list without duplicate types. */
  6232. using type = value_list<>;
  6233. };
  6234. /**
  6235. * @brief Helper type.
  6236. * @tparam Type A value list.
  6237. */
  6238. template<typename Type>
  6239. using value_list_unique_t = typename value_list_unique<Type>::type;
  6240. /**
  6241. * @brief Provides the member constant `value` to true if a value list contains
  6242. * a given value, false otherwise.
  6243. * @tparam List Value list.
  6244. * @tparam Value Value to look for.
  6245. */
  6246. template<typename List, auto Value>
  6247. struct value_list_contains;
  6248. /**
  6249. * @copybrief value_list_contains
  6250. * @tparam Value Values provided by the value list.
  6251. * @tparam Other Value to look for.
  6252. */
  6253. template<auto... Value, auto Other>
  6254. struct value_list_contains<value_list<Value...>, Other>
  6255. : std::bool_constant<((Value == Other) || ...)> {};
  6256. /**
  6257. * @brief Helper variable template.
  6258. * @tparam List Value list.
  6259. * @tparam Value Value to look for.
  6260. */
  6261. template<typename List, auto Value>
  6262. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  6263. /*! @brief Primary template isn't defined on purpose. */
  6264. template<typename...>
  6265. struct value_list_diff;
  6266. /**
  6267. * @brief Computes the difference between two value lists.
  6268. * @tparam Value Values provided by the first value list.
  6269. * @tparam Other Values provided by the second value list.
  6270. */
  6271. template<auto... Value, auto... Other>
  6272. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  6273. /*! @brief A value list that is the difference between the two value lists. */
  6274. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  6275. };
  6276. /**
  6277. * @brief Helper type.
  6278. * @tparam List Value lists between which to compute the difference.
  6279. */
  6280. template<typename... List>
  6281. using value_list_diff_t = typename value_list_diff<List...>::type;
  6282. /*! @brief Same as std::is_invocable, but with tuples. */
  6283. template<typename, typename>
  6284. struct is_applicable: std::false_type {};
  6285. /**
  6286. * @copybrief is_applicable
  6287. * @tparam Func A valid function type.
  6288. * @tparam Tuple Tuple-like type.
  6289. * @tparam Args The list of arguments to use to probe the function type.
  6290. */
  6291. template<typename Func, template<typename...> class Tuple, typename... Args>
  6292. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  6293. /**
  6294. * @copybrief is_applicable
  6295. * @tparam Func A valid function type.
  6296. * @tparam Tuple Tuple-like type.
  6297. * @tparam Args The list of arguments to use to probe the function type.
  6298. */
  6299. template<typename Func, template<typename...> class Tuple, typename... Args>
  6300. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  6301. /**
  6302. * @brief Helper variable template.
  6303. * @tparam Func A valid function type.
  6304. * @tparam Args The list of arguments to use to probe the function type.
  6305. */
  6306. template<typename Func, typename Args>
  6307. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  6308. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  6309. template<typename, typename, typename>
  6310. struct is_applicable_r: std::false_type {};
  6311. /**
  6312. * @copybrief is_applicable_r
  6313. * @tparam Ret The type to which the return type of the function should be
  6314. * convertible.
  6315. * @tparam Func A valid function type.
  6316. * @tparam Args The list of arguments to use to probe the function type.
  6317. */
  6318. template<typename Ret, typename Func, typename... Args>
  6319. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  6320. /**
  6321. * @brief Helper variable template.
  6322. * @tparam Ret The type to which the return type of the function should be
  6323. * convertible.
  6324. * @tparam Func A valid function type.
  6325. * @tparam Args The list of arguments to use to probe the function type.
  6326. */
  6327. template<typename Ret, typename Func, typename Args>
  6328. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  6329. /**
  6330. * @brief Provides the member constant `value` to true if a given type is
  6331. * complete, false otherwise.
  6332. * @tparam Type The type to test.
  6333. */
  6334. template<typename Type, typename = void>
  6335. struct is_complete: std::false_type {};
  6336. /*! @copydoc is_complete */
  6337. template<typename Type>
  6338. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  6339. /**
  6340. * @brief Helper variable template.
  6341. * @tparam Type The type to test.
  6342. */
  6343. template<typename Type>
  6344. inline constexpr bool is_complete_v = is_complete<Type>::value;
  6345. /**
  6346. * @brief Provides the member constant `value` to true if a given type is an
  6347. * iterator, false otherwise.
  6348. * @tparam Type The type to test.
  6349. */
  6350. template<typename Type, typename = void>
  6351. struct is_iterator: std::false_type {};
  6352. /*! @cond TURN_OFF_DOXYGEN */
  6353. namespace internal {
  6354. template<typename, typename = void>
  6355. struct has_iterator_category: std::false_type {};
  6356. template<typename Type>
  6357. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  6358. } // namespace internal
  6359. /*! @endcond */
  6360. /*! @copydoc is_iterator */
  6361. template<typename Type>
  6362. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  6363. : internal::has_iterator_category<Type> {};
  6364. /**
  6365. * @brief Helper variable template.
  6366. * @tparam Type The type to test.
  6367. */
  6368. template<typename Type>
  6369. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  6370. /**
  6371. * @brief Provides the member constant `value` to true if a given type is both
  6372. * an empty and non-final class, false otherwise.
  6373. * @tparam Type The type to test
  6374. */
  6375. template<typename Type>
  6376. struct is_ebco_eligible
  6377. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  6378. /**
  6379. * @brief Helper variable template.
  6380. * @tparam Type The type to test.
  6381. */
  6382. template<typename Type>
  6383. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  6384. /**
  6385. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  6386. * is valid and denotes a type, false otherwise.
  6387. * @tparam Type The type to test.
  6388. */
  6389. template<typename Type, typename = void>
  6390. struct is_transparent: std::false_type {};
  6391. /*! @copydoc is_transparent */
  6392. template<typename Type>
  6393. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  6394. /**
  6395. * @brief Helper variable template.
  6396. * @tparam Type The type to test.
  6397. */
  6398. template<typename Type>
  6399. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  6400. /*! @cond TURN_OFF_DOXYGEN */
  6401. namespace internal {
  6402. template<typename, typename = void>
  6403. struct has_tuple_size_value: std::false_type {};
  6404. template<typename Type>
  6405. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  6406. template<typename, typename = void>
  6407. struct has_value_type: std::false_type {};
  6408. template<typename Type>
  6409. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  6410. template<typename>
  6411. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  6412. template<typename Type, std::size_t... Index>
  6413. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  6414. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  6415. }
  6416. template<typename>
  6417. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  6418. return false;
  6419. }
  6420. template<typename Type>
  6421. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  6422. return true;
  6423. }
  6424. template<typename Type>
  6425. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  6426. // NOLINTBEGIN(modernize-use-transparent-functors)
  6427. if constexpr(std::is_array_v<Type>) {
  6428. return false;
  6429. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  6430. if constexpr(has_tuple_size_value<Type>::value) {
  6431. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  6432. } else {
  6433. return maybe_equality_comparable<Type>(0);
  6434. }
  6435. } else if constexpr(has_value_type<Type>::value) {
  6436. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  6437. return maybe_equality_comparable<Type>(0);
  6438. } else {
  6439. return false;
  6440. }
  6441. } else {
  6442. return maybe_equality_comparable<Type>(0);
  6443. }
  6444. // NOLINTEND(modernize-use-transparent-functors)
  6445. }
  6446. } // namespace internal
  6447. /*! @endcond */
  6448. /**
  6449. * @brief Provides the member constant `value` to true if a given type is
  6450. * equality comparable, false otherwise.
  6451. * @tparam Type The type to test.
  6452. */
  6453. template<typename Type>
  6454. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  6455. /*! @copydoc is_equality_comparable */
  6456. template<typename Type>
  6457. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  6458. /**
  6459. * @brief Helper variable template.
  6460. * @tparam Type The type to test.
  6461. */
  6462. template<typename Type>
  6463. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  6464. /**
  6465. * @brief Transcribes the constness of a type to another type.
  6466. * @tparam To The type to which to transcribe the constness.
  6467. * @tparam From The type from which to transcribe the constness.
  6468. */
  6469. template<typename To, typename From>
  6470. struct constness_as {
  6471. /*! @brief The type resulting from the transcription of the constness. */
  6472. using type = std::remove_const_t<To>;
  6473. };
  6474. /*! @copydoc constness_as */
  6475. template<typename To, typename From>
  6476. struct constness_as<To, const From> {
  6477. /*! @brief The type resulting from the transcription of the constness. */
  6478. using type = const To;
  6479. };
  6480. /**
  6481. * @brief Alias template to facilitate the transcription of the constness.
  6482. * @tparam To The type to which to transcribe the constness.
  6483. * @tparam From The type from which to transcribe the constness.
  6484. */
  6485. template<typename To, typename From>
  6486. using constness_as_t = typename constness_as<To, From>::type;
  6487. /**
  6488. * @brief Extracts the class of a non-static member object or function.
  6489. * @tparam Member A pointer to a non-static member object or function.
  6490. */
  6491. template<typename Member>
  6492. class member_class {
  6493. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  6494. template<typename Class, typename Ret, typename... Args>
  6495. static Class *clazz(Ret (Class::*)(Args...));
  6496. template<typename Class, typename Ret, typename... Args>
  6497. static Class *clazz(Ret (Class::*)(Args...) const);
  6498. template<typename Class, typename Type>
  6499. static Class *clazz(Type Class::*);
  6500. public:
  6501. /*! @brief The class of the given non-static member object or function. */
  6502. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  6503. };
  6504. /**
  6505. * @brief Helper type.
  6506. * @tparam Member A pointer to a non-static member object or function.
  6507. */
  6508. template<typename Member>
  6509. using member_class_t = typename member_class<Member>::type;
  6510. /**
  6511. * @brief Extracts the n-th argument of a _callable_ type.
  6512. * @tparam Index The index of the argument to extract.
  6513. * @tparam Candidate A valid _callable_ type.
  6514. */
  6515. template<std::size_t Index, typename Candidate>
  6516. class nth_argument {
  6517. template<typename Ret, typename... Args>
  6518. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  6519. template<typename Ret, typename Class, typename... Args>
  6520. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  6521. template<typename Ret, typename Class, typename... Args>
  6522. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  6523. template<typename Type, typename Class>
  6524. static constexpr type_list<Type> pick_up(Type Class ::*);
  6525. template<typename Type>
  6526. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  6527. public:
  6528. /*! @brief N-th argument of the _callable_ type. */
  6529. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  6530. };
  6531. /**
  6532. * @brief Helper type.
  6533. * @tparam Index The index of the argument to extract.
  6534. * @tparam Candidate A valid function, member function or data member type.
  6535. */
  6536. template<std::size_t Index, typename Candidate>
  6537. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  6538. } // namespace entt
  6539. template<typename... Type>
  6540. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  6541. template<std::size_t Index, typename... Type>
  6542. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  6543. template<auto... Value>
  6544. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  6545. template<std::size_t Index, auto... Value>
  6546. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  6547. #endif
  6548. // #include "utility.hpp"
  6549. namespace entt {
  6550. /*! @cond TURN_OFF_DOXYGEN */
  6551. namespace internal {
  6552. enum class any_request : std::uint8_t {
  6553. info,
  6554. transfer,
  6555. assign,
  6556. compare,
  6557. copy,
  6558. move
  6559. };
  6560. template<std::size_t Len, std::size_t Align>
  6561. struct basic_any_storage {
  6562. static constexpr bool has_buffer = true;
  6563. union {
  6564. const void *instance{};
  6565. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  6566. alignas(Align) std::byte buffer[Len];
  6567. };
  6568. };
  6569. template<std::size_t Align>
  6570. struct basic_any_storage<0u, Align> {
  6571. static constexpr bool has_buffer = false;
  6572. const void *instance{};
  6573. };
  6574. template<typename Type, std::size_t Len, std::size_t Align>
  6575. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  6576. struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v<Type>> {};
  6577. template<std::size_t Len, std::size_t Align>
  6578. struct in_situ<void, Len, Align>: std::false_type {};
  6579. } // namespace internal
  6580. /*! @endcond */
  6581. /**
  6582. * @brief A SBO friendly, type-safe container for single values of any type.
  6583. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  6584. * @tparam Align Optional alignment requirement.
  6585. */
  6586. template<std::size_t Len, std::size_t Align>
  6587. class basic_any: private internal::basic_any_storage<Len, Align> {
  6588. using request = internal::any_request;
  6589. using base_type = internal::basic_any_storage<Len, Align>;
  6590. using vtable_type = const void *(const request, const basic_any &, const void *);
  6591. using deleter_type = void(const basic_any &);
  6592. template<typename Type>
  6593. static constexpr bool in_situ_v = internal::in_situ<Type, Len, Align>::value;
  6594. template<typename Type>
  6595. static const void *basic_vtable(const request req, const basic_any &value, const void *other) {
  6596. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  6597. switch(const auto *elem = static_cast<const Type *>(value.data()); req) {
  6598. case request::info:
  6599. return &type_id<Type>();
  6600. case request::transfer:
  6601. if constexpr(std::is_move_assignable_v<Type>) {
  6602. // NOLINTNEXTLINE(bugprone-casting-through-void)
  6603. *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  6604. return other;
  6605. }
  6606. [[fallthrough]];
  6607. case request::assign:
  6608. if constexpr(std::is_copy_assignable_v<Type>) {
  6609. *const_cast<Type *>(elem) = *static_cast<const Type *>(other);
  6610. return other;
  6611. }
  6612. break;
  6613. case request::compare:
  6614. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  6615. return (*elem == *static_cast<const Type *>(other)) ? other : nullptr;
  6616. } else {
  6617. return (elem == other) ? other : nullptr;
  6618. }
  6619. case request::copy:
  6620. if constexpr(std::is_copy_constructible_v<Type>) {
  6621. // NOLINTNEXTLINE(bugprone-casting-through-void)
  6622. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*elem);
  6623. }
  6624. break;
  6625. case request::move:
  6626. ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
  6627. if constexpr(in_situ_v<Type>) {
  6628. // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion)
  6629. return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->buffer) Type{std::move(*const_cast<Type *>(elem))};
  6630. }
  6631. }
  6632. return nullptr;
  6633. }
  6634. template<typename Type>
  6635. static void basic_deleter(const basic_any &value) {
  6636. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  6637. ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v<Type>), "Unexpected policy");
  6638. const auto *elem = static_cast<const Type *>(value.data());
  6639. if constexpr(in_situ_v<Type>) {
  6640. (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem);
  6641. } else if constexpr(std::is_array_v<Type>) {
  6642. delete[] elem;
  6643. } else {
  6644. delete elem;
  6645. }
  6646. }
  6647. template<typename Type, typename... Args>
  6648. void initialize([[maybe_unused]] Args &&...args) {
  6649. using plain_type = std::remove_const_t<std::remove_reference_t<Type>>;
  6650. vtable = basic_vtable<plain_type>;
  6651. underlying_type = type_hash<plain_type>::value();
  6652. if constexpr(std::is_void_v<Type>) {
  6653. deleter = nullptr;
  6654. mode = any_policy::empty;
  6655. this->instance = nullptr;
  6656. } else if constexpr(std::is_lvalue_reference_v<Type>) {
  6657. deleter = nullptr;
  6658. mode = std::is_const_v<std::remove_reference_t<Type>> ? any_policy::cref : any_policy::ref;
  6659. static_assert((std::is_lvalue_reference_v<Args> && ...) && (sizeof...(Args) == 1u), "Invalid arguments");
  6660. // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
  6661. this->instance = (std::addressof(args), ...);
  6662. } else if constexpr(in_situ_v<plain_type>) {
  6663. if constexpr(std::is_trivially_destructible_v<plain_type>) {
  6664. deleter = nullptr;
  6665. } else {
  6666. deleter = &basic_deleter<plain_type>;
  6667. }
  6668. mode = any_policy::embedded;
  6669. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  6670. ::new(&this->buffer) plain_type{std::forward<Args>(args)...};
  6671. } else {
  6672. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  6673. ::new(&this->buffer) plain_type(std::forward<Args>(args)...);
  6674. }
  6675. } else {
  6676. deleter = &basic_deleter<plain_type>;
  6677. mode = any_policy::dynamic;
  6678. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  6679. this->instance = new plain_type{std::forward<Args>(args)...};
  6680. } else if constexpr(std::is_array_v<plain_type>) {
  6681. static_assert(sizeof...(Args) == 0u, "Invalid arguments");
  6682. this->instance = new plain_type[std::extent_v<plain_type>]();
  6683. } else {
  6684. this->instance = new plain_type(std::forward<Args>(args)...);
  6685. }
  6686. }
  6687. }
  6688. void invoke_deleter_if_exists() {
  6689. if(deleter != nullptr) {
  6690. deleter(*this);
  6691. }
  6692. }
  6693. public:
  6694. /*! @brief Size of the internal buffer. */
  6695. static constexpr auto length = Len;
  6696. /*! @brief Alignment requirement. */
  6697. static constexpr auto alignment = Align;
  6698. /*! @brief Default constructor. */
  6699. constexpr basic_any() noexcept
  6700. : basic_any{std::in_place_type<void>} {}
  6701. /**
  6702. * @brief Constructs a wrapper by directly initializing the new object.
  6703. * @tparam Type Type of object to use to initialize the wrapper.
  6704. * @tparam Args Types of arguments to use to construct the new instance.
  6705. * @param args Parameters to use to construct the instance.
  6706. */
  6707. template<typename Type, typename... Args>
  6708. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  6709. : base_type{} {
  6710. initialize<Type>(std::forward<Args>(args)...);
  6711. }
  6712. /**
  6713. * @brief Constructs a wrapper taking ownership of the passed object.
  6714. * @tparam Type Type of object to use to initialize the wrapper.
  6715. * @param value A pointer to an object to take ownership of.
  6716. */
  6717. template<typename Type>
  6718. explicit basic_any(std::in_place_t, Type *value)
  6719. : base_type{} {
  6720. static_assert(!std::is_const_v<Type> && !std::is_void_v<Type>, "Non-const non-void pointer required");
  6721. if(value == nullptr) {
  6722. initialize<void>();
  6723. } else {
  6724. initialize<Type &>(*value);
  6725. deleter = &basic_deleter<Type>;
  6726. mode = any_policy::dynamic;
  6727. }
  6728. }
  6729. /**
  6730. * @brief Constructs a wrapper from a given value.
  6731. * @tparam Type Type of object to use to initialize the wrapper.
  6732. * @param value An instance of an object to use to initialize the wrapper.
  6733. */
  6734. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  6735. basic_any(Type &&value)
  6736. : basic_any{std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
  6737. /**
  6738. * @brief Copy constructor.
  6739. * @param other The instance to copy from.
  6740. */
  6741. basic_any(const basic_any &other)
  6742. : basic_any{} {
  6743. other.vtable(request::copy, other, this);
  6744. }
  6745. /**
  6746. * @brief Move constructor.
  6747. * @param other The instance to move from.
  6748. */
  6749. basic_any(basic_any &&other) noexcept
  6750. : base_type{},
  6751. vtable{other.vtable},
  6752. deleter{other.deleter},
  6753. underlying_type{other.underlying_type},
  6754. mode{other.mode} {
  6755. if(other.mode == any_policy::embedded) {
  6756. other.vtable(request::move, other, this);
  6757. } else if(other.mode != any_policy::empty) {
  6758. this->instance = std::exchange(other.instance, nullptr);
  6759. }
  6760. }
  6761. /*! @brief Frees the internal buffer, whatever it means. */
  6762. ~basic_any() {
  6763. invoke_deleter_if_exists();
  6764. }
  6765. /**
  6766. * @brief Copy assignment operator.
  6767. * @param other The instance to copy from.
  6768. * @return This any object.
  6769. */
  6770. basic_any &operator=(const basic_any &other) {
  6771. if(this != &other) {
  6772. invoke_deleter_if_exists();
  6773. if(other) {
  6774. other.vtable(request::copy, other, this);
  6775. } else {
  6776. initialize<void>();
  6777. }
  6778. }
  6779. return *this;
  6780. }
  6781. /**
  6782. * @brief Move assignment operator.
  6783. * @param other The instance to move from.
  6784. * @return This any object.
  6785. */
  6786. basic_any &operator=(basic_any &&other) noexcept {
  6787. if(this != &other) {
  6788. invoke_deleter_if_exists();
  6789. if(other.mode == any_policy::embedded) {
  6790. other.vtable(request::move, other, this);
  6791. } else if(other.mode != any_policy::empty) {
  6792. this->instance = std::exchange(other.instance, nullptr);
  6793. }
  6794. vtable = other.vtable;
  6795. deleter = other.deleter;
  6796. underlying_type = other.underlying_type;
  6797. mode = other.mode;
  6798. }
  6799. return *this;
  6800. }
  6801. /**
  6802. * @brief Value assignment operator.
  6803. * @tparam Type Type of object to use to initialize the wrapper.
  6804. * @param value An instance of an object to use to initialize the wrapper.
  6805. * @return This any object.
  6806. */
  6807. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  6808. basic_any &operator=(Type &&value) {
  6809. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  6810. return *this;
  6811. }
  6812. /**
  6813. * @brief Returns false if a wrapper is empty, true otherwise.
  6814. * @return False if the wrapper is empty, true otherwise.
  6815. */
  6816. [[nodiscard]] bool has_value() const noexcept {
  6817. return (mode != any_policy::empty);
  6818. }
  6819. /**
  6820. * @brief Returns false if the wrapper does not contain the expected type,
  6821. * true otherwise.
  6822. * @param req Expected type.
  6823. * @return False if the wrapper does not contain the expected type, true
  6824. * otherwise.
  6825. */
  6826. [[nodiscard]] bool has_value(const type_info &req) const noexcept {
  6827. return (underlying_type == req.hash());
  6828. }
  6829. /**
  6830. * @brief Returns false if the wrapper does not contain the expected type,
  6831. * true otherwise.
  6832. * @tparam Type Expected type.
  6833. * @return False if the wrapper does not contain the expected type, true
  6834. * otherwise.
  6835. */
  6836. template<typename Type>
  6837. [[nodiscard]] bool has_value() const noexcept {
  6838. static_assert(std::is_same_v<std::remove_const_t<Type>, Type>, "Invalid type");
  6839. return (underlying_type == type_hash<Type>::value());
  6840. }
  6841. /**
  6842. * @brief Returns the object type info if any, `type_id<void>()` otherwise.
  6843. * @return The object type info if any, `type_id<void>()` otherwise.
  6844. */
  6845. [[nodiscard]] const type_info &info() const noexcept {
  6846. return *static_cast<const type_info *>(vtable(request::info, *this, nullptr));
  6847. }
  6848. /*! @copydoc info */
  6849. [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept {
  6850. return info();
  6851. }
  6852. /**
  6853. * @brief Returns an opaque pointer to the contained instance.
  6854. * @return An opaque pointer the contained instance, if any.
  6855. */
  6856. [[nodiscard]] const void *data() const noexcept {
  6857. if constexpr(base_type::has_buffer) {
  6858. return (mode == any_policy::embedded) ? &this->buffer : this->instance;
  6859. } else {
  6860. return this->instance;
  6861. }
  6862. }
  6863. /**
  6864. * @brief Returns an opaque pointer to the contained instance.
  6865. * @param req Expected type.
  6866. * @return An opaque pointer the contained instance, if any.
  6867. */
  6868. [[nodiscard]] const void *data(const type_info &req) const noexcept {
  6869. return has_value(req) ? data() : nullptr;
  6870. }
  6871. /**
  6872. * @brief Returns an opaque pointer to the contained instance.
  6873. * @tparam Type Expected type.
  6874. * @return An opaque pointer the contained instance, if any.
  6875. */
  6876. template<typename Type>
  6877. [[nodiscard]] const Type *data() const noexcept {
  6878. return has_value<std::remove_const_t<Type>>() ? static_cast<const Type *>(data()) : nullptr;
  6879. }
  6880. /**
  6881. * @brief Returns an opaque pointer to the contained instance.
  6882. * @return An opaque pointer the contained instance, if any.
  6883. */
  6884. [[nodiscard]] void *data() noexcept {
  6885. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data());
  6886. }
  6887. /**
  6888. * @brief Returns an opaque pointer to the contained instance.
  6889. * @param req Expected type.
  6890. * @return An opaque pointer the contained instance, if any.
  6891. */
  6892. [[nodiscard]] void *data(const type_info &req) noexcept {
  6893. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data(req));
  6894. }
  6895. /**
  6896. * @brief Returns an opaque pointer to the contained instance.
  6897. * @tparam Type Expected type.
  6898. * @return An opaque pointer the contained instance, if any.
  6899. */
  6900. template<typename Type>
  6901. [[nodiscard]] Type *data() noexcept {
  6902. if constexpr(std::is_const_v<Type>) {
  6903. return std::as_const(*this).template data<std::remove_const_t<Type>>();
  6904. } else {
  6905. return (mode == any_policy::cref) ? nullptr : const_cast<Type *>(std::as_const(*this).template data<std::remove_const_t<Type>>());
  6906. }
  6907. }
  6908. /**
  6909. * @brief Replaces the contained object by creating a new instance directly.
  6910. * @tparam Type Type of object to use to initialize the wrapper.
  6911. * @tparam Args Types of arguments to use to construct the new instance.
  6912. * @param args Parameters to use to construct the instance.
  6913. */
  6914. template<typename Type, typename... Args>
  6915. void emplace(Args &&...args) {
  6916. invoke_deleter_if_exists();
  6917. initialize<Type>(std::forward<Args>(args)...);
  6918. }
  6919. /**
  6920. * @brief Assigns a value to the contained object without replacing it.
  6921. * @param other The value to assign to the contained object.
  6922. * @return True in case of success, false otherwise.
  6923. */
  6924. bool assign(const basic_any &other) {
  6925. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  6926. return (vtable(request::assign, *this, other.data()) != nullptr);
  6927. }
  6928. return false;
  6929. }
  6930. /*! @copydoc assign */
  6931. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  6932. bool assign(basic_any &&other) {
  6933. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  6934. return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr);
  6935. }
  6936. return false;
  6937. }
  6938. /*! @brief Destroys contained object */
  6939. void reset() {
  6940. invoke_deleter_if_exists();
  6941. initialize<void>();
  6942. }
  6943. /**
  6944. * @brief Returns false if a wrapper is empty, true otherwise.
  6945. * @return False if the wrapper is empty, true otherwise.
  6946. */
  6947. [[nodiscard]] explicit operator bool() const noexcept {
  6948. return has_value();
  6949. }
  6950. /**
  6951. * @brief Checks if two wrappers differ in their content.
  6952. * @param other Wrapper with which to compare.
  6953. * @return False if the two objects differ in their content, true otherwise.
  6954. */
  6955. [[nodiscard]] bool operator==(const basic_any &other) const noexcept {
  6956. if(other && (underlying_type == other.underlying_type)) {
  6957. return (vtable(request::compare, *this, other.data()) != nullptr);
  6958. }
  6959. return (!*this && !other);
  6960. }
  6961. /**
  6962. * @brief Checks if two wrappers differ in their content.
  6963. * @param other Wrapper with which to compare.
  6964. * @return True if the two objects differ in their content, false otherwise.
  6965. */
  6966. [[nodiscard]] bool operator!=(const basic_any &other) const noexcept {
  6967. return !(*this == other);
  6968. }
  6969. /**
  6970. * @brief Aliasing constructor.
  6971. * @return A wrapper that shares a reference to an unmanaged object.
  6972. */
  6973. [[nodiscard]] basic_any as_ref() noexcept {
  6974. basic_any other = std::as_const(*this).as_ref();
  6975. other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref);
  6976. return other;
  6977. }
  6978. /*! @copydoc as_ref */
  6979. [[nodiscard]] basic_any as_ref() const noexcept {
  6980. basic_any other{};
  6981. other.instance = data();
  6982. other.vtable = vtable;
  6983. other.underlying_type = underlying_type;
  6984. other.mode = any_policy::cref;
  6985. return other;
  6986. }
  6987. /**
  6988. * @brief Returns true if a wrapper owns its object, false otherwise.
  6989. * @return True if the wrapper owns its object, false otherwise.
  6990. */
  6991. [[nodiscard]] bool owner() const noexcept {
  6992. return (mode == any_policy::dynamic || mode == any_policy::embedded);
  6993. }
  6994. /**
  6995. * @brief Returns the current mode of an any object.
  6996. * @return The current mode of the any object.
  6997. */
  6998. [[nodiscard]] any_policy policy() const noexcept {
  6999. return mode;
  7000. }
  7001. private:
  7002. vtable_type *vtable{};
  7003. deleter_type *deleter{};
  7004. id_type underlying_type{};
  7005. any_policy mode{};
  7006. };
  7007. /**
  7008. * @brief Performs type-safe access to the contained object.
  7009. * @tparam Type Type to which conversion is required.
  7010. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  7011. * @tparam Align Alignment requirement.
  7012. * @param data Target any object.
  7013. * @return The element converted to the requested type.
  7014. */
  7015. template<typename Type, std::size_t Len, std::size_t Align>
  7016. [[nodiscard]] std::remove_const_t<Type> any_cast(const basic_any<Len, Align> &data) noexcept {
  7017. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  7018. ENTT_ASSERT(instance, "Invalid instance");
  7019. return static_cast<Type>(*instance);
  7020. }
  7021. /*! @copydoc any_cast */
  7022. template<typename Type, std::size_t Len, std::size_t Align>
  7023. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &data) noexcept {
  7024. // forces const on non-reference types to make them work also with wrappers for const references
  7025. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  7026. ENTT_ASSERT(instance, "Invalid instance");
  7027. return static_cast<Type>(*instance);
  7028. }
  7029. /*! @copydoc any_cast */
  7030. template<typename Type, std::size_t Len, std::size_t Align>
  7031. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  7032. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &&data) noexcept {
  7033. if constexpr(std::is_copy_constructible_v<std::remove_const_t<std::remove_reference_t<Type>>>) {
  7034. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  7035. return static_cast<Type>(std::move(*instance));
  7036. }
  7037. return any_cast<Type>(data);
  7038. } else {
  7039. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  7040. ENTT_ASSERT(instance, "Invalid instance");
  7041. return static_cast<Type>(std::move(*instance));
  7042. }
  7043. }
  7044. /*! @copydoc any_cast */
  7045. template<typename Type, std::size_t Len, std::size_t Align>
  7046. [[nodiscard]] const Type *any_cast(const basic_any<Len, Align> *data) noexcept {
  7047. return data->template data<std::remove_const_t<Type>>();
  7048. }
  7049. /*! @copydoc any_cast */
  7050. template<typename Type, std::size_t Len, std::size_t Align>
  7051. [[nodiscard]] Type *any_cast(basic_any<Len, Align> *data) noexcept {
  7052. if constexpr(std::is_const_v<Type>) {
  7053. // last attempt to make wrappers for const references return their values
  7054. return any_cast<Type>(&std::as_const(*data));
  7055. } else {
  7056. return data->template data<Type>();
  7057. }
  7058. }
  7059. /**
  7060. * @brief Constructs a wrapper from a given type, passing it all arguments.
  7061. * @tparam Type Type of object to use to initialize the wrapper.
  7062. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  7063. * @tparam Align Optional alignment requirement.
  7064. * @tparam Args Types of arguments to use to construct the new instance.
  7065. * @param args Parameters to use to construct the instance.
  7066. * @return A properly initialized wrapper for an object of the given type.
  7067. */
  7068. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  7069. [[nodiscard]] basic_any<Len, Align> make_any(Args &&...args) {
  7070. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  7071. }
  7072. /**
  7073. * @brief Forwards its argument and avoids copies for lvalue references.
  7074. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  7075. * @tparam Align Optional alignment requirement.
  7076. * @tparam Type Type of argument to use to construct the new instance.
  7077. * @param value Parameter to use to construct the instance.
  7078. * @return A properly initialized and not necessarily owning wrapper.
  7079. */
  7080. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  7081. [[nodiscard]] basic_any<Len, Align> forward_as_any(Type &&value) {
  7082. return basic_any<Len, Align>{std::in_place_type<Type &&>, std::forward<Type>(value)};
  7083. }
  7084. } // namespace entt
  7085. #endif
  7086. // #include "core/bit.hpp"
  7087. #ifndef ENTT_CORE_BIT_HPP
  7088. #define ENTT_CORE_BIT_HPP
  7089. #include <cstddef>
  7090. #include <limits>
  7091. #include <type_traits>
  7092. // #include "../config/config.h"
  7093. namespace entt {
  7094. /**
  7095. * @brief Returns the number of set bits in a value (waiting for C++20 and
  7096. * `std::popcount`).
  7097. * @tparam Type Unsigned integer type.
  7098. * @param value A value of unsigned integer type.
  7099. * @return The number of set bits in the value.
  7100. */
  7101. template<typename Type>
  7102. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  7103. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  7104. }
  7105. /**
  7106. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  7107. * `std::has_single_bit`).
  7108. * @tparam Type Unsigned integer type.
  7109. * @param value A value of unsigned integer type.
  7110. * @return True if the value is a power of two, false otherwise.
  7111. */
  7112. template<typename Type>
  7113. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  7114. return value && ((value & (value - 1)) == 0);
  7115. }
  7116. /**
  7117. * @brief Computes the smallest power of two greater than or equal to a value
  7118. * (waiting for C++20 and `std::bit_ceil`).
  7119. * @tparam Type Unsigned integer type.
  7120. * @param value A value of unsigned integer type.
  7121. * @return The smallest power of two greater than or equal to the given value.
  7122. */
  7123. template<typename Type>
  7124. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  7125. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  7126. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  7127. Type curr = value - (value != 0u);
  7128. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  7129. curr |= (curr >> next);
  7130. }
  7131. return ++curr;
  7132. }
  7133. /**
  7134. * @brief Fast module utility function (powers of two only).
  7135. * @tparam Type Unsigned integer type.
  7136. * @param value A value of unsigned integer type.
  7137. * @param mod _Modulus_, it must be a power of two.
  7138. * @return The common remainder.
  7139. */
  7140. template<typename Type>
  7141. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  7142. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  7143. return static_cast<Type>(value & (mod - 1u));
  7144. }
  7145. } // namespace entt
  7146. #endif
  7147. // #include "core/compressed_pair.hpp"
  7148. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  7149. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  7150. #include <cstddef>
  7151. #include <tuple>
  7152. #include <type_traits>
  7153. #include <utility>
  7154. // #include "fwd.hpp"
  7155. // #include "type_traits.hpp"
  7156. namespace entt {
  7157. /*! @cond TURN_OFF_DOXYGEN */
  7158. namespace internal {
  7159. template<typename Type, std::size_t, typename = void>
  7160. struct compressed_pair_element {
  7161. using reference = Type &;
  7162. using const_reference = const Type &;
  7163. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  7164. // NOLINTNEXTLINE(modernize-use-equals-default)
  7165. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  7166. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  7167. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  7168. : value{std::forward<Arg>(arg)} {}
  7169. template<typename... Args, std::size_t... Index>
  7170. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  7171. : value{std::forward<Args>(std::get<Index>(args))...} {}
  7172. [[nodiscard]] constexpr reference get() noexcept {
  7173. return value;
  7174. }
  7175. [[nodiscard]] constexpr const_reference get() const noexcept {
  7176. return value;
  7177. }
  7178. private:
  7179. Type value{};
  7180. };
  7181. template<typename Type, std::size_t Tag>
  7182. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  7183. using reference = Type &;
  7184. using const_reference = const Type &;
  7185. using base_type = Type;
  7186. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  7187. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  7188. : base_type{} {}
  7189. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  7190. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  7191. : base_type{std::forward<Arg>(arg)} {}
  7192. template<typename... Args, std::size_t... Index>
  7193. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  7194. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  7195. [[nodiscard]] constexpr reference get() noexcept {
  7196. return *this;
  7197. }
  7198. [[nodiscard]] constexpr const_reference get() const noexcept {
  7199. return *this;
  7200. }
  7201. };
  7202. } // namespace internal
  7203. /*! @endcond */
  7204. /**
  7205. * @brief A compressed pair.
  7206. *
  7207. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  7208. * reduce its final size to a minimum.
  7209. *
  7210. * @tparam First The type of the first element that the pair stores.
  7211. * @tparam Second The type of the second element that the pair stores.
  7212. */
  7213. template<typename First, typename Second>
  7214. class compressed_pair final
  7215. : internal::compressed_pair_element<First, 0u>,
  7216. internal::compressed_pair_element<Second, 1u> {
  7217. using first_base = internal::compressed_pair_element<First, 0u>;
  7218. using second_base = internal::compressed_pair_element<Second, 1u>;
  7219. public:
  7220. /*! @brief The type of the first element that the pair stores. */
  7221. using first_type = First;
  7222. /*! @brief The type of the second element that the pair stores. */
  7223. using second_type = Second;
  7224. /**
  7225. * @brief Default constructor, conditionally enabled.
  7226. *
  7227. * This constructor is only available when the types that the pair stores
  7228. * are both at least default constructible.
  7229. *
  7230. * @tparam Dummy Dummy template parameter used for internal purposes.
  7231. */
  7232. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  7233. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  7234. : first_base{},
  7235. second_base{} {}
  7236. /**
  7237. * @brief Copy constructor.
  7238. * @param other The instance to copy from.
  7239. */
  7240. constexpr compressed_pair(const compressed_pair &other) = default;
  7241. /**
  7242. * @brief Move constructor.
  7243. * @param other The instance to move from.
  7244. */
  7245. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  7246. /**
  7247. * @brief Constructs a pair from its values.
  7248. * @tparam Arg Type of value to use to initialize the first element.
  7249. * @tparam Other Type of value to use to initialize the second element.
  7250. * @param arg Value to use to initialize the first element.
  7251. * @param other Value to use to initialize the second element.
  7252. */
  7253. template<typename Arg, typename Other>
  7254. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  7255. : first_base{std::forward<Arg>(arg)},
  7256. second_base{std::forward<Other>(other)} {}
  7257. /**
  7258. * @brief Constructs a pair by forwarding the arguments to its parts.
  7259. * @tparam Args Types of arguments to use to initialize the first element.
  7260. * @tparam Other Types of arguments to use to initialize the second element.
  7261. * @param args Arguments to use to initialize the first element.
  7262. * @param other Arguments to use to initialize the second element.
  7263. */
  7264. template<typename... Args, typename... Other>
  7265. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  7266. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  7267. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  7268. /*! @brief Default destructor. */
  7269. ~compressed_pair() = default;
  7270. /**
  7271. * @brief Copy assignment operator.
  7272. * @param other The instance to copy from.
  7273. * @return This compressed pair object.
  7274. */
  7275. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  7276. /**
  7277. * @brief Move assignment operator.
  7278. * @param other The instance to move from.
  7279. * @return This compressed pair object.
  7280. */
  7281. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  7282. /**
  7283. * @brief Returns the first element that a pair stores.
  7284. * @return The first element that a pair stores.
  7285. */
  7286. [[nodiscard]] constexpr first_type &first() noexcept {
  7287. return static_cast<first_base &>(*this).get();
  7288. }
  7289. /*! @copydoc first */
  7290. [[nodiscard]] constexpr const first_type &first() const noexcept {
  7291. return static_cast<const first_base &>(*this).get();
  7292. }
  7293. /**
  7294. * @brief Returns the second element that a pair stores.
  7295. * @return The second element that a pair stores.
  7296. */
  7297. [[nodiscard]] constexpr second_type &second() noexcept {
  7298. return static_cast<second_base &>(*this).get();
  7299. }
  7300. /*! @copydoc second */
  7301. [[nodiscard]] constexpr const second_type &second() const noexcept {
  7302. return static_cast<const second_base &>(*this).get();
  7303. }
  7304. /**
  7305. * @brief Swaps two compressed pair objects.
  7306. * @param other The compressed pair to swap with.
  7307. */
  7308. constexpr void swap(compressed_pair &other) noexcept {
  7309. using std::swap;
  7310. swap(first(), other.first());
  7311. swap(second(), other.second());
  7312. }
  7313. /**
  7314. * @brief Extracts an element from the compressed pair.
  7315. * @tparam Index An integer value that is either 0 or 1.
  7316. * @return Returns a reference to the first element if `Index` is 0 and a
  7317. * reference to the second element if `Index` is 1.
  7318. */
  7319. template<std::size_t Index>
  7320. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  7321. if constexpr(Index == 0u) {
  7322. return first();
  7323. } else {
  7324. static_assert(Index == 1u, "Index out of bounds");
  7325. return second();
  7326. }
  7327. }
  7328. /*! @copydoc get */
  7329. template<std::size_t Index>
  7330. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  7331. if constexpr(Index == 0u) {
  7332. return first();
  7333. } else {
  7334. static_assert(Index == 1u, "Index out of bounds");
  7335. return second();
  7336. }
  7337. }
  7338. };
  7339. /**
  7340. * @brief Deduction guide.
  7341. * @tparam Type Type of value to use to initialize the first element.
  7342. * @tparam Other Type of value to use to initialize the second element.
  7343. */
  7344. template<typename Type, typename Other>
  7345. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  7346. /**
  7347. * @brief Swaps two compressed pair objects.
  7348. * @tparam First The type of the first element that the pairs store.
  7349. * @tparam Second The type of the second element that the pairs store.
  7350. * @param lhs A valid compressed pair object.
  7351. * @param rhs A valid compressed pair object.
  7352. */
  7353. template<typename First, typename Second>
  7354. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  7355. lhs.swap(rhs);
  7356. }
  7357. } // namespace entt
  7358. namespace std {
  7359. /**
  7360. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  7361. * @tparam First The type of the first element that the pair stores.
  7362. * @tparam Second The type of the second element that the pair stores.
  7363. */
  7364. template<typename First, typename Second>
  7365. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  7366. /**
  7367. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  7368. * @tparam Index The index of the type to return.
  7369. * @tparam First The type of the first element that the pair stores.
  7370. * @tparam Second The type of the second element that the pair stores.
  7371. */
  7372. template<size_t Index, typename First, typename Second>
  7373. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  7374. static_assert(Index < 2u, "Index out of bounds");
  7375. };
  7376. } // namespace std
  7377. #endif
  7378. // #include "core/enum.hpp"
  7379. #ifndef ENTT_CORE_ENUM_HPP
  7380. #define ENTT_CORE_ENUM_HPP
  7381. #include <type_traits>
  7382. namespace entt {
  7383. /**
  7384. * @brief Enable bitmask support for enum classes.
  7385. * @tparam Type The enum type for which to enable bitmask support.
  7386. */
  7387. template<typename Type, typename = void>
  7388. struct enum_as_bitmask: std::false_type {};
  7389. /*! @copydoc enum_as_bitmask */
  7390. template<typename Type>
  7391. struct enum_as_bitmask<Type, std::void_t<decltype(Type::_entt_enum_as_bitmask)>>: std::is_enum<Type> {};
  7392. /**
  7393. * @brief Helper variable template.
  7394. * @tparam Type The enum class type for which to enable bitmask support.
  7395. */
  7396. template<typename Type>
  7397. inline constexpr bool enum_as_bitmask_v = enum_as_bitmask<Type>::value;
  7398. } // namespace entt
  7399. /**
  7400. * @brief Operator available for enums for which bitmask support is enabled.
  7401. * @tparam Type Enum class type.
  7402. * @param lhs The first value to use.
  7403. * @param rhs The second value to use.
  7404. * @return The result of invoking the operator on the underlying types of the
  7405. * two values provided.
  7406. */
  7407. template<typename Type>
  7408. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  7409. operator|(const Type lhs, const Type rhs) noexcept {
  7410. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) | static_cast<std::underlying_type_t<Type>>(rhs));
  7411. }
  7412. /*! @copydoc operator| */
  7413. template<typename Type>
  7414. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  7415. operator&(const Type lhs, const Type rhs) noexcept {
  7416. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) & static_cast<std::underlying_type_t<Type>>(rhs));
  7417. }
  7418. /*! @copydoc operator| */
  7419. template<typename Type>
  7420. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  7421. operator^(const Type lhs, const Type rhs) noexcept {
  7422. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) ^ static_cast<std::underlying_type_t<Type>>(rhs));
  7423. }
  7424. /**
  7425. * @brief Operator available for enums for which bitmask support is enabled.
  7426. * @tparam Type Enum class type.
  7427. * @param value The value to use.
  7428. * @return The result of invoking the operator on the underlying types of the
  7429. * value provided.
  7430. */
  7431. template<typename Type>
  7432. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  7433. operator~(const Type value) noexcept {
  7434. return static_cast<Type>(~static_cast<std::underlying_type_t<Type>>(value));
  7435. }
  7436. /*! @copydoc operator~ */
  7437. template<typename Type>
  7438. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, bool>
  7439. operator!(const Type value) noexcept {
  7440. return !static_cast<std::underlying_type_t<Type>>(value);
  7441. }
  7442. /*! @copydoc operator| */
  7443. template<typename Type>
  7444. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  7445. operator|=(Type &lhs, const Type rhs) noexcept {
  7446. return (lhs = (lhs | rhs));
  7447. }
  7448. /*! @copydoc operator| */
  7449. template<typename Type>
  7450. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  7451. operator&=(Type &lhs, const Type rhs) noexcept {
  7452. return (lhs = (lhs & rhs));
  7453. }
  7454. /*! @copydoc operator| */
  7455. template<typename Type>
  7456. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  7457. operator^=(Type &lhs, const Type rhs) noexcept {
  7458. return (lhs = (lhs ^ rhs));
  7459. }
  7460. #endif
  7461. // #include "core/family.hpp"
  7462. #ifndef ENTT_CORE_FAMILY_HPP
  7463. #define ENTT_CORE_FAMILY_HPP
  7464. // #include "../config/config.h"
  7465. // #include "fwd.hpp"
  7466. namespace entt {
  7467. /**
  7468. * @brief Dynamic identifier generator.
  7469. *
  7470. * Utility class template that can be used to assign unique identifiers to types
  7471. * at runtime. Use different specializations to create separate sets of
  7472. * identifiers.
  7473. */
  7474. template<typename...>
  7475. class family {
  7476. static auto identifier() noexcept {
  7477. static ENTT_MAYBE_ATOMIC(id_type) value{};
  7478. return value++;
  7479. }
  7480. public:
  7481. /*! @brief Unsigned integer type. */
  7482. using value_type = id_type;
  7483. /*! @brief Statically generated unique identifier for the given type. */
  7484. template<typename... Type>
  7485. // at the time I'm writing, clang crashes during compilation if auto is used instead of family_type
  7486. inline static const value_type value = identifier();
  7487. };
  7488. } // namespace entt
  7489. #endif
  7490. // #include "core/hashed_string.hpp"
  7491. #ifndef ENTT_CORE_HASHED_STRING_HPP
  7492. #define ENTT_CORE_HASHED_STRING_HPP
  7493. #include <cstddef>
  7494. #include <cstdint>
  7495. // #include "fwd.hpp"
  7496. namespace entt {
  7497. /*! @cond TURN_OFF_DOXYGEN */
  7498. namespace internal {
  7499. template<typename = id_type>
  7500. struct fnv_1a_params;
  7501. template<>
  7502. struct fnv_1a_params<std::uint32_t> {
  7503. static constexpr auto offset = 2166136261;
  7504. static constexpr auto prime = 16777619;
  7505. };
  7506. template<>
  7507. struct fnv_1a_params<std::uint64_t> {
  7508. static constexpr auto offset = 14695981039346656037ull;
  7509. static constexpr auto prime = 1099511628211ull;
  7510. };
  7511. template<typename Char>
  7512. struct basic_hashed_string {
  7513. using value_type = Char;
  7514. using size_type = std::size_t;
  7515. using hash_type = id_type;
  7516. const value_type *repr{};
  7517. hash_type hash{fnv_1a_params<>::offset};
  7518. size_type length{};
  7519. };
  7520. } // namespace internal
  7521. /*! @endcond */
  7522. /**
  7523. * @brief Zero overhead unique identifier.
  7524. *
  7525. * A hashed string is a compile-time tool that allows users to use
  7526. * human-readable identifiers in the codebase while using their numeric
  7527. * counterparts at runtime.<br/>
  7528. * Because of that, a hashed string can also be used in constant expressions if
  7529. * required.
  7530. *
  7531. * @warning
  7532. * This class doesn't take ownership of user-supplied strings nor does it make a
  7533. * copy of them.
  7534. *
  7535. * @tparam Char Character type.
  7536. */
  7537. template<typename Char>
  7538. class basic_hashed_string: internal::basic_hashed_string<Char> {
  7539. using base_type = internal::basic_hashed_string<Char>;
  7540. using params = internal::fnv_1a_params<>;
  7541. struct const_wrapper {
  7542. // non-explicit constructor on purpose
  7543. constexpr const_wrapper(const typename base_type::value_type *str) noexcept
  7544. : repr{str} {}
  7545. const typename base_type::value_type *repr;
  7546. };
  7547. public:
  7548. /*! @brief Character type. */
  7549. using value_type = typename base_type::value_type;
  7550. /*! @brief Unsigned integer type. */
  7551. using size_type = typename base_type::size_type;
  7552. /*! @brief Unsigned integer type. */
  7553. using hash_type = typename base_type::hash_type;
  7554. /**
  7555. * @brief Returns directly the numeric representation of a string view.
  7556. * @param str Human-readable identifier.
  7557. * @param len Length of the string to hash.
  7558. * @return The numeric representation of the string.
  7559. */
  7560. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
  7561. return basic_hashed_string{str, len};
  7562. }
  7563. /**
  7564. * @brief Returns directly the numeric representation of a string.
  7565. * @tparam N Number of characters of the identifier.
  7566. * @param str Human-readable identifier.
  7567. * @return The numeric representation of the string.
  7568. */
  7569. template<std::size_t N>
  7570. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  7571. [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept {
  7572. return basic_hashed_string{str};
  7573. }
  7574. /**
  7575. * @brief Returns directly the numeric representation of a string.
  7576. * @param wrapper Helps achieving the purpose by relying on overloading.
  7577. * @return The numeric representation of the string.
  7578. */
  7579. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
  7580. return basic_hashed_string{wrapper};
  7581. }
  7582. /*! @brief Constructs an empty hashed string. */
  7583. constexpr basic_hashed_string() noexcept
  7584. : basic_hashed_string{nullptr, 0u} {}
  7585. /**
  7586. * @brief Constructs a hashed string from a string view.
  7587. * @param str Human-readable identifier.
  7588. * @param len Length of the string to hash.
  7589. */
  7590. constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
  7591. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  7592. : base_type{str} {
  7593. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  7594. for(; base_type::length < len; ++base_type::length) {
  7595. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  7596. }
  7597. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  7598. }
  7599. /**
  7600. * @brief Constructs a hashed string from an array of const characters.
  7601. * @tparam N Number of characters of the identifier.
  7602. * @param str Human-readable identifier.
  7603. */
  7604. template<std::size_t N>
  7605. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  7606. ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept
  7607. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  7608. : base_type{str} {
  7609. for(; str[base_type::length]; ++base_type::length) {
  7610. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  7611. }
  7612. }
  7613. /**
  7614. * @brief Explicit constructor on purpose to avoid constructing a hashed
  7615. * string directly from a `const value_type *`.
  7616. *
  7617. * @warning
  7618. * The lifetime of the string is not extended nor is it copied.
  7619. *
  7620. * @param wrapper Helps achieving the purpose by relying on overloading.
  7621. */
  7622. explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
  7623. : base_type{wrapper.repr} {
  7624. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  7625. for(; wrapper.repr[base_type::length]; ++base_type::length) {
  7626. base_type::hash = (base_type::hash ^ static_cast<id_type>(wrapper.repr[base_type::length])) * params::prime;
  7627. }
  7628. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  7629. }
  7630. /**
  7631. * @brief Returns the size of a hashed string.
  7632. * @return The size of the hashed string.
  7633. */
  7634. [[nodiscard]] constexpr size_type size() const noexcept {
  7635. return base_type::length;
  7636. }
  7637. /**
  7638. * @brief Returns the human-readable representation of a hashed string.
  7639. * @return The string used to initialize the hashed string.
  7640. */
  7641. [[nodiscard]] constexpr const value_type *data() const noexcept {
  7642. return base_type::repr;
  7643. }
  7644. /**
  7645. * @brief Returns the numeric representation of a hashed string.
  7646. * @return The numeric representation of the hashed string.
  7647. */
  7648. [[nodiscard]] constexpr hash_type value() const noexcept {
  7649. return base_type::hash;
  7650. }
  7651. /*! @copydoc data */
  7652. [[nodiscard]] explicit constexpr operator const value_type *() const noexcept {
  7653. return data();
  7654. }
  7655. /**
  7656. * @brief Returns the numeric representation of a hashed string.
  7657. * @return The numeric representation of the hashed string.
  7658. */
  7659. [[nodiscard]] constexpr operator hash_type() const noexcept {
  7660. return value();
  7661. }
  7662. };
  7663. /**
  7664. * @brief Deduction guide.
  7665. * @tparam Char Character type.
  7666. * @param str Human-readable identifier.
  7667. * @param len Length of the string to hash.
  7668. */
  7669. template<typename Char>
  7670. basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string<Char>;
  7671. /**
  7672. * @brief Deduction guide.
  7673. * @tparam Char Character type.
  7674. * @tparam N Number of characters of the identifier.
  7675. * @param str Human-readable identifier.
  7676. */
  7677. template<typename Char, std::size_t N>
  7678. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  7679. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  7680. /**
  7681. * @brief Compares two hashed strings.
  7682. * @tparam Char Character type.
  7683. * @param lhs A valid hashed string.
  7684. * @param rhs A valid hashed string.
  7685. * @return True if the two hashed strings are identical, false otherwise.
  7686. */
  7687. template<typename Char>
  7688. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  7689. return lhs.value() == rhs.value();
  7690. }
  7691. /**
  7692. * @brief Compares two hashed strings.
  7693. * @tparam Char Character type.
  7694. * @param lhs A valid hashed string.
  7695. * @param rhs A valid hashed string.
  7696. * @return True if the two hashed strings differ, false otherwise.
  7697. */
  7698. template<typename Char>
  7699. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  7700. return !(lhs == rhs);
  7701. }
  7702. /**
  7703. * @brief Compares two hashed strings.
  7704. * @tparam Char Character type.
  7705. * @param lhs A valid hashed string.
  7706. * @param rhs A valid hashed string.
  7707. * @return True if the first element is less than the second, false otherwise.
  7708. */
  7709. template<typename Char>
  7710. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  7711. return lhs.value() < rhs.value();
  7712. }
  7713. /**
  7714. * @brief Compares two hashed strings.
  7715. * @tparam Char Character type.
  7716. * @param lhs A valid hashed string.
  7717. * @param rhs A valid hashed string.
  7718. * @return True if the first element is less than or equal to the second, false
  7719. * otherwise.
  7720. */
  7721. template<typename Char>
  7722. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  7723. return !(rhs < lhs);
  7724. }
  7725. /**
  7726. * @brief Compares two hashed strings.
  7727. * @tparam Char Character type.
  7728. * @param lhs A valid hashed string.
  7729. * @param rhs A valid hashed string.
  7730. * @return True if the first element is greater than the second, false
  7731. * otherwise.
  7732. */
  7733. template<typename Char>
  7734. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  7735. return rhs < lhs;
  7736. }
  7737. /**
  7738. * @brief Compares two hashed strings.
  7739. * @tparam Char Character type.
  7740. * @param lhs A valid hashed string.
  7741. * @param rhs A valid hashed string.
  7742. * @return True if the first element is greater than or equal to the second,
  7743. * false otherwise.
  7744. */
  7745. template<typename Char>
  7746. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  7747. return !(lhs < rhs);
  7748. }
  7749. inline namespace literals {
  7750. /**
  7751. * @brief User defined literal for hashed strings.
  7752. * @param str The literal without its suffix.
  7753. * @return A properly initialized hashed string.
  7754. */
  7755. [[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept {
  7756. return hashed_string{str};
  7757. }
  7758. /**
  7759. * @brief User defined literal for hashed wstrings.
  7760. * @param str The literal without its suffix.
  7761. * @return A properly initialized hashed wstring.
  7762. */
  7763. [[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept {
  7764. return hashed_wstring{str};
  7765. }
  7766. } // namespace literals
  7767. } // namespace entt
  7768. #endif
  7769. // #include "core/ident.hpp"
  7770. #ifndef ENTT_CORE_IDENT_HPP
  7771. #define ENTT_CORE_IDENT_HPP
  7772. #include <cstddef>
  7773. #include <type_traits>
  7774. #include <utility>
  7775. // #include "fwd.hpp"
  7776. // #include "type_traits.hpp"
  7777. namespace entt {
  7778. /**
  7779. * @brief Type integral identifiers.
  7780. * @tparam Type List of types for which to generate identifiers.
  7781. */
  7782. template<typename... Type>
  7783. class ident {
  7784. template<typename Curr, std::size_t... Index>
  7785. [[nodiscard]] static constexpr id_type get(std::index_sequence<Index...>) noexcept {
  7786. static_assert((std::is_same_v<Curr, Type> || ...), "Invalid type");
  7787. return (0 + ... + (std::is_same_v<Curr, type_list_element_t<Index, type_list<std::decay_t<Type>...>>> ? id_type{Index} : id_type{}));
  7788. }
  7789. public:
  7790. /*! @brief Unsigned integer type. */
  7791. using value_type = id_type;
  7792. /*! @brief Statically generated unique identifier for the given type. */
  7793. template<typename Curr>
  7794. static constexpr value_type value = get<std::decay_t<Curr>>(std::index_sequence_for<Type...>{});
  7795. };
  7796. } // namespace entt
  7797. #endif
  7798. // #include "core/iterator.hpp"
  7799. #ifndef ENTT_CORE_ITERATOR_HPP
  7800. #define ENTT_CORE_ITERATOR_HPP
  7801. #include <iterator>
  7802. #include <memory>
  7803. #include <type_traits>
  7804. #include <utility>
  7805. namespace entt {
  7806. /**
  7807. * @brief Helper type to use as pointer with input iterators.
  7808. * @tparam Type of wrapped value.
  7809. */
  7810. template<typename Type>
  7811. struct input_iterator_pointer final {
  7812. /*! @brief Value type. */
  7813. using value_type = Type;
  7814. /*! @brief Pointer type. */
  7815. using pointer = Type *;
  7816. /*! @brief Reference type. */
  7817. using reference = Type &;
  7818. /**
  7819. * @brief Constructs a proxy object by move.
  7820. * @param val Value to use to initialize the proxy object.
  7821. */
  7822. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  7823. : value{std::move(val)} {}
  7824. /**
  7825. * @brief Access operator for accessing wrapped values.
  7826. * @return A pointer to the wrapped value.
  7827. */
  7828. [[nodiscard]] constexpr pointer operator->() noexcept {
  7829. return std::addressof(value);
  7830. }
  7831. /**
  7832. * @brief Dereference operator for accessing wrapped values.
  7833. * @return A reference to the wrapped value.
  7834. */
  7835. [[nodiscard]] constexpr reference operator*() noexcept {
  7836. return value;
  7837. }
  7838. private:
  7839. Type value;
  7840. };
  7841. /**
  7842. * @brief Plain iota iterator (waiting for C++20).
  7843. * @tparam Type Value type.
  7844. */
  7845. template<typename Type>
  7846. class iota_iterator final {
  7847. static_assert(std::is_integral_v<Type>, "Not an integral type");
  7848. public:
  7849. /*! @brief Value type, likely an integral one. */
  7850. using value_type = Type;
  7851. /*! @brief Invalid pointer type. */
  7852. using pointer = void;
  7853. /*! @brief Non-reference type, same as value type. */
  7854. using reference = value_type;
  7855. /*! @brief Difference type. */
  7856. using difference_type = std::ptrdiff_t;
  7857. /*! @brief Iterator category. */
  7858. using iterator_category = std::input_iterator_tag;
  7859. /*! @brief Default constructor. */
  7860. constexpr iota_iterator() noexcept
  7861. : current{} {}
  7862. /**
  7863. * @brief Constructs an iota iterator from a given value.
  7864. * @param init The initial value assigned to the iota iterator.
  7865. */
  7866. constexpr iota_iterator(const value_type init) noexcept
  7867. : current{init} {}
  7868. /**
  7869. * @brief Pre-increment operator.
  7870. * @return This iota iterator.
  7871. */
  7872. constexpr iota_iterator &operator++() noexcept {
  7873. return ++current, *this;
  7874. }
  7875. /**
  7876. * @brief Post-increment operator.
  7877. * @return This iota iterator.
  7878. */
  7879. constexpr iota_iterator operator++(int) noexcept {
  7880. const iota_iterator orig = *this;
  7881. return ++(*this), orig;
  7882. }
  7883. /**
  7884. * @brief Dereference operator.
  7885. * @return The underlying value.
  7886. */
  7887. [[nodiscard]] constexpr reference operator*() const noexcept {
  7888. return current;
  7889. }
  7890. private:
  7891. value_type current;
  7892. };
  7893. /**
  7894. * @brief Comparison operator.
  7895. * @tparam Type Value type of the iota iterator.
  7896. * @param lhs A properly initialized iota iterator.
  7897. * @param rhs A properly initialized iota iterator.
  7898. * @return True if the two iterators are identical, false otherwise.
  7899. */
  7900. template<typename Type>
  7901. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  7902. return *lhs == *rhs;
  7903. }
  7904. /**
  7905. * @brief Comparison operator.
  7906. * @tparam Type Value type of the iota iterator.
  7907. * @param lhs A properly initialized iota iterator.
  7908. * @param rhs A properly initialized iota iterator.
  7909. * @return True if the two iterators differ, false otherwise.
  7910. */
  7911. template<typename Type>
  7912. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  7913. return !(lhs == rhs);
  7914. }
  7915. /**
  7916. * @brief Utility class to create an iterable object from a pair of iterators.
  7917. * @tparam It Type of iterator.
  7918. * @tparam Sentinel Type of sentinel.
  7919. */
  7920. template<typename It, typename Sentinel = It>
  7921. struct iterable_adaptor final {
  7922. /*! @brief Value type. */
  7923. using value_type = typename std::iterator_traits<It>::value_type;
  7924. /*! @brief Iterator type. */
  7925. using iterator = It;
  7926. /*! @brief Sentinel type. */
  7927. using sentinel = Sentinel;
  7928. /*! @brief Default constructor. */
  7929. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  7930. : first{},
  7931. last{} {}
  7932. /**
  7933. * @brief Creates an iterable object from a pair of iterators.
  7934. * @param from Begin iterator.
  7935. * @param to End iterator.
  7936. */
  7937. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  7938. : first{std::move(from)},
  7939. last{std::move(to)} {}
  7940. /**
  7941. * @brief Returns an iterator to the beginning.
  7942. * @return An iterator to the first element of the range.
  7943. */
  7944. [[nodiscard]] constexpr iterator begin() const noexcept {
  7945. return first;
  7946. }
  7947. /**
  7948. * @brief Returns an iterator to the end.
  7949. * @return An iterator to the element following the last element of the
  7950. * range.
  7951. */
  7952. [[nodiscard]] constexpr sentinel end() const noexcept {
  7953. return last;
  7954. }
  7955. /*! @copydoc begin */
  7956. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  7957. return begin();
  7958. }
  7959. /*! @copydoc end */
  7960. [[nodiscard]] constexpr sentinel cend() const noexcept {
  7961. return end();
  7962. }
  7963. private:
  7964. It first;
  7965. Sentinel last;
  7966. };
  7967. } // namespace entt
  7968. #endif
  7969. // #include "core/memory.hpp"
  7970. #ifndef ENTT_CORE_MEMORY_HPP
  7971. #define ENTT_CORE_MEMORY_HPP
  7972. #include <cstddef>
  7973. #include <memory>
  7974. #include <tuple>
  7975. #include <type_traits>
  7976. #include <utility>
  7977. // #include "../config/config.h"
  7978. namespace entt {
  7979. /**
  7980. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  7981. * @tparam Type Pointer type.
  7982. * @param ptr Fancy or raw pointer.
  7983. * @return A raw pointer that represents the address of the original pointer.
  7984. */
  7985. template<typename Type>
  7986. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  7987. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  7988. return ptr;
  7989. } else {
  7990. return to_address(std::forward<Type>(ptr).operator->());
  7991. }
  7992. }
  7993. /**
  7994. * @brief Utility function to design allocation-aware containers.
  7995. * @tparam Allocator Type of allocator.
  7996. * @param lhs A valid allocator.
  7997. * @param rhs Another valid allocator.
  7998. */
  7999. template<typename Allocator>
  8000. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  8001. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  8002. lhs = rhs;
  8003. }
  8004. }
  8005. /**
  8006. * @brief Utility function to design allocation-aware containers.
  8007. * @tparam Allocator Type of allocator.
  8008. * @param lhs A valid allocator.
  8009. * @param rhs Another valid allocator.
  8010. */
  8011. template<typename Allocator>
  8012. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  8013. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  8014. lhs = std::move(rhs);
  8015. }
  8016. }
  8017. /**
  8018. * @brief Utility function to design allocation-aware containers.
  8019. * @tparam Allocator Type of allocator.
  8020. * @param lhs A valid allocator.
  8021. * @param rhs Another valid allocator.
  8022. */
  8023. template<typename Allocator>
  8024. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  8025. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  8026. using std::swap;
  8027. swap(lhs, rhs);
  8028. } else {
  8029. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  8030. }
  8031. }
  8032. /**
  8033. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  8034. * @tparam Allocator Type of allocator used to manage memory and elements.
  8035. */
  8036. template<typename Allocator>
  8037. struct allocation_deleter: private Allocator {
  8038. /*! @brief Allocator type. */
  8039. using allocator_type = Allocator;
  8040. /*! @brief Pointer type. */
  8041. using pointer = typename std::allocator_traits<Allocator>::pointer;
  8042. /**
  8043. * @brief Inherited constructors.
  8044. * @param alloc The allocator to use.
  8045. */
  8046. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  8047. : Allocator{alloc} {}
  8048. /**
  8049. * @brief Destroys the pointed object and deallocates its memory.
  8050. * @param ptr A valid pointer to an object of the given type.
  8051. */
  8052. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  8053. using alloc_traits = std::allocator_traits<Allocator>;
  8054. alloc_traits::destroy(*this, to_address(ptr));
  8055. alloc_traits::deallocate(*this, ptr, 1u);
  8056. }
  8057. };
  8058. /**
  8059. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  8060. * @tparam Type Type of object to allocate for and to construct.
  8061. * @tparam Allocator Type of allocator used to manage memory and elements.
  8062. * @tparam Args Types of arguments to use to construct the object.
  8063. * @param allocator The allocator to use.
  8064. * @param args Parameters to use to construct the object.
  8065. * @return A properly initialized unique pointer with a custom deleter.
  8066. */
  8067. template<typename Type, typename Allocator, typename... Args>
  8068. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  8069. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  8070. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  8071. using allocator_type = typename alloc_traits::allocator_type;
  8072. allocator_type alloc{allocator};
  8073. auto ptr = alloc_traits::allocate(alloc, 1u);
  8074. ENTT_TRY {
  8075. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  8076. }
  8077. ENTT_CATCH {
  8078. alloc_traits::deallocate(alloc, ptr, 1u);
  8079. ENTT_THROW;
  8080. }
  8081. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  8082. }
  8083. /*! @cond TURN_OFF_DOXYGEN */
  8084. namespace internal {
  8085. template<typename Type>
  8086. struct uses_allocator_construction {
  8087. template<typename Allocator, typename... Params>
  8088. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  8089. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  8090. return std::forward_as_tuple(std::forward<Params>(params)...);
  8091. } else {
  8092. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  8093. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  8094. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  8095. } else {
  8096. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  8097. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  8098. }
  8099. }
  8100. }
  8101. };
  8102. template<typename Type, typename Other>
  8103. struct uses_allocator_construction<std::pair<Type, Other>> {
  8104. using type = std::pair<Type, Other>;
  8105. template<typename Allocator, typename First, typename Second>
  8106. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  8107. return std::make_tuple(
  8108. std::piecewise_construct,
  8109. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  8110. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  8111. }
  8112. template<typename Allocator>
  8113. static constexpr auto args(const Allocator &allocator) noexcept {
  8114. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  8115. }
  8116. template<typename Allocator, typename First, typename Second>
  8117. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  8118. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  8119. }
  8120. template<typename Allocator, typename First, typename Second>
  8121. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  8122. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  8123. }
  8124. template<typename Allocator, typename First, typename Second>
  8125. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  8126. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  8127. }
  8128. };
  8129. } // namespace internal
  8130. /*! @endcond */
  8131. /**
  8132. * @brief Uses-allocator construction utility (waiting for C++20).
  8133. *
  8134. * Primarily intended for internal use. Prepares the argument list needed to
  8135. * create an object of a given type by means of uses-allocator construction.
  8136. *
  8137. * @tparam Type Type to return arguments for.
  8138. * @tparam Allocator Type of allocator used to manage memory and elements.
  8139. * @tparam Args Types of arguments to use to construct the object.
  8140. * @param allocator The allocator to use.
  8141. * @param args Parameters to use to construct the object.
  8142. * @return The arguments needed to create an object of the given type.
  8143. */
  8144. template<typename Type, typename Allocator, typename... Args>
  8145. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  8146. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  8147. }
  8148. /**
  8149. * @brief Uses-allocator construction utility (waiting for C++20).
  8150. *
  8151. * Primarily intended for internal use. Creates an object of a given type by
  8152. * means of uses-allocator construction.
  8153. *
  8154. * @tparam Type Type of object to create.
  8155. * @tparam Allocator Type of allocator used to manage memory and elements.
  8156. * @tparam Args Types of arguments to use to construct the object.
  8157. * @param allocator The allocator to use.
  8158. * @param args Parameters to use to construct the object.
  8159. * @return A newly created object of the given type.
  8160. */
  8161. template<typename Type, typename Allocator, typename... Args>
  8162. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  8163. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  8164. }
  8165. /**
  8166. * @brief Uses-allocator construction utility (waiting for C++20).
  8167. *
  8168. * Primarily intended for internal use. Creates an object of a given type by
  8169. * means of uses-allocator construction at an uninitialized memory location.
  8170. *
  8171. * @tparam Type Type of object to create.
  8172. * @tparam Allocator Type of allocator used to manage memory and elements.
  8173. * @tparam Args Types of arguments to use to construct the object.
  8174. * @param value Memory location in which to place the object.
  8175. * @param allocator The allocator to use.
  8176. * @param args Parameters to use to construct the object.
  8177. * @return A pointer to the newly created object of the given type.
  8178. */
  8179. template<typename Type, typename Allocator, typename... Args>
  8180. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  8181. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  8182. }
  8183. } // namespace entt
  8184. #endif
  8185. // #include "core/monostate.hpp"
  8186. #ifndef ENTT_CORE_MONOSTATE_HPP
  8187. #define ENTT_CORE_MONOSTATE_HPP
  8188. // #include "../config/config.h"
  8189. // #include "fwd.hpp"
  8190. namespace entt {
  8191. /**
  8192. * @brief Minimal implementation of the monostate pattern.
  8193. *
  8194. * A minimal, yet complete configuration system built on top of the monostate
  8195. * pattern. Thread safe by design, it works only with basic types like `int`s or
  8196. * `bool`s.<br/>
  8197. * Multiple types and therefore more than one value can be associated with a
  8198. * single key. Because of this, users must pay attention to use the same type
  8199. * both during an assignment and when they try to read back their data.
  8200. * Otherwise, they can incur in unexpected results.
  8201. */
  8202. template<id_type>
  8203. struct monostate {
  8204. /**
  8205. * @brief Assigns a value of a specific type to a given key.
  8206. * @tparam Type Type of the value to assign.
  8207. * @param val User data to assign to the given key.
  8208. * @return This monostate object.
  8209. */
  8210. template<typename Type>
  8211. monostate &operator=(Type val) noexcept {
  8212. value<Type> = val;
  8213. return *this;
  8214. }
  8215. /**
  8216. * @brief Gets a value of a specific type for a given key.
  8217. * @tparam Type Type of the value to get.
  8218. * @return Stored value, if any.
  8219. */
  8220. template<typename Type>
  8221. operator Type() const noexcept {
  8222. return value<Type>;
  8223. }
  8224. private:
  8225. template<typename Type>
  8226. // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  8227. inline static ENTT_MAYBE_ATOMIC(Type) value{};
  8228. };
  8229. /**
  8230. * @brief Helper variable template.
  8231. * @tparam Value Value used to differentiate between different variables.
  8232. */
  8233. template<id_type Value>
  8234. // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  8235. inline monostate<Value> monostate_v{};
  8236. } // namespace entt
  8237. #endif
  8238. // #include "core/ranges.hpp"
  8239. #ifndef ENTT_CORE_RANGES_HPP
  8240. #define ENTT_CORE_RANGES_HPP
  8241. #if __has_include(<version>)
  8242. # include <version>
  8243. #
  8244. # if defined(__cpp_lib_ranges)
  8245. # include <ranges>
  8246. // # include "iterator.hpp"
  8247. #ifndef ENTT_CORE_ITERATOR_HPP
  8248. #define ENTT_CORE_ITERATOR_HPP
  8249. #include <iterator>
  8250. #include <memory>
  8251. #include <type_traits>
  8252. #include <utility>
  8253. namespace entt {
  8254. /**
  8255. * @brief Helper type to use as pointer with input iterators.
  8256. * @tparam Type of wrapped value.
  8257. */
  8258. template<typename Type>
  8259. struct input_iterator_pointer final {
  8260. /*! @brief Value type. */
  8261. using value_type = Type;
  8262. /*! @brief Pointer type. */
  8263. using pointer = Type *;
  8264. /*! @brief Reference type. */
  8265. using reference = Type &;
  8266. /**
  8267. * @brief Constructs a proxy object by move.
  8268. * @param val Value to use to initialize the proxy object.
  8269. */
  8270. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  8271. : value{std::move(val)} {}
  8272. /**
  8273. * @brief Access operator for accessing wrapped values.
  8274. * @return A pointer to the wrapped value.
  8275. */
  8276. [[nodiscard]] constexpr pointer operator->() noexcept {
  8277. return std::addressof(value);
  8278. }
  8279. /**
  8280. * @brief Dereference operator for accessing wrapped values.
  8281. * @return A reference to the wrapped value.
  8282. */
  8283. [[nodiscard]] constexpr reference operator*() noexcept {
  8284. return value;
  8285. }
  8286. private:
  8287. Type value;
  8288. };
  8289. /**
  8290. * @brief Plain iota iterator (waiting for C++20).
  8291. * @tparam Type Value type.
  8292. */
  8293. template<typename Type>
  8294. class iota_iterator final {
  8295. static_assert(std::is_integral_v<Type>, "Not an integral type");
  8296. public:
  8297. /*! @brief Value type, likely an integral one. */
  8298. using value_type = Type;
  8299. /*! @brief Invalid pointer type. */
  8300. using pointer = void;
  8301. /*! @brief Non-reference type, same as value type. */
  8302. using reference = value_type;
  8303. /*! @brief Difference type. */
  8304. using difference_type = std::ptrdiff_t;
  8305. /*! @brief Iterator category. */
  8306. using iterator_category = std::input_iterator_tag;
  8307. /*! @brief Default constructor. */
  8308. constexpr iota_iterator() noexcept
  8309. : current{} {}
  8310. /**
  8311. * @brief Constructs an iota iterator from a given value.
  8312. * @param init The initial value assigned to the iota iterator.
  8313. */
  8314. constexpr iota_iterator(const value_type init) noexcept
  8315. : current{init} {}
  8316. /**
  8317. * @brief Pre-increment operator.
  8318. * @return This iota iterator.
  8319. */
  8320. constexpr iota_iterator &operator++() noexcept {
  8321. return ++current, *this;
  8322. }
  8323. /**
  8324. * @brief Post-increment operator.
  8325. * @return This iota iterator.
  8326. */
  8327. constexpr iota_iterator operator++(int) noexcept {
  8328. const iota_iterator orig = *this;
  8329. return ++(*this), orig;
  8330. }
  8331. /**
  8332. * @brief Dereference operator.
  8333. * @return The underlying value.
  8334. */
  8335. [[nodiscard]] constexpr reference operator*() const noexcept {
  8336. return current;
  8337. }
  8338. private:
  8339. value_type current;
  8340. };
  8341. /**
  8342. * @brief Comparison operator.
  8343. * @tparam Type Value type of the iota iterator.
  8344. * @param lhs A properly initialized iota iterator.
  8345. * @param rhs A properly initialized iota iterator.
  8346. * @return True if the two iterators are identical, false otherwise.
  8347. */
  8348. template<typename Type>
  8349. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  8350. return *lhs == *rhs;
  8351. }
  8352. /**
  8353. * @brief Comparison operator.
  8354. * @tparam Type Value type of the iota iterator.
  8355. * @param lhs A properly initialized iota iterator.
  8356. * @param rhs A properly initialized iota iterator.
  8357. * @return True if the two iterators differ, false otherwise.
  8358. */
  8359. template<typename Type>
  8360. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  8361. return !(lhs == rhs);
  8362. }
  8363. /**
  8364. * @brief Utility class to create an iterable object from a pair of iterators.
  8365. * @tparam It Type of iterator.
  8366. * @tparam Sentinel Type of sentinel.
  8367. */
  8368. template<typename It, typename Sentinel = It>
  8369. struct iterable_adaptor final {
  8370. /*! @brief Value type. */
  8371. using value_type = typename std::iterator_traits<It>::value_type;
  8372. /*! @brief Iterator type. */
  8373. using iterator = It;
  8374. /*! @brief Sentinel type. */
  8375. using sentinel = Sentinel;
  8376. /*! @brief Default constructor. */
  8377. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  8378. : first{},
  8379. last{} {}
  8380. /**
  8381. * @brief Creates an iterable object from a pair of iterators.
  8382. * @param from Begin iterator.
  8383. * @param to End iterator.
  8384. */
  8385. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  8386. : first{std::move(from)},
  8387. last{std::move(to)} {}
  8388. /**
  8389. * @brief Returns an iterator to the beginning.
  8390. * @return An iterator to the first element of the range.
  8391. */
  8392. [[nodiscard]] constexpr iterator begin() const noexcept {
  8393. return first;
  8394. }
  8395. /**
  8396. * @brief Returns an iterator to the end.
  8397. * @return An iterator to the element following the last element of the
  8398. * range.
  8399. */
  8400. [[nodiscard]] constexpr sentinel end() const noexcept {
  8401. return last;
  8402. }
  8403. /*! @copydoc begin */
  8404. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  8405. return begin();
  8406. }
  8407. /*! @copydoc end */
  8408. [[nodiscard]] constexpr sentinel cend() const noexcept {
  8409. return end();
  8410. }
  8411. private:
  8412. It first;
  8413. Sentinel last;
  8414. };
  8415. } // namespace entt
  8416. #endif
  8417. template<class... Args>
  8418. inline constexpr bool std::ranges::enable_borrowed_range<entt::iterable_adaptor<Args...>>{true};
  8419. template<class... Args>
  8420. inline constexpr bool std::ranges::enable_view<entt::iterable_adaptor<Args...>>{true};
  8421. # endif
  8422. #endif
  8423. #endif
  8424. // #include "core/tuple.hpp"
  8425. #ifndef ENTT_CORE_TUPLE_HPP
  8426. #define ENTT_CORE_TUPLE_HPP
  8427. #include <tuple>
  8428. #include <type_traits>
  8429. #include <utility>
  8430. namespace entt {
  8431. /**
  8432. * @brief Provides the member constant `value` to true if a given type is a
  8433. * tuple, false otherwise.
  8434. * @tparam Type The type to test.
  8435. */
  8436. template<typename Type>
  8437. struct is_tuple: std::false_type {};
  8438. /**
  8439. * @copybrief is_tuple
  8440. * @tparam Args Tuple template arguments.
  8441. */
  8442. template<typename... Args>
  8443. struct is_tuple<std::tuple<Args...>>: std::true_type {};
  8444. /**
  8445. * @brief Helper variable template.
  8446. * @tparam Type The type to test.
  8447. */
  8448. template<typename Type>
  8449. inline constexpr bool is_tuple_v = is_tuple<Type>::value;
  8450. /**
  8451. * @brief Utility function to unwrap tuples of a single element.
  8452. * @tparam Type Tuple type of any sizes.
  8453. * @param value A tuple object of the given type.
  8454. * @return The tuple itself if it contains more than one element, the first
  8455. * element otherwise.
  8456. */
  8457. template<typename Type>
  8458. constexpr decltype(auto) unwrap_tuple(Type &&value) noexcept {
  8459. if constexpr(std::tuple_size_v<std::remove_reference_t<Type>> == 1u) {
  8460. return std::get<0>(std::forward<Type>(value));
  8461. } else {
  8462. return std::forward<Type>(value);
  8463. }
  8464. }
  8465. /**
  8466. * @brief Utility class to forward-and-apply tuple objects.
  8467. * @tparam Func Type of underlying invocable object.
  8468. */
  8469. template<typename Func>
  8470. struct forward_apply: private Func {
  8471. /**
  8472. * @brief Constructs a forward-and-apply object.
  8473. * @tparam Args Types of arguments to use to construct the new instance.
  8474. * @param args Parameters to use to construct the instance.
  8475. */
  8476. template<typename... Args>
  8477. constexpr forward_apply(Args &&...args) noexcept(std::is_nothrow_constructible_v<Func, Args...>)
  8478. : Func{std::forward<Args>(args)...} {}
  8479. /**
  8480. * @brief Forwards and applies the arguments with the underlying function.
  8481. * @tparam Type Tuple-like type to forward to the underlying function.
  8482. * @param args Parameters to forward to the underlying function.
  8483. * @return Return value of the underlying function, if any.
  8484. */
  8485. template<typename Type>
  8486. constexpr decltype(auto) operator()(Type &&args) noexcept(noexcept(std::apply(std::declval<Func &>(), args))) {
  8487. return std::apply(static_cast<Func &>(*this), std::forward<Type>(args));
  8488. }
  8489. /*! @copydoc operator()() */
  8490. template<typename Type>
  8491. constexpr decltype(auto) operator()(Type &&args) const noexcept(noexcept(std::apply(std::declval<const Func &>(), args))) {
  8492. return std::apply(static_cast<const Func &>(*this), std::forward<Type>(args));
  8493. }
  8494. };
  8495. /**
  8496. * @brief Deduction guide.
  8497. * @tparam Func Type of underlying invocable object.
  8498. */
  8499. template<typename Func>
  8500. forward_apply(Func) -> forward_apply<std::remove_reference_t<std::remove_const_t<Func>>>;
  8501. } // namespace entt
  8502. #endif
  8503. // #include "core/type_info.hpp"
  8504. #ifndef ENTT_CORE_TYPE_INFO_HPP
  8505. #define ENTT_CORE_TYPE_INFO_HPP
  8506. #include <string_view>
  8507. #include <type_traits>
  8508. #include <utility>
  8509. // #include "../config/config.h"
  8510. // #include "fwd.hpp"
  8511. // #include "hashed_string.hpp"
  8512. namespace entt {
  8513. /*! @cond TURN_OFF_DOXYGEN */
  8514. namespace internal {
  8515. struct ENTT_API type_index final {
  8516. [[nodiscard]] static id_type next() noexcept {
  8517. static ENTT_MAYBE_ATOMIC(id_type) value{};
  8518. return value++;
  8519. }
  8520. };
  8521. template<typename Type>
  8522. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  8523. #if defined ENTT_PRETTY_FUNCTION
  8524. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  8525. #else
  8526. return "";
  8527. #endif
  8528. }
  8529. template<typename Type>
  8530. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  8531. #if defined ENTT_PRETTY_FUNCTION
  8532. const std::string_view full_name{pretty_function<Type>()};
  8533. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  8534. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  8535. return value;
  8536. #else
  8537. return std::string_view{};
  8538. #endif
  8539. }
  8540. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  8541. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  8542. constexpr auto value = stripped_type_name<Type>();
  8543. return value;
  8544. }
  8545. template<typename Type>
  8546. [[nodiscard]] std::string_view type_name(char) noexcept {
  8547. static const auto value = stripped_type_name<Type>();
  8548. return value;
  8549. }
  8550. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  8551. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  8552. constexpr auto stripped = stripped_type_name<Type>();
  8553. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  8554. return value;
  8555. }
  8556. template<typename Type>
  8557. [[nodiscard]] id_type type_hash(char) noexcept {
  8558. static const auto value = [](const auto stripped) {
  8559. return hashed_string::value(stripped.data(), stripped.size());
  8560. }(stripped_type_name<Type>());
  8561. return value;
  8562. }
  8563. } // namespace internal
  8564. /*! @endcond */
  8565. /**
  8566. * @brief Type sequential identifier.
  8567. * @tparam Type Type for which to generate a sequential identifier.
  8568. */
  8569. template<typename Type, typename = void>
  8570. struct ENTT_API type_index final {
  8571. /**
  8572. * @brief Returns the sequential identifier of a given type.
  8573. * @return The sequential identifier of a given type.
  8574. */
  8575. [[nodiscard]] static id_type value() noexcept {
  8576. static const id_type value = internal::type_index::next();
  8577. return value;
  8578. }
  8579. /*! @copydoc value */
  8580. [[nodiscard]] constexpr operator id_type() const noexcept {
  8581. return value();
  8582. }
  8583. };
  8584. /**
  8585. * @brief Type hash.
  8586. * @tparam Type Type for which to generate a hash value.
  8587. */
  8588. template<typename Type, typename = void>
  8589. struct type_hash final {
  8590. /**
  8591. * @brief Returns the numeric representation of a given type.
  8592. * @return The numeric representation of the given type.
  8593. */
  8594. #if defined ENTT_PRETTY_FUNCTION
  8595. [[nodiscard]] static constexpr id_type value() noexcept {
  8596. return internal::type_hash<Type>(0);
  8597. #else
  8598. [[nodiscard]] static constexpr id_type value() noexcept {
  8599. return type_index<Type>::value();
  8600. #endif
  8601. }
  8602. /*! @copydoc value */
  8603. [[nodiscard]] constexpr operator id_type() const noexcept {
  8604. return value();
  8605. }
  8606. };
  8607. /**
  8608. * @brief Type name.
  8609. * @tparam Type Type for which to generate a name.
  8610. */
  8611. template<typename Type, typename = void>
  8612. struct type_name final {
  8613. /**
  8614. * @brief Returns the name of a given type.
  8615. * @return The name of the given type.
  8616. */
  8617. [[nodiscard]] static constexpr std::string_view value() noexcept {
  8618. return internal::type_name<Type>(0);
  8619. }
  8620. /*! @copydoc value */
  8621. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  8622. return value();
  8623. }
  8624. };
  8625. /*! @brief Implementation specific information about a type. */
  8626. struct type_info final {
  8627. /**
  8628. * @brief Constructs a type info object for a given type.
  8629. * @tparam Type Type for which to construct a type info object.
  8630. */
  8631. template<typename Type>
  8632. // NOLINTBEGIN(modernize-use-transparent-functors)
  8633. constexpr type_info(std::in_place_type_t<Type>) noexcept
  8634. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  8635. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  8636. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  8637. // NOLINTEND(modernize-use-transparent-functors)
  8638. /**
  8639. * @brief Type index.
  8640. * @return Type index.
  8641. */
  8642. [[nodiscard]] constexpr id_type index() const noexcept {
  8643. return seq;
  8644. }
  8645. /**
  8646. * @brief Type hash.
  8647. * @return Type hash.
  8648. */
  8649. [[nodiscard]] constexpr id_type hash() const noexcept {
  8650. return identifier;
  8651. }
  8652. /**
  8653. * @brief Type name.
  8654. * @return Type name.
  8655. */
  8656. [[nodiscard]] constexpr std::string_view name() const noexcept {
  8657. return alias;
  8658. }
  8659. private:
  8660. id_type seq;
  8661. id_type identifier;
  8662. std::string_view alias;
  8663. };
  8664. /**
  8665. * @brief Compares the contents of two type info objects.
  8666. * @param lhs A type info object.
  8667. * @param rhs A type info object.
  8668. * @return True if the two type info objects are identical, false otherwise.
  8669. */
  8670. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  8671. return lhs.hash() == rhs.hash();
  8672. }
  8673. /**
  8674. * @brief Compares the contents of two type info objects.
  8675. * @param lhs A type info object.
  8676. * @param rhs A type info object.
  8677. * @return True if the two type info objects differ, false otherwise.
  8678. */
  8679. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  8680. return !(lhs == rhs);
  8681. }
  8682. /**
  8683. * @brief Compares two type info objects.
  8684. * @param lhs A valid type info object.
  8685. * @param rhs A valid type info object.
  8686. * @return True if the first element is less than the second, false otherwise.
  8687. */
  8688. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  8689. return lhs.index() < rhs.index();
  8690. }
  8691. /**
  8692. * @brief Compares two type info objects.
  8693. * @param lhs A valid type info object.
  8694. * @param rhs A valid type info object.
  8695. * @return True if the first element is less than or equal to the second, false
  8696. * otherwise.
  8697. */
  8698. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  8699. return !(rhs < lhs);
  8700. }
  8701. /**
  8702. * @brief Compares two type info objects.
  8703. * @param lhs A valid type info object.
  8704. * @param rhs A valid type info object.
  8705. * @return True if the first element is greater than the second, false
  8706. * otherwise.
  8707. */
  8708. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  8709. return rhs < lhs;
  8710. }
  8711. /**
  8712. * @brief Compares two type info objects.
  8713. * @param lhs A valid type info object.
  8714. * @param rhs A valid type info object.
  8715. * @return True if the first element is greater than or equal to the second,
  8716. * false otherwise.
  8717. */
  8718. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  8719. return !(lhs < rhs);
  8720. }
  8721. /**
  8722. * @brief Returns the type info object associated to a given type.
  8723. *
  8724. * The returned element refers to an object with static storage duration.<br/>
  8725. * The type doesn't need to be a complete type. If the type is a reference, the
  8726. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  8727. * are ignored.
  8728. *
  8729. * @tparam Type Type for which to generate a type info object.
  8730. * @return A reference to a properly initialized type info object.
  8731. */
  8732. template<typename Type>
  8733. [[nodiscard]] const type_info &type_id() noexcept {
  8734. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  8735. static const type_info instance{std::in_place_type<Type>};
  8736. return instance;
  8737. } else {
  8738. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  8739. }
  8740. }
  8741. /*! @copydoc type_id */
  8742. template<typename Type>
  8743. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  8744. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  8745. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  8746. }
  8747. } // namespace entt
  8748. #endif
  8749. // #include "core/type_traits.hpp"
  8750. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  8751. #define ENTT_CORE_TYPE_TRAITS_HPP
  8752. #include <cstddef>
  8753. #include <iterator>
  8754. #include <tuple>
  8755. #include <type_traits>
  8756. #include <utility>
  8757. // #include "../config/config.h"
  8758. // #include "fwd.hpp"
  8759. namespace entt {
  8760. /**
  8761. * @brief Utility class to disambiguate overloaded functions.
  8762. * @tparam N Number of choices available.
  8763. */
  8764. template<std::size_t N>
  8765. struct choice_t
  8766. // unfortunately, doxygen cannot parse such a construct
  8767. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  8768. {};
  8769. /*! @copybrief choice_t */
  8770. template<>
  8771. struct choice_t<0> {};
  8772. /**
  8773. * @brief Variable template for the choice trick.
  8774. * @tparam N Number of choices available.
  8775. */
  8776. template<std::size_t N>
  8777. inline constexpr choice_t<N> choice{};
  8778. /**
  8779. * @brief Identity type trait.
  8780. *
  8781. * Useful to establish non-deduced contexts in template argument deduction
  8782. * (waiting for C++20) or to provide types through function arguments.
  8783. *
  8784. * @tparam Type A type.
  8785. */
  8786. template<typename Type>
  8787. struct type_identity {
  8788. /*! @brief Identity type. */
  8789. using type = Type;
  8790. };
  8791. /**
  8792. * @brief Helper type.
  8793. * @tparam Type A type.
  8794. */
  8795. template<typename Type>
  8796. using type_identity_t = typename type_identity<Type>::type;
  8797. /**
  8798. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  8799. * @tparam Type The type of which to return the size.
  8800. */
  8801. template<typename Type, typename = void>
  8802. struct size_of: std::integral_constant<std::size_t, 0u> {};
  8803. /*! @copydoc size_of */
  8804. template<typename Type>
  8805. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  8806. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  8807. : std::integral_constant<std::size_t, sizeof(Type)> {};
  8808. /**
  8809. * @brief Helper variable template.
  8810. * @tparam Type The type of which to return the size.
  8811. */
  8812. template<typename Type>
  8813. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  8814. /**
  8815. * @brief Using declaration to be used to _repeat_ the same type a number of
  8816. * times equal to the size of a given parameter pack.
  8817. * @tparam Type A type to repeat.
  8818. */
  8819. template<typename Type, typename>
  8820. using unpack_as_type = Type;
  8821. /**
  8822. * @brief Helper variable template to be used to _repeat_ the same value a
  8823. * number of times equal to the size of a given parameter pack.
  8824. * @tparam Value A value to repeat.
  8825. */
  8826. template<auto Value, typename>
  8827. inline constexpr auto unpack_as_value = Value;
  8828. /**
  8829. * @brief Wraps a static constant.
  8830. * @tparam Value A static constant.
  8831. */
  8832. template<auto Value>
  8833. using integral_constant = std::integral_constant<decltype(Value), Value>;
  8834. /**
  8835. * @brief Alias template to facilitate the creation of named values.
  8836. * @tparam Value A constant value at least convertible to `id_type`.
  8837. */
  8838. template<id_type Value>
  8839. using tag = integral_constant<Value>;
  8840. /**
  8841. * @brief A class to use to push around lists of types, nothing more.
  8842. * @tparam Type Types provided by the type list.
  8843. */
  8844. template<typename... Type>
  8845. struct type_list {
  8846. /*! @brief Type list type. */
  8847. using type = type_list;
  8848. /*! @brief Compile-time number of elements in the type list. */
  8849. static constexpr auto size = sizeof...(Type);
  8850. };
  8851. /*! @brief Primary template isn't defined on purpose. */
  8852. template<std::size_t, typename>
  8853. struct type_list_element;
  8854. /**
  8855. * @brief Provides compile-time indexed access to the types of a type list.
  8856. * @tparam Index Index of the type to return.
  8857. * @tparam First First type provided by the type list.
  8858. * @tparam Other Other types provided by the type list.
  8859. */
  8860. template<std::size_t Index, typename First, typename... Other>
  8861. struct type_list_element<Index, type_list<First, Other...>>
  8862. : type_list_element<Index - 1u, type_list<Other...>> {};
  8863. /**
  8864. * @brief Provides compile-time indexed access to the types of a type list.
  8865. * @tparam First First type provided by the type list.
  8866. * @tparam Other Other types provided by the type list.
  8867. */
  8868. template<typename First, typename... Other>
  8869. struct type_list_element<0u, type_list<First, Other...>> {
  8870. /*! @brief Searched type. */
  8871. using type = First;
  8872. };
  8873. /**
  8874. * @brief Helper type.
  8875. * @tparam Index Index of the type to return.
  8876. * @tparam List Type list to search into.
  8877. */
  8878. template<std::size_t Index, typename List>
  8879. using type_list_element_t = typename type_list_element<Index, List>::type;
  8880. /*! @brief Primary template isn't defined on purpose. */
  8881. template<typename, typename>
  8882. struct type_list_index;
  8883. /**
  8884. * @brief Provides compile-time type access to the types of a type list.
  8885. * @tparam Type Type to look for and for which to return the index.
  8886. * @tparam First First type provided by the type list.
  8887. * @tparam Other Other types provided by the type list.
  8888. */
  8889. template<typename Type, typename First, typename... Other>
  8890. struct type_list_index<Type, type_list<First, Other...>> {
  8891. /*! @brief Unsigned integer type. */
  8892. using value_type = std::size_t;
  8893. /*! @brief Compile-time position of the given type in the sublist. */
  8894. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  8895. };
  8896. /**
  8897. * @brief Provides compile-time type access to the types of a type list.
  8898. * @tparam Type Type to look for and for which to return the index.
  8899. * @tparam Other Other types provided by the type list.
  8900. */
  8901. template<typename Type, typename... Other>
  8902. struct type_list_index<Type, type_list<Type, Other...>> {
  8903. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  8904. /*! @brief Unsigned integer type. */
  8905. using value_type = std::size_t;
  8906. /*! @brief Compile-time position of the given type in the sublist. */
  8907. static constexpr value_type value = 0u;
  8908. };
  8909. /**
  8910. * @brief Provides compile-time type access to the types of a type list.
  8911. * @tparam Type Type to look for and for which to return the index.
  8912. */
  8913. template<typename Type>
  8914. struct type_list_index<Type, type_list<>> {
  8915. /*! @brief Unsigned integer type. */
  8916. using value_type = std::size_t;
  8917. /*! @brief Compile-time position of the given type in the sublist. */
  8918. static constexpr value_type value = 0u;
  8919. };
  8920. /**
  8921. * @brief Helper variable template.
  8922. * @tparam List Type list.
  8923. * @tparam Type Type to look for and for which to return the index.
  8924. */
  8925. template<typename Type, typename List>
  8926. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  8927. /**
  8928. * @brief Concatenates multiple type lists.
  8929. * @tparam Type Types provided by the first type list.
  8930. * @tparam Other Types provided by the second type list.
  8931. * @return A type list composed by the types of both the type lists.
  8932. */
  8933. template<typename... Type, typename... Other>
  8934. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  8935. return {};
  8936. }
  8937. /*! @brief Primary template isn't defined on purpose. */
  8938. template<typename...>
  8939. struct type_list_cat;
  8940. /*! @brief Concatenates multiple type lists. */
  8941. template<>
  8942. struct type_list_cat<> {
  8943. /*! @brief A type list composed by the types of all the type lists. */
  8944. using type = type_list<>;
  8945. };
  8946. /**
  8947. * @brief Concatenates multiple type lists.
  8948. * @tparam Type Types provided by the first type list.
  8949. * @tparam Other Types provided by the second type list.
  8950. * @tparam List Other type lists, if any.
  8951. */
  8952. template<typename... Type, typename... Other, typename... List>
  8953. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  8954. /*! @brief A type list composed by the types of all the type lists. */
  8955. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  8956. };
  8957. /**
  8958. * @brief Concatenates multiple type lists.
  8959. * @tparam Type Types provided by the type list.
  8960. */
  8961. template<typename... Type>
  8962. struct type_list_cat<type_list<Type...>> {
  8963. /*! @brief A type list composed by the types of all the type lists. */
  8964. using type = type_list<Type...>;
  8965. };
  8966. /**
  8967. * @brief Helper type.
  8968. * @tparam List Type lists to concatenate.
  8969. */
  8970. template<typename... List>
  8971. using type_list_cat_t = typename type_list_cat<List...>::type;
  8972. /*! @cond TURN_OFF_DOXYGEN */
  8973. namespace internal {
  8974. template<typename...>
  8975. struct type_list_unique;
  8976. template<typename First, typename... Other, typename... Type>
  8977. struct type_list_unique<type_list<First, Other...>, Type...>
  8978. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  8979. template<typename... Type>
  8980. struct type_list_unique<type_list<>, Type...> {
  8981. using type = type_list<Type...>;
  8982. };
  8983. } // namespace internal
  8984. /*! @endcond */
  8985. /**
  8986. * @brief Removes duplicates types from a type list.
  8987. * @tparam List Type list.
  8988. */
  8989. template<typename List>
  8990. struct type_list_unique {
  8991. /*! @brief A type list without duplicate types. */
  8992. using type = typename internal::type_list_unique<List>::type;
  8993. };
  8994. /**
  8995. * @brief Helper type.
  8996. * @tparam List Type list.
  8997. */
  8998. template<typename List>
  8999. using type_list_unique_t = typename type_list_unique<List>::type;
  9000. /**
  9001. * @brief Provides the member constant `value` to true if a type list contains a
  9002. * given type, false otherwise.
  9003. * @tparam List Type list.
  9004. * @tparam Type Type to look for.
  9005. */
  9006. template<typename List, typename Type>
  9007. struct type_list_contains;
  9008. /**
  9009. * @copybrief type_list_contains
  9010. * @tparam Type Types provided by the type list.
  9011. * @tparam Other Type to look for.
  9012. */
  9013. template<typename... Type, typename Other>
  9014. struct type_list_contains<type_list<Type...>, Other>
  9015. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  9016. /**
  9017. * @brief Helper variable template.
  9018. * @tparam List Type list.
  9019. * @tparam Type Type to look for.
  9020. */
  9021. template<typename List, typename Type>
  9022. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  9023. /*! @brief Primary template isn't defined on purpose. */
  9024. template<typename...>
  9025. struct type_list_diff;
  9026. /**
  9027. * @brief Computes the difference between two type lists.
  9028. * @tparam Type Types provided by the first type list.
  9029. * @tparam Other Types provided by the second type list.
  9030. */
  9031. template<typename... Type, typename... Other>
  9032. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  9033. /*! @brief A type list that is the difference between the two type lists. */
  9034. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  9035. };
  9036. /**
  9037. * @brief Helper type.
  9038. * @tparam List Type lists between which to compute the difference.
  9039. */
  9040. template<typename... List>
  9041. using type_list_diff_t = typename type_list_diff<List...>::type;
  9042. /*! @brief Primary template isn't defined on purpose. */
  9043. template<typename, template<typename...> class>
  9044. struct type_list_transform;
  9045. /**
  9046. * @brief Applies a given _function_ to a type list and generate a new list.
  9047. * @tparam Type Types provided by the type list.
  9048. * @tparam Op Unary operation as template class with a type member named `type`.
  9049. */
  9050. template<typename... Type, template<typename...> class Op>
  9051. struct type_list_transform<type_list<Type...>, Op> {
  9052. /*! @brief Resulting type list after applying the transform function. */
  9053. // NOLINTNEXTLINE(modernize-type-traits)
  9054. using type = type_list<typename Op<Type>::type...>;
  9055. };
  9056. /**
  9057. * @brief Helper type.
  9058. * @tparam List Type list.
  9059. * @tparam Op Unary operation as template class with a type member named `type`.
  9060. */
  9061. template<typename List, template<typename...> class Op>
  9062. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  9063. /**
  9064. * @brief A class to use to push around lists of constant values, nothing more.
  9065. * @tparam Value Values provided by the value list.
  9066. */
  9067. template<auto... Value>
  9068. struct value_list {
  9069. /*! @brief Value list type. */
  9070. using type = value_list;
  9071. /*! @brief Compile-time number of elements in the value list. */
  9072. static constexpr auto size = sizeof...(Value);
  9073. };
  9074. /*! @brief Primary template isn't defined on purpose. */
  9075. template<std::size_t, typename>
  9076. struct value_list_element;
  9077. /**
  9078. * @brief Provides compile-time indexed access to the values of a value list.
  9079. * @tparam Index Index of the value to return.
  9080. * @tparam Value First value provided by the value list.
  9081. * @tparam Other Other values provided by the value list.
  9082. */
  9083. template<std::size_t Index, auto Value, auto... Other>
  9084. struct value_list_element<Index, value_list<Value, Other...>>
  9085. : value_list_element<Index - 1u, value_list<Other...>> {};
  9086. /**
  9087. * @brief Provides compile-time indexed access to the types of a type list.
  9088. * @tparam Value First value provided by the value list.
  9089. * @tparam Other Other values provided by the value list.
  9090. */
  9091. template<auto Value, auto... Other>
  9092. struct value_list_element<0u, value_list<Value, Other...>> {
  9093. /*! @brief Searched type. */
  9094. using type = decltype(Value);
  9095. /*! @brief Searched value. */
  9096. static constexpr auto value = Value;
  9097. };
  9098. /**
  9099. * @brief Helper type.
  9100. * @tparam Index Index of the type to return.
  9101. * @tparam List Value list to search into.
  9102. */
  9103. template<std::size_t Index, typename List>
  9104. using value_list_element_t = typename value_list_element<Index, List>::type;
  9105. /**
  9106. * @brief Helper type.
  9107. * @tparam Index Index of the value to return.
  9108. * @tparam List Value list to search into.
  9109. */
  9110. template<std::size_t Index, typename List>
  9111. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  9112. /*! @brief Primary template isn't defined on purpose. */
  9113. template<auto, typename>
  9114. struct value_list_index;
  9115. /**
  9116. * @brief Provides compile-time type access to the values of a value list.
  9117. * @tparam Value Value to look for and for which to return the index.
  9118. * @tparam First First value provided by the value list.
  9119. * @tparam Other Other values provided by the value list.
  9120. */
  9121. template<auto Value, auto First, auto... Other>
  9122. struct value_list_index<Value, value_list<First, Other...>> {
  9123. /*! @brief Unsigned integer type. */
  9124. using value_type = std::size_t;
  9125. /*! @brief Compile-time position of the given value in the sublist. */
  9126. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  9127. };
  9128. /**
  9129. * @brief Provides compile-time type access to the values of a value list.
  9130. * @tparam Value Value to look for and for which to return the index.
  9131. * @tparam Other Other values provided by the value list.
  9132. */
  9133. template<auto Value, auto... Other>
  9134. struct value_list_index<Value, value_list<Value, Other...>> {
  9135. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  9136. /*! @brief Unsigned integer type. */
  9137. using value_type = std::size_t;
  9138. /*! @brief Compile-time position of the given value in the sublist. */
  9139. static constexpr value_type value = 0u;
  9140. };
  9141. /**
  9142. * @brief Provides compile-time type access to the values of a value list.
  9143. * @tparam Value Value to look for and for which to return the index.
  9144. */
  9145. template<auto Value>
  9146. struct value_list_index<Value, value_list<>> {
  9147. /*! @brief Unsigned integer type. */
  9148. using value_type = std::size_t;
  9149. /*! @brief Compile-time position of the given type in the sublist. */
  9150. static constexpr value_type value = 0u;
  9151. };
  9152. /**
  9153. * @brief Helper variable template.
  9154. * @tparam List Value list.
  9155. * @tparam Value Value to look for and for which to return the index.
  9156. */
  9157. template<auto Value, typename List>
  9158. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  9159. /**
  9160. * @brief Concatenates multiple value lists.
  9161. * @tparam Value Values provided by the first value list.
  9162. * @tparam Other Values provided by the second value list.
  9163. * @return A value list composed by the values of both the value lists.
  9164. */
  9165. template<auto... Value, auto... Other>
  9166. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  9167. return {};
  9168. }
  9169. /*! @brief Primary template isn't defined on purpose. */
  9170. template<typename...>
  9171. struct value_list_cat;
  9172. /*! @brief Concatenates multiple value lists. */
  9173. template<>
  9174. struct value_list_cat<> {
  9175. /*! @brief A value list composed by the values of all the value lists. */
  9176. using type = value_list<>;
  9177. };
  9178. /**
  9179. * @brief Concatenates multiple value lists.
  9180. * @tparam Value Values provided by the first value list.
  9181. * @tparam Other Values provided by the second value list.
  9182. * @tparam List Other value lists, if any.
  9183. */
  9184. template<auto... Value, auto... Other, typename... List>
  9185. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  9186. /*! @brief A value list composed by the values of all the value lists. */
  9187. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  9188. };
  9189. /**
  9190. * @brief Concatenates multiple value lists.
  9191. * @tparam Value Values provided by the value list.
  9192. */
  9193. template<auto... Value>
  9194. struct value_list_cat<value_list<Value...>> {
  9195. /*! @brief A value list composed by the values of all the value lists. */
  9196. using type = value_list<Value...>;
  9197. };
  9198. /**
  9199. * @brief Helper type.
  9200. * @tparam List Value lists to concatenate.
  9201. */
  9202. template<typename... List>
  9203. using value_list_cat_t = typename value_list_cat<List...>::type;
  9204. /*! @brief Primary template isn't defined on purpose. */
  9205. template<typename>
  9206. struct value_list_unique;
  9207. /**
  9208. * @brief Removes duplicates values from a value list.
  9209. * @tparam Value One of the values provided by the given value list.
  9210. * @tparam Other The other values provided by the given value list.
  9211. */
  9212. template<auto Value, auto... Other>
  9213. struct value_list_unique<value_list<Value, Other...>> {
  9214. /*! @brief A value list without duplicate types. */
  9215. using type = std::conditional_t<
  9216. ((Value == Other) || ...),
  9217. typename value_list_unique<value_list<Other...>>::type,
  9218. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  9219. };
  9220. /*! @brief Removes duplicates values from a value list. */
  9221. template<>
  9222. struct value_list_unique<value_list<>> {
  9223. /*! @brief A value list without duplicate types. */
  9224. using type = value_list<>;
  9225. };
  9226. /**
  9227. * @brief Helper type.
  9228. * @tparam Type A value list.
  9229. */
  9230. template<typename Type>
  9231. using value_list_unique_t = typename value_list_unique<Type>::type;
  9232. /**
  9233. * @brief Provides the member constant `value` to true if a value list contains
  9234. * a given value, false otherwise.
  9235. * @tparam List Value list.
  9236. * @tparam Value Value to look for.
  9237. */
  9238. template<typename List, auto Value>
  9239. struct value_list_contains;
  9240. /**
  9241. * @copybrief value_list_contains
  9242. * @tparam Value Values provided by the value list.
  9243. * @tparam Other Value to look for.
  9244. */
  9245. template<auto... Value, auto Other>
  9246. struct value_list_contains<value_list<Value...>, Other>
  9247. : std::bool_constant<((Value == Other) || ...)> {};
  9248. /**
  9249. * @brief Helper variable template.
  9250. * @tparam List Value list.
  9251. * @tparam Value Value to look for.
  9252. */
  9253. template<typename List, auto Value>
  9254. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  9255. /*! @brief Primary template isn't defined on purpose. */
  9256. template<typename...>
  9257. struct value_list_diff;
  9258. /**
  9259. * @brief Computes the difference between two value lists.
  9260. * @tparam Value Values provided by the first value list.
  9261. * @tparam Other Values provided by the second value list.
  9262. */
  9263. template<auto... Value, auto... Other>
  9264. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  9265. /*! @brief A value list that is the difference between the two value lists. */
  9266. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  9267. };
  9268. /**
  9269. * @brief Helper type.
  9270. * @tparam List Value lists between which to compute the difference.
  9271. */
  9272. template<typename... List>
  9273. using value_list_diff_t = typename value_list_diff<List...>::type;
  9274. /*! @brief Same as std::is_invocable, but with tuples. */
  9275. template<typename, typename>
  9276. struct is_applicable: std::false_type {};
  9277. /**
  9278. * @copybrief is_applicable
  9279. * @tparam Func A valid function type.
  9280. * @tparam Tuple Tuple-like type.
  9281. * @tparam Args The list of arguments to use to probe the function type.
  9282. */
  9283. template<typename Func, template<typename...> class Tuple, typename... Args>
  9284. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  9285. /**
  9286. * @copybrief is_applicable
  9287. * @tparam Func A valid function type.
  9288. * @tparam Tuple Tuple-like type.
  9289. * @tparam Args The list of arguments to use to probe the function type.
  9290. */
  9291. template<typename Func, template<typename...> class Tuple, typename... Args>
  9292. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  9293. /**
  9294. * @brief Helper variable template.
  9295. * @tparam Func A valid function type.
  9296. * @tparam Args The list of arguments to use to probe the function type.
  9297. */
  9298. template<typename Func, typename Args>
  9299. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  9300. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  9301. template<typename, typename, typename>
  9302. struct is_applicable_r: std::false_type {};
  9303. /**
  9304. * @copybrief is_applicable_r
  9305. * @tparam Ret The type to which the return type of the function should be
  9306. * convertible.
  9307. * @tparam Func A valid function type.
  9308. * @tparam Args The list of arguments to use to probe the function type.
  9309. */
  9310. template<typename Ret, typename Func, typename... Args>
  9311. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  9312. /**
  9313. * @brief Helper variable template.
  9314. * @tparam Ret The type to which the return type of the function should be
  9315. * convertible.
  9316. * @tparam Func A valid function type.
  9317. * @tparam Args The list of arguments to use to probe the function type.
  9318. */
  9319. template<typename Ret, typename Func, typename Args>
  9320. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  9321. /**
  9322. * @brief Provides the member constant `value` to true if a given type is
  9323. * complete, false otherwise.
  9324. * @tparam Type The type to test.
  9325. */
  9326. template<typename Type, typename = void>
  9327. struct is_complete: std::false_type {};
  9328. /*! @copydoc is_complete */
  9329. template<typename Type>
  9330. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  9331. /**
  9332. * @brief Helper variable template.
  9333. * @tparam Type The type to test.
  9334. */
  9335. template<typename Type>
  9336. inline constexpr bool is_complete_v = is_complete<Type>::value;
  9337. /**
  9338. * @brief Provides the member constant `value` to true if a given type is an
  9339. * iterator, false otherwise.
  9340. * @tparam Type The type to test.
  9341. */
  9342. template<typename Type, typename = void>
  9343. struct is_iterator: std::false_type {};
  9344. /*! @cond TURN_OFF_DOXYGEN */
  9345. namespace internal {
  9346. template<typename, typename = void>
  9347. struct has_iterator_category: std::false_type {};
  9348. template<typename Type>
  9349. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  9350. } // namespace internal
  9351. /*! @endcond */
  9352. /*! @copydoc is_iterator */
  9353. template<typename Type>
  9354. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  9355. : internal::has_iterator_category<Type> {};
  9356. /**
  9357. * @brief Helper variable template.
  9358. * @tparam Type The type to test.
  9359. */
  9360. template<typename Type>
  9361. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  9362. /**
  9363. * @brief Provides the member constant `value` to true if a given type is both
  9364. * an empty and non-final class, false otherwise.
  9365. * @tparam Type The type to test
  9366. */
  9367. template<typename Type>
  9368. struct is_ebco_eligible
  9369. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  9370. /**
  9371. * @brief Helper variable template.
  9372. * @tparam Type The type to test.
  9373. */
  9374. template<typename Type>
  9375. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  9376. /**
  9377. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  9378. * is valid and denotes a type, false otherwise.
  9379. * @tparam Type The type to test.
  9380. */
  9381. template<typename Type, typename = void>
  9382. struct is_transparent: std::false_type {};
  9383. /*! @copydoc is_transparent */
  9384. template<typename Type>
  9385. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  9386. /**
  9387. * @brief Helper variable template.
  9388. * @tparam Type The type to test.
  9389. */
  9390. template<typename Type>
  9391. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  9392. /*! @cond TURN_OFF_DOXYGEN */
  9393. namespace internal {
  9394. template<typename, typename = void>
  9395. struct has_tuple_size_value: std::false_type {};
  9396. template<typename Type>
  9397. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  9398. template<typename, typename = void>
  9399. struct has_value_type: std::false_type {};
  9400. template<typename Type>
  9401. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  9402. template<typename>
  9403. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  9404. template<typename Type, std::size_t... Index>
  9405. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  9406. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  9407. }
  9408. template<typename>
  9409. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  9410. return false;
  9411. }
  9412. template<typename Type>
  9413. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  9414. return true;
  9415. }
  9416. template<typename Type>
  9417. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  9418. // NOLINTBEGIN(modernize-use-transparent-functors)
  9419. if constexpr(std::is_array_v<Type>) {
  9420. return false;
  9421. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  9422. if constexpr(has_tuple_size_value<Type>::value) {
  9423. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  9424. } else {
  9425. return maybe_equality_comparable<Type>(0);
  9426. }
  9427. } else if constexpr(has_value_type<Type>::value) {
  9428. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  9429. return maybe_equality_comparable<Type>(0);
  9430. } else {
  9431. return false;
  9432. }
  9433. } else {
  9434. return maybe_equality_comparable<Type>(0);
  9435. }
  9436. // NOLINTEND(modernize-use-transparent-functors)
  9437. }
  9438. } // namespace internal
  9439. /*! @endcond */
  9440. /**
  9441. * @brief Provides the member constant `value` to true if a given type is
  9442. * equality comparable, false otherwise.
  9443. * @tparam Type The type to test.
  9444. */
  9445. template<typename Type>
  9446. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  9447. /*! @copydoc is_equality_comparable */
  9448. template<typename Type>
  9449. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  9450. /**
  9451. * @brief Helper variable template.
  9452. * @tparam Type The type to test.
  9453. */
  9454. template<typename Type>
  9455. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  9456. /**
  9457. * @brief Transcribes the constness of a type to another type.
  9458. * @tparam To The type to which to transcribe the constness.
  9459. * @tparam From The type from which to transcribe the constness.
  9460. */
  9461. template<typename To, typename From>
  9462. struct constness_as {
  9463. /*! @brief The type resulting from the transcription of the constness. */
  9464. using type = std::remove_const_t<To>;
  9465. };
  9466. /*! @copydoc constness_as */
  9467. template<typename To, typename From>
  9468. struct constness_as<To, const From> {
  9469. /*! @brief The type resulting from the transcription of the constness. */
  9470. using type = const To;
  9471. };
  9472. /**
  9473. * @brief Alias template to facilitate the transcription of the constness.
  9474. * @tparam To The type to which to transcribe the constness.
  9475. * @tparam From The type from which to transcribe the constness.
  9476. */
  9477. template<typename To, typename From>
  9478. using constness_as_t = typename constness_as<To, From>::type;
  9479. /**
  9480. * @brief Extracts the class of a non-static member object or function.
  9481. * @tparam Member A pointer to a non-static member object or function.
  9482. */
  9483. template<typename Member>
  9484. class member_class {
  9485. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  9486. template<typename Class, typename Ret, typename... Args>
  9487. static Class *clazz(Ret (Class::*)(Args...));
  9488. template<typename Class, typename Ret, typename... Args>
  9489. static Class *clazz(Ret (Class::*)(Args...) const);
  9490. template<typename Class, typename Type>
  9491. static Class *clazz(Type Class::*);
  9492. public:
  9493. /*! @brief The class of the given non-static member object or function. */
  9494. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  9495. };
  9496. /**
  9497. * @brief Helper type.
  9498. * @tparam Member A pointer to a non-static member object or function.
  9499. */
  9500. template<typename Member>
  9501. using member_class_t = typename member_class<Member>::type;
  9502. /**
  9503. * @brief Extracts the n-th argument of a _callable_ type.
  9504. * @tparam Index The index of the argument to extract.
  9505. * @tparam Candidate A valid _callable_ type.
  9506. */
  9507. template<std::size_t Index, typename Candidate>
  9508. class nth_argument {
  9509. template<typename Ret, typename... Args>
  9510. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  9511. template<typename Ret, typename Class, typename... Args>
  9512. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  9513. template<typename Ret, typename Class, typename... Args>
  9514. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  9515. template<typename Type, typename Class>
  9516. static constexpr type_list<Type> pick_up(Type Class ::*);
  9517. template<typename Type>
  9518. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  9519. public:
  9520. /*! @brief N-th argument of the _callable_ type. */
  9521. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  9522. };
  9523. /**
  9524. * @brief Helper type.
  9525. * @tparam Index The index of the argument to extract.
  9526. * @tparam Candidate A valid function, member function or data member type.
  9527. */
  9528. template<std::size_t Index, typename Candidate>
  9529. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  9530. } // namespace entt
  9531. template<typename... Type>
  9532. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  9533. template<std::size_t Index, typename... Type>
  9534. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  9535. template<auto... Value>
  9536. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  9537. template<std::size_t Index, auto... Value>
  9538. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  9539. #endif
  9540. // #include "core/utility.hpp"
  9541. #ifndef ENTT_CORE_UTILITY_HPP
  9542. #define ENTT_CORE_UTILITY_HPP
  9543. #include <type_traits>
  9544. #include <utility>
  9545. namespace entt {
  9546. /*! @brief Identity function object (waiting for C++20). */
  9547. struct identity {
  9548. /*! @brief Indicates that this is a transparent function object. */
  9549. using is_transparent = void;
  9550. /**
  9551. * @brief Returns its argument unchanged.
  9552. * @tparam Type Type of the argument.
  9553. * @param value The actual argument.
  9554. * @return The submitted value as-is.
  9555. */
  9556. template<typename Type>
  9557. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  9558. return std::forward<Type>(value);
  9559. }
  9560. };
  9561. /**
  9562. * @brief Constant utility to disambiguate overloaded members of a class.
  9563. * @tparam Type Type of the desired overload.
  9564. * @tparam Class Type of class to which the member belongs.
  9565. * @param member A valid pointer to a member.
  9566. * @return Pointer to the member.
  9567. */
  9568. template<typename Type, typename Class>
  9569. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  9570. return member;
  9571. }
  9572. /**
  9573. * @brief Constant utility to disambiguate overloaded functions.
  9574. * @tparam Func Function type of the desired overload.
  9575. * @param func A valid pointer to a function.
  9576. * @return Pointer to the function.
  9577. */
  9578. template<typename Func>
  9579. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  9580. return func;
  9581. }
  9582. /**
  9583. * @brief Helper type for visitors.
  9584. * @tparam Func Types of function objects.
  9585. */
  9586. template<typename... Func>
  9587. struct overloaded: Func... {
  9588. using Func::operator()...;
  9589. };
  9590. /**
  9591. * @brief Deduction guide.
  9592. * @tparam Func Types of function objects.
  9593. */
  9594. template<typename... Func>
  9595. overloaded(Func...) -> overloaded<Func...>;
  9596. /**
  9597. * @brief Basic implementation of a y-combinator.
  9598. * @tparam Func Type of a potentially recursive function.
  9599. */
  9600. template<typename Func>
  9601. struct y_combinator {
  9602. /**
  9603. * @brief Constructs a y-combinator from a given function.
  9604. * @param recursive A potentially recursive function.
  9605. */
  9606. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  9607. : func{std::move(recursive)} {}
  9608. /**
  9609. * @brief Invokes a y-combinator and therefore its underlying function.
  9610. * @tparam Args Types of arguments to use to invoke the underlying function.
  9611. * @param args Parameters to use to invoke the underlying function.
  9612. * @return Return value of the underlying function, if any.
  9613. */
  9614. template<typename... Args>
  9615. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  9616. return func(*this, std::forward<Args>(args)...);
  9617. }
  9618. /*! @copydoc operator()() */
  9619. template<typename... Args>
  9620. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  9621. return func(*this, std::forward<Args>(args)...);
  9622. }
  9623. private:
  9624. Func func;
  9625. };
  9626. } // namespace entt
  9627. #endif
  9628. // #include "entity/component.hpp"
  9629. #ifndef ENTT_ENTITY_COMPONENT_HPP
  9630. #define ENTT_ENTITY_COMPONENT_HPP
  9631. #include <cstddef>
  9632. #include <type_traits>
  9633. // #include "../config/config.h"
  9634. #ifndef ENTT_CONFIG_CONFIG_H
  9635. #define ENTT_CONFIG_CONFIG_H
  9636. // #include "version.h"
  9637. #ifndef ENTT_CONFIG_VERSION_H
  9638. #define ENTT_CONFIG_VERSION_H
  9639. // #include "macro.h"
  9640. #ifndef ENTT_CONFIG_MACRO_H
  9641. #define ENTT_CONFIG_MACRO_H
  9642. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  9643. #define ENTT_STR(arg) #arg
  9644. #define ENTT_XSTR(arg) ENTT_STR(arg)
  9645. // NOLINTEND(cppcoreguidelines-macro-usage)
  9646. #endif
  9647. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  9648. #define ENTT_VERSION_MAJOR 3
  9649. #define ENTT_VERSION_MINOR 16
  9650. #define ENTT_VERSION_PATCH 0
  9651. #define ENTT_VERSION \
  9652. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  9653. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  9654. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  9655. #endif
  9656. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  9657. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  9658. # define ENTT_CONSTEXPR
  9659. # define ENTT_THROW throw
  9660. # define ENTT_TRY try
  9661. # define ENTT_CATCH catch(...)
  9662. #else
  9663. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  9664. # define ENTT_THROW
  9665. # define ENTT_TRY if(true)
  9666. # define ENTT_CATCH if(false)
  9667. #endif
  9668. #if __has_include(<version>)
  9669. # include <version>
  9670. #
  9671. # if defined(__cpp_consteval)
  9672. # define ENTT_CONSTEVAL consteval
  9673. # endif
  9674. #endif
  9675. #ifndef ENTT_CONSTEVAL
  9676. # define ENTT_CONSTEVAL constexpr
  9677. #endif
  9678. #ifdef ENTT_USE_ATOMIC
  9679. # include <atomic>
  9680. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  9681. #else
  9682. # define ENTT_MAYBE_ATOMIC(Type) Type
  9683. #endif
  9684. #ifndef ENTT_ID_TYPE
  9685. # include <cstdint>
  9686. # define ENTT_ID_TYPE std::uint32_t
  9687. #else
  9688. # include <cstdint> // provides coverage for types in the std namespace
  9689. #endif
  9690. #ifndef ENTT_SPARSE_PAGE
  9691. # define ENTT_SPARSE_PAGE 4096
  9692. #endif
  9693. #ifndef ENTT_PACKED_PAGE
  9694. # define ENTT_PACKED_PAGE 1024
  9695. #endif
  9696. #ifdef ENTT_DISABLE_ASSERT
  9697. # undef ENTT_ASSERT
  9698. # define ENTT_ASSERT(condition, msg) (void(0))
  9699. #elif !defined ENTT_ASSERT
  9700. # include <cassert>
  9701. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  9702. #endif
  9703. #ifdef ENTT_DISABLE_ASSERT
  9704. # undef ENTT_ASSERT_CONSTEXPR
  9705. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  9706. #elif !defined ENTT_ASSERT_CONSTEXPR
  9707. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  9708. #endif
  9709. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  9710. #ifdef ENTT_NO_ETO
  9711. # define ENTT_ETO_TYPE(Type) void
  9712. #else
  9713. # define ENTT_ETO_TYPE(Type) Type
  9714. #endif
  9715. #ifdef ENTT_NO_MIXIN
  9716. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  9717. #else
  9718. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  9719. #endif
  9720. #ifdef ENTT_STANDARD_CPP
  9721. # define ENTT_NONSTD false
  9722. #else
  9723. # define ENTT_NONSTD true
  9724. # if defined __clang__ || defined __GNUC__
  9725. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  9726. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  9727. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  9728. # elif defined _MSC_VER
  9729. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  9730. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  9731. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  9732. # endif
  9733. #endif
  9734. #ifndef ENTT_EXPORT
  9735. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  9736. # define ENTT_EXPORT __declspec(dllexport)
  9737. # define ENTT_IMPORT __declspec(dllimport)
  9738. # define ENTT_HIDDEN
  9739. # elif defined __GNUC__ && __GNUC__ >= 4
  9740. # define ENTT_EXPORT __attribute__((visibility("default")))
  9741. # define ENTT_IMPORT __attribute__((visibility("default")))
  9742. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  9743. # else /* Unsupported compiler */
  9744. # define ENTT_EXPORT
  9745. # define ENTT_IMPORT
  9746. # define ENTT_HIDDEN
  9747. # endif
  9748. #endif
  9749. #ifndef ENTT_API
  9750. # if defined ENTT_API_EXPORT
  9751. # define ENTT_API ENTT_EXPORT
  9752. # elif defined ENTT_API_IMPORT
  9753. # define ENTT_API ENTT_IMPORT
  9754. # else /* No API */
  9755. # define ENTT_API
  9756. # endif
  9757. #endif
  9758. #if defined _MSC_VER
  9759. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  9760. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  9761. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  9762. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  9763. #endif
  9764. // NOLINTEND(cppcoreguidelines-macro-usage)
  9765. #endif
  9766. // #include "fwd.hpp"
  9767. #ifndef ENTT_ENTITY_FWD_HPP
  9768. #define ENTT_ENTITY_FWD_HPP
  9769. #include <cstdint>
  9770. #include <memory>
  9771. #include <type_traits>
  9772. // #include "../config/config.h"
  9773. // #include "../core/fwd.hpp"
  9774. #ifndef ENTT_CORE_FWD_HPP
  9775. #define ENTT_CORE_FWD_HPP
  9776. #include <cstddef>
  9777. #include <cstdint>
  9778. // #include "../config/config.h"
  9779. #ifndef ENTT_CONFIG_CONFIG_H
  9780. #define ENTT_CONFIG_CONFIG_H
  9781. // #include "version.h"
  9782. #ifndef ENTT_CONFIG_VERSION_H
  9783. #define ENTT_CONFIG_VERSION_H
  9784. // #include "macro.h"
  9785. #ifndef ENTT_CONFIG_MACRO_H
  9786. #define ENTT_CONFIG_MACRO_H
  9787. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  9788. #define ENTT_STR(arg) #arg
  9789. #define ENTT_XSTR(arg) ENTT_STR(arg)
  9790. // NOLINTEND(cppcoreguidelines-macro-usage)
  9791. #endif
  9792. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  9793. #define ENTT_VERSION_MAJOR 3
  9794. #define ENTT_VERSION_MINOR 16
  9795. #define ENTT_VERSION_PATCH 0
  9796. #define ENTT_VERSION \
  9797. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  9798. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  9799. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  9800. #endif
  9801. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  9802. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  9803. # define ENTT_CONSTEXPR
  9804. # define ENTT_THROW throw
  9805. # define ENTT_TRY try
  9806. # define ENTT_CATCH catch(...)
  9807. #else
  9808. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  9809. # define ENTT_THROW
  9810. # define ENTT_TRY if(true)
  9811. # define ENTT_CATCH if(false)
  9812. #endif
  9813. #if __has_include(<version>)
  9814. # include <version>
  9815. #
  9816. # if defined(__cpp_consteval)
  9817. # define ENTT_CONSTEVAL consteval
  9818. # endif
  9819. #endif
  9820. #ifndef ENTT_CONSTEVAL
  9821. # define ENTT_CONSTEVAL constexpr
  9822. #endif
  9823. #ifdef ENTT_USE_ATOMIC
  9824. # include <atomic>
  9825. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  9826. #else
  9827. # define ENTT_MAYBE_ATOMIC(Type) Type
  9828. #endif
  9829. #ifndef ENTT_ID_TYPE
  9830. # include <cstdint>
  9831. # define ENTT_ID_TYPE std::uint32_t
  9832. #else
  9833. # include <cstdint> // provides coverage for types in the std namespace
  9834. #endif
  9835. #ifndef ENTT_SPARSE_PAGE
  9836. # define ENTT_SPARSE_PAGE 4096
  9837. #endif
  9838. #ifndef ENTT_PACKED_PAGE
  9839. # define ENTT_PACKED_PAGE 1024
  9840. #endif
  9841. #ifdef ENTT_DISABLE_ASSERT
  9842. # undef ENTT_ASSERT
  9843. # define ENTT_ASSERT(condition, msg) (void(0))
  9844. #elif !defined ENTT_ASSERT
  9845. # include <cassert>
  9846. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  9847. #endif
  9848. #ifdef ENTT_DISABLE_ASSERT
  9849. # undef ENTT_ASSERT_CONSTEXPR
  9850. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  9851. #elif !defined ENTT_ASSERT_CONSTEXPR
  9852. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  9853. #endif
  9854. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  9855. #ifdef ENTT_NO_ETO
  9856. # define ENTT_ETO_TYPE(Type) void
  9857. #else
  9858. # define ENTT_ETO_TYPE(Type) Type
  9859. #endif
  9860. #ifdef ENTT_NO_MIXIN
  9861. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  9862. #else
  9863. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  9864. #endif
  9865. #ifdef ENTT_STANDARD_CPP
  9866. # define ENTT_NONSTD false
  9867. #else
  9868. # define ENTT_NONSTD true
  9869. # if defined __clang__ || defined __GNUC__
  9870. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  9871. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  9872. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  9873. # elif defined _MSC_VER
  9874. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  9875. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  9876. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  9877. # endif
  9878. #endif
  9879. #ifndef ENTT_EXPORT
  9880. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  9881. # define ENTT_EXPORT __declspec(dllexport)
  9882. # define ENTT_IMPORT __declspec(dllimport)
  9883. # define ENTT_HIDDEN
  9884. # elif defined __GNUC__ && __GNUC__ >= 4
  9885. # define ENTT_EXPORT __attribute__((visibility("default")))
  9886. # define ENTT_IMPORT __attribute__((visibility("default")))
  9887. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  9888. # else /* Unsupported compiler */
  9889. # define ENTT_EXPORT
  9890. # define ENTT_IMPORT
  9891. # define ENTT_HIDDEN
  9892. # endif
  9893. #endif
  9894. #ifndef ENTT_API
  9895. # if defined ENTT_API_EXPORT
  9896. # define ENTT_API ENTT_EXPORT
  9897. # elif defined ENTT_API_IMPORT
  9898. # define ENTT_API ENTT_IMPORT
  9899. # else /* No API */
  9900. # define ENTT_API
  9901. # endif
  9902. #endif
  9903. #if defined _MSC_VER
  9904. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  9905. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  9906. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  9907. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  9908. #endif
  9909. // NOLINTEND(cppcoreguidelines-macro-usage)
  9910. #endif
  9911. namespace entt {
  9912. /*! @brief Possible modes of an any object. */
  9913. enum class any_policy : std::uint8_t {
  9914. /*! @brief Default mode, no element available. */
  9915. empty,
  9916. /*! @brief Owning mode, dynamically allocated element. */
  9917. dynamic,
  9918. /*! @brief Owning mode, embedded element. */
  9919. embedded,
  9920. /*! @brief Aliasing mode, non-const reference. */
  9921. ref,
  9922. /*! @brief Const aliasing mode, const reference. */
  9923. cref
  9924. };
  9925. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  9926. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  9927. class basic_any;
  9928. /*! @brief Alias declaration for type identifiers. */
  9929. using id_type = ENTT_ID_TYPE;
  9930. /*! @brief Alias declaration for the most common use case. */
  9931. using any = basic_any<>;
  9932. template<typename, typename>
  9933. class compressed_pair;
  9934. template<typename>
  9935. class basic_hashed_string;
  9936. /*! @brief Aliases for common character types. */
  9937. using hashed_string = basic_hashed_string<char>;
  9938. /*! @brief Aliases for common character types. */
  9939. using hashed_wstring = basic_hashed_string<wchar_t>;
  9940. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  9941. struct type_info;
  9942. } // namespace entt
  9943. #endif
  9944. // #include "../core/type_traits.hpp"
  9945. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  9946. #define ENTT_CORE_TYPE_TRAITS_HPP
  9947. #include <cstddef>
  9948. #include <iterator>
  9949. #include <tuple>
  9950. #include <type_traits>
  9951. #include <utility>
  9952. // #include "../config/config.h"
  9953. // #include "fwd.hpp"
  9954. #ifndef ENTT_CORE_FWD_HPP
  9955. #define ENTT_CORE_FWD_HPP
  9956. #include <cstddef>
  9957. #include <cstdint>
  9958. // #include "../config/config.h"
  9959. namespace entt {
  9960. /*! @brief Possible modes of an any object. */
  9961. enum class any_policy : std::uint8_t {
  9962. /*! @brief Default mode, no element available. */
  9963. empty,
  9964. /*! @brief Owning mode, dynamically allocated element. */
  9965. dynamic,
  9966. /*! @brief Owning mode, embedded element. */
  9967. embedded,
  9968. /*! @brief Aliasing mode, non-const reference. */
  9969. ref,
  9970. /*! @brief Const aliasing mode, const reference. */
  9971. cref
  9972. };
  9973. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  9974. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  9975. class basic_any;
  9976. /*! @brief Alias declaration for type identifiers. */
  9977. using id_type = ENTT_ID_TYPE;
  9978. /*! @brief Alias declaration for the most common use case. */
  9979. using any = basic_any<>;
  9980. template<typename, typename>
  9981. class compressed_pair;
  9982. template<typename>
  9983. class basic_hashed_string;
  9984. /*! @brief Aliases for common character types. */
  9985. using hashed_string = basic_hashed_string<char>;
  9986. /*! @brief Aliases for common character types. */
  9987. using hashed_wstring = basic_hashed_string<wchar_t>;
  9988. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  9989. struct type_info;
  9990. } // namespace entt
  9991. #endif
  9992. namespace entt {
  9993. /**
  9994. * @brief Utility class to disambiguate overloaded functions.
  9995. * @tparam N Number of choices available.
  9996. */
  9997. template<std::size_t N>
  9998. struct choice_t
  9999. // unfortunately, doxygen cannot parse such a construct
  10000. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  10001. {};
  10002. /*! @copybrief choice_t */
  10003. template<>
  10004. struct choice_t<0> {};
  10005. /**
  10006. * @brief Variable template for the choice trick.
  10007. * @tparam N Number of choices available.
  10008. */
  10009. template<std::size_t N>
  10010. inline constexpr choice_t<N> choice{};
  10011. /**
  10012. * @brief Identity type trait.
  10013. *
  10014. * Useful to establish non-deduced contexts in template argument deduction
  10015. * (waiting for C++20) or to provide types through function arguments.
  10016. *
  10017. * @tparam Type A type.
  10018. */
  10019. template<typename Type>
  10020. struct type_identity {
  10021. /*! @brief Identity type. */
  10022. using type = Type;
  10023. };
  10024. /**
  10025. * @brief Helper type.
  10026. * @tparam Type A type.
  10027. */
  10028. template<typename Type>
  10029. using type_identity_t = typename type_identity<Type>::type;
  10030. /**
  10031. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  10032. * @tparam Type The type of which to return the size.
  10033. */
  10034. template<typename Type, typename = void>
  10035. struct size_of: std::integral_constant<std::size_t, 0u> {};
  10036. /*! @copydoc size_of */
  10037. template<typename Type>
  10038. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  10039. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  10040. : std::integral_constant<std::size_t, sizeof(Type)> {};
  10041. /**
  10042. * @brief Helper variable template.
  10043. * @tparam Type The type of which to return the size.
  10044. */
  10045. template<typename Type>
  10046. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  10047. /**
  10048. * @brief Using declaration to be used to _repeat_ the same type a number of
  10049. * times equal to the size of a given parameter pack.
  10050. * @tparam Type A type to repeat.
  10051. */
  10052. template<typename Type, typename>
  10053. using unpack_as_type = Type;
  10054. /**
  10055. * @brief Helper variable template to be used to _repeat_ the same value a
  10056. * number of times equal to the size of a given parameter pack.
  10057. * @tparam Value A value to repeat.
  10058. */
  10059. template<auto Value, typename>
  10060. inline constexpr auto unpack_as_value = Value;
  10061. /**
  10062. * @brief Wraps a static constant.
  10063. * @tparam Value A static constant.
  10064. */
  10065. template<auto Value>
  10066. using integral_constant = std::integral_constant<decltype(Value), Value>;
  10067. /**
  10068. * @brief Alias template to facilitate the creation of named values.
  10069. * @tparam Value A constant value at least convertible to `id_type`.
  10070. */
  10071. template<id_type Value>
  10072. using tag = integral_constant<Value>;
  10073. /**
  10074. * @brief A class to use to push around lists of types, nothing more.
  10075. * @tparam Type Types provided by the type list.
  10076. */
  10077. template<typename... Type>
  10078. struct type_list {
  10079. /*! @brief Type list type. */
  10080. using type = type_list;
  10081. /*! @brief Compile-time number of elements in the type list. */
  10082. static constexpr auto size = sizeof...(Type);
  10083. };
  10084. /*! @brief Primary template isn't defined on purpose. */
  10085. template<std::size_t, typename>
  10086. struct type_list_element;
  10087. /**
  10088. * @brief Provides compile-time indexed access to the types of a type list.
  10089. * @tparam Index Index of the type to return.
  10090. * @tparam First First type provided by the type list.
  10091. * @tparam Other Other types provided by the type list.
  10092. */
  10093. template<std::size_t Index, typename First, typename... Other>
  10094. struct type_list_element<Index, type_list<First, Other...>>
  10095. : type_list_element<Index - 1u, type_list<Other...>> {};
  10096. /**
  10097. * @brief Provides compile-time indexed access to the types of a type list.
  10098. * @tparam First First type provided by the type list.
  10099. * @tparam Other Other types provided by the type list.
  10100. */
  10101. template<typename First, typename... Other>
  10102. struct type_list_element<0u, type_list<First, Other...>> {
  10103. /*! @brief Searched type. */
  10104. using type = First;
  10105. };
  10106. /**
  10107. * @brief Helper type.
  10108. * @tparam Index Index of the type to return.
  10109. * @tparam List Type list to search into.
  10110. */
  10111. template<std::size_t Index, typename List>
  10112. using type_list_element_t = typename type_list_element<Index, List>::type;
  10113. /*! @brief Primary template isn't defined on purpose. */
  10114. template<typename, typename>
  10115. struct type_list_index;
  10116. /**
  10117. * @brief Provides compile-time type access to the types of a type list.
  10118. * @tparam Type Type to look for and for which to return the index.
  10119. * @tparam First First type provided by the type list.
  10120. * @tparam Other Other types provided by the type list.
  10121. */
  10122. template<typename Type, typename First, typename... Other>
  10123. struct type_list_index<Type, type_list<First, Other...>> {
  10124. /*! @brief Unsigned integer type. */
  10125. using value_type = std::size_t;
  10126. /*! @brief Compile-time position of the given type in the sublist. */
  10127. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  10128. };
  10129. /**
  10130. * @brief Provides compile-time type access to the types of a type list.
  10131. * @tparam Type Type to look for and for which to return the index.
  10132. * @tparam Other Other types provided by the type list.
  10133. */
  10134. template<typename Type, typename... Other>
  10135. struct type_list_index<Type, type_list<Type, Other...>> {
  10136. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  10137. /*! @brief Unsigned integer type. */
  10138. using value_type = std::size_t;
  10139. /*! @brief Compile-time position of the given type in the sublist. */
  10140. static constexpr value_type value = 0u;
  10141. };
  10142. /**
  10143. * @brief Provides compile-time type access to the types of a type list.
  10144. * @tparam Type Type to look for and for which to return the index.
  10145. */
  10146. template<typename Type>
  10147. struct type_list_index<Type, type_list<>> {
  10148. /*! @brief Unsigned integer type. */
  10149. using value_type = std::size_t;
  10150. /*! @brief Compile-time position of the given type in the sublist. */
  10151. static constexpr value_type value = 0u;
  10152. };
  10153. /**
  10154. * @brief Helper variable template.
  10155. * @tparam List Type list.
  10156. * @tparam Type Type to look for and for which to return the index.
  10157. */
  10158. template<typename Type, typename List>
  10159. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  10160. /**
  10161. * @brief Concatenates multiple type lists.
  10162. * @tparam Type Types provided by the first type list.
  10163. * @tparam Other Types provided by the second type list.
  10164. * @return A type list composed by the types of both the type lists.
  10165. */
  10166. template<typename... Type, typename... Other>
  10167. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  10168. return {};
  10169. }
  10170. /*! @brief Primary template isn't defined on purpose. */
  10171. template<typename...>
  10172. struct type_list_cat;
  10173. /*! @brief Concatenates multiple type lists. */
  10174. template<>
  10175. struct type_list_cat<> {
  10176. /*! @brief A type list composed by the types of all the type lists. */
  10177. using type = type_list<>;
  10178. };
  10179. /**
  10180. * @brief Concatenates multiple type lists.
  10181. * @tparam Type Types provided by the first type list.
  10182. * @tparam Other Types provided by the second type list.
  10183. * @tparam List Other type lists, if any.
  10184. */
  10185. template<typename... Type, typename... Other, typename... List>
  10186. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  10187. /*! @brief A type list composed by the types of all the type lists. */
  10188. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  10189. };
  10190. /**
  10191. * @brief Concatenates multiple type lists.
  10192. * @tparam Type Types provided by the type list.
  10193. */
  10194. template<typename... Type>
  10195. struct type_list_cat<type_list<Type...>> {
  10196. /*! @brief A type list composed by the types of all the type lists. */
  10197. using type = type_list<Type...>;
  10198. };
  10199. /**
  10200. * @brief Helper type.
  10201. * @tparam List Type lists to concatenate.
  10202. */
  10203. template<typename... List>
  10204. using type_list_cat_t = typename type_list_cat<List...>::type;
  10205. /*! @cond TURN_OFF_DOXYGEN */
  10206. namespace internal {
  10207. template<typename...>
  10208. struct type_list_unique;
  10209. template<typename First, typename... Other, typename... Type>
  10210. struct type_list_unique<type_list<First, Other...>, Type...>
  10211. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  10212. template<typename... Type>
  10213. struct type_list_unique<type_list<>, Type...> {
  10214. using type = type_list<Type...>;
  10215. };
  10216. } // namespace internal
  10217. /*! @endcond */
  10218. /**
  10219. * @brief Removes duplicates types from a type list.
  10220. * @tparam List Type list.
  10221. */
  10222. template<typename List>
  10223. struct type_list_unique {
  10224. /*! @brief A type list without duplicate types. */
  10225. using type = typename internal::type_list_unique<List>::type;
  10226. };
  10227. /**
  10228. * @brief Helper type.
  10229. * @tparam List Type list.
  10230. */
  10231. template<typename List>
  10232. using type_list_unique_t = typename type_list_unique<List>::type;
  10233. /**
  10234. * @brief Provides the member constant `value` to true if a type list contains a
  10235. * given type, false otherwise.
  10236. * @tparam List Type list.
  10237. * @tparam Type Type to look for.
  10238. */
  10239. template<typename List, typename Type>
  10240. struct type_list_contains;
  10241. /**
  10242. * @copybrief type_list_contains
  10243. * @tparam Type Types provided by the type list.
  10244. * @tparam Other Type to look for.
  10245. */
  10246. template<typename... Type, typename Other>
  10247. struct type_list_contains<type_list<Type...>, Other>
  10248. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  10249. /**
  10250. * @brief Helper variable template.
  10251. * @tparam List Type list.
  10252. * @tparam Type Type to look for.
  10253. */
  10254. template<typename List, typename Type>
  10255. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  10256. /*! @brief Primary template isn't defined on purpose. */
  10257. template<typename...>
  10258. struct type_list_diff;
  10259. /**
  10260. * @brief Computes the difference between two type lists.
  10261. * @tparam Type Types provided by the first type list.
  10262. * @tparam Other Types provided by the second type list.
  10263. */
  10264. template<typename... Type, typename... Other>
  10265. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  10266. /*! @brief A type list that is the difference between the two type lists. */
  10267. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  10268. };
  10269. /**
  10270. * @brief Helper type.
  10271. * @tparam List Type lists between which to compute the difference.
  10272. */
  10273. template<typename... List>
  10274. using type_list_diff_t = typename type_list_diff<List...>::type;
  10275. /*! @brief Primary template isn't defined on purpose. */
  10276. template<typename, template<typename...> class>
  10277. struct type_list_transform;
  10278. /**
  10279. * @brief Applies a given _function_ to a type list and generate a new list.
  10280. * @tparam Type Types provided by the type list.
  10281. * @tparam Op Unary operation as template class with a type member named `type`.
  10282. */
  10283. template<typename... Type, template<typename...> class Op>
  10284. struct type_list_transform<type_list<Type...>, Op> {
  10285. /*! @brief Resulting type list after applying the transform function. */
  10286. // NOLINTNEXTLINE(modernize-type-traits)
  10287. using type = type_list<typename Op<Type>::type...>;
  10288. };
  10289. /**
  10290. * @brief Helper type.
  10291. * @tparam List Type list.
  10292. * @tparam Op Unary operation as template class with a type member named `type`.
  10293. */
  10294. template<typename List, template<typename...> class Op>
  10295. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  10296. /**
  10297. * @brief A class to use to push around lists of constant values, nothing more.
  10298. * @tparam Value Values provided by the value list.
  10299. */
  10300. template<auto... Value>
  10301. struct value_list {
  10302. /*! @brief Value list type. */
  10303. using type = value_list;
  10304. /*! @brief Compile-time number of elements in the value list. */
  10305. static constexpr auto size = sizeof...(Value);
  10306. };
  10307. /*! @brief Primary template isn't defined on purpose. */
  10308. template<std::size_t, typename>
  10309. struct value_list_element;
  10310. /**
  10311. * @brief Provides compile-time indexed access to the values of a value list.
  10312. * @tparam Index Index of the value to return.
  10313. * @tparam Value First value provided by the value list.
  10314. * @tparam Other Other values provided by the value list.
  10315. */
  10316. template<std::size_t Index, auto Value, auto... Other>
  10317. struct value_list_element<Index, value_list<Value, Other...>>
  10318. : value_list_element<Index - 1u, value_list<Other...>> {};
  10319. /**
  10320. * @brief Provides compile-time indexed access to the types of a type list.
  10321. * @tparam Value First value provided by the value list.
  10322. * @tparam Other Other values provided by the value list.
  10323. */
  10324. template<auto Value, auto... Other>
  10325. struct value_list_element<0u, value_list<Value, Other...>> {
  10326. /*! @brief Searched type. */
  10327. using type = decltype(Value);
  10328. /*! @brief Searched value. */
  10329. static constexpr auto value = Value;
  10330. };
  10331. /**
  10332. * @brief Helper type.
  10333. * @tparam Index Index of the type to return.
  10334. * @tparam List Value list to search into.
  10335. */
  10336. template<std::size_t Index, typename List>
  10337. using value_list_element_t = typename value_list_element<Index, List>::type;
  10338. /**
  10339. * @brief Helper type.
  10340. * @tparam Index Index of the value to return.
  10341. * @tparam List Value list to search into.
  10342. */
  10343. template<std::size_t Index, typename List>
  10344. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  10345. /*! @brief Primary template isn't defined on purpose. */
  10346. template<auto, typename>
  10347. struct value_list_index;
  10348. /**
  10349. * @brief Provides compile-time type access to the values of a value list.
  10350. * @tparam Value Value to look for and for which to return the index.
  10351. * @tparam First First value provided by the value list.
  10352. * @tparam Other Other values provided by the value list.
  10353. */
  10354. template<auto Value, auto First, auto... Other>
  10355. struct value_list_index<Value, value_list<First, Other...>> {
  10356. /*! @brief Unsigned integer type. */
  10357. using value_type = std::size_t;
  10358. /*! @brief Compile-time position of the given value in the sublist. */
  10359. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  10360. };
  10361. /**
  10362. * @brief Provides compile-time type access to the values of a value list.
  10363. * @tparam Value Value to look for and for which to return the index.
  10364. * @tparam Other Other values provided by the value list.
  10365. */
  10366. template<auto Value, auto... Other>
  10367. struct value_list_index<Value, value_list<Value, Other...>> {
  10368. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  10369. /*! @brief Unsigned integer type. */
  10370. using value_type = std::size_t;
  10371. /*! @brief Compile-time position of the given value in the sublist. */
  10372. static constexpr value_type value = 0u;
  10373. };
  10374. /**
  10375. * @brief Provides compile-time type access to the values of a value list.
  10376. * @tparam Value Value to look for and for which to return the index.
  10377. */
  10378. template<auto Value>
  10379. struct value_list_index<Value, value_list<>> {
  10380. /*! @brief Unsigned integer type. */
  10381. using value_type = std::size_t;
  10382. /*! @brief Compile-time position of the given type in the sublist. */
  10383. static constexpr value_type value = 0u;
  10384. };
  10385. /**
  10386. * @brief Helper variable template.
  10387. * @tparam List Value list.
  10388. * @tparam Value Value to look for and for which to return the index.
  10389. */
  10390. template<auto Value, typename List>
  10391. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  10392. /**
  10393. * @brief Concatenates multiple value lists.
  10394. * @tparam Value Values provided by the first value list.
  10395. * @tparam Other Values provided by the second value list.
  10396. * @return A value list composed by the values of both the value lists.
  10397. */
  10398. template<auto... Value, auto... Other>
  10399. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  10400. return {};
  10401. }
  10402. /*! @brief Primary template isn't defined on purpose. */
  10403. template<typename...>
  10404. struct value_list_cat;
  10405. /*! @brief Concatenates multiple value lists. */
  10406. template<>
  10407. struct value_list_cat<> {
  10408. /*! @brief A value list composed by the values of all the value lists. */
  10409. using type = value_list<>;
  10410. };
  10411. /**
  10412. * @brief Concatenates multiple value lists.
  10413. * @tparam Value Values provided by the first value list.
  10414. * @tparam Other Values provided by the second value list.
  10415. * @tparam List Other value lists, if any.
  10416. */
  10417. template<auto... Value, auto... Other, typename... List>
  10418. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  10419. /*! @brief A value list composed by the values of all the value lists. */
  10420. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  10421. };
  10422. /**
  10423. * @brief Concatenates multiple value lists.
  10424. * @tparam Value Values provided by the value list.
  10425. */
  10426. template<auto... Value>
  10427. struct value_list_cat<value_list<Value...>> {
  10428. /*! @brief A value list composed by the values of all the value lists. */
  10429. using type = value_list<Value...>;
  10430. };
  10431. /**
  10432. * @brief Helper type.
  10433. * @tparam List Value lists to concatenate.
  10434. */
  10435. template<typename... List>
  10436. using value_list_cat_t = typename value_list_cat<List...>::type;
  10437. /*! @brief Primary template isn't defined on purpose. */
  10438. template<typename>
  10439. struct value_list_unique;
  10440. /**
  10441. * @brief Removes duplicates values from a value list.
  10442. * @tparam Value One of the values provided by the given value list.
  10443. * @tparam Other The other values provided by the given value list.
  10444. */
  10445. template<auto Value, auto... Other>
  10446. struct value_list_unique<value_list<Value, Other...>> {
  10447. /*! @brief A value list without duplicate types. */
  10448. using type = std::conditional_t<
  10449. ((Value == Other) || ...),
  10450. typename value_list_unique<value_list<Other...>>::type,
  10451. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  10452. };
  10453. /*! @brief Removes duplicates values from a value list. */
  10454. template<>
  10455. struct value_list_unique<value_list<>> {
  10456. /*! @brief A value list without duplicate types. */
  10457. using type = value_list<>;
  10458. };
  10459. /**
  10460. * @brief Helper type.
  10461. * @tparam Type A value list.
  10462. */
  10463. template<typename Type>
  10464. using value_list_unique_t = typename value_list_unique<Type>::type;
  10465. /**
  10466. * @brief Provides the member constant `value` to true if a value list contains
  10467. * a given value, false otherwise.
  10468. * @tparam List Value list.
  10469. * @tparam Value Value to look for.
  10470. */
  10471. template<typename List, auto Value>
  10472. struct value_list_contains;
  10473. /**
  10474. * @copybrief value_list_contains
  10475. * @tparam Value Values provided by the value list.
  10476. * @tparam Other Value to look for.
  10477. */
  10478. template<auto... Value, auto Other>
  10479. struct value_list_contains<value_list<Value...>, Other>
  10480. : std::bool_constant<((Value == Other) || ...)> {};
  10481. /**
  10482. * @brief Helper variable template.
  10483. * @tparam List Value list.
  10484. * @tparam Value Value to look for.
  10485. */
  10486. template<typename List, auto Value>
  10487. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  10488. /*! @brief Primary template isn't defined on purpose. */
  10489. template<typename...>
  10490. struct value_list_diff;
  10491. /**
  10492. * @brief Computes the difference between two value lists.
  10493. * @tparam Value Values provided by the first value list.
  10494. * @tparam Other Values provided by the second value list.
  10495. */
  10496. template<auto... Value, auto... Other>
  10497. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  10498. /*! @brief A value list that is the difference between the two value lists. */
  10499. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  10500. };
  10501. /**
  10502. * @brief Helper type.
  10503. * @tparam List Value lists between which to compute the difference.
  10504. */
  10505. template<typename... List>
  10506. using value_list_diff_t = typename value_list_diff<List...>::type;
  10507. /*! @brief Same as std::is_invocable, but with tuples. */
  10508. template<typename, typename>
  10509. struct is_applicable: std::false_type {};
  10510. /**
  10511. * @copybrief is_applicable
  10512. * @tparam Func A valid function type.
  10513. * @tparam Tuple Tuple-like type.
  10514. * @tparam Args The list of arguments to use to probe the function type.
  10515. */
  10516. template<typename Func, template<typename...> class Tuple, typename... Args>
  10517. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  10518. /**
  10519. * @copybrief is_applicable
  10520. * @tparam Func A valid function type.
  10521. * @tparam Tuple Tuple-like type.
  10522. * @tparam Args The list of arguments to use to probe the function type.
  10523. */
  10524. template<typename Func, template<typename...> class Tuple, typename... Args>
  10525. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  10526. /**
  10527. * @brief Helper variable template.
  10528. * @tparam Func A valid function type.
  10529. * @tparam Args The list of arguments to use to probe the function type.
  10530. */
  10531. template<typename Func, typename Args>
  10532. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  10533. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  10534. template<typename, typename, typename>
  10535. struct is_applicable_r: std::false_type {};
  10536. /**
  10537. * @copybrief is_applicable_r
  10538. * @tparam Ret The type to which the return type of the function should be
  10539. * convertible.
  10540. * @tparam Func A valid function type.
  10541. * @tparam Args The list of arguments to use to probe the function type.
  10542. */
  10543. template<typename Ret, typename Func, typename... Args>
  10544. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  10545. /**
  10546. * @brief Helper variable template.
  10547. * @tparam Ret The type to which the return type of the function should be
  10548. * convertible.
  10549. * @tparam Func A valid function type.
  10550. * @tparam Args The list of arguments to use to probe the function type.
  10551. */
  10552. template<typename Ret, typename Func, typename Args>
  10553. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  10554. /**
  10555. * @brief Provides the member constant `value` to true if a given type is
  10556. * complete, false otherwise.
  10557. * @tparam Type The type to test.
  10558. */
  10559. template<typename Type, typename = void>
  10560. struct is_complete: std::false_type {};
  10561. /*! @copydoc is_complete */
  10562. template<typename Type>
  10563. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  10564. /**
  10565. * @brief Helper variable template.
  10566. * @tparam Type The type to test.
  10567. */
  10568. template<typename Type>
  10569. inline constexpr bool is_complete_v = is_complete<Type>::value;
  10570. /**
  10571. * @brief Provides the member constant `value` to true if a given type is an
  10572. * iterator, false otherwise.
  10573. * @tparam Type The type to test.
  10574. */
  10575. template<typename Type, typename = void>
  10576. struct is_iterator: std::false_type {};
  10577. /*! @cond TURN_OFF_DOXYGEN */
  10578. namespace internal {
  10579. template<typename, typename = void>
  10580. struct has_iterator_category: std::false_type {};
  10581. template<typename Type>
  10582. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  10583. } // namespace internal
  10584. /*! @endcond */
  10585. /*! @copydoc is_iterator */
  10586. template<typename Type>
  10587. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  10588. : internal::has_iterator_category<Type> {};
  10589. /**
  10590. * @brief Helper variable template.
  10591. * @tparam Type The type to test.
  10592. */
  10593. template<typename Type>
  10594. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  10595. /**
  10596. * @brief Provides the member constant `value` to true if a given type is both
  10597. * an empty and non-final class, false otherwise.
  10598. * @tparam Type The type to test
  10599. */
  10600. template<typename Type>
  10601. struct is_ebco_eligible
  10602. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  10603. /**
  10604. * @brief Helper variable template.
  10605. * @tparam Type The type to test.
  10606. */
  10607. template<typename Type>
  10608. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  10609. /**
  10610. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  10611. * is valid and denotes a type, false otherwise.
  10612. * @tparam Type The type to test.
  10613. */
  10614. template<typename Type, typename = void>
  10615. struct is_transparent: std::false_type {};
  10616. /*! @copydoc is_transparent */
  10617. template<typename Type>
  10618. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  10619. /**
  10620. * @brief Helper variable template.
  10621. * @tparam Type The type to test.
  10622. */
  10623. template<typename Type>
  10624. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  10625. /*! @cond TURN_OFF_DOXYGEN */
  10626. namespace internal {
  10627. template<typename, typename = void>
  10628. struct has_tuple_size_value: std::false_type {};
  10629. template<typename Type>
  10630. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  10631. template<typename, typename = void>
  10632. struct has_value_type: std::false_type {};
  10633. template<typename Type>
  10634. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  10635. template<typename>
  10636. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  10637. template<typename Type, std::size_t... Index>
  10638. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  10639. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  10640. }
  10641. template<typename>
  10642. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  10643. return false;
  10644. }
  10645. template<typename Type>
  10646. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  10647. return true;
  10648. }
  10649. template<typename Type>
  10650. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  10651. // NOLINTBEGIN(modernize-use-transparent-functors)
  10652. if constexpr(std::is_array_v<Type>) {
  10653. return false;
  10654. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  10655. if constexpr(has_tuple_size_value<Type>::value) {
  10656. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  10657. } else {
  10658. return maybe_equality_comparable<Type>(0);
  10659. }
  10660. } else if constexpr(has_value_type<Type>::value) {
  10661. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  10662. return maybe_equality_comparable<Type>(0);
  10663. } else {
  10664. return false;
  10665. }
  10666. } else {
  10667. return maybe_equality_comparable<Type>(0);
  10668. }
  10669. // NOLINTEND(modernize-use-transparent-functors)
  10670. }
  10671. } // namespace internal
  10672. /*! @endcond */
  10673. /**
  10674. * @brief Provides the member constant `value` to true if a given type is
  10675. * equality comparable, false otherwise.
  10676. * @tparam Type The type to test.
  10677. */
  10678. template<typename Type>
  10679. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  10680. /*! @copydoc is_equality_comparable */
  10681. template<typename Type>
  10682. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  10683. /**
  10684. * @brief Helper variable template.
  10685. * @tparam Type The type to test.
  10686. */
  10687. template<typename Type>
  10688. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  10689. /**
  10690. * @brief Transcribes the constness of a type to another type.
  10691. * @tparam To The type to which to transcribe the constness.
  10692. * @tparam From The type from which to transcribe the constness.
  10693. */
  10694. template<typename To, typename From>
  10695. struct constness_as {
  10696. /*! @brief The type resulting from the transcription of the constness. */
  10697. using type = std::remove_const_t<To>;
  10698. };
  10699. /*! @copydoc constness_as */
  10700. template<typename To, typename From>
  10701. struct constness_as<To, const From> {
  10702. /*! @brief The type resulting from the transcription of the constness. */
  10703. using type = const To;
  10704. };
  10705. /**
  10706. * @brief Alias template to facilitate the transcription of the constness.
  10707. * @tparam To The type to which to transcribe the constness.
  10708. * @tparam From The type from which to transcribe the constness.
  10709. */
  10710. template<typename To, typename From>
  10711. using constness_as_t = typename constness_as<To, From>::type;
  10712. /**
  10713. * @brief Extracts the class of a non-static member object or function.
  10714. * @tparam Member A pointer to a non-static member object or function.
  10715. */
  10716. template<typename Member>
  10717. class member_class {
  10718. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  10719. template<typename Class, typename Ret, typename... Args>
  10720. static Class *clazz(Ret (Class::*)(Args...));
  10721. template<typename Class, typename Ret, typename... Args>
  10722. static Class *clazz(Ret (Class::*)(Args...) const);
  10723. template<typename Class, typename Type>
  10724. static Class *clazz(Type Class::*);
  10725. public:
  10726. /*! @brief The class of the given non-static member object or function. */
  10727. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  10728. };
  10729. /**
  10730. * @brief Helper type.
  10731. * @tparam Member A pointer to a non-static member object or function.
  10732. */
  10733. template<typename Member>
  10734. using member_class_t = typename member_class<Member>::type;
  10735. /**
  10736. * @brief Extracts the n-th argument of a _callable_ type.
  10737. * @tparam Index The index of the argument to extract.
  10738. * @tparam Candidate A valid _callable_ type.
  10739. */
  10740. template<std::size_t Index, typename Candidate>
  10741. class nth_argument {
  10742. template<typename Ret, typename... Args>
  10743. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  10744. template<typename Ret, typename Class, typename... Args>
  10745. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  10746. template<typename Ret, typename Class, typename... Args>
  10747. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  10748. template<typename Type, typename Class>
  10749. static constexpr type_list<Type> pick_up(Type Class ::*);
  10750. template<typename Type>
  10751. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  10752. public:
  10753. /*! @brief N-th argument of the _callable_ type. */
  10754. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  10755. };
  10756. /**
  10757. * @brief Helper type.
  10758. * @tparam Index The index of the argument to extract.
  10759. * @tparam Candidate A valid function, member function or data member type.
  10760. */
  10761. template<std::size_t Index, typename Candidate>
  10762. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  10763. } // namespace entt
  10764. template<typename... Type>
  10765. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  10766. template<std::size_t Index, typename... Type>
  10767. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  10768. template<auto... Value>
  10769. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  10770. template<std::size_t Index, auto... Value>
  10771. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  10772. #endif
  10773. namespace entt {
  10774. /*! @brief Default entity identifier. */
  10775. enum class entity : id_type {};
  10776. /*! @brief Storage deletion policy. */
  10777. enum class deletion_policy : std::uint8_t {
  10778. /*! @brief Swap-and-pop deletion policy. */
  10779. swap_and_pop = 0u,
  10780. /*! @brief In-place deletion policy. */
  10781. in_place = 1u,
  10782. /*! @brief Swap-only deletion policy. */
  10783. swap_only = 2u,
  10784. /*! @brief Unspecified deletion policy. */
  10785. unspecified = swap_and_pop
  10786. };
  10787. template<typename Type, typename Entity = entity, typename = void>
  10788. struct component_traits;
  10789. template<typename Entity = entity, typename = std::allocator<Entity>>
  10790. class basic_sparse_set;
  10791. template<typename Type, typename = entity, typename = std::allocator<Type>, typename = void>
  10792. class basic_storage;
  10793. template<typename, typename>
  10794. class basic_sigh_mixin;
  10795. template<typename, typename>
  10796. class basic_reactive_mixin;
  10797. template<typename Entity = entity, typename = std::allocator<Entity>>
  10798. class basic_registry;
  10799. template<typename, typename, typename = void>
  10800. class basic_view;
  10801. template<typename Type, typename = std::allocator<Type *>>
  10802. class basic_runtime_view;
  10803. template<typename, typename, typename>
  10804. class basic_group;
  10805. template<typename>
  10806. class basic_organizer;
  10807. template<typename, typename...>
  10808. class basic_handle;
  10809. template<typename>
  10810. class basic_snapshot;
  10811. template<typename>
  10812. class basic_snapshot_loader;
  10813. template<typename>
  10814. class basic_continuous_loader;
  10815. /*! @brief Alias declaration for the most common use case. */
  10816. using sparse_set = basic_sparse_set<>;
  10817. /**
  10818. * @brief Alias declaration for the most common use case.
  10819. * @tparam Type Element type.
  10820. */
  10821. template<typename Type>
  10822. using storage = basic_storage<Type>;
  10823. /**
  10824. * @brief Alias declaration for the most common use case.
  10825. * @tparam Type Underlying storage type.
  10826. */
  10827. template<typename Type>
  10828. using sigh_mixin = basic_sigh_mixin<Type, basic_registry<typename Type::entity_type, typename Type::base_type::allocator_type>>;
  10829. /**
  10830. * @brief Alias declaration for the most common use case.
  10831. * @tparam Type Underlying storage type.
  10832. */
  10833. template<typename Type>
  10834. using reactive_mixin = basic_reactive_mixin<Type, basic_registry<typename Type::entity_type, typename Type::base_type::allocator_type>>;
  10835. /*! @brief Alias declaration for the most common use case. */
  10836. using registry = basic_registry<>;
  10837. /*! @brief Alias declaration for the most common use case. */
  10838. using organizer = basic_organizer<registry>;
  10839. /*! @brief Alias declaration for the most common use case. */
  10840. using handle = basic_handle<registry>;
  10841. /*! @brief Alias declaration for the most common use case. */
  10842. using const_handle = basic_handle<const registry>;
  10843. /**
  10844. * @brief Alias declaration for the most common use case.
  10845. * @tparam Args Other template parameters.
  10846. */
  10847. template<typename... Args>
  10848. using handle_view = basic_handle<registry, Args...>;
  10849. /**
  10850. * @brief Alias declaration for the most common use case.
  10851. * @tparam Args Other template parameters.
  10852. */
  10853. template<typename... Args>
  10854. using const_handle_view = basic_handle<const registry, Args...>;
  10855. /*! @brief Alias declaration for the most common use case. */
  10856. using snapshot = basic_snapshot<registry>;
  10857. /*! @brief Alias declaration for the most common use case. */
  10858. using snapshot_loader = basic_snapshot_loader<registry>;
  10859. /*! @brief Alias declaration for the most common use case. */
  10860. using continuous_loader = basic_continuous_loader<registry>;
  10861. /*! @brief Alias declaration for the most common use case. */
  10862. using runtime_view = basic_runtime_view<sparse_set>;
  10863. /*! @brief Alias declaration for the most common use case. */
  10864. using const_runtime_view = basic_runtime_view<const sparse_set>;
  10865. /**
  10866. * @brief Alias for exclusion lists.
  10867. * @tparam Type List of types.
  10868. */
  10869. template<typename... Type>
  10870. struct exclude_t final: type_list<Type...> {
  10871. /*! @brief Default constructor. */
  10872. explicit constexpr exclude_t() = default;
  10873. };
  10874. /**
  10875. * @brief Variable template for exclusion lists.
  10876. * @tparam Type List of types.
  10877. */
  10878. template<typename... Type>
  10879. inline constexpr exclude_t<Type...> exclude{};
  10880. /**
  10881. * @brief Alias for lists of observed elements.
  10882. * @tparam Type List of types.
  10883. */
  10884. template<typename... Type>
  10885. struct get_t final: type_list<Type...> {
  10886. /*! @brief Default constructor. */
  10887. explicit constexpr get_t() = default;
  10888. };
  10889. /**
  10890. * @brief Variable template for lists of observed elements.
  10891. * @tparam Type List of types.
  10892. */
  10893. template<typename... Type>
  10894. inline constexpr get_t<Type...> get{};
  10895. /**
  10896. * @brief Alias for lists of owned elements.
  10897. * @tparam Type List of types.
  10898. */
  10899. template<typename... Type>
  10900. struct owned_t final: type_list<Type...> {
  10901. /*! @brief Default constructor. */
  10902. explicit constexpr owned_t() = default;
  10903. };
  10904. /**
  10905. * @brief Variable template for lists of owned elements.
  10906. * @tparam Type List of types.
  10907. */
  10908. template<typename... Type>
  10909. inline constexpr owned_t<Type...> owned{};
  10910. /**
  10911. * @brief Applies a given _function_ to a get list and generate a new list.
  10912. * @tparam Type Types provided by the get list.
  10913. * @tparam Op Unary operation as template class with a type member named `type`.
  10914. */
  10915. template<typename... Type, template<typename...> class Op>
  10916. struct type_list_transform<get_t<Type...>, Op> {
  10917. /*! @brief Resulting get list after applying the transform function. */
  10918. using type = get_t<typename Op<Type>::type...>;
  10919. };
  10920. /**
  10921. * @brief Applies a given _function_ to an exclude list and generate a new list.
  10922. * @tparam Type Types provided by the exclude list.
  10923. * @tparam Op Unary operation as template class with a type member named `type`.
  10924. */
  10925. template<typename... Type, template<typename...> class Op>
  10926. struct type_list_transform<exclude_t<Type...>, Op> {
  10927. /*! @brief Resulting exclude list after applying the transform function. */
  10928. using type = exclude_t<typename Op<Type>::type...>;
  10929. };
  10930. /**
  10931. * @brief Applies a given _function_ to an owned list and generate a new list.
  10932. * @tparam Type Types provided by the owned list.
  10933. * @tparam Op Unary operation as template class with a type member named `type`.
  10934. */
  10935. template<typename... Type, template<typename...> class Op>
  10936. struct type_list_transform<owned_t<Type...>, Op> {
  10937. /*! @brief Resulting owned list after applying the transform function. */
  10938. using type = owned_t<typename Op<Type>::type...>;
  10939. };
  10940. /**
  10941. * @brief Provides a common way to define storage types.
  10942. * @tparam Type Storage value type.
  10943. * @tparam Entity A valid entity type.
  10944. * @tparam Allocator Type of allocator used to manage memory and elements.
  10945. */
  10946. template<typename Type, typename Entity = entity, typename Allocator = std::allocator<Type>, typename = void>
  10947. struct storage_type {
  10948. /*! @brief Type-to-storage conversion result. */
  10949. using type = ENTT_STORAGE(sigh_mixin, basic_storage<Type, Entity, Allocator>);
  10950. };
  10951. /*! @brief Empty value type for reactive storage types. */
  10952. struct reactive final {};
  10953. /**
  10954. * @ brief Partial specialization for reactive storage types.
  10955. * @tparam Entity A valid entity type.
  10956. * @tparam Allocator Type of allocator used to manage memory and elements.
  10957. */
  10958. template<typename Entity, typename Allocator>
  10959. struct storage_type<reactive, Entity, Allocator> {
  10960. /*! @brief Type-to-storage conversion result. */
  10961. using type = ENTT_STORAGE(reactive_mixin, basic_storage<reactive, Entity, Allocator>);
  10962. };
  10963. /**
  10964. * @brief Helper type.
  10965. * @tparam Args Arguments to forward.
  10966. */
  10967. template<typename... Args>
  10968. using storage_type_t = typename storage_type<Args...>::type;
  10969. /**
  10970. * Type-to-storage conversion utility that preserves constness.
  10971. * @tparam Type Storage value type, eventually const.
  10972. * @tparam Entity A valid entity type.
  10973. * @tparam Allocator Type of allocator used to manage memory and elements.
  10974. */
  10975. template<typename Type, typename Entity = entity, typename Allocator = std::allocator<std::remove_const_t<Type>>>
  10976. struct storage_for {
  10977. /*! @brief Type-to-storage conversion result. */
  10978. using type = constness_as_t<storage_type_t<std::remove_const_t<Type>, Entity, Allocator>, Type>;
  10979. };
  10980. /**
  10981. * @brief Helper type.
  10982. * @tparam Args Arguments to forward.
  10983. */
  10984. template<typename... Args>
  10985. using storage_for_t = typename storage_for<Args...>::type;
  10986. /**
  10987. * @brief Alias declaration for the most common use case.
  10988. * @tparam Get Types of storage iterated by the view.
  10989. * @tparam Exclude Types of storage used to filter the view.
  10990. */
  10991. template<typename Get, typename Exclude = exclude_t<>>
  10992. using view = basic_view<type_list_transform_t<Get, storage_for>, type_list_transform_t<Exclude, storage_for>>;
  10993. /**
  10994. * @brief Alias declaration for the most common use case.
  10995. * @tparam Owned Types of storage _owned_ by the group.
  10996. * @tparam Get Types of storage _observed_ by the group.
  10997. * @tparam Exclude Types of storage used to filter the group.
  10998. */
  10999. template<typename Owned, typename Get = get_t<>, typename Exclude = exclude_t<>>
  11000. using group = basic_group<type_list_transform_t<Owned, storage_for>, type_list_transform_t<Get, storage_for>, type_list_transform_t<Exclude, storage_for>>;
  11001. } // namespace entt
  11002. #endif
  11003. namespace entt {
  11004. /*! @cond TURN_OFF_DOXYGEN */
  11005. namespace internal {
  11006. template<typename Type, typename = void>
  11007. struct in_place_delete: std::bool_constant<!(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>)> {};
  11008. template<>
  11009. struct in_place_delete<void>: std::false_type {};
  11010. template<typename Type>
  11011. struct in_place_delete<Type, std::enable_if_t<Type::in_place_delete>>
  11012. : std::true_type {};
  11013. template<typename Type, typename = void>
  11014. struct page_size: std::integral_constant<std::size_t, !std::is_empty_v<ENTT_ETO_TYPE(Type)> * ENTT_PACKED_PAGE> {};
  11015. template<>
  11016. struct page_size<void>: std::integral_constant<std::size_t, 0u> {};
  11017. template<typename Type>
  11018. struct page_size<Type, std::void_t<decltype(Type::page_size)>>
  11019. : std::integral_constant<std::size_t, Type::page_size> {};
  11020. } // namespace internal
  11021. /*! @endcond */
  11022. /**
  11023. * @brief Common way to access various properties of components.
  11024. * @tparam Type Element type.
  11025. * @tparam Entity A valid entity type.
  11026. */
  11027. template<typename Type, typename Entity, typename>
  11028. struct component_traits {
  11029. static_assert(std::is_same_v<std::decay_t<Type>, Type>, "Unsupported type");
  11030. /*! @brief Element type. */
  11031. using element_type = Type;
  11032. /*! @brief Underlying entity identifier. */
  11033. using entity_type = Entity;
  11034. /*! @brief Pointer stability, default is `false`. */
  11035. static constexpr bool in_place_delete = internal::in_place_delete<Type>::value;
  11036. /*! @brief Page size, default is `ENTT_PACKED_PAGE` for non-empty types. */
  11037. static constexpr std::size_t page_size = internal::page_size<Type>::value;
  11038. };
  11039. } // namespace entt
  11040. #endif
  11041. // #include "entity/entity.hpp"
  11042. #ifndef ENTT_ENTITY_ENTITY_HPP
  11043. #define ENTT_ENTITY_ENTITY_HPP
  11044. #include <cstddef>
  11045. #include <cstdint>
  11046. #include <type_traits>
  11047. // #include "../config/config.h"
  11048. // #include "../core/bit.hpp"
  11049. #ifndef ENTT_CORE_BIT_HPP
  11050. #define ENTT_CORE_BIT_HPP
  11051. #include <cstddef>
  11052. #include <limits>
  11053. #include <type_traits>
  11054. // #include "../config/config.h"
  11055. namespace entt {
  11056. /**
  11057. * @brief Returns the number of set bits in a value (waiting for C++20 and
  11058. * `std::popcount`).
  11059. * @tparam Type Unsigned integer type.
  11060. * @param value A value of unsigned integer type.
  11061. * @return The number of set bits in the value.
  11062. */
  11063. template<typename Type>
  11064. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  11065. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  11066. }
  11067. /**
  11068. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  11069. * `std::has_single_bit`).
  11070. * @tparam Type Unsigned integer type.
  11071. * @param value A value of unsigned integer type.
  11072. * @return True if the value is a power of two, false otherwise.
  11073. */
  11074. template<typename Type>
  11075. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  11076. return value && ((value & (value - 1)) == 0);
  11077. }
  11078. /**
  11079. * @brief Computes the smallest power of two greater than or equal to a value
  11080. * (waiting for C++20 and `std::bit_ceil`).
  11081. * @tparam Type Unsigned integer type.
  11082. * @param value A value of unsigned integer type.
  11083. * @return The smallest power of two greater than or equal to the given value.
  11084. */
  11085. template<typename Type>
  11086. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  11087. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  11088. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  11089. Type curr = value - (value != 0u);
  11090. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  11091. curr |= (curr >> next);
  11092. }
  11093. return ++curr;
  11094. }
  11095. /**
  11096. * @brief Fast module utility function (powers of two only).
  11097. * @tparam Type Unsigned integer type.
  11098. * @param value A value of unsigned integer type.
  11099. * @param mod _Modulus_, it must be a power of two.
  11100. * @return The common remainder.
  11101. */
  11102. template<typename Type>
  11103. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  11104. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  11105. return static_cast<Type>(value & (mod - 1u));
  11106. }
  11107. } // namespace entt
  11108. #endif
  11109. // #include "fwd.hpp"
  11110. namespace entt {
  11111. /*! @cond TURN_OFF_DOXYGEN */
  11112. namespace internal {
  11113. template<typename, typename = void>
  11114. struct entt_traits;
  11115. template<typename Type>
  11116. struct entt_traits<Type, std::enable_if_t<std::is_enum_v<Type>>>
  11117. : entt_traits<std::underlying_type_t<Type>> {
  11118. using value_type = Type;
  11119. };
  11120. template<typename Type>
  11121. struct entt_traits<Type, std::enable_if_t<std::is_class_v<Type>>>
  11122. : entt_traits<typename Type::entity_type> {
  11123. using value_type = Type;
  11124. };
  11125. template<>
  11126. struct entt_traits<std::uint32_t> {
  11127. using value_type = std::uint32_t;
  11128. using entity_type = std::uint32_t;
  11129. using version_type = std::uint16_t;
  11130. static constexpr entity_type entity_mask = 0xFFFFF;
  11131. static constexpr entity_type version_mask = 0xFFF;
  11132. };
  11133. template<>
  11134. struct entt_traits<std::uint64_t> {
  11135. using value_type = std::uint64_t;
  11136. using entity_type = std::uint64_t;
  11137. using version_type = std::uint32_t;
  11138. static constexpr entity_type entity_mask = 0xFFFFFFFF;
  11139. static constexpr entity_type version_mask = 0xFFFFFFFF;
  11140. };
  11141. } // namespace internal
  11142. /*! @endcond */
  11143. /**
  11144. * @brief Common basic entity traits implementation.
  11145. * @tparam Traits Actual entity traits to use.
  11146. */
  11147. template<typename Traits>
  11148. class basic_entt_traits {
  11149. static constexpr auto length = popcount(Traits::entity_mask);
  11150. static_assert(Traits::entity_mask && ((Traits::entity_mask & (Traits::entity_mask + 1)) == 0), "Invalid entity mask");
  11151. static_assert((Traits::version_mask & (Traits::version_mask + 1)) == 0, "Invalid version mask");
  11152. public:
  11153. /*! @brief Value type. */
  11154. using value_type = typename Traits::value_type;
  11155. /*! @brief Underlying entity type. */
  11156. using entity_type = typename Traits::entity_type;
  11157. /*! @brief Underlying version type. */
  11158. using version_type = typename Traits::version_type;
  11159. /*! @brief Entity mask size. */
  11160. static constexpr entity_type entity_mask = Traits::entity_mask;
  11161. /*! @brief Version mask size */
  11162. static constexpr entity_type version_mask = Traits::version_mask;
  11163. /**
  11164. * @brief Converts an entity to its underlying type.
  11165. * @param value The value to convert.
  11166. * @return The integral representation of the given value.
  11167. */
  11168. [[nodiscard]] static constexpr entity_type to_integral(const value_type value) noexcept {
  11169. return static_cast<entity_type>(value);
  11170. }
  11171. /**
  11172. * @brief Returns the entity part once converted to the underlying type.
  11173. * @param value The value to convert.
  11174. * @return The integral representation of the entity part.
  11175. */
  11176. [[nodiscard]] static constexpr entity_type to_entity(const value_type value) noexcept {
  11177. return (to_integral(value) & entity_mask);
  11178. }
  11179. /**
  11180. * @brief Returns the version part once converted to the underlying type.
  11181. * @param value The value to convert.
  11182. * @return The integral representation of the version part.
  11183. */
  11184. [[nodiscard]] static constexpr version_type to_version(const value_type value) noexcept {
  11185. if constexpr(Traits::version_mask == 0u) {
  11186. return version_type{};
  11187. } else {
  11188. return (static_cast<version_type>(to_integral(value) >> length) & version_mask);
  11189. }
  11190. }
  11191. /**
  11192. * @brief Returns the successor of a given identifier.
  11193. * @param value The identifier of which to return the successor.
  11194. * @return The successor of the given identifier.
  11195. */
  11196. [[nodiscard]] static constexpr value_type next(const value_type value) noexcept {
  11197. const auto vers = to_version(value) + 1;
  11198. return construct(to_integral(value), static_cast<version_type>(vers + (vers == version_mask)));
  11199. }
  11200. /**
  11201. * @brief Constructs an identifier from its parts.
  11202. *
  11203. * If the version part is not provided, a tombstone is returned.<br/>
  11204. * If the entity part is not provided, a null identifier is returned.
  11205. *
  11206. * @param entity The entity part of the identifier.
  11207. * @param version The version part of the identifier.
  11208. * @return A properly constructed identifier.
  11209. */
  11210. [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) noexcept {
  11211. if constexpr(Traits::version_mask == 0u) {
  11212. return value_type{entity & entity_mask};
  11213. } else {
  11214. return value_type{(entity & entity_mask) | (static_cast<entity_type>(version & version_mask) << length)};
  11215. }
  11216. }
  11217. /**
  11218. * @brief Combines two identifiers in a single one.
  11219. *
  11220. * The returned identifier is a copy of the first element except for its
  11221. * version, which is taken from the second element.
  11222. *
  11223. * @param lhs The identifier from which to take the entity part.
  11224. * @param rhs The identifier from which to take the version part.
  11225. * @return A properly constructed identifier.
  11226. */
  11227. [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) noexcept {
  11228. if constexpr(Traits::version_mask == 0u) {
  11229. return value_type{lhs & entity_mask};
  11230. } else {
  11231. return value_type{(lhs & entity_mask) | (rhs & (version_mask << length))};
  11232. }
  11233. }
  11234. };
  11235. /**
  11236. * @brief Entity traits.
  11237. * @tparam Type Type of identifier.
  11238. */
  11239. template<typename Type>
  11240. struct entt_traits: basic_entt_traits<internal::entt_traits<Type>> {
  11241. /*! @brief Base type. */
  11242. using base_type = basic_entt_traits<internal::entt_traits<Type>>;
  11243. /*! @brief Page size, default is `ENTT_SPARSE_PAGE`. */
  11244. static constexpr std::size_t page_size = ENTT_SPARSE_PAGE;
  11245. };
  11246. /**
  11247. * @brief Converts an entity to its underlying type.
  11248. * @tparam Entity The value type.
  11249. * @param value The value to convert.
  11250. * @return The integral representation of the given value.
  11251. */
  11252. template<typename Entity>
  11253. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_integral(const Entity value) noexcept {
  11254. return entt_traits<Entity>::to_integral(value);
  11255. }
  11256. /**
  11257. * @brief Returns the entity part once converted to the underlying type.
  11258. * @tparam Entity The value type.
  11259. * @param value The value to convert.
  11260. * @return The integral representation of the entity part.
  11261. */
  11262. template<typename Entity>
  11263. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_entity(const Entity value) noexcept {
  11264. return entt_traits<Entity>::to_entity(value);
  11265. }
  11266. /**
  11267. * @brief Returns the version part once converted to the underlying type.
  11268. * @tparam Entity The value type.
  11269. * @param value The value to convert.
  11270. * @return The integral representation of the version part.
  11271. */
  11272. template<typename Entity>
  11273. [[nodiscard]] constexpr typename entt_traits<Entity>::version_type to_version(const Entity value) noexcept {
  11274. return entt_traits<Entity>::to_version(value);
  11275. }
  11276. /*! @brief Null object for all identifiers. */
  11277. struct null_t {
  11278. /**
  11279. * @brief Converts the null object to identifiers of any type.
  11280. * @tparam Entity Type of identifier.
  11281. * @return The null representation for the given type.
  11282. */
  11283. template<typename Entity>
  11284. [[nodiscard]] constexpr operator Entity() const noexcept {
  11285. using traits_type = entt_traits<Entity>;
  11286. constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask);
  11287. return value;
  11288. }
  11289. /**
  11290. * @brief Compares two null objects.
  11291. * @param other A null object.
  11292. * @return True in all cases.
  11293. */
  11294. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const null_t other) const noexcept {
  11295. return true;
  11296. }
  11297. /**
  11298. * @brief Compares two null objects.
  11299. * @param other A null object.
  11300. * @return False in all cases.
  11301. */
  11302. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const null_t other) const noexcept {
  11303. return false;
  11304. }
  11305. /**
  11306. * @brief Compares a null object and an identifier of any type.
  11307. * @tparam Entity Type of identifier.
  11308. * @param entity Identifier with which to compare.
  11309. * @return False if the two elements differ, true otherwise.
  11310. */
  11311. template<typename Entity>
  11312. [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept {
  11313. using traits_type = entt_traits<Entity>;
  11314. return traits_type::to_entity(entity) == traits_type::to_entity(*this);
  11315. }
  11316. /**
  11317. * @brief Compares a null object and an identifier of any type.
  11318. * @tparam Entity Type of identifier.
  11319. * @param entity Identifier with which to compare.
  11320. * @return True if the two elements differ, false otherwise.
  11321. */
  11322. template<typename Entity>
  11323. [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept {
  11324. return !(entity == *this);
  11325. }
  11326. };
  11327. /**
  11328. * @brief Compares a null object and an identifier of any type.
  11329. * @tparam Entity Type of identifier.
  11330. * @param lhs Identifier with which to compare.
  11331. * @param rhs A null object yet to be converted.
  11332. * @return False if the two elements differ, true otherwise.
  11333. */
  11334. template<typename Entity>
  11335. [[nodiscard]] constexpr bool operator==(const Entity lhs, const null_t rhs) noexcept {
  11336. return rhs.operator==(lhs);
  11337. }
  11338. /**
  11339. * @brief Compares a null object and an identifier of any type.
  11340. * @tparam Entity Type of identifier.
  11341. * @param lhs Identifier with which to compare.
  11342. * @param rhs A null object yet to be converted.
  11343. * @return True if the two elements differ, false otherwise.
  11344. */
  11345. template<typename Entity>
  11346. [[nodiscard]] constexpr bool operator!=(const Entity lhs, const null_t rhs) noexcept {
  11347. return !(rhs == lhs);
  11348. }
  11349. /*! @brief Tombstone object for all identifiers. */
  11350. struct tombstone_t {
  11351. /**
  11352. * @brief Converts the tombstone object to identifiers of any type.
  11353. * @tparam Entity Type of identifier.
  11354. * @return The tombstone representation for the given type.
  11355. */
  11356. template<typename Entity>
  11357. [[nodiscard]] constexpr operator Entity() const noexcept {
  11358. using traits_type = entt_traits<Entity>;
  11359. constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask);
  11360. return value;
  11361. }
  11362. /**
  11363. * @brief Compares two tombstone objects.
  11364. * @param other A tombstone object.
  11365. * @return True in all cases.
  11366. */
  11367. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const tombstone_t other) const noexcept {
  11368. return true;
  11369. }
  11370. /**
  11371. * @brief Compares two tombstone objects.
  11372. * @param other A tombstone object.
  11373. * @return False in all cases.
  11374. */
  11375. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const tombstone_t other) const noexcept {
  11376. return false;
  11377. }
  11378. /**
  11379. * @brief Compares a tombstone object and an identifier of any type.
  11380. * @tparam Entity Type of identifier.
  11381. * @param entity Identifier with which to compare.
  11382. * @return False if the two elements differ, true otherwise.
  11383. */
  11384. template<typename Entity>
  11385. [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept {
  11386. using traits_type = entt_traits<Entity>;
  11387. if constexpr(traits_type::version_mask == 0u) {
  11388. return false;
  11389. } else {
  11390. return (traits_type::to_version(entity) == traits_type::to_version(*this));
  11391. }
  11392. }
  11393. /**
  11394. * @brief Compares a tombstone object and an identifier of any type.
  11395. * @tparam Entity Type of identifier.
  11396. * @param entity Identifier with which to compare.
  11397. * @return True if the two elements differ, false otherwise.
  11398. */
  11399. template<typename Entity>
  11400. [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept {
  11401. return !(entity == *this);
  11402. }
  11403. };
  11404. /**
  11405. * @brief Compares a tombstone object and an identifier of any type.
  11406. * @tparam Entity Type of identifier.
  11407. * @param lhs Identifier with which to compare.
  11408. * @param rhs A tombstone object yet to be converted.
  11409. * @return False if the two elements differ, true otherwise.
  11410. */
  11411. template<typename Entity>
  11412. [[nodiscard]] constexpr bool operator==(const Entity lhs, const tombstone_t rhs) noexcept {
  11413. return rhs.operator==(lhs);
  11414. }
  11415. /**
  11416. * @brief Compares a tombstone object and an identifier of any type.
  11417. * @tparam Entity Type of identifier.
  11418. * @param lhs Identifier with which to compare.
  11419. * @param rhs A tombstone object yet to be converted.
  11420. * @return True if the two elements differ, false otherwise.
  11421. */
  11422. template<typename Entity>
  11423. [[nodiscard]] constexpr bool operator!=(const Entity lhs, const tombstone_t rhs) noexcept {
  11424. return !(rhs == lhs);
  11425. }
  11426. /**
  11427. * @brief Compile-time constant for null entities.
  11428. *
  11429. * There exist implicit conversions from this variable to identifiers of any
  11430. * allowed type. Similarly, there exist comparison operators between the null
  11431. * entity and any other identifier.
  11432. */
  11433. inline constexpr null_t null{};
  11434. /**
  11435. * @brief Compile-time constant for tombstone entities.
  11436. *
  11437. * There exist implicit conversions from this variable to identifiers of any
  11438. * allowed type. Similarly, there exist comparison operators between the
  11439. * tombstone entity and any other identifier.
  11440. */
  11441. inline constexpr tombstone_t tombstone{};
  11442. } // namespace entt
  11443. #endif
  11444. // #include "entity/group.hpp"
  11445. #ifndef ENTT_ENTITY_GROUP_HPP
  11446. #define ENTT_ENTITY_GROUP_HPP
  11447. #include <array>
  11448. #include <cstddef>
  11449. #include <iterator>
  11450. #include <tuple>
  11451. #include <type_traits>
  11452. #include <utility>
  11453. // #include "../config/config.h"
  11454. // #include "../core/algorithm.hpp"
  11455. #ifndef ENTT_CORE_ALGORITHM_HPP
  11456. #define ENTT_CORE_ALGORITHM_HPP
  11457. #include <algorithm>
  11458. #include <functional>
  11459. #include <iterator>
  11460. #include <utility>
  11461. #include <vector>
  11462. // #include "utility.hpp"
  11463. #ifndef ENTT_CORE_UTILITY_HPP
  11464. #define ENTT_CORE_UTILITY_HPP
  11465. #include <type_traits>
  11466. #include <utility>
  11467. namespace entt {
  11468. /*! @brief Identity function object (waiting for C++20). */
  11469. struct identity {
  11470. /*! @brief Indicates that this is a transparent function object. */
  11471. using is_transparent = void;
  11472. /**
  11473. * @brief Returns its argument unchanged.
  11474. * @tparam Type Type of the argument.
  11475. * @param value The actual argument.
  11476. * @return The submitted value as-is.
  11477. */
  11478. template<typename Type>
  11479. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  11480. return std::forward<Type>(value);
  11481. }
  11482. };
  11483. /**
  11484. * @brief Constant utility to disambiguate overloaded members of a class.
  11485. * @tparam Type Type of the desired overload.
  11486. * @tparam Class Type of class to which the member belongs.
  11487. * @param member A valid pointer to a member.
  11488. * @return Pointer to the member.
  11489. */
  11490. template<typename Type, typename Class>
  11491. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  11492. return member;
  11493. }
  11494. /**
  11495. * @brief Constant utility to disambiguate overloaded functions.
  11496. * @tparam Func Function type of the desired overload.
  11497. * @param func A valid pointer to a function.
  11498. * @return Pointer to the function.
  11499. */
  11500. template<typename Func>
  11501. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  11502. return func;
  11503. }
  11504. /**
  11505. * @brief Helper type for visitors.
  11506. * @tparam Func Types of function objects.
  11507. */
  11508. template<typename... Func>
  11509. struct overloaded: Func... {
  11510. using Func::operator()...;
  11511. };
  11512. /**
  11513. * @brief Deduction guide.
  11514. * @tparam Func Types of function objects.
  11515. */
  11516. template<typename... Func>
  11517. overloaded(Func...) -> overloaded<Func...>;
  11518. /**
  11519. * @brief Basic implementation of a y-combinator.
  11520. * @tparam Func Type of a potentially recursive function.
  11521. */
  11522. template<typename Func>
  11523. struct y_combinator {
  11524. /**
  11525. * @brief Constructs a y-combinator from a given function.
  11526. * @param recursive A potentially recursive function.
  11527. */
  11528. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  11529. : func{std::move(recursive)} {}
  11530. /**
  11531. * @brief Invokes a y-combinator and therefore its underlying function.
  11532. * @tparam Args Types of arguments to use to invoke the underlying function.
  11533. * @param args Parameters to use to invoke the underlying function.
  11534. * @return Return value of the underlying function, if any.
  11535. */
  11536. template<typename... Args>
  11537. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  11538. return func(*this, std::forward<Args>(args)...);
  11539. }
  11540. /*! @copydoc operator()() */
  11541. template<typename... Args>
  11542. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  11543. return func(*this, std::forward<Args>(args)...);
  11544. }
  11545. private:
  11546. Func func;
  11547. };
  11548. } // namespace entt
  11549. #endif
  11550. namespace entt {
  11551. /**
  11552. * @brief Function object to wrap `std::sort` in a class type.
  11553. *
  11554. * Unfortunately, `std::sort` cannot be passed as template argument to a class
  11555. * template or a function template.<br/>
  11556. * This class fills the gap by wrapping some flavors of `std::sort` in a
  11557. * function object.
  11558. */
  11559. struct std_sort {
  11560. /**
  11561. * @brief Sorts the elements in a range.
  11562. *
  11563. * Sorts the elements in a range using the given binary comparison function.
  11564. *
  11565. * @tparam It Type of random access iterator.
  11566. * @tparam Compare Type of comparison function object.
  11567. * @tparam Args Types of arguments to forward to the sort function.
  11568. * @param first An iterator to the first element of the range to sort.
  11569. * @param last An iterator past the last element of the range to sort.
  11570. * @param compare A valid comparison function object.
  11571. * @param args Arguments to forward to the sort function, if any.
  11572. */
  11573. template<typename It, typename Compare = std::less<>, typename... Args>
  11574. void operator()(It first, It last, Compare compare = Compare{}, Args &&...args) const {
  11575. std::sort(std::forward<Args>(args)..., std::move(first), std::move(last), std::move(compare));
  11576. }
  11577. };
  11578. /*! @brief Function object for performing insertion sort. */
  11579. struct insertion_sort {
  11580. /**
  11581. * @brief Sorts the elements in a range.
  11582. *
  11583. * Sorts the elements in a range using the given binary comparison function.
  11584. *
  11585. * @tparam It Type of random access iterator.
  11586. * @tparam Compare Type of comparison function object.
  11587. * @param first An iterator to the first element of the range to sort.
  11588. * @param last An iterator past the last element of the range to sort.
  11589. * @param compare A valid comparison function object.
  11590. */
  11591. template<typename It, typename Compare = std::less<>>
  11592. void operator()(It first, It last, Compare compare = Compare{}) const {
  11593. if(first < last) {
  11594. for(auto it = first + 1; it < last; ++it) {
  11595. auto value = std::move(*it);
  11596. auto pre = it;
  11597. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  11598. for(; pre > first && compare(value, *(pre - 1)); --pre) {
  11599. *pre = std::move(*(pre - 1));
  11600. }
  11601. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  11602. *pre = std::move(value);
  11603. }
  11604. }
  11605. }
  11606. };
  11607. /**
  11608. * @brief Function object for performing LSD radix sort.
  11609. * @tparam Bit Number of bits processed per pass.
  11610. * @tparam N Maximum number of bits to sort.
  11611. */
  11612. template<std::size_t Bit, std::size_t N>
  11613. struct radix_sort {
  11614. static_assert((N % Bit) == 0, "The maximum number of bits to sort must be a multiple of the number of bits processed per pass");
  11615. /**
  11616. * @brief Sorts the elements in a range.
  11617. *
  11618. * Sorts the elements in a range using the given _getter_ to access the
  11619. * actual data to be sorted.
  11620. *
  11621. * This implementation is inspired by the online book
  11622. * [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies.html#RadixSort).
  11623. *
  11624. * @tparam It Type of random access iterator.
  11625. * @tparam Getter Type of _getter_ function object.
  11626. * @param first An iterator to the first element of the range to sort.
  11627. * @param last An iterator past the last element of the range to sort.
  11628. * @param getter A valid _getter_ function object.
  11629. */
  11630. template<typename It, typename Getter = identity>
  11631. void operator()(It first, It last, Getter getter = Getter{}) const {
  11632. if(first < last) {
  11633. constexpr auto passes = N / Bit;
  11634. using value_type = typename std::iterator_traits<It>::value_type;
  11635. using difference_type = typename std::iterator_traits<It>::difference_type;
  11636. std::vector<value_type> aux(static_cast<std::size_t>(std::distance(first, last)));
  11637. auto part = [getter = std::move(getter)](auto from, auto to, auto out, auto start) {
  11638. constexpr auto mask = (1 << Bit) - 1;
  11639. constexpr auto buckets = 1 << Bit;
  11640. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays, misc-const-correctness)
  11641. std::size_t count[buckets]{};
  11642. for(auto it = from; it != to; ++it) {
  11643. ++count[(getter(*it) >> start) & mask];
  11644. }
  11645. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  11646. std::size_t index[buckets]{};
  11647. for(std::size_t pos{}, end = buckets - 1u; pos < end; ++pos) {
  11648. index[pos + 1u] = index[pos] + count[pos];
  11649. }
  11650. for(auto it = from; it != to; ++it) {
  11651. const auto pos = index[(getter(*it) >> start) & mask]++;
  11652. out[static_cast<difference_type>(pos)] = std::move(*it);
  11653. }
  11654. };
  11655. for(std::size_t pass = 0; pass < (passes & ~1u); pass += 2) {
  11656. part(first, last, aux.begin(), pass * Bit);
  11657. part(aux.begin(), aux.end(), first, (pass + 1) * Bit);
  11658. }
  11659. if constexpr(passes & 1) {
  11660. part(first, last, aux.begin(), (passes - 1) * Bit);
  11661. std::move(aux.begin(), aux.end(), first);
  11662. }
  11663. }
  11664. }
  11665. };
  11666. } // namespace entt
  11667. #endif
  11668. // #include "../core/fwd.hpp"
  11669. // #include "../core/iterator.hpp"
  11670. #ifndef ENTT_CORE_ITERATOR_HPP
  11671. #define ENTT_CORE_ITERATOR_HPP
  11672. #include <iterator>
  11673. #include <memory>
  11674. #include <type_traits>
  11675. #include <utility>
  11676. namespace entt {
  11677. /**
  11678. * @brief Helper type to use as pointer with input iterators.
  11679. * @tparam Type of wrapped value.
  11680. */
  11681. template<typename Type>
  11682. struct input_iterator_pointer final {
  11683. /*! @brief Value type. */
  11684. using value_type = Type;
  11685. /*! @brief Pointer type. */
  11686. using pointer = Type *;
  11687. /*! @brief Reference type. */
  11688. using reference = Type &;
  11689. /**
  11690. * @brief Constructs a proxy object by move.
  11691. * @param val Value to use to initialize the proxy object.
  11692. */
  11693. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  11694. : value{std::move(val)} {}
  11695. /**
  11696. * @brief Access operator for accessing wrapped values.
  11697. * @return A pointer to the wrapped value.
  11698. */
  11699. [[nodiscard]] constexpr pointer operator->() noexcept {
  11700. return std::addressof(value);
  11701. }
  11702. /**
  11703. * @brief Dereference operator for accessing wrapped values.
  11704. * @return A reference to the wrapped value.
  11705. */
  11706. [[nodiscard]] constexpr reference operator*() noexcept {
  11707. return value;
  11708. }
  11709. private:
  11710. Type value;
  11711. };
  11712. /**
  11713. * @brief Plain iota iterator (waiting for C++20).
  11714. * @tparam Type Value type.
  11715. */
  11716. template<typename Type>
  11717. class iota_iterator final {
  11718. static_assert(std::is_integral_v<Type>, "Not an integral type");
  11719. public:
  11720. /*! @brief Value type, likely an integral one. */
  11721. using value_type = Type;
  11722. /*! @brief Invalid pointer type. */
  11723. using pointer = void;
  11724. /*! @brief Non-reference type, same as value type. */
  11725. using reference = value_type;
  11726. /*! @brief Difference type. */
  11727. using difference_type = std::ptrdiff_t;
  11728. /*! @brief Iterator category. */
  11729. using iterator_category = std::input_iterator_tag;
  11730. /*! @brief Default constructor. */
  11731. constexpr iota_iterator() noexcept
  11732. : current{} {}
  11733. /**
  11734. * @brief Constructs an iota iterator from a given value.
  11735. * @param init The initial value assigned to the iota iterator.
  11736. */
  11737. constexpr iota_iterator(const value_type init) noexcept
  11738. : current{init} {}
  11739. /**
  11740. * @brief Pre-increment operator.
  11741. * @return This iota iterator.
  11742. */
  11743. constexpr iota_iterator &operator++() noexcept {
  11744. return ++current, *this;
  11745. }
  11746. /**
  11747. * @brief Post-increment operator.
  11748. * @return This iota iterator.
  11749. */
  11750. constexpr iota_iterator operator++(int) noexcept {
  11751. const iota_iterator orig = *this;
  11752. return ++(*this), orig;
  11753. }
  11754. /**
  11755. * @brief Dereference operator.
  11756. * @return The underlying value.
  11757. */
  11758. [[nodiscard]] constexpr reference operator*() const noexcept {
  11759. return current;
  11760. }
  11761. private:
  11762. value_type current;
  11763. };
  11764. /**
  11765. * @brief Comparison operator.
  11766. * @tparam Type Value type of the iota iterator.
  11767. * @param lhs A properly initialized iota iterator.
  11768. * @param rhs A properly initialized iota iterator.
  11769. * @return True if the two iterators are identical, false otherwise.
  11770. */
  11771. template<typename Type>
  11772. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  11773. return *lhs == *rhs;
  11774. }
  11775. /**
  11776. * @brief Comparison operator.
  11777. * @tparam Type Value type of the iota iterator.
  11778. * @param lhs A properly initialized iota iterator.
  11779. * @param rhs A properly initialized iota iterator.
  11780. * @return True if the two iterators differ, false otherwise.
  11781. */
  11782. template<typename Type>
  11783. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  11784. return !(lhs == rhs);
  11785. }
  11786. /**
  11787. * @brief Utility class to create an iterable object from a pair of iterators.
  11788. * @tparam It Type of iterator.
  11789. * @tparam Sentinel Type of sentinel.
  11790. */
  11791. template<typename It, typename Sentinel = It>
  11792. struct iterable_adaptor final {
  11793. /*! @brief Value type. */
  11794. using value_type = typename std::iterator_traits<It>::value_type;
  11795. /*! @brief Iterator type. */
  11796. using iterator = It;
  11797. /*! @brief Sentinel type. */
  11798. using sentinel = Sentinel;
  11799. /*! @brief Default constructor. */
  11800. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  11801. : first{},
  11802. last{} {}
  11803. /**
  11804. * @brief Creates an iterable object from a pair of iterators.
  11805. * @param from Begin iterator.
  11806. * @param to End iterator.
  11807. */
  11808. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  11809. : first{std::move(from)},
  11810. last{std::move(to)} {}
  11811. /**
  11812. * @brief Returns an iterator to the beginning.
  11813. * @return An iterator to the first element of the range.
  11814. */
  11815. [[nodiscard]] constexpr iterator begin() const noexcept {
  11816. return first;
  11817. }
  11818. /**
  11819. * @brief Returns an iterator to the end.
  11820. * @return An iterator to the element following the last element of the
  11821. * range.
  11822. */
  11823. [[nodiscard]] constexpr sentinel end() const noexcept {
  11824. return last;
  11825. }
  11826. /*! @copydoc begin */
  11827. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  11828. return begin();
  11829. }
  11830. /*! @copydoc end */
  11831. [[nodiscard]] constexpr sentinel cend() const noexcept {
  11832. return end();
  11833. }
  11834. private:
  11835. It first;
  11836. Sentinel last;
  11837. };
  11838. } // namespace entt
  11839. #endif
  11840. // #include "../core/type_info.hpp"
  11841. #ifndef ENTT_CORE_TYPE_INFO_HPP
  11842. #define ENTT_CORE_TYPE_INFO_HPP
  11843. #include <string_view>
  11844. #include <type_traits>
  11845. #include <utility>
  11846. // #include "../config/config.h"
  11847. // #include "fwd.hpp"
  11848. // #include "hashed_string.hpp"
  11849. #ifndef ENTT_CORE_HASHED_STRING_HPP
  11850. #define ENTT_CORE_HASHED_STRING_HPP
  11851. #include <cstddef>
  11852. #include <cstdint>
  11853. // #include "fwd.hpp"
  11854. namespace entt {
  11855. /*! @cond TURN_OFF_DOXYGEN */
  11856. namespace internal {
  11857. template<typename = id_type>
  11858. struct fnv_1a_params;
  11859. template<>
  11860. struct fnv_1a_params<std::uint32_t> {
  11861. static constexpr auto offset = 2166136261;
  11862. static constexpr auto prime = 16777619;
  11863. };
  11864. template<>
  11865. struct fnv_1a_params<std::uint64_t> {
  11866. static constexpr auto offset = 14695981039346656037ull;
  11867. static constexpr auto prime = 1099511628211ull;
  11868. };
  11869. template<typename Char>
  11870. struct basic_hashed_string {
  11871. using value_type = Char;
  11872. using size_type = std::size_t;
  11873. using hash_type = id_type;
  11874. const value_type *repr{};
  11875. hash_type hash{fnv_1a_params<>::offset};
  11876. size_type length{};
  11877. };
  11878. } // namespace internal
  11879. /*! @endcond */
  11880. /**
  11881. * @brief Zero overhead unique identifier.
  11882. *
  11883. * A hashed string is a compile-time tool that allows users to use
  11884. * human-readable identifiers in the codebase while using their numeric
  11885. * counterparts at runtime.<br/>
  11886. * Because of that, a hashed string can also be used in constant expressions if
  11887. * required.
  11888. *
  11889. * @warning
  11890. * This class doesn't take ownership of user-supplied strings nor does it make a
  11891. * copy of them.
  11892. *
  11893. * @tparam Char Character type.
  11894. */
  11895. template<typename Char>
  11896. class basic_hashed_string: internal::basic_hashed_string<Char> {
  11897. using base_type = internal::basic_hashed_string<Char>;
  11898. using params = internal::fnv_1a_params<>;
  11899. struct const_wrapper {
  11900. // non-explicit constructor on purpose
  11901. constexpr const_wrapper(const typename base_type::value_type *str) noexcept
  11902. : repr{str} {}
  11903. const typename base_type::value_type *repr;
  11904. };
  11905. public:
  11906. /*! @brief Character type. */
  11907. using value_type = typename base_type::value_type;
  11908. /*! @brief Unsigned integer type. */
  11909. using size_type = typename base_type::size_type;
  11910. /*! @brief Unsigned integer type. */
  11911. using hash_type = typename base_type::hash_type;
  11912. /**
  11913. * @brief Returns directly the numeric representation of a string view.
  11914. * @param str Human-readable identifier.
  11915. * @param len Length of the string to hash.
  11916. * @return The numeric representation of the string.
  11917. */
  11918. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
  11919. return basic_hashed_string{str, len};
  11920. }
  11921. /**
  11922. * @brief Returns directly the numeric representation of a string.
  11923. * @tparam N Number of characters of the identifier.
  11924. * @param str Human-readable identifier.
  11925. * @return The numeric representation of the string.
  11926. */
  11927. template<std::size_t N>
  11928. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  11929. [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept {
  11930. return basic_hashed_string{str};
  11931. }
  11932. /**
  11933. * @brief Returns directly the numeric representation of a string.
  11934. * @param wrapper Helps achieving the purpose by relying on overloading.
  11935. * @return The numeric representation of the string.
  11936. */
  11937. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
  11938. return basic_hashed_string{wrapper};
  11939. }
  11940. /*! @brief Constructs an empty hashed string. */
  11941. constexpr basic_hashed_string() noexcept
  11942. : basic_hashed_string{nullptr, 0u} {}
  11943. /**
  11944. * @brief Constructs a hashed string from a string view.
  11945. * @param str Human-readable identifier.
  11946. * @param len Length of the string to hash.
  11947. */
  11948. constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
  11949. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  11950. : base_type{str} {
  11951. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  11952. for(; base_type::length < len; ++base_type::length) {
  11953. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  11954. }
  11955. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  11956. }
  11957. /**
  11958. * @brief Constructs a hashed string from an array of const characters.
  11959. * @tparam N Number of characters of the identifier.
  11960. * @param str Human-readable identifier.
  11961. */
  11962. template<std::size_t N>
  11963. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  11964. ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept
  11965. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  11966. : base_type{str} {
  11967. for(; str[base_type::length]; ++base_type::length) {
  11968. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  11969. }
  11970. }
  11971. /**
  11972. * @brief Explicit constructor on purpose to avoid constructing a hashed
  11973. * string directly from a `const value_type *`.
  11974. *
  11975. * @warning
  11976. * The lifetime of the string is not extended nor is it copied.
  11977. *
  11978. * @param wrapper Helps achieving the purpose by relying on overloading.
  11979. */
  11980. explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
  11981. : base_type{wrapper.repr} {
  11982. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  11983. for(; wrapper.repr[base_type::length]; ++base_type::length) {
  11984. base_type::hash = (base_type::hash ^ static_cast<id_type>(wrapper.repr[base_type::length])) * params::prime;
  11985. }
  11986. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  11987. }
  11988. /**
  11989. * @brief Returns the size of a hashed string.
  11990. * @return The size of the hashed string.
  11991. */
  11992. [[nodiscard]] constexpr size_type size() const noexcept {
  11993. return base_type::length;
  11994. }
  11995. /**
  11996. * @brief Returns the human-readable representation of a hashed string.
  11997. * @return The string used to initialize the hashed string.
  11998. */
  11999. [[nodiscard]] constexpr const value_type *data() const noexcept {
  12000. return base_type::repr;
  12001. }
  12002. /**
  12003. * @brief Returns the numeric representation of a hashed string.
  12004. * @return The numeric representation of the hashed string.
  12005. */
  12006. [[nodiscard]] constexpr hash_type value() const noexcept {
  12007. return base_type::hash;
  12008. }
  12009. /*! @copydoc data */
  12010. [[nodiscard]] explicit constexpr operator const value_type *() const noexcept {
  12011. return data();
  12012. }
  12013. /**
  12014. * @brief Returns the numeric representation of a hashed string.
  12015. * @return The numeric representation of the hashed string.
  12016. */
  12017. [[nodiscard]] constexpr operator hash_type() const noexcept {
  12018. return value();
  12019. }
  12020. };
  12021. /**
  12022. * @brief Deduction guide.
  12023. * @tparam Char Character type.
  12024. * @param str Human-readable identifier.
  12025. * @param len Length of the string to hash.
  12026. */
  12027. template<typename Char>
  12028. basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string<Char>;
  12029. /**
  12030. * @brief Deduction guide.
  12031. * @tparam Char Character type.
  12032. * @tparam N Number of characters of the identifier.
  12033. * @param str Human-readable identifier.
  12034. */
  12035. template<typename Char, std::size_t N>
  12036. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  12037. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  12038. /**
  12039. * @brief Compares two hashed strings.
  12040. * @tparam Char Character type.
  12041. * @param lhs A valid hashed string.
  12042. * @param rhs A valid hashed string.
  12043. * @return True if the two hashed strings are identical, false otherwise.
  12044. */
  12045. template<typename Char>
  12046. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  12047. return lhs.value() == rhs.value();
  12048. }
  12049. /**
  12050. * @brief Compares two hashed strings.
  12051. * @tparam Char Character type.
  12052. * @param lhs A valid hashed string.
  12053. * @param rhs A valid hashed string.
  12054. * @return True if the two hashed strings differ, false otherwise.
  12055. */
  12056. template<typename Char>
  12057. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  12058. return !(lhs == rhs);
  12059. }
  12060. /**
  12061. * @brief Compares two hashed strings.
  12062. * @tparam Char Character type.
  12063. * @param lhs A valid hashed string.
  12064. * @param rhs A valid hashed string.
  12065. * @return True if the first element is less than the second, false otherwise.
  12066. */
  12067. template<typename Char>
  12068. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  12069. return lhs.value() < rhs.value();
  12070. }
  12071. /**
  12072. * @brief Compares two hashed strings.
  12073. * @tparam Char Character type.
  12074. * @param lhs A valid hashed string.
  12075. * @param rhs A valid hashed string.
  12076. * @return True if the first element is less than or equal to the second, false
  12077. * otherwise.
  12078. */
  12079. template<typename Char>
  12080. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  12081. return !(rhs < lhs);
  12082. }
  12083. /**
  12084. * @brief Compares two hashed strings.
  12085. * @tparam Char Character type.
  12086. * @param lhs A valid hashed string.
  12087. * @param rhs A valid hashed string.
  12088. * @return True if the first element is greater than the second, false
  12089. * otherwise.
  12090. */
  12091. template<typename Char>
  12092. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  12093. return rhs < lhs;
  12094. }
  12095. /**
  12096. * @brief Compares two hashed strings.
  12097. * @tparam Char Character type.
  12098. * @param lhs A valid hashed string.
  12099. * @param rhs A valid hashed string.
  12100. * @return True if the first element is greater than or equal to the second,
  12101. * false otherwise.
  12102. */
  12103. template<typename Char>
  12104. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  12105. return !(lhs < rhs);
  12106. }
  12107. inline namespace literals {
  12108. /**
  12109. * @brief User defined literal for hashed strings.
  12110. * @param str The literal without its suffix.
  12111. * @return A properly initialized hashed string.
  12112. */
  12113. [[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept {
  12114. return hashed_string{str};
  12115. }
  12116. /**
  12117. * @brief User defined literal for hashed wstrings.
  12118. * @param str The literal without its suffix.
  12119. * @return A properly initialized hashed wstring.
  12120. */
  12121. [[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept {
  12122. return hashed_wstring{str};
  12123. }
  12124. } // namespace literals
  12125. } // namespace entt
  12126. #endif
  12127. namespace entt {
  12128. /*! @cond TURN_OFF_DOXYGEN */
  12129. namespace internal {
  12130. struct ENTT_API type_index final {
  12131. [[nodiscard]] static id_type next() noexcept {
  12132. static ENTT_MAYBE_ATOMIC(id_type) value{};
  12133. return value++;
  12134. }
  12135. };
  12136. template<typename Type>
  12137. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  12138. #if defined ENTT_PRETTY_FUNCTION
  12139. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  12140. #else
  12141. return "";
  12142. #endif
  12143. }
  12144. template<typename Type>
  12145. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  12146. #if defined ENTT_PRETTY_FUNCTION
  12147. const std::string_view full_name{pretty_function<Type>()};
  12148. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  12149. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  12150. return value;
  12151. #else
  12152. return std::string_view{};
  12153. #endif
  12154. }
  12155. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  12156. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  12157. constexpr auto value = stripped_type_name<Type>();
  12158. return value;
  12159. }
  12160. template<typename Type>
  12161. [[nodiscard]] std::string_view type_name(char) noexcept {
  12162. static const auto value = stripped_type_name<Type>();
  12163. return value;
  12164. }
  12165. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  12166. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  12167. constexpr auto stripped = stripped_type_name<Type>();
  12168. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  12169. return value;
  12170. }
  12171. template<typename Type>
  12172. [[nodiscard]] id_type type_hash(char) noexcept {
  12173. static const auto value = [](const auto stripped) {
  12174. return hashed_string::value(stripped.data(), stripped.size());
  12175. }(stripped_type_name<Type>());
  12176. return value;
  12177. }
  12178. } // namespace internal
  12179. /*! @endcond */
  12180. /**
  12181. * @brief Type sequential identifier.
  12182. * @tparam Type Type for which to generate a sequential identifier.
  12183. */
  12184. template<typename Type, typename = void>
  12185. struct ENTT_API type_index final {
  12186. /**
  12187. * @brief Returns the sequential identifier of a given type.
  12188. * @return The sequential identifier of a given type.
  12189. */
  12190. [[nodiscard]] static id_type value() noexcept {
  12191. static const id_type value = internal::type_index::next();
  12192. return value;
  12193. }
  12194. /*! @copydoc value */
  12195. [[nodiscard]] constexpr operator id_type() const noexcept {
  12196. return value();
  12197. }
  12198. };
  12199. /**
  12200. * @brief Type hash.
  12201. * @tparam Type Type for which to generate a hash value.
  12202. */
  12203. template<typename Type, typename = void>
  12204. struct type_hash final {
  12205. /**
  12206. * @brief Returns the numeric representation of a given type.
  12207. * @return The numeric representation of the given type.
  12208. */
  12209. #if defined ENTT_PRETTY_FUNCTION
  12210. [[nodiscard]] static constexpr id_type value() noexcept {
  12211. return internal::type_hash<Type>(0);
  12212. #else
  12213. [[nodiscard]] static constexpr id_type value() noexcept {
  12214. return type_index<Type>::value();
  12215. #endif
  12216. }
  12217. /*! @copydoc value */
  12218. [[nodiscard]] constexpr operator id_type() const noexcept {
  12219. return value();
  12220. }
  12221. };
  12222. /**
  12223. * @brief Type name.
  12224. * @tparam Type Type for which to generate a name.
  12225. */
  12226. template<typename Type, typename = void>
  12227. struct type_name final {
  12228. /**
  12229. * @brief Returns the name of a given type.
  12230. * @return The name of the given type.
  12231. */
  12232. [[nodiscard]] static constexpr std::string_view value() noexcept {
  12233. return internal::type_name<Type>(0);
  12234. }
  12235. /*! @copydoc value */
  12236. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  12237. return value();
  12238. }
  12239. };
  12240. /*! @brief Implementation specific information about a type. */
  12241. struct type_info final {
  12242. /**
  12243. * @brief Constructs a type info object for a given type.
  12244. * @tparam Type Type for which to construct a type info object.
  12245. */
  12246. template<typename Type>
  12247. // NOLINTBEGIN(modernize-use-transparent-functors)
  12248. constexpr type_info(std::in_place_type_t<Type>) noexcept
  12249. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  12250. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  12251. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  12252. // NOLINTEND(modernize-use-transparent-functors)
  12253. /**
  12254. * @brief Type index.
  12255. * @return Type index.
  12256. */
  12257. [[nodiscard]] constexpr id_type index() const noexcept {
  12258. return seq;
  12259. }
  12260. /**
  12261. * @brief Type hash.
  12262. * @return Type hash.
  12263. */
  12264. [[nodiscard]] constexpr id_type hash() const noexcept {
  12265. return identifier;
  12266. }
  12267. /**
  12268. * @brief Type name.
  12269. * @return Type name.
  12270. */
  12271. [[nodiscard]] constexpr std::string_view name() const noexcept {
  12272. return alias;
  12273. }
  12274. private:
  12275. id_type seq;
  12276. id_type identifier;
  12277. std::string_view alias;
  12278. };
  12279. /**
  12280. * @brief Compares the contents of two type info objects.
  12281. * @param lhs A type info object.
  12282. * @param rhs A type info object.
  12283. * @return True if the two type info objects are identical, false otherwise.
  12284. */
  12285. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  12286. return lhs.hash() == rhs.hash();
  12287. }
  12288. /**
  12289. * @brief Compares the contents of two type info objects.
  12290. * @param lhs A type info object.
  12291. * @param rhs A type info object.
  12292. * @return True if the two type info objects differ, false otherwise.
  12293. */
  12294. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  12295. return !(lhs == rhs);
  12296. }
  12297. /**
  12298. * @brief Compares two type info objects.
  12299. * @param lhs A valid type info object.
  12300. * @param rhs A valid type info object.
  12301. * @return True if the first element is less than the second, false otherwise.
  12302. */
  12303. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  12304. return lhs.index() < rhs.index();
  12305. }
  12306. /**
  12307. * @brief Compares two type info objects.
  12308. * @param lhs A valid type info object.
  12309. * @param rhs A valid type info object.
  12310. * @return True if the first element is less than or equal to the second, false
  12311. * otherwise.
  12312. */
  12313. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  12314. return !(rhs < lhs);
  12315. }
  12316. /**
  12317. * @brief Compares two type info objects.
  12318. * @param lhs A valid type info object.
  12319. * @param rhs A valid type info object.
  12320. * @return True if the first element is greater than the second, false
  12321. * otherwise.
  12322. */
  12323. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  12324. return rhs < lhs;
  12325. }
  12326. /**
  12327. * @brief Compares two type info objects.
  12328. * @param lhs A valid type info object.
  12329. * @param rhs A valid type info object.
  12330. * @return True if the first element is greater than or equal to the second,
  12331. * false otherwise.
  12332. */
  12333. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  12334. return !(lhs < rhs);
  12335. }
  12336. /**
  12337. * @brief Returns the type info object associated to a given type.
  12338. *
  12339. * The returned element refers to an object with static storage duration.<br/>
  12340. * The type doesn't need to be a complete type. If the type is a reference, the
  12341. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  12342. * are ignored.
  12343. *
  12344. * @tparam Type Type for which to generate a type info object.
  12345. * @return A reference to a properly initialized type info object.
  12346. */
  12347. template<typename Type>
  12348. [[nodiscard]] const type_info &type_id() noexcept {
  12349. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  12350. static const type_info instance{std::in_place_type<Type>};
  12351. return instance;
  12352. } else {
  12353. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  12354. }
  12355. }
  12356. /*! @copydoc type_id */
  12357. template<typename Type>
  12358. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  12359. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  12360. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  12361. }
  12362. } // namespace entt
  12363. #endif
  12364. // #include "../core/type_traits.hpp"
  12365. // #include "entity.hpp"
  12366. #ifndef ENTT_ENTITY_ENTITY_HPP
  12367. #define ENTT_ENTITY_ENTITY_HPP
  12368. #include <cstddef>
  12369. #include <cstdint>
  12370. #include <type_traits>
  12371. // #include "../config/config.h"
  12372. // #include "../core/bit.hpp"
  12373. // #include "fwd.hpp"
  12374. namespace entt {
  12375. /*! @cond TURN_OFF_DOXYGEN */
  12376. namespace internal {
  12377. template<typename, typename = void>
  12378. struct entt_traits;
  12379. template<typename Type>
  12380. struct entt_traits<Type, std::enable_if_t<std::is_enum_v<Type>>>
  12381. : entt_traits<std::underlying_type_t<Type>> {
  12382. using value_type = Type;
  12383. };
  12384. template<typename Type>
  12385. struct entt_traits<Type, std::enable_if_t<std::is_class_v<Type>>>
  12386. : entt_traits<typename Type::entity_type> {
  12387. using value_type = Type;
  12388. };
  12389. template<>
  12390. struct entt_traits<std::uint32_t> {
  12391. using value_type = std::uint32_t;
  12392. using entity_type = std::uint32_t;
  12393. using version_type = std::uint16_t;
  12394. static constexpr entity_type entity_mask = 0xFFFFF;
  12395. static constexpr entity_type version_mask = 0xFFF;
  12396. };
  12397. template<>
  12398. struct entt_traits<std::uint64_t> {
  12399. using value_type = std::uint64_t;
  12400. using entity_type = std::uint64_t;
  12401. using version_type = std::uint32_t;
  12402. static constexpr entity_type entity_mask = 0xFFFFFFFF;
  12403. static constexpr entity_type version_mask = 0xFFFFFFFF;
  12404. };
  12405. } // namespace internal
  12406. /*! @endcond */
  12407. /**
  12408. * @brief Common basic entity traits implementation.
  12409. * @tparam Traits Actual entity traits to use.
  12410. */
  12411. template<typename Traits>
  12412. class basic_entt_traits {
  12413. static constexpr auto length = popcount(Traits::entity_mask);
  12414. static_assert(Traits::entity_mask && ((Traits::entity_mask & (Traits::entity_mask + 1)) == 0), "Invalid entity mask");
  12415. static_assert((Traits::version_mask & (Traits::version_mask + 1)) == 0, "Invalid version mask");
  12416. public:
  12417. /*! @brief Value type. */
  12418. using value_type = typename Traits::value_type;
  12419. /*! @brief Underlying entity type. */
  12420. using entity_type = typename Traits::entity_type;
  12421. /*! @brief Underlying version type. */
  12422. using version_type = typename Traits::version_type;
  12423. /*! @brief Entity mask size. */
  12424. static constexpr entity_type entity_mask = Traits::entity_mask;
  12425. /*! @brief Version mask size */
  12426. static constexpr entity_type version_mask = Traits::version_mask;
  12427. /**
  12428. * @brief Converts an entity to its underlying type.
  12429. * @param value The value to convert.
  12430. * @return The integral representation of the given value.
  12431. */
  12432. [[nodiscard]] static constexpr entity_type to_integral(const value_type value) noexcept {
  12433. return static_cast<entity_type>(value);
  12434. }
  12435. /**
  12436. * @brief Returns the entity part once converted to the underlying type.
  12437. * @param value The value to convert.
  12438. * @return The integral representation of the entity part.
  12439. */
  12440. [[nodiscard]] static constexpr entity_type to_entity(const value_type value) noexcept {
  12441. return (to_integral(value) & entity_mask);
  12442. }
  12443. /**
  12444. * @brief Returns the version part once converted to the underlying type.
  12445. * @param value The value to convert.
  12446. * @return The integral representation of the version part.
  12447. */
  12448. [[nodiscard]] static constexpr version_type to_version(const value_type value) noexcept {
  12449. if constexpr(Traits::version_mask == 0u) {
  12450. return version_type{};
  12451. } else {
  12452. return (static_cast<version_type>(to_integral(value) >> length) & version_mask);
  12453. }
  12454. }
  12455. /**
  12456. * @brief Returns the successor of a given identifier.
  12457. * @param value The identifier of which to return the successor.
  12458. * @return The successor of the given identifier.
  12459. */
  12460. [[nodiscard]] static constexpr value_type next(const value_type value) noexcept {
  12461. const auto vers = to_version(value) + 1;
  12462. return construct(to_integral(value), static_cast<version_type>(vers + (vers == version_mask)));
  12463. }
  12464. /**
  12465. * @brief Constructs an identifier from its parts.
  12466. *
  12467. * If the version part is not provided, a tombstone is returned.<br/>
  12468. * If the entity part is not provided, a null identifier is returned.
  12469. *
  12470. * @param entity The entity part of the identifier.
  12471. * @param version The version part of the identifier.
  12472. * @return A properly constructed identifier.
  12473. */
  12474. [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) noexcept {
  12475. if constexpr(Traits::version_mask == 0u) {
  12476. return value_type{entity & entity_mask};
  12477. } else {
  12478. return value_type{(entity & entity_mask) | (static_cast<entity_type>(version & version_mask) << length)};
  12479. }
  12480. }
  12481. /**
  12482. * @brief Combines two identifiers in a single one.
  12483. *
  12484. * The returned identifier is a copy of the first element except for its
  12485. * version, which is taken from the second element.
  12486. *
  12487. * @param lhs The identifier from which to take the entity part.
  12488. * @param rhs The identifier from which to take the version part.
  12489. * @return A properly constructed identifier.
  12490. */
  12491. [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) noexcept {
  12492. if constexpr(Traits::version_mask == 0u) {
  12493. return value_type{lhs & entity_mask};
  12494. } else {
  12495. return value_type{(lhs & entity_mask) | (rhs & (version_mask << length))};
  12496. }
  12497. }
  12498. };
  12499. /**
  12500. * @brief Entity traits.
  12501. * @tparam Type Type of identifier.
  12502. */
  12503. template<typename Type>
  12504. struct entt_traits: basic_entt_traits<internal::entt_traits<Type>> {
  12505. /*! @brief Base type. */
  12506. using base_type = basic_entt_traits<internal::entt_traits<Type>>;
  12507. /*! @brief Page size, default is `ENTT_SPARSE_PAGE`. */
  12508. static constexpr std::size_t page_size = ENTT_SPARSE_PAGE;
  12509. };
  12510. /**
  12511. * @brief Converts an entity to its underlying type.
  12512. * @tparam Entity The value type.
  12513. * @param value The value to convert.
  12514. * @return The integral representation of the given value.
  12515. */
  12516. template<typename Entity>
  12517. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_integral(const Entity value) noexcept {
  12518. return entt_traits<Entity>::to_integral(value);
  12519. }
  12520. /**
  12521. * @brief Returns the entity part once converted to the underlying type.
  12522. * @tparam Entity The value type.
  12523. * @param value The value to convert.
  12524. * @return The integral representation of the entity part.
  12525. */
  12526. template<typename Entity>
  12527. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_entity(const Entity value) noexcept {
  12528. return entt_traits<Entity>::to_entity(value);
  12529. }
  12530. /**
  12531. * @brief Returns the version part once converted to the underlying type.
  12532. * @tparam Entity The value type.
  12533. * @param value The value to convert.
  12534. * @return The integral representation of the version part.
  12535. */
  12536. template<typename Entity>
  12537. [[nodiscard]] constexpr typename entt_traits<Entity>::version_type to_version(const Entity value) noexcept {
  12538. return entt_traits<Entity>::to_version(value);
  12539. }
  12540. /*! @brief Null object for all identifiers. */
  12541. struct null_t {
  12542. /**
  12543. * @brief Converts the null object to identifiers of any type.
  12544. * @tparam Entity Type of identifier.
  12545. * @return The null representation for the given type.
  12546. */
  12547. template<typename Entity>
  12548. [[nodiscard]] constexpr operator Entity() const noexcept {
  12549. using traits_type = entt_traits<Entity>;
  12550. constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask);
  12551. return value;
  12552. }
  12553. /**
  12554. * @brief Compares two null objects.
  12555. * @param other A null object.
  12556. * @return True in all cases.
  12557. */
  12558. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const null_t other) const noexcept {
  12559. return true;
  12560. }
  12561. /**
  12562. * @brief Compares two null objects.
  12563. * @param other A null object.
  12564. * @return False in all cases.
  12565. */
  12566. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const null_t other) const noexcept {
  12567. return false;
  12568. }
  12569. /**
  12570. * @brief Compares a null object and an identifier of any type.
  12571. * @tparam Entity Type of identifier.
  12572. * @param entity Identifier with which to compare.
  12573. * @return False if the two elements differ, true otherwise.
  12574. */
  12575. template<typename Entity>
  12576. [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept {
  12577. using traits_type = entt_traits<Entity>;
  12578. return traits_type::to_entity(entity) == traits_type::to_entity(*this);
  12579. }
  12580. /**
  12581. * @brief Compares a null object and an identifier of any type.
  12582. * @tparam Entity Type of identifier.
  12583. * @param entity Identifier with which to compare.
  12584. * @return True if the two elements differ, false otherwise.
  12585. */
  12586. template<typename Entity>
  12587. [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept {
  12588. return !(entity == *this);
  12589. }
  12590. };
  12591. /**
  12592. * @brief Compares a null object and an identifier of any type.
  12593. * @tparam Entity Type of identifier.
  12594. * @param lhs Identifier with which to compare.
  12595. * @param rhs A null object yet to be converted.
  12596. * @return False if the two elements differ, true otherwise.
  12597. */
  12598. template<typename Entity>
  12599. [[nodiscard]] constexpr bool operator==(const Entity lhs, const null_t rhs) noexcept {
  12600. return rhs.operator==(lhs);
  12601. }
  12602. /**
  12603. * @brief Compares a null object and an identifier of any type.
  12604. * @tparam Entity Type of identifier.
  12605. * @param lhs Identifier with which to compare.
  12606. * @param rhs A null object yet to be converted.
  12607. * @return True if the two elements differ, false otherwise.
  12608. */
  12609. template<typename Entity>
  12610. [[nodiscard]] constexpr bool operator!=(const Entity lhs, const null_t rhs) noexcept {
  12611. return !(rhs == lhs);
  12612. }
  12613. /*! @brief Tombstone object for all identifiers. */
  12614. struct tombstone_t {
  12615. /**
  12616. * @brief Converts the tombstone object to identifiers of any type.
  12617. * @tparam Entity Type of identifier.
  12618. * @return The tombstone representation for the given type.
  12619. */
  12620. template<typename Entity>
  12621. [[nodiscard]] constexpr operator Entity() const noexcept {
  12622. using traits_type = entt_traits<Entity>;
  12623. constexpr auto value = traits_type::construct(traits_type::entity_mask, traits_type::version_mask);
  12624. return value;
  12625. }
  12626. /**
  12627. * @brief Compares two tombstone objects.
  12628. * @param other A tombstone object.
  12629. * @return True in all cases.
  12630. */
  12631. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const tombstone_t other) const noexcept {
  12632. return true;
  12633. }
  12634. /**
  12635. * @brief Compares two tombstone objects.
  12636. * @param other A tombstone object.
  12637. * @return False in all cases.
  12638. */
  12639. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const tombstone_t other) const noexcept {
  12640. return false;
  12641. }
  12642. /**
  12643. * @brief Compares a tombstone object and an identifier of any type.
  12644. * @tparam Entity Type of identifier.
  12645. * @param entity Identifier with which to compare.
  12646. * @return False if the two elements differ, true otherwise.
  12647. */
  12648. template<typename Entity>
  12649. [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept {
  12650. using traits_type = entt_traits<Entity>;
  12651. if constexpr(traits_type::version_mask == 0u) {
  12652. return false;
  12653. } else {
  12654. return (traits_type::to_version(entity) == traits_type::to_version(*this));
  12655. }
  12656. }
  12657. /**
  12658. * @brief Compares a tombstone object and an identifier of any type.
  12659. * @tparam Entity Type of identifier.
  12660. * @param entity Identifier with which to compare.
  12661. * @return True if the two elements differ, false otherwise.
  12662. */
  12663. template<typename Entity>
  12664. [[nodiscard]] constexpr bool operator!=(const Entity entity) const noexcept {
  12665. return !(entity == *this);
  12666. }
  12667. };
  12668. /**
  12669. * @brief Compares a tombstone object and an identifier of any type.
  12670. * @tparam Entity Type of identifier.
  12671. * @param lhs Identifier with which to compare.
  12672. * @param rhs A tombstone object yet to be converted.
  12673. * @return False if the two elements differ, true otherwise.
  12674. */
  12675. template<typename Entity>
  12676. [[nodiscard]] constexpr bool operator==(const Entity lhs, const tombstone_t rhs) noexcept {
  12677. return rhs.operator==(lhs);
  12678. }
  12679. /**
  12680. * @brief Compares a tombstone object and an identifier of any type.
  12681. * @tparam Entity Type of identifier.
  12682. * @param lhs Identifier with which to compare.
  12683. * @param rhs A tombstone object yet to be converted.
  12684. * @return True if the two elements differ, false otherwise.
  12685. */
  12686. template<typename Entity>
  12687. [[nodiscard]] constexpr bool operator!=(const Entity lhs, const tombstone_t rhs) noexcept {
  12688. return !(rhs == lhs);
  12689. }
  12690. /**
  12691. * @brief Compile-time constant for null entities.
  12692. *
  12693. * There exist implicit conversions from this variable to identifiers of any
  12694. * allowed type. Similarly, there exist comparison operators between the null
  12695. * entity and any other identifier.
  12696. */
  12697. inline constexpr null_t null{};
  12698. /**
  12699. * @brief Compile-time constant for tombstone entities.
  12700. *
  12701. * There exist implicit conversions from this variable to identifiers of any
  12702. * allowed type. Similarly, there exist comparison operators between the
  12703. * tombstone entity and any other identifier.
  12704. */
  12705. inline constexpr tombstone_t tombstone{};
  12706. } // namespace entt
  12707. #endif
  12708. // #include "fwd.hpp"
  12709. namespace entt {
  12710. /*! @cond TURN_OFF_DOXYGEN */
  12711. namespace internal {
  12712. template<typename, typename, typename>
  12713. class extended_group_iterator;
  12714. template<typename It, typename... Owned, typename... Get>
  12715. class extended_group_iterator<It, owned_t<Owned...>, get_t<Get...>> {
  12716. template<typename Type>
  12717. [[nodiscard]] auto index_to_element([[maybe_unused]] Type &cpool) const {
  12718. if constexpr(std::is_void_v<typename Type::value_type>) {
  12719. return std::make_tuple();
  12720. } else {
  12721. return std::forward_as_tuple(cpool.rbegin()[it.index()]);
  12722. }
  12723. }
  12724. public:
  12725. using iterator_type = It;
  12726. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Owned>().get_as_tuple({})..., std::declval<Get>().get_as_tuple({})...));
  12727. using pointer = input_iterator_pointer<value_type>;
  12728. using reference = value_type;
  12729. using difference_type = std::ptrdiff_t;
  12730. using iterator_category = std::input_iterator_tag;
  12731. using iterator_concept = std::forward_iterator_tag;
  12732. constexpr extended_group_iterator()
  12733. : it{},
  12734. pools{} {}
  12735. extended_group_iterator(iterator_type from, std::tuple<Owned *..., Get *...> cpools)
  12736. : it{from},
  12737. pools{std::move(cpools)} {}
  12738. extended_group_iterator &operator++() noexcept {
  12739. return ++it, *this;
  12740. }
  12741. extended_group_iterator operator++(int) noexcept {
  12742. const extended_group_iterator orig = *this;
  12743. return ++(*this), orig;
  12744. }
  12745. [[nodiscard]] reference operator*() const noexcept {
  12746. return std::tuple_cat(std::make_tuple(*it), index_to_element(*std::get<Owned *>(pools))..., std::get<Get *>(pools)->get_as_tuple(*it)...);
  12747. }
  12748. [[nodiscard]] pointer operator->() const noexcept {
  12749. return operator*();
  12750. }
  12751. [[nodiscard]] constexpr iterator_type base() const noexcept {
  12752. return it;
  12753. }
  12754. template<typename... Lhs, typename... Rhs>
  12755. friend constexpr bool operator==(const extended_group_iterator<Lhs...> &, const extended_group_iterator<Rhs...> &) noexcept;
  12756. private:
  12757. It it;
  12758. std::tuple<Owned *..., Get *...> pools;
  12759. };
  12760. template<typename... Lhs, typename... Rhs>
  12761. [[nodiscard]] constexpr bool operator==(const extended_group_iterator<Lhs...> &lhs, const extended_group_iterator<Rhs...> &rhs) noexcept {
  12762. return lhs.it == rhs.it;
  12763. }
  12764. template<typename... Lhs, typename... Rhs>
  12765. [[nodiscard]] constexpr bool operator!=(const extended_group_iterator<Lhs...> &lhs, const extended_group_iterator<Rhs...> &rhs) noexcept {
  12766. return !(lhs == rhs);
  12767. }
  12768. struct group_descriptor {
  12769. using size_type = std::size_t;
  12770. virtual ~group_descriptor() = default;
  12771. [[nodiscard]] virtual bool owned(const id_type) const noexcept {
  12772. return false;
  12773. }
  12774. };
  12775. template<typename Type, std::size_t Owned, std::size_t Get, std::size_t Exclude>
  12776. class group_handler final: public group_descriptor {
  12777. using entity_type = typename Type::entity_type;
  12778. void swap_elements(const std::size_t pos, const entity_type entt) {
  12779. for(size_type next{}; next < Owned; ++next) {
  12780. pools[next]->swap_elements((*pools[next])[pos], entt);
  12781. }
  12782. }
  12783. void push_on_construct(const entity_type entt) {
  12784. if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools)
  12785. && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) {
  12786. swap_elements(len++, entt);
  12787. }
  12788. }
  12789. void push_on_destroy(const entity_type entt) {
  12790. if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools)
  12791. && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) {
  12792. swap_elements(len++, entt);
  12793. }
  12794. }
  12795. void remove_if(const entity_type entt) {
  12796. if(pools[0u]->contains(entt) && (pools[0u]->index(entt) < len)) {
  12797. swap_elements(--len, entt);
  12798. }
  12799. }
  12800. void common_setup() {
  12801. // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
  12802. for(auto first = pools[0u]->rbegin(), last = first + static_cast<typename decltype(pools)::difference_type>(pools[0u]->size()); first != last; ++first) {
  12803. push_on_construct(*first);
  12804. }
  12805. }
  12806. public:
  12807. using common_type = Type;
  12808. using size_type = typename Type::size_type;
  12809. template<typename... OGType, typename... EType>
  12810. group_handler(std::tuple<OGType &...> ogpool, std::tuple<EType &...> epool)
  12811. : pools{std::apply([](auto &&...cpool) { return std::array<common_type *, (Owned + Get)>{&cpool...}; }, ogpool)},
  12812. filter{std::apply([](auto &&...cpool) { return std::array<common_type *, Exclude>{&cpool...}; }, epool)} {
  12813. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, ogpool);
  12814. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool);
  12815. common_setup();
  12816. }
  12817. [[nodiscard]] bool owned(const id_type hash) const noexcept override {
  12818. for(size_type pos{}; pos < Owned; ++pos) {
  12819. if(pools[pos]->info().hash() == hash) {
  12820. return true;
  12821. }
  12822. }
  12823. return false;
  12824. }
  12825. [[nodiscard]] size_type length() const noexcept {
  12826. return len;
  12827. }
  12828. template<std::size_t Index>
  12829. [[nodiscard]] common_type *storage() const noexcept {
  12830. if constexpr(Index < (Owned + Get)) {
  12831. return pools[Index];
  12832. } else {
  12833. return filter[Index - (Owned + Get)];
  12834. }
  12835. }
  12836. private:
  12837. std::array<common_type *, (Owned + Get)> pools;
  12838. std::array<common_type *, Exclude> filter;
  12839. std::size_t len{};
  12840. };
  12841. template<typename Type, std::size_t Get, std::size_t Exclude>
  12842. class group_handler<Type, 0u, Get, Exclude> final: public group_descriptor {
  12843. using entity_type = typename Type::entity_type;
  12844. void push_on_construct(const entity_type entt) {
  12845. if(!elem.contains(entt)
  12846. && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools)
  12847. && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) {
  12848. elem.push(entt);
  12849. }
  12850. }
  12851. void push_on_destroy(const entity_type entt) {
  12852. if(!elem.contains(entt)
  12853. && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools)
  12854. && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) {
  12855. elem.push(entt);
  12856. }
  12857. }
  12858. void remove_if(const entity_type entt) {
  12859. elem.remove(entt);
  12860. }
  12861. void common_setup() {
  12862. for(const auto entity: *pools[0u]) {
  12863. push_on_construct(entity);
  12864. }
  12865. }
  12866. public:
  12867. using common_type = Type;
  12868. template<typename Allocator, typename... GType, typename... EType>
  12869. group_handler(const Allocator &allocator, std::tuple<GType &...> gpool, std::tuple<EType &...> epool)
  12870. : pools{std::apply([](auto &&...cpool) { return std::array<common_type *, Get>{&cpool...}; }, gpool)},
  12871. filter{std::apply([](auto &&...cpool) { return std::array<common_type *, Exclude>{&cpool...}; }, epool)},
  12872. elem{allocator} {
  12873. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, gpool);
  12874. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool);
  12875. common_setup();
  12876. }
  12877. [[nodiscard]] common_type &handle() noexcept {
  12878. return elem;
  12879. }
  12880. [[nodiscard]] const common_type &handle() const noexcept {
  12881. return elem;
  12882. }
  12883. template<std::size_t Index>
  12884. [[nodiscard]] common_type *storage() const noexcept {
  12885. if constexpr(Index < Get) {
  12886. return pools[Index];
  12887. } else {
  12888. return filter[Index - Get];
  12889. }
  12890. }
  12891. private:
  12892. std::array<common_type *, Get> pools;
  12893. std::array<common_type *, Exclude> filter;
  12894. common_type elem;
  12895. };
  12896. } // namespace internal
  12897. /*! @endcond */
  12898. /**
  12899. * @brief Group.
  12900. *
  12901. * Primary template isn't defined on purpose. All the specializations give a
  12902. * compile-time error, but for a few reasonable cases.
  12903. */
  12904. template<typename, typename, typename>
  12905. class basic_group;
  12906. /**
  12907. * @brief Non-owning group.
  12908. *
  12909. * A non-owning group returns all entities and only the entities that are at
  12910. * least in the given storage. Moreover, it's guaranteed that the entity list is
  12911. * tightly packed in memory for fast iterations.
  12912. *
  12913. * @b Important
  12914. *
  12915. * Iterators aren't invalidated if:
  12916. *
  12917. * * New elements are added to the storage.
  12918. * * The entity currently pointed is modified (for example, elements are added
  12919. * or removed from it).
  12920. * * The entity currently pointed is destroyed.
  12921. *
  12922. * In all other cases, modifying the pools iterated by the group in any way
  12923. * invalidates all the iterators.
  12924. *
  12925. * @tparam Get Types of storage _observed_ by the group.
  12926. * @tparam Exclude Types of storage used to filter the group.
  12927. */
  12928. template<typename... Get, typename... Exclude>
  12929. class basic_group<owned_t<>, get_t<Get...>, exclude_t<Exclude...>> {
  12930. using base_type = std::common_type_t<typename Get::base_type..., typename Exclude::base_type...>;
  12931. using underlying_type = typename base_type::entity_type;
  12932. template<typename Type>
  12933. static constexpr std::size_t index_of = type_list_index_v<std::remove_const_t<Type>, type_list<typename Get::element_type..., typename Exclude::element_type...>>;
  12934. template<std::size_t... Index>
  12935. [[nodiscard]] auto pools_for(std::index_sequence<Index...>) const noexcept {
  12936. using return_type = std::tuple<Get *...>;
  12937. return descriptor ? return_type{static_cast<Get *>(descriptor->template storage<Index>())...} : return_type{};
  12938. }
  12939. public:
  12940. /*! @brief Underlying entity identifier. */
  12941. using entity_type = underlying_type;
  12942. /*! @brief Unsigned integer type. */
  12943. using size_type = std::size_t;
  12944. /*! @brief Signed integer type. */
  12945. using difference_type = std::ptrdiff_t;
  12946. /*! @brief Common type among all storage types. */
  12947. using common_type = base_type;
  12948. /*! @brief Random access iterator type. */
  12949. using iterator = typename common_type::iterator;
  12950. /*! @brief Reverse iterator type. */
  12951. using reverse_iterator = typename common_type::reverse_iterator;
  12952. /*! @brief Iterable group type. */
  12953. using iterable = iterable_adaptor<internal::extended_group_iterator<iterator, owned_t<>, get_t<Get...>>>;
  12954. /*! @brief Group handler type. */
  12955. using handler = internal::group_handler<common_type, 0u, sizeof...(Get), sizeof...(Exclude)>;
  12956. /**
  12957. * @brief Group opaque identifier.
  12958. * @return Group opaque identifier.
  12959. */
  12960. static id_type group_id() noexcept {
  12961. return type_hash<basic_group<owned_t<>, get_t<std::remove_const_t<Get>...>, exclude_t<std::remove_const_t<Exclude>...>>>::value();
  12962. }
  12963. /*! @brief Default constructor to use to create empty, invalid groups. */
  12964. basic_group() noexcept
  12965. : descriptor{} {}
  12966. /**
  12967. * @brief Constructs a group from a set of storage classes.
  12968. * @param ref A reference to a group handler.
  12969. */
  12970. basic_group(handler &ref) noexcept
  12971. : descriptor{&ref} {}
  12972. /**
  12973. * @brief Returns the leading storage of a group.
  12974. * @return The leading storage of the group.
  12975. */
  12976. [[nodiscard]] const common_type &handle() const noexcept {
  12977. return descriptor->handle();
  12978. }
  12979. /**
  12980. * @brief Returns the storage for a given element type, if any.
  12981. * @tparam Type Type of element of which to return the storage.
  12982. * @return The storage for the given element type.
  12983. */
  12984. template<typename Type>
  12985. [[nodiscard]] auto *storage() const noexcept {
  12986. return storage<index_of<Type>>();
  12987. }
  12988. /**
  12989. * @brief Returns the storage for a given index, if any.
  12990. * @tparam Index Index of the storage to return.
  12991. * @return The storage for the given index.
  12992. */
  12993. template<std::size_t Index>
  12994. [[nodiscard]] auto *storage() const noexcept {
  12995. using type = type_list_element_t<Index, type_list<Get..., Exclude...>>;
  12996. return *this ? static_cast<type *>(descriptor->template storage<Index>()) : nullptr;
  12997. }
  12998. /**
  12999. * @brief Returns the number of entities that are part of the group.
  13000. * @return Number of entities that are part of the group.
  13001. */
  13002. [[nodiscard]] size_type size() const noexcept {
  13003. return *this ? handle().size() : size_type{};
  13004. }
  13005. /**
  13006. * @brief Returns the number of elements that a group has currently
  13007. * allocated space for.
  13008. * @return Capacity of the group.
  13009. */
  13010. [[nodiscard]] size_type capacity() const noexcept {
  13011. return *this ? handle().capacity() : size_type{};
  13012. }
  13013. /*! @brief Requests the removal of unused capacity. */
  13014. void shrink_to_fit() {
  13015. if(*this) {
  13016. descriptor->handle().shrink_to_fit();
  13017. }
  13018. }
  13019. /**
  13020. * @brief Checks whether a group is empty.
  13021. * @return True if the group is empty, false otherwise.
  13022. */
  13023. [[nodiscard]] bool empty() const noexcept {
  13024. return !*this || handle().empty();
  13025. }
  13026. /**
  13027. * @brief Returns an iterator to the first entity of the group.
  13028. *
  13029. * If the group is empty, the returned iterator will be equal to `end()`.
  13030. *
  13031. * @return An iterator to the first entity of the group.
  13032. */
  13033. [[nodiscard]] iterator begin() const noexcept {
  13034. return *this ? handle().begin() : iterator{};
  13035. }
  13036. /**
  13037. * @brief Returns an iterator that is past the last entity of the group.
  13038. * @return An iterator to the entity following the last entity of the
  13039. * group.
  13040. */
  13041. [[nodiscard]] iterator end() const noexcept {
  13042. return *this ? handle().end() : iterator{};
  13043. }
  13044. /**
  13045. * @brief Returns an iterator to the first entity of the reversed group.
  13046. *
  13047. * If the group is empty, the returned iterator will be equal to `rend()`.
  13048. *
  13049. * @return An iterator to the first entity of the reversed group.
  13050. */
  13051. [[nodiscard]] reverse_iterator rbegin() const noexcept {
  13052. return *this ? handle().rbegin() : reverse_iterator{};
  13053. }
  13054. /**
  13055. * @brief Returns an iterator that is past the last entity of the reversed
  13056. * group.
  13057. * @return An iterator to the entity following the last entity of the
  13058. * reversed group.
  13059. */
  13060. [[nodiscard]] reverse_iterator rend() const noexcept {
  13061. return *this ? handle().rend() : reverse_iterator{};
  13062. }
  13063. /**
  13064. * @brief Returns the first entity of the group, if any.
  13065. * @return The first entity of the group if one exists, the null entity
  13066. * otherwise.
  13067. */
  13068. [[nodiscard]] entity_type front() const noexcept {
  13069. const auto it = begin();
  13070. return it != end() ? *it : null;
  13071. }
  13072. /**
  13073. * @brief Returns the last entity of the group, if any.
  13074. * @return The last entity of the group if one exists, the null entity
  13075. * otherwise.
  13076. */
  13077. [[nodiscard]] entity_type back() const noexcept {
  13078. const auto it = rbegin();
  13079. return it != rend() ? *it : null;
  13080. }
  13081. /**
  13082. * @brief Finds an entity.
  13083. * @param entt A valid identifier.
  13084. * @return An iterator to the given entity if it's found, past the end
  13085. * iterator otherwise.
  13086. */
  13087. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  13088. return *this ? handle().find(entt) : iterator{};
  13089. }
  13090. /**
  13091. * @brief Returns the identifier that occupies the given position.
  13092. * @param pos Position of the element to return.
  13093. * @return The identifier that occupies the given position.
  13094. */
  13095. [[nodiscard]] entity_type operator[](const size_type pos) const {
  13096. return begin()[static_cast<difference_type>(pos)];
  13097. }
  13098. /**
  13099. * @brief Checks if a group is properly initialized.
  13100. * @return True if the group is properly initialized, false otherwise.
  13101. */
  13102. [[nodiscard]] explicit operator bool() const noexcept {
  13103. return descriptor != nullptr;
  13104. }
  13105. /**
  13106. * @brief Checks if a group contains an entity.
  13107. * @param entt A valid identifier.
  13108. * @return True if the group contains the given entity, false otherwise.
  13109. */
  13110. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  13111. return *this && handle().contains(entt);
  13112. }
  13113. /**
  13114. * @brief Returns the elements assigned to the given entity.
  13115. * @tparam Type Type of the element to get.
  13116. * @tparam Other Other types of elements to get.
  13117. * @param entt A valid identifier.
  13118. * @return The elements assigned to the entity.
  13119. */
  13120. template<typename Type, typename... Other>
  13121. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  13122. return get<index_of<Type>, index_of<Other>...>(entt);
  13123. }
  13124. /**
  13125. * @brief Returns the elements assigned to the given entity.
  13126. * @tparam Index Indexes of the elements to get.
  13127. * @param entt A valid identifier.
  13128. * @return The elements assigned to the entity.
  13129. */
  13130. template<std::size_t... Index>
  13131. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  13132. const auto cpools = pools_for(std::index_sequence_for<Get...>{});
  13133. if constexpr(sizeof...(Index) == 0) {
  13134. return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools);
  13135. } else if constexpr(sizeof...(Index) == 1) {
  13136. return (std::get<Index>(cpools)->get(entt), ...);
  13137. } else {
  13138. return std::tuple_cat(std::get<Index>(cpools)->get_as_tuple(entt)...);
  13139. }
  13140. }
  13141. /**
  13142. * @brief Iterates entities and elements and applies the given function
  13143. * object to them.
  13144. *
  13145. * The function object is invoked for each entity. It is provided with the
  13146. * entity itself and a set of references to non-empty elements. The
  13147. * _constness_ of the elements is as requested.<br/>
  13148. * The signature of the function must be equivalent to one of the following
  13149. * forms:
  13150. *
  13151. * @code{.cpp}
  13152. * void(const entity_type, Type &...);
  13153. * void(Type &...);
  13154. * @endcode
  13155. *
  13156. * @note
  13157. * Empty types aren't explicitly instantiated and therefore they are never
  13158. * returned during iterations.
  13159. *
  13160. * @tparam Func Type of the function object to invoke.
  13161. * @param func A valid function object.
  13162. */
  13163. template<typename Func>
  13164. void each(Func func) const {
  13165. for(const auto entt: *this) {
  13166. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  13167. std::apply(func, std::tuple_cat(std::make_tuple(entt), get(entt)));
  13168. } else {
  13169. std::apply(func, get(entt));
  13170. }
  13171. }
  13172. }
  13173. /**
  13174. * @brief Returns an iterable object to use to _visit_ a group.
  13175. *
  13176. * The iterable object returns tuples that contain the current entity and a
  13177. * set of references to its non-empty elements. The _constness_ of the
  13178. * elements is as requested.
  13179. *
  13180. * @note
  13181. * Empty types aren't explicitly instantiated and therefore they are never
  13182. * returned during iterations.
  13183. *
  13184. * @return An iterable object to use to _visit_ the group.
  13185. */
  13186. [[nodiscard]] iterable each() const noexcept {
  13187. const auto cpools = pools_for(std::index_sequence_for<Get...>{});
  13188. return iterable{{begin(), cpools}, {end(), cpools}};
  13189. }
  13190. /**
  13191. * @brief Sort a group according to the given comparison function.
  13192. *
  13193. * The comparison function object must return `true` if the first element
  13194. * is _less_ than the second one, `false` otherwise. The signature of the
  13195. * comparison function should be equivalent to one of the following:
  13196. *
  13197. * @code{.cpp}
  13198. * bool(std::tuple<Type &...>, std::tuple<Type &...>);
  13199. * bool(const Type &..., const Type &...);
  13200. * bool(const Entity, const Entity);
  13201. * @endcode
  13202. *
  13203. * Where `Type` are such that they are iterated by the group.<br/>
  13204. * Moreover, the comparison function object shall induce a
  13205. * _strict weak ordering_ on the values.
  13206. *
  13207. * The sort function object must offer a member function template
  13208. * `operator()` that accepts three arguments:
  13209. *
  13210. * * An iterator to the first element of the range to sort.
  13211. * * An iterator past the last element of the range to sort.
  13212. * * A comparison function to use to compare the elements.
  13213. *
  13214. * @tparam Type Optional type of element to compare.
  13215. * @tparam Other Other optional types of elements to compare.
  13216. * @tparam Compare Type of comparison function object.
  13217. * @tparam Sort Type of sort function object.
  13218. * @tparam Args Types of arguments to forward to the sort function object.
  13219. * @param compare A valid comparison function object.
  13220. * @param algo A valid sort function object.
  13221. * @param args Arguments to forward to the sort function object, if any.
  13222. */
  13223. template<typename Type, typename... Other, typename Compare, typename Sort = std_sort, typename... Args>
  13224. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  13225. sort<index_of<Type>, index_of<Other>...>(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  13226. }
  13227. /**
  13228. * @brief Sort a group according to the given comparison function.
  13229. *
  13230. * @sa sort
  13231. *
  13232. * @tparam Index Optional indexes of elements to compare.
  13233. * @tparam Compare Type of comparison function object.
  13234. * @tparam Sort Type of sort function object.
  13235. * @tparam Args Types of arguments to forward to the sort function object.
  13236. * @param compare A valid comparison function object.
  13237. * @param algo A valid sort function object.
  13238. * @param args Arguments to forward to the sort function object, if any.
  13239. */
  13240. template<std::size_t... Index, typename Compare, typename Sort = std_sort, typename... Args>
  13241. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  13242. if(*this) {
  13243. if constexpr(sizeof...(Index) == 0) {
  13244. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  13245. descriptor->handle().sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  13246. } else {
  13247. auto comp = [&compare, cpools = pools_for(std::index_sequence_for<Get...>{})](const entity_type lhs, const entity_type rhs) {
  13248. if constexpr(sizeof...(Index) == 1) {
  13249. return compare((std::get<Index>(cpools)->get(lhs), ...), (std::get<Index>(cpools)->get(rhs), ...));
  13250. } else {
  13251. return compare(std::forward_as_tuple(std::get<Index>(cpools)->get(lhs)...), std::forward_as_tuple(std::get<Index>(cpools)->get(rhs)...));
  13252. }
  13253. };
  13254. descriptor->handle().sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
  13255. }
  13256. }
  13257. }
  13258. /**
  13259. * @brief Sort entities according to their order in a range.
  13260. *
  13261. * The shared pool of entities and thus its order is affected by the changes
  13262. * to each and every pool that it tracks.
  13263. *
  13264. * @tparam It Type of input iterator.
  13265. * @param first An iterator to the first element of the range of entities.
  13266. * @param last An iterator past the last element of the range of entities.
  13267. */
  13268. template<typename It>
  13269. void sort_as(It first, It last) const {
  13270. if(*this) {
  13271. descriptor->handle().sort_as(first, last);
  13272. }
  13273. }
  13274. private:
  13275. handler *descriptor;
  13276. };
  13277. /**
  13278. * @brief Owning group.
  13279. *
  13280. * Owning groups returns all entities and only the entities that are at
  13281. * least in the given storage. Moreover:
  13282. *
  13283. * * It's guaranteed that the entity list is tightly packed in memory for fast
  13284. * iterations.
  13285. * * It's guaranteed that all elements in the owned storage are tightly packed
  13286. * in memory for even faster iterations and to allow direct access.
  13287. * * They stay true to the order of the owned storage and all instances have the
  13288. * same order in memory.
  13289. *
  13290. * The more types of storage are owned, the faster it is to iterate a group.
  13291. *
  13292. * @b Important
  13293. *
  13294. * Iterators aren't invalidated if:
  13295. *
  13296. * * New elements are added to the storage.
  13297. * * The entity currently pointed is modified (for example, elements are added
  13298. * or removed from it).
  13299. * * The entity currently pointed is destroyed.
  13300. *
  13301. * In all other cases, modifying the pools iterated by the group in any way
  13302. * invalidates all the iterators.
  13303. *
  13304. * @tparam Owned Types of storage _owned_ by the group.
  13305. * @tparam Get Types of storage _observed_ by the group.
  13306. * @tparam Exclude Types of storage used to filter the group.
  13307. */
  13308. template<typename... Owned, typename... Get, typename... Exclude>
  13309. class basic_group<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> {
  13310. static_assert(((Owned::storage_policy != deletion_policy::in_place) && ...), "Groups do not support in-place delete");
  13311. using base_type = std::common_type_t<typename Owned::base_type..., typename Get::base_type..., typename Exclude::base_type...>;
  13312. using underlying_type = typename base_type::entity_type;
  13313. template<typename Type>
  13314. static constexpr std::size_t index_of = type_list_index_v<std::remove_const_t<Type>, type_list<typename Owned::element_type..., typename Get::element_type..., typename Exclude::element_type...>>;
  13315. template<std::size_t... Index, std::size_t... Other>
  13316. [[nodiscard]] auto pools_for(std::index_sequence<Index...>, std::index_sequence<Other...>) const noexcept {
  13317. using return_type = std::tuple<Owned *..., Get *...>;
  13318. return descriptor ? return_type{static_cast<Owned *>(descriptor->template storage<Index>())..., static_cast<Get *>(descriptor->template storage<sizeof...(Owned) + Other>())...} : return_type{};
  13319. }
  13320. public:
  13321. /*! @brief Underlying entity identifier. */
  13322. using entity_type = underlying_type;
  13323. /*! @brief Unsigned integer type. */
  13324. using size_type = std::size_t;
  13325. /*! @brief Signed integer type. */
  13326. using difference_type = std::ptrdiff_t;
  13327. /*! @brief Common type among all storage types. */
  13328. using common_type = base_type;
  13329. /*! @brief Random access iterator type. */
  13330. using iterator = typename common_type::iterator;
  13331. /*! @brief Reverse iterator type. */
  13332. using reverse_iterator = typename common_type::reverse_iterator;
  13333. /*! @brief Iterable group type. */
  13334. using iterable = iterable_adaptor<internal::extended_group_iterator<iterator, owned_t<Owned...>, get_t<Get...>>>;
  13335. /*! @brief Group handler type. */
  13336. using handler = internal::group_handler<common_type, sizeof...(Owned), sizeof...(Get), sizeof...(Exclude)>;
  13337. /**
  13338. * @brief Group opaque identifier.
  13339. * @return Group opaque identifier.
  13340. */
  13341. static id_type group_id() noexcept {
  13342. return type_hash<basic_group<owned_t<std::remove_const_t<Owned>...>, get_t<std::remove_const_t<Get>...>, exclude_t<std::remove_const_t<Exclude>...>>>::value();
  13343. }
  13344. /*! @brief Default constructor to use to create empty, invalid groups. */
  13345. basic_group() noexcept
  13346. : descriptor{} {}
  13347. /**
  13348. * @brief Constructs a group from a set of storage classes.
  13349. * @param ref A reference to a group handler.
  13350. */
  13351. basic_group(handler &ref) noexcept
  13352. : descriptor{&ref} {}
  13353. /**
  13354. * @brief Returns the leading storage of a group.
  13355. * @return The leading storage of the group.
  13356. */
  13357. [[nodiscard]] const common_type &handle() const noexcept {
  13358. return *storage<0>();
  13359. }
  13360. /**
  13361. * @brief Returns the storage for a given element type, if any.
  13362. * @tparam Type Type of element of which to return the storage.
  13363. * @return The storage for the given element type.
  13364. */
  13365. template<typename Type>
  13366. [[nodiscard]] auto *storage() const noexcept {
  13367. return storage<index_of<Type>>();
  13368. }
  13369. /**
  13370. * @brief Returns the storage for a given index, if any.
  13371. * @tparam Index Index of the storage to return.
  13372. * @return The storage for the given index.
  13373. */
  13374. template<std::size_t Index>
  13375. [[nodiscard]] auto *storage() const noexcept {
  13376. using type = type_list_element_t<Index, type_list<Owned..., Get..., Exclude...>>;
  13377. return *this ? static_cast<type *>(descriptor->template storage<Index>()) : nullptr;
  13378. }
  13379. /**
  13380. * @brief Returns the number of entities that that are part of the group.
  13381. * @return Number of entities that that are part of the group.
  13382. */
  13383. [[nodiscard]] size_type size() const noexcept {
  13384. return *this ? descriptor->length() : size_type{};
  13385. }
  13386. /**
  13387. * @brief Checks whether a group is empty.
  13388. * @return True if the group is empty, false otherwise.
  13389. */
  13390. [[nodiscard]] bool empty() const noexcept {
  13391. return !*this || !descriptor->length();
  13392. }
  13393. /**
  13394. * @brief Returns an iterator to the first entity of the group.
  13395. *
  13396. * If the group is empty, the returned iterator will be equal to `end()`.
  13397. *
  13398. * @return An iterator to the first entity of the group.
  13399. */
  13400. [[nodiscard]] iterator begin() const noexcept {
  13401. return *this ? (handle().end() - static_cast<difference_type>(descriptor->length())) : iterator{};
  13402. }
  13403. /**
  13404. * @brief Returns an iterator that is past the last entity of the group.
  13405. * @return An iterator to the entity following the last entity of the
  13406. * group.
  13407. */
  13408. [[nodiscard]] iterator end() const noexcept {
  13409. return *this ? handle().end() : iterator{};
  13410. }
  13411. /**
  13412. * @brief Returns an iterator to the first entity of the reversed group.
  13413. *
  13414. * If the group is empty, the returned iterator will be equal to `rend()`.
  13415. *
  13416. * @return An iterator to the first entity of the reversed group.
  13417. */
  13418. [[nodiscard]] reverse_iterator rbegin() const noexcept {
  13419. return *this ? handle().rbegin() : reverse_iterator{};
  13420. }
  13421. /**
  13422. * @brief Returns an iterator that is past the last entity of the reversed
  13423. * group.
  13424. * @return An iterator to the entity following the last entity of the
  13425. * reversed group.
  13426. */
  13427. [[nodiscard]] reverse_iterator rend() const noexcept {
  13428. return *this ? (handle().rbegin() + static_cast<difference_type>(descriptor->length())) : reverse_iterator{};
  13429. }
  13430. /**
  13431. * @brief Returns the first entity of the group, if any.
  13432. * @return The first entity of the group if one exists, the null entity
  13433. * otherwise.
  13434. */
  13435. [[nodiscard]] entity_type front() const noexcept {
  13436. const auto it = begin();
  13437. return it != end() ? *it : null;
  13438. }
  13439. /**
  13440. * @brief Returns the last entity of the group, if any.
  13441. * @return The last entity of the group if one exists, the null entity
  13442. * otherwise.
  13443. */
  13444. [[nodiscard]] entity_type back() const noexcept {
  13445. const auto it = rbegin();
  13446. return it != rend() ? *it : null;
  13447. }
  13448. /**
  13449. * @brief Finds an entity.
  13450. * @param entt A valid identifier.
  13451. * @return An iterator to the given entity if it's found, past the end
  13452. * iterator otherwise.
  13453. */
  13454. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  13455. const auto it = *this ? handle().find(entt) : iterator{};
  13456. return it >= begin() ? it : iterator{};
  13457. }
  13458. /**
  13459. * @brief Returns the identifier that occupies the given position.
  13460. * @param pos Position of the element to return.
  13461. * @return The identifier that occupies the given position.
  13462. */
  13463. [[nodiscard]] entity_type operator[](const size_type pos) const {
  13464. return begin()[static_cast<difference_type>(pos)];
  13465. }
  13466. /**
  13467. * @brief Checks if a group is properly initialized.
  13468. * @return True if the group is properly initialized, false otherwise.
  13469. */
  13470. [[nodiscard]] explicit operator bool() const noexcept {
  13471. return descriptor != nullptr;
  13472. }
  13473. /**
  13474. * @brief Checks if a group contains an entity.
  13475. * @param entt A valid identifier.
  13476. * @return True if the group contains the given entity, false otherwise.
  13477. */
  13478. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  13479. return *this && handle().contains(entt) && (handle().index(entt) < (descriptor->length()));
  13480. }
  13481. /**
  13482. * @brief Returns the elements assigned to the given entity.
  13483. * @tparam Type Type of the element to get.
  13484. * @tparam Other Other types of elements to get.
  13485. * @param entt A valid identifier.
  13486. * @return The elements assigned to the entity.
  13487. */
  13488. template<typename Type, typename... Other>
  13489. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  13490. return get<index_of<Type>, index_of<Other>...>(entt);
  13491. }
  13492. /**
  13493. * @brief Returns the elements assigned to the given entity.
  13494. * @tparam Index Indexes of the elements to get.
  13495. * @param entt A valid identifier.
  13496. * @return The elements assigned to the entity.
  13497. */
  13498. template<std::size_t... Index>
  13499. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  13500. const auto cpools = pools_for(std::index_sequence_for<Owned...>{}, std::index_sequence_for<Get...>{});
  13501. if constexpr(sizeof...(Index) == 0) {
  13502. return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools);
  13503. } else if constexpr(sizeof...(Index) == 1) {
  13504. return (std::get<Index>(cpools)->get(entt), ...);
  13505. } else {
  13506. return std::tuple_cat(std::get<Index>(cpools)->get_as_tuple(entt)...);
  13507. }
  13508. }
  13509. /**
  13510. * @brief Iterates entities and elements and applies the given function
  13511. * object to them.
  13512. *
  13513. * The function object is invoked for each entity. It is provided with the
  13514. * entity itself and a set of references to non-empty elements. The
  13515. * _constness_ of the elements is as requested.<br/>
  13516. * The signature of the function must be equivalent to one of the following
  13517. * forms:
  13518. *
  13519. * @code{.cpp}
  13520. * void(const entity_type, Type &...);
  13521. * void(Type &...);
  13522. * @endcode
  13523. *
  13524. * @note
  13525. * Empty types aren't explicitly instantiated and therefore they are never
  13526. * returned during iterations.
  13527. *
  13528. * @tparam Func Type of the function object to invoke.
  13529. * @param func A valid function object.
  13530. */
  13531. template<typename Func>
  13532. void each(Func func) const {
  13533. for(auto args: each()) {
  13534. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  13535. std::apply(func, args);
  13536. } else {
  13537. std::apply([&func](auto, auto &&...less) { func(std::forward<decltype(less)>(less)...); }, args);
  13538. }
  13539. }
  13540. }
  13541. /**
  13542. * @brief Returns an iterable object to use to _visit_ a group.
  13543. *
  13544. * The iterable object returns tuples that contain the current entity and a
  13545. * set of references to its non-empty elements. The _constness_ of the
  13546. * elements is as requested.
  13547. *
  13548. * @note
  13549. * Empty types aren't explicitly instantiated and therefore they are never
  13550. * returned during iterations.
  13551. *
  13552. * @return An iterable object to use to _visit_ the group.
  13553. */
  13554. [[nodiscard]] iterable each() const noexcept {
  13555. const auto cpools = pools_for(std::index_sequence_for<Owned...>{}, std::index_sequence_for<Get...>{});
  13556. return iterable{{begin(), cpools}, {end(), cpools}};
  13557. }
  13558. /**
  13559. * @brief Sort a group according to the given comparison function.
  13560. *
  13561. * The comparison function object must return `true` if the first element
  13562. * is _less_ than the second one, `false` otherwise. The signature of the
  13563. * comparison function should be equivalent to one of the following:
  13564. *
  13565. * @code{.cpp}
  13566. * bool(std::tuple<Type &...>, std::tuple<Type &...>);
  13567. * bool(const Type &, const Type &);
  13568. * bool(const Entity, const Entity);
  13569. * @endcode
  13570. *
  13571. * Where `Type` are either owned types or not but still such that they are
  13572. * iterated by the group.<br/>
  13573. * Moreover, the comparison function object shall induce a
  13574. * _strict weak ordering_ on the values.
  13575. *
  13576. * The sort function object must offer a member function template
  13577. * `operator()` that accepts three arguments:
  13578. *
  13579. * * An iterator to the first element of the range to sort.
  13580. * * An iterator past the last element of the range to sort.
  13581. * * A comparison function to use to compare the elements.
  13582. *
  13583. * @tparam Type Optional type of element to compare.
  13584. * @tparam Other Other optional types of elements to compare.
  13585. * @tparam Compare Type of comparison function object.
  13586. * @tparam Sort Type of sort function object.
  13587. * @tparam Args Types of arguments to forward to the sort function object.
  13588. * @param compare A valid comparison function object.
  13589. * @param algo A valid sort function object.
  13590. * @param args Arguments to forward to the sort function object, if any.
  13591. */
  13592. template<typename Type, typename... Other, typename Compare, typename Sort = std_sort, typename... Args>
  13593. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const {
  13594. sort<index_of<Type>, index_of<Other>...>(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  13595. }
  13596. /**
  13597. * @brief Sort a group according to the given comparison function.
  13598. *
  13599. * @sa sort
  13600. *
  13601. * @tparam Index Optional indexes of elements to compare.
  13602. * @tparam Compare Type of comparison function object.
  13603. * @tparam Sort Type of sort function object.
  13604. * @tparam Args Types of arguments to forward to the sort function object.
  13605. * @param compare A valid comparison function object.
  13606. * @param algo A valid sort function object.
  13607. * @param args Arguments to forward to the sort function object, if any.
  13608. */
  13609. template<std::size_t... Index, typename Compare, typename Sort = std_sort, typename... Args>
  13610. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const {
  13611. const auto cpools = pools_for(std::index_sequence_for<Owned...>{}, std::index_sequence_for<Get...>{});
  13612. if constexpr(sizeof...(Index) == 0) {
  13613. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  13614. storage<0>()->sort_n(descriptor->length(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
  13615. } else {
  13616. auto comp = [&compare, &cpools](const entity_type lhs, const entity_type rhs) {
  13617. if constexpr(sizeof...(Index) == 1) {
  13618. return compare((std::get<Index>(cpools)->get(lhs), ...), (std::get<Index>(cpools)->get(rhs), ...));
  13619. } else {
  13620. return compare(std::forward_as_tuple(std::get<Index>(cpools)->get(lhs)...), std::forward_as_tuple(std::get<Index>(cpools)->get(rhs)...));
  13621. }
  13622. };
  13623. storage<0>()->sort_n(descriptor->length(), std::move(comp), std::move(algo), std::forward<Args>(args)...);
  13624. }
  13625. auto cb = [this](auto *head, auto *...other) {
  13626. for(auto next = descriptor->length(); next; --next) {
  13627. const auto pos = next - 1;
  13628. [[maybe_unused]] const auto entt = head->data()[pos];
  13629. (other->swap_elements(other->data()[pos], entt), ...);
  13630. }
  13631. };
  13632. std::apply(cb, cpools);
  13633. }
  13634. private:
  13635. handler *descriptor;
  13636. };
  13637. } // namespace entt
  13638. #endif
  13639. // #include "entity/handle.hpp"
  13640. #ifndef ENTT_ENTITY_HANDLE_HPP
  13641. #define ENTT_ENTITY_HANDLE_HPP
  13642. #include <iterator>
  13643. #include <tuple>
  13644. #include <type_traits>
  13645. #include <utility>
  13646. // #include "../config/config.h"
  13647. // #include "../core/iterator.hpp"
  13648. // #include "../core/type_traits.hpp"
  13649. // #include "entity.hpp"
  13650. // #include "fwd.hpp"
  13651. namespace entt {
  13652. /*! @cond TURN_OFF_DOXYGEN */
  13653. namespace internal {
  13654. template<typename It>
  13655. class handle_storage_iterator final {
  13656. template<typename Other>
  13657. friend class handle_storage_iterator;
  13658. using underlying_type = std::remove_reference_t<typename It::value_type::second_type>;
  13659. using entity_type = typename underlying_type::entity_type;
  13660. public:
  13661. using value_type = typename std::iterator_traits<It>::value_type;
  13662. using pointer = input_iterator_pointer<value_type>;
  13663. using reference = value_type;
  13664. using difference_type = std::ptrdiff_t;
  13665. using iterator_category = std::input_iterator_tag;
  13666. using iterator_concept = std::forward_iterator_tag;
  13667. constexpr handle_storage_iterator() noexcept
  13668. : entt{null},
  13669. it{},
  13670. last{} {}
  13671. constexpr handle_storage_iterator(entity_type value, It from, It to) noexcept
  13672. : entt{value},
  13673. it{from},
  13674. last{to} {
  13675. while(it != last && !it->second.contains(entt)) {
  13676. ++it;
  13677. }
  13678. }
  13679. constexpr handle_storage_iterator &operator++() noexcept {
  13680. for(++it; it != last && !it->second.contains(entt); ++it) {}
  13681. return *this;
  13682. }
  13683. constexpr handle_storage_iterator operator++(int) noexcept {
  13684. const handle_storage_iterator orig = *this;
  13685. return ++(*this), orig;
  13686. }
  13687. [[nodiscard]] constexpr reference operator*() const noexcept {
  13688. return *it;
  13689. }
  13690. [[nodiscard]] constexpr pointer operator->() const noexcept {
  13691. return operator*();
  13692. }
  13693. template<typename ILhs, typename IRhs>
  13694. friend constexpr bool operator==(const handle_storage_iterator<ILhs> &, const handle_storage_iterator<IRhs> &) noexcept;
  13695. private:
  13696. entity_type entt;
  13697. It it;
  13698. It last;
  13699. };
  13700. template<typename ILhs, typename IRhs>
  13701. [[nodiscard]] constexpr bool operator==(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
  13702. return lhs.it == rhs.it;
  13703. }
  13704. template<typename ILhs, typename IRhs>
  13705. [[nodiscard]] constexpr bool operator!=(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
  13706. return !(lhs == rhs);
  13707. }
  13708. } // namespace internal
  13709. /*! @endcond */
  13710. /**
  13711. * @brief Non-owning handle to an entity.
  13712. *
  13713. * Tiny wrapper around a registry and an entity.
  13714. *
  13715. * @tparam Registry Basic registry type.
  13716. * @tparam Scope Types to which to restrict the scope of a handle.
  13717. */
  13718. template<typename Registry, typename... Scope>
  13719. class basic_handle {
  13720. using traits_type = entt_traits<typename Registry::entity_type>;
  13721. [[nodiscard]] auto &owner_or_assert() const noexcept {
  13722. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  13723. return static_cast<Registry &>(*owner);
  13724. }
  13725. public:
  13726. /*! @brief Type of registry accepted by the handle. */
  13727. using registry_type = Registry;
  13728. /*! @brief Underlying entity identifier. */
  13729. using entity_type = typename traits_type::value_type;
  13730. /*! @brief Underlying version type. */
  13731. using version_type = typename traits_type::version_type;
  13732. /*! @brief Unsigned integer type. */
  13733. using size_type = std::size_t;
  13734. /*! @brief Iterable handle type. */
  13735. using iterable = iterable_adaptor<internal::handle_storage_iterator<typename decltype(std::declval<registry_type>().storage())::iterator>>;
  13736. /*! @brief Constructs an invalid handle. */
  13737. basic_handle() noexcept
  13738. : owner{},
  13739. entt{null} {}
  13740. /**
  13741. * @brief Constructs a handle from a given registry and entity.
  13742. * @param ref An instance of the registry class.
  13743. * @param value A valid identifier.
  13744. */
  13745. basic_handle(registry_type &ref, entity_type value) noexcept
  13746. : owner{&ref},
  13747. entt{value} {}
  13748. /**
  13749. * @brief Returns an iterable object to use to _visit_ a handle.
  13750. *
  13751. * The iterable object returns a pair that contains the name and a reference
  13752. * to the current storage.<br/>
  13753. * Returned storage are those that contain the entity associated with the
  13754. * handle.
  13755. *
  13756. * @return An iterable object to use to _visit_ the handle.
  13757. */
  13758. [[nodiscard]] iterable storage() const noexcept {
  13759. auto underlying = owner_or_assert().storage();
  13760. return iterable{{entt, underlying.begin(), underlying.end()}, {entt, underlying.end(), underlying.end()}};
  13761. }
  13762. /*! @copydoc valid */
  13763. [[nodiscard]] explicit operator bool() const noexcept {
  13764. return owner && owner->valid(entt);
  13765. }
  13766. /**
  13767. * @brief Checks if a handle refers to a valid registry and entity.
  13768. * @return True if the handle refers to a valid registry and entity, false
  13769. * otherwise.
  13770. */
  13771. [[nodiscard]] bool valid() const {
  13772. return static_cast<bool>(*this);
  13773. }
  13774. /**
  13775. * @brief Returns a pointer to the underlying registry, if any.
  13776. * @return A pointer to the underlying registry, if any.
  13777. */
  13778. [[nodiscard]] registry_type *registry() const noexcept {
  13779. return owner;
  13780. }
  13781. /**
  13782. * @brief Returns the entity associated with a handle.
  13783. * @return The entity associated with the handle.
  13784. */
  13785. [[nodiscard]] entity_type entity() const noexcept {
  13786. return entt;
  13787. }
  13788. /*! @copydoc entity */
  13789. [[nodiscard]] operator entity_type() const noexcept {
  13790. return entity();
  13791. }
  13792. /*! @brief Destroys the entity associated with a handle. */
  13793. void destroy() {
  13794. owner_or_assert().destroy(std::exchange(entt, null));
  13795. }
  13796. /**
  13797. * @brief Destroys the entity associated with a handle.
  13798. * @param version A desired version upon destruction.
  13799. */
  13800. void destroy(const version_type version) {
  13801. owner_or_assert().destroy(std::exchange(entt, null), version);
  13802. }
  13803. /**
  13804. * @brief Assigns the given element to a handle.
  13805. * @tparam Type Type of element to create.
  13806. * @tparam Args Types of arguments to use to construct the element.
  13807. * @param args Parameters to use to initialize the element.
  13808. * @return A reference to the newly created element.
  13809. */
  13810. template<typename Type, typename... Args>
  13811. // NOLINTNEXTLINE(modernize-use-nodiscard)
  13812. decltype(auto) emplace(Args &&...args) const {
  13813. static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
  13814. return owner_or_assert().template emplace<Type>(entt, std::forward<Args>(args)...);
  13815. }
  13816. /**
  13817. * @brief Assigns or replaces the given element for a handle.
  13818. * @tparam Type Type of element to assign or replace.
  13819. * @tparam Args Types of arguments to use to construct the element.
  13820. * @param args Parameters to use to initialize the element.
  13821. * @return A reference to the newly created element.
  13822. */
  13823. template<typename Type, typename... Args>
  13824. decltype(auto) emplace_or_replace(Args &&...args) const {
  13825. static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
  13826. return owner_or_assert().template emplace_or_replace<Type>(entt, std::forward<Args>(args)...);
  13827. }
  13828. /**
  13829. * @brief Patches the given element for a handle.
  13830. * @tparam Type Type of element to patch.
  13831. * @tparam Func Types of the function objects to invoke.
  13832. * @param func Valid function objects.
  13833. * @return A reference to the patched element.
  13834. */
  13835. template<typename Type, typename... Func>
  13836. decltype(auto) patch(Func &&...func) const {
  13837. static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
  13838. return owner_or_assert().template patch<Type>(entt, std::forward<Func>(func)...);
  13839. }
  13840. /**
  13841. * @brief Replaces the given element for a handle.
  13842. * @tparam Type Type of element to replace.
  13843. * @tparam Args Types of arguments to use to construct the element.
  13844. * @param args Parameters to use to initialize the element.
  13845. * @return A reference to the element being replaced.
  13846. */
  13847. template<typename Type, typename... Args>
  13848. decltype(auto) replace(Args &&...args) const {
  13849. static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
  13850. return owner_or_assert().template replace<Type>(entt, std::forward<Args>(args)...);
  13851. }
  13852. /**
  13853. * @brief Removes the given elements from a handle.
  13854. * @tparam Type Types of elements to remove.
  13855. * @return The number of elements actually removed.
  13856. */
  13857. template<typename... Type>
  13858. // NOLINTNEXTLINE(modernize-use-nodiscard)
  13859. size_type remove() const {
  13860. static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
  13861. return owner_or_assert().template remove<Type...>(entt);
  13862. }
  13863. /**
  13864. * @brief Erases the given elements from a handle.
  13865. * @tparam Type Types of elements to erase.
  13866. */
  13867. template<typename... Type>
  13868. void erase() const {
  13869. static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
  13870. owner_or_assert().template erase<Type...>(entt);
  13871. }
  13872. /**
  13873. * @brief Checks if a handle has all the given elements.
  13874. * @tparam Type Elements for which to perform the check.
  13875. * @return True if the handle has all the elements, false otherwise.
  13876. */
  13877. template<typename... Type>
  13878. [[nodiscard]] decltype(auto) all_of() const {
  13879. return owner_or_assert().template all_of<Type...>(entt);
  13880. }
  13881. /**
  13882. * @brief Checks if a handle has at least one of the given elements.
  13883. * @tparam Type Elements for which to perform the check.
  13884. * @return True if the handle has at least one of the given elements,
  13885. * false otherwise.
  13886. */
  13887. template<typename... Type>
  13888. [[nodiscard]] decltype(auto) any_of() const {
  13889. return owner_or_assert().template any_of<Type...>(entt);
  13890. }
  13891. /**
  13892. * @brief Returns references to the given elements for a handle.
  13893. * @tparam Type Types of elements to get.
  13894. * @return References to the elements owned by the handle.
  13895. */
  13896. template<typename... Type>
  13897. [[nodiscard]] decltype(auto) get() const {
  13898. static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
  13899. return owner_or_assert().template get<Type...>(entt);
  13900. }
  13901. /**
  13902. * @brief Returns a reference to the given element for a handle.
  13903. * @tparam Type Type of element to get.
  13904. * @tparam Args Types of arguments to use to construct the element.
  13905. * @param args Parameters to use to initialize the element.
  13906. * @return Reference to the element owned by the handle.
  13907. */
  13908. template<typename Type, typename... Args>
  13909. [[nodiscard]] decltype(auto) get_or_emplace(Args &&...args) const {
  13910. static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
  13911. return owner_or_assert().template get_or_emplace<Type>(entt, std::forward<Args>(args)...);
  13912. }
  13913. /**
  13914. * @brief Returns pointers to the given elements for a handle.
  13915. * @tparam Type Types of elements to get.
  13916. * @return Pointers to the elements owned by the handle.
  13917. */
  13918. template<typename... Type>
  13919. [[nodiscard]] auto try_get() const {
  13920. static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
  13921. return owner_or_assert().template try_get<Type...>(entt);
  13922. }
  13923. /**
  13924. * @brief Checks if a handle has elements assigned.
  13925. * @return True if the handle has no elements assigned, false otherwise.
  13926. */
  13927. [[nodiscard]] bool orphan() const {
  13928. return owner_or_assert().orphan(entt);
  13929. }
  13930. /**
  13931. * @brief Returns a const handle from a non-const one.
  13932. * @tparam Other A valid entity type.
  13933. * @tparam Args Scope of the handle to construct.
  13934. * @return A const handle referring to the same registry and the same
  13935. * entity.
  13936. */
  13937. template<typename Other, typename... Args>
  13938. operator basic_handle<Other, Args...>() const noexcept {
  13939. static_assert(std::is_same_v<Other, Registry> || std::is_same_v<std::remove_const_t<Other>, Registry>, "Invalid conversion between different handles");
  13940. static_assert((sizeof...(Scope) == 0 || ((sizeof...(Args) != 0 && sizeof...(Args) <= sizeof...(Scope)) && ... && (type_list_contains_v<type_list<Scope...>, Args>))), "Invalid conversion between different handles");
  13941. return owner ? basic_handle<Other, Args...>{*owner, entt} : basic_handle<Other, Args...>{};
  13942. }
  13943. private:
  13944. registry_type *owner;
  13945. entity_type entt;
  13946. };
  13947. /**
  13948. * @brief Compares two handles.
  13949. * @tparam Args Scope of the first handle.
  13950. * @tparam Other Scope of the second handle.
  13951. * @param lhs A valid handle.
  13952. * @param rhs A valid handle.
  13953. * @return True if both handles refer to the same registry and the same
  13954. * entity, false otherwise.
  13955. */
  13956. template<typename... Args, typename... Other>
  13957. [[nodiscard]] bool operator==(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
  13958. return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
  13959. }
  13960. /**
  13961. * @brief Compares two handles.
  13962. * @tparam Args Scope of the first handle.
  13963. * @tparam Other Scope of the second handle.
  13964. * @param lhs A valid handle.
  13965. * @param rhs A valid handle.
  13966. * @return False if both handles refer to the same registry and the same
  13967. * entity, true otherwise.
  13968. */
  13969. template<typename... Args, typename... Other>
  13970. [[nodiscard]] bool operator!=(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
  13971. return !(lhs == rhs);
  13972. }
  13973. /**
  13974. * @brief Compares a handle with the null object.
  13975. * @tparam Args Scope of the handle.
  13976. * @param lhs A valid handle.
  13977. * @param rhs A null object yet to be converted.
  13978. * @return False if the two elements differ, true otherwise.
  13979. */
  13980. template<typename... Args>
  13981. [[nodiscard]] constexpr bool operator==(const basic_handle<Args...> &lhs, const null_t rhs) noexcept {
  13982. return (lhs.entity() == rhs);
  13983. }
  13984. /**
  13985. * @brief Compares a handle with the null object.
  13986. * @tparam Args Scope of the handle.
  13987. * @param lhs A null object yet to be converted.
  13988. * @param rhs A valid handle.
  13989. * @return False if the two elements differ, true otherwise.
  13990. */
  13991. template<typename... Args>
  13992. [[nodiscard]] constexpr bool operator==(const null_t lhs, const basic_handle<Args...> &rhs) noexcept {
  13993. return (rhs == lhs);
  13994. }
  13995. /**
  13996. * @brief Compares a handle with the null object.
  13997. * @tparam Args Scope of the handle.
  13998. * @param lhs A valid handle.
  13999. * @param rhs A null object yet to be converted.
  14000. * @return True if the two elements differ, false otherwise.
  14001. */
  14002. template<typename... Args>
  14003. [[nodiscard]] constexpr bool operator!=(const basic_handle<Args...> &lhs, const null_t rhs) noexcept {
  14004. return (lhs.entity() != rhs);
  14005. }
  14006. /**
  14007. * @brief Compares a handle with the null object.
  14008. * @tparam Args Scope of the handle.
  14009. * @param lhs A null object yet to be converted.
  14010. * @param rhs A valid handle.
  14011. * @return True if the two elements differ, false otherwise.
  14012. */
  14013. template<typename... Args>
  14014. [[nodiscard]] constexpr bool operator!=(const null_t lhs, const basic_handle<Args...> &rhs) noexcept {
  14015. return (rhs != lhs);
  14016. }
  14017. } // namespace entt
  14018. #endif
  14019. // #include "entity/helper.hpp"
  14020. #ifndef ENTT_ENTITY_HELPER_HPP
  14021. #define ENTT_ENTITY_HELPER_HPP
  14022. #include <memory>
  14023. #include <type_traits>
  14024. #include <utility>
  14025. // #include "../core/fwd.hpp"
  14026. // #include "../core/type_traits.hpp"
  14027. // #include "component.hpp"
  14028. #ifndef ENTT_ENTITY_COMPONENT_HPP
  14029. #define ENTT_ENTITY_COMPONENT_HPP
  14030. #include <cstddef>
  14031. #include <type_traits>
  14032. // #include "../config/config.h"
  14033. // #include "fwd.hpp"
  14034. namespace entt {
  14035. /*! @cond TURN_OFF_DOXYGEN */
  14036. namespace internal {
  14037. template<typename Type, typename = void>
  14038. struct in_place_delete: std::bool_constant<!(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>)> {};
  14039. template<>
  14040. struct in_place_delete<void>: std::false_type {};
  14041. template<typename Type>
  14042. struct in_place_delete<Type, std::enable_if_t<Type::in_place_delete>>
  14043. : std::true_type {};
  14044. template<typename Type, typename = void>
  14045. struct page_size: std::integral_constant<std::size_t, !std::is_empty_v<ENTT_ETO_TYPE(Type)> * ENTT_PACKED_PAGE> {};
  14046. template<>
  14047. struct page_size<void>: std::integral_constant<std::size_t, 0u> {};
  14048. template<typename Type>
  14049. struct page_size<Type, std::void_t<decltype(Type::page_size)>>
  14050. : std::integral_constant<std::size_t, Type::page_size> {};
  14051. } // namespace internal
  14052. /*! @endcond */
  14053. /**
  14054. * @brief Common way to access various properties of components.
  14055. * @tparam Type Element type.
  14056. * @tparam Entity A valid entity type.
  14057. */
  14058. template<typename Type, typename Entity, typename>
  14059. struct component_traits {
  14060. static_assert(std::is_same_v<std::decay_t<Type>, Type>, "Unsupported type");
  14061. /*! @brief Element type. */
  14062. using element_type = Type;
  14063. /*! @brief Underlying entity identifier. */
  14064. using entity_type = Entity;
  14065. /*! @brief Pointer stability, default is `false`. */
  14066. static constexpr bool in_place_delete = internal::in_place_delete<Type>::value;
  14067. /*! @brief Page size, default is `ENTT_PACKED_PAGE` for non-empty types. */
  14068. static constexpr std::size_t page_size = internal::page_size<Type>::value;
  14069. };
  14070. } // namespace entt
  14071. #endif
  14072. // #include "fwd.hpp"
  14073. // #include "group.hpp"
  14074. #ifndef ENTT_ENTITY_GROUP_HPP
  14075. #define ENTT_ENTITY_GROUP_HPP
  14076. #include <array>
  14077. #include <cstddef>
  14078. #include <iterator>
  14079. #include <tuple>
  14080. #include <type_traits>
  14081. #include <utility>
  14082. // #include "../config/config.h"
  14083. // #include "../core/algorithm.hpp"
  14084. // #include "../core/fwd.hpp"
  14085. // #include "../core/iterator.hpp"
  14086. // #include "../core/type_info.hpp"
  14087. // #include "../core/type_traits.hpp"
  14088. // #include "entity.hpp"
  14089. // #include "fwd.hpp"
  14090. namespace entt {
  14091. /*! @cond TURN_OFF_DOXYGEN */
  14092. namespace internal {
  14093. template<typename, typename, typename>
  14094. class extended_group_iterator;
  14095. template<typename It, typename... Owned, typename... Get>
  14096. class extended_group_iterator<It, owned_t<Owned...>, get_t<Get...>> {
  14097. template<typename Type>
  14098. [[nodiscard]] auto index_to_element([[maybe_unused]] Type &cpool) const {
  14099. if constexpr(std::is_void_v<typename Type::value_type>) {
  14100. return std::make_tuple();
  14101. } else {
  14102. return std::forward_as_tuple(cpool.rbegin()[it.index()]);
  14103. }
  14104. }
  14105. public:
  14106. using iterator_type = It;
  14107. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Owned>().get_as_tuple({})..., std::declval<Get>().get_as_tuple({})...));
  14108. using pointer = input_iterator_pointer<value_type>;
  14109. using reference = value_type;
  14110. using difference_type = std::ptrdiff_t;
  14111. using iterator_category = std::input_iterator_tag;
  14112. using iterator_concept = std::forward_iterator_tag;
  14113. constexpr extended_group_iterator()
  14114. : it{},
  14115. pools{} {}
  14116. extended_group_iterator(iterator_type from, std::tuple<Owned *..., Get *...> cpools)
  14117. : it{from},
  14118. pools{std::move(cpools)} {}
  14119. extended_group_iterator &operator++() noexcept {
  14120. return ++it, *this;
  14121. }
  14122. extended_group_iterator operator++(int) noexcept {
  14123. const extended_group_iterator orig = *this;
  14124. return ++(*this), orig;
  14125. }
  14126. [[nodiscard]] reference operator*() const noexcept {
  14127. return std::tuple_cat(std::make_tuple(*it), index_to_element(*std::get<Owned *>(pools))..., std::get<Get *>(pools)->get_as_tuple(*it)...);
  14128. }
  14129. [[nodiscard]] pointer operator->() const noexcept {
  14130. return operator*();
  14131. }
  14132. [[nodiscard]] constexpr iterator_type base() const noexcept {
  14133. return it;
  14134. }
  14135. template<typename... Lhs, typename... Rhs>
  14136. friend constexpr bool operator==(const extended_group_iterator<Lhs...> &, const extended_group_iterator<Rhs...> &) noexcept;
  14137. private:
  14138. It it;
  14139. std::tuple<Owned *..., Get *...> pools;
  14140. };
  14141. template<typename... Lhs, typename... Rhs>
  14142. [[nodiscard]] constexpr bool operator==(const extended_group_iterator<Lhs...> &lhs, const extended_group_iterator<Rhs...> &rhs) noexcept {
  14143. return lhs.it == rhs.it;
  14144. }
  14145. template<typename... Lhs, typename... Rhs>
  14146. [[nodiscard]] constexpr bool operator!=(const extended_group_iterator<Lhs...> &lhs, const extended_group_iterator<Rhs...> &rhs) noexcept {
  14147. return !(lhs == rhs);
  14148. }
  14149. struct group_descriptor {
  14150. using size_type = std::size_t;
  14151. virtual ~group_descriptor() = default;
  14152. [[nodiscard]] virtual bool owned(const id_type) const noexcept {
  14153. return false;
  14154. }
  14155. };
  14156. template<typename Type, std::size_t Owned, std::size_t Get, std::size_t Exclude>
  14157. class group_handler final: public group_descriptor {
  14158. using entity_type = typename Type::entity_type;
  14159. void swap_elements(const std::size_t pos, const entity_type entt) {
  14160. for(size_type next{}; next < Owned; ++next) {
  14161. pools[next]->swap_elements((*pools[next])[pos], entt);
  14162. }
  14163. }
  14164. void push_on_construct(const entity_type entt) {
  14165. if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools)
  14166. && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) {
  14167. swap_elements(len++, entt);
  14168. }
  14169. }
  14170. void push_on_destroy(const entity_type entt) {
  14171. if(std::apply([entt, pos = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < pos) && (other->contains(entt) && ...); }, pools)
  14172. && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) {
  14173. swap_elements(len++, entt);
  14174. }
  14175. }
  14176. void remove_if(const entity_type entt) {
  14177. if(pools[0u]->contains(entt) && (pools[0u]->index(entt) < len)) {
  14178. swap_elements(--len, entt);
  14179. }
  14180. }
  14181. void common_setup() {
  14182. // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
  14183. for(auto first = pools[0u]->rbegin(), last = first + static_cast<typename decltype(pools)::difference_type>(pools[0u]->size()); first != last; ++first) {
  14184. push_on_construct(*first);
  14185. }
  14186. }
  14187. public:
  14188. using common_type = Type;
  14189. using size_type = typename Type::size_type;
  14190. template<typename... OGType, typename... EType>
  14191. group_handler(std::tuple<OGType &...> ogpool, std::tuple<EType &...> epool)
  14192. : pools{std::apply([](auto &&...cpool) { return std::array<common_type *, (Owned + Get)>{&cpool...}; }, ogpool)},
  14193. filter{std::apply([](auto &&...cpool) { return std::array<common_type *, Exclude>{&cpool...}; }, epool)} {
  14194. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, ogpool);
  14195. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool);
  14196. common_setup();
  14197. }
  14198. [[nodiscard]] bool owned(const id_type hash) const noexcept override {
  14199. for(size_type pos{}; pos < Owned; ++pos) {
  14200. if(pools[pos]->info().hash() == hash) {
  14201. return true;
  14202. }
  14203. }
  14204. return false;
  14205. }
  14206. [[nodiscard]] size_type length() const noexcept {
  14207. return len;
  14208. }
  14209. template<std::size_t Index>
  14210. [[nodiscard]] common_type *storage() const noexcept {
  14211. if constexpr(Index < (Owned + Get)) {
  14212. return pools[Index];
  14213. } else {
  14214. return filter[Index - (Owned + Get)];
  14215. }
  14216. }
  14217. private:
  14218. std::array<common_type *, (Owned + Get)> pools;
  14219. std::array<common_type *, Exclude> filter;
  14220. std::size_t len{};
  14221. };
  14222. template<typename Type, std::size_t Get, std::size_t Exclude>
  14223. class group_handler<Type, 0u, Get, Exclude> final: public group_descriptor {
  14224. using entity_type = typename Type::entity_type;
  14225. void push_on_construct(const entity_type entt) {
  14226. if(!elem.contains(entt)
  14227. && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools)
  14228. && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) {
  14229. elem.push(entt);
  14230. }
  14231. }
  14232. void push_on_destroy(const entity_type entt) {
  14233. if(!elem.contains(entt)
  14234. && std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools)
  14235. && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) {
  14236. elem.push(entt);
  14237. }
  14238. }
  14239. void remove_if(const entity_type entt) {
  14240. elem.remove(entt);
  14241. }
  14242. void common_setup() {
  14243. for(const auto entity: *pools[0u]) {
  14244. push_on_construct(entity);
  14245. }
  14246. }
  14247. public:
  14248. using common_type = Type;
  14249. template<typename Allocator, typename... GType, typename... EType>
  14250. group_handler(const Allocator &allocator, std::tuple<GType &...> gpool, std::tuple<EType &...> epool)
  14251. : pools{std::apply([](auto &&...cpool) { return std::array<common_type *, Get>{&cpool...}; }, gpool)},
  14252. filter{std::apply([](auto &&...cpool) { return std::array<common_type *, Exclude>{&cpool...}; }, epool)},
  14253. elem{allocator} {
  14254. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::push_on_construct>(*this), cpool.on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, gpool);
  14255. std::apply([this](auto &...cpool) { ((cpool.on_construct().template connect<&group_handler::remove_if>(*this), cpool.on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, epool);
  14256. common_setup();
  14257. }
  14258. [[nodiscard]] common_type &handle() noexcept {
  14259. return elem;
  14260. }
  14261. [[nodiscard]] const common_type &handle() const noexcept {
  14262. return elem;
  14263. }
  14264. template<std::size_t Index>
  14265. [[nodiscard]] common_type *storage() const noexcept {
  14266. if constexpr(Index < Get) {
  14267. return pools[Index];
  14268. } else {
  14269. return filter[Index - Get];
  14270. }
  14271. }
  14272. private:
  14273. std::array<common_type *, Get> pools;
  14274. std::array<common_type *, Exclude> filter;
  14275. common_type elem;
  14276. };
  14277. } // namespace internal
  14278. /*! @endcond */
  14279. /**
  14280. * @brief Group.
  14281. *
  14282. * Primary template isn't defined on purpose. All the specializations give a
  14283. * compile-time error, but for a few reasonable cases.
  14284. */
  14285. template<typename, typename, typename>
  14286. class basic_group;
  14287. /**
  14288. * @brief Non-owning group.
  14289. *
  14290. * A non-owning group returns all entities and only the entities that are at
  14291. * least in the given storage. Moreover, it's guaranteed that the entity list is
  14292. * tightly packed in memory for fast iterations.
  14293. *
  14294. * @b Important
  14295. *
  14296. * Iterators aren't invalidated if:
  14297. *
  14298. * * New elements are added to the storage.
  14299. * * The entity currently pointed is modified (for example, elements are added
  14300. * or removed from it).
  14301. * * The entity currently pointed is destroyed.
  14302. *
  14303. * In all other cases, modifying the pools iterated by the group in any way
  14304. * invalidates all the iterators.
  14305. *
  14306. * @tparam Get Types of storage _observed_ by the group.
  14307. * @tparam Exclude Types of storage used to filter the group.
  14308. */
  14309. template<typename... Get, typename... Exclude>
  14310. class basic_group<owned_t<>, get_t<Get...>, exclude_t<Exclude...>> {
  14311. using base_type = std::common_type_t<typename Get::base_type..., typename Exclude::base_type...>;
  14312. using underlying_type = typename base_type::entity_type;
  14313. template<typename Type>
  14314. static constexpr std::size_t index_of = type_list_index_v<std::remove_const_t<Type>, type_list<typename Get::element_type..., typename Exclude::element_type...>>;
  14315. template<std::size_t... Index>
  14316. [[nodiscard]] auto pools_for(std::index_sequence<Index...>) const noexcept {
  14317. using return_type = std::tuple<Get *...>;
  14318. return descriptor ? return_type{static_cast<Get *>(descriptor->template storage<Index>())...} : return_type{};
  14319. }
  14320. public:
  14321. /*! @brief Underlying entity identifier. */
  14322. using entity_type = underlying_type;
  14323. /*! @brief Unsigned integer type. */
  14324. using size_type = std::size_t;
  14325. /*! @brief Signed integer type. */
  14326. using difference_type = std::ptrdiff_t;
  14327. /*! @brief Common type among all storage types. */
  14328. using common_type = base_type;
  14329. /*! @brief Random access iterator type. */
  14330. using iterator = typename common_type::iterator;
  14331. /*! @brief Reverse iterator type. */
  14332. using reverse_iterator = typename common_type::reverse_iterator;
  14333. /*! @brief Iterable group type. */
  14334. using iterable = iterable_adaptor<internal::extended_group_iterator<iterator, owned_t<>, get_t<Get...>>>;
  14335. /*! @brief Group handler type. */
  14336. using handler = internal::group_handler<common_type, 0u, sizeof...(Get), sizeof...(Exclude)>;
  14337. /**
  14338. * @brief Group opaque identifier.
  14339. * @return Group opaque identifier.
  14340. */
  14341. static id_type group_id() noexcept {
  14342. return type_hash<basic_group<owned_t<>, get_t<std::remove_const_t<Get>...>, exclude_t<std::remove_const_t<Exclude>...>>>::value();
  14343. }
  14344. /*! @brief Default constructor to use to create empty, invalid groups. */
  14345. basic_group() noexcept
  14346. : descriptor{} {}
  14347. /**
  14348. * @brief Constructs a group from a set of storage classes.
  14349. * @param ref A reference to a group handler.
  14350. */
  14351. basic_group(handler &ref) noexcept
  14352. : descriptor{&ref} {}
  14353. /**
  14354. * @brief Returns the leading storage of a group.
  14355. * @return The leading storage of the group.
  14356. */
  14357. [[nodiscard]] const common_type &handle() const noexcept {
  14358. return descriptor->handle();
  14359. }
  14360. /**
  14361. * @brief Returns the storage for a given element type, if any.
  14362. * @tparam Type Type of element of which to return the storage.
  14363. * @return The storage for the given element type.
  14364. */
  14365. template<typename Type>
  14366. [[nodiscard]] auto *storage() const noexcept {
  14367. return storage<index_of<Type>>();
  14368. }
  14369. /**
  14370. * @brief Returns the storage for a given index, if any.
  14371. * @tparam Index Index of the storage to return.
  14372. * @return The storage for the given index.
  14373. */
  14374. template<std::size_t Index>
  14375. [[nodiscard]] auto *storage() const noexcept {
  14376. using type = type_list_element_t<Index, type_list<Get..., Exclude...>>;
  14377. return *this ? static_cast<type *>(descriptor->template storage<Index>()) : nullptr;
  14378. }
  14379. /**
  14380. * @brief Returns the number of entities that are part of the group.
  14381. * @return Number of entities that are part of the group.
  14382. */
  14383. [[nodiscard]] size_type size() const noexcept {
  14384. return *this ? handle().size() : size_type{};
  14385. }
  14386. /**
  14387. * @brief Returns the number of elements that a group has currently
  14388. * allocated space for.
  14389. * @return Capacity of the group.
  14390. */
  14391. [[nodiscard]] size_type capacity() const noexcept {
  14392. return *this ? handle().capacity() : size_type{};
  14393. }
  14394. /*! @brief Requests the removal of unused capacity. */
  14395. void shrink_to_fit() {
  14396. if(*this) {
  14397. descriptor->handle().shrink_to_fit();
  14398. }
  14399. }
  14400. /**
  14401. * @brief Checks whether a group is empty.
  14402. * @return True if the group is empty, false otherwise.
  14403. */
  14404. [[nodiscard]] bool empty() const noexcept {
  14405. return !*this || handle().empty();
  14406. }
  14407. /**
  14408. * @brief Returns an iterator to the first entity of the group.
  14409. *
  14410. * If the group is empty, the returned iterator will be equal to `end()`.
  14411. *
  14412. * @return An iterator to the first entity of the group.
  14413. */
  14414. [[nodiscard]] iterator begin() const noexcept {
  14415. return *this ? handle().begin() : iterator{};
  14416. }
  14417. /**
  14418. * @brief Returns an iterator that is past the last entity of the group.
  14419. * @return An iterator to the entity following the last entity of the
  14420. * group.
  14421. */
  14422. [[nodiscard]] iterator end() const noexcept {
  14423. return *this ? handle().end() : iterator{};
  14424. }
  14425. /**
  14426. * @brief Returns an iterator to the first entity of the reversed group.
  14427. *
  14428. * If the group is empty, the returned iterator will be equal to `rend()`.
  14429. *
  14430. * @return An iterator to the first entity of the reversed group.
  14431. */
  14432. [[nodiscard]] reverse_iterator rbegin() const noexcept {
  14433. return *this ? handle().rbegin() : reverse_iterator{};
  14434. }
  14435. /**
  14436. * @brief Returns an iterator that is past the last entity of the reversed
  14437. * group.
  14438. * @return An iterator to the entity following the last entity of the
  14439. * reversed group.
  14440. */
  14441. [[nodiscard]] reverse_iterator rend() const noexcept {
  14442. return *this ? handle().rend() : reverse_iterator{};
  14443. }
  14444. /**
  14445. * @brief Returns the first entity of the group, if any.
  14446. * @return The first entity of the group if one exists, the null entity
  14447. * otherwise.
  14448. */
  14449. [[nodiscard]] entity_type front() const noexcept {
  14450. const auto it = begin();
  14451. return it != end() ? *it : null;
  14452. }
  14453. /**
  14454. * @brief Returns the last entity of the group, if any.
  14455. * @return The last entity of the group if one exists, the null entity
  14456. * otherwise.
  14457. */
  14458. [[nodiscard]] entity_type back() const noexcept {
  14459. const auto it = rbegin();
  14460. return it != rend() ? *it : null;
  14461. }
  14462. /**
  14463. * @brief Finds an entity.
  14464. * @param entt A valid identifier.
  14465. * @return An iterator to the given entity if it's found, past the end
  14466. * iterator otherwise.
  14467. */
  14468. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  14469. return *this ? handle().find(entt) : iterator{};
  14470. }
  14471. /**
  14472. * @brief Returns the identifier that occupies the given position.
  14473. * @param pos Position of the element to return.
  14474. * @return The identifier that occupies the given position.
  14475. */
  14476. [[nodiscard]] entity_type operator[](const size_type pos) const {
  14477. return begin()[static_cast<difference_type>(pos)];
  14478. }
  14479. /**
  14480. * @brief Checks if a group is properly initialized.
  14481. * @return True if the group is properly initialized, false otherwise.
  14482. */
  14483. [[nodiscard]] explicit operator bool() const noexcept {
  14484. return descriptor != nullptr;
  14485. }
  14486. /**
  14487. * @brief Checks if a group contains an entity.
  14488. * @param entt A valid identifier.
  14489. * @return True if the group contains the given entity, false otherwise.
  14490. */
  14491. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  14492. return *this && handle().contains(entt);
  14493. }
  14494. /**
  14495. * @brief Returns the elements assigned to the given entity.
  14496. * @tparam Type Type of the element to get.
  14497. * @tparam Other Other types of elements to get.
  14498. * @param entt A valid identifier.
  14499. * @return The elements assigned to the entity.
  14500. */
  14501. template<typename Type, typename... Other>
  14502. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  14503. return get<index_of<Type>, index_of<Other>...>(entt);
  14504. }
  14505. /**
  14506. * @brief Returns the elements assigned to the given entity.
  14507. * @tparam Index Indexes of the elements to get.
  14508. * @param entt A valid identifier.
  14509. * @return The elements assigned to the entity.
  14510. */
  14511. template<std::size_t... Index>
  14512. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  14513. const auto cpools = pools_for(std::index_sequence_for<Get...>{});
  14514. if constexpr(sizeof...(Index) == 0) {
  14515. return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools);
  14516. } else if constexpr(sizeof...(Index) == 1) {
  14517. return (std::get<Index>(cpools)->get(entt), ...);
  14518. } else {
  14519. return std::tuple_cat(std::get<Index>(cpools)->get_as_tuple(entt)...);
  14520. }
  14521. }
  14522. /**
  14523. * @brief Iterates entities and elements and applies the given function
  14524. * object to them.
  14525. *
  14526. * The function object is invoked for each entity. It is provided with the
  14527. * entity itself and a set of references to non-empty elements. The
  14528. * _constness_ of the elements is as requested.<br/>
  14529. * The signature of the function must be equivalent to one of the following
  14530. * forms:
  14531. *
  14532. * @code{.cpp}
  14533. * void(const entity_type, Type &...);
  14534. * void(Type &...);
  14535. * @endcode
  14536. *
  14537. * @note
  14538. * Empty types aren't explicitly instantiated and therefore they are never
  14539. * returned during iterations.
  14540. *
  14541. * @tparam Func Type of the function object to invoke.
  14542. * @param func A valid function object.
  14543. */
  14544. template<typename Func>
  14545. void each(Func func) const {
  14546. for(const auto entt: *this) {
  14547. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  14548. std::apply(func, std::tuple_cat(std::make_tuple(entt), get(entt)));
  14549. } else {
  14550. std::apply(func, get(entt));
  14551. }
  14552. }
  14553. }
  14554. /**
  14555. * @brief Returns an iterable object to use to _visit_ a group.
  14556. *
  14557. * The iterable object returns tuples that contain the current entity and a
  14558. * set of references to its non-empty elements. The _constness_ of the
  14559. * elements is as requested.
  14560. *
  14561. * @note
  14562. * Empty types aren't explicitly instantiated and therefore they are never
  14563. * returned during iterations.
  14564. *
  14565. * @return An iterable object to use to _visit_ the group.
  14566. */
  14567. [[nodiscard]] iterable each() const noexcept {
  14568. const auto cpools = pools_for(std::index_sequence_for<Get...>{});
  14569. return iterable{{begin(), cpools}, {end(), cpools}};
  14570. }
  14571. /**
  14572. * @brief Sort a group according to the given comparison function.
  14573. *
  14574. * The comparison function object must return `true` if the first element
  14575. * is _less_ than the second one, `false` otherwise. The signature of the
  14576. * comparison function should be equivalent to one of the following:
  14577. *
  14578. * @code{.cpp}
  14579. * bool(std::tuple<Type &...>, std::tuple<Type &...>);
  14580. * bool(const Type &..., const Type &...);
  14581. * bool(const Entity, const Entity);
  14582. * @endcode
  14583. *
  14584. * Where `Type` are such that they are iterated by the group.<br/>
  14585. * Moreover, the comparison function object shall induce a
  14586. * _strict weak ordering_ on the values.
  14587. *
  14588. * The sort function object must offer a member function template
  14589. * `operator()` that accepts three arguments:
  14590. *
  14591. * * An iterator to the first element of the range to sort.
  14592. * * An iterator past the last element of the range to sort.
  14593. * * A comparison function to use to compare the elements.
  14594. *
  14595. * @tparam Type Optional type of element to compare.
  14596. * @tparam Other Other optional types of elements to compare.
  14597. * @tparam Compare Type of comparison function object.
  14598. * @tparam Sort Type of sort function object.
  14599. * @tparam Args Types of arguments to forward to the sort function object.
  14600. * @param compare A valid comparison function object.
  14601. * @param algo A valid sort function object.
  14602. * @param args Arguments to forward to the sort function object, if any.
  14603. */
  14604. template<typename Type, typename... Other, typename Compare, typename Sort = std_sort, typename... Args>
  14605. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  14606. sort<index_of<Type>, index_of<Other>...>(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  14607. }
  14608. /**
  14609. * @brief Sort a group according to the given comparison function.
  14610. *
  14611. * @sa sort
  14612. *
  14613. * @tparam Index Optional indexes of elements to compare.
  14614. * @tparam Compare Type of comparison function object.
  14615. * @tparam Sort Type of sort function object.
  14616. * @tparam Args Types of arguments to forward to the sort function object.
  14617. * @param compare A valid comparison function object.
  14618. * @param algo A valid sort function object.
  14619. * @param args Arguments to forward to the sort function object, if any.
  14620. */
  14621. template<std::size_t... Index, typename Compare, typename Sort = std_sort, typename... Args>
  14622. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  14623. if(*this) {
  14624. if constexpr(sizeof...(Index) == 0) {
  14625. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  14626. descriptor->handle().sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  14627. } else {
  14628. auto comp = [&compare, cpools = pools_for(std::index_sequence_for<Get...>{})](const entity_type lhs, const entity_type rhs) {
  14629. if constexpr(sizeof...(Index) == 1) {
  14630. return compare((std::get<Index>(cpools)->get(lhs), ...), (std::get<Index>(cpools)->get(rhs), ...));
  14631. } else {
  14632. return compare(std::forward_as_tuple(std::get<Index>(cpools)->get(lhs)...), std::forward_as_tuple(std::get<Index>(cpools)->get(rhs)...));
  14633. }
  14634. };
  14635. descriptor->handle().sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
  14636. }
  14637. }
  14638. }
  14639. /**
  14640. * @brief Sort entities according to their order in a range.
  14641. *
  14642. * The shared pool of entities and thus its order is affected by the changes
  14643. * to each and every pool that it tracks.
  14644. *
  14645. * @tparam It Type of input iterator.
  14646. * @param first An iterator to the first element of the range of entities.
  14647. * @param last An iterator past the last element of the range of entities.
  14648. */
  14649. template<typename It>
  14650. void sort_as(It first, It last) const {
  14651. if(*this) {
  14652. descriptor->handle().sort_as(first, last);
  14653. }
  14654. }
  14655. private:
  14656. handler *descriptor;
  14657. };
  14658. /**
  14659. * @brief Owning group.
  14660. *
  14661. * Owning groups returns all entities and only the entities that are at
  14662. * least in the given storage. Moreover:
  14663. *
  14664. * * It's guaranteed that the entity list is tightly packed in memory for fast
  14665. * iterations.
  14666. * * It's guaranteed that all elements in the owned storage are tightly packed
  14667. * in memory for even faster iterations and to allow direct access.
  14668. * * They stay true to the order of the owned storage and all instances have the
  14669. * same order in memory.
  14670. *
  14671. * The more types of storage are owned, the faster it is to iterate a group.
  14672. *
  14673. * @b Important
  14674. *
  14675. * Iterators aren't invalidated if:
  14676. *
  14677. * * New elements are added to the storage.
  14678. * * The entity currently pointed is modified (for example, elements are added
  14679. * or removed from it).
  14680. * * The entity currently pointed is destroyed.
  14681. *
  14682. * In all other cases, modifying the pools iterated by the group in any way
  14683. * invalidates all the iterators.
  14684. *
  14685. * @tparam Owned Types of storage _owned_ by the group.
  14686. * @tparam Get Types of storage _observed_ by the group.
  14687. * @tparam Exclude Types of storage used to filter the group.
  14688. */
  14689. template<typename... Owned, typename... Get, typename... Exclude>
  14690. class basic_group<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> {
  14691. static_assert(((Owned::storage_policy != deletion_policy::in_place) && ...), "Groups do not support in-place delete");
  14692. using base_type = std::common_type_t<typename Owned::base_type..., typename Get::base_type..., typename Exclude::base_type...>;
  14693. using underlying_type = typename base_type::entity_type;
  14694. template<typename Type>
  14695. static constexpr std::size_t index_of = type_list_index_v<std::remove_const_t<Type>, type_list<typename Owned::element_type..., typename Get::element_type..., typename Exclude::element_type...>>;
  14696. template<std::size_t... Index, std::size_t... Other>
  14697. [[nodiscard]] auto pools_for(std::index_sequence<Index...>, std::index_sequence<Other...>) const noexcept {
  14698. using return_type = std::tuple<Owned *..., Get *...>;
  14699. return descriptor ? return_type{static_cast<Owned *>(descriptor->template storage<Index>())..., static_cast<Get *>(descriptor->template storage<sizeof...(Owned) + Other>())...} : return_type{};
  14700. }
  14701. public:
  14702. /*! @brief Underlying entity identifier. */
  14703. using entity_type = underlying_type;
  14704. /*! @brief Unsigned integer type. */
  14705. using size_type = std::size_t;
  14706. /*! @brief Signed integer type. */
  14707. using difference_type = std::ptrdiff_t;
  14708. /*! @brief Common type among all storage types. */
  14709. using common_type = base_type;
  14710. /*! @brief Random access iterator type. */
  14711. using iterator = typename common_type::iterator;
  14712. /*! @brief Reverse iterator type. */
  14713. using reverse_iterator = typename common_type::reverse_iterator;
  14714. /*! @brief Iterable group type. */
  14715. using iterable = iterable_adaptor<internal::extended_group_iterator<iterator, owned_t<Owned...>, get_t<Get...>>>;
  14716. /*! @brief Group handler type. */
  14717. using handler = internal::group_handler<common_type, sizeof...(Owned), sizeof...(Get), sizeof...(Exclude)>;
  14718. /**
  14719. * @brief Group opaque identifier.
  14720. * @return Group opaque identifier.
  14721. */
  14722. static id_type group_id() noexcept {
  14723. return type_hash<basic_group<owned_t<std::remove_const_t<Owned>...>, get_t<std::remove_const_t<Get>...>, exclude_t<std::remove_const_t<Exclude>...>>>::value();
  14724. }
  14725. /*! @brief Default constructor to use to create empty, invalid groups. */
  14726. basic_group() noexcept
  14727. : descriptor{} {}
  14728. /**
  14729. * @brief Constructs a group from a set of storage classes.
  14730. * @param ref A reference to a group handler.
  14731. */
  14732. basic_group(handler &ref) noexcept
  14733. : descriptor{&ref} {}
  14734. /**
  14735. * @brief Returns the leading storage of a group.
  14736. * @return The leading storage of the group.
  14737. */
  14738. [[nodiscard]] const common_type &handle() const noexcept {
  14739. return *storage<0>();
  14740. }
  14741. /**
  14742. * @brief Returns the storage for a given element type, if any.
  14743. * @tparam Type Type of element of which to return the storage.
  14744. * @return The storage for the given element type.
  14745. */
  14746. template<typename Type>
  14747. [[nodiscard]] auto *storage() const noexcept {
  14748. return storage<index_of<Type>>();
  14749. }
  14750. /**
  14751. * @brief Returns the storage for a given index, if any.
  14752. * @tparam Index Index of the storage to return.
  14753. * @return The storage for the given index.
  14754. */
  14755. template<std::size_t Index>
  14756. [[nodiscard]] auto *storage() const noexcept {
  14757. using type = type_list_element_t<Index, type_list<Owned..., Get..., Exclude...>>;
  14758. return *this ? static_cast<type *>(descriptor->template storage<Index>()) : nullptr;
  14759. }
  14760. /**
  14761. * @brief Returns the number of entities that that are part of the group.
  14762. * @return Number of entities that that are part of the group.
  14763. */
  14764. [[nodiscard]] size_type size() const noexcept {
  14765. return *this ? descriptor->length() : size_type{};
  14766. }
  14767. /**
  14768. * @brief Checks whether a group is empty.
  14769. * @return True if the group is empty, false otherwise.
  14770. */
  14771. [[nodiscard]] bool empty() const noexcept {
  14772. return !*this || !descriptor->length();
  14773. }
  14774. /**
  14775. * @brief Returns an iterator to the first entity of the group.
  14776. *
  14777. * If the group is empty, the returned iterator will be equal to `end()`.
  14778. *
  14779. * @return An iterator to the first entity of the group.
  14780. */
  14781. [[nodiscard]] iterator begin() const noexcept {
  14782. return *this ? (handle().end() - static_cast<difference_type>(descriptor->length())) : iterator{};
  14783. }
  14784. /**
  14785. * @brief Returns an iterator that is past the last entity of the group.
  14786. * @return An iterator to the entity following the last entity of the
  14787. * group.
  14788. */
  14789. [[nodiscard]] iterator end() const noexcept {
  14790. return *this ? handle().end() : iterator{};
  14791. }
  14792. /**
  14793. * @brief Returns an iterator to the first entity of the reversed group.
  14794. *
  14795. * If the group is empty, the returned iterator will be equal to `rend()`.
  14796. *
  14797. * @return An iterator to the first entity of the reversed group.
  14798. */
  14799. [[nodiscard]] reverse_iterator rbegin() const noexcept {
  14800. return *this ? handle().rbegin() : reverse_iterator{};
  14801. }
  14802. /**
  14803. * @brief Returns an iterator that is past the last entity of the reversed
  14804. * group.
  14805. * @return An iterator to the entity following the last entity of the
  14806. * reversed group.
  14807. */
  14808. [[nodiscard]] reverse_iterator rend() const noexcept {
  14809. return *this ? (handle().rbegin() + static_cast<difference_type>(descriptor->length())) : reverse_iterator{};
  14810. }
  14811. /**
  14812. * @brief Returns the first entity of the group, if any.
  14813. * @return The first entity of the group if one exists, the null entity
  14814. * otherwise.
  14815. */
  14816. [[nodiscard]] entity_type front() const noexcept {
  14817. const auto it = begin();
  14818. return it != end() ? *it : null;
  14819. }
  14820. /**
  14821. * @brief Returns the last entity of the group, if any.
  14822. * @return The last entity of the group if one exists, the null entity
  14823. * otherwise.
  14824. */
  14825. [[nodiscard]] entity_type back() const noexcept {
  14826. const auto it = rbegin();
  14827. return it != rend() ? *it : null;
  14828. }
  14829. /**
  14830. * @brief Finds an entity.
  14831. * @param entt A valid identifier.
  14832. * @return An iterator to the given entity if it's found, past the end
  14833. * iterator otherwise.
  14834. */
  14835. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  14836. const auto it = *this ? handle().find(entt) : iterator{};
  14837. return it >= begin() ? it : iterator{};
  14838. }
  14839. /**
  14840. * @brief Returns the identifier that occupies the given position.
  14841. * @param pos Position of the element to return.
  14842. * @return The identifier that occupies the given position.
  14843. */
  14844. [[nodiscard]] entity_type operator[](const size_type pos) const {
  14845. return begin()[static_cast<difference_type>(pos)];
  14846. }
  14847. /**
  14848. * @brief Checks if a group is properly initialized.
  14849. * @return True if the group is properly initialized, false otherwise.
  14850. */
  14851. [[nodiscard]] explicit operator bool() const noexcept {
  14852. return descriptor != nullptr;
  14853. }
  14854. /**
  14855. * @brief Checks if a group contains an entity.
  14856. * @param entt A valid identifier.
  14857. * @return True if the group contains the given entity, false otherwise.
  14858. */
  14859. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  14860. return *this && handle().contains(entt) && (handle().index(entt) < (descriptor->length()));
  14861. }
  14862. /**
  14863. * @brief Returns the elements assigned to the given entity.
  14864. * @tparam Type Type of the element to get.
  14865. * @tparam Other Other types of elements to get.
  14866. * @param entt A valid identifier.
  14867. * @return The elements assigned to the entity.
  14868. */
  14869. template<typename Type, typename... Other>
  14870. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  14871. return get<index_of<Type>, index_of<Other>...>(entt);
  14872. }
  14873. /**
  14874. * @brief Returns the elements assigned to the given entity.
  14875. * @tparam Index Indexes of the elements to get.
  14876. * @param entt A valid identifier.
  14877. * @return The elements assigned to the entity.
  14878. */
  14879. template<std::size_t... Index>
  14880. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  14881. const auto cpools = pools_for(std::index_sequence_for<Owned...>{}, std::index_sequence_for<Get...>{});
  14882. if constexpr(sizeof...(Index) == 0) {
  14883. return std::apply([entt](auto *...curr) { return std::tuple_cat(curr->get_as_tuple(entt)...); }, cpools);
  14884. } else if constexpr(sizeof...(Index) == 1) {
  14885. return (std::get<Index>(cpools)->get(entt), ...);
  14886. } else {
  14887. return std::tuple_cat(std::get<Index>(cpools)->get_as_tuple(entt)...);
  14888. }
  14889. }
  14890. /**
  14891. * @brief Iterates entities and elements and applies the given function
  14892. * object to them.
  14893. *
  14894. * The function object is invoked for each entity. It is provided with the
  14895. * entity itself and a set of references to non-empty elements. The
  14896. * _constness_ of the elements is as requested.<br/>
  14897. * The signature of the function must be equivalent to one of the following
  14898. * forms:
  14899. *
  14900. * @code{.cpp}
  14901. * void(const entity_type, Type &...);
  14902. * void(Type &...);
  14903. * @endcode
  14904. *
  14905. * @note
  14906. * Empty types aren't explicitly instantiated and therefore they are never
  14907. * returned during iterations.
  14908. *
  14909. * @tparam Func Type of the function object to invoke.
  14910. * @param func A valid function object.
  14911. */
  14912. template<typename Func>
  14913. void each(Func func) const {
  14914. for(auto args: each()) {
  14915. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_group>().get({})))>) {
  14916. std::apply(func, args);
  14917. } else {
  14918. std::apply([&func](auto, auto &&...less) { func(std::forward<decltype(less)>(less)...); }, args);
  14919. }
  14920. }
  14921. }
  14922. /**
  14923. * @brief Returns an iterable object to use to _visit_ a group.
  14924. *
  14925. * The iterable object returns tuples that contain the current entity and a
  14926. * set of references to its non-empty elements. The _constness_ of the
  14927. * elements is as requested.
  14928. *
  14929. * @note
  14930. * Empty types aren't explicitly instantiated and therefore they are never
  14931. * returned during iterations.
  14932. *
  14933. * @return An iterable object to use to _visit_ the group.
  14934. */
  14935. [[nodiscard]] iterable each() const noexcept {
  14936. const auto cpools = pools_for(std::index_sequence_for<Owned...>{}, std::index_sequence_for<Get...>{});
  14937. return iterable{{begin(), cpools}, {end(), cpools}};
  14938. }
  14939. /**
  14940. * @brief Sort a group according to the given comparison function.
  14941. *
  14942. * The comparison function object must return `true` if the first element
  14943. * is _less_ than the second one, `false` otherwise. The signature of the
  14944. * comparison function should be equivalent to one of the following:
  14945. *
  14946. * @code{.cpp}
  14947. * bool(std::tuple<Type &...>, std::tuple<Type &...>);
  14948. * bool(const Type &, const Type &);
  14949. * bool(const Entity, const Entity);
  14950. * @endcode
  14951. *
  14952. * Where `Type` are either owned types or not but still such that they are
  14953. * iterated by the group.<br/>
  14954. * Moreover, the comparison function object shall induce a
  14955. * _strict weak ordering_ on the values.
  14956. *
  14957. * The sort function object must offer a member function template
  14958. * `operator()` that accepts three arguments:
  14959. *
  14960. * * An iterator to the first element of the range to sort.
  14961. * * An iterator past the last element of the range to sort.
  14962. * * A comparison function to use to compare the elements.
  14963. *
  14964. * @tparam Type Optional type of element to compare.
  14965. * @tparam Other Other optional types of elements to compare.
  14966. * @tparam Compare Type of comparison function object.
  14967. * @tparam Sort Type of sort function object.
  14968. * @tparam Args Types of arguments to forward to the sort function object.
  14969. * @param compare A valid comparison function object.
  14970. * @param algo A valid sort function object.
  14971. * @param args Arguments to forward to the sort function object, if any.
  14972. */
  14973. template<typename Type, typename... Other, typename Compare, typename Sort = std_sort, typename... Args>
  14974. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const {
  14975. sort<index_of<Type>, index_of<Other>...>(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  14976. }
  14977. /**
  14978. * @brief Sort a group according to the given comparison function.
  14979. *
  14980. * @sa sort
  14981. *
  14982. * @tparam Index Optional indexes of elements to compare.
  14983. * @tparam Compare Type of comparison function object.
  14984. * @tparam Sort Type of sort function object.
  14985. * @tparam Args Types of arguments to forward to the sort function object.
  14986. * @param compare A valid comparison function object.
  14987. * @param algo A valid sort function object.
  14988. * @param args Arguments to forward to the sort function object, if any.
  14989. */
  14990. template<std::size_t... Index, typename Compare, typename Sort = std_sort, typename... Args>
  14991. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) const {
  14992. const auto cpools = pools_for(std::index_sequence_for<Owned...>{}, std::index_sequence_for<Get...>{});
  14993. if constexpr(sizeof...(Index) == 0) {
  14994. static_assert(std::is_invocable_v<Compare, const entity_type, const entity_type>, "Invalid comparison function");
  14995. storage<0>()->sort_n(descriptor->length(), std::move(compare), std::move(algo), std::forward<Args>(args)...);
  14996. } else {
  14997. auto comp = [&compare, &cpools](const entity_type lhs, const entity_type rhs) {
  14998. if constexpr(sizeof...(Index) == 1) {
  14999. return compare((std::get<Index>(cpools)->get(lhs), ...), (std::get<Index>(cpools)->get(rhs), ...));
  15000. } else {
  15001. return compare(std::forward_as_tuple(std::get<Index>(cpools)->get(lhs)...), std::forward_as_tuple(std::get<Index>(cpools)->get(rhs)...));
  15002. }
  15003. };
  15004. storage<0>()->sort_n(descriptor->length(), std::move(comp), std::move(algo), std::forward<Args>(args)...);
  15005. }
  15006. auto cb = [this](auto *head, auto *...other) {
  15007. for(auto next = descriptor->length(); next; --next) {
  15008. const auto pos = next - 1;
  15009. [[maybe_unused]] const auto entt = head->data()[pos];
  15010. (other->swap_elements(other->data()[pos], entt), ...);
  15011. }
  15012. };
  15013. std::apply(cb, cpools);
  15014. }
  15015. private:
  15016. handler *descriptor;
  15017. };
  15018. } // namespace entt
  15019. #endif
  15020. // #include "storage.hpp"
  15021. #ifndef ENTT_ENTITY_STORAGE_HPP
  15022. #define ENTT_ENTITY_STORAGE_HPP
  15023. #include <cstddef>
  15024. #include <iterator>
  15025. #include <memory>
  15026. #include <tuple>
  15027. #include <type_traits>
  15028. #include <utility>
  15029. #include <vector>
  15030. // #include "../config/config.h"
  15031. // #include "../core/bit.hpp"
  15032. // #include "../core/iterator.hpp"
  15033. // #include "../core/memory.hpp"
  15034. #ifndef ENTT_CORE_MEMORY_HPP
  15035. #define ENTT_CORE_MEMORY_HPP
  15036. #include <cstddef>
  15037. #include <memory>
  15038. #include <tuple>
  15039. #include <type_traits>
  15040. #include <utility>
  15041. // #include "../config/config.h"
  15042. namespace entt {
  15043. /**
  15044. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  15045. * @tparam Type Pointer type.
  15046. * @param ptr Fancy or raw pointer.
  15047. * @return A raw pointer that represents the address of the original pointer.
  15048. */
  15049. template<typename Type>
  15050. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  15051. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  15052. return ptr;
  15053. } else {
  15054. return to_address(std::forward<Type>(ptr).operator->());
  15055. }
  15056. }
  15057. /**
  15058. * @brief Utility function to design allocation-aware containers.
  15059. * @tparam Allocator Type of allocator.
  15060. * @param lhs A valid allocator.
  15061. * @param rhs Another valid allocator.
  15062. */
  15063. template<typename Allocator>
  15064. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  15065. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  15066. lhs = rhs;
  15067. }
  15068. }
  15069. /**
  15070. * @brief Utility function to design allocation-aware containers.
  15071. * @tparam Allocator Type of allocator.
  15072. * @param lhs A valid allocator.
  15073. * @param rhs Another valid allocator.
  15074. */
  15075. template<typename Allocator>
  15076. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  15077. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  15078. lhs = std::move(rhs);
  15079. }
  15080. }
  15081. /**
  15082. * @brief Utility function to design allocation-aware containers.
  15083. * @tparam Allocator Type of allocator.
  15084. * @param lhs A valid allocator.
  15085. * @param rhs Another valid allocator.
  15086. */
  15087. template<typename Allocator>
  15088. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  15089. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  15090. using std::swap;
  15091. swap(lhs, rhs);
  15092. } else {
  15093. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  15094. }
  15095. }
  15096. /**
  15097. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  15098. * @tparam Allocator Type of allocator used to manage memory and elements.
  15099. */
  15100. template<typename Allocator>
  15101. struct allocation_deleter: private Allocator {
  15102. /*! @brief Allocator type. */
  15103. using allocator_type = Allocator;
  15104. /*! @brief Pointer type. */
  15105. using pointer = typename std::allocator_traits<Allocator>::pointer;
  15106. /**
  15107. * @brief Inherited constructors.
  15108. * @param alloc The allocator to use.
  15109. */
  15110. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  15111. : Allocator{alloc} {}
  15112. /**
  15113. * @brief Destroys the pointed object and deallocates its memory.
  15114. * @param ptr A valid pointer to an object of the given type.
  15115. */
  15116. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  15117. using alloc_traits = std::allocator_traits<Allocator>;
  15118. alloc_traits::destroy(*this, to_address(ptr));
  15119. alloc_traits::deallocate(*this, ptr, 1u);
  15120. }
  15121. };
  15122. /**
  15123. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  15124. * @tparam Type Type of object to allocate for and to construct.
  15125. * @tparam Allocator Type of allocator used to manage memory and elements.
  15126. * @tparam Args Types of arguments to use to construct the object.
  15127. * @param allocator The allocator to use.
  15128. * @param args Parameters to use to construct the object.
  15129. * @return A properly initialized unique pointer with a custom deleter.
  15130. */
  15131. template<typename Type, typename Allocator, typename... Args>
  15132. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  15133. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  15134. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  15135. using allocator_type = typename alloc_traits::allocator_type;
  15136. allocator_type alloc{allocator};
  15137. auto ptr = alloc_traits::allocate(alloc, 1u);
  15138. ENTT_TRY {
  15139. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  15140. }
  15141. ENTT_CATCH {
  15142. alloc_traits::deallocate(alloc, ptr, 1u);
  15143. ENTT_THROW;
  15144. }
  15145. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  15146. }
  15147. /*! @cond TURN_OFF_DOXYGEN */
  15148. namespace internal {
  15149. template<typename Type>
  15150. struct uses_allocator_construction {
  15151. template<typename Allocator, typename... Params>
  15152. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  15153. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  15154. return std::forward_as_tuple(std::forward<Params>(params)...);
  15155. } else {
  15156. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  15157. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  15158. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  15159. } else {
  15160. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  15161. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  15162. }
  15163. }
  15164. }
  15165. };
  15166. template<typename Type, typename Other>
  15167. struct uses_allocator_construction<std::pair<Type, Other>> {
  15168. using type = std::pair<Type, Other>;
  15169. template<typename Allocator, typename First, typename Second>
  15170. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  15171. return std::make_tuple(
  15172. std::piecewise_construct,
  15173. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  15174. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  15175. }
  15176. template<typename Allocator>
  15177. static constexpr auto args(const Allocator &allocator) noexcept {
  15178. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  15179. }
  15180. template<typename Allocator, typename First, typename Second>
  15181. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  15182. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  15183. }
  15184. template<typename Allocator, typename First, typename Second>
  15185. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  15186. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  15187. }
  15188. template<typename Allocator, typename First, typename Second>
  15189. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  15190. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  15191. }
  15192. };
  15193. } // namespace internal
  15194. /*! @endcond */
  15195. /**
  15196. * @brief Uses-allocator construction utility (waiting for C++20).
  15197. *
  15198. * Primarily intended for internal use. Prepares the argument list needed to
  15199. * create an object of a given type by means of uses-allocator construction.
  15200. *
  15201. * @tparam Type Type to return arguments for.
  15202. * @tparam Allocator Type of allocator used to manage memory and elements.
  15203. * @tparam Args Types of arguments to use to construct the object.
  15204. * @param allocator The allocator to use.
  15205. * @param args Parameters to use to construct the object.
  15206. * @return The arguments needed to create an object of the given type.
  15207. */
  15208. template<typename Type, typename Allocator, typename... Args>
  15209. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  15210. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  15211. }
  15212. /**
  15213. * @brief Uses-allocator construction utility (waiting for C++20).
  15214. *
  15215. * Primarily intended for internal use. Creates an object of a given type by
  15216. * means of uses-allocator construction.
  15217. *
  15218. * @tparam Type Type of object to create.
  15219. * @tparam Allocator Type of allocator used to manage memory and elements.
  15220. * @tparam Args Types of arguments to use to construct the object.
  15221. * @param allocator The allocator to use.
  15222. * @param args Parameters to use to construct the object.
  15223. * @return A newly created object of the given type.
  15224. */
  15225. template<typename Type, typename Allocator, typename... Args>
  15226. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  15227. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  15228. }
  15229. /**
  15230. * @brief Uses-allocator construction utility (waiting for C++20).
  15231. *
  15232. * Primarily intended for internal use. Creates an object of a given type by
  15233. * means of uses-allocator construction at an uninitialized memory location.
  15234. *
  15235. * @tparam Type Type of object to create.
  15236. * @tparam Allocator Type of allocator used to manage memory and elements.
  15237. * @tparam Args Types of arguments to use to construct the object.
  15238. * @param value Memory location in which to place the object.
  15239. * @param allocator The allocator to use.
  15240. * @param args Parameters to use to construct the object.
  15241. * @return A pointer to the newly created object of the given type.
  15242. */
  15243. template<typename Type, typename Allocator, typename... Args>
  15244. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  15245. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  15246. }
  15247. } // namespace entt
  15248. #endif
  15249. // #include "../core/type_info.hpp"
  15250. // #include "component.hpp"
  15251. // #include "entity.hpp"
  15252. // #include "fwd.hpp"
  15253. // #include "sparse_set.hpp"
  15254. #ifndef ENTT_ENTITY_SPARSE_SET_HPP
  15255. #define ENTT_ENTITY_SPARSE_SET_HPP
  15256. #include <cstddef>
  15257. #include <iterator>
  15258. #include <memory>
  15259. #include <type_traits>
  15260. #include <utility>
  15261. #include <vector>
  15262. // #include "../config/config.h"
  15263. // #include "../core/algorithm.hpp"
  15264. // #include "../core/any.hpp"
  15265. #ifndef ENTT_CORE_ANY_HPP
  15266. #define ENTT_CORE_ANY_HPP
  15267. #include <cstddef>
  15268. #include <memory>
  15269. #include <type_traits>
  15270. #include <utility>
  15271. // #include "../config/config.h"
  15272. // #include "fwd.hpp"
  15273. // #include "type_info.hpp"
  15274. #ifndef ENTT_CORE_TYPE_INFO_HPP
  15275. #define ENTT_CORE_TYPE_INFO_HPP
  15276. #include <string_view>
  15277. #include <type_traits>
  15278. #include <utility>
  15279. // #include "../config/config.h"
  15280. // #include "fwd.hpp"
  15281. // #include "hashed_string.hpp"
  15282. namespace entt {
  15283. /*! @cond TURN_OFF_DOXYGEN */
  15284. namespace internal {
  15285. struct ENTT_API type_index final {
  15286. [[nodiscard]] static id_type next() noexcept {
  15287. static ENTT_MAYBE_ATOMIC(id_type) value{};
  15288. return value++;
  15289. }
  15290. };
  15291. template<typename Type>
  15292. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  15293. #if defined ENTT_PRETTY_FUNCTION
  15294. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  15295. #else
  15296. return "";
  15297. #endif
  15298. }
  15299. template<typename Type>
  15300. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  15301. #if defined ENTT_PRETTY_FUNCTION
  15302. const std::string_view full_name{pretty_function<Type>()};
  15303. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  15304. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  15305. return value;
  15306. #else
  15307. return std::string_view{};
  15308. #endif
  15309. }
  15310. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  15311. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  15312. constexpr auto value = stripped_type_name<Type>();
  15313. return value;
  15314. }
  15315. template<typename Type>
  15316. [[nodiscard]] std::string_view type_name(char) noexcept {
  15317. static const auto value = stripped_type_name<Type>();
  15318. return value;
  15319. }
  15320. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  15321. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  15322. constexpr auto stripped = stripped_type_name<Type>();
  15323. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  15324. return value;
  15325. }
  15326. template<typename Type>
  15327. [[nodiscard]] id_type type_hash(char) noexcept {
  15328. static const auto value = [](const auto stripped) {
  15329. return hashed_string::value(stripped.data(), stripped.size());
  15330. }(stripped_type_name<Type>());
  15331. return value;
  15332. }
  15333. } // namespace internal
  15334. /*! @endcond */
  15335. /**
  15336. * @brief Type sequential identifier.
  15337. * @tparam Type Type for which to generate a sequential identifier.
  15338. */
  15339. template<typename Type, typename = void>
  15340. struct ENTT_API type_index final {
  15341. /**
  15342. * @brief Returns the sequential identifier of a given type.
  15343. * @return The sequential identifier of a given type.
  15344. */
  15345. [[nodiscard]] static id_type value() noexcept {
  15346. static const id_type value = internal::type_index::next();
  15347. return value;
  15348. }
  15349. /*! @copydoc value */
  15350. [[nodiscard]] constexpr operator id_type() const noexcept {
  15351. return value();
  15352. }
  15353. };
  15354. /**
  15355. * @brief Type hash.
  15356. * @tparam Type Type for which to generate a hash value.
  15357. */
  15358. template<typename Type, typename = void>
  15359. struct type_hash final {
  15360. /**
  15361. * @brief Returns the numeric representation of a given type.
  15362. * @return The numeric representation of the given type.
  15363. */
  15364. #if defined ENTT_PRETTY_FUNCTION
  15365. [[nodiscard]] static constexpr id_type value() noexcept {
  15366. return internal::type_hash<Type>(0);
  15367. #else
  15368. [[nodiscard]] static constexpr id_type value() noexcept {
  15369. return type_index<Type>::value();
  15370. #endif
  15371. }
  15372. /*! @copydoc value */
  15373. [[nodiscard]] constexpr operator id_type() const noexcept {
  15374. return value();
  15375. }
  15376. };
  15377. /**
  15378. * @brief Type name.
  15379. * @tparam Type Type for which to generate a name.
  15380. */
  15381. template<typename Type, typename = void>
  15382. struct type_name final {
  15383. /**
  15384. * @brief Returns the name of a given type.
  15385. * @return The name of the given type.
  15386. */
  15387. [[nodiscard]] static constexpr std::string_view value() noexcept {
  15388. return internal::type_name<Type>(0);
  15389. }
  15390. /*! @copydoc value */
  15391. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  15392. return value();
  15393. }
  15394. };
  15395. /*! @brief Implementation specific information about a type. */
  15396. struct type_info final {
  15397. /**
  15398. * @brief Constructs a type info object for a given type.
  15399. * @tparam Type Type for which to construct a type info object.
  15400. */
  15401. template<typename Type>
  15402. // NOLINTBEGIN(modernize-use-transparent-functors)
  15403. constexpr type_info(std::in_place_type_t<Type>) noexcept
  15404. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  15405. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  15406. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  15407. // NOLINTEND(modernize-use-transparent-functors)
  15408. /**
  15409. * @brief Type index.
  15410. * @return Type index.
  15411. */
  15412. [[nodiscard]] constexpr id_type index() const noexcept {
  15413. return seq;
  15414. }
  15415. /**
  15416. * @brief Type hash.
  15417. * @return Type hash.
  15418. */
  15419. [[nodiscard]] constexpr id_type hash() const noexcept {
  15420. return identifier;
  15421. }
  15422. /**
  15423. * @brief Type name.
  15424. * @return Type name.
  15425. */
  15426. [[nodiscard]] constexpr std::string_view name() const noexcept {
  15427. return alias;
  15428. }
  15429. private:
  15430. id_type seq;
  15431. id_type identifier;
  15432. std::string_view alias;
  15433. };
  15434. /**
  15435. * @brief Compares the contents of two type info objects.
  15436. * @param lhs A type info object.
  15437. * @param rhs A type info object.
  15438. * @return True if the two type info objects are identical, false otherwise.
  15439. */
  15440. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  15441. return lhs.hash() == rhs.hash();
  15442. }
  15443. /**
  15444. * @brief Compares the contents of two type info objects.
  15445. * @param lhs A type info object.
  15446. * @param rhs A type info object.
  15447. * @return True if the two type info objects differ, false otherwise.
  15448. */
  15449. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  15450. return !(lhs == rhs);
  15451. }
  15452. /**
  15453. * @brief Compares two type info objects.
  15454. * @param lhs A valid type info object.
  15455. * @param rhs A valid type info object.
  15456. * @return True if the first element is less than the second, false otherwise.
  15457. */
  15458. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  15459. return lhs.index() < rhs.index();
  15460. }
  15461. /**
  15462. * @brief Compares two type info objects.
  15463. * @param lhs A valid type info object.
  15464. * @param rhs A valid type info object.
  15465. * @return True if the first element is less than or equal to the second, false
  15466. * otherwise.
  15467. */
  15468. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  15469. return !(rhs < lhs);
  15470. }
  15471. /**
  15472. * @brief Compares two type info objects.
  15473. * @param lhs A valid type info object.
  15474. * @param rhs A valid type info object.
  15475. * @return True if the first element is greater than the second, false
  15476. * otherwise.
  15477. */
  15478. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  15479. return rhs < lhs;
  15480. }
  15481. /**
  15482. * @brief Compares two type info objects.
  15483. * @param lhs A valid type info object.
  15484. * @param rhs A valid type info object.
  15485. * @return True if the first element is greater than or equal to the second,
  15486. * false otherwise.
  15487. */
  15488. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  15489. return !(lhs < rhs);
  15490. }
  15491. /**
  15492. * @brief Returns the type info object associated to a given type.
  15493. *
  15494. * The returned element refers to an object with static storage duration.<br/>
  15495. * The type doesn't need to be a complete type. If the type is a reference, the
  15496. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  15497. * are ignored.
  15498. *
  15499. * @tparam Type Type for which to generate a type info object.
  15500. * @return A reference to a properly initialized type info object.
  15501. */
  15502. template<typename Type>
  15503. [[nodiscard]] const type_info &type_id() noexcept {
  15504. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  15505. static const type_info instance{std::in_place_type<Type>};
  15506. return instance;
  15507. } else {
  15508. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  15509. }
  15510. }
  15511. /*! @copydoc type_id */
  15512. template<typename Type>
  15513. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  15514. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  15515. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  15516. }
  15517. } // namespace entt
  15518. #endif
  15519. // #include "type_traits.hpp"
  15520. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  15521. #define ENTT_CORE_TYPE_TRAITS_HPP
  15522. #include <cstddef>
  15523. #include <iterator>
  15524. #include <tuple>
  15525. #include <type_traits>
  15526. #include <utility>
  15527. // #include "../config/config.h"
  15528. // #include "fwd.hpp"
  15529. namespace entt {
  15530. /**
  15531. * @brief Utility class to disambiguate overloaded functions.
  15532. * @tparam N Number of choices available.
  15533. */
  15534. template<std::size_t N>
  15535. struct choice_t
  15536. // unfortunately, doxygen cannot parse such a construct
  15537. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  15538. {};
  15539. /*! @copybrief choice_t */
  15540. template<>
  15541. struct choice_t<0> {};
  15542. /**
  15543. * @brief Variable template for the choice trick.
  15544. * @tparam N Number of choices available.
  15545. */
  15546. template<std::size_t N>
  15547. inline constexpr choice_t<N> choice{};
  15548. /**
  15549. * @brief Identity type trait.
  15550. *
  15551. * Useful to establish non-deduced contexts in template argument deduction
  15552. * (waiting for C++20) or to provide types through function arguments.
  15553. *
  15554. * @tparam Type A type.
  15555. */
  15556. template<typename Type>
  15557. struct type_identity {
  15558. /*! @brief Identity type. */
  15559. using type = Type;
  15560. };
  15561. /**
  15562. * @brief Helper type.
  15563. * @tparam Type A type.
  15564. */
  15565. template<typename Type>
  15566. using type_identity_t = typename type_identity<Type>::type;
  15567. /**
  15568. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  15569. * @tparam Type The type of which to return the size.
  15570. */
  15571. template<typename Type, typename = void>
  15572. struct size_of: std::integral_constant<std::size_t, 0u> {};
  15573. /*! @copydoc size_of */
  15574. template<typename Type>
  15575. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  15576. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  15577. : std::integral_constant<std::size_t, sizeof(Type)> {};
  15578. /**
  15579. * @brief Helper variable template.
  15580. * @tparam Type The type of which to return the size.
  15581. */
  15582. template<typename Type>
  15583. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  15584. /**
  15585. * @brief Using declaration to be used to _repeat_ the same type a number of
  15586. * times equal to the size of a given parameter pack.
  15587. * @tparam Type A type to repeat.
  15588. */
  15589. template<typename Type, typename>
  15590. using unpack_as_type = Type;
  15591. /**
  15592. * @brief Helper variable template to be used to _repeat_ the same value a
  15593. * number of times equal to the size of a given parameter pack.
  15594. * @tparam Value A value to repeat.
  15595. */
  15596. template<auto Value, typename>
  15597. inline constexpr auto unpack_as_value = Value;
  15598. /**
  15599. * @brief Wraps a static constant.
  15600. * @tparam Value A static constant.
  15601. */
  15602. template<auto Value>
  15603. using integral_constant = std::integral_constant<decltype(Value), Value>;
  15604. /**
  15605. * @brief Alias template to facilitate the creation of named values.
  15606. * @tparam Value A constant value at least convertible to `id_type`.
  15607. */
  15608. template<id_type Value>
  15609. using tag = integral_constant<Value>;
  15610. /**
  15611. * @brief A class to use to push around lists of types, nothing more.
  15612. * @tparam Type Types provided by the type list.
  15613. */
  15614. template<typename... Type>
  15615. struct type_list {
  15616. /*! @brief Type list type. */
  15617. using type = type_list;
  15618. /*! @brief Compile-time number of elements in the type list. */
  15619. static constexpr auto size = sizeof...(Type);
  15620. };
  15621. /*! @brief Primary template isn't defined on purpose. */
  15622. template<std::size_t, typename>
  15623. struct type_list_element;
  15624. /**
  15625. * @brief Provides compile-time indexed access to the types of a type list.
  15626. * @tparam Index Index of the type to return.
  15627. * @tparam First First type provided by the type list.
  15628. * @tparam Other Other types provided by the type list.
  15629. */
  15630. template<std::size_t Index, typename First, typename... Other>
  15631. struct type_list_element<Index, type_list<First, Other...>>
  15632. : type_list_element<Index - 1u, type_list<Other...>> {};
  15633. /**
  15634. * @brief Provides compile-time indexed access to the types of a type list.
  15635. * @tparam First First type provided by the type list.
  15636. * @tparam Other Other types provided by the type list.
  15637. */
  15638. template<typename First, typename... Other>
  15639. struct type_list_element<0u, type_list<First, Other...>> {
  15640. /*! @brief Searched type. */
  15641. using type = First;
  15642. };
  15643. /**
  15644. * @brief Helper type.
  15645. * @tparam Index Index of the type to return.
  15646. * @tparam List Type list to search into.
  15647. */
  15648. template<std::size_t Index, typename List>
  15649. using type_list_element_t = typename type_list_element<Index, List>::type;
  15650. /*! @brief Primary template isn't defined on purpose. */
  15651. template<typename, typename>
  15652. struct type_list_index;
  15653. /**
  15654. * @brief Provides compile-time type access to the types of a type list.
  15655. * @tparam Type Type to look for and for which to return the index.
  15656. * @tparam First First type provided by the type list.
  15657. * @tparam Other Other types provided by the type list.
  15658. */
  15659. template<typename Type, typename First, typename... Other>
  15660. struct type_list_index<Type, type_list<First, Other...>> {
  15661. /*! @brief Unsigned integer type. */
  15662. using value_type = std::size_t;
  15663. /*! @brief Compile-time position of the given type in the sublist. */
  15664. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  15665. };
  15666. /**
  15667. * @brief Provides compile-time type access to the types of a type list.
  15668. * @tparam Type Type to look for and for which to return the index.
  15669. * @tparam Other Other types provided by the type list.
  15670. */
  15671. template<typename Type, typename... Other>
  15672. struct type_list_index<Type, type_list<Type, Other...>> {
  15673. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  15674. /*! @brief Unsigned integer type. */
  15675. using value_type = std::size_t;
  15676. /*! @brief Compile-time position of the given type in the sublist. */
  15677. static constexpr value_type value = 0u;
  15678. };
  15679. /**
  15680. * @brief Provides compile-time type access to the types of a type list.
  15681. * @tparam Type Type to look for and for which to return the index.
  15682. */
  15683. template<typename Type>
  15684. struct type_list_index<Type, type_list<>> {
  15685. /*! @brief Unsigned integer type. */
  15686. using value_type = std::size_t;
  15687. /*! @brief Compile-time position of the given type in the sublist. */
  15688. static constexpr value_type value = 0u;
  15689. };
  15690. /**
  15691. * @brief Helper variable template.
  15692. * @tparam List Type list.
  15693. * @tparam Type Type to look for and for which to return the index.
  15694. */
  15695. template<typename Type, typename List>
  15696. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  15697. /**
  15698. * @brief Concatenates multiple type lists.
  15699. * @tparam Type Types provided by the first type list.
  15700. * @tparam Other Types provided by the second type list.
  15701. * @return A type list composed by the types of both the type lists.
  15702. */
  15703. template<typename... Type, typename... Other>
  15704. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  15705. return {};
  15706. }
  15707. /*! @brief Primary template isn't defined on purpose. */
  15708. template<typename...>
  15709. struct type_list_cat;
  15710. /*! @brief Concatenates multiple type lists. */
  15711. template<>
  15712. struct type_list_cat<> {
  15713. /*! @brief A type list composed by the types of all the type lists. */
  15714. using type = type_list<>;
  15715. };
  15716. /**
  15717. * @brief Concatenates multiple type lists.
  15718. * @tparam Type Types provided by the first type list.
  15719. * @tparam Other Types provided by the second type list.
  15720. * @tparam List Other type lists, if any.
  15721. */
  15722. template<typename... Type, typename... Other, typename... List>
  15723. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  15724. /*! @brief A type list composed by the types of all the type lists. */
  15725. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  15726. };
  15727. /**
  15728. * @brief Concatenates multiple type lists.
  15729. * @tparam Type Types provided by the type list.
  15730. */
  15731. template<typename... Type>
  15732. struct type_list_cat<type_list<Type...>> {
  15733. /*! @brief A type list composed by the types of all the type lists. */
  15734. using type = type_list<Type...>;
  15735. };
  15736. /**
  15737. * @brief Helper type.
  15738. * @tparam List Type lists to concatenate.
  15739. */
  15740. template<typename... List>
  15741. using type_list_cat_t = typename type_list_cat<List...>::type;
  15742. /*! @cond TURN_OFF_DOXYGEN */
  15743. namespace internal {
  15744. template<typename...>
  15745. struct type_list_unique;
  15746. template<typename First, typename... Other, typename... Type>
  15747. struct type_list_unique<type_list<First, Other...>, Type...>
  15748. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  15749. template<typename... Type>
  15750. struct type_list_unique<type_list<>, Type...> {
  15751. using type = type_list<Type...>;
  15752. };
  15753. } // namespace internal
  15754. /*! @endcond */
  15755. /**
  15756. * @brief Removes duplicates types from a type list.
  15757. * @tparam List Type list.
  15758. */
  15759. template<typename List>
  15760. struct type_list_unique {
  15761. /*! @brief A type list without duplicate types. */
  15762. using type = typename internal::type_list_unique<List>::type;
  15763. };
  15764. /**
  15765. * @brief Helper type.
  15766. * @tparam List Type list.
  15767. */
  15768. template<typename List>
  15769. using type_list_unique_t = typename type_list_unique<List>::type;
  15770. /**
  15771. * @brief Provides the member constant `value` to true if a type list contains a
  15772. * given type, false otherwise.
  15773. * @tparam List Type list.
  15774. * @tparam Type Type to look for.
  15775. */
  15776. template<typename List, typename Type>
  15777. struct type_list_contains;
  15778. /**
  15779. * @copybrief type_list_contains
  15780. * @tparam Type Types provided by the type list.
  15781. * @tparam Other Type to look for.
  15782. */
  15783. template<typename... Type, typename Other>
  15784. struct type_list_contains<type_list<Type...>, Other>
  15785. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  15786. /**
  15787. * @brief Helper variable template.
  15788. * @tparam List Type list.
  15789. * @tparam Type Type to look for.
  15790. */
  15791. template<typename List, typename Type>
  15792. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  15793. /*! @brief Primary template isn't defined on purpose. */
  15794. template<typename...>
  15795. struct type_list_diff;
  15796. /**
  15797. * @brief Computes the difference between two type lists.
  15798. * @tparam Type Types provided by the first type list.
  15799. * @tparam Other Types provided by the second type list.
  15800. */
  15801. template<typename... Type, typename... Other>
  15802. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  15803. /*! @brief A type list that is the difference between the two type lists. */
  15804. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  15805. };
  15806. /**
  15807. * @brief Helper type.
  15808. * @tparam List Type lists between which to compute the difference.
  15809. */
  15810. template<typename... List>
  15811. using type_list_diff_t = typename type_list_diff<List...>::type;
  15812. /*! @brief Primary template isn't defined on purpose. */
  15813. template<typename, template<typename...> class>
  15814. struct type_list_transform;
  15815. /**
  15816. * @brief Applies a given _function_ to a type list and generate a new list.
  15817. * @tparam Type Types provided by the type list.
  15818. * @tparam Op Unary operation as template class with a type member named `type`.
  15819. */
  15820. template<typename... Type, template<typename...> class Op>
  15821. struct type_list_transform<type_list<Type...>, Op> {
  15822. /*! @brief Resulting type list after applying the transform function. */
  15823. // NOLINTNEXTLINE(modernize-type-traits)
  15824. using type = type_list<typename Op<Type>::type...>;
  15825. };
  15826. /**
  15827. * @brief Helper type.
  15828. * @tparam List Type list.
  15829. * @tparam Op Unary operation as template class with a type member named `type`.
  15830. */
  15831. template<typename List, template<typename...> class Op>
  15832. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  15833. /**
  15834. * @brief A class to use to push around lists of constant values, nothing more.
  15835. * @tparam Value Values provided by the value list.
  15836. */
  15837. template<auto... Value>
  15838. struct value_list {
  15839. /*! @brief Value list type. */
  15840. using type = value_list;
  15841. /*! @brief Compile-time number of elements in the value list. */
  15842. static constexpr auto size = sizeof...(Value);
  15843. };
  15844. /*! @brief Primary template isn't defined on purpose. */
  15845. template<std::size_t, typename>
  15846. struct value_list_element;
  15847. /**
  15848. * @brief Provides compile-time indexed access to the values of a value list.
  15849. * @tparam Index Index of the value to return.
  15850. * @tparam Value First value provided by the value list.
  15851. * @tparam Other Other values provided by the value list.
  15852. */
  15853. template<std::size_t Index, auto Value, auto... Other>
  15854. struct value_list_element<Index, value_list<Value, Other...>>
  15855. : value_list_element<Index - 1u, value_list<Other...>> {};
  15856. /**
  15857. * @brief Provides compile-time indexed access to the types of a type list.
  15858. * @tparam Value First value provided by the value list.
  15859. * @tparam Other Other values provided by the value list.
  15860. */
  15861. template<auto Value, auto... Other>
  15862. struct value_list_element<0u, value_list<Value, Other...>> {
  15863. /*! @brief Searched type. */
  15864. using type = decltype(Value);
  15865. /*! @brief Searched value. */
  15866. static constexpr auto value = Value;
  15867. };
  15868. /**
  15869. * @brief Helper type.
  15870. * @tparam Index Index of the type to return.
  15871. * @tparam List Value list to search into.
  15872. */
  15873. template<std::size_t Index, typename List>
  15874. using value_list_element_t = typename value_list_element<Index, List>::type;
  15875. /**
  15876. * @brief Helper type.
  15877. * @tparam Index Index of the value to return.
  15878. * @tparam List Value list to search into.
  15879. */
  15880. template<std::size_t Index, typename List>
  15881. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  15882. /*! @brief Primary template isn't defined on purpose. */
  15883. template<auto, typename>
  15884. struct value_list_index;
  15885. /**
  15886. * @brief Provides compile-time type access to the values of a value list.
  15887. * @tparam Value Value to look for and for which to return the index.
  15888. * @tparam First First value provided by the value list.
  15889. * @tparam Other Other values provided by the value list.
  15890. */
  15891. template<auto Value, auto First, auto... Other>
  15892. struct value_list_index<Value, value_list<First, Other...>> {
  15893. /*! @brief Unsigned integer type. */
  15894. using value_type = std::size_t;
  15895. /*! @brief Compile-time position of the given value in the sublist. */
  15896. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  15897. };
  15898. /**
  15899. * @brief Provides compile-time type access to the values of a value list.
  15900. * @tparam Value Value to look for and for which to return the index.
  15901. * @tparam Other Other values provided by the value list.
  15902. */
  15903. template<auto Value, auto... Other>
  15904. struct value_list_index<Value, value_list<Value, Other...>> {
  15905. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  15906. /*! @brief Unsigned integer type. */
  15907. using value_type = std::size_t;
  15908. /*! @brief Compile-time position of the given value in the sublist. */
  15909. static constexpr value_type value = 0u;
  15910. };
  15911. /**
  15912. * @brief Provides compile-time type access to the values of a value list.
  15913. * @tparam Value Value to look for and for which to return the index.
  15914. */
  15915. template<auto Value>
  15916. struct value_list_index<Value, value_list<>> {
  15917. /*! @brief Unsigned integer type. */
  15918. using value_type = std::size_t;
  15919. /*! @brief Compile-time position of the given type in the sublist. */
  15920. static constexpr value_type value = 0u;
  15921. };
  15922. /**
  15923. * @brief Helper variable template.
  15924. * @tparam List Value list.
  15925. * @tparam Value Value to look for and for which to return the index.
  15926. */
  15927. template<auto Value, typename List>
  15928. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  15929. /**
  15930. * @brief Concatenates multiple value lists.
  15931. * @tparam Value Values provided by the first value list.
  15932. * @tparam Other Values provided by the second value list.
  15933. * @return A value list composed by the values of both the value lists.
  15934. */
  15935. template<auto... Value, auto... Other>
  15936. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  15937. return {};
  15938. }
  15939. /*! @brief Primary template isn't defined on purpose. */
  15940. template<typename...>
  15941. struct value_list_cat;
  15942. /*! @brief Concatenates multiple value lists. */
  15943. template<>
  15944. struct value_list_cat<> {
  15945. /*! @brief A value list composed by the values of all the value lists. */
  15946. using type = value_list<>;
  15947. };
  15948. /**
  15949. * @brief Concatenates multiple value lists.
  15950. * @tparam Value Values provided by the first value list.
  15951. * @tparam Other Values provided by the second value list.
  15952. * @tparam List Other value lists, if any.
  15953. */
  15954. template<auto... Value, auto... Other, typename... List>
  15955. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  15956. /*! @brief A value list composed by the values of all the value lists. */
  15957. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  15958. };
  15959. /**
  15960. * @brief Concatenates multiple value lists.
  15961. * @tparam Value Values provided by the value list.
  15962. */
  15963. template<auto... Value>
  15964. struct value_list_cat<value_list<Value...>> {
  15965. /*! @brief A value list composed by the values of all the value lists. */
  15966. using type = value_list<Value...>;
  15967. };
  15968. /**
  15969. * @brief Helper type.
  15970. * @tparam List Value lists to concatenate.
  15971. */
  15972. template<typename... List>
  15973. using value_list_cat_t = typename value_list_cat<List...>::type;
  15974. /*! @brief Primary template isn't defined on purpose. */
  15975. template<typename>
  15976. struct value_list_unique;
  15977. /**
  15978. * @brief Removes duplicates values from a value list.
  15979. * @tparam Value One of the values provided by the given value list.
  15980. * @tparam Other The other values provided by the given value list.
  15981. */
  15982. template<auto Value, auto... Other>
  15983. struct value_list_unique<value_list<Value, Other...>> {
  15984. /*! @brief A value list without duplicate types. */
  15985. using type = std::conditional_t<
  15986. ((Value == Other) || ...),
  15987. typename value_list_unique<value_list<Other...>>::type,
  15988. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  15989. };
  15990. /*! @brief Removes duplicates values from a value list. */
  15991. template<>
  15992. struct value_list_unique<value_list<>> {
  15993. /*! @brief A value list without duplicate types. */
  15994. using type = value_list<>;
  15995. };
  15996. /**
  15997. * @brief Helper type.
  15998. * @tparam Type A value list.
  15999. */
  16000. template<typename Type>
  16001. using value_list_unique_t = typename value_list_unique<Type>::type;
  16002. /**
  16003. * @brief Provides the member constant `value` to true if a value list contains
  16004. * a given value, false otherwise.
  16005. * @tparam List Value list.
  16006. * @tparam Value Value to look for.
  16007. */
  16008. template<typename List, auto Value>
  16009. struct value_list_contains;
  16010. /**
  16011. * @copybrief value_list_contains
  16012. * @tparam Value Values provided by the value list.
  16013. * @tparam Other Value to look for.
  16014. */
  16015. template<auto... Value, auto Other>
  16016. struct value_list_contains<value_list<Value...>, Other>
  16017. : std::bool_constant<((Value == Other) || ...)> {};
  16018. /**
  16019. * @brief Helper variable template.
  16020. * @tparam List Value list.
  16021. * @tparam Value Value to look for.
  16022. */
  16023. template<typename List, auto Value>
  16024. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  16025. /*! @brief Primary template isn't defined on purpose. */
  16026. template<typename...>
  16027. struct value_list_diff;
  16028. /**
  16029. * @brief Computes the difference between two value lists.
  16030. * @tparam Value Values provided by the first value list.
  16031. * @tparam Other Values provided by the second value list.
  16032. */
  16033. template<auto... Value, auto... Other>
  16034. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  16035. /*! @brief A value list that is the difference between the two value lists. */
  16036. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  16037. };
  16038. /**
  16039. * @brief Helper type.
  16040. * @tparam List Value lists between which to compute the difference.
  16041. */
  16042. template<typename... List>
  16043. using value_list_diff_t = typename value_list_diff<List...>::type;
  16044. /*! @brief Same as std::is_invocable, but with tuples. */
  16045. template<typename, typename>
  16046. struct is_applicable: std::false_type {};
  16047. /**
  16048. * @copybrief is_applicable
  16049. * @tparam Func A valid function type.
  16050. * @tparam Tuple Tuple-like type.
  16051. * @tparam Args The list of arguments to use to probe the function type.
  16052. */
  16053. template<typename Func, template<typename...> class Tuple, typename... Args>
  16054. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  16055. /**
  16056. * @copybrief is_applicable
  16057. * @tparam Func A valid function type.
  16058. * @tparam Tuple Tuple-like type.
  16059. * @tparam Args The list of arguments to use to probe the function type.
  16060. */
  16061. template<typename Func, template<typename...> class Tuple, typename... Args>
  16062. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  16063. /**
  16064. * @brief Helper variable template.
  16065. * @tparam Func A valid function type.
  16066. * @tparam Args The list of arguments to use to probe the function type.
  16067. */
  16068. template<typename Func, typename Args>
  16069. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  16070. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  16071. template<typename, typename, typename>
  16072. struct is_applicable_r: std::false_type {};
  16073. /**
  16074. * @copybrief is_applicable_r
  16075. * @tparam Ret The type to which the return type of the function should be
  16076. * convertible.
  16077. * @tparam Func A valid function type.
  16078. * @tparam Args The list of arguments to use to probe the function type.
  16079. */
  16080. template<typename Ret, typename Func, typename... Args>
  16081. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  16082. /**
  16083. * @brief Helper variable template.
  16084. * @tparam Ret The type to which the return type of the function should be
  16085. * convertible.
  16086. * @tparam Func A valid function type.
  16087. * @tparam Args The list of arguments to use to probe the function type.
  16088. */
  16089. template<typename Ret, typename Func, typename Args>
  16090. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  16091. /**
  16092. * @brief Provides the member constant `value` to true if a given type is
  16093. * complete, false otherwise.
  16094. * @tparam Type The type to test.
  16095. */
  16096. template<typename Type, typename = void>
  16097. struct is_complete: std::false_type {};
  16098. /*! @copydoc is_complete */
  16099. template<typename Type>
  16100. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  16101. /**
  16102. * @brief Helper variable template.
  16103. * @tparam Type The type to test.
  16104. */
  16105. template<typename Type>
  16106. inline constexpr bool is_complete_v = is_complete<Type>::value;
  16107. /**
  16108. * @brief Provides the member constant `value` to true if a given type is an
  16109. * iterator, false otherwise.
  16110. * @tparam Type The type to test.
  16111. */
  16112. template<typename Type, typename = void>
  16113. struct is_iterator: std::false_type {};
  16114. /*! @cond TURN_OFF_DOXYGEN */
  16115. namespace internal {
  16116. template<typename, typename = void>
  16117. struct has_iterator_category: std::false_type {};
  16118. template<typename Type>
  16119. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  16120. } // namespace internal
  16121. /*! @endcond */
  16122. /*! @copydoc is_iterator */
  16123. template<typename Type>
  16124. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  16125. : internal::has_iterator_category<Type> {};
  16126. /**
  16127. * @brief Helper variable template.
  16128. * @tparam Type The type to test.
  16129. */
  16130. template<typename Type>
  16131. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  16132. /**
  16133. * @brief Provides the member constant `value` to true if a given type is both
  16134. * an empty and non-final class, false otherwise.
  16135. * @tparam Type The type to test
  16136. */
  16137. template<typename Type>
  16138. struct is_ebco_eligible
  16139. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  16140. /**
  16141. * @brief Helper variable template.
  16142. * @tparam Type The type to test.
  16143. */
  16144. template<typename Type>
  16145. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  16146. /**
  16147. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  16148. * is valid and denotes a type, false otherwise.
  16149. * @tparam Type The type to test.
  16150. */
  16151. template<typename Type, typename = void>
  16152. struct is_transparent: std::false_type {};
  16153. /*! @copydoc is_transparent */
  16154. template<typename Type>
  16155. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  16156. /**
  16157. * @brief Helper variable template.
  16158. * @tparam Type The type to test.
  16159. */
  16160. template<typename Type>
  16161. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  16162. /*! @cond TURN_OFF_DOXYGEN */
  16163. namespace internal {
  16164. template<typename, typename = void>
  16165. struct has_tuple_size_value: std::false_type {};
  16166. template<typename Type>
  16167. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  16168. template<typename, typename = void>
  16169. struct has_value_type: std::false_type {};
  16170. template<typename Type>
  16171. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  16172. template<typename>
  16173. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  16174. template<typename Type, std::size_t... Index>
  16175. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  16176. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  16177. }
  16178. template<typename>
  16179. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  16180. return false;
  16181. }
  16182. template<typename Type>
  16183. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  16184. return true;
  16185. }
  16186. template<typename Type>
  16187. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  16188. // NOLINTBEGIN(modernize-use-transparent-functors)
  16189. if constexpr(std::is_array_v<Type>) {
  16190. return false;
  16191. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  16192. if constexpr(has_tuple_size_value<Type>::value) {
  16193. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  16194. } else {
  16195. return maybe_equality_comparable<Type>(0);
  16196. }
  16197. } else if constexpr(has_value_type<Type>::value) {
  16198. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  16199. return maybe_equality_comparable<Type>(0);
  16200. } else {
  16201. return false;
  16202. }
  16203. } else {
  16204. return maybe_equality_comparable<Type>(0);
  16205. }
  16206. // NOLINTEND(modernize-use-transparent-functors)
  16207. }
  16208. } // namespace internal
  16209. /*! @endcond */
  16210. /**
  16211. * @brief Provides the member constant `value` to true if a given type is
  16212. * equality comparable, false otherwise.
  16213. * @tparam Type The type to test.
  16214. */
  16215. template<typename Type>
  16216. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  16217. /*! @copydoc is_equality_comparable */
  16218. template<typename Type>
  16219. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  16220. /**
  16221. * @brief Helper variable template.
  16222. * @tparam Type The type to test.
  16223. */
  16224. template<typename Type>
  16225. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  16226. /**
  16227. * @brief Transcribes the constness of a type to another type.
  16228. * @tparam To The type to which to transcribe the constness.
  16229. * @tparam From The type from which to transcribe the constness.
  16230. */
  16231. template<typename To, typename From>
  16232. struct constness_as {
  16233. /*! @brief The type resulting from the transcription of the constness. */
  16234. using type = std::remove_const_t<To>;
  16235. };
  16236. /*! @copydoc constness_as */
  16237. template<typename To, typename From>
  16238. struct constness_as<To, const From> {
  16239. /*! @brief The type resulting from the transcription of the constness. */
  16240. using type = const To;
  16241. };
  16242. /**
  16243. * @brief Alias template to facilitate the transcription of the constness.
  16244. * @tparam To The type to which to transcribe the constness.
  16245. * @tparam From The type from which to transcribe the constness.
  16246. */
  16247. template<typename To, typename From>
  16248. using constness_as_t = typename constness_as<To, From>::type;
  16249. /**
  16250. * @brief Extracts the class of a non-static member object or function.
  16251. * @tparam Member A pointer to a non-static member object or function.
  16252. */
  16253. template<typename Member>
  16254. class member_class {
  16255. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  16256. template<typename Class, typename Ret, typename... Args>
  16257. static Class *clazz(Ret (Class::*)(Args...));
  16258. template<typename Class, typename Ret, typename... Args>
  16259. static Class *clazz(Ret (Class::*)(Args...) const);
  16260. template<typename Class, typename Type>
  16261. static Class *clazz(Type Class::*);
  16262. public:
  16263. /*! @brief The class of the given non-static member object or function. */
  16264. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  16265. };
  16266. /**
  16267. * @brief Helper type.
  16268. * @tparam Member A pointer to a non-static member object or function.
  16269. */
  16270. template<typename Member>
  16271. using member_class_t = typename member_class<Member>::type;
  16272. /**
  16273. * @brief Extracts the n-th argument of a _callable_ type.
  16274. * @tparam Index The index of the argument to extract.
  16275. * @tparam Candidate A valid _callable_ type.
  16276. */
  16277. template<std::size_t Index, typename Candidate>
  16278. class nth_argument {
  16279. template<typename Ret, typename... Args>
  16280. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  16281. template<typename Ret, typename Class, typename... Args>
  16282. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  16283. template<typename Ret, typename Class, typename... Args>
  16284. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  16285. template<typename Type, typename Class>
  16286. static constexpr type_list<Type> pick_up(Type Class ::*);
  16287. template<typename Type>
  16288. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  16289. public:
  16290. /*! @brief N-th argument of the _callable_ type. */
  16291. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  16292. };
  16293. /**
  16294. * @brief Helper type.
  16295. * @tparam Index The index of the argument to extract.
  16296. * @tparam Candidate A valid function, member function or data member type.
  16297. */
  16298. template<std::size_t Index, typename Candidate>
  16299. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  16300. } // namespace entt
  16301. template<typename... Type>
  16302. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  16303. template<std::size_t Index, typename... Type>
  16304. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  16305. template<auto... Value>
  16306. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  16307. template<std::size_t Index, auto... Value>
  16308. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  16309. #endif
  16310. // #include "utility.hpp"
  16311. namespace entt {
  16312. /*! @cond TURN_OFF_DOXYGEN */
  16313. namespace internal {
  16314. enum class any_request : std::uint8_t {
  16315. info,
  16316. transfer,
  16317. assign,
  16318. compare,
  16319. copy,
  16320. move
  16321. };
  16322. template<std::size_t Len, std::size_t Align>
  16323. struct basic_any_storage {
  16324. static constexpr bool has_buffer = true;
  16325. union {
  16326. const void *instance{};
  16327. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  16328. alignas(Align) std::byte buffer[Len];
  16329. };
  16330. };
  16331. template<std::size_t Align>
  16332. struct basic_any_storage<0u, Align> {
  16333. static constexpr bool has_buffer = false;
  16334. const void *instance{};
  16335. };
  16336. template<typename Type, std::size_t Len, std::size_t Align>
  16337. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  16338. struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v<Type>> {};
  16339. template<std::size_t Len, std::size_t Align>
  16340. struct in_situ<void, Len, Align>: std::false_type {};
  16341. } // namespace internal
  16342. /*! @endcond */
  16343. /**
  16344. * @brief A SBO friendly, type-safe container for single values of any type.
  16345. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  16346. * @tparam Align Optional alignment requirement.
  16347. */
  16348. template<std::size_t Len, std::size_t Align>
  16349. class basic_any: private internal::basic_any_storage<Len, Align> {
  16350. using request = internal::any_request;
  16351. using base_type = internal::basic_any_storage<Len, Align>;
  16352. using vtable_type = const void *(const request, const basic_any &, const void *);
  16353. using deleter_type = void(const basic_any &);
  16354. template<typename Type>
  16355. static constexpr bool in_situ_v = internal::in_situ<Type, Len, Align>::value;
  16356. template<typename Type>
  16357. static const void *basic_vtable(const request req, const basic_any &value, const void *other) {
  16358. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  16359. switch(const auto *elem = static_cast<const Type *>(value.data()); req) {
  16360. case request::info:
  16361. return &type_id<Type>();
  16362. case request::transfer:
  16363. if constexpr(std::is_move_assignable_v<Type>) {
  16364. // NOLINTNEXTLINE(bugprone-casting-through-void)
  16365. *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  16366. return other;
  16367. }
  16368. [[fallthrough]];
  16369. case request::assign:
  16370. if constexpr(std::is_copy_assignable_v<Type>) {
  16371. *const_cast<Type *>(elem) = *static_cast<const Type *>(other);
  16372. return other;
  16373. }
  16374. break;
  16375. case request::compare:
  16376. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  16377. return (*elem == *static_cast<const Type *>(other)) ? other : nullptr;
  16378. } else {
  16379. return (elem == other) ? other : nullptr;
  16380. }
  16381. case request::copy:
  16382. if constexpr(std::is_copy_constructible_v<Type>) {
  16383. // NOLINTNEXTLINE(bugprone-casting-through-void)
  16384. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*elem);
  16385. }
  16386. break;
  16387. case request::move:
  16388. ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
  16389. if constexpr(in_situ_v<Type>) {
  16390. // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion)
  16391. return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->buffer) Type{std::move(*const_cast<Type *>(elem))};
  16392. }
  16393. }
  16394. return nullptr;
  16395. }
  16396. template<typename Type>
  16397. static void basic_deleter(const basic_any &value) {
  16398. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  16399. ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v<Type>), "Unexpected policy");
  16400. const auto *elem = static_cast<const Type *>(value.data());
  16401. if constexpr(in_situ_v<Type>) {
  16402. (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem);
  16403. } else if constexpr(std::is_array_v<Type>) {
  16404. delete[] elem;
  16405. } else {
  16406. delete elem;
  16407. }
  16408. }
  16409. template<typename Type, typename... Args>
  16410. void initialize([[maybe_unused]] Args &&...args) {
  16411. using plain_type = std::remove_const_t<std::remove_reference_t<Type>>;
  16412. vtable = basic_vtable<plain_type>;
  16413. underlying_type = type_hash<plain_type>::value();
  16414. if constexpr(std::is_void_v<Type>) {
  16415. deleter = nullptr;
  16416. mode = any_policy::empty;
  16417. this->instance = nullptr;
  16418. } else if constexpr(std::is_lvalue_reference_v<Type>) {
  16419. deleter = nullptr;
  16420. mode = std::is_const_v<std::remove_reference_t<Type>> ? any_policy::cref : any_policy::ref;
  16421. static_assert((std::is_lvalue_reference_v<Args> && ...) && (sizeof...(Args) == 1u), "Invalid arguments");
  16422. // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
  16423. this->instance = (std::addressof(args), ...);
  16424. } else if constexpr(in_situ_v<plain_type>) {
  16425. if constexpr(std::is_trivially_destructible_v<plain_type>) {
  16426. deleter = nullptr;
  16427. } else {
  16428. deleter = &basic_deleter<plain_type>;
  16429. }
  16430. mode = any_policy::embedded;
  16431. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  16432. ::new(&this->buffer) plain_type{std::forward<Args>(args)...};
  16433. } else {
  16434. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  16435. ::new(&this->buffer) plain_type(std::forward<Args>(args)...);
  16436. }
  16437. } else {
  16438. deleter = &basic_deleter<plain_type>;
  16439. mode = any_policy::dynamic;
  16440. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  16441. this->instance = new plain_type{std::forward<Args>(args)...};
  16442. } else if constexpr(std::is_array_v<plain_type>) {
  16443. static_assert(sizeof...(Args) == 0u, "Invalid arguments");
  16444. this->instance = new plain_type[std::extent_v<plain_type>]();
  16445. } else {
  16446. this->instance = new plain_type(std::forward<Args>(args)...);
  16447. }
  16448. }
  16449. }
  16450. void invoke_deleter_if_exists() {
  16451. if(deleter != nullptr) {
  16452. deleter(*this);
  16453. }
  16454. }
  16455. public:
  16456. /*! @brief Size of the internal buffer. */
  16457. static constexpr auto length = Len;
  16458. /*! @brief Alignment requirement. */
  16459. static constexpr auto alignment = Align;
  16460. /*! @brief Default constructor. */
  16461. constexpr basic_any() noexcept
  16462. : basic_any{std::in_place_type<void>} {}
  16463. /**
  16464. * @brief Constructs a wrapper by directly initializing the new object.
  16465. * @tparam Type Type of object to use to initialize the wrapper.
  16466. * @tparam Args Types of arguments to use to construct the new instance.
  16467. * @param args Parameters to use to construct the instance.
  16468. */
  16469. template<typename Type, typename... Args>
  16470. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  16471. : base_type{} {
  16472. initialize<Type>(std::forward<Args>(args)...);
  16473. }
  16474. /**
  16475. * @brief Constructs a wrapper taking ownership of the passed object.
  16476. * @tparam Type Type of object to use to initialize the wrapper.
  16477. * @param value A pointer to an object to take ownership of.
  16478. */
  16479. template<typename Type>
  16480. explicit basic_any(std::in_place_t, Type *value)
  16481. : base_type{} {
  16482. static_assert(!std::is_const_v<Type> && !std::is_void_v<Type>, "Non-const non-void pointer required");
  16483. if(value == nullptr) {
  16484. initialize<void>();
  16485. } else {
  16486. initialize<Type &>(*value);
  16487. deleter = &basic_deleter<Type>;
  16488. mode = any_policy::dynamic;
  16489. }
  16490. }
  16491. /**
  16492. * @brief Constructs a wrapper from a given value.
  16493. * @tparam Type Type of object to use to initialize the wrapper.
  16494. * @param value An instance of an object to use to initialize the wrapper.
  16495. */
  16496. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  16497. basic_any(Type &&value)
  16498. : basic_any{std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
  16499. /**
  16500. * @brief Copy constructor.
  16501. * @param other The instance to copy from.
  16502. */
  16503. basic_any(const basic_any &other)
  16504. : basic_any{} {
  16505. other.vtable(request::copy, other, this);
  16506. }
  16507. /**
  16508. * @brief Move constructor.
  16509. * @param other The instance to move from.
  16510. */
  16511. basic_any(basic_any &&other) noexcept
  16512. : base_type{},
  16513. vtable{other.vtable},
  16514. deleter{other.deleter},
  16515. underlying_type{other.underlying_type},
  16516. mode{other.mode} {
  16517. if(other.mode == any_policy::embedded) {
  16518. other.vtable(request::move, other, this);
  16519. } else if(other.mode != any_policy::empty) {
  16520. this->instance = std::exchange(other.instance, nullptr);
  16521. }
  16522. }
  16523. /*! @brief Frees the internal buffer, whatever it means. */
  16524. ~basic_any() {
  16525. invoke_deleter_if_exists();
  16526. }
  16527. /**
  16528. * @brief Copy assignment operator.
  16529. * @param other The instance to copy from.
  16530. * @return This any object.
  16531. */
  16532. basic_any &operator=(const basic_any &other) {
  16533. if(this != &other) {
  16534. invoke_deleter_if_exists();
  16535. if(other) {
  16536. other.vtable(request::copy, other, this);
  16537. } else {
  16538. initialize<void>();
  16539. }
  16540. }
  16541. return *this;
  16542. }
  16543. /**
  16544. * @brief Move assignment operator.
  16545. * @param other The instance to move from.
  16546. * @return This any object.
  16547. */
  16548. basic_any &operator=(basic_any &&other) noexcept {
  16549. if(this != &other) {
  16550. invoke_deleter_if_exists();
  16551. if(other.mode == any_policy::embedded) {
  16552. other.vtable(request::move, other, this);
  16553. } else if(other.mode != any_policy::empty) {
  16554. this->instance = std::exchange(other.instance, nullptr);
  16555. }
  16556. vtable = other.vtable;
  16557. deleter = other.deleter;
  16558. underlying_type = other.underlying_type;
  16559. mode = other.mode;
  16560. }
  16561. return *this;
  16562. }
  16563. /**
  16564. * @brief Value assignment operator.
  16565. * @tparam Type Type of object to use to initialize the wrapper.
  16566. * @param value An instance of an object to use to initialize the wrapper.
  16567. * @return This any object.
  16568. */
  16569. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  16570. basic_any &operator=(Type &&value) {
  16571. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  16572. return *this;
  16573. }
  16574. /**
  16575. * @brief Returns false if a wrapper is empty, true otherwise.
  16576. * @return False if the wrapper is empty, true otherwise.
  16577. */
  16578. [[nodiscard]] bool has_value() const noexcept {
  16579. return (mode != any_policy::empty);
  16580. }
  16581. /**
  16582. * @brief Returns false if the wrapper does not contain the expected type,
  16583. * true otherwise.
  16584. * @param req Expected type.
  16585. * @return False if the wrapper does not contain the expected type, true
  16586. * otherwise.
  16587. */
  16588. [[nodiscard]] bool has_value(const type_info &req) const noexcept {
  16589. return (underlying_type == req.hash());
  16590. }
  16591. /**
  16592. * @brief Returns false if the wrapper does not contain the expected type,
  16593. * true otherwise.
  16594. * @tparam Type Expected type.
  16595. * @return False if the wrapper does not contain the expected type, true
  16596. * otherwise.
  16597. */
  16598. template<typename Type>
  16599. [[nodiscard]] bool has_value() const noexcept {
  16600. static_assert(std::is_same_v<std::remove_const_t<Type>, Type>, "Invalid type");
  16601. return (underlying_type == type_hash<Type>::value());
  16602. }
  16603. /**
  16604. * @brief Returns the object type info if any, `type_id<void>()` otherwise.
  16605. * @return The object type info if any, `type_id<void>()` otherwise.
  16606. */
  16607. [[nodiscard]] const type_info &info() const noexcept {
  16608. return *static_cast<const type_info *>(vtable(request::info, *this, nullptr));
  16609. }
  16610. /*! @copydoc info */
  16611. [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept {
  16612. return info();
  16613. }
  16614. /**
  16615. * @brief Returns an opaque pointer to the contained instance.
  16616. * @return An opaque pointer the contained instance, if any.
  16617. */
  16618. [[nodiscard]] const void *data() const noexcept {
  16619. if constexpr(base_type::has_buffer) {
  16620. return (mode == any_policy::embedded) ? &this->buffer : this->instance;
  16621. } else {
  16622. return this->instance;
  16623. }
  16624. }
  16625. /**
  16626. * @brief Returns an opaque pointer to the contained instance.
  16627. * @param req Expected type.
  16628. * @return An opaque pointer the contained instance, if any.
  16629. */
  16630. [[nodiscard]] const void *data(const type_info &req) const noexcept {
  16631. return has_value(req) ? data() : nullptr;
  16632. }
  16633. /**
  16634. * @brief Returns an opaque pointer to the contained instance.
  16635. * @tparam Type Expected type.
  16636. * @return An opaque pointer the contained instance, if any.
  16637. */
  16638. template<typename Type>
  16639. [[nodiscard]] const Type *data() const noexcept {
  16640. return has_value<std::remove_const_t<Type>>() ? static_cast<const Type *>(data()) : nullptr;
  16641. }
  16642. /**
  16643. * @brief Returns an opaque pointer to the contained instance.
  16644. * @return An opaque pointer the contained instance, if any.
  16645. */
  16646. [[nodiscard]] void *data() noexcept {
  16647. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data());
  16648. }
  16649. /**
  16650. * @brief Returns an opaque pointer to the contained instance.
  16651. * @param req Expected type.
  16652. * @return An opaque pointer the contained instance, if any.
  16653. */
  16654. [[nodiscard]] void *data(const type_info &req) noexcept {
  16655. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data(req));
  16656. }
  16657. /**
  16658. * @brief Returns an opaque pointer to the contained instance.
  16659. * @tparam Type Expected type.
  16660. * @return An opaque pointer the contained instance, if any.
  16661. */
  16662. template<typename Type>
  16663. [[nodiscard]] Type *data() noexcept {
  16664. if constexpr(std::is_const_v<Type>) {
  16665. return std::as_const(*this).template data<std::remove_const_t<Type>>();
  16666. } else {
  16667. return (mode == any_policy::cref) ? nullptr : const_cast<Type *>(std::as_const(*this).template data<std::remove_const_t<Type>>());
  16668. }
  16669. }
  16670. /**
  16671. * @brief Replaces the contained object by creating a new instance directly.
  16672. * @tparam Type Type of object to use to initialize the wrapper.
  16673. * @tparam Args Types of arguments to use to construct the new instance.
  16674. * @param args Parameters to use to construct the instance.
  16675. */
  16676. template<typename Type, typename... Args>
  16677. void emplace(Args &&...args) {
  16678. invoke_deleter_if_exists();
  16679. initialize<Type>(std::forward<Args>(args)...);
  16680. }
  16681. /**
  16682. * @brief Assigns a value to the contained object without replacing it.
  16683. * @param other The value to assign to the contained object.
  16684. * @return True in case of success, false otherwise.
  16685. */
  16686. bool assign(const basic_any &other) {
  16687. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  16688. return (vtable(request::assign, *this, other.data()) != nullptr);
  16689. }
  16690. return false;
  16691. }
  16692. /*! @copydoc assign */
  16693. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  16694. bool assign(basic_any &&other) {
  16695. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  16696. return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr);
  16697. }
  16698. return false;
  16699. }
  16700. /*! @brief Destroys contained object */
  16701. void reset() {
  16702. invoke_deleter_if_exists();
  16703. initialize<void>();
  16704. }
  16705. /**
  16706. * @brief Returns false if a wrapper is empty, true otherwise.
  16707. * @return False if the wrapper is empty, true otherwise.
  16708. */
  16709. [[nodiscard]] explicit operator bool() const noexcept {
  16710. return has_value();
  16711. }
  16712. /**
  16713. * @brief Checks if two wrappers differ in their content.
  16714. * @param other Wrapper with which to compare.
  16715. * @return False if the two objects differ in their content, true otherwise.
  16716. */
  16717. [[nodiscard]] bool operator==(const basic_any &other) const noexcept {
  16718. if(other && (underlying_type == other.underlying_type)) {
  16719. return (vtable(request::compare, *this, other.data()) != nullptr);
  16720. }
  16721. return (!*this && !other);
  16722. }
  16723. /**
  16724. * @brief Checks if two wrappers differ in their content.
  16725. * @param other Wrapper with which to compare.
  16726. * @return True if the two objects differ in their content, false otherwise.
  16727. */
  16728. [[nodiscard]] bool operator!=(const basic_any &other) const noexcept {
  16729. return !(*this == other);
  16730. }
  16731. /**
  16732. * @brief Aliasing constructor.
  16733. * @return A wrapper that shares a reference to an unmanaged object.
  16734. */
  16735. [[nodiscard]] basic_any as_ref() noexcept {
  16736. basic_any other = std::as_const(*this).as_ref();
  16737. other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref);
  16738. return other;
  16739. }
  16740. /*! @copydoc as_ref */
  16741. [[nodiscard]] basic_any as_ref() const noexcept {
  16742. basic_any other{};
  16743. other.instance = data();
  16744. other.vtable = vtable;
  16745. other.underlying_type = underlying_type;
  16746. other.mode = any_policy::cref;
  16747. return other;
  16748. }
  16749. /**
  16750. * @brief Returns true if a wrapper owns its object, false otherwise.
  16751. * @return True if the wrapper owns its object, false otherwise.
  16752. */
  16753. [[nodiscard]] bool owner() const noexcept {
  16754. return (mode == any_policy::dynamic || mode == any_policy::embedded);
  16755. }
  16756. /**
  16757. * @brief Returns the current mode of an any object.
  16758. * @return The current mode of the any object.
  16759. */
  16760. [[nodiscard]] any_policy policy() const noexcept {
  16761. return mode;
  16762. }
  16763. private:
  16764. vtable_type *vtable{};
  16765. deleter_type *deleter{};
  16766. id_type underlying_type{};
  16767. any_policy mode{};
  16768. };
  16769. /**
  16770. * @brief Performs type-safe access to the contained object.
  16771. * @tparam Type Type to which conversion is required.
  16772. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  16773. * @tparam Align Alignment requirement.
  16774. * @param data Target any object.
  16775. * @return The element converted to the requested type.
  16776. */
  16777. template<typename Type, std::size_t Len, std::size_t Align>
  16778. [[nodiscard]] std::remove_const_t<Type> any_cast(const basic_any<Len, Align> &data) noexcept {
  16779. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  16780. ENTT_ASSERT(instance, "Invalid instance");
  16781. return static_cast<Type>(*instance);
  16782. }
  16783. /*! @copydoc any_cast */
  16784. template<typename Type, std::size_t Len, std::size_t Align>
  16785. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &data) noexcept {
  16786. // forces const on non-reference types to make them work also with wrappers for const references
  16787. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  16788. ENTT_ASSERT(instance, "Invalid instance");
  16789. return static_cast<Type>(*instance);
  16790. }
  16791. /*! @copydoc any_cast */
  16792. template<typename Type, std::size_t Len, std::size_t Align>
  16793. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  16794. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &&data) noexcept {
  16795. if constexpr(std::is_copy_constructible_v<std::remove_const_t<std::remove_reference_t<Type>>>) {
  16796. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  16797. return static_cast<Type>(std::move(*instance));
  16798. }
  16799. return any_cast<Type>(data);
  16800. } else {
  16801. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  16802. ENTT_ASSERT(instance, "Invalid instance");
  16803. return static_cast<Type>(std::move(*instance));
  16804. }
  16805. }
  16806. /*! @copydoc any_cast */
  16807. template<typename Type, std::size_t Len, std::size_t Align>
  16808. [[nodiscard]] const Type *any_cast(const basic_any<Len, Align> *data) noexcept {
  16809. return data->template data<std::remove_const_t<Type>>();
  16810. }
  16811. /*! @copydoc any_cast */
  16812. template<typename Type, std::size_t Len, std::size_t Align>
  16813. [[nodiscard]] Type *any_cast(basic_any<Len, Align> *data) noexcept {
  16814. if constexpr(std::is_const_v<Type>) {
  16815. // last attempt to make wrappers for const references return their values
  16816. return any_cast<Type>(&std::as_const(*data));
  16817. } else {
  16818. return data->template data<Type>();
  16819. }
  16820. }
  16821. /**
  16822. * @brief Constructs a wrapper from a given type, passing it all arguments.
  16823. * @tparam Type Type of object to use to initialize the wrapper.
  16824. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  16825. * @tparam Align Optional alignment requirement.
  16826. * @tparam Args Types of arguments to use to construct the new instance.
  16827. * @param args Parameters to use to construct the instance.
  16828. * @return A properly initialized wrapper for an object of the given type.
  16829. */
  16830. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  16831. [[nodiscard]] basic_any<Len, Align> make_any(Args &&...args) {
  16832. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  16833. }
  16834. /**
  16835. * @brief Forwards its argument and avoids copies for lvalue references.
  16836. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  16837. * @tparam Align Optional alignment requirement.
  16838. * @tparam Type Type of argument to use to construct the new instance.
  16839. * @param value Parameter to use to construct the instance.
  16840. * @return A properly initialized and not necessarily owning wrapper.
  16841. */
  16842. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  16843. [[nodiscard]] basic_any<Len, Align> forward_as_any(Type &&value) {
  16844. return basic_any<Len, Align>{std::in_place_type<Type &&>, std::forward<Type>(value)};
  16845. }
  16846. } // namespace entt
  16847. #endif
  16848. // #include "../core/bit.hpp"
  16849. // #include "../core/type_info.hpp"
  16850. // #include "entity.hpp"
  16851. // #include "fwd.hpp"
  16852. namespace entt {
  16853. /*! @cond TURN_OFF_DOXYGEN */
  16854. namespace internal {
  16855. template<typename Container>
  16856. struct sparse_set_iterator final {
  16857. using value_type = typename Container::value_type;
  16858. using pointer = typename Container::const_pointer;
  16859. using reference = typename Container::const_reference;
  16860. using difference_type = typename Container::difference_type;
  16861. using iterator_category = std::random_access_iterator_tag;
  16862. constexpr sparse_set_iterator() noexcept
  16863. : packed{},
  16864. offset{} {}
  16865. constexpr sparse_set_iterator(const Container &ref, const difference_type idx) noexcept
  16866. : packed{&ref},
  16867. offset{idx} {}
  16868. constexpr sparse_set_iterator &operator++() noexcept {
  16869. return --offset, *this;
  16870. }
  16871. constexpr sparse_set_iterator operator++(int) noexcept {
  16872. const sparse_set_iterator orig = *this;
  16873. return ++(*this), orig;
  16874. }
  16875. constexpr sparse_set_iterator &operator--() noexcept {
  16876. return ++offset, *this;
  16877. }
  16878. constexpr sparse_set_iterator operator--(int) noexcept {
  16879. const sparse_set_iterator orig = *this;
  16880. return operator--(), orig;
  16881. }
  16882. constexpr sparse_set_iterator &operator+=(const difference_type value) noexcept {
  16883. offset -= value;
  16884. return *this;
  16885. }
  16886. constexpr sparse_set_iterator operator+(const difference_type value) const noexcept {
  16887. sparse_set_iterator copy = *this;
  16888. return (copy += value);
  16889. }
  16890. constexpr sparse_set_iterator &operator-=(const difference_type value) noexcept {
  16891. return (*this += -value);
  16892. }
  16893. constexpr sparse_set_iterator operator-(const difference_type value) const noexcept {
  16894. return (*this + -value);
  16895. }
  16896. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  16897. return (*packed)[static_cast<typename Container::size_type>(index() - value)];
  16898. }
  16899. [[nodiscard]] constexpr pointer operator->() const noexcept {
  16900. return std::addressof(operator[](0));
  16901. }
  16902. [[nodiscard]] constexpr reference operator*() const noexcept {
  16903. return operator[](0);
  16904. }
  16905. [[nodiscard]] constexpr pointer data() const noexcept {
  16906. return packed ? packed->data() : nullptr;
  16907. }
  16908. [[nodiscard]] constexpr difference_type index() const noexcept {
  16909. return offset - 1;
  16910. }
  16911. private:
  16912. const Container *packed;
  16913. difference_type offset;
  16914. };
  16915. template<typename Container>
  16916. [[nodiscard]] constexpr std::ptrdiff_t operator-(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  16917. return rhs.index() - lhs.index();
  16918. }
  16919. template<typename Container>
  16920. [[nodiscard]] constexpr bool operator==(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  16921. return lhs.index() == rhs.index();
  16922. }
  16923. template<typename Container>
  16924. [[nodiscard]] constexpr bool operator!=(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  16925. return !(lhs == rhs);
  16926. }
  16927. template<typename Container>
  16928. [[nodiscard]] constexpr bool operator<(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  16929. return lhs.index() > rhs.index();
  16930. }
  16931. template<typename Container>
  16932. [[nodiscard]] constexpr bool operator>(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  16933. return rhs < lhs;
  16934. }
  16935. template<typename Container>
  16936. [[nodiscard]] constexpr bool operator<=(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  16937. return !(lhs > rhs);
  16938. }
  16939. template<typename Container>
  16940. [[nodiscard]] constexpr bool operator>=(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  16941. return !(lhs < rhs);
  16942. }
  16943. } // namespace internal
  16944. /*! @endcond */
  16945. /**
  16946. * @brief Sparse set implementation.
  16947. *
  16948. * Sparse set or packed array or whatever is the name users give it.<br/>
  16949. * Two arrays: an _external_ one and an _internal_ one; a _sparse_ one and a
  16950. * _packed_ one; one used for direct access through contiguous memory, the other
  16951. * one used to get the data through an extra level of indirection.<br/>
  16952. * This type of data structure is widely documented in the literature and on the
  16953. * web. This is nothing more than a customized implementation suitable for the
  16954. * purpose of the framework.
  16955. *
  16956. * @note
  16957. * Internal data structures arrange elements to maximize performance. There are
  16958. * no guarantees that entities are returned in the insertion order when iterate
  16959. * a sparse set. Do not make assumption on the order in any case.
  16960. *
  16961. * @tparam Entity A valid entity type.
  16962. * @tparam Allocator Type of allocator used to manage memory and elements.
  16963. */
  16964. template<typename Entity, typename Allocator>
  16965. class basic_sparse_set {
  16966. using alloc_traits = std::allocator_traits<Allocator>;
  16967. static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");
  16968. using sparse_container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  16969. using packed_container_type = std::vector<Entity, Allocator>;
  16970. using traits_type = entt_traits<Entity>;
  16971. static constexpr auto max_size = static_cast<std::size_t>(traits_type::to_entity(null));
  16972. // it could be auto but gcc complains and emits a warning due to a false positive
  16973. [[nodiscard]] std::size_t policy_to_head() const noexcept {
  16974. return static_cast<size_type>(max_size * static_cast<std::remove_const_t<decltype(max_size)>>(mode != deletion_policy::swap_only));
  16975. }
  16976. [[nodiscard]] auto entity_to_pos(const Entity entt) const noexcept {
  16977. return static_cast<size_type>(traits_type::to_entity(entt));
  16978. }
  16979. [[nodiscard]] auto pos_to_page(const std::size_t pos) const noexcept {
  16980. return static_cast<size_type>(pos / traits_type::page_size);
  16981. }
  16982. [[nodiscard]] auto sparse_ptr(const Entity entt) const {
  16983. const auto pos = entity_to_pos(entt);
  16984. const auto page = pos_to_page(pos);
  16985. return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod(pos, traits_type::page_size)) : nullptr;
  16986. }
  16987. [[nodiscard]] auto &sparse_ref(const Entity entt) const {
  16988. ENTT_ASSERT(sparse_ptr(entt), "Invalid element");
  16989. const auto pos = entity_to_pos(entt);
  16990. return sparse[pos_to_page(pos)][fast_mod(pos, traits_type::page_size)];
  16991. }
  16992. [[nodiscard]] auto to_iterator(const Entity entt) const {
  16993. return --(end() - static_cast<difference_type>(index(entt)));
  16994. }
  16995. [[nodiscard]] auto &assure_at_least(const Entity entt) {
  16996. const auto pos = entity_to_pos(entt);
  16997. const auto page = pos_to_page(pos);
  16998. if(!(page < sparse.size())) {
  16999. sparse.resize(page + 1u, nullptr);
  17000. }
  17001. if(!sparse[page]) {
  17002. constexpr entity_type init = null;
  17003. auto page_allocator{packed.get_allocator()};
  17004. sparse[page] = alloc_traits::allocate(page_allocator, traits_type::page_size);
  17005. std::uninitialized_fill(sparse[page], sparse[page] + traits_type::page_size, init);
  17006. }
  17007. return sparse[page][fast_mod(pos, traits_type::page_size)];
  17008. }
  17009. void release_sparse_pages() {
  17010. auto page_allocator{packed.get_allocator()};
  17011. for(auto &&page: sparse) {
  17012. if(page != nullptr) {
  17013. std::destroy(page, page + traits_type::page_size);
  17014. alloc_traits::deallocate(page_allocator, page, traits_type::page_size);
  17015. page = nullptr;
  17016. }
  17017. }
  17018. }
  17019. void swap_at(const std::size_t lhs, const std::size_t rhs) {
  17020. auto &from = packed[lhs];
  17021. auto &to = packed[rhs];
  17022. sparse_ref(from) = traits_type::combine(static_cast<typename traits_type::entity_type>(rhs), traits_type::to_integral(from));
  17023. sparse_ref(to) = traits_type::combine(static_cast<typename traits_type::entity_type>(lhs), traits_type::to_integral(to));
  17024. std::swap(from, to);
  17025. }
  17026. private:
  17027. [[nodiscard]] virtual const void *get_at(const std::size_t) const {
  17028. return nullptr;
  17029. }
  17030. virtual void swap_or_move([[maybe_unused]] const std::size_t lhs, [[maybe_unused]] const std::size_t rhs) {
  17031. ENTT_ASSERT((mode != deletion_policy::swap_only) || ((lhs < head) == (rhs < head)), "Cross swapping is not supported");
  17032. }
  17033. protected:
  17034. /*! @brief Random access iterator type. */
  17035. using basic_iterator = internal::sparse_set_iterator<packed_container_type>;
  17036. /**
  17037. * @brief Erases an entity from a sparse set.
  17038. * @param it An iterator to the element to pop.
  17039. */
  17040. void swap_only(const basic_iterator it) {
  17041. ENTT_ASSERT(mode == deletion_policy::swap_only, "Deletion policy mismatch");
  17042. const auto pos = index(*it);
  17043. bump(traits_type::next(*it));
  17044. swap_at(pos, head -= (pos < head));
  17045. }
  17046. /**
  17047. * @brief Erases an entity from a sparse set.
  17048. * @param it An iterator to the element to pop.
  17049. */
  17050. void swap_and_pop(const basic_iterator it) {
  17051. ENTT_ASSERT(mode == deletion_policy::swap_and_pop, "Deletion policy mismatch");
  17052. auto &self = sparse_ref(*it);
  17053. const auto entt = traits_type::to_entity(self);
  17054. sparse_ref(packed.back()) = traits_type::combine(entt, traits_type::to_integral(packed.back()));
  17055. packed[static_cast<size_type>(entt)] = packed.back();
  17056. // unnecessary but it helps to detect nasty bugs
  17057. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  17058. ENTT_ASSERT((packed.back() = null, true), "");
  17059. // lazy self-assignment guard
  17060. self = null;
  17061. packed.pop_back();
  17062. }
  17063. /**
  17064. * @brief Erases an entity from a sparse set.
  17065. * @param it An iterator to the element to pop.
  17066. */
  17067. void in_place_pop(const basic_iterator it) {
  17068. ENTT_ASSERT(mode == deletion_policy::in_place, "Deletion policy mismatch");
  17069. const auto pos = entity_to_pos(std::exchange(sparse_ref(*it), null));
  17070. packed[pos] = traits_type::combine(static_cast<typename traits_type::entity_type>(std::exchange(head, pos)), tombstone);
  17071. }
  17072. /**
  17073. * @brief Erases entities from a sparse set.
  17074. * @param first An iterator to the first element of the range of entities.
  17075. * @param last An iterator past the last element of the range of entities.
  17076. */
  17077. virtual void pop(basic_iterator first, basic_iterator last) {
  17078. switch(mode) {
  17079. case deletion_policy::swap_and_pop:
  17080. for(; first != last; ++first) {
  17081. swap_and_pop(first);
  17082. }
  17083. break;
  17084. case deletion_policy::in_place:
  17085. for(; first != last; ++first) {
  17086. in_place_pop(first);
  17087. }
  17088. break;
  17089. case deletion_policy::swap_only:
  17090. for(; first != last; ++first) {
  17091. swap_only(first);
  17092. }
  17093. break;
  17094. }
  17095. }
  17096. /*! @brief Erases all entities of a sparse set. */
  17097. virtual void pop_all() {
  17098. switch(mode) {
  17099. case deletion_policy::in_place:
  17100. if(head != max_size) {
  17101. for(auto &&elem: packed) {
  17102. if(elem != tombstone) {
  17103. sparse_ref(elem) = null;
  17104. }
  17105. }
  17106. break;
  17107. }
  17108. [[fallthrough]];
  17109. case deletion_policy::swap_only:
  17110. case deletion_policy::swap_and_pop:
  17111. for(auto &&elem: packed) {
  17112. sparse_ref(elem) = null;
  17113. }
  17114. break;
  17115. }
  17116. head = policy_to_head();
  17117. packed.clear();
  17118. }
  17119. /**
  17120. * @brief Assigns an entity to a sparse set.
  17121. * @param entt A valid identifier.
  17122. * @param force_back Force back insertion.
  17123. * @return Iterator pointing to the emplaced element.
  17124. */
  17125. virtual basic_iterator try_emplace(const Entity entt, const bool force_back, const void * = nullptr) {
  17126. ENTT_ASSERT(entt != null && entt != tombstone, "Invalid element");
  17127. auto &elem = assure_at_least(entt);
  17128. auto pos = size();
  17129. switch(mode) {
  17130. case deletion_policy::in_place:
  17131. if(head != max_size && !force_back) {
  17132. pos = head;
  17133. ENTT_ASSERT(elem == null, "Slot not available");
  17134. elem = traits_type::combine(static_cast<typename traits_type::entity_type>(head), traits_type::to_integral(entt));
  17135. head = entity_to_pos(std::exchange(packed[pos], entt));
  17136. break;
  17137. }
  17138. [[fallthrough]];
  17139. case deletion_policy::swap_and_pop:
  17140. packed.push_back(entt);
  17141. ENTT_ASSERT(elem == null, "Slot not available");
  17142. elem = traits_type::combine(static_cast<typename traits_type::entity_type>(packed.size() - 1u), traits_type::to_integral(entt));
  17143. break;
  17144. case deletion_policy::swap_only:
  17145. if(elem == null) {
  17146. packed.push_back(entt);
  17147. elem = traits_type::combine(static_cast<typename traits_type::entity_type>(packed.size() - 1u), traits_type::to_integral(entt));
  17148. } else {
  17149. ENTT_ASSERT(!(entity_to_pos(elem) < head), "Slot not available");
  17150. bump(entt);
  17151. }
  17152. pos = head++;
  17153. swap_at(entity_to_pos(elem), pos);
  17154. break;
  17155. }
  17156. return iterator{packed, static_cast<difference_type>(++pos)};
  17157. }
  17158. /*! @brief Forwards variables to derived classes, if any. */
  17159. // NOLINTNEXTLINE(performance-unnecessary-value-param)
  17160. virtual void bind_any(any) noexcept {}
  17161. public:
  17162. /*! @brief Allocator type. */
  17163. using allocator_type = Allocator;
  17164. /*! @brief Underlying entity identifier. */
  17165. using entity_type = typename traits_type::value_type;
  17166. /*! @brief Underlying version type. */
  17167. using version_type = typename traits_type::version_type;
  17168. /*! @brief Unsigned integer type. */
  17169. using size_type = std::size_t;
  17170. /*! @brief Signed integer type. */
  17171. using difference_type = std::ptrdiff_t;
  17172. /*! @brief Pointer type to contained entities. */
  17173. using pointer = typename packed_container_type::const_pointer;
  17174. /*! @brief Random access iterator type. */
  17175. using iterator = basic_iterator;
  17176. /*! @brief Constant random access iterator type. */
  17177. using const_iterator = iterator;
  17178. /*! @brief Reverse iterator type. */
  17179. using reverse_iterator = std::reverse_iterator<iterator>;
  17180. /*! @brief Constant reverse iterator type. */
  17181. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  17182. /*! @brief Default constructor. */
  17183. basic_sparse_set()
  17184. : basic_sparse_set{type_id<void>()} {}
  17185. /**
  17186. * @brief Constructs an empty container with a given allocator.
  17187. * @param allocator The allocator to use.
  17188. */
  17189. explicit basic_sparse_set(const allocator_type &allocator)
  17190. : basic_sparse_set{deletion_policy::swap_and_pop, allocator} {}
  17191. /**
  17192. * @brief Constructs an empty container with the given policy and allocator.
  17193. * @param pol Type of deletion policy.
  17194. * @param allocator The allocator to use (possibly default-constructed).
  17195. */
  17196. explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {})
  17197. : basic_sparse_set{type_id<void>(), pol, allocator} {}
  17198. /**
  17199. * @brief Constructs an empty container with the given value type, policy
  17200. * and allocator.
  17201. * @param elem Returned value type, if any.
  17202. * @param pol Type of deletion policy.
  17203. * @param allocator The allocator to use (possibly default-constructed).
  17204. */
  17205. explicit basic_sparse_set(const type_info &elem, deletion_policy pol = deletion_policy::swap_and_pop, const allocator_type &allocator = {})
  17206. : sparse{allocator},
  17207. packed{allocator},
  17208. descriptor{&elem},
  17209. mode{pol},
  17210. head{policy_to_head()} {
  17211. ENTT_ASSERT(traits_type::version_mask || mode != deletion_policy::in_place, "Policy does not support zero-sized versions");
  17212. }
  17213. /*! @brief Default copy constructor, deleted on purpose. */
  17214. basic_sparse_set(const basic_sparse_set &) = delete;
  17215. /**
  17216. * @brief Move constructor.
  17217. * @param other The instance to move from.
  17218. */
  17219. basic_sparse_set(basic_sparse_set &&other) noexcept
  17220. : sparse{std::move(other.sparse)},
  17221. packed{std::move(other.packed)},
  17222. descriptor{other.descriptor},
  17223. mode{other.mode},
  17224. head{std::exchange(other.head, policy_to_head())} {}
  17225. /**
  17226. * @brief Allocator-extended move constructor.
  17227. * @param other The instance to move from.
  17228. * @param allocator The allocator to use.
  17229. */
  17230. basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator)
  17231. : sparse{std::move(other.sparse), allocator},
  17232. packed{std::move(other.packed), allocator},
  17233. descriptor{other.descriptor},
  17234. mode{other.mode},
  17235. head{std::exchange(other.head, policy_to_head())} {
  17236. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed");
  17237. }
  17238. /*! @brief Default destructor. */
  17239. virtual ~basic_sparse_set() {
  17240. release_sparse_pages();
  17241. }
  17242. /**
  17243. * @brief Default copy assignment operator, deleted on purpose.
  17244. * @return This sparse set.
  17245. */
  17246. basic_sparse_set &operator=(const basic_sparse_set &) = delete;
  17247. /**
  17248. * @brief Move assignment operator.
  17249. * @param other The instance to move from.
  17250. * @return This sparse set.
  17251. */
  17252. basic_sparse_set &operator=(basic_sparse_set &&other) noexcept {
  17253. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed");
  17254. swap(other);
  17255. return *this;
  17256. }
  17257. /**
  17258. * @brief Exchanges the contents with those of a given sparse set.
  17259. * @param other Sparse set to exchange the content with.
  17260. */
  17261. void swap(basic_sparse_set &other) noexcept {
  17262. using std::swap;
  17263. swap(sparse, other.sparse);
  17264. swap(packed, other.packed);
  17265. swap(descriptor, other.descriptor);
  17266. swap(mode, other.mode);
  17267. swap(head, other.head);
  17268. }
  17269. /**
  17270. * @brief Returns the associated allocator.
  17271. * @return The associated allocator.
  17272. */
  17273. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  17274. return packed.get_allocator();
  17275. }
  17276. /**
  17277. * @brief Returns the deletion policy of a sparse set.
  17278. * @return The deletion policy of the sparse set.
  17279. */
  17280. [[nodiscard]] deletion_policy policy() const noexcept {
  17281. return mode;
  17282. }
  17283. /**
  17284. * @brief Returns data on the free list whose meaning depends on the mode.
  17285. * @return Free list information that is mode dependent.
  17286. */
  17287. [[nodiscard]] size_type free_list() const noexcept {
  17288. return head;
  17289. }
  17290. /**
  17291. * @brief Sets data on the free list whose meaning depends on the mode.
  17292. * @param value Free list information that is mode dependent.
  17293. */
  17294. void free_list(const size_type value) noexcept {
  17295. ENTT_ASSERT((mode == deletion_policy::swap_only) && !(value > packed.size()), "Invalid value");
  17296. head = value;
  17297. }
  17298. /**
  17299. * @brief Increases the capacity of a sparse set.
  17300. *
  17301. * If the new capacity is greater than the current capacity, new storage is
  17302. * allocated, otherwise the method does nothing.
  17303. *
  17304. * @param cap Desired capacity.
  17305. */
  17306. virtual void reserve(const size_type cap) {
  17307. packed.reserve(cap);
  17308. }
  17309. /**
  17310. * @brief Returns the number of elements that a sparse set has currently
  17311. * allocated space for.
  17312. * @return Capacity of the sparse set.
  17313. */
  17314. [[nodiscard]] virtual size_type capacity() const noexcept {
  17315. return packed.capacity();
  17316. }
  17317. /*! @brief Requests the removal of unused capacity. */
  17318. virtual void shrink_to_fit() {
  17319. sparse_container_type other{sparse.get_allocator()};
  17320. const auto len = sparse.size();
  17321. size_type cnt{};
  17322. other.reserve(len);
  17323. for(auto &&elem: std::as_const(packed)) {
  17324. if(elem != tombstone) {
  17325. if(const auto page = pos_to_page(entity_to_pos(elem)); sparse[page] != nullptr) {
  17326. if(const auto sz = page + 1u; sz > other.size()) {
  17327. other.resize(sz, nullptr);
  17328. }
  17329. other[page] = std::exchange(sparse[page], nullptr);
  17330. if(++cnt == len) {
  17331. // early exit due to lack of pages
  17332. break;
  17333. }
  17334. }
  17335. }
  17336. }
  17337. release_sparse_pages();
  17338. sparse.swap(other);
  17339. sparse.shrink_to_fit();
  17340. packed.shrink_to_fit();
  17341. }
  17342. /**
  17343. * @brief Returns the extent of a sparse set.
  17344. *
  17345. * The extent of a sparse set is also the size of the internal sparse array.
  17346. * There is no guarantee that all pages have been allocated, nor that the
  17347. * internal packed array is be the same size.
  17348. *
  17349. * @return Extent of the sparse set.
  17350. */
  17351. [[nodiscard]] size_type extent() const noexcept {
  17352. return sparse.size() * traits_type::page_size;
  17353. }
  17354. /**
  17355. * @brief Returns the number of elements in a sparse set.
  17356. *
  17357. * The number of elements is also the size of the internal packed array.
  17358. * There is no guarantee that the internal sparse array has the same size.
  17359. * Usually the size of the internal sparse array is equal or greater than
  17360. * the one of the internal packed array.
  17361. *
  17362. * @return Number of elements.
  17363. */
  17364. [[nodiscard]] size_type size() const noexcept {
  17365. return packed.size();
  17366. }
  17367. /**
  17368. * @brief Checks whether a sparse set is empty.
  17369. * @return True if the sparse set is empty, false otherwise.
  17370. */
  17371. [[nodiscard]] bool empty() const noexcept {
  17372. return packed.empty();
  17373. }
  17374. /**
  17375. * @brief Checks whether a sparse set is fully packed.
  17376. * @return True if the sparse set is fully packed, false otherwise.
  17377. */
  17378. [[nodiscard]] bool contiguous() const noexcept {
  17379. return (mode != deletion_policy::in_place) || (head == max_size);
  17380. }
  17381. /**
  17382. * @brief Direct access to the internal packed array.
  17383. * @return A pointer to the internal packed array.
  17384. */
  17385. [[nodiscard]] pointer data() const noexcept {
  17386. return packed.data();
  17387. }
  17388. /**
  17389. * @brief Returns an iterator to the beginning.
  17390. *
  17391. * If the sparse set is empty, the returned iterator will be equal to
  17392. * `end()`.
  17393. *
  17394. * @return An iterator to the first entity of the sparse set.
  17395. */
  17396. [[nodiscard]] iterator begin() const noexcept {
  17397. const auto pos = static_cast<difference_type>(packed.size());
  17398. return iterator{packed, pos};
  17399. }
  17400. /*! @copydoc begin */
  17401. [[nodiscard]] const_iterator cbegin() const noexcept {
  17402. return begin();
  17403. }
  17404. /**
  17405. * @brief Returns an iterator to the end.
  17406. * @return An iterator to the element following the last entity of a sparse
  17407. * set.
  17408. */
  17409. [[nodiscard]] iterator end() const noexcept {
  17410. return iterator{packed, {}};
  17411. }
  17412. /*! @copydoc end */
  17413. [[nodiscard]] const_iterator cend() const noexcept {
  17414. return end();
  17415. }
  17416. /**
  17417. * @brief Returns a reverse iterator to the beginning.
  17418. *
  17419. * If the sparse set is empty, the returned iterator will be equal to
  17420. * `rend()`.
  17421. *
  17422. * @return An iterator to the first entity of the reversed internal packed
  17423. * array.
  17424. */
  17425. [[nodiscard]] reverse_iterator rbegin() const noexcept {
  17426. return std::make_reverse_iterator(end());
  17427. }
  17428. /*! @copydoc rbegin */
  17429. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  17430. return rbegin();
  17431. }
  17432. /**
  17433. * @brief Returns a reverse iterator to the end.
  17434. * @return An iterator to the element following the last entity of the
  17435. * reversed sparse set.
  17436. */
  17437. [[nodiscard]] reverse_iterator rend() const noexcept {
  17438. return std::make_reverse_iterator(begin());
  17439. }
  17440. /*! @copydoc rend */
  17441. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  17442. return rend();
  17443. }
  17444. /**
  17445. * @brief Finds an entity.
  17446. * @param entt A valid identifier.
  17447. * @return An iterator to the given entity if it's found, past the end
  17448. * iterator otherwise.
  17449. */
  17450. [[nodiscard]] const_iterator find(const entity_type entt) const noexcept {
  17451. return contains(entt) ? to_iterator(entt) : end();
  17452. }
  17453. /**
  17454. * @brief Checks if a sparse set contains an entity.
  17455. * @param entt A valid identifier.
  17456. * @return True if the sparse set contains the entity, false otherwise.
  17457. */
  17458. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  17459. const auto *elem = sparse_ptr(entt);
  17460. constexpr auto cap = traits_type::entity_mask;
  17461. constexpr auto mask = traits_type::to_integral(null) & ~cap;
  17462. // testing versions permits to avoid accessing the packed array
  17463. return elem && (((mask & traits_type::to_integral(entt)) ^ traits_type::to_integral(*elem)) < cap);
  17464. }
  17465. /**
  17466. * @brief Returns the contained version for an identifier.
  17467. * @param entt A valid identifier.
  17468. * @return The version for the given identifier if present, the tombstone
  17469. * version otherwise.
  17470. */
  17471. [[nodiscard]] version_type current(const entity_type entt) const noexcept {
  17472. const auto *elem = sparse_ptr(entt);
  17473. constexpr auto fallback = traits_type::to_version(tombstone);
  17474. return elem ? traits_type::to_version(*elem) : fallback;
  17475. }
  17476. /**
  17477. * @brief Returns the position of an entity in a sparse set.
  17478. *
  17479. * @warning
  17480. * Attempting to get the position of an entity that doesn't belong to the
  17481. * sparse set results in undefined behavior.
  17482. *
  17483. * @param entt A valid identifier.
  17484. * @return The position of the entity in the sparse set.
  17485. */
  17486. [[nodiscard]] size_type index(const entity_type entt) const noexcept {
  17487. ENTT_ASSERT(contains(entt), "Set does not contain entity");
  17488. return entity_to_pos(sparse_ref(entt));
  17489. }
  17490. /**
  17491. * @brief Returns the entity at specified location.
  17492. * @param pos The position for which to return the entity.
  17493. * @return The entity at specified location.
  17494. */
  17495. [[nodiscard]] entity_type operator[](const size_type pos) const noexcept {
  17496. ENTT_ASSERT(pos < packed.size(), "Index out of bounds");
  17497. return packed[pos];
  17498. }
  17499. /**
  17500. * @brief Returns the element assigned to an entity, if any.
  17501. *
  17502. * @warning
  17503. * Attempting to use an entity that doesn't belong to the sparse set results
  17504. * in undefined behavior.
  17505. *
  17506. * @param entt A valid identifier.
  17507. * @return An opaque pointer to the element assigned to the entity, if any.
  17508. */
  17509. [[nodiscard]] const void *value(const entity_type entt) const noexcept {
  17510. return get_at(index(entt));
  17511. }
  17512. /*! @copydoc value */
  17513. [[nodiscard]] void *value(const entity_type entt) noexcept {
  17514. return const_cast<void *>(std::as_const(*this).value(entt));
  17515. }
  17516. /**
  17517. * @brief Assigns an entity to a sparse set.
  17518. *
  17519. * @warning
  17520. * Attempting to assign an entity that already belongs to the sparse set
  17521. * results in undefined behavior.
  17522. *
  17523. * @param entt A valid identifier.
  17524. * @param elem Optional opaque element to forward to mixins, if any.
  17525. * @return Iterator pointing to the emplaced element in case of success, the
  17526. * `end()` iterator otherwise.
  17527. */
  17528. iterator push(const entity_type entt, const void *elem = nullptr) {
  17529. return try_emplace(entt, false, elem);
  17530. }
  17531. /**
  17532. * @brief Assigns one or more entities to a sparse set.
  17533. *
  17534. * @warning
  17535. * Attempting to assign an entity that already belongs to the sparse set
  17536. * results in undefined behavior.
  17537. *
  17538. * @tparam It Type of input iterator.
  17539. * @param first An iterator to the first element of the range of entities.
  17540. * @param last An iterator past the last element of the range of entities.
  17541. * @return Iterator pointing to the first element inserted in case of
  17542. * success, the `end()` iterator otherwise.
  17543. */
  17544. template<typename It>
  17545. iterator push(It first, It last) {
  17546. auto curr = end();
  17547. for(; first != last; ++first) {
  17548. curr = try_emplace(*first, true);
  17549. }
  17550. return curr;
  17551. }
  17552. /**
  17553. * @brief Bump the version number of an entity.
  17554. *
  17555. * @warning
  17556. * Attempting to bump the version of an entity that doesn't belong to the
  17557. * sparse set results in undefined behavior.
  17558. *
  17559. * @param entt A valid identifier.
  17560. * @return The version of the given identifier.
  17561. */
  17562. version_type bump(const entity_type entt) {
  17563. auto &elem = sparse_ref(entt);
  17564. ENTT_ASSERT(entt != null && elem != tombstone, "Cannot set the required version");
  17565. elem = traits_type::combine(traits_type::to_integral(elem), traits_type::to_integral(entt));
  17566. packed[entity_to_pos(elem)] = entt;
  17567. return traits_type::to_version(entt);
  17568. }
  17569. /**
  17570. * @brief Erases an entity from a sparse set.
  17571. *
  17572. * @warning
  17573. * Attempting to erase an entity that doesn't belong to the sparse set
  17574. * results in undefined behavior.
  17575. *
  17576. * @param entt A valid identifier.
  17577. */
  17578. void erase(const entity_type entt) {
  17579. const auto it = to_iterator(entt);
  17580. pop(it, it + 1u);
  17581. }
  17582. /**
  17583. * @brief Erases entities from a set.
  17584. *
  17585. * @sa erase
  17586. *
  17587. * @tparam It Type of input iterator.
  17588. * @param first An iterator to the first element of the range of entities.
  17589. * @param last An iterator past the last element of the range of entities.
  17590. */
  17591. template<typename It>
  17592. void erase(It first, It last) {
  17593. if constexpr(std::is_same_v<It, basic_iterator>) {
  17594. pop(first, last);
  17595. } else {
  17596. for(; first != last; ++first) {
  17597. erase(*first);
  17598. }
  17599. }
  17600. }
  17601. /**
  17602. * @brief Removes an entity from a sparse set if it exists.
  17603. * @param entt A valid identifier.
  17604. * @return True if the entity is actually removed, false otherwise.
  17605. */
  17606. bool remove(const entity_type entt) {
  17607. return contains(entt) && (erase(entt), true);
  17608. }
  17609. /**
  17610. * @brief Removes entities from a sparse set if they exist.
  17611. * @tparam It Type of input iterator.
  17612. * @param first An iterator to the first element of the range of entities.
  17613. * @param last An iterator past the last element of the range of entities.
  17614. * @return The number of entities actually removed.
  17615. */
  17616. template<typename It>
  17617. size_type remove(It first, It last) {
  17618. size_type count{};
  17619. if constexpr(std::is_same_v<It, basic_iterator>) {
  17620. while(first != last) {
  17621. while(first != last && !contains(*first)) {
  17622. ++first;
  17623. }
  17624. const auto it = first;
  17625. while(first != last && contains(*first)) {
  17626. ++first;
  17627. }
  17628. count += static_cast<size_type>(std::distance(it, first));
  17629. erase(it, first);
  17630. }
  17631. } else {
  17632. for(; first != last; ++first) {
  17633. count += remove(*first);
  17634. }
  17635. }
  17636. return count;
  17637. }
  17638. /*! @brief Removes all tombstones from a sparse set. */
  17639. void compact() {
  17640. if(mode == deletion_policy::in_place) {
  17641. size_type from = packed.size();
  17642. size_type pos = std::exchange(head, max_size);
  17643. for(; from && packed[from - 1u] == tombstone; --from) {}
  17644. while(pos != max_size) {
  17645. if(const auto to = std::exchange(pos, entity_to_pos(packed[pos])); to < from) {
  17646. --from;
  17647. swap_or_move(from, to);
  17648. packed[to] = packed[from];
  17649. const auto elem = static_cast<typename traits_type::entity_type>(to);
  17650. sparse_ref(packed[to]) = traits_type::combine(elem, traits_type::to_integral(packed[to]));
  17651. for(; from && packed[from - 1u] == tombstone; --from) {}
  17652. }
  17653. }
  17654. packed.erase(packed.begin() + static_cast<difference_type>(from), packed.end());
  17655. }
  17656. }
  17657. /**
  17658. * @brief Swaps two entities in a sparse set.
  17659. *
  17660. * For what it's worth, this function affects both the internal sparse array
  17661. * and the internal packed array. Users should not care of that anyway.
  17662. *
  17663. * @warning
  17664. * Attempting to swap entities that don't belong to the sparse set results
  17665. * in undefined behavior.
  17666. *
  17667. * @param lhs A valid identifier.
  17668. * @param rhs A valid identifier.
  17669. */
  17670. void swap_elements(const entity_type lhs, const entity_type rhs) {
  17671. const auto from = index(lhs);
  17672. const auto to = index(rhs);
  17673. // basic no-leak guarantee if swapping throws
  17674. swap_or_move(from, to);
  17675. swap_at(from, to);
  17676. }
  17677. /**
  17678. * @brief Sort the first count elements according to the given comparison
  17679. * function.
  17680. *
  17681. * The comparison function object must return `true` if the first element
  17682. * is _less_ than the second one, `false` otherwise. The signature of the
  17683. * comparison function should be equivalent to the following:
  17684. *
  17685. * @code{.cpp}
  17686. * bool(const Entity, const Entity);
  17687. * @endcode
  17688. *
  17689. * Moreover, the comparison function object shall induce a
  17690. * _strict weak ordering_ on the values.
  17691. *
  17692. * The sort function object must offer a member function template
  17693. * `operator()` that accepts three arguments:
  17694. *
  17695. * * An iterator to the first element of the range to sort.
  17696. * * An iterator past the last element of the range to sort.
  17697. * * A comparison function to use to compare the elements.
  17698. *
  17699. * @tparam Compare Type of comparison function object.
  17700. * @tparam Sort Type of sort function object.
  17701. * @tparam Args Types of arguments to forward to the sort function object.
  17702. * @param length Number of elements to sort.
  17703. * @param compare A valid comparison function object.
  17704. * @param algo A valid sort function object.
  17705. * @param args Arguments to forward to the sort function object, if any.
  17706. */
  17707. template<typename Compare, typename Sort = std_sort, typename... Args>
  17708. void sort_n(const size_type length, Compare compare, Sort algo = Sort{}, Args &&...args) {
  17709. ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed");
  17710. ENTT_ASSERT(!(length > packed.size()), "Length exceeds the number of elements");
  17711. algo(packed.rend() - static_cast<difference_type>(length), packed.rend(), std::move(compare), std::forward<Args>(args)...);
  17712. for(size_type pos{}; pos < length; ++pos) {
  17713. auto curr = pos;
  17714. auto next = index(packed[curr]);
  17715. while(curr != next) {
  17716. const auto idx = index(packed[next]);
  17717. const auto entt = packed[curr];
  17718. swap_or_move(next, idx);
  17719. const auto elem = static_cast<typename traits_type::entity_type>(curr);
  17720. sparse_ref(entt) = traits_type::combine(elem, traits_type::to_integral(packed[curr]));
  17721. curr = std::exchange(next, idx);
  17722. }
  17723. }
  17724. }
  17725. /**
  17726. * @brief Sort all elements according to the given comparison function.
  17727. *
  17728. * @sa sort_n
  17729. *
  17730. * @tparam Compare Type of comparison function object.
  17731. * @tparam Sort Type of sort function object.
  17732. * @tparam Args Types of arguments to forward to the sort function object.
  17733. * @param compare A valid comparison function object.
  17734. * @param algo A valid sort function object.
  17735. * @param args Arguments to forward to the sort function object, if any.
  17736. */
  17737. template<typename Compare, typename Sort = std_sort, typename... Args>
  17738. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  17739. const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size();
  17740. sort_n(len, std::move(compare), std::move(algo), std::forward<Args>(args)...);
  17741. }
  17742. /**
  17743. * @brief Sort entities according to their order in a range.
  17744. *
  17745. * Entities that are part of both the sparse set and the range are ordered
  17746. * internally according to the order they have in the range.<br/>
  17747. * All other entities goes to the end of the sparse set and there are no
  17748. * guarantees on their order.
  17749. *
  17750. * @tparam It Type of input iterator.
  17751. * @param first An iterator to the first element of the range of entities.
  17752. * @param last An iterator past the last element of the range of entities.
  17753. * @return An iterator past the last of the elements actually shared.
  17754. */
  17755. template<typename It>
  17756. iterator sort_as(It first, It last) {
  17757. ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed");
  17758. const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size();
  17759. auto it = end() - static_cast<difference_type>(len);
  17760. for(const auto other = end(); (it != other) && (first != last); ++first) {
  17761. if(const auto curr = *first; contains(curr)) {
  17762. if(const auto entt = *it; entt != curr) {
  17763. // basic no-leak guarantee (with invalid state) if swapping throws
  17764. swap_elements(entt, curr);
  17765. }
  17766. ++it;
  17767. }
  17768. }
  17769. return it;
  17770. }
  17771. /*! @brief Clears a sparse set. */
  17772. void clear() {
  17773. pop_all();
  17774. // sanity check to avoid subtle issues due to storage classes
  17775. ENTT_ASSERT((compact(), size()) == 0u, "Non-empty set");
  17776. head = policy_to_head();
  17777. packed.clear();
  17778. }
  17779. /**
  17780. * @brief Returns a type info object for the value type, if any.
  17781. * @return A type info object for the value type, if any.
  17782. */
  17783. [[nodiscard]] const type_info &info() const noexcept {
  17784. return *descriptor;
  17785. }
  17786. /*! @copydoc info */
  17787. [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept {
  17788. return info();
  17789. }
  17790. /**
  17791. * @brief Forwards variables to derived classes, if any.
  17792. * @tparam Type Type of the element to forward.
  17793. * @param value The element to forward.
  17794. */
  17795. template<typename Type>
  17796. void bind(Type &&value) noexcept {
  17797. bind_any(forward_as_any(std::forward<Type>(value)));
  17798. }
  17799. private:
  17800. sparse_container_type sparse;
  17801. packed_container_type packed;
  17802. const type_info *descriptor;
  17803. deletion_policy mode;
  17804. size_type head;
  17805. };
  17806. } // namespace entt
  17807. #endif
  17808. namespace entt {
  17809. /*! @cond TURN_OFF_DOXYGEN */
  17810. namespace internal {
  17811. template<typename Container, auto Page>
  17812. class storage_iterator final {
  17813. friend storage_iterator<const Container, Page>;
  17814. using container_type = std::remove_const_t<Container>;
  17815. using alloc_traits = std::allocator_traits<typename container_type::allocator_type>;
  17816. using iterator_traits = std::iterator_traits<std::conditional_t<
  17817. std::is_const_v<Container>,
  17818. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::const_pointer,
  17819. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::pointer>>;
  17820. public:
  17821. using value_type = typename iterator_traits::value_type;
  17822. using pointer = typename iterator_traits::pointer;
  17823. using reference = typename iterator_traits::reference;
  17824. using difference_type = typename iterator_traits::difference_type;
  17825. using iterator_category = std::random_access_iterator_tag;
  17826. constexpr storage_iterator() noexcept = default;
  17827. constexpr storage_iterator(Container *ref, const difference_type idx) noexcept
  17828. : payload{ref},
  17829. offset{idx} {}
  17830. template<bool Const = std::is_const_v<Container>, typename = std::enable_if_t<Const>>
  17831. constexpr storage_iterator(const storage_iterator<std::remove_const_t<Container>, Page> &other) noexcept
  17832. : storage_iterator{other.payload, other.offset} {}
  17833. constexpr storage_iterator &operator++() noexcept {
  17834. return --offset, *this;
  17835. }
  17836. constexpr storage_iterator operator++(int) noexcept {
  17837. const storage_iterator orig = *this;
  17838. return ++(*this), orig;
  17839. }
  17840. constexpr storage_iterator &operator--() noexcept {
  17841. return ++offset, *this;
  17842. }
  17843. constexpr storage_iterator operator--(int) noexcept {
  17844. const storage_iterator orig = *this;
  17845. return operator--(), orig;
  17846. }
  17847. constexpr storage_iterator &operator+=(const difference_type value) noexcept {
  17848. offset -= value;
  17849. return *this;
  17850. }
  17851. constexpr storage_iterator operator+(const difference_type value) const noexcept {
  17852. storage_iterator copy = *this;
  17853. return (copy += value);
  17854. }
  17855. constexpr storage_iterator &operator-=(const difference_type value) noexcept {
  17856. return (*this += -value);
  17857. }
  17858. constexpr storage_iterator operator-(const difference_type value) const noexcept {
  17859. return (*this + -value);
  17860. }
  17861. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  17862. const auto pos = static_cast<typename Container::size_type>(index() - value);
  17863. return (*payload)[pos / Page][fast_mod(static_cast<std::size_t>(pos), Page)];
  17864. }
  17865. [[nodiscard]] constexpr pointer operator->() const noexcept {
  17866. return std::addressof(operator[](0));
  17867. }
  17868. [[nodiscard]] constexpr reference operator*() const noexcept {
  17869. return operator[](0);
  17870. }
  17871. [[nodiscard]] constexpr difference_type index() const noexcept {
  17872. return offset - 1;
  17873. }
  17874. private:
  17875. Container *payload;
  17876. difference_type offset;
  17877. };
  17878. template<typename Lhs, typename Rhs, auto Page>
  17879. [[nodiscard]] constexpr std::ptrdiff_t operator-(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  17880. return rhs.index() - lhs.index();
  17881. }
  17882. template<typename Lhs, typename Rhs, auto Page>
  17883. [[nodiscard]] constexpr bool operator==(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  17884. return lhs.index() == rhs.index();
  17885. }
  17886. template<typename Lhs, typename Rhs, auto Page>
  17887. [[nodiscard]] constexpr bool operator!=(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  17888. return !(lhs == rhs);
  17889. }
  17890. template<typename Lhs, typename Rhs, auto Page>
  17891. [[nodiscard]] constexpr bool operator<(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  17892. return lhs.index() > rhs.index();
  17893. }
  17894. template<typename Lhs, typename Rhs, auto Page>
  17895. [[nodiscard]] constexpr bool operator>(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  17896. return rhs < lhs;
  17897. }
  17898. template<typename Lhs, typename Rhs, auto Page>
  17899. [[nodiscard]] constexpr bool operator<=(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  17900. return !(lhs > rhs);
  17901. }
  17902. template<typename Lhs, typename Rhs, auto Page>
  17903. [[nodiscard]] constexpr bool operator>=(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  17904. return !(lhs < rhs);
  17905. }
  17906. template<typename It, typename... Other>
  17907. class extended_storage_iterator final {
  17908. template<typename Iter, typename... Args>
  17909. friend class extended_storage_iterator;
  17910. public:
  17911. using iterator_type = It;
  17912. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::forward_as_tuple(*std::declval<Other>()...)));
  17913. using pointer = input_iterator_pointer<value_type>;
  17914. using reference = value_type;
  17915. using difference_type = std::ptrdiff_t;
  17916. using iterator_category = std::input_iterator_tag;
  17917. using iterator_concept = std::forward_iterator_tag;
  17918. constexpr extended_storage_iterator()
  17919. : it{} {}
  17920. constexpr extended_storage_iterator(iterator_type base, Other... other)
  17921. : it{base, other...} {}
  17922. template<typename... Args, typename = std::enable_if_t<(!std::is_same_v<Other, Args> && ...) && (std::is_constructible_v<Other, Args> && ...)>>
  17923. constexpr extended_storage_iterator(const extended_storage_iterator<It, Args...> &other)
  17924. : it{other.it} {}
  17925. constexpr extended_storage_iterator &operator++() noexcept {
  17926. return ++std::get<It>(it), (++std::get<Other>(it), ...), *this;
  17927. }
  17928. constexpr extended_storage_iterator operator++(int) noexcept {
  17929. const extended_storage_iterator orig = *this;
  17930. return ++(*this), orig;
  17931. }
  17932. [[nodiscard]] constexpr pointer operator->() const noexcept {
  17933. return operator*();
  17934. }
  17935. [[nodiscard]] constexpr reference operator*() const noexcept {
  17936. return {*std::get<It>(it), *std::get<Other>(it)...};
  17937. }
  17938. [[nodiscard]] constexpr iterator_type base() const noexcept {
  17939. return std::get<It>(it);
  17940. }
  17941. template<typename... Lhs, typename... Rhs>
  17942. friend constexpr bool operator==(const extended_storage_iterator<Lhs...> &, const extended_storage_iterator<Rhs...> &) noexcept;
  17943. private:
  17944. std::tuple<It, Other...> it;
  17945. };
  17946. template<typename... Lhs, typename... Rhs>
  17947. [[nodiscard]] constexpr bool operator==(const extended_storage_iterator<Lhs...> &lhs, const extended_storage_iterator<Rhs...> &rhs) noexcept {
  17948. return std::get<0>(lhs.it) == std::get<0>(rhs.it);
  17949. }
  17950. template<typename... Lhs, typename... Rhs>
  17951. [[nodiscard]] constexpr bool operator!=(const extended_storage_iterator<Lhs...> &lhs, const extended_storage_iterator<Rhs...> &rhs) noexcept {
  17952. return !(lhs == rhs);
  17953. }
  17954. } // namespace internal
  17955. /*! @endcond */
  17956. /**
  17957. * @brief Storage implementation.
  17958. *
  17959. * Internal data structures arrange elements to maximize performance. There are
  17960. * no guarantees that objects are returned in the insertion order when iterate
  17961. * a storage. Do not make assumption on the order in any case.
  17962. *
  17963. * @warning
  17964. * Empty types aren't explicitly instantiated. Therefore, many of the functions
  17965. * normally available for non-empty types will not be available for empty ones.
  17966. *
  17967. * @tparam Type Element type.
  17968. * @tparam Entity A valid entity type.
  17969. * @tparam Allocator Type of allocator used to manage memory and elements.
  17970. */
  17971. template<typename Type, typename Entity, typename Allocator, typename>
  17972. class basic_storage: public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  17973. using alloc_traits = std::allocator_traits<Allocator>;
  17974. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  17975. using container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  17976. using underlying_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  17977. using underlying_iterator = typename underlying_type::basic_iterator;
  17978. using traits_type = component_traits<Type, Entity>;
  17979. [[nodiscard]] auto &element_at(const std::size_t pos) const {
  17980. return payload[pos / traits_type::page_size][fast_mod(pos, traits_type::page_size)];
  17981. }
  17982. auto assure_at_least(const std::size_t pos) {
  17983. const auto idx = pos / traits_type::page_size;
  17984. if(!(idx < payload.size())) {
  17985. auto curr = payload.size();
  17986. allocator_type allocator{get_allocator()};
  17987. payload.resize(idx + 1u, nullptr);
  17988. ENTT_TRY {
  17989. for(const auto last = payload.size(); curr < last; ++curr) {
  17990. payload[curr] = alloc_traits::allocate(allocator, traits_type::page_size);
  17991. }
  17992. }
  17993. ENTT_CATCH {
  17994. payload.resize(curr);
  17995. ENTT_THROW;
  17996. }
  17997. }
  17998. return payload[idx] + fast_mod(pos, traits_type::page_size);
  17999. }
  18000. template<typename... Args>
  18001. auto emplace_element(const Entity entt, const bool force_back, Args &&...args) {
  18002. const auto it = base_type::try_emplace(entt, force_back);
  18003. ENTT_TRY {
  18004. auto *elem = to_address(assure_at_least(static_cast<size_type>(it.index())));
  18005. entt::uninitialized_construct_using_allocator(elem, get_allocator(), std::forward<Args>(args)...);
  18006. }
  18007. ENTT_CATCH {
  18008. base_type::pop(it, it + 1u);
  18009. ENTT_THROW;
  18010. }
  18011. return it;
  18012. }
  18013. void shrink_to_size(const std::size_t sz) {
  18014. const auto from = (sz + traits_type::page_size - 1u) / traits_type::page_size;
  18015. allocator_type allocator{get_allocator()};
  18016. for(auto pos = sz, length = base_type::size(); pos < length; ++pos) {
  18017. if constexpr(traits_type::in_place_delete) {
  18018. if(base_type::data()[pos] != tombstone) {
  18019. alloc_traits::destroy(allocator, std::addressof(element_at(pos)));
  18020. }
  18021. } else {
  18022. alloc_traits::destroy(allocator, std::addressof(element_at(pos)));
  18023. }
  18024. }
  18025. for(auto pos = from, last = payload.size(); pos < last; ++pos) {
  18026. alloc_traits::deallocate(allocator, payload[pos], traits_type::page_size);
  18027. }
  18028. payload.resize(from);
  18029. payload.shrink_to_fit();
  18030. }
  18031. void swap_at(const std::size_t lhs, const std::size_t rhs) {
  18032. using std::swap;
  18033. swap(element_at(lhs), element_at(rhs));
  18034. }
  18035. void move_to(const std::size_t lhs, const std::size_t rhs) {
  18036. auto &elem = element_at(lhs);
  18037. allocator_type allocator{get_allocator()};
  18038. entt::uninitialized_construct_using_allocator(to_address(assure_at_least(rhs)), allocator, std::move(elem));
  18039. alloc_traits::destroy(allocator, std::addressof(elem));
  18040. }
  18041. private:
  18042. [[nodiscard]] const void *get_at(const std::size_t pos) const final {
  18043. return std::addressof(element_at(pos));
  18044. }
  18045. void swap_or_move([[maybe_unused]] const std::size_t from, [[maybe_unused]] const std::size_t to) override {
  18046. static constexpr bool is_pinned_type = !(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>);
  18047. // use a runtime value to avoid compile-time suppression that drives the code coverage tool crazy
  18048. ENTT_ASSERT((from + 1u) && !is_pinned_type, "Pinned type");
  18049. if constexpr(!is_pinned_type) {
  18050. if constexpr(traits_type::in_place_delete) {
  18051. (base_type::operator[](to) == tombstone) ? move_to(from, to) : swap_at(from, to);
  18052. } else {
  18053. swap_at(from, to);
  18054. }
  18055. }
  18056. }
  18057. protected:
  18058. /**
  18059. * @brief Erases entities from a storage.
  18060. * @param first An iterator to the first element of the range of entities.
  18061. * @param last An iterator past the last element of the range of entities.
  18062. */
  18063. void pop(underlying_iterator first, underlying_iterator last) override {
  18064. for(allocator_type allocator{get_allocator()}; first != last; ++first) {
  18065. // cannot use first.index() because it would break with cross iterators
  18066. auto &elem = element_at(base_type::index(*first));
  18067. if constexpr(traits_type::in_place_delete) {
  18068. base_type::in_place_pop(first);
  18069. alloc_traits::destroy(allocator, std::addressof(elem));
  18070. } else {
  18071. auto &other = element_at(base_type::size() - 1u);
  18072. // destroying on exit allows reentrant destructors
  18073. [[maybe_unused]] auto unused = std::exchange(elem, std::move(other));
  18074. alloc_traits::destroy(allocator, std::addressof(other));
  18075. base_type::swap_and_pop(first);
  18076. }
  18077. }
  18078. }
  18079. /*! @brief Erases all entities of a storage. */
  18080. void pop_all() override {
  18081. allocator_type allocator{get_allocator()};
  18082. for(auto first = base_type::begin(); !(first.index() < 0); ++first) {
  18083. if constexpr(traits_type::in_place_delete) {
  18084. if(*first != tombstone) {
  18085. base_type::in_place_pop(first);
  18086. alloc_traits::destroy(allocator, std::addressof(element_at(static_cast<size_type>(first.index()))));
  18087. }
  18088. } else {
  18089. base_type::swap_and_pop(first);
  18090. alloc_traits::destroy(allocator, std::addressof(element_at(static_cast<size_type>(first.index()))));
  18091. }
  18092. }
  18093. }
  18094. /**
  18095. * @brief Assigns an entity to a storage.
  18096. * @param entt A valid identifier.
  18097. * @param value Optional opaque value.
  18098. * @param force_back Force back insertion.
  18099. * @return Iterator pointing to the emplaced element.
  18100. */
  18101. underlying_iterator try_emplace([[maybe_unused]] const Entity entt, [[maybe_unused]] const bool force_back, const void *value) override {
  18102. if(value != nullptr) {
  18103. if constexpr(std::is_copy_constructible_v<element_type>) {
  18104. return emplace_element(entt, force_back, *static_cast<const element_type *>(value));
  18105. } else {
  18106. return base_type::end();
  18107. }
  18108. } else {
  18109. if constexpr(std::is_default_constructible_v<element_type>) {
  18110. return emplace_element(entt, force_back);
  18111. } else {
  18112. return base_type::end();
  18113. }
  18114. }
  18115. }
  18116. public:
  18117. /*! @brief Allocator type. */
  18118. using allocator_type = Allocator;
  18119. /*! @brief Base type. */
  18120. using base_type = underlying_type;
  18121. /*! @brief Element type. */
  18122. using element_type = Type;
  18123. /*! @brief Type of the objects assigned to entities. */
  18124. using value_type = element_type;
  18125. /*! @brief Underlying entity identifier. */
  18126. using entity_type = Entity;
  18127. /*! @brief Unsigned integer type. */
  18128. using size_type = std::size_t;
  18129. /*! @brief Signed integer type. */
  18130. using difference_type = std::ptrdiff_t;
  18131. /*! @brief Pointer type to contained elements. */
  18132. using pointer = typename container_type::pointer;
  18133. /*! @brief Constant pointer type to contained elements. */
  18134. using const_pointer = typename alloc_traits::template rebind_traits<typename alloc_traits::const_pointer>::const_pointer;
  18135. /*! @brief Random access iterator type. */
  18136. using iterator = internal::storage_iterator<container_type, traits_type::page_size>;
  18137. /*! @brief Constant random access iterator type. */
  18138. using const_iterator = internal::storage_iterator<const container_type, traits_type::page_size>;
  18139. /*! @brief Reverse iterator type. */
  18140. using reverse_iterator = std::reverse_iterator<iterator>;
  18141. /*! @brief Constant reverse iterator type. */
  18142. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  18143. /*! @brief Extended iterable storage proxy. */
  18144. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator, iterator>>;
  18145. /*! @brief Constant extended iterable storage proxy. */
  18146. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator, const_iterator>>;
  18147. /*! @brief Extended reverse iterable storage proxy. */
  18148. using reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::reverse_iterator, reverse_iterator>>;
  18149. /*! @brief Constant extended reverse iterable storage proxy. */
  18150. using const_reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_reverse_iterator, const_reverse_iterator>>;
  18151. /*! @brief Storage deletion policy. */
  18152. static constexpr deletion_policy storage_policy{traits_type::in_place_delete};
  18153. /*! @brief Default constructor. */
  18154. basic_storage()
  18155. : basic_storage{allocator_type{}} {}
  18156. /**
  18157. * @brief Constructs an empty storage with a given allocator.
  18158. * @param allocator The allocator to use.
  18159. */
  18160. explicit basic_storage(const allocator_type &allocator)
  18161. : base_type{type_id<element_type>(), storage_policy, allocator},
  18162. payload{allocator} {}
  18163. /*! @brief Default copy constructor, deleted on purpose. */
  18164. basic_storage(const basic_storage &) = delete;
  18165. /**
  18166. * @brief Move constructor.
  18167. * @param other The instance to move from.
  18168. */
  18169. basic_storage(basic_storage &&other) noexcept
  18170. : base_type{static_cast<base_type &&>(other)},
  18171. payload{std::move(other.payload)} {}
  18172. /**
  18173. * @brief Allocator-extended move constructor.
  18174. * @param other The instance to move from.
  18175. * @param allocator The allocator to use.
  18176. */
  18177. basic_storage(basic_storage &&other, const allocator_type &allocator)
  18178. : base_type{static_cast<base_type &&>(other), allocator},
  18179. payload{std::move(other.payload), allocator} {
  18180. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed");
  18181. }
  18182. /*! @brief Default destructor. */
  18183. // NOLINTNEXTLINE(bugprone-exception-escape)
  18184. ~basic_storage() override {
  18185. shrink_to_size(0u);
  18186. }
  18187. /**
  18188. * @brief Default copy assignment operator, deleted on purpose.
  18189. * @return This storage.
  18190. */
  18191. basic_storage &operator=(const basic_storage &) = delete;
  18192. /**
  18193. * @brief Move assignment operator.
  18194. * @param other The instance to move from.
  18195. * @return This storage.
  18196. */
  18197. basic_storage &operator=(basic_storage &&other) noexcept {
  18198. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed");
  18199. swap(other);
  18200. return *this;
  18201. }
  18202. /**
  18203. * @brief Exchanges the contents with those of a given storage.
  18204. * @param other Storage to exchange the content with.
  18205. */
  18206. void swap(basic_storage &other) noexcept {
  18207. using std::swap;
  18208. swap(payload, other.payload);
  18209. base_type::swap(other);
  18210. }
  18211. /**
  18212. * @brief Returns the associated allocator.
  18213. * @return The associated allocator.
  18214. */
  18215. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  18216. return payload.get_allocator();
  18217. }
  18218. /**
  18219. * @brief Increases the capacity of a storage.
  18220. *
  18221. * If the new capacity is greater than the current capacity, new storage is
  18222. * allocated, otherwise the method does nothing.
  18223. *
  18224. * @param cap Desired capacity.
  18225. */
  18226. void reserve(const size_type cap) override {
  18227. if(cap != 0u) {
  18228. base_type::reserve(cap);
  18229. assure_at_least(cap - 1u);
  18230. }
  18231. }
  18232. /**
  18233. * @brief Returns the number of elements that a storage has currently
  18234. * allocated space for.
  18235. * @return Capacity of the storage.
  18236. */
  18237. [[nodiscard]] size_type capacity() const noexcept override {
  18238. return payload.size() * traits_type::page_size;
  18239. }
  18240. /*! @brief Requests the removal of unused capacity. */
  18241. void shrink_to_fit() override {
  18242. base_type::shrink_to_fit();
  18243. shrink_to_size(base_type::size());
  18244. }
  18245. /**
  18246. * @brief Direct access to the array of objects.
  18247. * @return A pointer to the array of objects.
  18248. */
  18249. [[nodiscard]] const_pointer raw() const noexcept {
  18250. return payload.data();
  18251. }
  18252. /*! @copydoc raw */
  18253. [[nodiscard]] pointer raw() noexcept {
  18254. return payload.data();
  18255. }
  18256. /**
  18257. * @brief Returns an iterator to the beginning.
  18258. *
  18259. * If the storage is empty, the returned iterator will be equal to `end()`.
  18260. *
  18261. * @return An iterator to the first instance of the internal array.
  18262. */
  18263. [[nodiscard]] const_iterator cbegin() const noexcept {
  18264. const auto pos = static_cast<difference_type>(base_type::size());
  18265. return const_iterator{&payload, pos};
  18266. }
  18267. /*! @copydoc cbegin */
  18268. [[nodiscard]] const_iterator begin() const noexcept {
  18269. return cbegin();
  18270. }
  18271. /*! @copydoc begin */
  18272. [[nodiscard]] iterator begin() noexcept {
  18273. const auto pos = static_cast<difference_type>(base_type::size());
  18274. return iterator{&payload, pos};
  18275. }
  18276. /**
  18277. * @brief Returns an iterator to the end.
  18278. * @return An iterator to the element following the last instance of the
  18279. * internal array.
  18280. */
  18281. [[nodiscard]] const_iterator cend() const noexcept {
  18282. return const_iterator{&payload, {}};
  18283. }
  18284. /*! @copydoc cend */
  18285. [[nodiscard]] const_iterator end() const noexcept {
  18286. return cend();
  18287. }
  18288. /*! @copydoc end */
  18289. [[nodiscard]] iterator end() noexcept {
  18290. return iterator{&payload, {}};
  18291. }
  18292. /**
  18293. * @brief Returns a reverse iterator to the beginning.
  18294. *
  18295. * If the storage is empty, the returned iterator will be equal to `rend()`.
  18296. *
  18297. * @return An iterator to the first instance of the reversed internal array.
  18298. */
  18299. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  18300. return std::make_reverse_iterator(cend());
  18301. }
  18302. /*! @copydoc crbegin */
  18303. [[nodiscard]] const_reverse_iterator rbegin() const noexcept {
  18304. return crbegin();
  18305. }
  18306. /*! @copydoc rbegin */
  18307. [[nodiscard]] reverse_iterator rbegin() noexcept {
  18308. return std::make_reverse_iterator(end());
  18309. }
  18310. /**
  18311. * @brief Returns a reverse iterator to the end.
  18312. * @return An iterator to the element following the last instance of the
  18313. * reversed internal array.
  18314. */
  18315. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  18316. return std::make_reverse_iterator(cbegin());
  18317. }
  18318. /*! @copydoc crend */
  18319. [[nodiscard]] const_reverse_iterator rend() const noexcept {
  18320. return crend();
  18321. }
  18322. /*! @copydoc rend */
  18323. [[nodiscard]] reverse_iterator rend() noexcept {
  18324. return std::make_reverse_iterator(begin());
  18325. }
  18326. /**
  18327. * @brief Returns the object assigned to an entity.
  18328. *
  18329. * @warning
  18330. * Attempting to use an entity that doesn't belong to the storage results in
  18331. * undefined behavior.
  18332. *
  18333. * @param entt A valid identifier.
  18334. * @return The object assigned to the entity.
  18335. */
  18336. [[nodiscard]] const value_type &get(const entity_type entt) const noexcept {
  18337. return element_at(base_type::index(entt));
  18338. }
  18339. /*! @copydoc get */
  18340. [[nodiscard]] value_type &get(const entity_type entt) noexcept {
  18341. return const_cast<value_type &>(std::as_const(*this).get(entt));
  18342. }
  18343. /**
  18344. * @brief Returns the object assigned to an entity as a tuple.
  18345. * @param entt A valid identifier.
  18346. * @return The object assigned to the entity as a tuple.
  18347. */
  18348. [[nodiscard]] std::tuple<const value_type &> get_as_tuple(const entity_type entt) const noexcept {
  18349. return std::forward_as_tuple(get(entt));
  18350. }
  18351. /*! @copydoc get_as_tuple */
  18352. [[nodiscard]] std::tuple<value_type &> get_as_tuple(const entity_type entt) noexcept {
  18353. return std::forward_as_tuple(get(entt));
  18354. }
  18355. /**
  18356. * @brief Assigns an entity to a storage and constructs its object.
  18357. *
  18358. * @warning
  18359. * Attempting to use an entity that already belongs to the storage results
  18360. * in undefined behavior.
  18361. *
  18362. * @tparam Args Types of arguments to use to construct the object.
  18363. * @param entt A valid identifier.
  18364. * @param args Parameters to use to construct an object for the entity.
  18365. * @return A reference to the newly created object.
  18366. */
  18367. template<typename... Args>
  18368. value_type &emplace(const entity_type entt, Args &&...args) {
  18369. if constexpr(std::is_aggregate_v<value_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<value_type>)) {
  18370. const auto it = emplace_element(entt, false, Type{std::forward<Args>(args)...});
  18371. return element_at(static_cast<size_type>(it.index()));
  18372. } else {
  18373. const auto it = emplace_element(entt, false, std::forward<Args>(args)...);
  18374. return element_at(static_cast<size_type>(it.index()));
  18375. }
  18376. }
  18377. /**
  18378. * @brief Updates the instance assigned to a given entity in-place.
  18379. * @tparam Func Types of the function objects to invoke.
  18380. * @param entt A valid identifier.
  18381. * @param func Valid function objects.
  18382. * @return A reference to the updated instance.
  18383. */
  18384. template<typename... Func>
  18385. value_type &patch(const entity_type entt, Func &&...func) {
  18386. const auto idx = base_type::index(entt);
  18387. auto &elem = element_at(idx);
  18388. (std::forward<Func>(func)(elem), ...);
  18389. return elem;
  18390. }
  18391. /**
  18392. * @brief Assigns one or more entities to a storage and constructs their
  18393. * objects from a given instance.
  18394. *
  18395. * @warning
  18396. * Attempting to assign an entity that already belongs to the storage
  18397. * results in undefined behavior.
  18398. *
  18399. * @tparam It Type of input iterator.
  18400. * @param first An iterator to the first element of the range of entities.
  18401. * @param last An iterator past the last element of the range of entities.
  18402. * @param value An instance of the object to construct.
  18403. * @return Iterator pointing to the first element inserted, if any.
  18404. */
  18405. template<typename It>
  18406. iterator insert(It first, It last, const value_type &value = {}) {
  18407. for(; first != last; ++first) {
  18408. emplace_element(*first, true, value);
  18409. }
  18410. return begin();
  18411. }
  18412. /**
  18413. * @brief Assigns one or more entities to a storage and constructs their
  18414. * objects from a given range.
  18415. *
  18416. * @sa construct
  18417. *
  18418. * @tparam EIt Type of input iterator.
  18419. * @tparam CIt Type of input iterator.
  18420. * @param first An iterator to the first element of the range of entities.
  18421. * @param last An iterator past the last element of the range of entities.
  18422. * @param from An iterator to the first element of the range of objects.
  18423. * @return Iterator pointing to the first element inserted, if any.
  18424. */
  18425. template<typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, value_type>>>
  18426. iterator insert(EIt first, EIt last, CIt from) {
  18427. for(; first != last; ++first, ++from) {
  18428. emplace_element(*first, true, *from);
  18429. }
  18430. return begin();
  18431. }
  18432. /**
  18433. * @brief Returns an iterable object to use to _visit_ a storage.
  18434. *
  18435. * The iterable object returns a tuple that contains the current entity and
  18436. * a reference to its element.
  18437. *
  18438. * @return An iterable object to use to _visit_ the storage.
  18439. */
  18440. [[nodiscard]] iterable each() noexcept {
  18441. return iterable{{base_type::begin(), begin()}, {base_type::end(), end()}};
  18442. }
  18443. /*! @copydoc each */
  18444. [[nodiscard]] const_iterable each() const noexcept {
  18445. return const_iterable{{base_type::cbegin(), cbegin()}, {base_type::cend(), cend()}};
  18446. }
  18447. /**
  18448. * @brief Returns a reverse iterable object to use to _visit_ a storage.
  18449. *
  18450. * @sa each
  18451. *
  18452. * @return A reverse iterable object to use to _visit_ the storage.
  18453. */
  18454. [[nodiscard]] reverse_iterable reach() noexcept {
  18455. return reverse_iterable{{base_type::rbegin(), rbegin()}, {base_type::rend(), rend()}};
  18456. }
  18457. /*! @copydoc reach */
  18458. [[nodiscard]] const_reverse_iterable reach() const noexcept {
  18459. return const_reverse_iterable{{base_type::crbegin(), crbegin()}, {base_type::crend(), crend()}};
  18460. }
  18461. private:
  18462. container_type payload;
  18463. };
  18464. /*! @copydoc basic_storage */
  18465. template<typename Type, typename Entity, typename Allocator>
  18466. class basic_storage<Type, Entity, Allocator, std::enable_if_t<component_traits<Type, Entity>::page_size == 0u>>
  18467. : public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  18468. using alloc_traits = std::allocator_traits<Allocator>;
  18469. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  18470. using traits_type = component_traits<Type, Entity>;
  18471. public:
  18472. /*! @brief Allocator type. */
  18473. using allocator_type = Allocator;
  18474. /*! @brief Base type. */
  18475. using base_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  18476. /*! @brief Element type. */
  18477. using element_type = Type;
  18478. /*! @brief Type of the objects assigned to entities. */
  18479. using value_type = void;
  18480. /*! @brief Underlying entity identifier. */
  18481. using entity_type = Entity;
  18482. /*! @brief Unsigned integer type. */
  18483. using size_type = std::size_t;
  18484. /*! @brief Signed integer type. */
  18485. using difference_type = std::ptrdiff_t;
  18486. /*! @brief Extended iterable storage proxy. */
  18487. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator>>;
  18488. /*! @brief Constant extended iterable storage proxy. */
  18489. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator>>;
  18490. /*! @brief Extended reverse iterable storage proxy. */
  18491. using reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::reverse_iterator>>;
  18492. /*! @brief Constant extended reverse iterable storage proxy. */
  18493. using const_reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_reverse_iterator>>;
  18494. /*! @brief Storage deletion policy. */
  18495. static constexpr deletion_policy storage_policy{traits_type::in_place_delete};
  18496. /*! @brief Default constructor. */
  18497. basic_storage()
  18498. : basic_storage{allocator_type{}} {}
  18499. /**
  18500. * @brief Constructs an empty container with a given allocator.
  18501. * @param allocator The allocator to use.
  18502. */
  18503. explicit basic_storage(const allocator_type &allocator)
  18504. : base_type{type_id<element_type>(), storage_policy, allocator} {}
  18505. /*! @brief Default copy constructor, deleted on purpose. */
  18506. basic_storage(const basic_storage &) = delete;
  18507. /**
  18508. * @brief Move constructor.
  18509. * @param other The instance to move from.
  18510. */
  18511. basic_storage(basic_storage &&other) noexcept = default;
  18512. /**
  18513. * @brief Allocator-extended move constructor.
  18514. * @param other The instance to move from.
  18515. * @param allocator The allocator to use.
  18516. */
  18517. basic_storage(basic_storage &&other, const allocator_type &allocator)
  18518. : base_type{std::move(other), allocator} {}
  18519. /*! @brief Default destructor. */
  18520. ~basic_storage() override = default;
  18521. /**
  18522. * @brief Default copy assignment operator, deleted on purpose.
  18523. * @return This storage.
  18524. */
  18525. basic_storage &operator=(const basic_storage &) = delete;
  18526. /**
  18527. * @brief Move assignment operator.
  18528. * @param other The instance to move from.
  18529. * @return This storage.
  18530. */
  18531. basic_storage &operator=(basic_storage &&other) noexcept = default;
  18532. /**
  18533. * @brief Returns the associated allocator.
  18534. * @return The associated allocator.
  18535. */
  18536. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  18537. // std::allocator<void> has no cross constructors (waiting for C++20)
  18538. if constexpr(std::is_void_v<element_type> && !std::is_constructible_v<allocator_type, typename base_type::allocator_type>) {
  18539. return allocator_type{};
  18540. } else {
  18541. return allocator_type{base_type::get_allocator()};
  18542. }
  18543. }
  18544. /**
  18545. * @brief Returns the object assigned to an entity, that is `void`.
  18546. *
  18547. * @warning
  18548. * Attempting to use an entity that doesn't belong to the storage results in
  18549. * undefined behavior.
  18550. *
  18551. * @param entt A valid identifier.
  18552. */
  18553. void get([[maybe_unused]] const entity_type entt) const noexcept {
  18554. ENTT_ASSERT(base_type::contains(entt), "Invalid entity");
  18555. }
  18556. /**
  18557. * @brief Returns an empty tuple.
  18558. * @param entt A valid identifier.
  18559. * @return Returns an empty tuple.
  18560. */
  18561. [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept {
  18562. ENTT_ASSERT(base_type::contains(entt), "Invalid entity");
  18563. return std::tuple{};
  18564. }
  18565. /**
  18566. * @brief Assigns an entity to a storage and constructs its object.
  18567. *
  18568. * @warning
  18569. * Attempting to use an entity that already belongs to the storage results
  18570. * in undefined behavior.
  18571. *
  18572. * @param entt A valid identifier.
  18573. */
  18574. void emplace(const entity_type entt) {
  18575. base_type::try_emplace(entt, false);
  18576. }
  18577. /**
  18578. * @brief Updates the instance assigned to a given entity in-place.
  18579. * @tparam Func Types of the function objects to invoke.
  18580. * @param entt A valid identifier.
  18581. * @param func Valid function objects.
  18582. */
  18583. template<typename... Func>
  18584. void patch([[maybe_unused]] const entity_type entt, Func &&...func) {
  18585. ENTT_ASSERT(base_type::contains(entt), "Invalid entity");
  18586. (std::forward<Func>(func)(), ...);
  18587. }
  18588. /**
  18589. * @brief Assigns entities to a storage.
  18590. * @tparam It Type of input iterator.
  18591. * @param first An iterator to the first element of the range of entities.
  18592. * @param last An iterator past the last element of the range of entities.
  18593. */
  18594. template<typename It>
  18595. void insert(It first, It last) {
  18596. for(; first != last; ++first) {
  18597. base_type::try_emplace(*first, true);
  18598. }
  18599. }
  18600. /**
  18601. * @brief Returns an iterable object to use to _visit_ a storage.
  18602. *
  18603. * The iterable object returns a tuple that contains the current entity.
  18604. *
  18605. * @return An iterable object to use to _visit_ the storage.
  18606. */
  18607. [[nodiscard]] iterable each() noexcept {
  18608. return iterable{base_type::begin(), base_type::end()};
  18609. }
  18610. /*! @copydoc each */
  18611. [[nodiscard]] const_iterable each() const noexcept {
  18612. return const_iterable{base_type::cbegin(), base_type::cend()};
  18613. }
  18614. /**
  18615. * @brief Returns a reverse iterable object to use to _visit_ a storage.
  18616. *
  18617. * @sa each
  18618. *
  18619. * @return A reverse iterable object to use to _visit_ the storage.
  18620. */
  18621. [[nodiscard]] reverse_iterable reach() noexcept {
  18622. return reverse_iterable{{base_type::rbegin()}, {base_type::rend()}};
  18623. }
  18624. /*! @copydoc reach */
  18625. [[nodiscard]] const_reverse_iterable reach() const noexcept {
  18626. return const_reverse_iterable{{base_type::crbegin()}, {base_type::crend()}};
  18627. }
  18628. };
  18629. /**
  18630. * @brief Swap-only entity storage specialization.
  18631. * @tparam Entity A valid entity type.
  18632. * @tparam Allocator Type of allocator used to manage memory and elements.
  18633. */
  18634. template<typename Entity, typename Allocator>
  18635. class basic_storage<Entity, Entity, Allocator>
  18636. : public basic_sparse_set<Entity, Allocator> {
  18637. using alloc_traits = std::allocator_traits<Allocator>;
  18638. static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");
  18639. using underlying_iterator = typename basic_sparse_set<Entity, Allocator>::basic_iterator;
  18640. using traits_type = entt_traits<Entity>;
  18641. auto from_placeholder() noexcept {
  18642. const auto entt = traits_type::combine(static_cast<typename traits_type::entity_type>(placeholder), {});
  18643. ENTT_ASSERT(entt != null, "No more entities available");
  18644. placeholder += static_cast<size_type>(entt != null);
  18645. return entt;
  18646. }
  18647. auto next() noexcept {
  18648. entity_type entt = from_placeholder();
  18649. while(base_type::current(entt) != traits_type::to_version(tombstone) && entt != null) {
  18650. entt = from_placeholder();
  18651. }
  18652. return entt;
  18653. }
  18654. protected:
  18655. /*! @brief Erases all entities of a storage. */
  18656. void pop_all() override {
  18657. base_type::pop_all();
  18658. placeholder = {};
  18659. }
  18660. /**
  18661. * @brief Assigns an entity to a storage.
  18662. * @param hint A valid identifier.
  18663. * @return Iterator pointing to the emplaced element.
  18664. */
  18665. underlying_iterator try_emplace(const Entity hint, const bool, const void *) override {
  18666. return base_type::find(generate(hint));
  18667. }
  18668. public:
  18669. /*! @brief Allocator type. */
  18670. using allocator_type = Allocator;
  18671. /*! @brief Base type. */
  18672. using base_type = basic_sparse_set<Entity, Allocator>;
  18673. /*! @brief Element type. */
  18674. using element_type = Entity;
  18675. /*! @brief Type of the objects assigned to entities. */
  18676. using value_type = void;
  18677. /*! @brief Underlying entity identifier. */
  18678. using entity_type = Entity;
  18679. /*! @brief Unsigned integer type. */
  18680. using size_type = std::size_t;
  18681. /*! @brief Signed integer type. */
  18682. using difference_type = std::ptrdiff_t;
  18683. /*! @brief Extended iterable storage proxy. */
  18684. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator>>;
  18685. /*! @brief Constant extended iterable storage proxy. */
  18686. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator>>;
  18687. /*! @brief Extended reverse iterable storage proxy. */
  18688. using reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::reverse_iterator>>;
  18689. /*! @brief Constant extended reverse iterable storage proxy. */
  18690. using const_reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_reverse_iterator>>;
  18691. /*! @brief Storage deletion policy. */
  18692. static constexpr deletion_policy storage_policy = deletion_policy::swap_only;
  18693. /*! @brief Default constructor. */
  18694. basic_storage()
  18695. : basic_storage{allocator_type{}} {
  18696. }
  18697. /**
  18698. * @brief Constructs an empty container with a given allocator.
  18699. * @param allocator The allocator to use.
  18700. */
  18701. explicit basic_storage(const allocator_type &allocator)
  18702. : base_type{type_id<void>(), storage_policy, allocator} {}
  18703. /*! @brief Default copy constructor, deleted on purpose. */
  18704. basic_storage(const basic_storage &) = delete;
  18705. /**
  18706. * @brief Move constructor.
  18707. * @param other The instance to move from.
  18708. */
  18709. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  18710. basic_storage(basic_storage &&other) noexcept
  18711. : base_type{static_cast<base_type &&>(other)},
  18712. placeholder{other.placeholder} {}
  18713. /**
  18714. * @brief Allocator-extended move constructor.
  18715. * @param other The instance to move from.
  18716. * @param allocator The allocator to use.
  18717. */
  18718. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  18719. basic_storage(basic_storage &&other, const allocator_type &allocator)
  18720. : base_type{static_cast<base_type &&>(other), allocator},
  18721. placeholder{other.placeholder} {}
  18722. /*! @brief Default destructor. */
  18723. ~basic_storage() override = default;
  18724. /**
  18725. * @brief Default copy assignment operator, deleted on purpose.
  18726. * @return This storage.
  18727. */
  18728. basic_storage &operator=(const basic_storage &) = delete;
  18729. /**
  18730. * @brief Move assignment operator.
  18731. * @param other The instance to move from.
  18732. * @return This storage.
  18733. */
  18734. basic_storage &operator=(basic_storage &&other) noexcept {
  18735. placeholder = other.placeholder;
  18736. base_type::operator=(std::move(other));
  18737. return *this;
  18738. }
  18739. /**
  18740. * @brief Exchanges the contents with those of a given storage.
  18741. * @param other Storage to exchange the content with.
  18742. */
  18743. void swap(basic_storage &other) noexcept {
  18744. using std::swap;
  18745. swap(placeholder, other.placeholder);
  18746. base_type::swap(other);
  18747. }
  18748. /**
  18749. * @brief Returns the object assigned to an entity, that is `void`.
  18750. *
  18751. * @warning
  18752. * Attempting to use an entity that doesn't belong to the storage results in
  18753. * undefined behavior.
  18754. *
  18755. * @param entt A valid identifier.
  18756. */
  18757. void get([[maybe_unused]] const entity_type entt) const noexcept {
  18758. ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one");
  18759. }
  18760. /**
  18761. * @brief Returns an empty tuple.
  18762. * @param entt A valid identifier.
  18763. * @return Returns an empty tuple.
  18764. */
  18765. [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept {
  18766. ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one");
  18767. return std::tuple{};
  18768. }
  18769. /**
  18770. * @brief Creates a new identifier or recycles a destroyed one.
  18771. * @return A valid identifier.
  18772. */
  18773. entity_type generate() {
  18774. const auto len = base_type::free_list();
  18775. const auto entt = (len == base_type::size()) ? next() : base_type::data()[len];
  18776. return *base_type::try_emplace(entt, true);
  18777. }
  18778. /**
  18779. * @brief Creates a new identifier or recycles a destroyed one.
  18780. *
  18781. * If the requested identifier isn't in use, the suggested one is used.
  18782. * Otherwise, a new identifier is returned.
  18783. *
  18784. * @param hint Required identifier.
  18785. * @return A valid identifier.
  18786. */
  18787. entity_type generate(const entity_type hint) {
  18788. if(hint != null && hint != tombstone) {
  18789. if(const auto curr = traits_type::construct(traits_type::to_entity(hint), base_type::current(hint)); curr == tombstone || !(base_type::index(curr) < base_type::free_list())) {
  18790. return *base_type::try_emplace(hint, true);
  18791. }
  18792. }
  18793. return generate();
  18794. }
  18795. /**
  18796. * @brief Assigns each element in a range an identifier.
  18797. * @tparam It Type of mutable forward iterator.
  18798. * @param first An iterator to the first element of the range to generate.
  18799. * @param last An iterator past the last element of the range to generate.
  18800. */
  18801. template<typename It>
  18802. void generate(It first, It last) {
  18803. for(const auto sz = base_type::size(); first != last && base_type::free_list() != sz; ++first) {
  18804. *first = *base_type::try_emplace(base_type::data()[base_type::free_list()], true);
  18805. }
  18806. for(; first != last; ++first) {
  18807. *first = *base_type::try_emplace(next(), true);
  18808. }
  18809. }
  18810. /**
  18811. * @brief Updates a given identifier.
  18812. * @tparam Func Types of the function objects to invoke.
  18813. * @param entt A valid identifier.
  18814. * @param func Valid function objects.
  18815. */
  18816. template<typename... Func>
  18817. void patch([[maybe_unused]] const entity_type entt, Func &&...func) {
  18818. ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one");
  18819. (std::forward<Func>(func)(), ...);
  18820. }
  18821. /**
  18822. * @brief Returns an iterable object to use to _visit_ a storage.
  18823. *
  18824. * The iterable object returns a tuple that contains the current entity.
  18825. *
  18826. * @return An iterable object to use to _visit_ the storage.
  18827. */
  18828. [[nodiscard]] iterable each() noexcept {
  18829. return std::as_const(*this).each();
  18830. }
  18831. /*! @copydoc each */
  18832. [[nodiscard]] const_iterable each() const noexcept {
  18833. const auto it = base_type::cend();
  18834. const auto offset = static_cast<difference_type>(base_type::free_list());
  18835. return const_iterable{it - offset, it};
  18836. }
  18837. /**
  18838. * @brief Returns a reverse iterable object to use to _visit_ a storage.
  18839. *
  18840. * @sa each
  18841. *
  18842. * @return A reverse iterable object to use to _visit_ the storage.
  18843. */
  18844. [[nodiscard]] reverse_iterable reach() noexcept {
  18845. return std::as_const(*this).reach();
  18846. }
  18847. /*! @copydoc reach */
  18848. [[nodiscard]] const_reverse_iterable reach() const noexcept {
  18849. const auto it = base_type::crbegin();
  18850. const auto offset = static_cast<difference_type>(base_type::free_list());
  18851. return const_reverse_iterable{it, it + offset};
  18852. }
  18853. /**
  18854. * @brief Sets the starting identifier for generation.
  18855. *
  18856. * The version is ignored, regardless of the value.
  18857. *
  18858. * @param hint A valid identifier.
  18859. */
  18860. void start_from(const entity_type hint) {
  18861. placeholder = static_cast<size_type>(traits_type::to_entity(hint));
  18862. }
  18863. private:
  18864. size_type placeholder{};
  18865. };
  18866. } // namespace entt
  18867. #endif
  18868. // #include "view.hpp"
  18869. #ifndef ENTT_ENTITY_VIEW_HPP
  18870. #define ENTT_ENTITY_VIEW_HPP
  18871. #include <array>
  18872. #include <cstddef>
  18873. #include <iterator>
  18874. #include <tuple>
  18875. #include <type_traits>
  18876. #include <utility>
  18877. // #include "../config/config.h"
  18878. // #include "../core/iterator.hpp"
  18879. // #include "../core/type_traits.hpp"
  18880. // #include "entity.hpp"
  18881. // #include "fwd.hpp"
  18882. namespace entt {
  18883. /*! @cond TURN_OFF_DOXYGEN */
  18884. namespace internal {
  18885. template<typename... Type>
  18886. // NOLINTNEXTLINE(misc-redundant-expression)
  18887. static constexpr bool tombstone_check_v = ((sizeof...(Type) == 1u) && ... && (Type::storage_policy == deletion_policy::in_place));
  18888. template<typename Type>
  18889. const Type *view_placeholder() {
  18890. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Unexpected type");
  18891. static const Type placeholder{};
  18892. return &placeholder;
  18893. }
  18894. template<typename It, typename Entity>
  18895. [[nodiscard]] bool all_of(It first, const It last, const Entity entt) noexcept {
  18896. for(; (first != last) && (*first)->contains(entt); ++first) {}
  18897. return first == last;
  18898. }
  18899. template<typename It, typename Entity>
  18900. [[nodiscard]] bool none_of(It first, const It last, const Entity entt) noexcept {
  18901. for(; (first != last) && !(*first)->contains(entt); ++first) {}
  18902. return first == last;
  18903. }
  18904. template<typename It>
  18905. [[nodiscard]] bool fully_initialized(It first, const It last, const std::remove_pointer_t<typename std::iterator_traits<It>::value_type> *placeholder) noexcept {
  18906. for(; (first != last) && *first != placeholder; ++first) {}
  18907. return first == last;
  18908. }
  18909. template<typename Result, typename View, typename Other, std::size_t... GLhs, std::size_t... ELhs, std::size_t... GRhs, std::size_t... ERhs>
  18910. [[nodiscard]] Result view_pack(const View &view, const Other &other, std::index_sequence<GLhs...>, std::index_sequence<ELhs...>, std::index_sequence<GRhs...>, std::index_sequence<ERhs...>) {
  18911. Result elem{};
  18912. // friend-initialization, avoid multiple calls to refresh
  18913. elem.pools = {view.template storage<GLhs>()..., other.template storage<GRhs>()...};
  18914. auto filter_or_placeholder = [placeholder = elem.placeholder](auto *value) { return (value == nullptr) ? placeholder : value; };
  18915. elem.filter = {filter_or_placeholder(view.template storage<sizeof...(GLhs) + ELhs>())..., filter_or_placeholder(other.template storage<sizeof...(GRhs) + ERhs>())...};
  18916. elem.refresh();
  18917. return elem;
  18918. }
  18919. template<typename Type, bool Checked, std::size_t Get, std::size_t Exclude>
  18920. class view_iterator final {
  18921. template<typename, typename...>
  18922. friend class extended_view_iterator;
  18923. using iterator_type = typename Type::const_iterator;
  18924. using iterator_traits = std::iterator_traits<iterator_type>;
  18925. [[nodiscard]] bool valid(const typename iterator_traits::value_type entt) const noexcept {
  18926. return (!Checked || (entt != tombstone))
  18927. && ((Get == 1u) || (internal::all_of(pools.begin(), pools.begin() + index, entt) && internal::all_of(pools.begin() + index + 1, pools.end(), entt)))
  18928. && ((Exclude == 0u) || internal::none_of(filter.begin(), filter.end(), entt));
  18929. }
  18930. void seek_next() {
  18931. for(constexpr iterator_type sentinel{}; it != sentinel && !valid(*it); ++it) {}
  18932. }
  18933. public:
  18934. using value_type = typename iterator_traits::value_type;
  18935. using pointer = typename iterator_traits::pointer;
  18936. using reference = typename iterator_traits::reference;
  18937. using difference_type = typename iterator_traits::difference_type;
  18938. using iterator_category = std::forward_iterator_tag;
  18939. constexpr view_iterator() noexcept
  18940. : it{},
  18941. pools{},
  18942. filter{},
  18943. index{} {}
  18944. view_iterator(iterator_type first, std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl, const std::size_t idx) noexcept
  18945. : it{first},
  18946. pools{value},
  18947. filter{excl},
  18948. index{static_cast<difference_type>(idx)} {
  18949. ENTT_ASSERT((Get != 1u) || (Exclude != 0u) || pools[0u]->policy() == deletion_policy::in_place, "Non in-place storage view iterator");
  18950. seek_next();
  18951. }
  18952. view_iterator &operator++() noexcept {
  18953. ++it;
  18954. seek_next();
  18955. return *this;
  18956. }
  18957. view_iterator operator++(int) noexcept {
  18958. const view_iterator orig = *this;
  18959. return ++(*this), orig;
  18960. }
  18961. [[nodiscard]] pointer operator->() const noexcept {
  18962. return &*it;
  18963. }
  18964. [[nodiscard]] reference operator*() const noexcept {
  18965. return *operator->();
  18966. }
  18967. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  18968. friend constexpr bool operator==(const view_iterator<LhsType, LhsArgs...> &, const view_iterator<RhsType, RhsArgs...> &) noexcept;
  18969. private:
  18970. iterator_type it;
  18971. std::array<const Type *, Get> pools;
  18972. std::array<const Type *, Exclude> filter;
  18973. difference_type index;
  18974. };
  18975. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  18976. [[nodiscard]] constexpr bool operator==(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) noexcept {
  18977. return lhs.it == rhs.it;
  18978. }
  18979. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  18980. [[nodiscard]] constexpr bool operator!=(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) noexcept {
  18981. return !(lhs == rhs);
  18982. }
  18983. template<typename It, typename... Get>
  18984. class extended_view_iterator final {
  18985. template<std::size_t... Index>
  18986. [[nodiscard]] auto dereference(std::index_sequence<Index...>) const noexcept {
  18987. return std::tuple_cat(std::make_tuple(*it), static_cast<Get *>(const_cast<constness_as_t<typename Get::base_type, Get> *>(std::get<Index>(it.pools)))->get_as_tuple(*it)...);
  18988. }
  18989. public:
  18990. using iterator_type = It;
  18991. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Get>().get_as_tuple({})...));
  18992. using pointer = input_iterator_pointer<value_type>;
  18993. using reference = value_type;
  18994. using difference_type = std::ptrdiff_t;
  18995. using iterator_category = std::input_iterator_tag;
  18996. using iterator_concept = std::forward_iterator_tag;
  18997. constexpr extended_view_iterator()
  18998. : it{} {}
  18999. extended_view_iterator(iterator_type from)
  19000. : it{from} {}
  19001. extended_view_iterator &operator++() noexcept {
  19002. return ++it, *this;
  19003. }
  19004. extended_view_iterator operator++(int) noexcept {
  19005. const extended_view_iterator orig = *this;
  19006. return ++(*this), orig;
  19007. }
  19008. [[nodiscard]] reference operator*() const noexcept {
  19009. return dereference(std::index_sequence_for<Get...>{});
  19010. }
  19011. [[nodiscard]] pointer operator->() const noexcept {
  19012. return operator*();
  19013. }
  19014. [[nodiscard]] constexpr iterator_type base() const noexcept {
  19015. return it;
  19016. }
  19017. template<typename... Lhs, typename... Rhs>
  19018. friend bool constexpr operator==(const extended_view_iterator<Lhs...> &, const extended_view_iterator<Rhs...> &) noexcept;
  19019. private:
  19020. It it;
  19021. };
  19022. template<typename... Lhs, typename... Rhs>
  19023. [[nodiscard]] constexpr bool operator==(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) noexcept {
  19024. return lhs.it == rhs.it;
  19025. }
  19026. template<typename... Lhs, typename... Rhs>
  19027. [[nodiscard]] constexpr bool operator!=(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) noexcept {
  19028. return !(lhs == rhs);
  19029. }
  19030. } // namespace internal
  19031. /*! @endcond */
  19032. /**
  19033. * @brief View implementation.
  19034. *
  19035. * Primary template isn't defined on purpose. All the specializations give a
  19036. * compile-time error, but for a few reasonable cases.
  19037. *
  19038. * @b Important
  19039. *
  19040. * View iterators aren't invalidated if:
  19041. *
  19042. * * New elements are added to the storage iterated by the view.
  19043. * * The entity currently returned is modified (for example, elements are added
  19044. * or removed from it).
  19045. * * The entity currently returned is destroyed.
  19046. *
  19047. * In all other cases, modifying the storage iterated by a view in any way can
  19048. * invalidate all iterators.
  19049. */
  19050. template<typename, typename, typename>
  19051. class basic_view;
  19052. /**
  19053. * @brief Basic storage view implementation.
  19054. * @warning For internal use only, backward compatibility not guaranteed.
  19055. * @tparam Type Common type among all storage types.
  19056. * @tparam Checked True to enable the tombstone check, false otherwise.
  19057. * @tparam Get Number of storage iterated by the view.
  19058. * @tparam Exclude Number of storage used to filter the view.
  19059. */
  19060. template<typename Type, bool Checked, std::size_t Get, std::size_t Exclude>
  19061. class basic_common_view {
  19062. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Unexpected type");
  19063. template<typename Return, typename View, typename Other, std::size_t... GLhs, std::size_t... ELhs, std::size_t... GRhs, std::size_t... ERhs>
  19064. friend Return internal::view_pack(const View &, const Other &, std::index_sequence<GLhs...>, std::index_sequence<ELhs...>, std::index_sequence<GRhs...>, std::index_sequence<ERhs...>);
  19065. [[nodiscard]] auto offset() const noexcept {
  19066. ENTT_ASSERT(index != Get, "Invalid view");
  19067. return (pools[index]->policy() == deletion_policy::swap_only) ? pools[index]->free_list() : pools[index]->size();
  19068. }
  19069. void unchecked_refresh() noexcept {
  19070. index = 0u;
  19071. if constexpr(Get > 1u) {
  19072. for(size_type pos{1u}; pos < Get; ++pos) {
  19073. if(pools[pos]->size() < pools[index]->size()) {
  19074. index = pos;
  19075. }
  19076. }
  19077. }
  19078. }
  19079. protected:
  19080. /*! @cond TURN_OFF_DOXYGEN */
  19081. basic_common_view() noexcept {
  19082. for(size_type pos{}, last = filter.size(); pos < last; ++pos) {
  19083. filter[pos] = placeholder;
  19084. }
  19085. }
  19086. basic_common_view(std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl) noexcept
  19087. : pools{value},
  19088. filter{excl},
  19089. index{Get} {
  19090. unchecked_refresh();
  19091. }
  19092. [[nodiscard]] const Type *pool_at(const std::size_t pos) const noexcept {
  19093. return pools[pos];
  19094. }
  19095. void pool_at(const std::size_t pos, const Type *elem) noexcept {
  19096. ENTT_ASSERT(elem != nullptr, "Unexpected element");
  19097. pools[pos] = elem;
  19098. refresh();
  19099. }
  19100. [[nodiscard]] const Type *filter_at(const std::size_t pos) const noexcept {
  19101. return (filter[pos] == placeholder) ? nullptr : filter[pos];
  19102. }
  19103. void filter_at(const std::size_t pos, const Type *elem) noexcept {
  19104. ENTT_ASSERT(elem != nullptr, "Unexpected element");
  19105. filter[pos] = elem;
  19106. }
  19107. [[nodiscard]] bool none_of(const typename Type::entity_type entt) const noexcept {
  19108. return internal::none_of(filter.begin(), filter.end(), entt);
  19109. }
  19110. void use(const std::size_t pos) noexcept {
  19111. index = (index != Get) ? pos : Get;
  19112. }
  19113. /*! @endcond */
  19114. public:
  19115. /*! @brief Common type among all storage types. */
  19116. using common_type = Type;
  19117. /*! @brief Underlying entity identifier. */
  19118. using entity_type = typename Type::entity_type;
  19119. /*! @brief Unsigned integer type. */
  19120. using size_type = std::size_t;
  19121. /*! @brief Signed integer type. */
  19122. using difference_type = std::ptrdiff_t;
  19123. /*! @brief Forward iterator type. */
  19124. using iterator = internal::view_iterator<common_type, Checked, Get, Exclude>;
  19125. /*! @brief Updates the internal leading view if required. */
  19126. void refresh() noexcept {
  19127. size_type pos = static_cast<size_type>(index != Get) * Get;
  19128. for(; pos < Get && pools[pos] != nullptr; ++pos) {}
  19129. if(pos == Get) {
  19130. unchecked_refresh();
  19131. }
  19132. }
  19133. /**
  19134. * @brief Returns the leading storage of a view, if any.
  19135. * @return The leading storage of the view.
  19136. */
  19137. [[nodiscard]] const common_type *handle() const noexcept {
  19138. return (index != Get) ? pools[index] : nullptr;
  19139. }
  19140. /**
  19141. * @brief Estimates the number of entities iterated by the view.
  19142. * @return Estimated number of entities iterated by the view.
  19143. */
  19144. [[nodiscard]] size_type size_hint() const noexcept {
  19145. return (index != Get) ? offset() : size_type{};
  19146. }
  19147. /**
  19148. * @brief Returns an iterator to the first entity of the view.
  19149. *
  19150. * If the view is empty, the returned iterator will be equal to `end()`.
  19151. *
  19152. * @return An iterator to the first entity of the view.
  19153. */
  19154. [[nodiscard]] iterator begin() const noexcept {
  19155. return (index != Get) ? iterator{pools[index]->end() - static_cast<difference_type>(offset()), pools, filter, index} : iterator{};
  19156. }
  19157. /**
  19158. * @brief Returns an iterator that is past the last entity of the view.
  19159. * @return An iterator to the entity following the last entity of the view.
  19160. */
  19161. [[nodiscard]] iterator end() const noexcept {
  19162. return (index != Get) ? iterator{pools[index]->end(), pools, filter, index} : iterator{};
  19163. }
  19164. /**
  19165. * @brief Returns the first entity of the view, if any.
  19166. * @return The first entity of the view if one exists, the null entity
  19167. * otherwise.
  19168. */
  19169. [[nodiscard]] entity_type front() const noexcept {
  19170. const auto it = begin();
  19171. return it != end() ? *it : null;
  19172. }
  19173. /**
  19174. * @brief Returns the last entity of the view, if any.
  19175. * @return The last entity of the view if one exists, the null entity
  19176. * otherwise.
  19177. */
  19178. [[nodiscard]] entity_type back() const noexcept {
  19179. if(index != Get) {
  19180. auto it = pools[index]->rbegin();
  19181. const auto last = it + static_cast<difference_type>(offset());
  19182. for(const auto idx = static_cast<difference_type>(index); it != last && !(internal::all_of(pools.begin(), pools.begin() + idx, *it) && internal::all_of(pools.begin() + idx + 1, pools.end(), *it) && internal::none_of(filter.begin(), filter.end(), *it)); ++it) {}
  19183. return it == last ? null : *it;
  19184. }
  19185. return null;
  19186. }
  19187. /**
  19188. * @brief Finds an entity.
  19189. * @param entt A valid identifier.
  19190. * @return An iterator to the given entity if it's found, past the end
  19191. * iterator otherwise.
  19192. */
  19193. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  19194. return contains(entt) ? iterator{pools[index]->find(entt), pools, filter, index} : end();
  19195. }
  19196. /**
  19197. * @brief Checks if a view is fully initialized.
  19198. * @return True if the view is fully initialized, false otherwise.
  19199. */
  19200. [[nodiscard]] explicit operator bool() const noexcept {
  19201. return (index != Get) && internal::fully_initialized(filter.begin(), filter.end(), placeholder);
  19202. }
  19203. /**
  19204. * @brief Checks if a view contains an entity.
  19205. * @param entt A valid identifier.
  19206. * @return True if the view contains the given entity, false otherwise.
  19207. */
  19208. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  19209. return (index != Get)
  19210. && internal::all_of(pools.begin(), pools.end(), entt)
  19211. && internal::none_of(filter.begin(), filter.end(), entt)
  19212. && pools[index]->index(entt) < offset();
  19213. }
  19214. private:
  19215. std::array<const common_type *, Get> pools{};
  19216. std::array<const common_type *, Exclude> filter{};
  19217. const common_type *placeholder{internal::view_placeholder<common_type>()};
  19218. size_type index{Get};
  19219. };
  19220. /**
  19221. * @brief General purpose view.
  19222. *
  19223. * This view visits all entities that are at least in the given storage. During
  19224. * initialization, it also looks at the number of elements available for each
  19225. * storage and uses the smallest set in order to get a performance boost.
  19226. *
  19227. * @sa basic_view
  19228. *
  19229. * @tparam Get Types of storage iterated by the view.
  19230. * @tparam Exclude Types of storage used to filter the view.
  19231. */
  19232. template<typename... Get, typename... Exclude>
  19233. class basic_view<get_t<Get...>, exclude_t<Exclude...>, std::enable_if_t<(sizeof...(Get) != 0u)>>
  19234. : public basic_common_view<std::common_type_t<typename Get::base_type...>, internal::tombstone_check_v<Get...>, sizeof...(Get), sizeof...(Exclude)> {
  19235. using base_type = basic_common_view<std::common_type_t<typename Get::base_type...>, internal::tombstone_check_v<Get...>, sizeof...(Get), sizeof...(Exclude)>;
  19236. template<std::size_t Index>
  19237. using element_at = type_list_element_t<Index, type_list<Get..., Exclude...>>;
  19238. template<typename Type>
  19239. static constexpr std::size_t index_of = type_list_index_v<std::remove_const_t<Type>, type_list<typename Get::element_type..., typename Exclude::element_type...>>;
  19240. template<std::size_t... Index>
  19241. [[nodiscard]] auto get(const typename base_type::entity_type entt, std::index_sequence<Index...>) const noexcept {
  19242. return std::tuple_cat(storage<Index>()->get_as_tuple(entt)...);
  19243. }
  19244. template<std::size_t Curr, std::size_t Other, typename... Args>
  19245. [[nodiscard]] auto dispatch_get(const std::tuple<typename base_type::entity_type, Args...> &curr) const {
  19246. if constexpr(Curr == Other) {
  19247. return std::forward_as_tuple(std::get<Args>(curr)...);
  19248. } else {
  19249. return storage<Other>()->get_as_tuple(std::get<0>(curr));
  19250. }
  19251. }
  19252. template<std::size_t Curr, typename Func, std::size_t... Index>
  19253. void each(Func &func, std::index_sequence<Index...>) const {
  19254. for(const auto curr: storage<Curr>()->each()) {
  19255. if(const auto entt = std::get<0>(curr); (!internal::tombstone_check_v<Get...> || (entt != tombstone)) && ((Curr == Index || base_type::pool_at(Index)->contains(entt)) && ...) && base_type::none_of(entt)) {
  19256. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
  19257. std::apply(func, std::tuple_cat(std::make_tuple(entt), dispatch_get<Curr, Index>(curr)...));
  19258. } else {
  19259. std::apply(func, std::tuple_cat(dispatch_get<Curr, Index>(curr)...));
  19260. }
  19261. }
  19262. }
  19263. }
  19264. template<typename Func, std::size_t... Index>
  19265. void pick_and_each(Func &func, std::index_sequence<Index...> seq) const {
  19266. if(const auto *view = base_type::handle(); view != nullptr) {
  19267. ((view == base_type::pool_at(Index) ? each<Index>(func, seq) : void()), ...);
  19268. }
  19269. }
  19270. public:
  19271. /*! @brief Common type among all storage types. */
  19272. using common_type = typename base_type::common_type;
  19273. /*! @brief Underlying entity identifier. */
  19274. using entity_type = typename base_type::entity_type;
  19275. /*! @brief Unsigned integer type. */
  19276. using size_type = typename base_type::size_type;
  19277. /*! @brief Signed integer type. */
  19278. using difference_type = std::ptrdiff_t;
  19279. /*! @brief Forward iterator type. */
  19280. using iterator = typename base_type::iterator;
  19281. /*! @brief Iterable view type. */
  19282. using iterable = iterable_adaptor<internal::extended_view_iterator<iterator, Get...>>;
  19283. /*! @brief Default constructor to use to create empty, invalid views. */
  19284. basic_view() noexcept
  19285. : base_type{} {}
  19286. /**
  19287. * @brief Constructs a view from a set of storage classes.
  19288. * @param value The storage for the types to iterate.
  19289. * @param excl The storage for the types used to filter the view.
  19290. */
  19291. basic_view(Get &...value, Exclude &...excl) noexcept
  19292. : base_type{{&value...}, {&excl...}} {
  19293. }
  19294. /**
  19295. * @brief Constructs a view from a set of storage classes.
  19296. * @param value The storage for the types to iterate.
  19297. * @param excl The storage for the types used to filter the view.
  19298. */
  19299. basic_view(std::tuple<Get &...> value, std::tuple<Exclude &...> excl = {}) noexcept
  19300. : basic_view{std::make_from_tuple<basic_view>(std::tuple_cat(value, excl))} {}
  19301. /**
  19302. * @brief Forces a view to use a given element to drive iterations
  19303. * @tparam Type Type of element to use to drive iterations.
  19304. */
  19305. template<typename Type>
  19306. void use() noexcept {
  19307. use<index_of<Type>>();
  19308. }
  19309. /**
  19310. * @brief Forces a view to use a given element to drive iterations
  19311. * @tparam Index Index of the element to use to drive iterations.
  19312. */
  19313. template<std::size_t Index>
  19314. void use() noexcept {
  19315. base_type::use(Index);
  19316. }
  19317. /**
  19318. * @brief Returns the storage for a given element type, if any.
  19319. * @tparam Type Type of element of which to return the storage.
  19320. * @return The storage for the given element type.
  19321. */
  19322. template<typename Type>
  19323. [[nodiscard]] auto *storage() const noexcept {
  19324. return storage<index_of<Type>>();
  19325. }
  19326. /**
  19327. * @brief Returns the storage for a given index, if any.
  19328. * @tparam Index Index of the storage to return.
  19329. * @return The storage for the given index.
  19330. */
  19331. template<std::size_t Index>
  19332. [[nodiscard]] auto *storage() const noexcept {
  19333. if constexpr(Index < sizeof...(Get)) {
  19334. return static_cast<element_at<Index> *>(const_cast<constness_as_t<common_type, element_at<Index>> *>(base_type::pool_at(Index)));
  19335. } else {
  19336. return static_cast<element_at<Index> *>(const_cast<constness_as_t<common_type, element_at<Index>> *>(base_type::filter_at(Index - sizeof...(Get))));
  19337. }
  19338. }
  19339. /**
  19340. * @brief Assigns a storage to a view.
  19341. * @tparam Type Type of storage to assign to the view.
  19342. * @param elem A storage to assign to the view.
  19343. */
  19344. template<typename Type>
  19345. void storage(Type &elem) noexcept {
  19346. storage<index_of<typename Type::element_type>>(elem);
  19347. }
  19348. /**
  19349. * @brief Assigns a storage to a view.
  19350. * @tparam Index Index of the storage to assign to the view.
  19351. * @tparam Type Type of storage to assign to the view.
  19352. * @param elem A storage to assign to the view.
  19353. */
  19354. template<std::size_t Index, typename Type>
  19355. void storage(Type &elem) noexcept {
  19356. static_assert(std::is_convertible_v<Type &, element_at<Index> &>, "Unexpected type");
  19357. if constexpr(Index < sizeof...(Get)) {
  19358. base_type::pool_at(Index, &elem);
  19359. } else {
  19360. base_type::filter_at(Index - sizeof...(Get), &elem);
  19361. }
  19362. }
  19363. /**
  19364. * @brief Returns the elements assigned to the given entity.
  19365. * @param entt A valid identifier.
  19366. * @return The elements assigned to the given entity.
  19367. */
  19368. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  19369. return get(entt);
  19370. }
  19371. /**
  19372. * @brief Returns the elements assigned to the given entity.
  19373. * @tparam Type Type of the element to get.
  19374. * @tparam Other Other types of elements to get.
  19375. * @param entt A valid identifier.
  19376. * @return The elements assigned to the entity.
  19377. */
  19378. template<typename Type, typename... Other>
  19379. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  19380. return get<index_of<Type>, index_of<Other>...>(entt);
  19381. }
  19382. /**
  19383. * @brief Returns the elements assigned to the given entity.
  19384. * @tparam Index Indexes of the elements to get.
  19385. * @param entt A valid identifier.
  19386. * @return The elements assigned to the entity.
  19387. */
  19388. template<std::size_t... Index>
  19389. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  19390. if constexpr(sizeof...(Index) == 0) {
  19391. return get(entt, std::index_sequence_for<Get...>{});
  19392. } else if constexpr(sizeof...(Index) == 1) {
  19393. return (storage<Index>()->get(entt), ...);
  19394. } else {
  19395. return std::tuple_cat(storage<Index>()->get_as_tuple(entt)...);
  19396. }
  19397. }
  19398. /**
  19399. * @brief Iterates entities and elements and applies the given function
  19400. * object to them.
  19401. *
  19402. * The signature of the function must be equivalent to one of the following
  19403. * (non-empty types only, constness as requested):
  19404. *
  19405. * @code{.cpp}
  19406. * void(const entity_type, Type &...);
  19407. * void(Type &...);
  19408. * @endcode
  19409. *
  19410. * @tparam Func Type of the function object to invoke.
  19411. * @param func A valid function object.
  19412. */
  19413. template<typename Func>
  19414. void each(Func func) const {
  19415. pick_and_each(func, std::index_sequence_for<Get...>{});
  19416. }
  19417. /**
  19418. * @brief Returns an iterable object to use to _visit_ a view.
  19419. *
  19420. * The iterable object returns a tuple that contains the current entity and
  19421. * a set of references to its non-empty elements. The _constness_ of the
  19422. * elements is as requested.
  19423. *
  19424. * @return An iterable object to use to _visit_ the view.
  19425. */
  19426. [[nodiscard]] iterable each() const noexcept {
  19427. return iterable{base_type::begin(), base_type::end()};
  19428. }
  19429. /**
  19430. * @brief Combines a view and a storage in _more specific_ view.
  19431. * @tparam OGet Type of storage to combine the view with.
  19432. * @param other The storage for the type to combine the view with.
  19433. * @return A more specific view.
  19434. */
  19435. template<typename OGet>
  19436. [[nodiscard]] std::enable_if_t<std::is_base_of_v<common_type, OGet>, basic_view<get_t<Get..., OGet>, exclude_t<Exclude...>>> operator|(OGet &other) const noexcept {
  19437. return *this | basic_view<get_t<OGet>, exclude_t<>>{other};
  19438. }
  19439. /**
  19440. * @brief Combines two views in a _more specific_ one.
  19441. * @tparam OGet Element list of the view to combine with.
  19442. * @tparam OExclude Filter list of the view to combine with.
  19443. * @param other The view to combine with.
  19444. * @return A more specific view.
  19445. */
  19446. template<typename... OGet, typename... OExclude>
  19447. [[nodiscard]] auto operator|(const basic_view<get_t<OGet...>, exclude_t<OExclude...>> &other) const noexcept {
  19448. return internal::view_pack<basic_view<get_t<Get..., OGet...>, exclude_t<Exclude..., OExclude...>>>(
  19449. *this, other, std::index_sequence_for<Get...>{}, std::index_sequence_for<Exclude...>{}, std::index_sequence_for<OGet...>{}, std::index_sequence_for<OExclude...>{});
  19450. }
  19451. };
  19452. /**
  19453. * @brief Basic storage view implementation.
  19454. * @warning For internal use only, backward compatibility not guaranteed.
  19455. * @tparam Type Common type among all storage types.
  19456. * @tparam Policy Storage policy.
  19457. */
  19458. template<typename Type, deletion_policy Policy>
  19459. class basic_storage_view {
  19460. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Unexpected type");
  19461. protected:
  19462. /*! @cond TURN_OFF_DOXYGEN */
  19463. basic_storage_view() noexcept = default;
  19464. basic_storage_view(const Type *value) noexcept
  19465. : leading{value} {
  19466. ENTT_ASSERT(leading->policy() == Policy, "Unexpected storage policy");
  19467. }
  19468. /*! @endcond */
  19469. public:
  19470. /*! @brief Common type among all storage types. */
  19471. using common_type = Type;
  19472. /*! @brief Underlying entity identifier. */
  19473. using entity_type = typename common_type::entity_type;
  19474. /*! @brief Unsigned integer type. */
  19475. using size_type = std::size_t;
  19476. /*! @brief Signed integer type. */
  19477. using difference_type = std::ptrdiff_t;
  19478. /*! @brief Random access iterator type. */
  19479. using iterator = std::conditional_t<Policy == deletion_policy::in_place, internal::view_iterator<common_type, true, 1u, 0u>, typename common_type::iterator>;
  19480. /*! @brief Reverse iterator type. */
  19481. using reverse_iterator = std::conditional_t<Policy == deletion_policy::in_place, void, typename common_type::reverse_iterator>;
  19482. /**
  19483. * @brief Returns the leading storage of a view, if any.
  19484. * @return The leading storage of the view.
  19485. */
  19486. [[nodiscard]] const common_type *handle() const noexcept {
  19487. return leading;
  19488. }
  19489. /**
  19490. * @brief Returns the number of entities that have the given element.
  19491. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  19492. * @return Number of entities that have the given element.
  19493. */
  19494. template<typename..., deletion_policy Pol = Policy>
  19495. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, size_type> size() const noexcept {
  19496. if constexpr(Policy == deletion_policy::swap_and_pop) {
  19497. return leading ? leading->size() : size_type{};
  19498. } else {
  19499. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  19500. return leading ? leading->free_list() : size_type{};
  19501. }
  19502. }
  19503. /**
  19504. * @brief Estimates the number of entities iterated by the view.
  19505. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  19506. * @return Estimated number of entities iterated by the view.
  19507. */
  19508. template<typename..., deletion_policy Pol = Policy>
  19509. [[nodiscard]] std::enable_if_t<Pol == deletion_policy::in_place, size_type> size_hint() const noexcept {
  19510. return leading ? leading->size() : size_type{};
  19511. }
  19512. /**
  19513. * @brief Checks whether a view is empty.
  19514. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  19515. * @return True if the view is empty, false otherwise.
  19516. */
  19517. template<typename..., deletion_policy Pol = Policy>
  19518. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, bool> empty() const noexcept {
  19519. if constexpr(Policy == deletion_policy::swap_and_pop) {
  19520. return !leading || leading->empty();
  19521. } else {
  19522. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  19523. return !leading || (leading->free_list() == 0u);
  19524. }
  19525. }
  19526. /**
  19527. * @brief Returns an iterator to the first entity of the view.
  19528. *
  19529. * If the view is empty, the returned iterator will be equal to `end()`.
  19530. *
  19531. * @return An iterator to the first entity of the view.
  19532. */
  19533. [[nodiscard]] iterator begin() const noexcept {
  19534. if constexpr(Policy == deletion_policy::swap_and_pop) {
  19535. return leading ? leading->begin() : iterator{};
  19536. } else if constexpr(Policy == deletion_policy::swap_only) {
  19537. return leading ? (leading->end() - static_cast<difference_type>(leading->free_list())) : iterator{};
  19538. } else {
  19539. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  19540. return leading ? iterator{leading->begin(), {leading}, {}, 0u} : iterator{};
  19541. }
  19542. }
  19543. /**
  19544. * @brief Returns an iterator that is past the last entity of the view.
  19545. * @return An iterator to the entity following the last entity of the view.
  19546. */
  19547. [[nodiscard]] iterator end() const noexcept {
  19548. if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) {
  19549. return leading ? leading->end() : iterator{};
  19550. } else {
  19551. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  19552. return leading ? iterator{leading->end(), {leading}, {}, 0u} : iterator{};
  19553. }
  19554. }
  19555. /**
  19556. * @brief Returns an iterator to the first entity of the reversed view.
  19557. *
  19558. * If the view is empty, the returned iterator will be equal to `rend()`.
  19559. *
  19560. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  19561. * @return An iterator to the first entity of the reversed view.
  19562. */
  19563. template<typename..., deletion_policy Pol = Policy>
  19564. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, reverse_iterator> rbegin() const noexcept {
  19565. return leading ? leading->rbegin() : reverse_iterator{};
  19566. }
  19567. /**
  19568. * @brief Returns an iterator that is past the last entity of the reversed
  19569. * view.
  19570. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  19571. * @return An iterator to the entity following the last entity of the
  19572. * reversed view.
  19573. */
  19574. template<typename..., deletion_policy Pol = Policy>
  19575. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, reverse_iterator> rend() const noexcept {
  19576. if constexpr(Policy == deletion_policy::swap_and_pop) {
  19577. return leading ? leading->rend() : reverse_iterator{};
  19578. } else {
  19579. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  19580. return leading ? (leading->rbegin() + static_cast<difference_type>(leading->free_list())) : reverse_iterator{};
  19581. }
  19582. }
  19583. /**
  19584. * @brief Returns the first entity of the view, if any.
  19585. * @return The first entity of the view if one exists, the null entity
  19586. * otherwise.
  19587. */
  19588. [[nodiscard]] entity_type front() const noexcept {
  19589. if constexpr(Policy == deletion_policy::swap_and_pop) {
  19590. return empty() ? null : *leading->begin();
  19591. } else if constexpr(Policy == deletion_policy::swap_only) {
  19592. return empty() ? null : *(leading->end() - static_cast<difference_type>(leading->free_list()));
  19593. } else {
  19594. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  19595. const auto it = begin();
  19596. return (it == end()) ? null : *it;
  19597. }
  19598. }
  19599. /**
  19600. * @brief Returns the last entity of the view, if any.
  19601. * @return The last entity of the view if one exists, the null entity
  19602. * otherwise.
  19603. */
  19604. [[nodiscard]] entity_type back() const noexcept {
  19605. if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) {
  19606. return empty() ? null : *leading->rbegin();
  19607. } else {
  19608. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  19609. if(leading) {
  19610. auto it = leading->rbegin();
  19611. const auto last = leading->rend();
  19612. for(; (it != last) && (*it == tombstone); ++it) {}
  19613. return it == last ? null : *it;
  19614. }
  19615. return null;
  19616. }
  19617. }
  19618. /**
  19619. * @brief Finds an entity.
  19620. * @param entt A valid identifier.
  19621. * @return An iterator to the given entity if it's found, past the end
  19622. * iterator otherwise.
  19623. */
  19624. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  19625. if constexpr(Policy == deletion_policy::swap_and_pop) {
  19626. return leading ? leading->find(entt) : iterator{};
  19627. } else if constexpr(Policy == deletion_policy::swap_only) {
  19628. const auto it = leading ? leading->find(entt) : iterator{};
  19629. return leading && (static_cast<size_type>(it.index()) < leading->free_list()) ? it : iterator{};
  19630. } else {
  19631. return leading ? iterator{leading->find(entt), {leading}, {}, 0u} : iterator{};
  19632. }
  19633. }
  19634. /**
  19635. * @brief Checks if a view is fully initialized.
  19636. * @return True if the view is fully initialized, false otherwise.
  19637. */
  19638. [[nodiscard]] explicit operator bool() const noexcept {
  19639. return (leading != nullptr);
  19640. }
  19641. /**
  19642. * @brief Checks if a view contains an entity.
  19643. * @param entt A valid identifier.
  19644. * @return True if the view contains the given entity, false otherwise.
  19645. */
  19646. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  19647. if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::in_place) {
  19648. return leading && leading->contains(entt);
  19649. } else {
  19650. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  19651. return leading && leading->contains(entt) && (leading->index(entt) < leading->free_list());
  19652. }
  19653. }
  19654. private:
  19655. const common_type *leading{};
  19656. };
  19657. /**
  19658. * @brief Storage view specialization.
  19659. *
  19660. * This specialization offers a boost in terms of performance. It can access the
  19661. * underlying data structure directly and avoid superfluous checks.
  19662. *
  19663. * @sa basic_view
  19664. *
  19665. * @tparam Get Type of storage iterated by the view.
  19666. */
  19667. template<typename Get>
  19668. class basic_view<get_t<Get>, exclude_t<>>
  19669. : public basic_storage_view<typename Get::base_type, Get::storage_policy> {
  19670. using base_type = basic_storage_view<typename Get::base_type, Get::storage_policy>;
  19671. public:
  19672. /*! @brief Common type among all storage types. */
  19673. using common_type = typename base_type::common_type;
  19674. /*! @brief Underlying entity identifier. */
  19675. using entity_type = typename base_type::entity_type;
  19676. /*! @brief Unsigned integer type. */
  19677. using size_type = typename base_type::size_type;
  19678. /*! @brief Signed integer type. */
  19679. using difference_type = std::ptrdiff_t;
  19680. /*! @brief Random access iterator type. */
  19681. using iterator = typename base_type::iterator;
  19682. /*! @brief Reverse iterator type. */
  19683. using reverse_iterator = typename base_type::reverse_iterator;
  19684. /*! @brief Iterable view type. */
  19685. using iterable = std::conditional_t<Get::storage_policy == deletion_policy::in_place, iterable_adaptor<internal::extended_view_iterator<iterator, Get>>, decltype(std::declval<Get>().each())>;
  19686. /*! @brief Default constructor to use to create empty, invalid views. */
  19687. basic_view() noexcept
  19688. : base_type{} {}
  19689. /**
  19690. * @brief Constructs a view from a storage class.
  19691. * @param value The storage for the type to iterate.
  19692. */
  19693. basic_view(Get &value) noexcept
  19694. : base_type{&value} {
  19695. }
  19696. /**
  19697. * @brief Constructs a view from a storage class.
  19698. * @param value The storage for the type to iterate.
  19699. */
  19700. basic_view(std::tuple<Get &> value, std::tuple<> = {}) noexcept
  19701. : basic_view{std::get<0>(value)} {}
  19702. /**
  19703. * @brief Returns the storage for a given element type, if any.
  19704. * @tparam Type Type of element of which to return the storage.
  19705. * @return The storage for the given element type.
  19706. */
  19707. template<typename Type = typename Get::element_type>
  19708. [[nodiscard]] auto *storage() const noexcept {
  19709. static_assert(std::is_same_v<std::remove_const_t<Type>, typename Get::element_type>, "Invalid element type");
  19710. return storage<0>();
  19711. }
  19712. /**
  19713. * @brief Returns the storage for a given index, if any.
  19714. * @tparam Index Index of the storage to return.
  19715. * @return The storage for the given index.
  19716. */
  19717. template<std::size_t Index>
  19718. [[nodiscard]] auto *storage() const noexcept {
  19719. static_assert(Index == 0u, "Index out of bounds");
  19720. return static_cast<Get *>(const_cast<constness_as_t<common_type, Get> *>(base_type::handle()));
  19721. }
  19722. /**
  19723. * @brief Assigns a storage to a view.
  19724. * @param elem A storage to assign to the view.
  19725. */
  19726. void storage(Get &elem) noexcept {
  19727. storage<0>(elem);
  19728. }
  19729. /**
  19730. * @brief Assigns a storage to a view.
  19731. * @tparam Index Index of the storage to assign to the view.
  19732. * @param elem A storage to assign to the view.
  19733. */
  19734. template<std::size_t Index>
  19735. void storage(Get &elem) noexcept {
  19736. static_assert(Index == 0u, "Index out of bounds");
  19737. *this = basic_view{elem};
  19738. }
  19739. /**
  19740. * @brief Returns a pointer to the underlying storage.
  19741. * @return A pointer to the underlying storage.
  19742. */
  19743. [[nodiscard]] Get *operator->() const noexcept {
  19744. return storage();
  19745. }
  19746. /**
  19747. * @brief Returns the element assigned to the given entity.
  19748. * @param entt A valid identifier.
  19749. * @return The element assigned to the given entity.
  19750. */
  19751. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  19752. return storage()->get(entt);
  19753. }
  19754. /**
  19755. * @brief Returns the element assigned to the given entity.
  19756. * @tparam Elem Type of the element to get.
  19757. * @param entt A valid identifier.
  19758. * @return The element assigned to the entity.
  19759. */
  19760. template<typename Elem>
  19761. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  19762. static_assert(std::is_same_v<std::remove_const_t<Elem>, typename Get::element_type>, "Invalid element type");
  19763. return get<0>(entt);
  19764. }
  19765. /**
  19766. * @brief Returns the element assigned to the given entity.
  19767. * @tparam Index Index of the element to get.
  19768. * @param entt A valid identifier.
  19769. * @return The element assigned to the entity.
  19770. */
  19771. template<std::size_t... Index>
  19772. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  19773. if constexpr(sizeof...(Index) == 0) {
  19774. return storage()->get_as_tuple(entt);
  19775. } else {
  19776. return storage<Index...>()->get(entt);
  19777. }
  19778. }
  19779. /**
  19780. * @brief Iterates entities and elements and applies the given function
  19781. * object to them.
  19782. *
  19783. * The signature of the function must be equivalent to one of the following
  19784. * (non-empty types only, constness as requested):
  19785. *
  19786. * @code{.cpp}
  19787. * void(const entity_type, Type &);
  19788. * void(typename Type &);
  19789. * @endcode
  19790. *
  19791. * @tparam Func Type of the function object to invoke.
  19792. * @param func A valid function object.
  19793. */
  19794. template<typename Func>
  19795. void each(Func func) const {
  19796. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
  19797. for(const auto pack: each()) {
  19798. std::apply(func, pack);
  19799. }
  19800. } else if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) {
  19801. if constexpr(std::is_void_v<typename Get::value_type>) {
  19802. for(size_type pos = base_type::size(); pos; --pos) {
  19803. func();
  19804. }
  19805. } else {
  19806. if(const auto len = static_cast<difference_type>(base_type::size()); len != 0) {
  19807. for(auto last = storage()->end(), first = last - len; first != last; ++first) {
  19808. func(*first);
  19809. }
  19810. }
  19811. }
  19812. } else {
  19813. static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy");
  19814. for(const auto pack: each()) {
  19815. std::apply([&func](const auto, auto &&...elem) { func(std::forward<decltype(elem)>(elem)...); }, pack);
  19816. }
  19817. }
  19818. }
  19819. /**
  19820. * @brief Returns an iterable object to use to _visit_ a view.
  19821. *
  19822. * The iterable object returns a tuple that contains the current entity and
  19823. * a reference to its element if it's a non-empty one. The _constness_ of
  19824. * the element is as requested.
  19825. *
  19826. * @return An iterable object to use to _visit_ the view.
  19827. */
  19828. [[nodiscard]] iterable each() const noexcept {
  19829. if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) {
  19830. return base_type::handle() ? storage()->each() : iterable{};
  19831. } else {
  19832. static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy");
  19833. return iterable{base_type::begin(), base_type::end()};
  19834. }
  19835. }
  19836. /**
  19837. * @brief Combines a view and a storage in _more specific_ view.
  19838. * @tparam OGet Type of storage to combine the view with.
  19839. * @param other The storage for the type to combine the view with.
  19840. * @return A more specific view.
  19841. */
  19842. template<typename OGet>
  19843. [[nodiscard]] std::enable_if_t<std::is_base_of_v<common_type, OGet>, basic_view<get_t<Get, OGet>, exclude_t<>>> operator|(OGet &other) const noexcept {
  19844. return *this | basic_view<get_t<OGet>, exclude_t<>>{other};
  19845. }
  19846. /**
  19847. * @brief Combines two views in a _more specific_ one.
  19848. * @tparam OGet Element list of the view to combine with.
  19849. * @tparam OExclude Filter list of the view to combine with.
  19850. * @param other The view to combine with.
  19851. * @return A more specific view.
  19852. */
  19853. template<typename... OGet, typename... OExclude>
  19854. [[nodiscard]] auto operator|(const basic_view<get_t<OGet...>, exclude_t<OExclude...>> &other) const noexcept {
  19855. return internal::view_pack<basic_view<get_t<Get, OGet...>, exclude_t<OExclude...>>>(
  19856. *this, other, std::index_sequence_for<Get>{}, std::index_sequence_for<>{}, std::index_sequence_for<OGet...>{}, std::index_sequence_for<OExclude...>{});
  19857. }
  19858. };
  19859. /**
  19860. * @brief Deduction guide.
  19861. * @tparam Type Type of storage classes used to create the view.
  19862. * @param storage The storage for the types to iterate.
  19863. */
  19864. template<typename... Type>
  19865. basic_view(Type &...storage) -> basic_view<get_t<Type...>, exclude_t<>>;
  19866. /**
  19867. * @brief Deduction guide.
  19868. * @tparam Get Types of elements iterated by the view.
  19869. * @tparam Exclude Types of elements used to filter the view.
  19870. */
  19871. template<typename... Get, typename... Exclude>
  19872. basic_view(std::tuple<Get &...>, std::tuple<Exclude &...> = {}) -> basic_view<get_t<Get...>, exclude_t<Exclude...>>;
  19873. } // namespace entt
  19874. #endif
  19875. namespace entt {
  19876. /**
  19877. * @brief Converts a registry to a view.
  19878. * @tparam Registry Basic registry type.
  19879. */
  19880. template<typename Registry>
  19881. class as_view {
  19882. template<typename... Get, typename... Exclude>
  19883. [[nodiscard]] auto dispatch(get_t<Get...>, exclude_t<Exclude...>) const {
  19884. return reg->template view<constness_as_t<typename Get::element_type, Get>...>(exclude_t<constness_as_t<typename Exclude::element_type, Exclude>...>{});
  19885. }
  19886. public:
  19887. /*! @brief Type of registry to convert. */
  19888. using registry_type = Registry;
  19889. /*! @brief Underlying entity identifier. */
  19890. using entity_type = typename registry_type::entity_type;
  19891. /**
  19892. * @brief Constructs a converter for a given registry.
  19893. * @param source A valid reference to a registry.
  19894. */
  19895. as_view(registry_type &source) noexcept
  19896. : reg{&source} {}
  19897. /**
  19898. * @brief Conversion function from a registry to a view.
  19899. * @tparam Get Type of storage used to construct the view.
  19900. * @tparam Exclude Types of storage used to filter the view.
  19901. * @return A newly created view.
  19902. */
  19903. template<typename Get, typename Exclude>
  19904. operator basic_view<Get, Exclude>() const {
  19905. return dispatch(Get{}, Exclude{});
  19906. }
  19907. private:
  19908. registry_type *reg;
  19909. };
  19910. /**
  19911. * @brief Converts a registry to a group.
  19912. * @tparam Registry Basic registry type.
  19913. */
  19914. template<typename Registry>
  19915. class as_group {
  19916. template<typename... Owned, typename... Get, typename... Exclude>
  19917. [[nodiscard]] auto dispatch(owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>) const {
  19918. if constexpr(std::is_const_v<registry_type>) {
  19919. return reg->template group_if_exists<typename Owned::element_type...>(get_t<typename Get::element_type...>{}, exclude_t<typename Exclude::element_type...>{});
  19920. } else {
  19921. return reg->template group<constness_as_t<typename Owned::element_type, Owned>...>(get_t<constness_as_t<typename Get::element_type, Get>...>{}, exclude_t<constness_as_t<typename Exclude::element_type, Exclude>...>{});
  19922. }
  19923. }
  19924. public:
  19925. /*! @brief Type of registry to convert. */
  19926. using registry_type = Registry;
  19927. /*! @brief Underlying entity identifier. */
  19928. using entity_type = typename registry_type::entity_type;
  19929. /**
  19930. * @brief Constructs a converter for a given registry.
  19931. * @param source A valid reference to a registry.
  19932. */
  19933. as_group(registry_type &source) noexcept
  19934. : reg{&source} {}
  19935. /**
  19936. * @brief Conversion function from a registry to a group.
  19937. * @tparam Owned Types of _owned_ by the group.
  19938. * @tparam Get Types of storage _observed_ by the group.
  19939. * @tparam Exclude Types of storage used to filter the group.
  19940. * @return A newly created group.
  19941. */
  19942. template<typename Owned, typename Get, typename Exclude>
  19943. operator basic_group<Owned, Get, Exclude>() const {
  19944. return dispatch(Owned{}, Get{}, Exclude{});
  19945. }
  19946. private:
  19947. registry_type *reg;
  19948. };
  19949. /**
  19950. * @brief Helper to create a listener that directly invokes a member function.
  19951. * @tparam Member Member function to invoke on an element of the given type.
  19952. * @tparam Registry Basic registry type.
  19953. * @param reg A registry that contains the given entity and its elements.
  19954. * @param entt Entity from which to get the element.
  19955. */
  19956. template<auto Member, typename Registry = std::decay_t<nth_argument_t<0u, decltype(Member)>>>
  19957. void invoke(Registry &reg, const typename Registry::entity_type entt) {
  19958. static_assert(std::is_member_function_pointer_v<decltype(Member)>, "Invalid pointer to non-static member function");
  19959. (reg.template get<member_class_t<decltype(Member)>>(entt).*Member)(reg, entt);
  19960. }
  19961. /**
  19962. * @brief Returns the entity associated with a given element.
  19963. *
  19964. * @warning
  19965. * Currently, this function only works correctly with the default storage as it
  19966. * makes assumptions about how the elements are laid out.
  19967. *
  19968. * @tparam Args Storage type template parameters.
  19969. * @param storage A storage that contains the given element.
  19970. * @param instance A valid element instance.
  19971. * @return The entity associated with the given element.
  19972. */
  19973. template<typename... Args>
  19974. typename basic_storage<Args...>::entity_type to_entity(const basic_storage<Args...> &storage, const typename basic_storage<Args...>::value_type &instance) {
  19975. using traits_type = component_traits<typename basic_storage<Args...>::value_type, typename basic_storage<Args...>::entity_type>;
  19976. static_assert(traits_type::page_size != 0u, "Unexpected page size");
  19977. const auto *page = storage.raw();
  19978. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  19979. for(std::size_t pos{}, count = storage.size(); pos < count; pos += traits_type::page_size, ++page) {
  19980. if(const auto dist = (std::addressof(instance) - *page); dist >= 0 && dist < static_cast<decltype(dist)>(traits_type::page_size)) {
  19981. return *(static_cast<const typename basic_storage<Args...>::base_type &>(storage).rbegin() + static_cast<decltype(dist)>(pos) + dist);
  19982. }
  19983. }
  19984. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  19985. return null;
  19986. }
  19987. /*! @brief Primary template isn't defined on purpose. */
  19988. template<typename...>
  19989. struct sigh_helper;
  19990. /**
  19991. * @brief Signal connection helper for registries.
  19992. * @tparam Registry Basic registry type.
  19993. */
  19994. template<typename Registry>
  19995. struct sigh_helper<Registry> {
  19996. /*! @brief Registry type. */
  19997. using registry_type = Registry;
  19998. /**
  19999. * @brief Constructs a helper for a given registry.
  20000. * @param ref A valid reference to a registry.
  20001. */
  20002. sigh_helper(registry_type &ref)
  20003. : bucket{&ref} {}
  20004. /**
  20005. * @brief Binds a properly initialized helper to a given signal type.
  20006. * @tparam Type Type of signal to bind the helper to.
  20007. * @param id Optional name for the underlying storage to use.
  20008. * @return A helper for a given registry and signal type.
  20009. */
  20010. template<typename Type>
  20011. auto with(const id_type id = type_hash<Type>::value()) noexcept {
  20012. return sigh_helper<registry_type, Type>{*bucket, id};
  20013. }
  20014. /**
  20015. * @brief Returns a reference to the underlying registry.
  20016. * @return A reference to the underlying registry.
  20017. */
  20018. [[nodiscard]] registry_type &registry() noexcept {
  20019. return *bucket;
  20020. }
  20021. private:
  20022. registry_type *bucket;
  20023. };
  20024. /**
  20025. * @brief Signal connection helper for registries.
  20026. * @tparam Registry Basic registry type.
  20027. * @tparam Type Type of signal to connect listeners to.
  20028. */
  20029. template<typename Registry, typename Type>
  20030. struct sigh_helper<Registry, Type> final: sigh_helper<Registry> {
  20031. /*! @brief Registry type. */
  20032. using registry_type = Registry;
  20033. /**
  20034. * @brief Constructs a helper for a given registry.
  20035. * @param ref A valid reference to a registry.
  20036. * @param id Optional name for the underlying storage to use.
  20037. */
  20038. sigh_helper(registry_type &ref, const id_type id = type_hash<Type>::value())
  20039. : sigh_helper<Registry>{ref},
  20040. name{id} {}
  20041. /**
  20042. * @brief Forwards the call to `on_construct` on the underlying storage.
  20043. * @tparam Candidate Function or member to connect.
  20044. * @tparam Args Type of class or type of payload, if any.
  20045. * @param args A valid object that fits the purpose, if any.
  20046. * @return This helper.
  20047. */
  20048. template<auto Candidate, typename... Args>
  20049. auto on_construct(Args &&...args) {
  20050. this->registry().template on_construct<Type>(name).template connect<Candidate>(std::forward<Args>(args)...);
  20051. return *this;
  20052. }
  20053. /**
  20054. * @brief Forwards the call to `on_update` on the underlying storage.
  20055. * @tparam Candidate Function or member to connect.
  20056. * @tparam Args Type of class or type of payload, if any.
  20057. * @param args A valid object that fits the purpose, if any.
  20058. * @return This helper.
  20059. */
  20060. template<auto Candidate, typename... Args>
  20061. auto on_update(Args &&...args) {
  20062. this->registry().template on_update<Type>(name).template connect<Candidate>(std::forward<Args>(args)...);
  20063. return *this;
  20064. }
  20065. /**
  20066. * @brief Forwards the call to `on_destroy` on the underlying storage.
  20067. * @tparam Candidate Function or member to connect.
  20068. * @tparam Args Type of class or type of payload, if any.
  20069. * @param args A valid object that fits the purpose, if any.
  20070. * @return This helper.
  20071. */
  20072. template<auto Candidate, typename... Args>
  20073. auto on_destroy(Args &&...args) {
  20074. this->registry().template on_destroy<Type>(name).template connect<Candidate>(std::forward<Args>(args)...);
  20075. return *this;
  20076. }
  20077. private:
  20078. id_type name;
  20079. };
  20080. /**
  20081. * @brief Deduction guide.
  20082. * @tparam Registry Basic registry type.
  20083. */
  20084. template<typename Registry>
  20085. sigh_helper(Registry &) -> sigh_helper<Registry>;
  20086. } // namespace entt
  20087. #endif
  20088. // #include "entity/mixin.hpp"
  20089. #ifndef ENTT_ENTITY_MIXIN_HPP
  20090. #define ENTT_ENTITY_MIXIN_HPP
  20091. #include <type_traits>
  20092. #include <utility>
  20093. // #include "../config/config.h"
  20094. // #include "../core/any.hpp"
  20095. // #include "../core/type_info.hpp"
  20096. // #include "../signal/sigh.hpp"
  20097. #ifndef ENTT_SIGNAL_SIGH_HPP
  20098. #define ENTT_SIGNAL_SIGH_HPP
  20099. #include <cstddef>
  20100. #include <memory>
  20101. #include <type_traits>
  20102. #include <utility>
  20103. #include <vector>
  20104. // #include "delegate.hpp"
  20105. #ifndef ENTT_SIGNAL_DELEGATE_HPP
  20106. #define ENTT_SIGNAL_DELEGATE_HPP
  20107. #include <cstddef>
  20108. #include <functional>
  20109. #include <tuple>
  20110. #include <type_traits>
  20111. #include <utility>
  20112. // #include "../config/config.h"
  20113. #ifndef ENTT_CONFIG_CONFIG_H
  20114. #define ENTT_CONFIG_CONFIG_H
  20115. // #include "version.h"
  20116. #ifndef ENTT_CONFIG_VERSION_H
  20117. #define ENTT_CONFIG_VERSION_H
  20118. // #include "macro.h"
  20119. #ifndef ENTT_CONFIG_MACRO_H
  20120. #define ENTT_CONFIG_MACRO_H
  20121. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  20122. #define ENTT_STR(arg) #arg
  20123. #define ENTT_XSTR(arg) ENTT_STR(arg)
  20124. // NOLINTEND(cppcoreguidelines-macro-usage)
  20125. #endif
  20126. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  20127. #define ENTT_VERSION_MAJOR 3
  20128. #define ENTT_VERSION_MINOR 16
  20129. #define ENTT_VERSION_PATCH 0
  20130. #define ENTT_VERSION \
  20131. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  20132. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  20133. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  20134. #endif
  20135. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  20136. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  20137. # define ENTT_CONSTEXPR
  20138. # define ENTT_THROW throw
  20139. # define ENTT_TRY try
  20140. # define ENTT_CATCH catch(...)
  20141. #else
  20142. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  20143. # define ENTT_THROW
  20144. # define ENTT_TRY if(true)
  20145. # define ENTT_CATCH if(false)
  20146. #endif
  20147. #if __has_include(<version>)
  20148. # include <version>
  20149. #
  20150. # if defined(__cpp_consteval)
  20151. # define ENTT_CONSTEVAL consteval
  20152. # endif
  20153. #endif
  20154. #ifndef ENTT_CONSTEVAL
  20155. # define ENTT_CONSTEVAL constexpr
  20156. #endif
  20157. #ifdef ENTT_USE_ATOMIC
  20158. # include <atomic>
  20159. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  20160. #else
  20161. # define ENTT_MAYBE_ATOMIC(Type) Type
  20162. #endif
  20163. #ifndef ENTT_ID_TYPE
  20164. # include <cstdint>
  20165. # define ENTT_ID_TYPE std::uint32_t
  20166. #else
  20167. # include <cstdint> // provides coverage for types in the std namespace
  20168. #endif
  20169. #ifndef ENTT_SPARSE_PAGE
  20170. # define ENTT_SPARSE_PAGE 4096
  20171. #endif
  20172. #ifndef ENTT_PACKED_PAGE
  20173. # define ENTT_PACKED_PAGE 1024
  20174. #endif
  20175. #ifdef ENTT_DISABLE_ASSERT
  20176. # undef ENTT_ASSERT
  20177. # define ENTT_ASSERT(condition, msg) (void(0))
  20178. #elif !defined ENTT_ASSERT
  20179. # include <cassert>
  20180. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  20181. #endif
  20182. #ifdef ENTT_DISABLE_ASSERT
  20183. # undef ENTT_ASSERT_CONSTEXPR
  20184. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  20185. #elif !defined ENTT_ASSERT_CONSTEXPR
  20186. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  20187. #endif
  20188. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  20189. #ifdef ENTT_NO_ETO
  20190. # define ENTT_ETO_TYPE(Type) void
  20191. #else
  20192. # define ENTT_ETO_TYPE(Type) Type
  20193. #endif
  20194. #ifdef ENTT_NO_MIXIN
  20195. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  20196. #else
  20197. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  20198. #endif
  20199. #ifdef ENTT_STANDARD_CPP
  20200. # define ENTT_NONSTD false
  20201. #else
  20202. # define ENTT_NONSTD true
  20203. # if defined __clang__ || defined __GNUC__
  20204. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  20205. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  20206. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  20207. # elif defined _MSC_VER
  20208. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  20209. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  20210. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  20211. # endif
  20212. #endif
  20213. #ifndef ENTT_EXPORT
  20214. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  20215. # define ENTT_EXPORT __declspec(dllexport)
  20216. # define ENTT_IMPORT __declspec(dllimport)
  20217. # define ENTT_HIDDEN
  20218. # elif defined __GNUC__ && __GNUC__ >= 4
  20219. # define ENTT_EXPORT __attribute__((visibility("default")))
  20220. # define ENTT_IMPORT __attribute__((visibility("default")))
  20221. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  20222. # else /* Unsupported compiler */
  20223. # define ENTT_EXPORT
  20224. # define ENTT_IMPORT
  20225. # define ENTT_HIDDEN
  20226. # endif
  20227. #endif
  20228. #ifndef ENTT_API
  20229. # if defined ENTT_API_EXPORT
  20230. # define ENTT_API ENTT_EXPORT
  20231. # elif defined ENTT_API_IMPORT
  20232. # define ENTT_API ENTT_IMPORT
  20233. # else /* No API */
  20234. # define ENTT_API
  20235. # endif
  20236. #endif
  20237. #if defined _MSC_VER
  20238. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  20239. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  20240. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  20241. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  20242. #endif
  20243. // NOLINTEND(cppcoreguidelines-macro-usage)
  20244. #endif
  20245. // #include "../core/type_traits.hpp"
  20246. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  20247. #define ENTT_CORE_TYPE_TRAITS_HPP
  20248. #include <cstddef>
  20249. #include <iterator>
  20250. #include <tuple>
  20251. #include <type_traits>
  20252. #include <utility>
  20253. // #include "../config/config.h"
  20254. #ifndef ENTT_CONFIG_CONFIG_H
  20255. #define ENTT_CONFIG_CONFIG_H
  20256. // #include "version.h"
  20257. #ifndef ENTT_CONFIG_VERSION_H
  20258. #define ENTT_CONFIG_VERSION_H
  20259. // #include "macro.h"
  20260. #ifndef ENTT_CONFIG_MACRO_H
  20261. #define ENTT_CONFIG_MACRO_H
  20262. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  20263. #define ENTT_STR(arg) #arg
  20264. #define ENTT_XSTR(arg) ENTT_STR(arg)
  20265. // NOLINTEND(cppcoreguidelines-macro-usage)
  20266. #endif
  20267. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  20268. #define ENTT_VERSION_MAJOR 3
  20269. #define ENTT_VERSION_MINOR 16
  20270. #define ENTT_VERSION_PATCH 0
  20271. #define ENTT_VERSION \
  20272. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  20273. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  20274. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  20275. #endif
  20276. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  20277. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  20278. # define ENTT_CONSTEXPR
  20279. # define ENTT_THROW throw
  20280. # define ENTT_TRY try
  20281. # define ENTT_CATCH catch(...)
  20282. #else
  20283. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  20284. # define ENTT_THROW
  20285. # define ENTT_TRY if(true)
  20286. # define ENTT_CATCH if(false)
  20287. #endif
  20288. #if __has_include(<version>)
  20289. # include <version>
  20290. #
  20291. # if defined(__cpp_consteval)
  20292. # define ENTT_CONSTEVAL consteval
  20293. # endif
  20294. #endif
  20295. #ifndef ENTT_CONSTEVAL
  20296. # define ENTT_CONSTEVAL constexpr
  20297. #endif
  20298. #ifdef ENTT_USE_ATOMIC
  20299. # include <atomic>
  20300. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  20301. #else
  20302. # define ENTT_MAYBE_ATOMIC(Type) Type
  20303. #endif
  20304. #ifndef ENTT_ID_TYPE
  20305. # include <cstdint>
  20306. # define ENTT_ID_TYPE std::uint32_t
  20307. #else
  20308. # include <cstdint> // provides coverage for types in the std namespace
  20309. #endif
  20310. #ifndef ENTT_SPARSE_PAGE
  20311. # define ENTT_SPARSE_PAGE 4096
  20312. #endif
  20313. #ifndef ENTT_PACKED_PAGE
  20314. # define ENTT_PACKED_PAGE 1024
  20315. #endif
  20316. #ifdef ENTT_DISABLE_ASSERT
  20317. # undef ENTT_ASSERT
  20318. # define ENTT_ASSERT(condition, msg) (void(0))
  20319. #elif !defined ENTT_ASSERT
  20320. # include <cassert>
  20321. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  20322. #endif
  20323. #ifdef ENTT_DISABLE_ASSERT
  20324. # undef ENTT_ASSERT_CONSTEXPR
  20325. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  20326. #elif !defined ENTT_ASSERT_CONSTEXPR
  20327. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  20328. #endif
  20329. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  20330. #ifdef ENTT_NO_ETO
  20331. # define ENTT_ETO_TYPE(Type) void
  20332. #else
  20333. # define ENTT_ETO_TYPE(Type) Type
  20334. #endif
  20335. #ifdef ENTT_NO_MIXIN
  20336. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  20337. #else
  20338. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  20339. #endif
  20340. #ifdef ENTT_STANDARD_CPP
  20341. # define ENTT_NONSTD false
  20342. #else
  20343. # define ENTT_NONSTD true
  20344. # if defined __clang__ || defined __GNUC__
  20345. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  20346. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  20347. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  20348. # elif defined _MSC_VER
  20349. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  20350. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  20351. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  20352. # endif
  20353. #endif
  20354. #ifndef ENTT_EXPORT
  20355. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  20356. # define ENTT_EXPORT __declspec(dllexport)
  20357. # define ENTT_IMPORT __declspec(dllimport)
  20358. # define ENTT_HIDDEN
  20359. # elif defined __GNUC__ && __GNUC__ >= 4
  20360. # define ENTT_EXPORT __attribute__((visibility("default")))
  20361. # define ENTT_IMPORT __attribute__((visibility("default")))
  20362. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  20363. # else /* Unsupported compiler */
  20364. # define ENTT_EXPORT
  20365. # define ENTT_IMPORT
  20366. # define ENTT_HIDDEN
  20367. # endif
  20368. #endif
  20369. #ifndef ENTT_API
  20370. # if defined ENTT_API_EXPORT
  20371. # define ENTT_API ENTT_EXPORT
  20372. # elif defined ENTT_API_IMPORT
  20373. # define ENTT_API ENTT_IMPORT
  20374. # else /* No API */
  20375. # define ENTT_API
  20376. # endif
  20377. #endif
  20378. #if defined _MSC_VER
  20379. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  20380. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  20381. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  20382. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  20383. #endif
  20384. // NOLINTEND(cppcoreguidelines-macro-usage)
  20385. #endif
  20386. // #include "fwd.hpp"
  20387. #ifndef ENTT_CORE_FWD_HPP
  20388. #define ENTT_CORE_FWD_HPP
  20389. #include <cstddef>
  20390. #include <cstdint>
  20391. // #include "../config/config.h"
  20392. namespace entt {
  20393. /*! @brief Possible modes of an any object. */
  20394. enum class any_policy : std::uint8_t {
  20395. /*! @brief Default mode, no element available. */
  20396. empty,
  20397. /*! @brief Owning mode, dynamically allocated element. */
  20398. dynamic,
  20399. /*! @brief Owning mode, embedded element. */
  20400. embedded,
  20401. /*! @brief Aliasing mode, non-const reference. */
  20402. ref,
  20403. /*! @brief Const aliasing mode, const reference. */
  20404. cref
  20405. };
  20406. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  20407. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  20408. class basic_any;
  20409. /*! @brief Alias declaration for type identifiers. */
  20410. using id_type = ENTT_ID_TYPE;
  20411. /*! @brief Alias declaration for the most common use case. */
  20412. using any = basic_any<>;
  20413. template<typename, typename>
  20414. class compressed_pair;
  20415. template<typename>
  20416. class basic_hashed_string;
  20417. /*! @brief Aliases for common character types. */
  20418. using hashed_string = basic_hashed_string<char>;
  20419. /*! @brief Aliases for common character types. */
  20420. using hashed_wstring = basic_hashed_string<wchar_t>;
  20421. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  20422. struct type_info;
  20423. } // namespace entt
  20424. #endif
  20425. namespace entt {
  20426. /**
  20427. * @brief Utility class to disambiguate overloaded functions.
  20428. * @tparam N Number of choices available.
  20429. */
  20430. template<std::size_t N>
  20431. struct choice_t
  20432. // unfortunately, doxygen cannot parse such a construct
  20433. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  20434. {};
  20435. /*! @copybrief choice_t */
  20436. template<>
  20437. struct choice_t<0> {};
  20438. /**
  20439. * @brief Variable template for the choice trick.
  20440. * @tparam N Number of choices available.
  20441. */
  20442. template<std::size_t N>
  20443. inline constexpr choice_t<N> choice{};
  20444. /**
  20445. * @brief Identity type trait.
  20446. *
  20447. * Useful to establish non-deduced contexts in template argument deduction
  20448. * (waiting for C++20) or to provide types through function arguments.
  20449. *
  20450. * @tparam Type A type.
  20451. */
  20452. template<typename Type>
  20453. struct type_identity {
  20454. /*! @brief Identity type. */
  20455. using type = Type;
  20456. };
  20457. /**
  20458. * @brief Helper type.
  20459. * @tparam Type A type.
  20460. */
  20461. template<typename Type>
  20462. using type_identity_t = typename type_identity<Type>::type;
  20463. /**
  20464. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  20465. * @tparam Type The type of which to return the size.
  20466. */
  20467. template<typename Type, typename = void>
  20468. struct size_of: std::integral_constant<std::size_t, 0u> {};
  20469. /*! @copydoc size_of */
  20470. template<typename Type>
  20471. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  20472. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  20473. : std::integral_constant<std::size_t, sizeof(Type)> {};
  20474. /**
  20475. * @brief Helper variable template.
  20476. * @tparam Type The type of which to return the size.
  20477. */
  20478. template<typename Type>
  20479. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  20480. /**
  20481. * @brief Using declaration to be used to _repeat_ the same type a number of
  20482. * times equal to the size of a given parameter pack.
  20483. * @tparam Type A type to repeat.
  20484. */
  20485. template<typename Type, typename>
  20486. using unpack_as_type = Type;
  20487. /**
  20488. * @brief Helper variable template to be used to _repeat_ the same value a
  20489. * number of times equal to the size of a given parameter pack.
  20490. * @tparam Value A value to repeat.
  20491. */
  20492. template<auto Value, typename>
  20493. inline constexpr auto unpack_as_value = Value;
  20494. /**
  20495. * @brief Wraps a static constant.
  20496. * @tparam Value A static constant.
  20497. */
  20498. template<auto Value>
  20499. using integral_constant = std::integral_constant<decltype(Value), Value>;
  20500. /**
  20501. * @brief Alias template to facilitate the creation of named values.
  20502. * @tparam Value A constant value at least convertible to `id_type`.
  20503. */
  20504. template<id_type Value>
  20505. using tag = integral_constant<Value>;
  20506. /**
  20507. * @brief A class to use to push around lists of types, nothing more.
  20508. * @tparam Type Types provided by the type list.
  20509. */
  20510. template<typename... Type>
  20511. struct type_list {
  20512. /*! @brief Type list type. */
  20513. using type = type_list;
  20514. /*! @brief Compile-time number of elements in the type list. */
  20515. static constexpr auto size = sizeof...(Type);
  20516. };
  20517. /*! @brief Primary template isn't defined on purpose. */
  20518. template<std::size_t, typename>
  20519. struct type_list_element;
  20520. /**
  20521. * @brief Provides compile-time indexed access to the types of a type list.
  20522. * @tparam Index Index of the type to return.
  20523. * @tparam First First type provided by the type list.
  20524. * @tparam Other Other types provided by the type list.
  20525. */
  20526. template<std::size_t Index, typename First, typename... Other>
  20527. struct type_list_element<Index, type_list<First, Other...>>
  20528. : type_list_element<Index - 1u, type_list<Other...>> {};
  20529. /**
  20530. * @brief Provides compile-time indexed access to the types of a type list.
  20531. * @tparam First First type provided by the type list.
  20532. * @tparam Other Other types provided by the type list.
  20533. */
  20534. template<typename First, typename... Other>
  20535. struct type_list_element<0u, type_list<First, Other...>> {
  20536. /*! @brief Searched type. */
  20537. using type = First;
  20538. };
  20539. /**
  20540. * @brief Helper type.
  20541. * @tparam Index Index of the type to return.
  20542. * @tparam List Type list to search into.
  20543. */
  20544. template<std::size_t Index, typename List>
  20545. using type_list_element_t = typename type_list_element<Index, List>::type;
  20546. /*! @brief Primary template isn't defined on purpose. */
  20547. template<typename, typename>
  20548. struct type_list_index;
  20549. /**
  20550. * @brief Provides compile-time type access to the types of a type list.
  20551. * @tparam Type Type to look for and for which to return the index.
  20552. * @tparam First First type provided by the type list.
  20553. * @tparam Other Other types provided by the type list.
  20554. */
  20555. template<typename Type, typename First, typename... Other>
  20556. struct type_list_index<Type, type_list<First, Other...>> {
  20557. /*! @brief Unsigned integer type. */
  20558. using value_type = std::size_t;
  20559. /*! @brief Compile-time position of the given type in the sublist. */
  20560. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  20561. };
  20562. /**
  20563. * @brief Provides compile-time type access to the types of a type list.
  20564. * @tparam Type Type to look for and for which to return the index.
  20565. * @tparam Other Other types provided by the type list.
  20566. */
  20567. template<typename Type, typename... Other>
  20568. struct type_list_index<Type, type_list<Type, Other...>> {
  20569. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  20570. /*! @brief Unsigned integer type. */
  20571. using value_type = std::size_t;
  20572. /*! @brief Compile-time position of the given type in the sublist. */
  20573. static constexpr value_type value = 0u;
  20574. };
  20575. /**
  20576. * @brief Provides compile-time type access to the types of a type list.
  20577. * @tparam Type Type to look for and for which to return the index.
  20578. */
  20579. template<typename Type>
  20580. struct type_list_index<Type, type_list<>> {
  20581. /*! @brief Unsigned integer type. */
  20582. using value_type = std::size_t;
  20583. /*! @brief Compile-time position of the given type in the sublist. */
  20584. static constexpr value_type value = 0u;
  20585. };
  20586. /**
  20587. * @brief Helper variable template.
  20588. * @tparam List Type list.
  20589. * @tparam Type Type to look for and for which to return the index.
  20590. */
  20591. template<typename Type, typename List>
  20592. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  20593. /**
  20594. * @brief Concatenates multiple type lists.
  20595. * @tparam Type Types provided by the first type list.
  20596. * @tparam Other Types provided by the second type list.
  20597. * @return A type list composed by the types of both the type lists.
  20598. */
  20599. template<typename... Type, typename... Other>
  20600. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  20601. return {};
  20602. }
  20603. /*! @brief Primary template isn't defined on purpose. */
  20604. template<typename...>
  20605. struct type_list_cat;
  20606. /*! @brief Concatenates multiple type lists. */
  20607. template<>
  20608. struct type_list_cat<> {
  20609. /*! @brief A type list composed by the types of all the type lists. */
  20610. using type = type_list<>;
  20611. };
  20612. /**
  20613. * @brief Concatenates multiple type lists.
  20614. * @tparam Type Types provided by the first type list.
  20615. * @tparam Other Types provided by the second type list.
  20616. * @tparam List Other type lists, if any.
  20617. */
  20618. template<typename... Type, typename... Other, typename... List>
  20619. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  20620. /*! @brief A type list composed by the types of all the type lists. */
  20621. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  20622. };
  20623. /**
  20624. * @brief Concatenates multiple type lists.
  20625. * @tparam Type Types provided by the type list.
  20626. */
  20627. template<typename... Type>
  20628. struct type_list_cat<type_list<Type...>> {
  20629. /*! @brief A type list composed by the types of all the type lists. */
  20630. using type = type_list<Type...>;
  20631. };
  20632. /**
  20633. * @brief Helper type.
  20634. * @tparam List Type lists to concatenate.
  20635. */
  20636. template<typename... List>
  20637. using type_list_cat_t = typename type_list_cat<List...>::type;
  20638. /*! @cond TURN_OFF_DOXYGEN */
  20639. namespace internal {
  20640. template<typename...>
  20641. struct type_list_unique;
  20642. template<typename First, typename... Other, typename... Type>
  20643. struct type_list_unique<type_list<First, Other...>, Type...>
  20644. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  20645. template<typename... Type>
  20646. struct type_list_unique<type_list<>, Type...> {
  20647. using type = type_list<Type...>;
  20648. };
  20649. } // namespace internal
  20650. /*! @endcond */
  20651. /**
  20652. * @brief Removes duplicates types from a type list.
  20653. * @tparam List Type list.
  20654. */
  20655. template<typename List>
  20656. struct type_list_unique {
  20657. /*! @brief A type list without duplicate types. */
  20658. using type = typename internal::type_list_unique<List>::type;
  20659. };
  20660. /**
  20661. * @brief Helper type.
  20662. * @tparam List Type list.
  20663. */
  20664. template<typename List>
  20665. using type_list_unique_t = typename type_list_unique<List>::type;
  20666. /**
  20667. * @brief Provides the member constant `value` to true if a type list contains a
  20668. * given type, false otherwise.
  20669. * @tparam List Type list.
  20670. * @tparam Type Type to look for.
  20671. */
  20672. template<typename List, typename Type>
  20673. struct type_list_contains;
  20674. /**
  20675. * @copybrief type_list_contains
  20676. * @tparam Type Types provided by the type list.
  20677. * @tparam Other Type to look for.
  20678. */
  20679. template<typename... Type, typename Other>
  20680. struct type_list_contains<type_list<Type...>, Other>
  20681. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  20682. /**
  20683. * @brief Helper variable template.
  20684. * @tparam List Type list.
  20685. * @tparam Type Type to look for.
  20686. */
  20687. template<typename List, typename Type>
  20688. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  20689. /*! @brief Primary template isn't defined on purpose. */
  20690. template<typename...>
  20691. struct type_list_diff;
  20692. /**
  20693. * @brief Computes the difference between two type lists.
  20694. * @tparam Type Types provided by the first type list.
  20695. * @tparam Other Types provided by the second type list.
  20696. */
  20697. template<typename... Type, typename... Other>
  20698. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  20699. /*! @brief A type list that is the difference between the two type lists. */
  20700. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  20701. };
  20702. /**
  20703. * @brief Helper type.
  20704. * @tparam List Type lists between which to compute the difference.
  20705. */
  20706. template<typename... List>
  20707. using type_list_diff_t = typename type_list_diff<List...>::type;
  20708. /*! @brief Primary template isn't defined on purpose. */
  20709. template<typename, template<typename...> class>
  20710. struct type_list_transform;
  20711. /**
  20712. * @brief Applies a given _function_ to a type list and generate a new list.
  20713. * @tparam Type Types provided by the type list.
  20714. * @tparam Op Unary operation as template class with a type member named `type`.
  20715. */
  20716. template<typename... Type, template<typename...> class Op>
  20717. struct type_list_transform<type_list<Type...>, Op> {
  20718. /*! @brief Resulting type list after applying the transform function. */
  20719. // NOLINTNEXTLINE(modernize-type-traits)
  20720. using type = type_list<typename Op<Type>::type...>;
  20721. };
  20722. /**
  20723. * @brief Helper type.
  20724. * @tparam List Type list.
  20725. * @tparam Op Unary operation as template class with a type member named `type`.
  20726. */
  20727. template<typename List, template<typename...> class Op>
  20728. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  20729. /**
  20730. * @brief A class to use to push around lists of constant values, nothing more.
  20731. * @tparam Value Values provided by the value list.
  20732. */
  20733. template<auto... Value>
  20734. struct value_list {
  20735. /*! @brief Value list type. */
  20736. using type = value_list;
  20737. /*! @brief Compile-time number of elements in the value list. */
  20738. static constexpr auto size = sizeof...(Value);
  20739. };
  20740. /*! @brief Primary template isn't defined on purpose. */
  20741. template<std::size_t, typename>
  20742. struct value_list_element;
  20743. /**
  20744. * @brief Provides compile-time indexed access to the values of a value list.
  20745. * @tparam Index Index of the value to return.
  20746. * @tparam Value First value provided by the value list.
  20747. * @tparam Other Other values provided by the value list.
  20748. */
  20749. template<std::size_t Index, auto Value, auto... Other>
  20750. struct value_list_element<Index, value_list<Value, Other...>>
  20751. : value_list_element<Index - 1u, value_list<Other...>> {};
  20752. /**
  20753. * @brief Provides compile-time indexed access to the types of a type list.
  20754. * @tparam Value First value provided by the value list.
  20755. * @tparam Other Other values provided by the value list.
  20756. */
  20757. template<auto Value, auto... Other>
  20758. struct value_list_element<0u, value_list<Value, Other...>> {
  20759. /*! @brief Searched type. */
  20760. using type = decltype(Value);
  20761. /*! @brief Searched value. */
  20762. static constexpr auto value = Value;
  20763. };
  20764. /**
  20765. * @brief Helper type.
  20766. * @tparam Index Index of the type to return.
  20767. * @tparam List Value list to search into.
  20768. */
  20769. template<std::size_t Index, typename List>
  20770. using value_list_element_t = typename value_list_element<Index, List>::type;
  20771. /**
  20772. * @brief Helper type.
  20773. * @tparam Index Index of the value to return.
  20774. * @tparam List Value list to search into.
  20775. */
  20776. template<std::size_t Index, typename List>
  20777. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  20778. /*! @brief Primary template isn't defined on purpose. */
  20779. template<auto, typename>
  20780. struct value_list_index;
  20781. /**
  20782. * @brief Provides compile-time type access to the values of a value list.
  20783. * @tparam Value Value to look for and for which to return the index.
  20784. * @tparam First First value provided by the value list.
  20785. * @tparam Other Other values provided by the value list.
  20786. */
  20787. template<auto Value, auto First, auto... Other>
  20788. struct value_list_index<Value, value_list<First, Other...>> {
  20789. /*! @brief Unsigned integer type. */
  20790. using value_type = std::size_t;
  20791. /*! @brief Compile-time position of the given value in the sublist. */
  20792. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  20793. };
  20794. /**
  20795. * @brief Provides compile-time type access to the values of a value list.
  20796. * @tparam Value Value to look for and for which to return the index.
  20797. * @tparam Other Other values provided by the value list.
  20798. */
  20799. template<auto Value, auto... Other>
  20800. struct value_list_index<Value, value_list<Value, Other...>> {
  20801. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  20802. /*! @brief Unsigned integer type. */
  20803. using value_type = std::size_t;
  20804. /*! @brief Compile-time position of the given value in the sublist. */
  20805. static constexpr value_type value = 0u;
  20806. };
  20807. /**
  20808. * @brief Provides compile-time type access to the values of a value list.
  20809. * @tparam Value Value to look for and for which to return the index.
  20810. */
  20811. template<auto Value>
  20812. struct value_list_index<Value, value_list<>> {
  20813. /*! @brief Unsigned integer type. */
  20814. using value_type = std::size_t;
  20815. /*! @brief Compile-time position of the given type in the sublist. */
  20816. static constexpr value_type value = 0u;
  20817. };
  20818. /**
  20819. * @brief Helper variable template.
  20820. * @tparam List Value list.
  20821. * @tparam Value Value to look for and for which to return the index.
  20822. */
  20823. template<auto Value, typename List>
  20824. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  20825. /**
  20826. * @brief Concatenates multiple value lists.
  20827. * @tparam Value Values provided by the first value list.
  20828. * @tparam Other Values provided by the second value list.
  20829. * @return A value list composed by the values of both the value lists.
  20830. */
  20831. template<auto... Value, auto... Other>
  20832. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  20833. return {};
  20834. }
  20835. /*! @brief Primary template isn't defined on purpose. */
  20836. template<typename...>
  20837. struct value_list_cat;
  20838. /*! @brief Concatenates multiple value lists. */
  20839. template<>
  20840. struct value_list_cat<> {
  20841. /*! @brief A value list composed by the values of all the value lists. */
  20842. using type = value_list<>;
  20843. };
  20844. /**
  20845. * @brief Concatenates multiple value lists.
  20846. * @tparam Value Values provided by the first value list.
  20847. * @tparam Other Values provided by the second value list.
  20848. * @tparam List Other value lists, if any.
  20849. */
  20850. template<auto... Value, auto... Other, typename... List>
  20851. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  20852. /*! @brief A value list composed by the values of all the value lists. */
  20853. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  20854. };
  20855. /**
  20856. * @brief Concatenates multiple value lists.
  20857. * @tparam Value Values provided by the value list.
  20858. */
  20859. template<auto... Value>
  20860. struct value_list_cat<value_list<Value...>> {
  20861. /*! @brief A value list composed by the values of all the value lists. */
  20862. using type = value_list<Value...>;
  20863. };
  20864. /**
  20865. * @brief Helper type.
  20866. * @tparam List Value lists to concatenate.
  20867. */
  20868. template<typename... List>
  20869. using value_list_cat_t = typename value_list_cat<List...>::type;
  20870. /*! @brief Primary template isn't defined on purpose. */
  20871. template<typename>
  20872. struct value_list_unique;
  20873. /**
  20874. * @brief Removes duplicates values from a value list.
  20875. * @tparam Value One of the values provided by the given value list.
  20876. * @tparam Other The other values provided by the given value list.
  20877. */
  20878. template<auto Value, auto... Other>
  20879. struct value_list_unique<value_list<Value, Other...>> {
  20880. /*! @brief A value list without duplicate types. */
  20881. using type = std::conditional_t<
  20882. ((Value == Other) || ...),
  20883. typename value_list_unique<value_list<Other...>>::type,
  20884. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  20885. };
  20886. /*! @brief Removes duplicates values from a value list. */
  20887. template<>
  20888. struct value_list_unique<value_list<>> {
  20889. /*! @brief A value list without duplicate types. */
  20890. using type = value_list<>;
  20891. };
  20892. /**
  20893. * @brief Helper type.
  20894. * @tparam Type A value list.
  20895. */
  20896. template<typename Type>
  20897. using value_list_unique_t = typename value_list_unique<Type>::type;
  20898. /**
  20899. * @brief Provides the member constant `value` to true if a value list contains
  20900. * a given value, false otherwise.
  20901. * @tparam List Value list.
  20902. * @tparam Value Value to look for.
  20903. */
  20904. template<typename List, auto Value>
  20905. struct value_list_contains;
  20906. /**
  20907. * @copybrief value_list_contains
  20908. * @tparam Value Values provided by the value list.
  20909. * @tparam Other Value to look for.
  20910. */
  20911. template<auto... Value, auto Other>
  20912. struct value_list_contains<value_list<Value...>, Other>
  20913. : std::bool_constant<((Value == Other) || ...)> {};
  20914. /**
  20915. * @brief Helper variable template.
  20916. * @tparam List Value list.
  20917. * @tparam Value Value to look for.
  20918. */
  20919. template<typename List, auto Value>
  20920. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  20921. /*! @brief Primary template isn't defined on purpose. */
  20922. template<typename...>
  20923. struct value_list_diff;
  20924. /**
  20925. * @brief Computes the difference between two value lists.
  20926. * @tparam Value Values provided by the first value list.
  20927. * @tparam Other Values provided by the second value list.
  20928. */
  20929. template<auto... Value, auto... Other>
  20930. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  20931. /*! @brief A value list that is the difference between the two value lists. */
  20932. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  20933. };
  20934. /**
  20935. * @brief Helper type.
  20936. * @tparam List Value lists between which to compute the difference.
  20937. */
  20938. template<typename... List>
  20939. using value_list_diff_t = typename value_list_diff<List...>::type;
  20940. /*! @brief Same as std::is_invocable, but with tuples. */
  20941. template<typename, typename>
  20942. struct is_applicable: std::false_type {};
  20943. /**
  20944. * @copybrief is_applicable
  20945. * @tparam Func A valid function type.
  20946. * @tparam Tuple Tuple-like type.
  20947. * @tparam Args The list of arguments to use to probe the function type.
  20948. */
  20949. template<typename Func, template<typename...> class Tuple, typename... Args>
  20950. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  20951. /**
  20952. * @copybrief is_applicable
  20953. * @tparam Func A valid function type.
  20954. * @tparam Tuple Tuple-like type.
  20955. * @tparam Args The list of arguments to use to probe the function type.
  20956. */
  20957. template<typename Func, template<typename...> class Tuple, typename... Args>
  20958. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  20959. /**
  20960. * @brief Helper variable template.
  20961. * @tparam Func A valid function type.
  20962. * @tparam Args The list of arguments to use to probe the function type.
  20963. */
  20964. template<typename Func, typename Args>
  20965. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  20966. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  20967. template<typename, typename, typename>
  20968. struct is_applicable_r: std::false_type {};
  20969. /**
  20970. * @copybrief is_applicable_r
  20971. * @tparam Ret The type to which the return type of the function should be
  20972. * convertible.
  20973. * @tparam Func A valid function type.
  20974. * @tparam Args The list of arguments to use to probe the function type.
  20975. */
  20976. template<typename Ret, typename Func, typename... Args>
  20977. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  20978. /**
  20979. * @brief Helper variable template.
  20980. * @tparam Ret The type to which the return type of the function should be
  20981. * convertible.
  20982. * @tparam Func A valid function type.
  20983. * @tparam Args The list of arguments to use to probe the function type.
  20984. */
  20985. template<typename Ret, typename Func, typename Args>
  20986. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  20987. /**
  20988. * @brief Provides the member constant `value` to true if a given type is
  20989. * complete, false otherwise.
  20990. * @tparam Type The type to test.
  20991. */
  20992. template<typename Type, typename = void>
  20993. struct is_complete: std::false_type {};
  20994. /*! @copydoc is_complete */
  20995. template<typename Type>
  20996. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  20997. /**
  20998. * @brief Helper variable template.
  20999. * @tparam Type The type to test.
  21000. */
  21001. template<typename Type>
  21002. inline constexpr bool is_complete_v = is_complete<Type>::value;
  21003. /**
  21004. * @brief Provides the member constant `value` to true if a given type is an
  21005. * iterator, false otherwise.
  21006. * @tparam Type The type to test.
  21007. */
  21008. template<typename Type, typename = void>
  21009. struct is_iterator: std::false_type {};
  21010. /*! @cond TURN_OFF_DOXYGEN */
  21011. namespace internal {
  21012. template<typename, typename = void>
  21013. struct has_iterator_category: std::false_type {};
  21014. template<typename Type>
  21015. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  21016. } // namespace internal
  21017. /*! @endcond */
  21018. /*! @copydoc is_iterator */
  21019. template<typename Type>
  21020. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  21021. : internal::has_iterator_category<Type> {};
  21022. /**
  21023. * @brief Helper variable template.
  21024. * @tparam Type The type to test.
  21025. */
  21026. template<typename Type>
  21027. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  21028. /**
  21029. * @brief Provides the member constant `value` to true if a given type is both
  21030. * an empty and non-final class, false otherwise.
  21031. * @tparam Type The type to test
  21032. */
  21033. template<typename Type>
  21034. struct is_ebco_eligible
  21035. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  21036. /**
  21037. * @brief Helper variable template.
  21038. * @tparam Type The type to test.
  21039. */
  21040. template<typename Type>
  21041. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  21042. /**
  21043. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  21044. * is valid and denotes a type, false otherwise.
  21045. * @tparam Type The type to test.
  21046. */
  21047. template<typename Type, typename = void>
  21048. struct is_transparent: std::false_type {};
  21049. /*! @copydoc is_transparent */
  21050. template<typename Type>
  21051. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  21052. /**
  21053. * @brief Helper variable template.
  21054. * @tparam Type The type to test.
  21055. */
  21056. template<typename Type>
  21057. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  21058. /*! @cond TURN_OFF_DOXYGEN */
  21059. namespace internal {
  21060. template<typename, typename = void>
  21061. struct has_tuple_size_value: std::false_type {};
  21062. template<typename Type>
  21063. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  21064. template<typename, typename = void>
  21065. struct has_value_type: std::false_type {};
  21066. template<typename Type>
  21067. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  21068. template<typename>
  21069. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  21070. template<typename Type, std::size_t... Index>
  21071. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  21072. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  21073. }
  21074. template<typename>
  21075. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  21076. return false;
  21077. }
  21078. template<typename Type>
  21079. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  21080. return true;
  21081. }
  21082. template<typename Type>
  21083. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  21084. // NOLINTBEGIN(modernize-use-transparent-functors)
  21085. if constexpr(std::is_array_v<Type>) {
  21086. return false;
  21087. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  21088. if constexpr(has_tuple_size_value<Type>::value) {
  21089. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  21090. } else {
  21091. return maybe_equality_comparable<Type>(0);
  21092. }
  21093. } else if constexpr(has_value_type<Type>::value) {
  21094. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  21095. return maybe_equality_comparable<Type>(0);
  21096. } else {
  21097. return false;
  21098. }
  21099. } else {
  21100. return maybe_equality_comparable<Type>(0);
  21101. }
  21102. // NOLINTEND(modernize-use-transparent-functors)
  21103. }
  21104. } // namespace internal
  21105. /*! @endcond */
  21106. /**
  21107. * @brief Provides the member constant `value` to true if a given type is
  21108. * equality comparable, false otherwise.
  21109. * @tparam Type The type to test.
  21110. */
  21111. template<typename Type>
  21112. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  21113. /*! @copydoc is_equality_comparable */
  21114. template<typename Type>
  21115. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  21116. /**
  21117. * @brief Helper variable template.
  21118. * @tparam Type The type to test.
  21119. */
  21120. template<typename Type>
  21121. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  21122. /**
  21123. * @brief Transcribes the constness of a type to another type.
  21124. * @tparam To The type to which to transcribe the constness.
  21125. * @tparam From The type from which to transcribe the constness.
  21126. */
  21127. template<typename To, typename From>
  21128. struct constness_as {
  21129. /*! @brief The type resulting from the transcription of the constness. */
  21130. using type = std::remove_const_t<To>;
  21131. };
  21132. /*! @copydoc constness_as */
  21133. template<typename To, typename From>
  21134. struct constness_as<To, const From> {
  21135. /*! @brief The type resulting from the transcription of the constness. */
  21136. using type = const To;
  21137. };
  21138. /**
  21139. * @brief Alias template to facilitate the transcription of the constness.
  21140. * @tparam To The type to which to transcribe the constness.
  21141. * @tparam From The type from which to transcribe the constness.
  21142. */
  21143. template<typename To, typename From>
  21144. using constness_as_t = typename constness_as<To, From>::type;
  21145. /**
  21146. * @brief Extracts the class of a non-static member object or function.
  21147. * @tparam Member A pointer to a non-static member object or function.
  21148. */
  21149. template<typename Member>
  21150. class member_class {
  21151. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  21152. template<typename Class, typename Ret, typename... Args>
  21153. static Class *clazz(Ret (Class::*)(Args...));
  21154. template<typename Class, typename Ret, typename... Args>
  21155. static Class *clazz(Ret (Class::*)(Args...) const);
  21156. template<typename Class, typename Type>
  21157. static Class *clazz(Type Class::*);
  21158. public:
  21159. /*! @brief The class of the given non-static member object or function. */
  21160. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  21161. };
  21162. /**
  21163. * @brief Helper type.
  21164. * @tparam Member A pointer to a non-static member object or function.
  21165. */
  21166. template<typename Member>
  21167. using member_class_t = typename member_class<Member>::type;
  21168. /**
  21169. * @brief Extracts the n-th argument of a _callable_ type.
  21170. * @tparam Index The index of the argument to extract.
  21171. * @tparam Candidate A valid _callable_ type.
  21172. */
  21173. template<std::size_t Index, typename Candidate>
  21174. class nth_argument {
  21175. template<typename Ret, typename... Args>
  21176. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  21177. template<typename Ret, typename Class, typename... Args>
  21178. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  21179. template<typename Ret, typename Class, typename... Args>
  21180. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  21181. template<typename Type, typename Class>
  21182. static constexpr type_list<Type> pick_up(Type Class ::*);
  21183. template<typename Type>
  21184. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  21185. public:
  21186. /*! @brief N-th argument of the _callable_ type. */
  21187. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  21188. };
  21189. /**
  21190. * @brief Helper type.
  21191. * @tparam Index The index of the argument to extract.
  21192. * @tparam Candidate A valid function, member function or data member type.
  21193. */
  21194. template<std::size_t Index, typename Candidate>
  21195. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  21196. } // namespace entt
  21197. template<typename... Type>
  21198. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  21199. template<std::size_t Index, typename... Type>
  21200. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  21201. template<auto... Value>
  21202. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  21203. template<std::size_t Index, auto... Value>
  21204. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  21205. #endif
  21206. // #include "fwd.hpp"
  21207. #ifndef ENTT_SIGNAL_FWD_HPP
  21208. #define ENTT_SIGNAL_FWD_HPP
  21209. #include <memory>
  21210. namespace entt {
  21211. template<typename>
  21212. class delegate;
  21213. template<typename = std::allocator<void>>
  21214. class basic_dispatcher;
  21215. template<typename, typename = std::allocator<void>>
  21216. class emitter;
  21217. class connection;
  21218. struct scoped_connection;
  21219. template<typename>
  21220. class sink;
  21221. template<typename Type, typename = std::allocator<void>>
  21222. class sigh;
  21223. /*! @brief Alias declaration for the most common use case. */
  21224. using dispatcher = basic_dispatcher<>;
  21225. /*! @brief Disambiguation tag for constructors and the like. */
  21226. template<auto>
  21227. struct connect_arg_t {
  21228. /*! @brief Default constructor. */
  21229. explicit connect_arg_t() = default;
  21230. };
  21231. /**
  21232. * @brief Constant of type connect_arg_t used to disambiguate calls.
  21233. * @tparam Candidate Element to connect (likely a free or member function).
  21234. */
  21235. template<auto Candidate>
  21236. inline constexpr connect_arg_t<Candidate> connect_arg{};
  21237. } // namespace entt
  21238. #endif
  21239. namespace entt {
  21240. /*! @cond TURN_OFF_DOXYGEN */
  21241. namespace internal {
  21242. template<typename Ret, typename... Args>
  21243. constexpr auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...);
  21244. template<typename Ret, typename Type, typename... Args, typename Other>
  21245. constexpr auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...);
  21246. template<typename Class, typename Ret, typename... Args, typename... Other>
  21247. constexpr auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...);
  21248. template<typename Class, typename Ret, typename... Args, typename... Other>
  21249. constexpr auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...);
  21250. template<typename Class, typename Type, typename... Other, typename = std::enable_if_t<std::is_member_object_pointer_v<Type Class::*>>>
  21251. constexpr auto function_pointer(Type Class::*, Other &&...) -> Type (*)();
  21252. template<typename... Type>
  21253. using function_pointer_t = decltype(function_pointer(std::declval<Type>()...));
  21254. template<typename... Class, typename Ret, typename... Args>
  21255. [[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) {
  21256. return std::index_sequence_for<Class..., Args...>{};
  21257. }
  21258. } // namespace internal
  21259. /*! @endcond */
  21260. /**
  21261. * @brief Basic delegate implementation.
  21262. *
  21263. * Primary template isn't defined on purpose. All the specializations give a
  21264. * compile-time error unless the template parameter is a function type.
  21265. */
  21266. template<typename>
  21267. class delegate;
  21268. /**
  21269. * @brief Utility class to use to send around functions and members.
  21270. *
  21271. * Unmanaged delegate for function pointers and members. Users of this class are
  21272. * in charge of disconnecting instances before deleting them.
  21273. *
  21274. * A delegate can be used as a general purpose invoker without memory overhead
  21275. * for free functions possibly with payloads and bound or unbound members.
  21276. *
  21277. * @tparam Ret Return type of a function type.
  21278. * @tparam Args Types of arguments of a function type.
  21279. */
  21280. template<typename Ret, typename... Args>
  21281. class delegate<Ret(Args...)> {
  21282. using return_type = std::remove_const_t<Ret>;
  21283. using delegate_type = return_type(const void *, Args...);
  21284. template<auto Candidate, std::size_t... Index>
  21285. [[nodiscard]] auto wrap(std::index_sequence<Index...>) noexcept {
  21286. return [](const void *, Args... args) -> return_type {
  21287. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  21288. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  21289. return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  21290. };
  21291. }
  21292. template<auto Candidate, typename Type, std::size_t... Index>
  21293. [[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) noexcept {
  21294. return [](const void *payload, Args... args) -> return_type {
  21295. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  21296. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  21297. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type &, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  21298. return static_cast<Ret>(std::invoke(Candidate, *curr, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  21299. };
  21300. }
  21301. template<auto Candidate, typename Type, std::size_t... Index>
  21302. [[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) noexcept {
  21303. return [](const void *payload, Args... args) -> return_type {
  21304. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  21305. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  21306. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type *, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  21307. return static_cast<Ret>(std::invoke(Candidate, curr, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  21308. };
  21309. }
  21310. public:
  21311. /*! @brief Function type of the contained target. */
  21312. using function_type = Ret(const void *, Args...);
  21313. /*! @brief Function type of the delegate. */
  21314. using type = Ret(Args...);
  21315. /*! @brief Return type of the delegate. */
  21316. using result_type = Ret;
  21317. /*! @brief Default constructor. */
  21318. delegate() noexcept = default;
  21319. /**
  21320. * @brief Constructs a delegate with a given object or payload, if any.
  21321. * @tparam Candidate Function or member to connect to the delegate.
  21322. * @tparam Type Type of class or type of payload, if any.
  21323. * @param value_or_instance Optional valid object that fits the purpose.
  21324. */
  21325. template<auto Candidate, typename... Type>
  21326. delegate(connect_arg_t<Candidate>, Type &&...value_or_instance) noexcept {
  21327. connect<Candidate>(std::forward<Type>(value_or_instance)...);
  21328. }
  21329. /**
  21330. * @brief Constructs a delegate and connects an user defined function with
  21331. * optional payload.
  21332. * @param function Function to connect to the delegate.
  21333. * @param payload User defined arbitrary data.
  21334. */
  21335. delegate(function_type *function, const void *payload = nullptr) noexcept {
  21336. connect(function, payload);
  21337. }
  21338. /**
  21339. * @brief Connects a free function or an unbound member to a delegate.
  21340. * @tparam Candidate Function or member to connect to the delegate.
  21341. */
  21342. template<auto Candidate>
  21343. void connect() noexcept {
  21344. instance = nullptr;
  21345. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  21346. fn = [](const void *, Args... args) -> return_type {
  21347. return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
  21348. };
  21349. } else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
  21350. fn = wrap<Candidate>(internal::index_sequence_for<type_list_element_t<0, type_list<Args...>>>(internal::function_pointer_t<decltype(Candidate)>{}));
  21351. } else {
  21352. fn = wrap<Candidate>(internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate)>{}));
  21353. }
  21354. }
  21355. /**
  21356. * @brief Connects a free function with payload or a bound member to a
  21357. * delegate.
  21358. *
  21359. * The delegate isn't responsible for the connected object or the payload.
  21360. * Users must always guarantee that the lifetime of the instance overcomes
  21361. * the one of the delegate.<br/>
  21362. * When used to connect a free function with payload, its signature must be
  21363. * such that the instance is the first argument before the ones used to
  21364. * define the delegate itself.
  21365. *
  21366. * @tparam Candidate Function or member to connect to the delegate.
  21367. * @tparam Type Type of class or type of payload.
  21368. * @param value_or_instance A valid reference that fits the purpose.
  21369. */
  21370. template<auto Candidate, typename Type>
  21371. void connect(Type &value_or_instance) noexcept {
  21372. instance = &value_or_instance;
  21373. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
  21374. fn = [](const void *payload, Args... args) -> return_type {
  21375. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  21376. return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
  21377. };
  21378. } else {
  21379. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  21380. }
  21381. }
  21382. /**
  21383. * @brief Connects a free function with payload or a bound member to a
  21384. * delegate.
  21385. *
  21386. * @sa connect(Type &)
  21387. *
  21388. * @tparam Candidate Function or member to connect to the delegate.
  21389. * @tparam Type Type of class or type of payload.
  21390. * @param value_or_instance A valid pointer that fits the purpose.
  21391. */
  21392. template<auto Candidate, typename Type>
  21393. void connect(Type *value_or_instance) noexcept {
  21394. instance = value_or_instance;
  21395. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
  21396. fn = [](const void *payload, Args... args) -> return_type {
  21397. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  21398. return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
  21399. };
  21400. } else {
  21401. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  21402. }
  21403. }
  21404. /**
  21405. * @brief Connects an user defined function with optional payload to a
  21406. * delegate.
  21407. *
  21408. * The delegate isn't responsible for the connected object or the payload.
  21409. * Users must always guarantee that the lifetime of an instance overcomes
  21410. * the one of the delegate.<br/>
  21411. * The payload is returned as the first argument to the target function in
  21412. * all cases.
  21413. *
  21414. * @param function Function to connect to the delegate.
  21415. * @param payload User defined arbitrary data.
  21416. */
  21417. void connect(function_type *function, const void *payload = nullptr) noexcept {
  21418. ENTT_ASSERT(function != nullptr, "Uninitialized function pointer");
  21419. instance = payload;
  21420. fn = function;
  21421. }
  21422. /**
  21423. * @brief Resets a delegate.
  21424. *
  21425. * After a reset, a delegate cannot be invoked anymore.
  21426. */
  21427. void reset() noexcept {
  21428. instance = nullptr;
  21429. fn = nullptr;
  21430. }
  21431. /**
  21432. * @brief Returns a pointer to the stored callable function target, if any.
  21433. * @return An opaque pointer to the stored callable function target.
  21434. */
  21435. [[nodiscard]] function_type *target() const noexcept {
  21436. return fn;
  21437. }
  21438. /**
  21439. * @brief Returns the instance or the payload linked to a delegate, if any.
  21440. * @return An opaque pointer to the underlying data.
  21441. */
  21442. [[nodiscard]] const void *data() const noexcept {
  21443. return instance;
  21444. }
  21445. /**
  21446. * @brief Triggers a delegate.
  21447. *
  21448. * The delegate invokes the underlying function and returns the result.
  21449. *
  21450. * @warning
  21451. * Attempting to trigger an invalid delegate results in undefined
  21452. * behavior.
  21453. *
  21454. * @param args Arguments to use to invoke the underlying function.
  21455. * @return The value returned by the underlying function.
  21456. */
  21457. Ret operator()(Args... args) const {
  21458. ENTT_ASSERT(static_cast<bool>(*this), "Uninitialized delegate");
  21459. return fn(instance, std::forward<Args>(args)...);
  21460. }
  21461. /**
  21462. * @brief Checks whether a delegate actually stores a listener.
  21463. * @return False if the delegate is empty, true otherwise.
  21464. */
  21465. [[nodiscard]] explicit operator bool() const noexcept {
  21466. // no need to also test instance
  21467. return !(fn == nullptr);
  21468. }
  21469. /**
  21470. * @brief Compares the contents of two delegates.
  21471. * @param other Delegate with which to compare.
  21472. * @return False if the two contents differ, true otherwise.
  21473. */
  21474. [[nodiscard]] bool operator==(const delegate<Ret(Args...)> &other) const noexcept {
  21475. return fn == other.fn && instance == other.instance;
  21476. }
  21477. private:
  21478. const void *instance{};
  21479. delegate_type *fn{};
  21480. };
  21481. /**
  21482. * @brief Compares the contents of two delegates.
  21483. * @tparam Ret Return type of a function type.
  21484. * @tparam Args Types of arguments of a function type.
  21485. * @param lhs A valid delegate object.
  21486. * @param rhs A valid delegate object.
  21487. * @return True if the two contents differ, false otherwise.
  21488. */
  21489. template<typename Ret, typename... Args>
  21490. [[nodiscard]] bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) noexcept {
  21491. return !(lhs == rhs);
  21492. }
  21493. /**
  21494. * @brief Deduction guide.
  21495. * @tparam Candidate Function or member to connect to the delegate.
  21496. */
  21497. template<auto Candidate>
  21498. delegate(connect_arg_t<Candidate>) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate)>>>;
  21499. /**
  21500. * @brief Deduction guide.
  21501. * @tparam Candidate Function or member to connect to the delegate.
  21502. * @tparam Type Type of class or type of payload.
  21503. */
  21504. template<auto Candidate, typename Type>
  21505. delegate(connect_arg_t<Candidate>, Type &&) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate), Type>>>;
  21506. /**
  21507. * @brief Deduction guide.
  21508. * @tparam Ret Return type of a function type.
  21509. * @tparam Args Types of arguments of a function type.
  21510. */
  21511. template<typename Ret, typename... Args>
  21512. delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate<Ret(Args...)>;
  21513. } // namespace entt
  21514. #endif
  21515. // #include "fwd.hpp"
  21516. namespace entt {
  21517. /**
  21518. * @brief Sink class.
  21519. *
  21520. * Primary template isn't defined on purpose. All the specializations give a
  21521. * compile-time error unless the template parameter is a function type.
  21522. *
  21523. * @tparam Type A valid signal handler type.
  21524. */
  21525. template<typename Type>
  21526. class sink;
  21527. /**
  21528. * @brief Unmanaged signal handler.
  21529. *
  21530. * Primary template isn't defined on purpose. All the specializations give a
  21531. * compile-time error unless the template parameter is a function type.
  21532. *
  21533. * @tparam Type A valid function type.
  21534. * @tparam Allocator Type of allocator used to manage memory and elements.
  21535. */
  21536. template<typename Type, typename Allocator>
  21537. class sigh;
  21538. /**
  21539. * @brief Unmanaged signal handler.
  21540. *
  21541. * It works directly with references to classes and pointers to member functions
  21542. * as well as pointers to free functions. Users of this class are in charge of
  21543. * disconnecting instances before deleting them.
  21544. *
  21545. * This class serves mainly two purposes:
  21546. *
  21547. * * Creating signals to use later to notify a bunch of listeners.
  21548. * * Collecting results from a set of functions like in a voting system.
  21549. *
  21550. * @tparam Ret Return type of a function type.
  21551. * @tparam Args Types of arguments of a function type.
  21552. * @tparam Allocator Type of allocator used to manage memory and elements.
  21553. */
  21554. template<typename Ret, typename... Args, typename Allocator>
  21555. class sigh<Ret(Args...), Allocator> {
  21556. friend class sink<sigh<Ret(Args...), Allocator>>;
  21557. using alloc_traits = std::allocator_traits<Allocator>;
  21558. using delegate_type = delegate<Ret(Args...)>;
  21559. using container_type = std::vector<delegate_type, typename alloc_traits::template rebind_alloc<delegate_type>>;
  21560. public:
  21561. /*! @brief Allocator type. */
  21562. using allocator_type = Allocator;
  21563. /*! @brief Unsigned integer type. */
  21564. using size_type = std::size_t;
  21565. /*! @brief Sink type. */
  21566. using sink_type = sink<sigh<Ret(Args...), Allocator>>;
  21567. /*! @brief Default constructor. */
  21568. sigh() noexcept(noexcept(allocator_type{}))
  21569. : sigh{allocator_type{}} {}
  21570. /**
  21571. * @brief Constructs a signal handler with a given allocator.
  21572. * @param allocator The allocator to use.
  21573. */
  21574. explicit sigh(const allocator_type &allocator) noexcept
  21575. : calls{allocator} {}
  21576. /**
  21577. * @brief Copy constructor.
  21578. * @param other The instance to copy from.
  21579. */
  21580. sigh(const sigh &other)
  21581. : calls{other.calls} {}
  21582. /**
  21583. * @brief Allocator-extended copy constructor.
  21584. * @param other The instance to copy from.
  21585. * @param allocator The allocator to use.
  21586. */
  21587. sigh(const sigh &other, const allocator_type &allocator)
  21588. : calls{other.calls, allocator} {}
  21589. /**
  21590. * @brief Move constructor.
  21591. * @param other The instance to move from.
  21592. */
  21593. sigh(sigh &&other) noexcept
  21594. : calls{std::move(other.calls)} {}
  21595. /**
  21596. * @brief Allocator-extended move constructor.
  21597. * @param other The instance to move from.
  21598. * @param allocator The allocator to use.
  21599. */
  21600. sigh(sigh &&other, const allocator_type &allocator)
  21601. : calls{std::move(other.calls), allocator} {}
  21602. /*! @brief Default destructor. */
  21603. ~sigh() = default;
  21604. /**
  21605. * @brief Copy assignment operator.
  21606. * @param other The instance to copy from.
  21607. * @return This signal handler.
  21608. */
  21609. sigh &operator=(const sigh &other) {
  21610. calls = other.calls;
  21611. return *this;
  21612. }
  21613. /**
  21614. * @brief Move assignment operator.
  21615. * @param other The instance to move from.
  21616. * @return This signal handler.
  21617. */
  21618. sigh &operator=(sigh &&other) noexcept {
  21619. swap(other);
  21620. return *this;
  21621. }
  21622. /**
  21623. * @brief Exchanges the contents with those of a given signal handler.
  21624. * @param other Signal handler to exchange the content with.
  21625. */
  21626. void swap(sigh &other) noexcept {
  21627. using std::swap;
  21628. swap(calls, other.calls);
  21629. }
  21630. /**
  21631. * @brief Returns the associated allocator.
  21632. * @return The associated allocator.
  21633. */
  21634. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  21635. return calls.get_allocator();
  21636. }
  21637. /**
  21638. * @brief Number of listeners connected to the signal.
  21639. * @return Number of listeners currently connected.
  21640. */
  21641. [[nodiscard]] size_type size() const noexcept {
  21642. return calls.size();
  21643. }
  21644. /**
  21645. * @brief Returns false if at least a listener is connected to the signal.
  21646. * @return True if the signal has no listeners connected, false otherwise.
  21647. */
  21648. [[nodiscard]] bool empty() const noexcept {
  21649. return calls.empty();
  21650. }
  21651. /**
  21652. * @brief Triggers a signal.
  21653. *
  21654. * All the listeners are notified. Order isn't guaranteed.
  21655. *
  21656. * @param args Arguments to use to invoke listeners.
  21657. */
  21658. void publish(Args... args) const {
  21659. for(auto pos = calls.size(); pos; --pos) {
  21660. calls[pos - 1u](args...);
  21661. }
  21662. }
  21663. /**
  21664. * @brief Collects return values from the listeners.
  21665. *
  21666. * The collector must expose a call operator with the following properties:
  21667. *
  21668. * * The return type is either `void` or such that it's convertible to
  21669. * `bool`. In the second case, a true value will stop the iteration.
  21670. * * The list of parameters is empty if `Ret` is `void`, otherwise it
  21671. * contains a single element such that `Ret` is convertible to it.
  21672. *
  21673. * @tparam Func Type of collector to use, if any.
  21674. * @param func A valid function object.
  21675. * @param args Arguments to use to invoke listeners.
  21676. */
  21677. template<typename Func>
  21678. void collect(Func func, Args... args) const {
  21679. for(auto pos = calls.size(); pos; --pos) {
  21680. if constexpr(std::is_void_v<Ret> || !std::is_invocable_v<Func, Ret>) {
  21681. calls[pos - 1u](args...);
  21682. if constexpr(std::is_invocable_r_v<bool, Func>) {
  21683. if(func()) {
  21684. break;
  21685. }
  21686. } else {
  21687. func();
  21688. }
  21689. } else {
  21690. if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
  21691. if(func(calls[pos - 1u](args...))) {
  21692. break;
  21693. }
  21694. } else {
  21695. func(calls[pos - 1u](args...));
  21696. }
  21697. }
  21698. }
  21699. }
  21700. private:
  21701. container_type calls;
  21702. };
  21703. /**
  21704. * @brief Connection class.
  21705. *
  21706. * Opaque object the aim of which is to allow users to release an already
  21707. * estabilished connection without having to keep a reference to the signal or
  21708. * the sink that generated it.
  21709. */
  21710. class connection {
  21711. template<typename>
  21712. friend class sink;
  21713. connection(delegate<void(void *)> fn, void *ref)
  21714. : disconnect{fn}, signal{ref} {}
  21715. public:
  21716. /*! @brief Default constructor. */
  21717. connection()
  21718. : signal{} {}
  21719. /**
  21720. * @brief Checks whether a connection is properly initialized.
  21721. * @return True if the connection is properly initialized, false otherwise.
  21722. */
  21723. [[nodiscard]] explicit operator bool() const noexcept {
  21724. return static_cast<bool>(disconnect);
  21725. }
  21726. /*! @brief Breaks the connection. */
  21727. void release() {
  21728. if(disconnect) {
  21729. disconnect(signal);
  21730. disconnect.reset();
  21731. }
  21732. }
  21733. private:
  21734. delegate<void(void *)> disconnect;
  21735. void *signal;
  21736. };
  21737. /**
  21738. * @brief Scoped connection class.
  21739. *
  21740. * Opaque object the aim of which is to allow users to release an already
  21741. * estabilished connection without having to keep a reference to the signal or
  21742. * the sink that generated it.<br/>
  21743. * A scoped connection automatically breaks the link between the two objects
  21744. * when it goes out of scope.
  21745. */
  21746. struct scoped_connection {
  21747. /*! @brief Default constructor. */
  21748. scoped_connection() = default;
  21749. /**
  21750. * @brief Constructs a scoped connection from a basic connection.
  21751. * @param other A valid connection object.
  21752. */
  21753. scoped_connection(const connection &other)
  21754. : conn{other} {}
  21755. /*! @brief Default copy constructor, deleted on purpose. */
  21756. scoped_connection(const scoped_connection &) = delete;
  21757. /**
  21758. * @brief Move constructor.
  21759. * @param other The scoped connection to move from.
  21760. */
  21761. scoped_connection(scoped_connection &&other) noexcept
  21762. : conn{std::exchange(other.conn, {})} {}
  21763. /*! @brief Automatically breaks the link on destruction. */
  21764. ~scoped_connection() {
  21765. conn.release();
  21766. }
  21767. /**
  21768. * @brief Default copy assignment operator, deleted on purpose.
  21769. * @return This scoped connection.
  21770. */
  21771. scoped_connection &operator=(const scoped_connection &) = delete;
  21772. /**
  21773. * @brief Move assignment operator.
  21774. * @param other The scoped connection to move from.
  21775. * @return This scoped connection.
  21776. */
  21777. scoped_connection &operator=(scoped_connection &&other) noexcept {
  21778. conn = std::exchange(other.conn, {});
  21779. return *this;
  21780. }
  21781. /**
  21782. * @brief Acquires a connection.
  21783. * @param other The connection object to acquire.
  21784. * @return This scoped connection.
  21785. */
  21786. scoped_connection &operator=(connection other) {
  21787. conn = other;
  21788. return *this;
  21789. }
  21790. /**
  21791. * @brief Checks whether a scoped connection is properly initialized.
  21792. * @return True if the connection is properly initialized, false otherwise.
  21793. */
  21794. [[nodiscard]] explicit operator bool() const noexcept {
  21795. return static_cast<bool>(conn);
  21796. }
  21797. /*! @brief Breaks the connection. */
  21798. void release() {
  21799. conn.release();
  21800. }
  21801. private:
  21802. connection conn;
  21803. };
  21804. /**
  21805. * @brief Sink class.
  21806. *
  21807. * A sink is used to connect listeners to signals and to disconnect them.<br/>
  21808. * The function type for a listener is the one of the signal to which it
  21809. * belongs.
  21810. *
  21811. * The clear separation between a signal and a sink permits to store the former
  21812. * as private data member without exposing the publish functionality to the
  21813. * users of the class.
  21814. *
  21815. * @warning
  21816. * Lifetime of a sink must not overcome that of the signal to which it refers.
  21817. * In any other case, attempting to use a sink results in undefined behavior.
  21818. *
  21819. * @tparam Ret Return type of a function type.
  21820. * @tparam Args Types of arguments of a function type.
  21821. * @tparam Allocator Type of allocator used to manage memory and elements.
  21822. */
  21823. template<typename Ret, typename... Args, typename Allocator>
  21824. class sink<sigh<Ret(Args...), Allocator>> {
  21825. using signal_type = sigh<Ret(Args...), Allocator>;
  21826. using delegate_type = typename signal_type::delegate_type;
  21827. using difference_type = typename signal_type::container_type::difference_type;
  21828. template<auto Candidate, typename Type>
  21829. static void release(Type value_or_instance, void *signal) {
  21830. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
  21831. }
  21832. template<auto Candidate>
  21833. static void release(void *signal) {
  21834. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>();
  21835. }
  21836. template<typename Func>
  21837. void disconnect_if(Func callback) {
  21838. auto &ref = signal_or_assert();
  21839. for(auto pos = ref.calls.size(); pos; --pos) {
  21840. if(auto &elem = ref.calls[pos - 1u]; callback(elem)) {
  21841. elem = std::move(ref.calls.back());
  21842. ref.calls.pop_back();
  21843. }
  21844. }
  21845. }
  21846. [[nodiscard]] auto &signal_or_assert() const noexcept {
  21847. ENTT_ASSERT(signal != nullptr, "Invalid pointer to signal");
  21848. return *signal;
  21849. }
  21850. public:
  21851. /*! @brief Constructs an invalid sink. */
  21852. sink() noexcept
  21853. : signal{} {}
  21854. /**
  21855. * @brief Constructs a sink that is allowed to modify a given signal.
  21856. * @param ref A valid reference to a signal object.
  21857. */
  21858. sink(sigh<Ret(Args...), Allocator> &ref) noexcept
  21859. : signal{&ref} {}
  21860. /**
  21861. * @brief Returns false if at least a listener is connected to the sink.
  21862. * @return True if the sink has no listeners connected, false otherwise.
  21863. */
  21864. [[nodiscard]] bool empty() const noexcept {
  21865. return signal_or_assert().calls.empty();
  21866. }
  21867. /**
  21868. * @brief Connects a free function or an unbound member to a signal.
  21869. * @tparam Candidate Function or member to connect to the signal.
  21870. * @return A properly initialized connection object.
  21871. */
  21872. template<auto Candidate>
  21873. connection connect() {
  21874. disconnect<Candidate>();
  21875. delegate_type call{};
  21876. call.template connect<Candidate>();
  21877. signal_or_assert().calls.push_back(std::move(call));
  21878. delegate<void(void *)> conn{};
  21879. conn.template connect<&release<Candidate>>();
  21880. return {conn, signal};
  21881. }
  21882. /**
  21883. * @brief Connects a free function with payload or a bound member to a
  21884. * signal.
  21885. *
  21886. * The signal isn't responsible for the connected object or the payload.
  21887. * Users must always guarantee that the lifetime of the instance overcomes
  21888. * the one of the signal.<br/>
  21889. * When used to connect a free function with payload, its signature must be
  21890. * such that the instance is the first argument before the ones used to
  21891. * define the signal itself.
  21892. *
  21893. * @tparam Candidate Function or member to connect to the signal.
  21894. * @tparam Type Type of class or type of payload.
  21895. * @param value_or_instance A valid reference that fits the purpose.
  21896. * @return A properly initialized connection object.
  21897. */
  21898. template<auto Candidate, typename Type>
  21899. connection connect(Type &value_or_instance) {
  21900. disconnect<Candidate>(value_or_instance);
  21901. delegate_type call{};
  21902. call.template connect<Candidate>(value_or_instance);
  21903. signal_or_assert().calls.push_back(std::move(call));
  21904. delegate<void(void *)> conn{};
  21905. conn.template connect<&release<Candidate, Type &>>(value_or_instance);
  21906. return {conn, signal};
  21907. }
  21908. /**
  21909. * @brief Connects a free function with payload or a bound member to a
  21910. * signal.
  21911. *
  21912. * @sa connect(Type &)
  21913. *
  21914. * @tparam Candidate Function or member to connect to the signal.
  21915. * @tparam Type Type of class or type of payload.
  21916. * @param value_or_instance A valid pointer that fits the purpose.
  21917. * @return A properly initialized connection object.
  21918. */
  21919. template<auto Candidate, typename Type>
  21920. connection connect(Type *value_or_instance) {
  21921. disconnect<Candidate>(value_or_instance);
  21922. delegate_type call{};
  21923. call.template connect<Candidate>(value_or_instance);
  21924. signal_or_assert().calls.push_back(std::move(call));
  21925. delegate<void(void *)> conn{};
  21926. conn.template connect<&release<Candidate, Type *>>(value_or_instance);
  21927. return {conn, signal};
  21928. }
  21929. /**
  21930. * @brief Disconnects a free function or an unbound member from a signal.
  21931. * @tparam Candidate Function or member to disconnect from the signal.
  21932. */
  21933. template<auto Candidate>
  21934. void disconnect() {
  21935. delegate_type call{};
  21936. call.template connect<Candidate>();
  21937. disconnect_if([&call](const auto &elem) { return elem == call; });
  21938. }
  21939. /**
  21940. * @brief Disconnects a free function with payload or a bound member from a
  21941. * signal.
  21942. *
  21943. * The signal isn't responsible for the connected object or the payload.
  21944. * Users must always guarantee that the lifetime of the instance overcomes
  21945. * the one of the signal.<br/>
  21946. * When used to connect a free function with payload, its signature must be
  21947. * such that the instance is the first argument before the ones used to
  21948. * define the signal itself.
  21949. *
  21950. * @tparam Candidate Function or member to disconnect from the signal.
  21951. * @tparam Type Type of class or type of payload, if any.
  21952. * @param value_or_instance A valid reference that fits the purpose.
  21953. */
  21954. template<auto Candidate, typename Type>
  21955. void disconnect(Type &value_or_instance) {
  21956. delegate_type call{};
  21957. call.template connect<Candidate>(value_or_instance);
  21958. disconnect_if([&call](const auto &elem) { return elem == call; });
  21959. }
  21960. /**
  21961. * @brief Disconnects a free function with payload or a bound member from a
  21962. * signal.
  21963. *
  21964. * @sa disconnect(Type &)
  21965. *
  21966. * @tparam Candidate Function or member to disconnect from the signal.
  21967. * @tparam Type Type of class or type of payload, if any.
  21968. * @param value_or_instance A valid pointer that fits the purpose.
  21969. */
  21970. template<auto Candidate, typename Type>
  21971. void disconnect(Type *value_or_instance) {
  21972. delegate_type call{};
  21973. call.template connect<Candidate>(value_or_instance);
  21974. disconnect_if([&call](const auto &elem) { return elem == call; });
  21975. }
  21976. /**
  21977. * @brief Disconnects free functions with payload or bound members from a
  21978. * signal.
  21979. * @param value_or_instance A valid object that fits the purpose.
  21980. */
  21981. void disconnect(const void *value_or_instance) {
  21982. ENTT_ASSERT(value_or_instance != nullptr, "Invalid value or instance");
  21983. disconnect_if([value_or_instance](const auto &elem) { return elem.data() == value_or_instance; });
  21984. }
  21985. /*! @brief Disconnects all the listeners from a signal. */
  21986. void disconnect() {
  21987. signal_or_assert().calls.clear();
  21988. }
  21989. /**
  21990. * @brief Returns true if a sink is correctly initialized, false otherwise.
  21991. * @return True if a sink is correctly initialized, false otherwise.
  21992. */
  21993. [[nodiscard]] explicit operator bool() const noexcept {
  21994. return signal != nullptr;
  21995. }
  21996. private:
  21997. signal_type *signal;
  21998. };
  21999. /**
  22000. * @brief Deduction guide.
  22001. *
  22002. * It allows to deduce the signal handler type of a sink directly from the
  22003. * signal it refers to.
  22004. *
  22005. * @tparam Ret Return type of a function type.
  22006. * @tparam Args Types of arguments of a function type.
  22007. * @tparam Allocator Type of allocator used to manage memory and elements.
  22008. */
  22009. template<typename Ret, typename... Args, typename Allocator>
  22010. sink(sigh<Ret(Args...), Allocator> &) -> sink<sigh<Ret(Args...), Allocator>>;
  22011. } // namespace entt
  22012. #endif
  22013. // #include "entity.hpp"
  22014. // #include "fwd.hpp"
  22015. namespace entt {
  22016. /*! @cond TURN_OFF_DOXYGEN */
  22017. namespace internal {
  22018. template<typename, typename, typename = void>
  22019. struct has_on_construct final: std::false_type {};
  22020. template<typename Type, typename Registry>
  22021. struct has_on_construct<Type, Registry, std::void_t<decltype(Type::on_construct(std::declval<Registry &>(), std::declval<Registry>().create()))>>
  22022. : std::true_type {};
  22023. template<typename, typename, typename = void>
  22024. struct has_on_update final: std::false_type {};
  22025. template<typename Type, typename Registry>
  22026. struct has_on_update<Type, Registry, std::void_t<decltype(Type::on_update(std::declval<Registry &>(), std::declval<Registry>().create()))>>
  22027. : std::true_type {};
  22028. template<typename, typename, typename = void>
  22029. struct has_on_destroy final: std::false_type {};
  22030. template<typename Type, typename Registry>
  22031. struct has_on_destroy<Type, Registry, std::void_t<decltype(Type::on_destroy(std::declval<Registry &>(), std::declval<Registry>().create()))>>
  22032. : std::true_type {};
  22033. } // namespace internal
  22034. /*! @endcond */
  22035. /**
  22036. * @brief Mixin type used to add signal support to storage types.
  22037. *
  22038. * The function type of a listener is equivalent to:
  22039. *
  22040. * @code{.cpp}
  22041. * void(basic_registry<entity_type> &, entity_type);
  22042. * @endcode
  22043. *
  22044. * This applies to all signals made available.
  22045. *
  22046. * @tparam Type Underlying storage type.
  22047. * @tparam Registry Basic registry type.
  22048. */
  22049. template<typename Type, typename Registry>
  22050. class basic_sigh_mixin final: public Type {
  22051. using underlying_type = Type;
  22052. using owner_type = Registry;
  22053. using basic_registry_type = basic_registry<typename owner_type::entity_type, typename owner_type::allocator_type>;
  22054. using sigh_type = sigh<void(owner_type &, const typename underlying_type::entity_type), typename underlying_type::allocator_type>;
  22055. using underlying_iterator = typename underlying_type::base_type::basic_iterator;
  22056. static_assert(std::is_base_of_v<basic_registry_type, owner_type>, "Invalid registry type");
  22057. [[nodiscard]] auto &owner_or_assert() const noexcept {
  22058. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  22059. return static_cast<owner_type &>(*owner);
  22060. }
  22061. private:
  22062. void pop(underlying_iterator first, underlying_iterator last) final {
  22063. if(auto &reg = owner_or_assert(); destruction.empty()) {
  22064. underlying_type::pop(first, last);
  22065. } else {
  22066. for(; first != last; ++first) {
  22067. const auto entt = *first;
  22068. destruction.publish(reg, entt);
  22069. const auto it = underlying_type::find(entt);
  22070. underlying_type::pop(it, it + 1u);
  22071. }
  22072. }
  22073. }
  22074. void pop_all() final {
  22075. if(auto &reg = owner_or_assert(); !destruction.empty()) {
  22076. if constexpr(std::is_same_v<typename underlying_type::element_type, entity_type>) {
  22077. for(typename underlying_type::size_type pos{}, last = underlying_type::free_list(); pos < last; ++pos) {
  22078. destruction.publish(reg, underlying_type::base_type::operator[](pos));
  22079. }
  22080. } else {
  22081. for(auto entt: static_cast<typename underlying_type::base_type &>(*this)) {
  22082. if constexpr(underlying_type::storage_policy == deletion_policy::in_place) {
  22083. if(entt != tombstone) {
  22084. destruction.publish(reg, entt);
  22085. }
  22086. } else {
  22087. destruction.publish(reg, entt);
  22088. }
  22089. }
  22090. }
  22091. }
  22092. underlying_type::pop_all();
  22093. }
  22094. underlying_iterator try_emplace(const typename underlying_type::entity_type entt, const bool force_back, const void *value) final {
  22095. const auto it = underlying_type::try_emplace(entt, force_back, value);
  22096. if(auto &reg = owner_or_assert(); it != underlying_type::base_type::end()) {
  22097. construction.publish(reg, *it);
  22098. }
  22099. return it;
  22100. }
  22101. void bind_any(any value) noexcept final {
  22102. owner = any_cast<basic_registry_type>(&value);
  22103. if constexpr(!std::is_same_v<registry_type, basic_registry_type>) {
  22104. if(owner == nullptr) {
  22105. owner = any_cast<registry_type>(&value);
  22106. }
  22107. }
  22108. underlying_type::bind_any(std::move(value));
  22109. }
  22110. public:
  22111. /*! @brief Allocator type. */
  22112. using allocator_type = typename underlying_type::allocator_type;
  22113. /*! @brief Underlying entity identifier. */
  22114. using entity_type = typename underlying_type::entity_type;
  22115. /*! @brief Expected registry type. */
  22116. using registry_type = owner_type;
  22117. /*! @brief Default constructor. */
  22118. basic_sigh_mixin()
  22119. : basic_sigh_mixin{allocator_type{}} {}
  22120. /**
  22121. * @brief Constructs an empty storage with a given allocator.
  22122. * @param allocator The allocator to use.
  22123. */
  22124. explicit basic_sigh_mixin(const allocator_type &allocator)
  22125. : underlying_type{allocator},
  22126. owner{},
  22127. construction{allocator},
  22128. destruction{allocator},
  22129. update{allocator} {
  22130. if constexpr(internal::has_on_construct<typename underlying_type::element_type, Registry>::value) {
  22131. sink{construction}.template connect<&underlying_type::element_type::on_construct>();
  22132. }
  22133. if constexpr(internal::has_on_update<typename underlying_type::element_type, Registry>::value) {
  22134. sink{update}.template connect<&underlying_type::element_type::on_update>();
  22135. }
  22136. if constexpr(internal::has_on_destroy<typename underlying_type::element_type, Registry>::value) {
  22137. sink{destruction}.template connect<&underlying_type::element_type::on_destroy>();
  22138. }
  22139. }
  22140. /*! @brief Default copy constructor, deleted on purpose. */
  22141. basic_sigh_mixin(const basic_sigh_mixin &) = delete;
  22142. /**
  22143. * @brief Move constructor.
  22144. * @param other The instance to move from.
  22145. */
  22146. basic_sigh_mixin(basic_sigh_mixin &&other) noexcept
  22147. : underlying_type{static_cast<underlying_type &&>(other)},
  22148. owner{other.owner},
  22149. construction{std::move(other.construction)},
  22150. destruction{std::move(other.destruction)},
  22151. update{std::move(other.update)} {}
  22152. /**
  22153. * @brief Allocator-extended move constructor.
  22154. * @param other The instance to move from.
  22155. * @param allocator The allocator to use.
  22156. */
  22157. basic_sigh_mixin(basic_sigh_mixin &&other, const allocator_type &allocator)
  22158. : underlying_type{static_cast<underlying_type &&>(other), allocator},
  22159. owner{other.owner},
  22160. construction{std::move(other.construction), allocator},
  22161. destruction{std::move(other.destruction), allocator},
  22162. update{std::move(other.update), allocator} {}
  22163. /*! @brief Default destructor. */
  22164. ~basic_sigh_mixin() override = default;
  22165. /**
  22166. * @brief Default copy assignment operator, deleted on purpose.
  22167. * @return This mixin.
  22168. */
  22169. basic_sigh_mixin &operator=(const basic_sigh_mixin &) = delete;
  22170. /**
  22171. * @brief Move assignment operator.
  22172. * @param other The instance to move from.
  22173. * @return This mixin.
  22174. */
  22175. basic_sigh_mixin &operator=(basic_sigh_mixin &&other) noexcept {
  22176. swap(other);
  22177. return *this;
  22178. }
  22179. /**
  22180. * @brief Exchanges the contents with those of a given storage.
  22181. * @param other Storage to exchange the content with.
  22182. */
  22183. void swap(basic_sigh_mixin &other) noexcept {
  22184. using std::swap;
  22185. swap(owner, other.owner);
  22186. swap(construction, other.construction);
  22187. swap(destruction, other.destruction);
  22188. swap(update, other.update);
  22189. underlying_type::swap(other);
  22190. }
  22191. /**
  22192. * @brief Returns a sink object.
  22193. *
  22194. * The sink returned by this function can be used to receive notifications
  22195. * whenever a new instance is created and assigned to an entity.<br/>
  22196. * Listeners are invoked after the object has been assigned to the entity.
  22197. *
  22198. * @sa sink
  22199. *
  22200. * @return A temporary sink object.
  22201. */
  22202. [[nodiscard]] auto on_construct() noexcept {
  22203. return sink{construction};
  22204. }
  22205. /**
  22206. * @brief Returns a sink object.
  22207. *
  22208. * The sink returned by this function can be used to receive notifications
  22209. * whenever an instance is explicitly updated.<br/>
  22210. * Listeners are invoked after the object has been updated.
  22211. *
  22212. * @sa sink
  22213. *
  22214. * @return A temporary sink object.
  22215. */
  22216. [[nodiscard]] auto on_update() noexcept {
  22217. return sink{update};
  22218. }
  22219. /**
  22220. * @brief Returns a sink object.
  22221. *
  22222. * The sink returned by this function can be used to receive notifications
  22223. * whenever an instance is removed from an entity and thus destroyed.<br/>
  22224. * Listeners are invoked before the object has been removed from the entity.
  22225. *
  22226. * @sa sink
  22227. *
  22228. * @return A temporary sink object.
  22229. */
  22230. [[nodiscard]] auto on_destroy() noexcept {
  22231. return sink{destruction};
  22232. }
  22233. /**
  22234. * @brief Checks if a mixin refers to a valid registry.
  22235. * @return True if the mixin refers to a valid registry, false otherwise.
  22236. */
  22237. [[nodiscard]] explicit operator bool() const noexcept {
  22238. return (owner != nullptr);
  22239. }
  22240. /**
  22241. * @brief Returns a pointer to the underlying registry, if any.
  22242. * @return A pointer to the underlying registry, if any.
  22243. */
  22244. [[nodiscard]] const registry_type &registry() const noexcept {
  22245. return owner_or_assert();
  22246. }
  22247. /*! @copydoc registry */
  22248. [[nodiscard]] registry_type &registry() noexcept {
  22249. return owner_or_assert();
  22250. }
  22251. /**
  22252. * @brief Creates a new identifier or recycles a destroyed one.
  22253. * @return A valid identifier.
  22254. */
  22255. auto generate() {
  22256. const auto entt = underlying_type::generate();
  22257. construction.publish(owner_or_assert(), entt);
  22258. return entt;
  22259. }
  22260. /**
  22261. * @brief Creates a new identifier or recycles a destroyed one.
  22262. * @param hint Required identifier.
  22263. * @return A valid identifier.
  22264. */
  22265. entity_type generate(const entity_type hint) {
  22266. const auto entt = underlying_type::generate(hint);
  22267. construction.publish(owner_or_assert(), entt);
  22268. return entt;
  22269. }
  22270. /**
  22271. * @brief Assigns each element in a range an identifier.
  22272. * @tparam It Type of mutable forward iterator.
  22273. * @param first An iterator to the first element of the range to generate.
  22274. * @param last An iterator past the last element of the range to generate.
  22275. */
  22276. template<typename It>
  22277. void generate(It first, It last) {
  22278. underlying_type::generate(first, last);
  22279. if(auto &reg = owner_or_assert(); !construction.empty()) {
  22280. for(; first != last; ++first) {
  22281. construction.publish(reg, *first);
  22282. }
  22283. }
  22284. }
  22285. /**
  22286. * @brief Assigns an entity to a storage and constructs its object.
  22287. * @tparam Args Types of arguments to forward to the underlying storage.
  22288. * @param entt A valid identifier.
  22289. * @param args Parameters to forward to the underlying storage.
  22290. * @return A reference to the newly created object.
  22291. */
  22292. template<typename... Args>
  22293. decltype(auto) emplace(const entity_type entt, Args &&...args) {
  22294. underlying_type::emplace(entt, std::forward<Args>(args)...);
  22295. construction.publish(owner_or_assert(), entt);
  22296. return this->get(entt);
  22297. }
  22298. /**
  22299. * @brief Updates the instance assigned to a given entity in-place.
  22300. * @tparam Func Types of the function objects to invoke.
  22301. * @param entt A valid identifier.
  22302. * @param func Valid function objects.
  22303. * @return A reference to the patched instance.
  22304. */
  22305. template<typename... Func>
  22306. decltype(auto) patch(const entity_type entt, Func &&...func) {
  22307. underlying_type::patch(entt, std::forward<Func>(func)...);
  22308. update.publish(owner_or_assert(), entt);
  22309. return this->get(entt);
  22310. }
  22311. /**
  22312. * @brief Assigns one or more entities to a storage and constructs their
  22313. * objects from a given instance.
  22314. * @tparam It Type of input iterator.
  22315. * @tparam Args Types of arguments to forward to the underlying storage.
  22316. * @param first An iterator to the first element of the range of entities.
  22317. * @param last An iterator past the last element of the range of entities.
  22318. * @param args Parameters to use to forward to the underlying storage.
  22319. */
  22320. template<typename It, typename... Args>
  22321. void insert(It first, It last, Args &&...args) {
  22322. auto from = underlying_type::size();
  22323. underlying_type::insert(first, last, std::forward<Args>(args)...);
  22324. if(auto &reg = owner_or_assert(); !construction.empty()) {
  22325. // fine as long as insert passes force_back true to try_emplace
  22326. for(const auto to = underlying_type::size(); from != to; ++from) {
  22327. construction.publish(reg, underlying_type::operator[](from));
  22328. }
  22329. }
  22330. }
  22331. private:
  22332. basic_registry_type *owner;
  22333. sigh_type construction;
  22334. sigh_type destruction;
  22335. sigh_type update;
  22336. };
  22337. /**
  22338. * @brief Mixin type used to add _reactive_ support to storage types.
  22339. * @tparam Type Underlying storage type.
  22340. * @tparam Registry Basic registry type.
  22341. */
  22342. template<typename Type, typename Registry>
  22343. class basic_reactive_mixin final: public Type {
  22344. using underlying_type = Type;
  22345. using owner_type = Registry;
  22346. using alloc_traits = std::allocator_traits<typename underlying_type::allocator_type>;
  22347. using basic_registry_type = basic_registry<typename owner_type::entity_type, typename owner_type::allocator_type>;
  22348. using container_type = std::vector<connection, typename alloc_traits::template rebind_alloc<connection>>;
  22349. static_assert(std::is_base_of_v<basic_registry_type, owner_type>, "Invalid registry type");
  22350. [[nodiscard]] auto &owner_or_assert() const noexcept {
  22351. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  22352. return static_cast<owner_type &>(*owner);
  22353. }
  22354. void emplace_element(const Registry &, typename underlying_type::entity_type entity) {
  22355. if(!underlying_type::contains(entity)) {
  22356. underlying_type::emplace(entity);
  22357. }
  22358. }
  22359. private:
  22360. void bind_any(any value) noexcept final {
  22361. owner = any_cast<basic_registry_type>(&value);
  22362. if constexpr(!std::is_same_v<registry_type, basic_registry_type>) {
  22363. if(owner == nullptr) {
  22364. owner = any_cast<registry_type>(&value);
  22365. }
  22366. }
  22367. underlying_type::bind_any(std::move(value));
  22368. }
  22369. public:
  22370. /*! @brief Allocator type. */
  22371. using allocator_type = typename underlying_type::allocator_type;
  22372. /*! @brief Underlying entity identifier. */
  22373. using entity_type = typename underlying_type::entity_type;
  22374. /*! @brief Expected registry type. */
  22375. using registry_type = owner_type;
  22376. /*! @brief Default constructor. */
  22377. basic_reactive_mixin()
  22378. : basic_reactive_mixin{allocator_type{}} {}
  22379. /**
  22380. * @brief Constructs an empty storage with a given allocator.
  22381. * @param allocator The allocator to use.
  22382. */
  22383. explicit basic_reactive_mixin(const allocator_type &allocator)
  22384. : underlying_type{allocator},
  22385. owner{},
  22386. conn{allocator} {
  22387. }
  22388. /*! @brief Default copy constructor, deleted on purpose. */
  22389. basic_reactive_mixin(const basic_reactive_mixin &) = delete;
  22390. /**
  22391. * @brief Move constructor.
  22392. * @param other The instance to move from.
  22393. */
  22394. basic_reactive_mixin(basic_reactive_mixin &&other) noexcept
  22395. : underlying_type{static_cast<underlying_type &&>(other)},
  22396. owner{other.owner},
  22397. conn{std::move(other.conn)} {
  22398. }
  22399. /**
  22400. * @brief Allocator-extended move constructor.
  22401. * @param other The instance to move from.
  22402. * @param allocator The allocator to use.
  22403. */
  22404. basic_reactive_mixin(basic_reactive_mixin &&other, const allocator_type &allocator)
  22405. : underlying_type{static_cast<underlying_type &&>(other), allocator},
  22406. owner{other.owner},
  22407. conn{std::move(other.conn), allocator} {
  22408. }
  22409. /*! @brief Default destructor. */
  22410. ~basic_reactive_mixin() override = default;
  22411. /**
  22412. * @brief Default copy assignment operator, deleted on purpose.
  22413. * @return This mixin.
  22414. */
  22415. basic_reactive_mixin &operator=(const basic_reactive_mixin &) = delete;
  22416. /**
  22417. * @brief Move assignment operator.
  22418. * @param other The instance to move from.
  22419. * @return This mixin.
  22420. */
  22421. basic_reactive_mixin &operator=(basic_reactive_mixin &&other) noexcept {
  22422. underlying_type::swap(other);
  22423. return *this;
  22424. }
  22425. /**
  22426. * @brief Makes storage _react_ to creation of objects of the given type.
  22427. * @tparam Clazz Type of element to _react_ to.
  22428. * @tparam Candidate Function to use to _react_ to the event.
  22429. * @param id Optional name used to map the storage within the registry.
  22430. * @return This mixin.
  22431. */
  22432. template<typename Clazz, auto Candidate = &basic_reactive_mixin::emplace_element>
  22433. basic_reactive_mixin &on_construct(const id_type id = type_hash<Clazz>::value()) {
  22434. auto curr = owner_or_assert().template storage<Clazz>(id).on_construct().template connect<Candidate>(*this);
  22435. conn.push_back(std::move(curr));
  22436. return *this;
  22437. }
  22438. /**
  22439. * @brief Makes storage _react_ to update of objects of the given type.
  22440. * @tparam Clazz Type of element to _react_ to.
  22441. * @tparam Candidate Function to use to _react_ to the event.
  22442. * @param id Optional name used to map the storage within the registry.
  22443. * @return This mixin.
  22444. */
  22445. template<typename Clazz, auto Candidate = &basic_reactive_mixin::emplace_element>
  22446. basic_reactive_mixin &on_update(const id_type id = type_hash<Clazz>::value()) {
  22447. auto curr = owner_or_assert().template storage<Clazz>(id).on_update().template connect<Candidate>(*this);
  22448. conn.push_back(std::move(curr));
  22449. return *this;
  22450. }
  22451. /**
  22452. * @brief Makes storage _react_ to destruction of objects of the given type.
  22453. * @tparam Clazz Type of element to _react_ to.
  22454. * @tparam Candidate Function to use to _react_ to the event.
  22455. * @param id Optional name used to map the storage within the registry.
  22456. * @return This mixin.
  22457. */
  22458. template<typename Clazz, auto Candidate = &basic_reactive_mixin::emplace_element>
  22459. basic_reactive_mixin &on_destroy(const id_type id = type_hash<Clazz>::value()) {
  22460. auto curr = owner_or_assert().template storage<Clazz>(id).on_destroy().template connect<Candidate>(*this);
  22461. conn.push_back(std::move(curr));
  22462. return *this;
  22463. }
  22464. /**
  22465. * @brief Checks if a mixin refers to a valid registry.
  22466. * @return True if the mixin refers to a valid registry, false otherwise.
  22467. */
  22468. [[nodiscard]] explicit operator bool() const noexcept {
  22469. return (owner != nullptr);
  22470. }
  22471. /**
  22472. * @brief Returns a pointer to the underlying registry, if any.
  22473. * @return A pointer to the underlying registry, if any.
  22474. */
  22475. [[nodiscard]] const registry_type &registry() const noexcept {
  22476. return owner_or_assert();
  22477. }
  22478. /*! @copydoc registry */
  22479. [[nodiscard]] registry_type &registry() noexcept {
  22480. return owner_or_assert();
  22481. }
  22482. /**
  22483. * @brief Returns a view that is filtered by the underlying storage.
  22484. * @tparam Get Types of elements used to construct the view.
  22485. * @tparam Exclude Types of elements used to filter the view.
  22486. * @return A newly created view.
  22487. */
  22488. template<typename... Get, typename... Exclude>
  22489. [[nodiscard]] basic_view<get_t<const basic_reactive_mixin, typename basic_registry_type::template storage_for_type<const Get>...>, exclude_t<typename basic_registry_type::template storage_for_type<const Exclude>...>>
  22490. view(exclude_t<Exclude...> = exclude_t{}) const {
  22491. const owner_type &parent = owner_or_assert();
  22492. basic_view<get_t<const basic_reactive_mixin, typename basic_registry_type::template storage_for_type<const Get>...>, exclude_t<typename basic_registry_type::template storage_for_type<const Exclude>...>> elem{};
  22493. [&elem](const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }(parent.template storage<std::remove_const_t<Exclude>>()..., parent.template storage<std::remove_const_t<Get>>()..., this);
  22494. return elem;
  22495. }
  22496. /*! @copydoc view */
  22497. template<typename... Get, typename... Exclude>
  22498. [[nodiscard]] basic_view<get_t<const basic_reactive_mixin, typename basic_registry_type::template storage_for_type<Get>...>, exclude_t<typename basic_registry_type::template storage_for_type<Exclude>...>>
  22499. view(exclude_t<Exclude...> = exclude_t{}) {
  22500. std::conditional_t<((std::is_const_v<Get> && ...) && (std::is_const_v<Exclude> && ...)), const owner_type, owner_type> &parent = owner_or_assert();
  22501. return {*this, parent.template storage<std::remove_const_t<Get>>()..., parent.template storage<std::remove_const_t<Exclude>>()...};
  22502. }
  22503. /*! @brief Releases all connections to the underlying registry, if any. */
  22504. void reset() {
  22505. for(auto &&curr: conn) {
  22506. curr.release();
  22507. }
  22508. conn.clear();
  22509. }
  22510. private:
  22511. basic_registry_type *owner;
  22512. container_type conn;
  22513. };
  22514. } // namespace entt
  22515. #endif
  22516. // #include "entity/organizer.hpp"
  22517. #ifndef ENTT_ENTITY_ORGANIZER_HPP
  22518. #define ENTT_ENTITY_ORGANIZER_HPP
  22519. #include <cstddef>
  22520. #include <type_traits>
  22521. #include <utility>
  22522. #include <vector>
  22523. // #include "../core/type_info.hpp"
  22524. // #include "../core/type_traits.hpp"
  22525. // #include "../core/utility.hpp"
  22526. #ifndef ENTT_CORE_UTILITY_HPP
  22527. #define ENTT_CORE_UTILITY_HPP
  22528. #include <type_traits>
  22529. #include <utility>
  22530. namespace entt {
  22531. /*! @brief Identity function object (waiting for C++20). */
  22532. struct identity {
  22533. /*! @brief Indicates that this is a transparent function object. */
  22534. using is_transparent = void;
  22535. /**
  22536. * @brief Returns its argument unchanged.
  22537. * @tparam Type Type of the argument.
  22538. * @param value The actual argument.
  22539. * @return The submitted value as-is.
  22540. */
  22541. template<typename Type>
  22542. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  22543. return std::forward<Type>(value);
  22544. }
  22545. };
  22546. /**
  22547. * @brief Constant utility to disambiguate overloaded members of a class.
  22548. * @tparam Type Type of the desired overload.
  22549. * @tparam Class Type of class to which the member belongs.
  22550. * @param member A valid pointer to a member.
  22551. * @return Pointer to the member.
  22552. */
  22553. template<typename Type, typename Class>
  22554. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  22555. return member;
  22556. }
  22557. /**
  22558. * @brief Constant utility to disambiguate overloaded functions.
  22559. * @tparam Func Function type of the desired overload.
  22560. * @param func A valid pointer to a function.
  22561. * @return Pointer to the function.
  22562. */
  22563. template<typename Func>
  22564. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  22565. return func;
  22566. }
  22567. /**
  22568. * @brief Helper type for visitors.
  22569. * @tparam Func Types of function objects.
  22570. */
  22571. template<typename... Func>
  22572. struct overloaded: Func... {
  22573. using Func::operator()...;
  22574. };
  22575. /**
  22576. * @brief Deduction guide.
  22577. * @tparam Func Types of function objects.
  22578. */
  22579. template<typename... Func>
  22580. overloaded(Func...) -> overloaded<Func...>;
  22581. /**
  22582. * @brief Basic implementation of a y-combinator.
  22583. * @tparam Func Type of a potentially recursive function.
  22584. */
  22585. template<typename Func>
  22586. struct y_combinator {
  22587. /**
  22588. * @brief Constructs a y-combinator from a given function.
  22589. * @param recursive A potentially recursive function.
  22590. */
  22591. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  22592. : func{std::move(recursive)} {}
  22593. /**
  22594. * @brief Invokes a y-combinator and therefore its underlying function.
  22595. * @tparam Args Types of arguments to use to invoke the underlying function.
  22596. * @param args Parameters to use to invoke the underlying function.
  22597. * @return Return value of the underlying function, if any.
  22598. */
  22599. template<typename... Args>
  22600. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  22601. return func(*this, std::forward<Args>(args)...);
  22602. }
  22603. /*! @copydoc operator()() */
  22604. template<typename... Args>
  22605. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  22606. return func(*this, std::forward<Args>(args)...);
  22607. }
  22608. private:
  22609. Func func;
  22610. };
  22611. } // namespace entt
  22612. #endif
  22613. // #include "../graph/adjacency_matrix.hpp"
  22614. #ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  22615. #define ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  22616. #include <cstddef>
  22617. #include <iterator>
  22618. #include <memory>
  22619. #include <type_traits>
  22620. #include <utility>
  22621. #include <vector>
  22622. // #include "../config/config.h"
  22623. #ifndef ENTT_CONFIG_CONFIG_H
  22624. #define ENTT_CONFIG_CONFIG_H
  22625. // #include "version.h"
  22626. #ifndef ENTT_CONFIG_VERSION_H
  22627. #define ENTT_CONFIG_VERSION_H
  22628. // #include "macro.h"
  22629. #ifndef ENTT_CONFIG_MACRO_H
  22630. #define ENTT_CONFIG_MACRO_H
  22631. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  22632. #define ENTT_STR(arg) #arg
  22633. #define ENTT_XSTR(arg) ENTT_STR(arg)
  22634. // NOLINTEND(cppcoreguidelines-macro-usage)
  22635. #endif
  22636. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  22637. #define ENTT_VERSION_MAJOR 3
  22638. #define ENTT_VERSION_MINOR 16
  22639. #define ENTT_VERSION_PATCH 0
  22640. #define ENTT_VERSION \
  22641. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  22642. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  22643. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  22644. #endif
  22645. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  22646. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  22647. # define ENTT_CONSTEXPR
  22648. # define ENTT_THROW throw
  22649. # define ENTT_TRY try
  22650. # define ENTT_CATCH catch(...)
  22651. #else
  22652. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  22653. # define ENTT_THROW
  22654. # define ENTT_TRY if(true)
  22655. # define ENTT_CATCH if(false)
  22656. #endif
  22657. #if __has_include(<version>)
  22658. # include <version>
  22659. #
  22660. # if defined(__cpp_consteval)
  22661. # define ENTT_CONSTEVAL consteval
  22662. # endif
  22663. #endif
  22664. #ifndef ENTT_CONSTEVAL
  22665. # define ENTT_CONSTEVAL constexpr
  22666. #endif
  22667. #ifdef ENTT_USE_ATOMIC
  22668. # include <atomic>
  22669. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  22670. #else
  22671. # define ENTT_MAYBE_ATOMIC(Type) Type
  22672. #endif
  22673. #ifndef ENTT_ID_TYPE
  22674. # include <cstdint>
  22675. # define ENTT_ID_TYPE std::uint32_t
  22676. #else
  22677. # include <cstdint> // provides coverage for types in the std namespace
  22678. #endif
  22679. #ifndef ENTT_SPARSE_PAGE
  22680. # define ENTT_SPARSE_PAGE 4096
  22681. #endif
  22682. #ifndef ENTT_PACKED_PAGE
  22683. # define ENTT_PACKED_PAGE 1024
  22684. #endif
  22685. #ifdef ENTT_DISABLE_ASSERT
  22686. # undef ENTT_ASSERT
  22687. # define ENTT_ASSERT(condition, msg) (void(0))
  22688. #elif !defined ENTT_ASSERT
  22689. # include <cassert>
  22690. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  22691. #endif
  22692. #ifdef ENTT_DISABLE_ASSERT
  22693. # undef ENTT_ASSERT_CONSTEXPR
  22694. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  22695. #elif !defined ENTT_ASSERT_CONSTEXPR
  22696. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  22697. #endif
  22698. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  22699. #ifdef ENTT_NO_ETO
  22700. # define ENTT_ETO_TYPE(Type) void
  22701. #else
  22702. # define ENTT_ETO_TYPE(Type) Type
  22703. #endif
  22704. #ifdef ENTT_NO_MIXIN
  22705. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  22706. #else
  22707. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  22708. #endif
  22709. #ifdef ENTT_STANDARD_CPP
  22710. # define ENTT_NONSTD false
  22711. #else
  22712. # define ENTT_NONSTD true
  22713. # if defined __clang__ || defined __GNUC__
  22714. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  22715. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  22716. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  22717. # elif defined _MSC_VER
  22718. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  22719. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  22720. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  22721. # endif
  22722. #endif
  22723. #ifndef ENTT_EXPORT
  22724. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  22725. # define ENTT_EXPORT __declspec(dllexport)
  22726. # define ENTT_IMPORT __declspec(dllimport)
  22727. # define ENTT_HIDDEN
  22728. # elif defined __GNUC__ && __GNUC__ >= 4
  22729. # define ENTT_EXPORT __attribute__((visibility("default")))
  22730. # define ENTT_IMPORT __attribute__((visibility("default")))
  22731. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  22732. # else /* Unsupported compiler */
  22733. # define ENTT_EXPORT
  22734. # define ENTT_IMPORT
  22735. # define ENTT_HIDDEN
  22736. # endif
  22737. #endif
  22738. #ifndef ENTT_API
  22739. # if defined ENTT_API_EXPORT
  22740. # define ENTT_API ENTT_EXPORT
  22741. # elif defined ENTT_API_IMPORT
  22742. # define ENTT_API ENTT_IMPORT
  22743. # else /* No API */
  22744. # define ENTT_API
  22745. # endif
  22746. #endif
  22747. #if defined _MSC_VER
  22748. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  22749. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  22750. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  22751. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  22752. #endif
  22753. // NOLINTEND(cppcoreguidelines-macro-usage)
  22754. #endif
  22755. // #include "../core/iterator.hpp"
  22756. #ifndef ENTT_CORE_ITERATOR_HPP
  22757. #define ENTT_CORE_ITERATOR_HPP
  22758. #include <iterator>
  22759. #include <memory>
  22760. #include <type_traits>
  22761. #include <utility>
  22762. namespace entt {
  22763. /**
  22764. * @brief Helper type to use as pointer with input iterators.
  22765. * @tparam Type of wrapped value.
  22766. */
  22767. template<typename Type>
  22768. struct input_iterator_pointer final {
  22769. /*! @brief Value type. */
  22770. using value_type = Type;
  22771. /*! @brief Pointer type. */
  22772. using pointer = Type *;
  22773. /*! @brief Reference type. */
  22774. using reference = Type &;
  22775. /**
  22776. * @brief Constructs a proxy object by move.
  22777. * @param val Value to use to initialize the proxy object.
  22778. */
  22779. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  22780. : value{std::move(val)} {}
  22781. /**
  22782. * @brief Access operator for accessing wrapped values.
  22783. * @return A pointer to the wrapped value.
  22784. */
  22785. [[nodiscard]] constexpr pointer operator->() noexcept {
  22786. return std::addressof(value);
  22787. }
  22788. /**
  22789. * @brief Dereference operator for accessing wrapped values.
  22790. * @return A reference to the wrapped value.
  22791. */
  22792. [[nodiscard]] constexpr reference operator*() noexcept {
  22793. return value;
  22794. }
  22795. private:
  22796. Type value;
  22797. };
  22798. /**
  22799. * @brief Plain iota iterator (waiting for C++20).
  22800. * @tparam Type Value type.
  22801. */
  22802. template<typename Type>
  22803. class iota_iterator final {
  22804. static_assert(std::is_integral_v<Type>, "Not an integral type");
  22805. public:
  22806. /*! @brief Value type, likely an integral one. */
  22807. using value_type = Type;
  22808. /*! @brief Invalid pointer type. */
  22809. using pointer = void;
  22810. /*! @brief Non-reference type, same as value type. */
  22811. using reference = value_type;
  22812. /*! @brief Difference type. */
  22813. using difference_type = std::ptrdiff_t;
  22814. /*! @brief Iterator category. */
  22815. using iterator_category = std::input_iterator_tag;
  22816. /*! @brief Default constructor. */
  22817. constexpr iota_iterator() noexcept
  22818. : current{} {}
  22819. /**
  22820. * @brief Constructs an iota iterator from a given value.
  22821. * @param init The initial value assigned to the iota iterator.
  22822. */
  22823. constexpr iota_iterator(const value_type init) noexcept
  22824. : current{init} {}
  22825. /**
  22826. * @brief Pre-increment operator.
  22827. * @return This iota iterator.
  22828. */
  22829. constexpr iota_iterator &operator++() noexcept {
  22830. return ++current, *this;
  22831. }
  22832. /**
  22833. * @brief Post-increment operator.
  22834. * @return This iota iterator.
  22835. */
  22836. constexpr iota_iterator operator++(int) noexcept {
  22837. const iota_iterator orig = *this;
  22838. return ++(*this), orig;
  22839. }
  22840. /**
  22841. * @brief Dereference operator.
  22842. * @return The underlying value.
  22843. */
  22844. [[nodiscard]] constexpr reference operator*() const noexcept {
  22845. return current;
  22846. }
  22847. private:
  22848. value_type current;
  22849. };
  22850. /**
  22851. * @brief Comparison operator.
  22852. * @tparam Type Value type of the iota iterator.
  22853. * @param lhs A properly initialized iota iterator.
  22854. * @param rhs A properly initialized iota iterator.
  22855. * @return True if the two iterators are identical, false otherwise.
  22856. */
  22857. template<typename Type>
  22858. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  22859. return *lhs == *rhs;
  22860. }
  22861. /**
  22862. * @brief Comparison operator.
  22863. * @tparam Type Value type of the iota iterator.
  22864. * @param lhs A properly initialized iota iterator.
  22865. * @param rhs A properly initialized iota iterator.
  22866. * @return True if the two iterators differ, false otherwise.
  22867. */
  22868. template<typename Type>
  22869. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  22870. return !(lhs == rhs);
  22871. }
  22872. /**
  22873. * @brief Utility class to create an iterable object from a pair of iterators.
  22874. * @tparam It Type of iterator.
  22875. * @tparam Sentinel Type of sentinel.
  22876. */
  22877. template<typename It, typename Sentinel = It>
  22878. struct iterable_adaptor final {
  22879. /*! @brief Value type. */
  22880. using value_type = typename std::iterator_traits<It>::value_type;
  22881. /*! @brief Iterator type. */
  22882. using iterator = It;
  22883. /*! @brief Sentinel type. */
  22884. using sentinel = Sentinel;
  22885. /*! @brief Default constructor. */
  22886. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  22887. : first{},
  22888. last{} {}
  22889. /**
  22890. * @brief Creates an iterable object from a pair of iterators.
  22891. * @param from Begin iterator.
  22892. * @param to End iterator.
  22893. */
  22894. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  22895. : first{std::move(from)},
  22896. last{std::move(to)} {}
  22897. /**
  22898. * @brief Returns an iterator to the beginning.
  22899. * @return An iterator to the first element of the range.
  22900. */
  22901. [[nodiscard]] constexpr iterator begin() const noexcept {
  22902. return first;
  22903. }
  22904. /**
  22905. * @brief Returns an iterator to the end.
  22906. * @return An iterator to the element following the last element of the
  22907. * range.
  22908. */
  22909. [[nodiscard]] constexpr sentinel end() const noexcept {
  22910. return last;
  22911. }
  22912. /*! @copydoc begin */
  22913. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  22914. return begin();
  22915. }
  22916. /*! @copydoc end */
  22917. [[nodiscard]] constexpr sentinel cend() const noexcept {
  22918. return end();
  22919. }
  22920. private:
  22921. It first;
  22922. Sentinel last;
  22923. };
  22924. } // namespace entt
  22925. #endif
  22926. // #include "fwd.hpp"
  22927. #ifndef ENTT_GRAPH_FWD_HPP
  22928. #define ENTT_GRAPH_FWD_HPP
  22929. #include <cstddef>
  22930. #include <memory>
  22931. // #include "../core/fwd.hpp"
  22932. #ifndef ENTT_CORE_FWD_HPP
  22933. #define ENTT_CORE_FWD_HPP
  22934. #include <cstddef>
  22935. #include <cstdint>
  22936. // #include "../config/config.h"
  22937. #ifndef ENTT_CONFIG_CONFIG_H
  22938. #define ENTT_CONFIG_CONFIG_H
  22939. // #include "version.h"
  22940. #ifndef ENTT_CONFIG_VERSION_H
  22941. #define ENTT_CONFIG_VERSION_H
  22942. // #include "macro.h"
  22943. #ifndef ENTT_CONFIG_MACRO_H
  22944. #define ENTT_CONFIG_MACRO_H
  22945. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  22946. #define ENTT_STR(arg) #arg
  22947. #define ENTT_XSTR(arg) ENTT_STR(arg)
  22948. // NOLINTEND(cppcoreguidelines-macro-usage)
  22949. #endif
  22950. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  22951. #define ENTT_VERSION_MAJOR 3
  22952. #define ENTT_VERSION_MINOR 16
  22953. #define ENTT_VERSION_PATCH 0
  22954. #define ENTT_VERSION \
  22955. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  22956. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  22957. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  22958. #endif
  22959. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  22960. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  22961. # define ENTT_CONSTEXPR
  22962. # define ENTT_THROW throw
  22963. # define ENTT_TRY try
  22964. # define ENTT_CATCH catch(...)
  22965. #else
  22966. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  22967. # define ENTT_THROW
  22968. # define ENTT_TRY if(true)
  22969. # define ENTT_CATCH if(false)
  22970. #endif
  22971. #if __has_include(<version>)
  22972. # include <version>
  22973. #
  22974. # if defined(__cpp_consteval)
  22975. # define ENTT_CONSTEVAL consteval
  22976. # endif
  22977. #endif
  22978. #ifndef ENTT_CONSTEVAL
  22979. # define ENTT_CONSTEVAL constexpr
  22980. #endif
  22981. #ifdef ENTT_USE_ATOMIC
  22982. # include <atomic>
  22983. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  22984. #else
  22985. # define ENTT_MAYBE_ATOMIC(Type) Type
  22986. #endif
  22987. #ifndef ENTT_ID_TYPE
  22988. # include <cstdint>
  22989. # define ENTT_ID_TYPE std::uint32_t
  22990. #else
  22991. # include <cstdint> // provides coverage for types in the std namespace
  22992. #endif
  22993. #ifndef ENTT_SPARSE_PAGE
  22994. # define ENTT_SPARSE_PAGE 4096
  22995. #endif
  22996. #ifndef ENTT_PACKED_PAGE
  22997. # define ENTT_PACKED_PAGE 1024
  22998. #endif
  22999. #ifdef ENTT_DISABLE_ASSERT
  23000. # undef ENTT_ASSERT
  23001. # define ENTT_ASSERT(condition, msg) (void(0))
  23002. #elif !defined ENTT_ASSERT
  23003. # include <cassert>
  23004. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  23005. #endif
  23006. #ifdef ENTT_DISABLE_ASSERT
  23007. # undef ENTT_ASSERT_CONSTEXPR
  23008. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  23009. #elif !defined ENTT_ASSERT_CONSTEXPR
  23010. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  23011. #endif
  23012. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  23013. #ifdef ENTT_NO_ETO
  23014. # define ENTT_ETO_TYPE(Type) void
  23015. #else
  23016. # define ENTT_ETO_TYPE(Type) Type
  23017. #endif
  23018. #ifdef ENTT_NO_MIXIN
  23019. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  23020. #else
  23021. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  23022. #endif
  23023. #ifdef ENTT_STANDARD_CPP
  23024. # define ENTT_NONSTD false
  23025. #else
  23026. # define ENTT_NONSTD true
  23027. # if defined __clang__ || defined __GNUC__
  23028. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  23029. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  23030. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  23031. # elif defined _MSC_VER
  23032. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  23033. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  23034. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  23035. # endif
  23036. #endif
  23037. #ifndef ENTT_EXPORT
  23038. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  23039. # define ENTT_EXPORT __declspec(dllexport)
  23040. # define ENTT_IMPORT __declspec(dllimport)
  23041. # define ENTT_HIDDEN
  23042. # elif defined __GNUC__ && __GNUC__ >= 4
  23043. # define ENTT_EXPORT __attribute__((visibility("default")))
  23044. # define ENTT_IMPORT __attribute__((visibility("default")))
  23045. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  23046. # else /* Unsupported compiler */
  23047. # define ENTT_EXPORT
  23048. # define ENTT_IMPORT
  23049. # define ENTT_HIDDEN
  23050. # endif
  23051. #endif
  23052. #ifndef ENTT_API
  23053. # if defined ENTT_API_EXPORT
  23054. # define ENTT_API ENTT_EXPORT
  23055. # elif defined ENTT_API_IMPORT
  23056. # define ENTT_API ENTT_IMPORT
  23057. # else /* No API */
  23058. # define ENTT_API
  23059. # endif
  23060. #endif
  23061. #if defined _MSC_VER
  23062. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  23063. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  23064. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  23065. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  23066. #endif
  23067. // NOLINTEND(cppcoreguidelines-macro-usage)
  23068. #endif
  23069. namespace entt {
  23070. /*! @brief Possible modes of an any object. */
  23071. enum class any_policy : std::uint8_t {
  23072. /*! @brief Default mode, no element available. */
  23073. empty,
  23074. /*! @brief Owning mode, dynamically allocated element. */
  23075. dynamic,
  23076. /*! @brief Owning mode, embedded element. */
  23077. embedded,
  23078. /*! @brief Aliasing mode, non-const reference. */
  23079. ref,
  23080. /*! @brief Const aliasing mode, const reference. */
  23081. cref
  23082. };
  23083. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  23084. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  23085. class basic_any;
  23086. /*! @brief Alias declaration for type identifiers. */
  23087. using id_type = ENTT_ID_TYPE;
  23088. /*! @brief Alias declaration for the most common use case. */
  23089. using any = basic_any<>;
  23090. template<typename, typename>
  23091. class compressed_pair;
  23092. template<typename>
  23093. class basic_hashed_string;
  23094. /*! @brief Aliases for common character types. */
  23095. using hashed_string = basic_hashed_string<char>;
  23096. /*! @brief Aliases for common character types. */
  23097. using hashed_wstring = basic_hashed_string<wchar_t>;
  23098. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  23099. struct type_info;
  23100. } // namespace entt
  23101. #endif
  23102. namespace entt {
  23103. /*! @brief Undirected graph category tag. */
  23104. struct directed_tag {};
  23105. /*! @brief Directed graph category tag. */
  23106. struct undirected_tag: directed_tag {};
  23107. template<typename, typename = std::allocator<std::size_t>>
  23108. class adjacency_matrix;
  23109. template<typename = std::allocator<id_type>>
  23110. class basic_flow;
  23111. /*! @brief Alias declaration for the most common use case. */
  23112. using flow = basic_flow<>;
  23113. } // namespace entt
  23114. #endif
  23115. namespace entt {
  23116. /*! @cond TURN_OFF_DOXYGEN */
  23117. namespace internal {
  23118. template<typename It>
  23119. class edge_iterator {
  23120. using size_type = std::size_t;
  23121. void find_next() noexcept {
  23122. for(; pos != last && !it[static_cast<typename It::difference_type>(pos)]; pos += offset) {}
  23123. }
  23124. public:
  23125. using value_type = std::pair<size_type, size_type>;
  23126. using pointer = input_iterator_pointer<value_type>;
  23127. using reference = value_type;
  23128. using difference_type = std::ptrdiff_t;
  23129. using iterator_category = std::input_iterator_tag;
  23130. using iterator_concept = std::forward_iterator_tag;
  23131. constexpr edge_iterator() noexcept = default;
  23132. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
  23133. constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept
  23134. : it{std::move(base)},
  23135. vert{vertices},
  23136. pos{from},
  23137. last{to},
  23138. offset{step} {
  23139. find_next();
  23140. }
  23141. constexpr edge_iterator &operator++() noexcept {
  23142. pos += offset;
  23143. find_next();
  23144. return *this;
  23145. }
  23146. constexpr edge_iterator operator++(int) noexcept {
  23147. const edge_iterator orig = *this;
  23148. return ++(*this), orig;
  23149. }
  23150. [[nodiscard]] constexpr reference operator*() const noexcept {
  23151. return *operator->();
  23152. }
  23153. [[nodiscard]] constexpr pointer operator->() const noexcept {
  23154. return std::make_pair<size_type>(pos / vert, pos % vert);
  23155. }
  23156. template<typename Type>
  23157. friend constexpr bool operator==(const edge_iterator<Type> &, const edge_iterator<Type> &) noexcept;
  23158. private:
  23159. It it{};
  23160. size_type vert{};
  23161. size_type pos{};
  23162. size_type last{};
  23163. size_type offset{};
  23164. };
  23165. template<typename Container>
  23166. [[nodiscard]] constexpr bool operator==(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  23167. return lhs.pos == rhs.pos;
  23168. }
  23169. template<typename Container>
  23170. [[nodiscard]] constexpr bool operator!=(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  23171. return !(lhs == rhs);
  23172. }
  23173. } // namespace internal
  23174. /*! @endcond */
  23175. /**
  23176. * @brief Basic implementation of a directed adjacency matrix.
  23177. * @tparam Category Either a directed or undirected category tag.
  23178. * @tparam Allocator Type of allocator used to manage memory and elements.
  23179. */
  23180. template<typename Category, typename Allocator>
  23181. class adjacency_matrix {
  23182. using alloc_traits = std::allocator_traits<Allocator>;
  23183. static_assert(std::is_base_of_v<directed_tag, Category>, "Invalid graph category");
  23184. static_assert(std::is_same_v<typename alloc_traits::value_type, std::size_t>, "Invalid value type");
  23185. using container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  23186. public:
  23187. /*! @brief Allocator type. */
  23188. using allocator_type = Allocator;
  23189. /*! @brief Unsigned integer type. */
  23190. using size_type = std::size_t;
  23191. /*! @brief Vertex type. */
  23192. using vertex_type = size_type;
  23193. /*! @brief Edge type. */
  23194. using edge_type = std::pair<vertex_type, vertex_type>;
  23195. /*! @brief Vertex iterator type. */
  23196. using vertex_iterator = iota_iterator<vertex_type>;
  23197. /*! @brief Edge iterator type. */
  23198. using edge_iterator = internal::edge_iterator<typename container_type::const_iterator>;
  23199. /*! @brief Out-edge iterator type. */
  23200. using out_edge_iterator = edge_iterator;
  23201. /*! @brief In-edge iterator type. */
  23202. using in_edge_iterator = edge_iterator;
  23203. /*! @brief Graph category tag. */
  23204. using graph_category = Category;
  23205. /*! @brief Default constructor. */
  23206. adjacency_matrix() noexcept(noexcept(allocator_type{}))
  23207. : adjacency_matrix{0u} {
  23208. }
  23209. /**
  23210. * @brief Constructs an empty container with a given allocator.
  23211. * @param allocator The allocator to use.
  23212. */
  23213. explicit adjacency_matrix(const allocator_type &allocator) noexcept
  23214. : adjacency_matrix{0u, allocator} {}
  23215. /**
  23216. * @brief Constructs an empty container with a given allocator and user
  23217. * supplied number of vertices.
  23218. * @param vertices Number of vertices.
  23219. * @param allocator The allocator to use.
  23220. */
  23221. adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{})
  23222. : matrix{vertices * vertices, allocator},
  23223. vert{vertices} {}
  23224. /*! @brief Default copy constructor. */
  23225. adjacency_matrix(const adjacency_matrix &) = default;
  23226. /**
  23227. * @brief Allocator-extended copy constructor.
  23228. * @param other The instance to copy from.
  23229. * @param allocator The allocator to use.
  23230. */
  23231. adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator)
  23232. : matrix{other.matrix, allocator},
  23233. vert{other.vert} {}
  23234. /*! @brief Default move constructor. */
  23235. adjacency_matrix(adjacency_matrix &&) noexcept = default;
  23236. /**
  23237. * @brief Allocator-extended move constructor.
  23238. * @param other The instance to move from.
  23239. * @param allocator The allocator to use.
  23240. */
  23241. adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator)
  23242. : matrix{std::move(other.matrix), allocator},
  23243. vert{other.vert} {}
  23244. /*! @brief Default destructor. */
  23245. ~adjacency_matrix() = default;
  23246. /**
  23247. * @brief Default copy assignment operator.
  23248. * @return This container.
  23249. */
  23250. adjacency_matrix &operator=(const adjacency_matrix &) = default;
  23251. /**
  23252. * @brief Default move assignment operator.
  23253. * @return This container.
  23254. */
  23255. adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default;
  23256. /**
  23257. * @brief Exchanges the contents with those of a given adjacency matrix.
  23258. * @param other Adjacency matrix to exchange the content with.
  23259. */
  23260. void swap(adjacency_matrix &other) noexcept {
  23261. using std::swap;
  23262. swap(matrix, other.matrix);
  23263. swap(vert, other.vert);
  23264. }
  23265. /**
  23266. * @brief Returns the associated allocator.
  23267. * @return The associated allocator.
  23268. */
  23269. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  23270. return matrix.get_allocator();
  23271. }
  23272. /*! @brief Clears the adjacency matrix. */
  23273. void clear() noexcept {
  23274. matrix.clear();
  23275. vert = {};
  23276. }
  23277. /**
  23278. * @brief Returns true if an adjacency matrix is empty, false otherwise.
  23279. *
  23280. * @warning
  23281. * Potentially expensive, try to avoid it on hot paths.
  23282. *
  23283. * @return True if the adjacency matrix is empty, false otherwise.
  23284. */
  23285. [[nodiscard]] bool empty() const noexcept {
  23286. const auto iterable = edges();
  23287. return (iterable.begin() == iterable.end());
  23288. }
  23289. /**
  23290. * @brief Returns the number of vertices.
  23291. * @return The number of vertices.
  23292. */
  23293. [[nodiscard]] size_type size() const noexcept {
  23294. return vert;
  23295. }
  23296. /**
  23297. * @brief Returns an iterable object to visit all vertices of a matrix.
  23298. * @return An iterable object to visit all vertices of a matrix.
  23299. */
  23300. [[nodiscard]] iterable_adaptor<vertex_iterator> vertices() const noexcept {
  23301. return {0u, vert};
  23302. }
  23303. /**
  23304. * @brief Returns an iterable object to visit all edges of a matrix.
  23305. * @return An iterable object to visit all edges of a matrix.
  23306. */
  23307. [[nodiscard]] iterable_adaptor<edge_iterator> edges() const noexcept {
  23308. const auto it = matrix.cbegin();
  23309. const auto sz = matrix.size();
  23310. return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}};
  23311. }
  23312. /**
  23313. * @brief Returns an iterable object to visit all out-edges of a vertex.
  23314. * @param vertex The vertex of which to return all out-edges.
  23315. * @return An iterable object to visit all out-edges of a vertex.
  23316. */
  23317. [[nodiscard]] iterable_adaptor<out_edge_iterator> out_edges(const vertex_type vertex) const noexcept {
  23318. const auto it = matrix.cbegin();
  23319. const auto from = vertex * vert;
  23320. const auto to = from + vert;
  23321. return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}};
  23322. }
  23323. /**
  23324. * @brief Returns an iterable object to visit all in-edges of a vertex.
  23325. * @param vertex The vertex of which to return all in-edges.
  23326. * @return An iterable object to visit all in-edges of a vertex.
  23327. */
  23328. [[nodiscard]] iterable_adaptor<in_edge_iterator> in_edges(const vertex_type vertex) const noexcept {
  23329. const auto it = matrix.cbegin();
  23330. const auto from = vertex;
  23331. const auto to = vert * vert + from;
  23332. return {{it, vert, from, to, vert}, {it, vert, to, to, vert}};
  23333. }
  23334. /**
  23335. * @brief Resizes an adjacency matrix.
  23336. * @param vertices The new number of vertices.
  23337. */
  23338. void resize(const size_type vertices) {
  23339. adjacency_matrix other{vertices, get_allocator()};
  23340. for(auto [lhs, rhs]: edges()) {
  23341. other.insert(lhs, rhs);
  23342. }
  23343. other.swap(*this);
  23344. }
  23345. /**
  23346. * @brief Inserts an edge into the adjacency matrix, if it does not exist.
  23347. * @param lhs The left hand vertex of the edge.
  23348. * @param rhs The right hand vertex of the edge.
  23349. * @return A pair consisting of an iterator to the inserted element (or to
  23350. * the element that prevented the insertion) and a bool denoting whether the
  23351. * insertion took place.
  23352. */
  23353. std::pair<edge_iterator, bool> insert(const vertex_type lhs, const vertex_type rhs) {
  23354. const auto pos = lhs * vert + rhs;
  23355. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  23356. const auto rev = rhs * vert + lhs;
  23357. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  23358. matrix[rev] = 1u;
  23359. }
  23360. const auto inserted = !std::exchange(matrix[pos], 1u);
  23361. return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted};
  23362. }
  23363. /**
  23364. * @brief Removes the edge associated with a pair of given vertices.
  23365. * @param lhs The left hand vertex of the edge.
  23366. * @param rhs The right hand vertex of the edge.
  23367. * @return Number of elements removed (either 0 or 1).
  23368. */
  23369. size_type erase(const vertex_type lhs, const vertex_type rhs) {
  23370. const auto pos = lhs * vert + rhs;
  23371. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  23372. const auto rev = rhs * vert + lhs;
  23373. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  23374. matrix[rev] = 0u;
  23375. }
  23376. return std::exchange(matrix[pos], 0u);
  23377. }
  23378. /**
  23379. * @brief Checks if an adjacency matrix contains a given edge.
  23380. * @param lhs The left hand vertex of the edge.
  23381. * @param rhs The right hand vertex of the edge.
  23382. * @return True if there is such an edge, false otherwise.
  23383. */
  23384. [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const {
  23385. const auto pos = lhs * vert + rhs;
  23386. return pos < matrix.size() && matrix[pos];
  23387. }
  23388. private:
  23389. container_type matrix;
  23390. size_type vert;
  23391. };
  23392. } // namespace entt
  23393. #endif
  23394. // #include "../graph/flow.hpp"
  23395. #ifndef ENTT_GRAPH_FLOW_HPP
  23396. #define ENTT_GRAPH_FLOW_HPP
  23397. #include <algorithm>
  23398. #include <cstddef>
  23399. #include <functional>
  23400. #include <iterator>
  23401. #include <memory>
  23402. #include <type_traits>
  23403. #include <utility>
  23404. #include <vector>
  23405. // #include "../config/config.h"
  23406. // #include "../container/dense_map.hpp"
  23407. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  23408. #define ENTT_CONTAINER_DENSE_MAP_HPP
  23409. #include <cmath>
  23410. #include <cstddef>
  23411. #include <functional>
  23412. #include <iterator>
  23413. #include <limits>
  23414. #include <memory>
  23415. #include <tuple>
  23416. #include <type_traits>
  23417. #include <utility>
  23418. #include <vector>
  23419. // #include "../config/config.h"
  23420. #ifndef ENTT_CONFIG_CONFIG_H
  23421. #define ENTT_CONFIG_CONFIG_H
  23422. // #include "version.h"
  23423. #ifndef ENTT_CONFIG_VERSION_H
  23424. #define ENTT_CONFIG_VERSION_H
  23425. // #include "macro.h"
  23426. #ifndef ENTT_CONFIG_MACRO_H
  23427. #define ENTT_CONFIG_MACRO_H
  23428. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  23429. #define ENTT_STR(arg) #arg
  23430. #define ENTT_XSTR(arg) ENTT_STR(arg)
  23431. // NOLINTEND(cppcoreguidelines-macro-usage)
  23432. #endif
  23433. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  23434. #define ENTT_VERSION_MAJOR 3
  23435. #define ENTT_VERSION_MINOR 16
  23436. #define ENTT_VERSION_PATCH 0
  23437. #define ENTT_VERSION \
  23438. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  23439. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  23440. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  23441. #endif
  23442. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  23443. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  23444. # define ENTT_CONSTEXPR
  23445. # define ENTT_THROW throw
  23446. # define ENTT_TRY try
  23447. # define ENTT_CATCH catch(...)
  23448. #else
  23449. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  23450. # define ENTT_THROW
  23451. # define ENTT_TRY if(true)
  23452. # define ENTT_CATCH if(false)
  23453. #endif
  23454. #if __has_include(<version>)
  23455. # include <version>
  23456. #
  23457. # if defined(__cpp_consteval)
  23458. # define ENTT_CONSTEVAL consteval
  23459. # endif
  23460. #endif
  23461. #ifndef ENTT_CONSTEVAL
  23462. # define ENTT_CONSTEVAL constexpr
  23463. #endif
  23464. #ifdef ENTT_USE_ATOMIC
  23465. # include <atomic>
  23466. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  23467. #else
  23468. # define ENTT_MAYBE_ATOMIC(Type) Type
  23469. #endif
  23470. #ifndef ENTT_ID_TYPE
  23471. # include <cstdint>
  23472. # define ENTT_ID_TYPE std::uint32_t
  23473. #else
  23474. # include <cstdint> // provides coverage for types in the std namespace
  23475. #endif
  23476. #ifndef ENTT_SPARSE_PAGE
  23477. # define ENTT_SPARSE_PAGE 4096
  23478. #endif
  23479. #ifndef ENTT_PACKED_PAGE
  23480. # define ENTT_PACKED_PAGE 1024
  23481. #endif
  23482. #ifdef ENTT_DISABLE_ASSERT
  23483. # undef ENTT_ASSERT
  23484. # define ENTT_ASSERT(condition, msg) (void(0))
  23485. #elif !defined ENTT_ASSERT
  23486. # include <cassert>
  23487. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  23488. #endif
  23489. #ifdef ENTT_DISABLE_ASSERT
  23490. # undef ENTT_ASSERT_CONSTEXPR
  23491. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  23492. #elif !defined ENTT_ASSERT_CONSTEXPR
  23493. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  23494. #endif
  23495. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  23496. #ifdef ENTT_NO_ETO
  23497. # define ENTT_ETO_TYPE(Type) void
  23498. #else
  23499. # define ENTT_ETO_TYPE(Type) Type
  23500. #endif
  23501. #ifdef ENTT_NO_MIXIN
  23502. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  23503. #else
  23504. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  23505. #endif
  23506. #ifdef ENTT_STANDARD_CPP
  23507. # define ENTT_NONSTD false
  23508. #else
  23509. # define ENTT_NONSTD true
  23510. # if defined __clang__ || defined __GNUC__
  23511. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  23512. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  23513. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  23514. # elif defined _MSC_VER
  23515. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  23516. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  23517. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  23518. # endif
  23519. #endif
  23520. #ifndef ENTT_EXPORT
  23521. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  23522. # define ENTT_EXPORT __declspec(dllexport)
  23523. # define ENTT_IMPORT __declspec(dllimport)
  23524. # define ENTT_HIDDEN
  23525. # elif defined __GNUC__ && __GNUC__ >= 4
  23526. # define ENTT_EXPORT __attribute__((visibility("default")))
  23527. # define ENTT_IMPORT __attribute__((visibility("default")))
  23528. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  23529. # else /* Unsupported compiler */
  23530. # define ENTT_EXPORT
  23531. # define ENTT_IMPORT
  23532. # define ENTT_HIDDEN
  23533. # endif
  23534. #endif
  23535. #ifndef ENTT_API
  23536. # if defined ENTT_API_EXPORT
  23537. # define ENTT_API ENTT_EXPORT
  23538. # elif defined ENTT_API_IMPORT
  23539. # define ENTT_API ENTT_IMPORT
  23540. # else /* No API */
  23541. # define ENTT_API
  23542. # endif
  23543. #endif
  23544. #if defined _MSC_VER
  23545. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  23546. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  23547. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  23548. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  23549. #endif
  23550. // NOLINTEND(cppcoreguidelines-macro-usage)
  23551. #endif
  23552. // #include "../core/bit.hpp"
  23553. #ifndef ENTT_CORE_BIT_HPP
  23554. #define ENTT_CORE_BIT_HPP
  23555. #include <cstddef>
  23556. #include <limits>
  23557. #include <type_traits>
  23558. // #include "../config/config.h"
  23559. #ifndef ENTT_CONFIG_CONFIG_H
  23560. #define ENTT_CONFIG_CONFIG_H
  23561. // #include "version.h"
  23562. #ifndef ENTT_CONFIG_VERSION_H
  23563. #define ENTT_CONFIG_VERSION_H
  23564. // #include "macro.h"
  23565. #ifndef ENTT_CONFIG_MACRO_H
  23566. #define ENTT_CONFIG_MACRO_H
  23567. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  23568. #define ENTT_STR(arg) #arg
  23569. #define ENTT_XSTR(arg) ENTT_STR(arg)
  23570. // NOLINTEND(cppcoreguidelines-macro-usage)
  23571. #endif
  23572. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  23573. #define ENTT_VERSION_MAJOR 3
  23574. #define ENTT_VERSION_MINOR 16
  23575. #define ENTT_VERSION_PATCH 0
  23576. #define ENTT_VERSION \
  23577. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  23578. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  23579. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  23580. #endif
  23581. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  23582. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  23583. # define ENTT_CONSTEXPR
  23584. # define ENTT_THROW throw
  23585. # define ENTT_TRY try
  23586. # define ENTT_CATCH catch(...)
  23587. #else
  23588. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  23589. # define ENTT_THROW
  23590. # define ENTT_TRY if(true)
  23591. # define ENTT_CATCH if(false)
  23592. #endif
  23593. #if __has_include(<version>)
  23594. # include <version>
  23595. #
  23596. # if defined(__cpp_consteval)
  23597. # define ENTT_CONSTEVAL consteval
  23598. # endif
  23599. #endif
  23600. #ifndef ENTT_CONSTEVAL
  23601. # define ENTT_CONSTEVAL constexpr
  23602. #endif
  23603. #ifdef ENTT_USE_ATOMIC
  23604. # include <atomic>
  23605. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  23606. #else
  23607. # define ENTT_MAYBE_ATOMIC(Type) Type
  23608. #endif
  23609. #ifndef ENTT_ID_TYPE
  23610. # include <cstdint>
  23611. # define ENTT_ID_TYPE std::uint32_t
  23612. #else
  23613. # include <cstdint> // provides coverage for types in the std namespace
  23614. #endif
  23615. #ifndef ENTT_SPARSE_PAGE
  23616. # define ENTT_SPARSE_PAGE 4096
  23617. #endif
  23618. #ifndef ENTT_PACKED_PAGE
  23619. # define ENTT_PACKED_PAGE 1024
  23620. #endif
  23621. #ifdef ENTT_DISABLE_ASSERT
  23622. # undef ENTT_ASSERT
  23623. # define ENTT_ASSERT(condition, msg) (void(0))
  23624. #elif !defined ENTT_ASSERT
  23625. # include <cassert>
  23626. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  23627. #endif
  23628. #ifdef ENTT_DISABLE_ASSERT
  23629. # undef ENTT_ASSERT_CONSTEXPR
  23630. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  23631. #elif !defined ENTT_ASSERT_CONSTEXPR
  23632. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  23633. #endif
  23634. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  23635. #ifdef ENTT_NO_ETO
  23636. # define ENTT_ETO_TYPE(Type) void
  23637. #else
  23638. # define ENTT_ETO_TYPE(Type) Type
  23639. #endif
  23640. #ifdef ENTT_NO_MIXIN
  23641. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  23642. #else
  23643. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  23644. #endif
  23645. #ifdef ENTT_STANDARD_CPP
  23646. # define ENTT_NONSTD false
  23647. #else
  23648. # define ENTT_NONSTD true
  23649. # if defined __clang__ || defined __GNUC__
  23650. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  23651. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  23652. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  23653. # elif defined _MSC_VER
  23654. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  23655. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  23656. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  23657. # endif
  23658. #endif
  23659. #ifndef ENTT_EXPORT
  23660. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  23661. # define ENTT_EXPORT __declspec(dllexport)
  23662. # define ENTT_IMPORT __declspec(dllimport)
  23663. # define ENTT_HIDDEN
  23664. # elif defined __GNUC__ && __GNUC__ >= 4
  23665. # define ENTT_EXPORT __attribute__((visibility("default")))
  23666. # define ENTT_IMPORT __attribute__((visibility("default")))
  23667. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  23668. # else /* Unsupported compiler */
  23669. # define ENTT_EXPORT
  23670. # define ENTT_IMPORT
  23671. # define ENTT_HIDDEN
  23672. # endif
  23673. #endif
  23674. #ifndef ENTT_API
  23675. # if defined ENTT_API_EXPORT
  23676. # define ENTT_API ENTT_EXPORT
  23677. # elif defined ENTT_API_IMPORT
  23678. # define ENTT_API ENTT_IMPORT
  23679. # else /* No API */
  23680. # define ENTT_API
  23681. # endif
  23682. #endif
  23683. #if defined _MSC_VER
  23684. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  23685. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  23686. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  23687. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  23688. #endif
  23689. // NOLINTEND(cppcoreguidelines-macro-usage)
  23690. #endif
  23691. namespace entt {
  23692. /**
  23693. * @brief Returns the number of set bits in a value (waiting for C++20 and
  23694. * `std::popcount`).
  23695. * @tparam Type Unsigned integer type.
  23696. * @param value A value of unsigned integer type.
  23697. * @return The number of set bits in the value.
  23698. */
  23699. template<typename Type>
  23700. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  23701. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  23702. }
  23703. /**
  23704. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  23705. * `std::has_single_bit`).
  23706. * @tparam Type Unsigned integer type.
  23707. * @param value A value of unsigned integer type.
  23708. * @return True if the value is a power of two, false otherwise.
  23709. */
  23710. template<typename Type>
  23711. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  23712. return value && ((value & (value - 1)) == 0);
  23713. }
  23714. /**
  23715. * @brief Computes the smallest power of two greater than or equal to a value
  23716. * (waiting for C++20 and `std::bit_ceil`).
  23717. * @tparam Type Unsigned integer type.
  23718. * @param value A value of unsigned integer type.
  23719. * @return The smallest power of two greater than or equal to the given value.
  23720. */
  23721. template<typename Type>
  23722. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  23723. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  23724. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  23725. Type curr = value - (value != 0u);
  23726. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  23727. curr |= (curr >> next);
  23728. }
  23729. return ++curr;
  23730. }
  23731. /**
  23732. * @brief Fast module utility function (powers of two only).
  23733. * @tparam Type Unsigned integer type.
  23734. * @param value A value of unsigned integer type.
  23735. * @param mod _Modulus_, it must be a power of two.
  23736. * @return The common remainder.
  23737. */
  23738. template<typename Type>
  23739. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  23740. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  23741. return static_cast<Type>(value & (mod - 1u));
  23742. }
  23743. } // namespace entt
  23744. #endif
  23745. // #include "../core/compressed_pair.hpp"
  23746. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  23747. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  23748. #include <cstddef>
  23749. #include <tuple>
  23750. #include <type_traits>
  23751. #include <utility>
  23752. // #include "fwd.hpp"
  23753. #ifndef ENTT_CORE_FWD_HPP
  23754. #define ENTT_CORE_FWD_HPP
  23755. #include <cstddef>
  23756. #include <cstdint>
  23757. // #include "../config/config.h"
  23758. namespace entt {
  23759. /*! @brief Possible modes of an any object. */
  23760. enum class any_policy : std::uint8_t {
  23761. /*! @brief Default mode, no element available. */
  23762. empty,
  23763. /*! @brief Owning mode, dynamically allocated element. */
  23764. dynamic,
  23765. /*! @brief Owning mode, embedded element. */
  23766. embedded,
  23767. /*! @brief Aliasing mode, non-const reference. */
  23768. ref,
  23769. /*! @brief Const aliasing mode, const reference. */
  23770. cref
  23771. };
  23772. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  23773. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  23774. class basic_any;
  23775. /*! @brief Alias declaration for type identifiers. */
  23776. using id_type = ENTT_ID_TYPE;
  23777. /*! @brief Alias declaration for the most common use case. */
  23778. using any = basic_any<>;
  23779. template<typename, typename>
  23780. class compressed_pair;
  23781. template<typename>
  23782. class basic_hashed_string;
  23783. /*! @brief Aliases for common character types. */
  23784. using hashed_string = basic_hashed_string<char>;
  23785. /*! @brief Aliases for common character types. */
  23786. using hashed_wstring = basic_hashed_string<wchar_t>;
  23787. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  23788. struct type_info;
  23789. } // namespace entt
  23790. #endif
  23791. // #include "type_traits.hpp"
  23792. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  23793. #define ENTT_CORE_TYPE_TRAITS_HPP
  23794. #include <cstddef>
  23795. #include <iterator>
  23796. #include <tuple>
  23797. #include <type_traits>
  23798. #include <utility>
  23799. // #include "../config/config.h"
  23800. // #include "fwd.hpp"
  23801. namespace entt {
  23802. /**
  23803. * @brief Utility class to disambiguate overloaded functions.
  23804. * @tparam N Number of choices available.
  23805. */
  23806. template<std::size_t N>
  23807. struct choice_t
  23808. // unfortunately, doxygen cannot parse such a construct
  23809. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  23810. {};
  23811. /*! @copybrief choice_t */
  23812. template<>
  23813. struct choice_t<0> {};
  23814. /**
  23815. * @brief Variable template for the choice trick.
  23816. * @tparam N Number of choices available.
  23817. */
  23818. template<std::size_t N>
  23819. inline constexpr choice_t<N> choice{};
  23820. /**
  23821. * @brief Identity type trait.
  23822. *
  23823. * Useful to establish non-deduced contexts in template argument deduction
  23824. * (waiting for C++20) or to provide types through function arguments.
  23825. *
  23826. * @tparam Type A type.
  23827. */
  23828. template<typename Type>
  23829. struct type_identity {
  23830. /*! @brief Identity type. */
  23831. using type = Type;
  23832. };
  23833. /**
  23834. * @brief Helper type.
  23835. * @tparam Type A type.
  23836. */
  23837. template<typename Type>
  23838. using type_identity_t = typename type_identity<Type>::type;
  23839. /**
  23840. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  23841. * @tparam Type The type of which to return the size.
  23842. */
  23843. template<typename Type, typename = void>
  23844. struct size_of: std::integral_constant<std::size_t, 0u> {};
  23845. /*! @copydoc size_of */
  23846. template<typename Type>
  23847. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  23848. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  23849. : std::integral_constant<std::size_t, sizeof(Type)> {};
  23850. /**
  23851. * @brief Helper variable template.
  23852. * @tparam Type The type of which to return the size.
  23853. */
  23854. template<typename Type>
  23855. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  23856. /**
  23857. * @brief Using declaration to be used to _repeat_ the same type a number of
  23858. * times equal to the size of a given parameter pack.
  23859. * @tparam Type A type to repeat.
  23860. */
  23861. template<typename Type, typename>
  23862. using unpack_as_type = Type;
  23863. /**
  23864. * @brief Helper variable template to be used to _repeat_ the same value a
  23865. * number of times equal to the size of a given parameter pack.
  23866. * @tparam Value A value to repeat.
  23867. */
  23868. template<auto Value, typename>
  23869. inline constexpr auto unpack_as_value = Value;
  23870. /**
  23871. * @brief Wraps a static constant.
  23872. * @tparam Value A static constant.
  23873. */
  23874. template<auto Value>
  23875. using integral_constant = std::integral_constant<decltype(Value), Value>;
  23876. /**
  23877. * @brief Alias template to facilitate the creation of named values.
  23878. * @tparam Value A constant value at least convertible to `id_type`.
  23879. */
  23880. template<id_type Value>
  23881. using tag = integral_constant<Value>;
  23882. /**
  23883. * @brief A class to use to push around lists of types, nothing more.
  23884. * @tparam Type Types provided by the type list.
  23885. */
  23886. template<typename... Type>
  23887. struct type_list {
  23888. /*! @brief Type list type. */
  23889. using type = type_list;
  23890. /*! @brief Compile-time number of elements in the type list. */
  23891. static constexpr auto size = sizeof...(Type);
  23892. };
  23893. /*! @brief Primary template isn't defined on purpose. */
  23894. template<std::size_t, typename>
  23895. struct type_list_element;
  23896. /**
  23897. * @brief Provides compile-time indexed access to the types of a type list.
  23898. * @tparam Index Index of the type to return.
  23899. * @tparam First First type provided by the type list.
  23900. * @tparam Other Other types provided by the type list.
  23901. */
  23902. template<std::size_t Index, typename First, typename... Other>
  23903. struct type_list_element<Index, type_list<First, Other...>>
  23904. : type_list_element<Index - 1u, type_list<Other...>> {};
  23905. /**
  23906. * @brief Provides compile-time indexed access to the types of a type list.
  23907. * @tparam First First type provided by the type list.
  23908. * @tparam Other Other types provided by the type list.
  23909. */
  23910. template<typename First, typename... Other>
  23911. struct type_list_element<0u, type_list<First, Other...>> {
  23912. /*! @brief Searched type. */
  23913. using type = First;
  23914. };
  23915. /**
  23916. * @brief Helper type.
  23917. * @tparam Index Index of the type to return.
  23918. * @tparam List Type list to search into.
  23919. */
  23920. template<std::size_t Index, typename List>
  23921. using type_list_element_t = typename type_list_element<Index, List>::type;
  23922. /*! @brief Primary template isn't defined on purpose. */
  23923. template<typename, typename>
  23924. struct type_list_index;
  23925. /**
  23926. * @brief Provides compile-time type access to the types of a type list.
  23927. * @tparam Type Type to look for and for which to return the index.
  23928. * @tparam First First type provided by the type list.
  23929. * @tparam Other Other types provided by the type list.
  23930. */
  23931. template<typename Type, typename First, typename... Other>
  23932. struct type_list_index<Type, type_list<First, Other...>> {
  23933. /*! @brief Unsigned integer type. */
  23934. using value_type = std::size_t;
  23935. /*! @brief Compile-time position of the given type in the sublist. */
  23936. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  23937. };
  23938. /**
  23939. * @brief Provides compile-time type access to the types of a type list.
  23940. * @tparam Type Type to look for and for which to return the index.
  23941. * @tparam Other Other types provided by the type list.
  23942. */
  23943. template<typename Type, typename... Other>
  23944. struct type_list_index<Type, type_list<Type, Other...>> {
  23945. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  23946. /*! @brief Unsigned integer type. */
  23947. using value_type = std::size_t;
  23948. /*! @brief Compile-time position of the given type in the sublist. */
  23949. static constexpr value_type value = 0u;
  23950. };
  23951. /**
  23952. * @brief Provides compile-time type access to the types of a type list.
  23953. * @tparam Type Type to look for and for which to return the index.
  23954. */
  23955. template<typename Type>
  23956. struct type_list_index<Type, type_list<>> {
  23957. /*! @brief Unsigned integer type. */
  23958. using value_type = std::size_t;
  23959. /*! @brief Compile-time position of the given type in the sublist. */
  23960. static constexpr value_type value = 0u;
  23961. };
  23962. /**
  23963. * @brief Helper variable template.
  23964. * @tparam List Type list.
  23965. * @tparam Type Type to look for and for which to return the index.
  23966. */
  23967. template<typename Type, typename List>
  23968. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  23969. /**
  23970. * @brief Concatenates multiple type lists.
  23971. * @tparam Type Types provided by the first type list.
  23972. * @tparam Other Types provided by the second type list.
  23973. * @return A type list composed by the types of both the type lists.
  23974. */
  23975. template<typename... Type, typename... Other>
  23976. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  23977. return {};
  23978. }
  23979. /*! @brief Primary template isn't defined on purpose. */
  23980. template<typename...>
  23981. struct type_list_cat;
  23982. /*! @brief Concatenates multiple type lists. */
  23983. template<>
  23984. struct type_list_cat<> {
  23985. /*! @brief A type list composed by the types of all the type lists. */
  23986. using type = type_list<>;
  23987. };
  23988. /**
  23989. * @brief Concatenates multiple type lists.
  23990. * @tparam Type Types provided by the first type list.
  23991. * @tparam Other Types provided by the second type list.
  23992. * @tparam List Other type lists, if any.
  23993. */
  23994. template<typename... Type, typename... Other, typename... List>
  23995. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  23996. /*! @brief A type list composed by the types of all the type lists. */
  23997. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  23998. };
  23999. /**
  24000. * @brief Concatenates multiple type lists.
  24001. * @tparam Type Types provided by the type list.
  24002. */
  24003. template<typename... Type>
  24004. struct type_list_cat<type_list<Type...>> {
  24005. /*! @brief A type list composed by the types of all the type lists. */
  24006. using type = type_list<Type...>;
  24007. };
  24008. /**
  24009. * @brief Helper type.
  24010. * @tparam List Type lists to concatenate.
  24011. */
  24012. template<typename... List>
  24013. using type_list_cat_t = typename type_list_cat<List...>::type;
  24014. /*! @cond TURN_OFF_DOXYGEN */
  24015. namespace internal {
  24016. template<typename...>
  24017. struct type_list_unique;
  24018. template<typename First, typename... Other, typename... Type>
  24019. struct type_list_unique<type_list<First, Other...>, Type...>
  24020. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  24021. template<typename... Type>
  24022. struct type_list_unique<type_list<>, Type...> {
  24023. using type = type_list<Type...>;
  24024. };
  24025. } // namespace internal
  24026. /*! @endcond */
  24027. /**
  24028. * @brief Removes duplicates types from a type list.
  24029. * @tparam List Type list.
  24030. */
  24031. template<typename List>
  24032. struct type_list_unique {
  24033. /*! @brief A type list without duplicate types. */
  24034. using type = typename internal::type_list_unique<List>::type;
  24035. };
  24036. /**
  24037. * @brief Helper type.
  24038. * @tparam List Type list.
  24039. */
  24040. template<typename List>
  24041. using type_list_unique_t = typename type_list_unique<List>::type;
  24042. /**
  24043. * @brief Provides the member constant `value` to true if a type list contains a
  24044. * given type, false otherwise.
  24045. * @tparam List Type list.
  24046. * @tparam Type Type to look for.
  24047. */
  24048. template<typename List, typename Type>
  24049. struct type_list_contains;
  24050. /**
  24051. * @copybrief type_list_contains
  24052. * @tparam Type Types provided by the type list.
  24053. * @tparam Other Type to look for.
  24054. */
  24055. template<typename... Type, typename Other>
  24056. struct type_list_contains<type_list<Type...>, Other>
  24057. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  24058. /**
  24059. * @brief Helper variable template.
  24060. * @tparam List Type list.
  24061. * @tparam Type Type to look for.
  24062. */
  24063. template<typename List, typename Type>
  24064. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  24065. /*! @brief Primary template isn't defined on purpose. */
  24066. template<typename...>
  24067. struct type_list_diff;
  24068. /**
  24069. * @brief Computes the difference between two type lists.
  24070. * @tparam Type Types provided by the first type list.
  24071. * @tparam Other Types provided by the second type list.
  24072. */
  24073. template<typename... Type, typename... Other>
  24074. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  24075. /*! @brief A type list that is the difference between the two type lists. */
  24076. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  24077. };
  24078. /**
  24079. * @brief Helper type.
  24080. * @tparam List Type lists between which to compute the difference.
  24081. */
  24082. template<typename... List>
  24083. using type_list_diff_t = typename type_list_diff<List...>::type;
  24084. /*! @brief Primary template isn't defined on purpose. */
  24085. template<typename, template<typename...> class>
  24086. struct type_list_transform;
  24087. /**
  24088. * @brief Applies a given _function_ to a type list and generate a new list.
  24089. * @tparam Type Types provided by the type list.
  24090. * @tparam Op Unary operation as template class with a type member named `type`.
  24091. */
  24092. template<typename... Type, template<typename...> class Op>
  24093. struct type_list_transform<type_list<Type...>, Op> {
  24094. /*! @brief Resulting type list after applying the transform function. */
  24095. // NOLINTNEXTLINE(modernize-type-traits)
  24096. using type = type_list<typename Op<Type>::type...>;
  24097. };
  24098. /**
  24099. * @brief Helper type.
  24100. * @tparam List Type list.
  24101. * @tparam Op Unary operation as template class with a type member named `type`.
  24102. */
  24103. template<typename List, template<typename...> class Op>
  24104. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  24105. /**
  24106. * @brief A class to use to push around lists of constant values, nothing more.
  24107. * @tparam Value Values provided by the value list.
  24108. */
  24109. template<auto... Value>
  24110. struct value_list {
  24111. /*! @brief Value list type. */
  24112. using type = value_list;
  24113. /*! @brief Compile-time number of elements in the value list. */
  24114. static constexpr auto size = sizeof...(Value);
  24115. };
  24116. /*! @brief Primary template isn't defined on purpose. */
  24117. template<std::size_t, typename>
  24118. struct value_list_element;
  24119. /**
  24120. * @brief Provides compile-time indexed access to the values of a value list.
  24121. * @tparam Index Index of the value to return.
  24122. * @tparam Value First value provided by the value list.
  24123. * @tparam Other Other values provided by the value list.
  24124. */
  24125. template<std::size_t Index, auto Value, auto... Other>
  24126. struct value_list_element<Index, value_list<Value, Other...>>
  24127. : value_list_element<Index - 1u, value_list<Other...>> {};
  24128. /**
  24129. * @brief Provides compile-time indexed access to the types of a type list.
  24130. * @tparam Value First value provided by the value list.
  24131. * @tparam Other Other values provided by the value list.
  24132. */
  24133. template<auto Value, auto... Other>
  24134. struct value_list_element<0u, value_list<Value, Other...>> {
  24135. /*! @brief Searched type. */
  24136. using type = decltype(Value);
  24137. /*! @brief Searched value. */
  24138. static constexpr auto value = Value;
  24139. };
  24140. /**
  24141. * @brief Helper type.
  24142. * @tparam Index Index of the type to return.
  24143. * @tparam List Value list to search into.
  24144. */
  24145. template<std::size_t Index, typename List>
  24146. using value_list_element_t = typename value_list_element<Index, List>::type;
  24147. /**
  24148. * @brief Helper type.
  24149. * @tparam Index Index of the value to return.
  24150. * @tparam List Value list to search into.
  24151. */
  24152. template<std::size_t Index, typename List>
  24153. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  24154. /*! @brief Primary template isn't defined on purpose. */
  24155. template<auto, typename>
  24156. struct value_list_index;
  24157. /**
  24158. * @brief Provides compile-time type access to the values of a value list.
  24159. * @tparam Value Value to look for and for which to return the index.
  24160. * @tparam First First value provided by the value list.
  24161. * @tparam Other Other values provided by the value list.
  24162. */
  24163. template<auto Value, auto First, auto... Other>
  24164. struct value_list_index<Value, value_list<First, Other...>> {
  24165. /*! @brief Unsigned integer type. */
  24166. using value_type = std::size_t;
  24167. /*! @brief Compile-time position of the given value in the sublist. */
  24168. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  24169. };
  24170. /**
  24171. * @brief Provides compile-time type access to the values of a value list.
  24172. * @tparam Value Value to look for and for which to return the index.
  24173. * @tparam Other Other values provided by the value list.
  24174. */
  24175. template<auto Value, auto... Other>
  24176. struct value_list_index<Value, value_list<Value, Other...>> {
  24177. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  24178. /*! @brief Unsigned integer type. */
  24179. using value_type = std::size_t;
  24180. /*! @brief Compile-time position of the given value in the sublist. */
  24181. static constexpr value_type value = 0u;
  24182. };
  24183. /**
  24184. * @brief Provides compile-time type access to the values of a value list.
  24185. * @tparam Value Value to look for and for which to return the index.
  24186. */
  24187. template<auto Value>
  24188. struct value_list_index<Value, value_list<>> {
  24189. /*! @brief Unsigned integer type. */
  24190. using value_type = std::size_t;
  24191. /*! @brief Compile-time position of the given type in the sublist. */
  24192. static constexpr value_type value = 0u;
  24193. };
  24194. /**
  24195. * @brief Helper variable template.
  24196. * @tparam List Value list.
  24197. * @tparam Value Value to look for and for which to return the index.
  24198. */
  24199. template<auto Value, typename List>
  24200. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  24201. /**
  24202. * @brief Concatenates multiple value lists.
  24203. * @tparam Value Values provided by the first value list.
  24204. * @tparam Other Values provided by the second value list.
  24205. * @return A value list composed by the values of both the value lists.
  24206. */
  24207. template<auto... Value, auto... Other>
  24208. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  24209. return {};
  24210. }
  24211. /*! @brief Primary template isn't defined on purpose. */
  24212. template<typename...>
  24213. struct value_list_cat;
  24214. /*! @brief Concatenates multiple value lists. */
  24215. template<>
  24216. struct value_list_cat<> {
  24217. /*! @brief A value list composed by the values of all the value lists. */
  24218. using type = value_list<>;
  24219. };
  24220. /**
  24221. * @brief Concatenates multiple value lists.
  24222. * @tparam Value Values provided by the first value list.
  24223. * @tparam Other Values provided by the second value list.
  24224. * @tparam List Other value lists, if any.
  24225. */
  24226. template<auto... Value, auto... Other, typename... List>
  24227. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  24228. /*! @brief A value list composed by the values of all the value lists. */
  24229. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  24230. };
  24231. /**
  24232. * @brief Concatenates multiple value lists.
  24233. * @tparam Value Values provided by the value list.
  24234. */
  24235. template<auto... Value>
  24236. struct value_list_cat<value_list<Value...>> {
  24237. /*! @brief A value list composed by the values of all the value lists. */
  24238. using type = value_list<Value...>;
  24239. };
  24240. /**
  24241. * @brief Helper type.
  24242. * @tparam List Value lists to concatenate.
  24243. */
  24244. template<typename... List>
  24245. using value_list_cat_t = typename value_list_cat<List...>::type;
  24246. /*! @brief Primary template isn't defined on purpose. */
  24247. template<typename>
  24248. struct value_list_unique;
  24249. /**
  24250. * @brief Removes duplicates values from a value list.
  24251. * @tparam Value One of the values provided by the given value list.
  24252. * @tparam Other The other values provided by the given value list.
  24253. */
  24254. template<auto Value, auto... Other>
  24255. struct value_list_unique<value_list<Value, Other...>> {
  24256. /*! @brief A value list without duplicate types. */
  24257. using type = std::conditional_t<
  24258. ((Value == Other) || ...),
  24259. typename value_list_unique<value_list<Other...>>::type,
  24260. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  24261. };
  24262. /*! @brief Removes duplicates values from a value list. */
  24263. template<>
  24264. struct value_list_unique<value_list<>> {
  24265. /*! @brief A value list without duplicate types. */
  24266. using type = value_list<>;
  24267. };
  24268. /**
  24269. * @brief Helper type.
  24270. * @tparam Type A value list.
  24271. */
  24272. template<typename Type>
  24273. using value_list_unique_t = typename value_list_unique<Type>::type;
  24274. /**
  24275. * @brief Provides the member constant `value` to true if a value list contains
  24276. * a given value, false otherwise.
  24277. * @tparam List Value list.
  24278. * @tparam Value Value to look for.
  24279. */
  24280. template<typename List, auto Value>
  24281. struct value_list_contains;
  24282. /**
  24283. * @copybrief value_list_contains
  24284. * @tparam Value Values provided by the value list.
  24285. * @tparam Other Value to look for.
  24286. */
  24287. template<auto... Value, auto Other>
  24288. struct value_list_contains<value_list<Value...>, Other>
  24289. : std::bool_constant<((Value == Other) || ...)> {};
  24290. /**
  24291. * @brief Helper variable template.
  24292. * @tparam List Value list.
  24293. * @tparam Value Value to look for.
  24294. */
  24295. template<typename List, auto Value>
  24296. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  24297. /*! @brief Primary template isn't defined on purpose. */
  24298. template<typename...>
  24299. struct value_list_diff;
  24300. /**
  24301. * @brief Computes the difference between two value lists.
  24302. * @tparam Value Values provided by the first value list.
  24303. * @tparam Other Values provided by the second value list.
  24304. */
  24305. template<auto... Value, auto... Other>
  24306. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  24307. /*! @brief A value list that is the difference between the two value lists. */
  24308. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  24309. };
  24310. /**
  24311. * @brief Helper type.
  24312. * @tparam List Value lists between which to compute the difference.
  24313. */
  24314. template<typename... List>
  24315. using value_list_diff_t = typename value_list_diff<List...>::type;
  24316. /*! @brief Same as std::is_invocable, but with tuples. */
  24317. template<typename, typename>
  24318. struct is_applicable: std::false_type {};
  24319. /**
  24320. * @copybrief is_applicable
  24321. * @tparam Func A valid function type.
  24322. * @tparam Tuple Tuple-like type.
  24323. * @tparam Args The list of arguments to use to probe the function type.
  24324. */
  24325. template<typename Func, template<typename...> class Tuple, typename... Args>
  24326. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  24327. /**
  24328. * @copybrief is_applicable
  24329. * @tparam Func A valid function type.
  24330. * @tparam Tuple Tuple-like type.
  24331. * @tparam Args The list of arguments to use to probe the function type.
  24332. */
  24333. template<typename Func, template<typename...> class Tuple, typename... Args>
  24334. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  24335. /**
  24336. * @brief Helper variable template.
  24337. * @tparam Func A valid function type.
  24338. * @tparam Args The list of arguments to use to probe the function type.
  24339. */
  24340. template<typename Func, typename Args>
  24341. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  24342. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  24343. template<typename, typename, typename>
  24344. struct is_applicable_r: std::false_type {};
  24345. /**
  24346. * @copybrief is_applicable_r
  24347. * @tparam Ret The type to which the return type of the function should be
  24348. * convertible.
  24349. * @tparam Func A valid function type.
  24350. * @tparam Args The list of arguments to use to probe the function type.
  24351. */
  24352. template<typename Ret, typename Func, typename... Args>
  24353. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  24354. /**
  24355. * @brief Helper variable template.
  24356. * @tparam Ret The type to which the return type of the function should be
  24357. * convertible.
  24358. * @tparam Func A valid function type.
  24359. * @tparam Args The list of arguments to use to probe the function type.
  24360. */
  24361. template<typename Ret, typename Func, typename Args>
  24362. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  24363. /**
  24364. * @brief Provides the member constant `value` to true if a given type is
  24365. * complete, false otherwise.
  24366. * @tparam Type The type to test.
  24367. */
  24368. template<typename Type, typename = void>
  24369. struct is_complete: std::false_type {};
  24370. /*! @copydoc is_complete */
  24371. template<typename Type>
  24372. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  24373. /**
  24374. * @brief Helper variable template.
  24375. * @tparam Type The type to test.
  24376. */
  24377. template<typename Type>
  24378. inline constexpr bool is_complete_v = is_complete<Type>::value;
  24379. /**
  24380. * @brief Provides the member constant `value` to true if a given type is an
  24381. * iterator, false otherwise.
  24382. * @tparam Type The type to test.
  24383. */
  24384. template<typename Type, typename = void>
  24385. struct is_iterator: std::false_type {};
  24386. /*! @cond TURN_OFF_DOXYGEN */
  24387. namespace internal {
  24388. template<typename, typename = void>
  24389. struct has_iterator_category: std::false_type {};
  24390. template<typename Type>
  24391. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  24392. } // namespace internal
  24393. /*! @endcond */
  24394. /*! @copydoc is_iterator */
  24395. template<typename Type>
  24396. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  24397. : internal::has_iterator_category<Type> {};
  24398. /**
  24399. * @brief Helper variable template.
  24400. * @tparam Type The type to test.
  24401. */
  24402. template<typename Type>
  24403. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  24404. /**
  24405. * @brief Provides the member constant `value` to true if a given type is both
  24406. * an empty and non-final class, false otherwise.
  24407. * @tparam Type The type to test
  24408. */
  24409. template<typename Type>
  24410. struct is_ebco_eligible
  24411. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  24412. /**
  24413. * @brief Helper variable template.
  24414. * @tparam Type The type to test.
  24415. */
  24416. template<typename Type>
  24417. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  24418. /**
  24419. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  24420. * is valid and denotes a type, false otherwise.
  24421. * @tparam Type The type to test.
  24422. */
  24423. template<typename Type, typename = void>
  24424. struct is_transparent: std::false_type {};
  24425. /*! @copydoc is_transparent */
  24426. template<typename Type>
  24427. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  24428. /**
  24429. * @brief Helper variable template.
  24430. * @tparam Type The type to test.
  24431. */
  24432. template<typename Type>
  24433. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  24434. /*! @cond TURN_OFF_DOXYGEN */
  24435. namespace internal {
  24436. template<typename, typename = void>
  24437. struct has_tuple_size_value: std::false_type {};
  24438. template<typename Type>
  24439. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  24440. template<typename, typename = void>
  24441. struct has_value_type: std::false_type {};
  24442. template<typename Type>
  24443. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  24444. template<typename>
  24445. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  24446. template<typename Type, std::size_t... Index>
  24447. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  24448. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  24449. }
  24450. template<typename>
  24451. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  24452. return false;
  24453. }
  24454. template<typename Type>
  24455. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  24456. return true;
  24457. }
  24458. template<typename Type>
  24459. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  24460. // NOLINTBEGIN(modernize-use-transparent-functors)
  24461. if constexpr(std::is_array_v<Type>) {
  24462. return false;
  24463. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  24464. if constexpr(has_tuple_size_value<Type>::value) {
  24465. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  24466. } else {
  24467. return maybe_equality_comparable<Type>(0);
  24468. }
  24469. } else if constexpr(has_value_type<Type>::value) {
  24470. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  24471. return maybe_equality_comparable<Type>(0);
  24472. } else {
  24473. return false;
  24474. }
  24475. } else {
  24476. return maybe_equality_comparable<Type>(0);
  24477. }
  24478. // NOLINTEND(modernize-use-transparent-functors)
  24479. }
  24480. } // namespace internal
  24481. /*! @endcond */
  24482. /**
  24483. * @brief Provides the member constant `value` to true if a given type is
  24484. * equality comparable, false otherwise.
  24485. * @tparam Type The type to test.
  24486. */
  24487. template<typename Type>
  24488. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  24489. /*! @copydoc is_equality_comparable */
  24490. template<typename Type>
  24491. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  24492. /**
  24493. * @brief Helper variable template.
  24494. * @tparam Type The type to test.
  24495. */
  24496. template<typename Type>
  24497. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  24498. /**
  24499. * @brief Transcribes the constness of a type to another type.
  24500. * @tparam To The type to which to transcribe the constness.
  24501. * @tparam From The type from which to transcribe the constness.
  24502. */
  24503. template<typename To, typename From>
  24504. struct constness_as {
  24505. /*! @brief The type resulting from the transcription of the constness. */
  24506. using type = std::remove_const_t<To>;
  24507. };
  24508. /*! @copydoc constness_as */
  24509. template<typename To, typename From>
  24510. struct constness_as<To, const From> {
  24511. /*! @brief The type resulting from the transcription of the constness. */
  24512. using type = const To;
  24513. };
  24514. /**
  24515. * @brief Alias template to facilitate the transcription of the constness.
  24516. * @tparam To The type to which to transcribe the constness.
  24517. * @tparam From The type from which to transcribe the constness.
  24518. */
  24519. template<typename To, typename From>
  24520. using constness_as_t = typename constness_as<To, From>::type;
  24521. /**
  24522. * @brief Extracts the class of a non-static member object or function.
  24523. * @tparam Member A pointer to a non-static member object or function.
  24524. */
  24525. template<typename Member>
  24526. class member_class {
  24527. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  24528. template<typename Class, typename Ret, typename... Args>
  24529. static Class *clazz(Ret (Class::*)(Args...));
  24530. template<typename Class, typename Ret, typename... Args>
  24531. static Class *clazz(Ret (Class::*)(Args...) const);
  24532. template<typename Class, typename Type>
  24533. static Class *clazz(Type Class::*);
  24534. public:
  24535. /*! @brief The class of the given non-static member object or function. */
  24536. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  24537. };
  24538. /**
  24539. * @brief Helper type.
  24540. * @tparam Member A pointer to a non-static member object or function.
  24541. */
  24542. template<typename Member>
  24543. using member_class_t = typename member_class<Member>::type;
  24544. /**
  24545. * @brief Extracts the n-th argument of a _callable_ type.
  24546. * @tparam Index The index of the argument to extract.
  24547. * @tparam Candidate A valid _callable_ type.
  24548. */
  24549. template<std::size_t Index, typename Candidate>
  24550. class nth_argument {
  24551. template<typename Ret, typename... Args>
  24552. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  24553. template<typename Ret, typename Class, typename... Args>
  24554. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  24555. template<typename Ret, typename Class, typename... Args>
  24556. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  24557. template<typename Type, typename Class>
  24558. static constexpr type_list<Type> pick_up(Type Class ::*);
  24559. template<typename Type>
  24560. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  24561. public:
  24562. /*! @brief N-th argument of the _callable_ type. */
  24563. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  24564. };
  24565. /**
  24566. * @brief Helper type.
  24567. * @tparam Index The index of the argument to extract.
  24568. * @tparam Candidate A valid function, member function or data member type.
  24569. */
  24570. template<std::size_t Index, typename Candidate>
  24571. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  24572. } // namespace entt
  24573. template<typename... Type>
  24574. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  24575. template<std::size_t Index, typename... Type>
  24576. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  24577. template<auto... Value>
  24578. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  24579. template<std::size_t Index, auto... Value>
  24580. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  24581. #endif
  24582. namespace entt {
  24583. /*! @cond TURN_OFF_DOXYGEN */
  24584. namespace internal {
  24585. template<typename Type, std::size_t, typename = void>
  24586. struct compressed_pair_element {
  24587. using reference = Type &;
  24588. using const_reference = const Type &;
  24589. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  24590. // NOLINTNEXTLINE(modernize-use-equals-default)
  24591. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  24592. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  24593. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  24594. : value{std::forward<Arg>(arg)} {}
  24595. template<typename... Args, std::size_t... Index>
  24596. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  24597. : value{std::forward<Args>(std::get<Index>(args))...} {}
  24598. [[nodiscard]] constexpr reference get() noexcept {
  24599. return value;
  24600. }
  24601. [[nodiscard]] constexpr const_reference get() const noexcept {
  24602. return value;
  24603. }
  24604. private:
  24605. Type value{};
  24606. };
  24607. template<typename Type, std::size_t Tag>
  24608. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  24609. using reference = Type &;
  24610. using const_reference = const Type &;
  24611. using base_type = Type;
  24612. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  24613. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  24614. : base_type{} {}
  24615. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  24616. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  24617. : base_type{std::forward<Arg>(arg)} {}
  24618. template<typename... Args, std::size_t... Index>
  24619. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  24620. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  24621. [[nodiscard]] constexpr reference get() noexcept {
  24622. return *this;
  24623. }
  24624. [[nodiscard]] constexpr const_reference get() const noexcept {
  24625. return *this;
  24626. }
  24627. };
  24628. } // namespace internal
  24629. /*! @endcond */
  24630. /**
  24631. * @brief A compressed pair.
  24632. *
  24633. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  24634. * reduce its final size to a minimum.
  24635. *
  24636. * @tparam First The type of the first element that the pair stores.
  24637. * @tparam Second The type of the second element that the pair stores.
  24638. */
  24639. template<typename First, typename Second>
  24640. class compressed_pair final
  24641. : internal::compressed_pair_element<First, 0u>,
  24642. internal::compressed_pair_element<Second, 1u> {
  24643. using first_base = internal::compressed_pair_element<First, 0u>;
  24644. using second_base = internal::compressed_pair_element<Second, 1u>;
  24645. public:
  24646. /*! @brief The type of the first element that the pair stores. */
  24647. using first_type = First;
  24648. /*! @brief The type of the second element that the pair stores. */
  24649. using second_type = Second;
  24650. /**
  24651. * @brief Default constructor, conditionally enabled.
  24652. *
  24653. * This constructor is only available when the types that the pair stores
  24654. * are both at least default constructible.
  24655. *
  24656. * @tparam Dummy Dummy template parameter used for internal purposes.
  24657. */
  24658. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  24659. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  24660. : first_base{},
  24661. second_base{} {}
  24662. /**
  24663. * @brief Copy constructor.
  24664. * @param other The instance to copy from.
  24665. */
  24666. constexpr compressed_pair(const compressed_pair &other) = default;
  24667. /**
  24668. * @brief Move constructor.
  24669. * @param other The instance to move from.
  24670. */
  24671. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  24672. /**
  24673. * @brief Constructs a pair from its values.
  24674. * @tparam Arg Type of value to use to initialize the first element.
  24675. * @tparam Other Type of value to use to initialize the second element.
  24676. * @param arg Value to use to initialize the first element.
  24677. * @param other Value to use to initialize the second element.
  24678. */
  24679. template<typename Arg, typename Other>
  24680. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  24681. : first_base{std::forward<Arg>(arg)},
  24682. second_base{std::forward<Other>(other)} {}
  24683. /**
  24684. * @brief Constructs a pair by forwarding the arguments to its parts.
  24685. * @tparam Args Types of arguments to use to initialize the first element.
  24686. * @tparam Other Types of arguments to use to initialize the second element.
  24687. * @param args Arguments to use to initialize the first element.
  24688. * @param other Arguments to use to initialize the second element.
  24689. */
  24690. template<typename... Args, typename... Other>
  24691. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  24692. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  24693. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  24694. /*! @brief Default destructor. */
  24695. ~compressed_pair() = default;
  24696. /**
  24697. * @brief Copy assignment operator.
  24698. * @param other The instance to copy from.
  24699. * @return This compressed pair object.
  24700. */
  24701. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  24702. /**
  24703. * @brief Move assignment operator.
  24704. * @param other The instance to move from.
  24705. * @return This compressed pair object.
  24706. */
  24707. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  24708. /**
  24709. * @brief Returns the first element that a pair stores.
  24710. * @return The first element that a pair stores.
  24711. */
  24712. [[nodiscard]] constexpr first_type &first() noexcept {
  24713. return static_cast<first_base &>(*this).get();
  24714. }
  24715. /*! @copydoc first */
  24716. [[nodiscard]] constexpr const first_type &first() const noexcept {
  24717. return static_cast<const first_base &>(*this).get();
  24718. }
  24719. /**
  24720. * @brief Returns the second element that a pair stores.
  24721. * @return The second element that a pair stores.
  24722. */
  24723. [[nodiscard]] constexpr second_type &second() noexcept {
  24724. return static_cast<second_base &>(*this).get();
  24725. }
  24726. /*! @copydoc second */
  24727. [[nodiscard]] constexpr const second_type &second() const noexcept {
  24728. return static_cast<const second_base &>(*this).get();
  24729. }
  24730. /**
  24731. * @brief Swaps two compressed pair objects.
  24732. * @param other The compressed pair to swap with.
  24733. */
  24734. constexpr void swap(compressed_pair &other) noexcept {
  24735. using std::swap;
  24736. swap(first(), other.first());
  24737. swap(second(), other.second());
  24738. }
  24739. /**
  24740. * @brief Extracts an element from the compressed pair.
  24741. * @tparam Index An integer value that is either 0 or 1.
  24742. * @return Returns a reference to the first element if `Index` is 0 and a
  24743. * reference to the second element if `Index` is 1.
  24744. */
  24745. template<std::size_t Index>
  24746. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  24747. if constexpr(Index == 0u) {
  24748. return first();
  24749. } else {
  24750. static_assert(Index == 1u, "Index out of bounds");
  24751. return second();
  24752. }
  24753. }
  24754. /*! @copydoc get */
  24755. template<std::size_t Index>
  24756. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  24757. if constexpr(Index == 0u) {
  24758. return first();
  24759. } else {
  24760. static_assert(Index == 1u, "Index out of bounds");
  24761. return second();
  24762. }
  24763. }
  24764. };
  24765. /**
  24766. * @brief Deduction guide.
  24767. * @tparam Type Type of value to use to initialize the first element.
  24768. * @tparam Other Type of value to use to initialize the second element.
  24769. */
  24770. template<typename Type, typename Other>
  24771. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  24772. /**
  24773. * @brief Swaps two compressed pair objects.
  24774. * @tparam First The type of the first element that the pairs store.
  24775. * @tparam Second The type of the second element that the pairs store.
  24776. * @param lhs A valid compressed pair object.
  24777. * @param rhs A valid compressed pair object.
  24778. */
  24779. template<typename First, typename Second>
  24780. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  24781. lhs.swap(rhs);
  24782. }
  24783. } // namespace entt
  24784. namespace std {
  24785. /**
  24786. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  24787. * @tparam First The type of the first element that the pair stores.
  24788. * @tparam Second The type of the second element that the pair stores.
  24789. */
  24790. template<typename First, typename Second>
  24791. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  24792. /**
  24793. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  24794. * @tparam Index The index of the type to return.
  24795. * @tparam First The type of the first element that the pair stores.
  24796. * @tparam Second The type of the second element that the pair stores.
  24797. */
  24798. template<size_t Index, typename First, typename Second>
  24799. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  24800. static_assert(Index < 2u, "Index out of bounds");
  24801. };
  24802. } // namespace std
  24803. #endif
  24804. // #include "../core/iterator.hpp"
  24805. #ifndef ENTT_CORE_ITERATOR_HPP
  24806. #define ENTT_CORE_ITERATOR_HPP
  24807. #include <iterator>
  24808. #include <memory>
  24809. #include <type_traits>
  24810. #include <utility>
  24811. namespace entt {
  24812. /**
  24813. * @brief Helper type to use as pointer with input iterators.
  24814. * @tparam Type of wrapped value.
  24815. */
  24816. template<typename Type>
  24817. struct input_iterator_pointer final {
  24818. /*! @brief Value type. */
  24819. using value_type = Type;
  24820. /*! @brief Pointer type. */
  24821. using pointer = Type *;
  24822. /*! @brief Reference type. */
  24823. using reference = Type &;
  24824. /**
  24825. * @brief Constructs a proxy object by move.
  24826. * @param val Value to use to initialize the proxy object.
  24827. */
  24828. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  24829. : value{std::move(val)} {}
  24830. /**
  24831. * @brief Access operator for accessing wrapped values.
  24832. * @return A pointer to the wrapped value.
  24833. */
  24834. [[nodiscard]] constexpr pointer operator->() noexcept {
  24835. return std::addressof(value);
  24836. }
  24837. /**
  24838. * @brief Dereference operator for accessing wrapped values.
  24839. * @return A reference to the wrapped value.
  24840. */
  24841. [[nodiscard]] constexpr reference operator*() noexcept {
  24842. return value;
  24843. }
  24844. private:
  24845. Type value;
  24846. };
  24847. /**
  24848. * @brief Plain iota iterator (waiting for C++20).
  24849. * @tparam Type Value type.
  24850. */
  24851. template<typename Type>
  24852. class iota_iterator final {
  24853. static_assert(std::is_integral_v<Type>, "Not an integral type");
  24854. public:
  24855. /*! @brief Value type, likely an integral one. */
  24856. using value_type = Type;
  24857. /*! @brief Invalid pointer type. */
  24858. using pointer = void;
  24859. /*! @brief Non-reference type, same as value type. */
  24860. using reference = value_type;
  24861. /*! @brief Difference type. */
  24862. using difference_type = std::ptrdiff_t;
  24863. /*! @brief Iterator category. */
  24864. using iterator_category = std::input_iterator_tag;
  24865. /*! @brief Default constructor. */
  24866. constexpr iota_iterator() noexcept
  24867. : current{} {}
  24868. /**
  24869. * @brief Constructs an iota iterator from a given value.
  24870. * @param init The initial value assigned to the iota iterator.
  24871. */
  24872. constexpr iota_iterator(const value_type init) noexcept
  24873. : current{init} {}
  24874. /**
  24875. * @brief Pre-increment operator.
  24876. * @return This iota iterator.
  24877. */
  24878. constexpr iota_iterator &operator++() noexcept {
  24879. return ++current, *this;
  24880. }
  24881. /**
  24882. * @brief Post-increment operator.
  24883. * @return This iota iterator.
  24884. */
  24885. constexpr iota_iterator operator++(int) noexcept {
  24886. const iota_iterator orig = *this;
  24887. return ++(*this), orig;
  24888. }
  24889. /**
  24890. * @brief Dereference operator.
  24891. * @return The underlying value.
  24892. */
  24893. [[nodiscard]] constexpr reference operator*() const noexcept {
  24894. return current;
  24895. }
  24896. private:
  24897. value_type current;
  24898. };
  24899. /**
  24900. * @brief Comparison operator.
  24901. * @tparam Type Value type of the iota iterator.
  24902. * @param lhs A properly initialized iota iterator.
  24903. * @param rhs A properly initialized iota iterator.
  24904. * @return True if the two iterators are identical, false otherwise.
  24905. */
  24906. template<typename Type>
  24907. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  24908. return *lhs == *rhs;
  24909. }
  24910. /**
  24911. * @brief Comparison operator.
  24912. * @tparam Type Value type of the iota iterator.
  24913. * @param lhs A properly initialized iota iterator.
  24914. * @param rhs A properly initialized iota iterator.
  24915. * @return True if the two iterators differ, false otherwise.
  24916. */
  24917. template<typename Type>
  24918. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  24919. return !(lhs == rhs);
  24920. }
  24921. /**
  24922. * @brief Utility class to create an iterable object from a pair of iterators.
  24923. * @tparam It Type of iterator.
  24924. * @tparam Sentinel Type of sentinel.
  24925. */
  24926. template<typename It, typename Sentinel = It>
  24927. struct iterable_adaptor final {
  24928. /*! @brief Value type. */
  24929. using value_type = typename std::iterator_traits<It>::value_type;
  24930. /*! @brief Iterator type. */
  24931. using iterator = It;
  24932. /*! @brief Sentinel type. */
  24933. using sentinel = Sentinel;
  24934. /*! @brief Default constructor. */
  24935. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  24936. : first{},
  24937. last{} {}
  24938. /**
  24939. * @brief Creates an iterable object from a pair of iterators.
  24940. * @param from Begin iterator.
  24941. * @param to End iterator.
  24942. */
  24943. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  24944. : first{std::move(from)},
  24945. last{std::move(to)} {}
  24946. /**
  24947. * @brief Returns an iterator to the beginning.
  24948. * @return An iterator to the first element of the range.
  24949. */
  24950. [[nodiscard]] constexpr iterator begin() const noexcept {
  24951. return first;
  24952. }
  24953. /**
  24954. * @brief Returns an iterator to the end.
  24955. * @return An iterator to the element following the last element of the
  24956. * range.
  24957. */
  24958. [[nodiscard]] constexpr sentinel end() const noexcept {
  24959. return last;
  24960. }
  24961. /*! @copydoc begin */
  24962. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  24963. return begin();
  24964. }
  24965. /*! @copydoc end */
  24966. [[nodiscard]] constexpr sentinel cend() const noexcept {
  24967. return end();
  24968. }
  24969. private:
  24970. It first;
  24971. Sentinel last;
  24972. };
  24973. } // namespace entt
  24974. #endif
  24975. // #include "../core/memory.hpp"
  24976. #ifndef ENTT_CORE_MEMORY_HPP
  24977. #define ENTT_CORE_MEMORY_HPP
  24978. #include <cstddef>
  24979. #include <memory>
  24980. #include <tuple>
  24981. #include <type_traits>
  24982. #include <utility>
  24983. // #include "../config/config.h"
  24984. namespace entt {
  24985. /**
  24986. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  24987. * @tparam Type Pointer type.
  24988. * @param ptr Fancy or raw pointer.
  24989. * @return A raw pointer that represents the address of the original pointer.
  24990. */
  24991. template<typename Type>
  24992. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  24993. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  24994. return ptr;
  24995. } else {
  24996. return to_address(std::forward<Type>(ptr).operator->());
  24997. }
  24998. }
  24999. /**
  25000. * @brief Utility function to design allocation-aware containers.
  25001. * @tparam Allocator Type of allocator.
  25002. * @param lhs A valid allocator.
  25003. * @param rhs Another valid allocator.
  25004. */
  25005. template<typename Allocator>
  25006. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  25007. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  25008. lhs = rhs;
  25009. }
  25010. }
  25011. /**
  25012. * @brief Utility function to design allocation-aware containers.
  25013. * @tparam Allocator Type of allocator.
  25014. * @param lhs A valid allocator.
  25015. * @param rhs Another valid allocator.
  25016. */
  25017. template<typename Allocator>
  25018. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  25019. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  25020. lhs = std::move(rhs);
  25021. }
  25022. }
  25023. /**
  25024. * @brief Utility function to design allocation-aware containers.
  25025. * @tparam Allocator Type of allocator.
  25026. * @param lhs A valid allocator.
  25027. * @param rhs Another valid allocator.
  25028. */
  25029. template<typename Allocator>
  25030. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  25031. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  25032. using std::swap;
  25033. swap(lhs, rhs);
  25034. } else {
  25035. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  25036. }
  25037. }
  25038. /**
  25039. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  25040. * @tparam Allocator Type of allocator used to manage memory and elements.
  25041. */
  25042. template<typename Allocator>
  25043. struct allocation_deleter: private Allocator {
  25044. /*! @brief Allocator type. */
  25045. using allocator_type = Allocator;
  25046. /*! @brief Pointer type. */
  25047. using pointer = typename std::allocator_traits<Allocator>::pointer;
  25048. /**
  25049. * @brief Inherited constructors.
  25050. * @param alloc The allocator to use.
  25051. */
  25052. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  25053. : Allocator{alloc} {}
  25054. /**
  25055. * @brief Destroys the pointed object and deallocates its memory.
  25056. * @param ptr A valid pointer to an object of the given type.
  25057. */
  25058. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  25059. using alloc_traits = std::allocator_traits<Allocator>;
  25060. alloc_traits::destroy(*this, to_address(ptr));
  25061. alloc_traits::deallocate(*this, ptr, 1u);
  25062. }
  25063. };
  25064. /**
  25065. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  25066. * @tparam Type Type of object to allocate for and to construct.
  25067. * @tparam Allocator Type of allocator used to manage memory and elements.
  25068. * @tparam Args Types of arguments to use to construct the object.
  25069. * @param allocator The allocator to use.
  25070. * @param args Parameters to use to construct the object.
  25071. * @return A properly initialized unique pointer with a custom deleter.
  25072. */
  25073. template<typename Type, typename Allocator, typename... Args>
  25074. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  25075. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  25076. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  25077. using allocator_type = typename alloc_traits::allocator_type;
  25078. allocator_type alloc{allocator};
  25079. auto ptr = alloc_traits::allocate(alloc, 1u);
  25080. ENTT_TRY {
  25081. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  25082. }
  25083. ENTT_CATCH {
  25084. alloc_traits::deallocate(alloc, ptr, 1u);
  25085. ENTT_THROW;
  25086. }
  25087. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  25088. }
  25089. /*! @cond TURN_OFF_DOXYGEN */
  25090. namespace internal {
  25091. template<typename Type>
  25092. struct uses_allocator_construction {
  25093. template<typename Allocator, typename... Params>
  25094. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  25095. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  25096. return std::forward_as_tuple(std::forward<Params>(params)...);
  25097. } else {
  25098. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  25099. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  25100. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  25101. } else {
  25102. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  25103. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  25104. }
  25105. }
  25106. }
  25107. };
  25108. template<typename Type, typename Other>
  25109. struct uses_allocator_construction<std::pair<Type, Other>> {
  25110. using type = std::pair<Type, Other>;
  25111. template<typename Allocator, typename First, typename Second>
  25112. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  25113. return std::make_tuple(
  25114. std::piecewise_construct,
  25115. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  25116. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  25117. }
  25118. template<typename Allocator>
  25119. static constexpr auto args(const Allocator &allocator) noexcept {
  25120. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  25121. }
  25122. template<typename Allocator, typename First, typename Second>
  25123. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  25124. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  25125. }
  25126. template<typename Allocator, typename First, typename Second>
  25127. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  25128. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  25129. }
  25130. template<typename Allocator, typename First, typename Second>
  25131. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  25132. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  25133. }
  25134. };
  25135. } // namespace internal
  25136. /*! @endcond */
  25137. /**
  25138. * @brief Uses-allocator construction utility (waiting for C++20).
  25139. *
  25140. * Primarily intended for internal use. Prepares the argument list needed to
  25141. * create an object of a given type by means of uses-allocator construction.
  25142. *
  25143. * @tparam Type Type to return arguments for.
  25144. * @tparam Allocator Type of allocator used to manage memory and elements.
  25145. * @tparam Args Types of arguments to use to construct the object.
  25146. * @param allocator The allocator to use.
  25147. * @param args Parameters to use to construct the object.
  25148. * @return The arguments needed to create an object of the given type.
  25149. */
  25150. template<typename Type, typename Allocator, typename... Args>
  25151. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  25152. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  25153. }
  25154. /**
  25155. * @brief Uses-allocator construction utility (waiting for C++20).
  25156. *
  25157. * Primarily intended for internal use. Creates an object of a given type by
  25158. * means of uses-allocator construction.
  25159. *
  25160. * @tparam Type Type of object to create.
  25161. * @tparam Allocator Type of allocator used to manage memory and elements.
  25162. * @tparam Args Types of arguments to use to construct the object.
  25163. * @param allocator The allocator to use.
  25164. * @param args Parameters to use to construct the object.
  25165. * @return A newly created object of the given type.
  25166. */
  25167. template<typename Type, typename Allocator, typename... Args>
  25168. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  25169. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  25170. }
  25171. /**
  25172. * @brief Uses-allocator construction utility (waiting for C++20).
  25173. *
  25174. * Primarily intended for internal use. Creates an object of a given type by
  25175. * means of uses-allocator construction at an uninitialized memory location.
  25176. *
  25177. * @tparam Type Type of object to create.
  25178. * @tparam Allocator Type of allocator used to manage memory and elements.
  25179. * @tparam Args Types of arguments to use to construct the object.
  25180. * @param value Memory location in which to place the object.
  25181. * @param allocator The allocator to use.
  25182. * @param args Parameters to use to construct the object.
  25183. * @return A pointer to the newly created object of the given type.
  25184. */
  25185. template<typename Type, typename Allocator, typename... Args>
  25186. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  25187. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  25188. }
  25189. } // namespace entt
  25190. #endif
  25191. // #include "../core/type_traits.hpp"
  25192. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  25193. #define ENTT_CORE_TYPE_TRAITS_HPP
  25194. #include <cstddef>
  25195. #include <iterator>
  25196. #include <tuple>
  25197. #include <type_traits>
  25198. #include <utility>
  25199. // #include "../config/config.h"
  25200. // #include "fwd.hpp"
  25201. namespace entt {
  25202. /**
  25203. * @brief Utility class to disambiguate overloaded functions.
  25204. * @tparam N Number of choices available.
  25205. */
  25206. template<std::size_t N>
  25207. struct choice_t
  25208. // unfortunately, doxygen cannot parse such a construct
  25209. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  25210. {};
  25211. /*! @copybrief choice_t */
  25212. template<>
  25213. struct choice_t<0> {};
  25214. /**
  25215. * @brief Variable template for the choice trick.
  25216. * @tparam N Number of choices available.
  25217. */
  25218. template<std::size_t N>
  25219. inline constexpr choice_t<N> choice{};
  25220. /**
  25221. * @brief Identity type trait.
  25222. *
  25223. * Useful to establish non-deduced contexts in template argument deduction
  25224. * (waiting for C++20) or to provide types through function arguments.
  25225. *
  25226. * @tparam Type A type.
  25227. */
  25228. template<typename Type>
  25229. struct type_identity {
  25230. /*! @brief Identity type. */
  25231. using type = Type;
  25232. };
  25233. /**
  25234. * @brief Helper type.
  25235. * @tparam Type A type.
  25236. */
  25237. template<typename Type>
  25238. using type_identity_t = typename type_identity<Type>::type;
  25239. /**
  25240. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  25241. * @tparam Type The type of which to return the size.
  25242. */
  25243. template<typename Type, typename = void>
  25244. struct size_of: std::integral_constant<std::size_t, 0u> {};
  25245. /*! @copydoc size_of */
  25246. template<typename Type>
  25247. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  25248. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  25249. : std::integral_constant<std::size_t, sizeof(Type)> {};
  25250. /**
  25251. * @brief Helper variable template.
  25252. * @tparam Type The type of which to return the size.
  25253. */
  25254. template<typename Type>
  25255. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  25256. /**
  25257. * @brief Using declaration to be used to _repeat_ the same type a number of
  25258. * times equal to the size of a given parameter pack.
  25259. * @tparam Type A type to repeat.
  25260. */
  25261. template<typename Type, typename>
  25262. using unpack_as_type = Type;
  25263. /**
  25264. * @brief Helper variable template to be used to _repeat_ the same value a
  25265. * number of times equal to the size of a given parameter pack.
  25266. * @tparam Value A value to repeat.
  25267. */
  25268. template<auto Value, typename>
  25269. inline constexpr auto unpack_as_value = Value;
  25270. /**
  25271. * @brief Wraps a static constant.
  25272. * @tparam Value A static constant.
  25273. */
  25274. template<auto Value>
  25275. using integral_constant = std::integral_constant<decltype(Value), Value>;
  25276. /**
  25277. * @brief Alias template to facilitate the creation of named values.
  25278. * @tparam Value A constant value at least convertible to `id_type`.
  25279. */
  25280. template<id_type Value>
  25281. using tag = integral_constant<Value>;
  25282. /**
  25283. * @brief A class to use to push around lists of types, nothing more.
  25284. * @tparam Type Types provided by the type list.
  25285. */
  25286. template<typename... Type>
  25287. struct type_list {
  25288. /*! @brief Type list type. */
  25289. using type = type_list;
  25290. /*! @brief Compile-time number of elements in the type list. */
  25291. static constexpr auto size = sizeof...(Type);
  25292. };
  25293. /*! @brief Primary template isn't defined on purpose. */
  25294. template<std::size_t, typename>
  25295. struct type_list_element;
  25296. /**
  25297. * @brief Provides compile-time indexed access to the types of a type list.
  25298. * @tparam Index Index of the type to return.
  25299. * @tparam First First type provided by the type list.
  25300. * @tparam Other Other types provided by the type list.
  25301. */
  25302. template<std::size_t Index, typename First, typename... Other>
  25303. struct type_list_element<Index, type_list<First, Other...>>
  25304. : type_list_element<Index - 1u, type_list<Other...>> {};
  25305. /**
  25306. * @brief Provides compile-time indexed access to the types of a type list.
  25307. * @tparam First First type provided by the type list.
  25308. * @tparam Other Other types provided by the type list.
  25309. */
  25310. template<typename First, typename... Other>
  25311. struct type_list_element<0u, type_list<First, Other...>> {
  25312. /*! @brief Searched type. */
  25313. using type = First;
  25314. };
  25315. /**
  25316. * @brief Helper type.
  25317. * @tparam Index Index of the type to return.
  25318. * @tparam List Type list to search into.
  25319. */
  25320. template<std::size_t Index, typename List>
  25321. using type_list_element_t = typename type_list_element<Index, List>::type;
  25322. /*! @brief Primary template isn't defined on purpose. */
  25323. template<typename, typename>
  25324. struct type_list_index;
  25325. /**
  25326. * @brief Provides compile-time type access to the types of a type list.
  25327. * @tparam Type Type to look for and for which to return the index.
  25328. * @tparam First First type provided by the type list.
  25329. * @tparam Other Other types provided by the type list.
  25330. */
  25331. template<typename Type, typename First, typename... Other>
  25332. struct type_list_index<Type, type_list<First, Other...>> {
  25333. /*! @brief Unsigned integer type. */
  25334. using value_type = std::size_t;
  25335. /*! @brief Compile-time position of the given type in the sublist. */
  25336. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  25337. };
  25338. /**
  25339. * @brief Provides compile-time type access to the types of a type list.
  25340. * @tparam Type Type to look for and for which to return the index.
  25341. * @tparam Other Other types provided by the type list.
  25342. */
  25343. template<typename Type, typename... Other>
  25344. struct type_list_index<Type, type_list<Type, Other...>> {
  25345. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  25346. /*! @brief Unsigned integer type. */
  25347. using value_type = std::size_t;
  25348. /*! @brief Compile-time position of the given type in the sublist. */
  25349. static constexpr value_type value = 0u;
  25350. };
  25351. /**
  25352. * @brief Provides compile-time type access to the types of a type list.
  25353. * @tparam Type Type to look for and for which to return the index.
  25354. */
  25355. template<typename Type>
  25356. struct type_list_index<Type, type_list<>> {
  25357. /*! @brief Unsigned integer type. */
  25358. using value_type = std::size_t;
  25359. /*! @brief Compile-time position of the given type in the sublist. */
  25360. static constexpr value_type value = 0u;
  25361. };
  25362. /**
  25363. * @brief Helper variable template.
  25364. * @tparam List Type list.
  25365. * @tparam Type Type to look for and for which to return the index.
  25366. */
  25367. template<typename Type, typename List>
  25368. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  25369. /**
  25370. * @brief Concatenates multiple type lists.
  25371. * @tparam Type Types provided by the first type list.
  25372. * @tparam Other Types provided by the second type list.
  25373. * @return A type list composed by the types of both the type lists.
  25374. */
  25375. template<typename... Type, typename... Other>
  25376. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  25377. return {};
  25378. }
  25379. /*! @brief Primary template isn't defined on purpose. */
  25380. template<typename...>
  25381. struct type_list_cat;
  25382. /*! @brief Concatenates multiple type lists. */
  25383. template<>
  25384. struct type_list_cat<> {
  25385. /*! @brief A type list composed by the types of all the type lists. */
  25386. using type = type_list<>;
  25387. };
  25388. /**
  25389. * @brief Concatenates multiple type lists.
  25390. * @tparam Type Types provided by the first type list.
  25391. * @tparam Other Types provided by the second type list.
  25392. * @tparam List Other type lists, if any.
  25393. */
  25394. template<typename... Type, typename... Other, typename... List>
  25395. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  25396. /*! @brief A type list composed by the types of all the type lists. */
  25397. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  25398. };
  25399. /**
  25400. * @brief Concatenates multiple type lists.
  25401. * @tparam Type Types provided by the type list.
  25402. */
  25403. template<typename... Type>
  25404. struct type_list_cat<type_list<Type...>> {
  25405. /*! @brief A type list composed by the types of all the type lists. */
  25406. using type = type_list<Type...>;
  25407. };
  25408. /**
  25409. * @brief Helper type.
  25410. * @tparam List Type lists to concatenate.
  25411. */
  25412. template<typename... List>
  25413. using type_list_cat_t = typename type_list_cat<List...>::type;
  25414. /*! @cond TURN_OFF_DOXYGEN */
  25415. namespace internal {
  25416. template<typename...>
  25417. struct type_list_unique;
  25418. template<typename First, typename... Other, typename... Type>
  25419. struct type_list_unique<type_list<First, Other...>, Type...>
  25420. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  25421. template<typename... Type>
  25422. struct type_list_unique<type_list<>, Type...> {
  25423. using type = type_list<Type...>;
  25424. };
  25425. } // namespace internal
  25426. /*! @endcond */
  25427. /**
  25428. * @brief Removes duplicates types from a type list.
  25429. * @tparam List Type list.
  25430. */
  25431. template<typename List>
  25432. struct type_list_unique {
  25433. /*! @brief A type list without duplicate types. */
  25434. using type = typename internal::type_list_unique<List>::type;
  25435. };
  25436. /**
  25437. * @brief Helper type.
  25438. * @tparam List Type list.
  25439. */
  25440. template<typename List>
  25441. using type_list_unique_t = typename type_list_unique<List>::type;
  25442. /**
  25443. * @brief Provides the member constant `value` to true if a type list contains a
  25444. * given type, false otherwise.
  25445. * @tparam List Type list.
  25446. * @tparam Type Type to look for.
  25447. */
  25448. template<typename List, typename Type>
  25449. struct type_list_contains;
  25450. /**
  25451. * @copybrief type_list_contains
  25452. * @tparam Type Types provided by the type list.
  25453. * @tparam Other Type to look for.
  25454. */
  25455. template<typename... Type, typename Other>
  25456. struct type_list_contains<type_list<Type...>, Other>
  25457. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  25458. /**
  25459. * @brief Helper variable template.
  25460. * @tparam List Type list.
  25461. * @tparam Type Type to look for.
  25462. */
  25463. template<typename List, typename Type>
  25464. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  25465. /*! @brief Primary template isn't defined on purpose. */
  25466. template<typename...>
  25467. struct type_list_diff;
  25468. /**
  25469. * @brief Computes the difference between two type lists.
  25470. * @tparam Type Types provided by the first type list.
  25471. * @tparam Other Types provided by the second type list.
  25472. */
  25473. template<typename... Type, typename... Other>
  25474. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  25475. /*! @brief A type list that is the difference between the two type lists. */
  25476. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  25477. };
  25478. /**
  25479. * @brief Helper type.
  25480. * @tparam List Type lists between which to compute the difference.
  25481. */
  25482. template<typename... List>
  25483. using type_list_diff_t = typename type_list_diff<List...>::type;
  25484. /*! @brief Primary template isn't defined on purpose. */
  25485. template<typename, template<typename...> class>
  25486. struct type_list_transform;
  25487. /**
  25488. * @brief Applies a given _function_ to a type list and generate a new list.
  25489. * @tparam Type Types provided by the type list.
  25490. * @tparam Op Unary operation as template class with a type member named `type`.
  25491. */
  25492. template<typename... Type, template<typename...> class Op>
  25493. struct type_list_transform<type_list<Type...>, Op> {
  25494. /*! @brief Resulting type list after applying the transform function. */
  25495. // NOLINTNEXTLINE(modernize-type-traits)
  25496. using type = type_list<typename Op<Type>::type...>;
  25497. };
  25498. /**
  25499. * @brief Helper type.
  25500. * @tparam List Type list.
  25501. * @tparam Op Unary operation as template class with a type member named `type`.
  25502. */
  25503. template<typename List, template<typename...> class Op>
  25504. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  25505. /**
  25506. * @brief A class to use to push around lists of constant values, nothing more.
  25507. * @tparam Value Values provided by the value list.
  25508. */
  25509. template<auto... Value>
  25510. struct value_list {
  25511. /*! @brief Value list type. */
  25512. using type = value_list;
  25513. /*! @brief Compile-time number of elements in the value list. */
  25514. static constexpr auto size = sizeof...(Value);
  25515. };
  25516. /*! @brief Primary template isn't defined on purpose. */
  25517. template<std::size_t, typename>
  25518. struct value_list_element;
  25519. /**
  25520. * @brief Provides compile-time indexed access to the values of a value list.
  25521. * @tparam Index Index of the value to return.
  25522. * @tparam Value First value provided by the value list.
  25523. * @tparam Other Other values provided by the value list.
  25524. */
  25525. template<std::size_t Index, auto Value, auto... Other>
  25526. struct value_list_element<Index, value_list<Value, Other...>>
  25527. : value_list_element<Index - 1u, value_list<Other...>> {};
  25528. /**
  25529. * @brief Provides compile-time indexed access to the types of a type list.
  25530. * @tparam Value First value provided by the value list.
  25531. * @tparam Other Other values provided by the value list.
  25532. */
  25533. template<auto Value, auto... Other>
  25534. struct value_list_element<0u, value_list<Value, Other...>> {
  25535. /*! @brief Searched type. */
  25536. using type = decltype(Value);
  25537. /*! @brief Searched value. */
  25538. static constexpr auto value = Value;
  25539. };
  25540. /**
  25541. * @brief Helper type.
  25542. * @tparam Index Index of the type to return.
  25543. * @tparam List Value list to search into.
  25544. */
  25545. template<std::size_t Index, typename List>
  25546. using value_list_element_t = typename value_list_element<Index, List>::type;
  25547. /**
  25548. * @brief Helper type.
  25549. * @tparam Index Index of the value to return.
  25550. * @tparam List Value list to search into.
  25551. */
  25552. template<std::size_t Index, typename List>
  25553. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  25554. /*! @brief Primary template isn't defined on purpose. */
  25555. template<auto, typename>
  25556. struct value_list_index;
  25557. /**
  25558. * @brief Provides compile-time type access to the values of a value list.
  25559. * @tparam Value Value to look for and for which to return the index.
  25560. * @tparam First First value provided by the value list.
  25561. * @tparam Other Other values provided by the value list.
  25562. */
  25563. template<auto Value, auto First, auto... Other>
  25564. struct value_list_index<Value, value_list<First, Other...>> {
  25565. /*! @brief Unsigned integer type. */
  25566. using value_type = std::size_t;
  25567. /*! @brief Compile-time position of the given value in the sublist. */
  25568. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  25569. };
  25570. /**
  25571. * @brief Provides compile-time type access to the values of a value list.
  25572. * @tparam Value Value to look for and for which to return the index.
  25573. * @tparam Other Other values provided by the value list.
  25574. */
  25575. template<auto Value, auto... Other>
  25576. struct value_list_index<Value, value_list<Value, Other...>> {
  25577. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  25578. /*! @brief Unsigned integer type. */
  25579. using value_type = std::size_t;
  25580. /*! @brief Compile-time position of the given value in the sublist. */
  25581. static constexpr value_type value = 0u;
  25582. };
  25583. /**
  25584. * @brief Provides compile-time type access to the values of a value list.
  25585. * @tparam Value Value to look for and for which to return the index.
  25586. */
  25587. template<auto Value>
  25588. struct value_list_index<Value, value_list<>> {
  25589. /*! @brief Unsigned integer type. */
  25590. using value_type = std::size_t;
  25591. /*! @brief Compile-time position of the given type in the sublist. */
  25592. static constexpr value_type value = 0u;
  25593. };
  25594. /**
  25595. * @brief Helper variable template.
  25596. * @tparam List Value list.
  25597. * @tparam Value Value to look for and for which to return the index.
  25598. */
  25599. template<auto Value, typename List>
  25600. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  25601. /**
  25602. * @brief Concatenates multiple value lists.
  25603. * @tparam Value Values provided by the first value list.
  25604. * @tparam Other Values provided by the second value list.
  25605. * @return A value list composed by the values of both the value lists.
  25606. */
  25607. template<auto... Value, auto... Other>
  25608. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  25609. return {};
  25610. }
  25611. /*! @brief Primary template isn't defined on purpose. */
  25612. template<typename...>
  25613. struct value_list_cat;
  25614. /*! @brief Concatenates multiple value lists. */
  25615. template<>
  25616. struct value_list_cat<> {
  25617. /*! @brief A value list composed by the values of all the value lists. */
  25618. using type = value_list<>;
  25619. };
  25620. /**
  25621. * @brief Concatenates multiple value lists.
  25622. * @tparam Value Values provided by the first value list.
  25623. * @tparam Other Values provided by the second value list.
  25624. * @tparam List Other value lists, if any.
  25625. */
  25626. template<auto... Value, auto... Other, typename... List>
  25627. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  25628. /*! @brief A value list composed by the values of all the value lists. */
  25629. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  25630. };
  25631. /**
  25632. * @brief Concatenates multiple value lists.
  25633. * @tparam Value Values provided by the value list.
  25634. */
  25635. template<auto... Value>
  25636. struct value_list_cat<value_list<Value...>> {
  25637. /*! @brief A value list composed by the values of all the value lists. */
  25638. using type = value_list<Value...>;
  25639. };
  25640. /**
  25641. * @brief Helper type.
  25642. * @tparam List Value lists to concatenate.
  25643. */
  25644. template<typename... List>
  25645. using value_list_cat_t = typename value_list_cat<List...>::type;
  25646. /*! @brief Primary template isn't defined on purpose. */
  25647. template<typename>
  25648. struct value_list_unique;
  25649. /**
  25650. * @brief Removes duplicates values from a value list.
  25651. * @tparam Value One of the values provided by the given value list.
  25652. * @tparam Other The other values provided by the given value list.
  25653. */
  25654. template<auto Value, auto... Other>
  25655. struct value_list_unique<value_list<Value, Other...>> {
  25656. /*! @brief A value list without duplicate types. */
  25657. using type = std::conditional_t<
  25658. ((Value == Other) || ...),
  25659. typename value_list_unique<value_list<Other...>>::type,
  25660. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  25661. };
  25662. /*! @brief Removes duplicates values from a value list. */
  25663. template<>
  25664. struct value_list_unique<value_list<>> {
  25665. /*! @brief A value list without duplicate types. */
  25666. using type = value_list<>;
  25667. };
  25668. /**
  25669. * @brief Helper type.
  25670. * @tparam Type A value list.
  25671. */
  25672. template<typename Type>
  25673. using value_list_unique_t = typename value_list_unique<Type>::type;
  25674. /**
  25675. * @brief Provides the member constant `value` to true if a value list contains
  25676. * a given value, false otherwise.
  25677. * @tparam List Value list.
  25678. * @tparam Value Value to look for.
  25679. */
  25680. template<typename List, auto Value>
  25681. struct value_list_contains;
  25682. /**
  25683. * @copybrief value_list_contains
  25684. * @tparam Value Values provided by the value list.
  25685. * @tparam Other Value to look for.
  25686. */
  25687. template<auto... Value, auto Other>
  25688. struct value_list_contains<value_list<Value...>, Other>
  25689. : std::bool_constant<((Value == Other) || ...)> {};
  25690. /**
  25691. * @brief Helper variable template.
  25692. * @tparam List Value list.
  25693. * @tparam Value Value to look for.
  25694. */
  25695. template<typename List, auto Value>
  25696. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  25697. /*! @brief Primary template isn't defined on purpose. */
  25698. template<typename...>
  25699. struct value_list_diff;
  25700. /**
  25701. * @brief Computes the difference between two value lists.
  25702. * @tparam Value Values provided by the first value list.
  25703. * @tparam Other Values provided by the second value list.
  25704. */
  25705. template<auto... Value, auto... Other>
  25706. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  25707. /*! @brief A value list that is the difference between the two value lists. */
  25708. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  25709. };
  25710. /**
  25711. * @brief Helper type.
  25712. * @tparam List Value lists between which to compute the difference.
  25713. */
  25714. template<typename... List>
  25715. using value_list_diff_t = typename value_list_diff<List...>::type;
  25716. /*! @brief Same as std::is_invocable, but with tuples. */
  25717. template<typename, typename>
  25718. struct is_applicable: std::false_type {};
  25719. /**
  25720. * @copybrief is_applicable
  25721. * @tparam Func A valid function type.
  25722. * @tparam Tuple Tuple-like type.
  25723. * @tparam Args The list of arguments to use to probe the function type.
  25724. */
  25725. template<typename Func, template<typename...> class Tuple, typename... Args>
  25726. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  25727. /**
  25728. * @copybrief is_applicable
  25729. * @tparam Func A valid function type.
  25730. * @tparam Tuple Tuple-like type.
  25731. * @tparam Args The list of arguments to use to probe the function type.
  25732. */
  25733. template<typename Func, template<typename...> class Tuple, typename... Args>
  25734. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  25735. /**
  25736. * @brief Helper variable template.
  25737. * @tparam Func A valid function type.
  25738. * @tparam Args The list of arguments to use to probe the function type.
  25739. */
  25740. template<typename Func, typename Args>
  25741. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  25742. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  25743. template<typename, typename, typename>
  25744. struct is_applicable_r: std::false_type {};
  25745. /**
  25746. * @copybrief is_applicable_r
  25747. * @tparam Ret The type to which the return type of the function should be
  25748. * convertible.
  25749. * @tparam Func A valid function type.
  25750. * @tparam Args The list of arguments to use to probe the function type.
  25751. */
  25752. template<typename Ret, typename Func, typename... Args>
  25753. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  25754. /**
  25755. * @brief Helper variable template.
  25756. * @tparam Ret The type to which the return type of the function should be
  25757. * convertible.
  25758. * @tparam Func A valid function type.
  25759. * @tparam Args The list of arguments to use to probe the function type.
  25760. */
  25761. template<typename Ret, typename Func, typename Args>
  25762. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  25763. /**
  25764. * @brief Provides the member constant `value` to true if a given type is
  25765. * complete, false otherwise.
  25766. * @tparam Type The type to test.
  25767. */
  25768. template<typename Type, typename = void>
  25769. struct is_complete: std::false_type {};
  25770. /*! @copydoc is_complete */
  25771. template<typename Type>
  25772. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  25773. /**
  25774. * @brief Helper variable template.
  25775. * @tparam Type The type to test.
  25776. */
  25777. template<typename Type>
  25778. inline constexpr bool is_complete_v = is_complete<Type>::value;
  25779. /**
  25780. * @brief Provides the member constant `value` to true if a given type is an
  25781. * iterator, false otherwise.
  25782. * @tparam Type The type to test.
  25783. */
  25784. template<typename Type, typename = void>
  25785. struct is_iterator: std::false_type {};
  25786. /*! @cond TURN_OFF_DOXYGEN */
  25787. namespace internal {
  25788. template<typename, typename = void>
  25789. struct has_iterator_category: std::false_type {};
  25790. template<typename Type>
  25791. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  25792. } // namespace internal
  25793. /*! @endcond */
  25794. /*! @copydoc is_iterator */
  25795. template<typename Type>
  25796. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  25797. : internal::has_iterator_category<Type> {};
  25798. /**
  25799. * @brief Helper variable template.
  25800. * @tparam Type The type to test.
  25801. */
  25802. template<typename Type>
  25803. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  25804. /**
  25805. * @brief Provides the member constant `value` to true if a given type is both
  25806. * an empty and non-final class, false otherwise.
  25807. * @tparam Type The type to test
  25808. */
  25809. template<typename Type>
  25810. struct is_ebco_eligible
  25811. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  25812. /**
  25813. * @brief Helper variable template.
  25814. * @tparam Type The type to test.
  25815. */
  25816. template<typename Type>
  25817. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  25818. /**
  25819. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  25820. * is valid and denotes a type, false otherwise.
  25821. * @tparam Type The type to test.
  25822. */
  25823. template<typename Type, typename = void>
  25824. struct is_transparent: std::false_type {};
  25825. /*! @copydoc is_transparent */
  25826. template<typename Type>
  25827. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  25828. /**
  25829. * @brief Helper variable template.
  25830. * @tparam Type The type to test.
  25831. */
  25832. template<typename Type>
  25833. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  25834. /*! @cond TURN_OFF_DOXYGEN */
  25835. namespace internal {
  25836. template<typename, typename = void>
  25837. struct has_tuple_size_value: std::false_type {};
  25838. template<typename Type>
  25839. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  25840. template<typename, typename = void>
  25841. struct has_value_type: std::false_type {};
  25842. template<typename Type>
  25843. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  25844. template<typename>
  25845. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  25846. template<typename Type, std::size_t... Index>
  25847. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  25848. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  25849. }
  25850. template<typename>
  25851. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  25852. return false;
  25853. }
  25854. template<typename Type>
  25855. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  25856. return true;
  25857. }
  25858. template<typename Type>
  25859. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  25860. // NOLINTBEGIN(modernize-use-transparent-functors)
  25861. if constexpr(std::is_array_v<Type>) {
  25862. return false;
  25863. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  25864. if constexpr(has_tuple_size_value<Type>::value) {
  25865. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  25866. } else {
  25867. return maybe_equality_comparable<Type>(0);
  25868. }
  25869. } else if constexpr(has_value_type<Type>::value) {
  25870. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  25871. return maybe_equality_comparable<Type>(0);
  25872. } else {
  25873. return false;
  25874. }
  25875. } else {
  25876. return maybe_equality_comparable<Type>(0);
  25877. }
  25878. // NOLINTEND(modernize-use-transparent-functors)
  25879. }
  25880. } // namespace internal
  25881. /*! @endcond */
  25882. /**
  25883. * @brief Provides the member constant `value` to true if a given type is
  25884. * equality comparable, false otherwise.
  25885. * @tparam Type The type to test.
  25886. */
  25887. template<typename Type>
  25888. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  25889. /*! @copydoc is_equality_comparable */
  25890. template<typename Type>
  25891. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  25892. /**
  25893. * @brief Helper variable template.
  25894. * @tparam Type The type to test.
  25895. */
  25896. template<typename Type>
  25897. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  25898. /**
  25899. * @brief Transcribes the constness of a type to another type.
  25900. * @tparam To The type to which to transcribe the constness.
  25901. * @tparam From The type from which to transcribe the constness.
  25902. */
  25903. template<typename To, typename From>
  25904. struct constness_as {
  25905. /*! @brief The type resulting from the transcription of the constness. */
  25906. using type = std::remove_const_t<To>;
  25907. };
  25908. /*! @copydoc constness_as */
  25909. template<typename To, typename From>
  25910. struct constness_as<To, const From> {
  25911. /*! @brief The type resulting from the transcription of the constness. */
  25912. using type = const To;
  25913. };
  25914. /**
  25915. * @brief Alias template to facilitate the transcription of the constness.
  25916. * @tparam To The type to which to transcribe the constness.
  25917. * @tparam From The type from which to transcribe the constness.
  25918. */
  25919. template<typename To, typename From>
  25920. using constness_as_t = typename constness_as<To, From>::type;
  25921. /**
  25922. * @brief Extracts the class of a non-static member object or function.
  25923. * @tparam Member A pointer to a non-static member object or function.
  25924. */
  25925. template<typename Member>
  25926. class member_class {
  25927. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  25928. template<typename Class, typename Ret, typename... Args>
  25929. static Class *clazz(Ret (Class::*)(Args...));
  25930. template<typename Class, typename Ret, typename... Args>
  25931. static Class *clazz(Ret (Class::*)(Args...) const);
  25932. template<typename Class, typename Type>
  25933. static Class *clazz(Type Class::*);
  25934. public:
  25935. /*! @brief The class of the given non-static member object or function. */
  25936. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  25937. };
  25938. /**
  25939. * @brief Helper type.
  25940. * @tparam Member A pointer to a non-static member object or function.
  25941. */
  25942. template<typename Member>
  25943. using member_class_t = typename member_class<Member>::type;
  25944. /**
  25945. * @brief Extracts the n-th argument of a _callable_ type.
  25946. * @tparam Index The index of the argument to extract.
  25947. * @tparam Candidate A valid _callable_ type.
  25948. */
  25949. template<std::size_t Index, typename Candidate>
  25950. class nth_argument {
  25951. template<typename Ret, typename... Args>
  25952. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  25953. template<typename Ret, typename Class, typename... Args>
  25954. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  25955. template<typename Ret, typename Class, typename... Args>
  25956. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  25957. template<typename Type, typename Class>
  25958. static constexpr type_list<Type> pick_up(Type Class ::*);
  25959. template<typename Type>
  25960. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  25961. public:
  25962. /*! @brief N-th argument of the _callable_ type. */
  25963. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  25964. };
  25965. /**
  25966. * @brief Helper type.
  25967. * @tparam Index The index of the argument to extract.
  25968. * @tparam Candidate A valid function, member function or data member type.
  25969. */
  25970. template<std::size_t Index, typename Candidate>
  25971. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  25972. } // namespace entt
  25973. template<typename... Type>
  25974. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  25975. template<std::size_t Index, typename... Type>
  25976. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  25977. template<auto... Value>
  25978. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  25979. template<std::size_t Index, auto... Value>
  25980. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  25981. #endif
  25982. // #include "fwd.hpp"
  25983. #ifndef ENTT_CONTAINER_FWD_HPP
  25984. #define ENTT_CONTAINER_FWD_HPP
  25985. #include <functional>
  25986. #include <memory>
  25987. #include <utility>
  25988. #include <vector>
  25989. namespace entt {
  25990. template<
  25991. typename Key,
  25992. typename Type,
  25993. typename = std::hash<Key>,
  25994. typename = std::equal_to<>,
  25995. typename = std::allocator<std::pair<const Key, Type>>>
  25996. class dense_map;
  25997. template<
  25998. typename Type,
  25999. typename = std::hash<Type>,
  26000. typename = std::equal_to<>,
  26001. typename = std::allocator<Type>>
  26002. class dense_set;
  26003. template<typename...>
  26004. class basic_table;
  26005. /**
  26006. * @brief Alias declaration for the most common use case.
  26007. * @tparam Type Element types.
  26008. */
  26009. template<typename... Type>
  26010. using table = basic_table<std::vector<Type>...>;
  26011. } // namespace entt
  26012. #endif
  26013. namespace entt {
  26014. /*! @cond TURN_OFF_DOXYGEN */
  26015. namespace internal {
  26016. static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  26017. template<typename Key, typename Type>
  26018. struct dense_map_node final {
  26019. using value_type = std::pair<Key, Type>;
  26020. template<typename... Args>
  26021. dense_map_node(const std::size_t pos, Args &&...args)
  26022. : next{pos},
  26023. element{std::forward<Args>(args)...} {}
  26024. template<typename Allocator, typename... Args>
  26025. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  26026. : next{pos},
  26027. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  26028. template<typename Allocator>
  26029. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  26030. : next{other.next},
  26031. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  26032. template<typename Allocator>
  26033. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  26034. : next{other.next},
  26035. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  26036. std::size_t next;
  26037. value_type element;
  26038. };
  26039. template<typename It>
  26040. class dense_map_iterator final {
  26041. template<typename>
  26042. friend class dense_map_iterator;
  26043. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  26044. using second_type = decltype((std::declval<It>()->element.second));
  26045. public:
  26046. using value_type = std::pair<first_type, second_type>;
  26047. using pointer = input_iterator_pointer<value_type>;
  26048. using reference = value_type;
  26049. using difference_type = std::ptrdiff_t;
  26050. using iterator_category = std::input_iterator_tag;
  26051. using iterator_concept = std::random_access_iterator_tag;
  26052. constexpr dense_map_iterator() noexcept
  26053. : it{} {}
  26054. constexpr dense_map_iterator(const It iter) noexcept
  26055. : it{iter} {}
  26056. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  26057. constexpr dense_map_iterator(const dense_map_iterator<Other> &other) noexcept
  26058. : it{other.it} {}
  26059. constexpr dense_map_iterator &operator++() noexcept {
  26060. return ++it, *this;
  26061. }
  26062. constexpr dense_map_iterator operator++(int) noexcept {
  26063. const dense_map_iterator orig = *this;
  26064. return ++(*this), orig;
  26065. }
  26066. constexpr dense_map_iterator &operator--() noexcept {
  26067. return --it, *this;
  26068. }
  26069. constexpr dense_map_iterator operator--(int) noexcept {
  26070. const dense_map_iterator orig = *this;
  26071. return operator--(), orig;
  26072. }
  26073. constexpr dense_map_iterator &operator+=(const difference_type value) noexcept {
  26074. it += value;
  26075. return *this;
  26076. }
  26077. constexpr dense_map_iterator operator+(const difference_type value) const noexcept {
  26078. dense_map_iterator copy = *this;
  26079. return (copy += value);
  26080. }
  26081. constexpr dense_map_iterator &operator-=(const difference_type value) noexcept {
  26082. return (*this += -value);
  26083. }
  26084. constexpr dense_map_iterator operator-(const difference_type value) const noexcept {
  26085. return (*this + -value);
  26086. }
  26087. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  26088. return {it[value].element.first, it[value].element.second};
  26089. }
  26090. [[nodiscard]] constexpr pointer operator->() const noexcept {
  26091. return operator*();
  26092. }
  26093. [[nodiscard]] constexpr reference operator*() const noexcept {
  26094. return operator[](0);
  26095. }
  26096. template<typename Lhs, typename Rhs>
  26097. friend constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  26098. template<typename Lhs, typename Rhs>
  26099. friend constexpr bool operator==(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  26100. template<typename Lhs, typename Rhs>
  26101. friend constexpr bool operator<(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  26102. private:
  26103. It it;
  26104. };
  26105. template<typename Lhs, typename Rhs>
  26106. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  26107. return lhs.it - rhs.it;
  26108. }
  26109. template<typename Lhs, typename Rhs>
  26110. [[nodiscard]] constexpr bool operator==(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  26111. return lhs.it == rhs.it;
  26112. }
  26113. template<typename Lhs, typename Rhs>
  26114. [[nodiscard]] constexpr bool operator!=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  26115. return !(lhs == rhs);
  26116. }
  26117. template<typename Lhs, typename Rhs>
  26118. [[nodiscard]] constexpr bool operator<(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  26119. return lhs.it < rhs.it;
  26120. }
  26121. template<typename Lhs, typename Rhs>
  26122. [[nodiscard]] constexpr bool operator>(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  26123. return rhs < lhs;
  26124. }
  26125. template<typename Lhs, typename Rhs>
  26126. [[nodiscard]] constexpr bool operator<=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  26127. return !(lhs > rhs);
  26128. }
  26129. template<typename Lhs, typename Rhs>
  26130. [[nodiscard]] constexpr bool operator>=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  26131. return !(lhs < rhs);
  26132. }
  26133. template<typename It>
  26134. class dense_map_local_iterator final {
  26135. template<typename>
  26136. friend class dense_map_local_iterator;
  26137. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  26138. using second_type = decltype((std::declval<It>()->element.second));
  26139. public:
  26140. using value_type = std::pair<first_type, second_type>;
  26141. using pointer = input_iterator_pointer<value_type>;
  26142. using reference = value_type;
  26143. using difference_type = std::ptrdiff_t;
  26144. using iterator_category = std::input_iterator_tag;
  26145. using iterator_concept = std::forward_iterator_tag;
  26146. constexpr dense_map_local_iterator() noexcept = default;
  26147. constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept
  26148. : it{iter},
  26149. offset{pos} {}
  26150. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  26151. constexpr dense_map_local_iterator(const dense_map_local_iterator<Other> &other) noexcept
  26152. : it{other.it},
  26153. offset{other.offset} {}
  26154. constexpr dense_map_local_iterator &operator++() noexcept {
  26155. return (offset = it[static_cast<typename It::difference_type>(offset)].next), *this;
  26156. }
  26157. constexpr dense_map_local_iterator operator++(int) noexcept {
  26158. const dense_map_local_iterator orig = *this;
  26159. return ++(*this), orig;
  26160. }
  26161. [[nodiscard]] constexpr pointer operator->() const noexcept {
  26162. return operator*();
  26163. }
  26164. [[nodiscard]] constexpr reference operator*() const noexcept {
  26165. const auto idx = static_cast<typename It::difference_type>(offset);
  26166. return {it[idx].element.first, it[idx].element.second};
  26167. }
  26168. [[nodiscard]] constexpr std::size_t index() const noexcept {
  26169. return offset;
  26170. }
  26171. private:
  26172. It it{};
  26173. std::size_t offset{dense_map_placeholder_position};
  26174. };
  26175. template<typename Lhs, typename Rhs>
  26176. [[nodiscard]] constexpr bool operator==(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  26177. return lhs.index() == rhs.index();
  26178. }
  26179. template<typename Lhs, typename Rhs>
  26180. [[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  26181. return !(lhs == rhs);
  26182. }
  26183. } // namespace internal
  26184. /*! @endcond */
  26185. /**
  26186. * @brief Associative container for key-value pairs with unique keys.
  26187. *
  26188. * Internally, elements are organized into buckets. Which bucket an element is
  26189. * placed into depends entirely on the hash of its key. Keys with the same hash
  26190. * code appear in the same bucket.
  26191. *
  26192. * @tparam Key Key type of the associative container.
  26193. * @tparam Type Mapped type of the associative container.
  26194. * @tparam Hash Type of function to use to hash the keys.
  26195. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  26196. * @tparam Allocator Type of allocator used to manage memory and elements.
  26197. */
  26198. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  26199. class dense_map {
  26200. static constexpr float default_threshold = 0.875f;
  26201. static constexpr std::size_t minimum_capacity = 8u;
  26202. static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position;
  26203. using node_type = internal::dense_map_node<Key, Type>;
  26204. using alloc_traits = std::allocator_traits<Allocator>;
  26205. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  26206. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  26207. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  26208. template<typename Other>
  26209. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept {
  26210. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  26211. return fast_mod(static_cast<size_type>(sparse.second()(key)), bucket_count());
  26212. }
  26213. template<typename Other>
  26214. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) {
  26215. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  26216. if(packed.second()(packed.first()[offset].element.first, key)) {
  26217. return begin() + static_cast<typename iterator::difference_type>(offset);
  26218. }
  26219. }
  26220. return end();
  26221. }
  26222. template<typename Other>
  26223. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const {
  26224. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  26225. if(packed.second()(packed.first()[offset].element.first, key)) {
  26226. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  26227. }
  26228. }
  26229. return cend();
  26230. }
  26231. template<typename Other, typename... Args>
  26232. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  26233. const auto index = key_to_bucket(key);
  26234. if(auto it = constrained_find(key, index); it != end()) {
  26235. return std::make_pair(it, false);
  26236. }
  26237. packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward<Other>(key)), std::forward_as_tuple(std::forward<Args>(args)...));
  26238. sparse.first()[index] = packed.first().size() - 1u;
  26239. rehash_if_required();
  26240. return std::make_pair(--end(), true);
  26241. }
  26242. template<typename Other, typename Arg>
  26243. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  26244. const auto index = key_to_bucket(key);
  26245. if(auto it = constrained_find(key, index); it != end()) {
  26246. it->second = std::forward<Arg>(value);
  26247. return std::make_pair(it, false);
  26248. }
  26249. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  26250. sparse.first()[index] = packed.first().size() - 1u;
  26251. rehash_if_required();
  26252. return std::make_pair(--end(), true);
  26253. }
  26254. void move_and_pop(const std::size_t pos) {
  26255. if(const auto last = size() - 1u; pos != last) {
  26256. size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)];
  26257. packed.first()[pos] = std::move(packed.first().back());
  26258. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  26259. *curr = pos;
  26260. }
  26261. packed.first().pop_back();
  26262. }
  26263. void rehash_if_required() {
  26264. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  26265. rehash(bc * 2u);
  26266. }
  26267. }
  26268. public:
  26269. /*! @brief Allocator type. */
  26270. using allocator_type = Allocator;
  26271. /*! @brief Key type of the container. */
  26272. using key_type = Key;
  26273. /*! @brief Mapped type of the container. */
  26274. using mapped_type = Type;
  26275. /*! @brief Key-value type of the container. */
  26276. using value_type = std::pair<const Key, Type>;
  26277. /*! @brief Unsigned integer type. */
  26278. using size_type = std::size_t;
  26279. /*! @brief Signed integer type. */
  26280. using difference_type = std::ptrdiff_t;
  26281. /*! @brief Type of function to use to hash the keys. */
  26282. using hasher = Hash;
  26283. /*! @brief Type of function to use to compare the keys for equality. */
  26284. using key_equal = KeyEqual;
  26285. /*! @brief Input iterator type. */
  26286. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  26287. /*! @brief Constant input iterator type. */
  26288. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  26289. /*! @brief Input iterator type. */
  26290. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  26291. /*! @brief Constant input iterator type. */
  26292. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  26293. /*! @brief Default constructor. */
  26294. dense_map()
  26295. : dense_map{minimum_capacity} {}
  26296. /**
  26297. * @brief Constructs an empty container with a given allocator.
  26298. * @param allocator The allocator to use.
  26299. */
  26300. explicit dense_map(const allocator_type &allocator)
  26301. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  26302. /**
  26303. * @brief Constructs an empty container with a given allocator and user
  26304. * supplied minimal number of buckets.
  26305. * @param cnt Minimal number of buckets.
  26306. * @param allocator The allocator to use.
  26307. */
  26308. dense_map(const size_type cnt, const allocator_type &allocator)
  26309. : dense_map{cnt, hasher{}, key_equal{}, allocator} {}
  26310. /**
  26311. * @brief Constructs an empty container with a given allocator, hash
  26312. * function and user supplied minimal number of buckets.
  26313. * @param cnt Minimal number of buckets.
  26314. * @param hash Hash function to use.
  26315. * @param allocator The allocator to use.
  26316. */
  26317. dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  26318. : dense_map{cnt, hash, key_equal{}, allocator} {}
  26319. /**
  26320. * @brief Constructs an empty container with a given allocator, hash
  26321. * function, compare function and user supplied minimal number of buckets.
  26322. * @param cnt Minimal number of buckets.
  26323. * @param hash Hash function to use.
  26324. * @param equal Compare function to use.
  26325. * @param allocator The allocator to use.
  26326. */
  26327. explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  26328. : sparse{allocator, hash},
  26329. packed{allocator, equal} {
  26330. rehash(cnt);
  26331. }
  26332. /*! @brief Default copy constructor. */
  26333. dense_map(const dense_map &) = default;
  26334. /**
  26335. * @brief Allocator-extended copy constructor.
  26336. * @param other The instance to copy from.
  26337. * @param allocator The allocator to use.
  26338. */
  26339. dense_map(const dense_map &other, const allocator_type &allocator)
  26340. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  26341. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  26342. threshold{other.threshold} {}
  26343. /*! @brief Default move constructor. */
  26344. dense_map(dense_map &&) noexcept = default;
  26345. /**
  26346. * @brief Allocator-extended move constructor.
  26347. * @param other The instance to move from.
  26348. * @param allocator The allocator to use.
  26349. */
  26350. dense_map(dense_map &&other, const allocator_type &allocator)
  26351. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  26352. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  26353. threshold{other.threshold} {}
  26354. /*! @brief Default destructor. */
  26355. ~dense_map() = default;
  26356. /**
  26357. * @brief Default copy assignment operator.
  26358. * @return This container.
  26359. */
  26360. dense_map &operator=(const dense_map &) = default;
  26361. /**
  26362. * @brief Default move assignment operator.
  26363. * @return This container.
  26364. */
  26365. dense_map &operator=(dense_map &&) noexcept = default;
  26366. /**
  26367. * @brief Exchanges the contents with those of a given container.
  26368. * @param other Container to exchange the content with.
  26369. */
  26370. void swap(dense_map &other) noexcept {
  26371. using std::swap;
  26372. swap(sparse, other.sparse);
  26373. swap(packed, other.packed);
  26374. swap(threshold, other.threshold);
  26375. }
  26376. /**
  26377. * @brief Returns the associated allocator.
  26378. * @return The associated allocator.
  26379. */
  26380. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  26381. return sparse.first().get_allocator();
  26382. }
  26383. /**
  26384. * @brief Returns an iterator to the beginning.
  26385. *
  26386. * If the array is empty, the returned iterator will be equal to `end()`.
  26387. *
  26388. * @return An iterator to the first instance of the internal array.
  26389. */
  26390. [[nodiscard]] const_iterator cbegin() const noexcept {
  26391. return packed.first().begin();
  26392. }
  26393. /*! @copydoc cbegin */
  26394. [[nodiscard]] const_iterator begin() const noexcept {
  26395. return cbegin();
  26396. }
  26397. /*! @copydoc begin */
  26398. [[nodiscard]] iterator begin() noexcept {
  26399. return packed.first().begin();
  26400. }
  26401. /**
  26402. * @brief Returns an iterator to the end.
  26403. * @return An iterator to the element following the last instance of the
  26404. * internal array.
  26405. */
  26406. [[nodiscard]] const_iterator cend() const noexcept {
  26407. return packed.first().end();
  26408. }
  26409. /*! @copydoc cend */
  26410. [[nodiscard]] const_iterator end() const noexcept {
  26411. return cend();
  26412. }
  26413. /*! @copydoc end */
  26414. [[nodiscard]] iterator end() noexcept {
  26415. return packed.first().end();
  26416. }
  26417. /**
  26418. * @brief Checks whether a container is empty.
  26419. * @return True if the container is empty, false otherwise.
  26420. */
  26421. [[nodiscard]] bool empty() const noexcept {
  26422. return packed.first().empty();
  26423. }
  26424. /**
  26425. * @brief Returns the number of elements in a container.
  26426. * @return Number of elements in a container.
  26427. */
  26428. [[nodiscard]] size_type size() const noexcept {
  26429. return packed.first().size();
  26430. }
  26431. /**
  26432. * @brief Returns the maximum possible number of elements.
  26433. * @return Maximum possible number of elements.
  26434. */
  26435. [[nodiscard]] size_type max_size() const noexcept {
  26436. return packed.first().max_size();
  26437. }
  26438. /*! @brief Clears the container. */
  26439. void clear() noexcept {
  26440. sparse.first().clear();
  26441. packed.first().clear();
  26442. rehash(0u);
  26443. }
  26444. /**
  26445. * @brief Inserts an element into the container, if the key does not exist.
  26446. * @param value A key-value pair eventually convertible to the value type.
  26447. * @return A pair consisting of an iterator to the inserted element (or to
  26448. * the element that prevented the insertion) and a bool denoting whether the
  26449. * insertion took place.
  26450. */
  26451. std::pair<iterator, bool> insert(const value_type &value) {
  26452. return insert_or_do_nothing(value.first, value.second);
  26453. }
  26454. /*! @copydoc insert */
  26455. std::pair<iterator, bool> insert(value_type &&value) {
  26456. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  26457. }
  26458. /**
  26459. * @copydoc insert
  26460. * @tparam Arg Type of the key-value pair to insert into the container.
  26461. */
  26462. template<typename Arg>
  26463. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  26464. insert(Arg &&value) {
  26465. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  26466. }
  26467. /**
  26468. * @brief Inserts elements into the container, if their keys do not exist.
  26469. * @tparam It Type of input iterator.
  26470. * @param first An iterator to the first element of the range of elements.
  26471. * @param last An iterator past the last element of the range of elements.
  26472. */
  26473. template<typename It>
  26474. void insert(It first, It last) {
  26475. for(; first != last; ++first) {
  26476. insert(*first);
  26477. }
  26478. }
  26479. /**
  26480. * @brief Inserts an element into the container or assigns to the current
  26481. * element if the key already exists.
  26482. * @tparam Arg Type of the value to insert or assign.
  26483. * @param key A key used both to look up and to insert if not found.
  26484. * @param value A value to insert or assign.
  26485. * @return A pair consisting of an iterator to the element and a bool
  26486. * denoting whether the insertion took place.
  26487. */
  26488. template<typename Arg>
  26489. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  26490. return insert_or_overwrite(key, std::forward<Arg>(value));
  26491. }
  26492. /*! @copydoc insert_or_assign */
  26493. template<typename Arg>
  26494. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  26495. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  26496. }
  26497. /**
  26498. * @brief Constructs an element in-place, if the key does not exist.
  26499. *
  26500. * The element is also constructed when the container already has the key,
  26501. * in which case the newly constructed object is destroyed immediately.
  26502. *
  26503. * @tparam Args Types of arguments to forward to the constructor of the
  26504. * element.
  26505. * @param args Arguments to forward to the constructor of the element.
  26506. * @return A pair consisting of an iterator to the inserted element (or to
  26507. * the element that prevented the insertion) and a bool denoting whether the
  26508. * insertion took place.
  26509. */
  26510. template<typename... Args>
  26511. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  26512. if constexpr(sizeof...(Args) == 0u) {
  26513. return insert_or_do_nothing(key_type{});
  26514. } else if constexpr(sizeof...(Args) == 1u) {
  26515. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  26516. } else if constexpr(sizeof...(Args) == 2u) {
  26517. return insert_or_do_nothing(std::forward<Args>(args)...);
  26518. } else {
  26519. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  26520. const auto index = key_to_bucket(node.element.first);
  26521. if(auto it = constrained_find(node.element.first, index); it != end()) {
  26522. packed.first().pop_back();
  26523. return std::make_pair(it, false);
  26524. }
  26525. std::swap(node.next, sparse.first()[index]);
  26526. rehash_if_required();
  26527. return std::make_pair(--end(), true);
  26528. }
  26529. }
  26530. /**
  26531. * @brief Inserts in-place if the key does not exist, does nothing if the
  26532. * key exists.
  26533. * @tparam Args Types of arguments to forward to the constructor of the
  26534. * element.
  26535. * @param key A key used both to look up and to insert if not found.
  26536. * @param args Arguments to forward to the constructor of the element.
  26537. * @return A pair consisting of an iterator to the inserted element (or to
  26538. * the element that prevented the insertion) and a bool denoting whether the
  26539. * insertion took place.
  26540. */
  26541. template<typename... Args>
  26542. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  26543. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  26544. }
  26545. /*! @copydoc try_emplace */
  26546. template<typename... Args>
  26547. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  26548. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  26549. }
  26550. /**
  26551. * @brief Removes an element from a given position.
  26552. * @param pos An iterator to the element to remove.
  26553. * @return An iterator following the removed element.
  26554. */
  26555. iterator erase(const_iterator pos) {
  26556. const auto diff = pos - cbegin();
  26557. erase(pos->first);
  26558. return begin() + diff;
  26559. }
  26560. /**
  26561. * @brief Removes the given elements from a container.
  26562. * @param first An iterator to the first element of the range of elements.
  26563. * @param last An iterator past the last element of the range of elements.
  26564. * @return An iterator following the last removed element.
  26565. */
  26566. iterator erase(const_iterator first, const_iterator last) {
  26567. const auto dist = first - cbegin();
  26568. for(auto from = last - cbegin(); from != dist; --from) {
  26569. erase(packed.first()[static_cast<size_type>(from) - 1u].element.first);
  26570. }
  26571. return (begin() + dist);
  26572. }
  26573. /**
  26574. * @brief Removes the element associated with a given key.
  26575. * @param key A key value of an element to remove.
  26576. * @return Number of elements removed (either 0 or 1).
  26577. */
  26578. size_type erase(const key_type &key) {
  26579. for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) {
  26580. if(packed.second()(packed.first()[*curr].element.first, key)) {
  26581. const auto index = *curr;
  26582. *curr = packed.first()[*curr].next;
  26583. move_and_pop(index);
  26584. return 1u;
  26585. }
  26586. }
  26587. return 0u;
  26588. }
  26589. /**
  26590. * @brief Accesses a given element with bounds checking.
  26591. * @param key A key of an element to find.
  26592. * @return A reference to the mapped value of the requested element.
  26593. */
  26594. [[nodiscard]] mapped_type &at(const key_type &key) {
  26595. auto it = find(key);
  26596. ENTT_ASSERT(it != end(), "Invalid key");
  26597. return it->second;
  26598. }
  26599. /*! @copydoc at */
  26600. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  26601. auto it = find(key);
  26602. ENTT_ASSERT(it != cend(), "Invalid key");
  26603. return it->second;
  26604. }
  26605. /**
  26606. * @brief Accesses a given element with bounds checking.
  26607. * @tparam Other Type of the key of an element to find.
  26608. * @param key A key of an element to find.
  26609. * @return A reference to the mapped value of the requested element.
  26610. */
  26611. template<typename Other>
  26612. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type const &>>
  26613. at(const Other &key) const {
  26614. auto it = find(key);
  26615. ENTT_ASSERT(it != cend(), "Invalid key");
  26616. return it->second;
  26617. }
  26618. /*! @copydoc at */
  26619. template<typename Other>
  26620. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type &>>
  26621. at(const Other &key) {
  26622. auto it = find(key);
  26623. ENTT_ASSERT(it != end(), "Invalid key");
  26624. return it->second;
  26625. }
  26626. /**
  26627. * @brief Accesses or inserts a given element.
  26628. * @param key A key of an element to find or insert.
  26629. * @return A reference to the mapped value of the requested element.
  26630. */
  26631. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  26632. return insert_or_do_nothing(key).first->second;
  26633. }
  26634. /**
  26635. * @brief Accesses or inserts a given element.
  26636. * @param key A key of an element to find or insert.
  26637. * @return A reference to the mapped value of the requested element.
  26638. */
  26639. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  26640. return insert_or_do_nothing(std::move(key)).first->second;
  26641. }
  26642. /**
  26643. * @brief Returns the number of elements matching a key (either 1 or 0).
  26644. * @param key Key value of an element to search for.
  26645. * @return Number of elements matching the key (either 1 or 0).
  26646. */
  26647. [[nodiscard]] size_type count(const key_type &key) const {
  26648. return find(key) != end();
  26649. }
  26650. /**
  26651. * @brief Returns the number of elements matching a key (either 1 or 0).
  26652. * @tparam Other Type of the key value of an element to search for.
  26653. * @param key Key value of an element to search for.
  26654. * @return Number of elements matching the key (either 1 or 0).
  26655. */
  26656. template<typename Other>
  26657. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  26658. count(const Other &key) const {
  26659. return find(key) != end();
  26660. }
  26661. /**
  26662. * @brief Finds an element with a given key.
  26663. * @param key Key value of an element to search for.
  26664. * @return An iterator to an element with the given key. If no such element
  26665. * is found, a past-the-end iterator is returned.
  26666. */
  26667. [[nodiscard]] iterator find(const key_type &key) {
  26668. return constrained_find(key, key_to_bucket(key));
  26669. }
  26670. /*! @copydoc find */
  26671. [[nodiscard]] const_iterator find(const key_type &key) const {
  26672. return constrained_find(key, key_to_bucket(key));
  26673. }
  26674. /**
  26675. * @brief Finds an element with a key that compares _equivalent_ to a given
  26676. * key.
  26677. * @tparam Other Type of the key value of an element to search for.
  26678. * @param key Key value of an element to search for.
  26679. * @return An iterator to an element with the given key. If no such element
  26680. * is found, a past-the-end iterator is returned.
  26681. */
  26682. template<typename Other>
  26683. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  26684. find(const Other &key) {
  26685. return constrained_find(key, key_to_bucket(key));
  26686. }
  26687. /*! @copydoc find */
  26688. template<typename Other>
  26689. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  26690. find(const Other &key) const {
  26691. return constrained_find(key, key_to_bucket(key));
  26692. }
  26693. /**
  26694. * @brief Returns a range containing all elements with a given key.
  26695. * @param key Key value of an element to search for.
  26696. * @return A pair of iterators pointing to the first element and past the
  26697. * last element of the range.
  26698. */
  26699. [[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
  26700. const auto it = find(key);
  26701. return {it, it + !(it == end())};
  26702. }
  26703. /*! @copydoc equal_range */
  26704. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
  26705. const auto it = find(key);
  26706. return {it, it + !(it == cend())};
  26707. }
  26708. /**
  26709. * @brief Returns a range containing all elements that compare _equivalent_
  26710. * to a given key.
  26711. * @tparam Other Type of an element to search for.
  26712. * @param key Key value of an element to search for.
  26713. * @return A pair of iterators pointing to the first element and past the
  26714. * last element of the range.
  26715. */
  26716. template<typename Other>
  26717. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  26718. equal_range(const Other &key) {
  26719. const auto it = find(key);
  26720. return {it, it + !(it == end())};
  26721. }
  26722. /*! @copydoc equal_range */
  26723. template<typename Other>
  26724. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  26725. equal_range(const Other &key) const {
  26726. const auto it = find(key);
  26727. return {it, it + !(it == cend())};
  26728. }
  26729. /**
  26730. * @brief Checks if the container contains an element with a given key.
  26731. * @param key Key value of an element to search for.
  26732. * @return True if there is such an element, false otherwise.
  26733. */
  26734. [[nodiscard]] bool contains(const key_type &key) const {
  26735. return (find(key) != cend());
  26736. }
  26737. /**
  26738. * @brief Checks if the container contains an element with a key that
  26739. * compares _equivalent_ to a given value.
  26740. * @tparam Other Type of the key value of an element to search for.
  26741. * @param key Key value of an element to search for.
  26742. * @return True if there is such an element, false otherwise.
  26743. */
  26744. template<typename Other>
  26745. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  26746. contains(const Other &key) const {
  26747. return (find(key) != cend());
  26748. }
  26749. /**
  26750. * @brief Returns an iterator to the beginning of a given bucket.
  26751. * @param index An index of a bucket to access.
  26752. * @return An iterator to the beginning of the given bucket.
  26753. */
  26754. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  26755. return {packed.first().begin(), sparse.first()[index]};
  26756. }
  26757. /**
  26758. * @brief Returns an iterator to the beginning of a given bucket.
  26759. * @param index An index of a bucket to access.
  26760. * @return An iterator to the beginning of the given bucket.
  26761. */
  26762. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  26763. return cbegin(index);
  26764. }
  26765. /**
  26766. * @brief Returns an iterator to the beginning of a given bucket.
  26767. * @param index An index of a bucket to access.
  26768. * @return An iterator to the beginning of the given bucket.
  26769. */
  26770. [[nodiscard]] local_iterator begin(const size_type index) {
  26771. return {packed.first().begin(), sparse.first()[index]};
  26772. }
  26773. /**
  26774. * @brief Returns an iterator to the end of a given bucket.
  26775. * @param index An index of a bucket to access.
  26776. * @return An iterator to the end of the given bucket.
  26777. */
  26778. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  26779. return {};
  26780. }
  26781. /**
  26782. * @brief Returns an iterator to the end of a given bucket.
  26783. * @param index An index of a bucket to access.
  26784. * @return An iterator to the end of the given bucket.
  26785. */
  26786. [[nodiscard]] const_local_iterator end(const size_type index) const {
  26787. return cend(index);
  26788. }
  26789. /**
  26790. * @brief Returns an iterator to the end of a given bucket.
  26791. * @param index An index of a bucket to access.
  26792. * @return An iterator to the end of the given bucket.
  26793. */
  26794. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  26795. return {};
  26796. }
  26797. /**
  26798. * @brief Returns the number of buckets.
  26799. * @return The number of buckets.
  26800. */
  26801. [[nodiscard]] size_type bucket_count() const {
  26802. return sparse.first().size();
  26803. }
  26804. /**
  26805. * @brief Returns the maximum number of buckets.
  26806. * @return The maximum number of buckets.
  26807. */
  26808. [[nodiscard]] size_type max_bucket_count() const {
  26809. return sparse.first().max_size();
  26810. }
  26811. /**
  26812. * @brief Returns the number of elements in a given bucket.
  26813. * @param index The index of the bucket to examine.
  26814. * @return The number of elements in the given bucket.
  26815. */
  26816. [[nodiscard]] size_type bucket_size(const size_type index) const {
  26817. return static_cast<size_type>(std::distance(begin(index), end(index)));
  26818. }
  26819. /**
  26820. * @brief Returns the bucket for a given key.
  26821. * @param key The value of the key to examine.
  26822. * @return The bucket for the given key.
  26823. */
  26824. [[nodiscard]] size_type bucket(const key_type &key) const {
  26825. return key_to_bucket(key);
  26826. }
  26827. /**
  26828. * @brief Returns the average number of elements per bucket.
  26829. * @return The average number of elements per bucket.
  26830. */
  26831. [[nodiscard]] float load_factor() const {
  26832. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  26833. }
  26834. /**
  26835. * @brief Returns the maximum average number of elements per bucket.
  26836. * @return The maximum average number of elements per bucket.
  26837. */
  26838. [[nodiscard]] float max_load_factor() const {
  26839. return threshold;
  26840. }
  26841. /**
  26842. * @brief Sets the desired maximum average number of elements per bucket.
  26843. * @param value A desired maximum average number of elements per bucket.
  26844. */
  26845. void max_load_factor(const float value) {
  26846. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  26847. threshold = value;
  26848. rehash(0u);
  26849. }
  26850. /**
  26851. * @brief Reserves at least the specified number of buckets and regenerates
  26852. * the hash table.
  26853. * @param cnt New number of buckets.
  26854. */
  26855. void rehash(const size_type cnt) {
  26856. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  26857. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  26858. value = value > cap ? value : cap;
  26859. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  26860. sparse.first().resize(sz);
  26861. for(auto &&elem: sparse.first()) {
  26862. elem = placeholder_position;
  26863. }
  26864. for(size_type pos{}, last = size(); pos < last; ++pos) {
  26865. const auto index = key_to_bucket(packed.first()[pos].element.first);
  26866. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  26867. }
  26868. }
  26869. }
  26870. /**
  26871. * @brief Reserves space for at least the specified number of elements and
  26872. * regenerates the hash table.
  26873. * @param cnt New number of elements.
  26874. */
  26875. void reserve(const size_type cnt) {
  26876. packed.first().reserve(cnt);
  26877. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  26878. }
  26879. /**
  26880. * @brief Returns the function used to hash the keys.
  26881. * @return The function used to hash the keys.
  26882. */
  26883. [[nodiscard]] hasher hash_function() const {
  26884. return sparse.second();
  26885. }
  26886. /**
  26887. * @brief Returns the function used to compare keys for equality.
  26888. * @return The function used to compare keys for equality.
  26889. */
  26890. [[nodiscard]] key_equal key_eq() const {
  26891. return packed.second();
  26892. }
  26893. private:
  26894. compressed_pair<sparse_container_type, hasher> sparse;
  26895. compressed_pair<packed_container_type, key_equal> packed;
  26896. float threshold{default_threshold};
  26897. };
  26898. } // namespace entt
  26899. /*! @cond TURN_OFF_DOXYGEN */
  26900. namespace std {
  26901. template<typename Key, typename Value, typename Allocator>
  26902. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  26903. : std::true_type {};
  26904. } // namespace std
  26905. /*! @endcond */
  26906. #endif
  26907. // #include "../container/dense_set.hpp"
  26908. #ifndef ENTT_CONTAINER_DENSE_SET_HPP
  26909. #define ENTT_CONTAINER_DENSE_SET_HPP
  26910. #include <cmath>
  26911. #include <cstddef>
  26912. #include <functional>
  26913. #include <iterator>
  26914. #include <limits>
  26915. #include <memory>
  26916. #include <tuple>
  26917. #include <type_traits>
  26918. #include <utility>
  26919. #include <vector>
  26920. // #include "../config/config.h"
  26921. // #include "../core/bit.hpp"
  26922. // #include "../core/compressed_pair.hpp"
  26923. // #include "../core/type_traits.hpp"
  26924. // #include "fwd.hpp"
  26925. namespace entt {
  26926. /*! @cond TURN_OFF_DOXYGEN */
  26927. namespace internal {
  26928. static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  26929. template<typename It>
  26930. class dense_set_iterator final {
  26931. template<typename>
  26932. friend class dense_set_iterator;
  26933. public:
  26934. using value_type = typename It::value_type::second_type;
  26935. using pointer = const value_type *;
  26936. using reference = const value_type &;
  26937. using difference_type = std::ptrdiff_t;
  26938. using iterator_category = std::random_access_iterator_tag;
  26939. constexpr dense_set_iterator() noexcept
  26940. : it{} {}
  26941. constexpr dense_set_iterator(const It iter) noexcept
  26942. : it{iter} {}
  26943. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  26944. constexpr dense_set_iterator(const dense_set_iterator<Other> &other) noexcept
  26945. : it{other.it} {}
  26946. constexpr dense_set_iterator &operator++() noexcept {
  26947. return ++it, *this;
  26948. }
  26949. constexpr dense_set_iterator operator++(int) noexcept {
  26950. const dense_set_iterator orig = *this;
  26951. return ++(*this), orig;
  26952. }
  26953. constexpr dense_set_iterator &operator--() noexcept {
  26954. return --it, *this;
  26955. }
  26956. constexpr dense_set_iterator operator--(int) noexcept {
  26957. const dense_set_iterator orig = *this;
  26958. return operator--(), orig;
  26959. }
  26960. constexpr dense_set_iterator &operator+=(const difference_type value) noexcept {
  26961. it += value;
  26962. return *this;
  26963. }
  26964. constexpr dense_set_iterator operator+(const difference_type value) const noexcept {
  26965. dense_set_iterator copy = *this;
  26966. return (copy += value);
  26967. }
  26968. constexpr dense_set_iterator &operator-=(const difference_type value) noexcept {
  26969. return (*this += -value);
  26970. }
  26971. constexpr dense_set_iterator operator-(const difference_type value) const noexcept {
  26972. return (*this + -value);
  26973. }
  26974. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  26975. return it[value].second;
  26976. }
  26977. [[nodiscard]] constexpr pointer operator->() const noexcept {
  26978. return std::addressof(operator[](0));
  26979. }
  26980. [[nodiscard]] constexpr reference operator*() const noexcept {
  26981. return operator[](0);
  26982. }
  26983. template<typename Lhs, typename Rhs>
  26984. friend constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  26985. template<typename Lhs, typename Rhs>
  26986. friend constexpr bool operator==(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  26987. template<typename Lhs, typename Rhs>
  26988. friend constexpr bool operator<(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  26989. private:
  26990. It it;
  26991. };
  26992. template<typename Lhs, typename Rhs>
  26993. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  26994. return lhs.it - rhs.it;
  26995. }
  26996. template<typename Lhs, typename Rhs>
  26997. [[nodiscard]] constexpr bool operator==(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  26998. return lhs.it == rhs.it;
  26999. }
  27000. template<typename Lhs, typename Rhs>
  27001. [[nodiscard]] constexpr bool operator!=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  27002. return !(lhs == rhs);
  27003. }
  27004. template<typename Lhs, typename Rhs>
  27005. [[nodiscard]] constexpr bool operator<(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  27006. return lhs.it < rhs.it;
  27007. }
  27008. template<typename Lhs, typename Rhs>
  27009. [[nodiscard]] constexpr bool operator>(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  27010. return rhs < lhs;
  27011. }
  27012. template<typename Lhs, typename Rhs>
  27013. [[nodiscard]] constexpr bool operator<=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  27014. return !(lhs > rhs);
  27015. }
  27016. template<typename Lhs, typename Rhs>
  27017. [[nodiscard]] constexpr bool operator>=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  27018. return !(lhs < rhs);
  27019. }
  27020. template<typename It>
  27021. class dense_set_local_iterator final {
  27022. template<typename>
  27023. friend class dense_set_local_iterator;
  27024. public:
  27025. using value_type = typename It::value_type::second_type;
  27026. using pointer = const value_type *;
  27027. using reference = const value_type &;
  27028. using difference_type = std::ptrdiff_t;
  27029. using iterator_category = std::forward_iterator_tag;
  27030. constexpr dense_set_local_iterator() noexcept = default;
  27031. constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept
  27032. : it{iter},
  27033. offset{pos} {}
  27034. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  27035. constexpr dense_set_local_iterator(const dense_set_local_iterator<Other> &other) noexcept
  27036. : it{other.it},
  27037. offset{other.offset} {}
  27038. constexpr dense_set_local_iterator &operator++() noexcept {
  27039. return offset = it[static_cast<typename It::difference_type>(offset)].first, *this;
  27040. }
  27041. constexpr dense_set_local_iterator operator++(int) noexcept {
  27042. const dense_set_local_iterator orig = *this;
  27043. return ++(*this), orig;
  27044. }
  27045. [[nodiscard]] constexpr pointer operator->() const noexcept {
  27046. return std::addressof(it[static_cast<typename It::difference_type>(offset)].second);
  27047. }
  27048. [[nodiscard]] constexpr reference operator*() const noexcept {
  27049. return *operator->();
  27050. }
  27051. [[nodiscard]] constexpr std::size_t index() const noexcept {
  27052. return offset;
  27053. }
  27054. private:
  27055. It it{};
  27056. std::size_t offset{dense_set_placeholder_position};
  27057. };
  27058. template<typename Lhs, typename Rhs>
  27059. [[nodiscard]] constexpr bool operator==(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  27060. return lhs.index() == rhs.index();
  27061. }
  27062. template<typename Lhs, typename Rhs>
  27063. [[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  27064. return !(lhs == rhs);
  27065. }
  27066. } // namespace internal
  27067. /*! @endcond */
  27068. /**
  27069. * @brief Associative container for unique objects of a given type.
  27070. *
  27071. * Internally, elements are organized into buckets. Which bucket an element is
  27072. * placed into depends entirely on its hash. Elements with the same hash code
  27073. * appear in the same bucket.
  27074. *
  27075. * @tparam Type Value type of the associative container.
  27076. * @tparam Hash Type of function to use to hash the values.
  27077. * @tparam KeyEqual Type of function to use to compare the values for equality.
  27078. * @tparam Allocator Type of allocator used to manage memory and elements.
  27079. */
  27080. template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
  27081. class dense_set {
  27082. static constexpr float default_threshold = 0.875f;
  27083. static constexpr std::size_t minimum_capacity = 8u;
  27084. static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position;
  27085. using node_type = std::pair<std::size_t, Type>;
  27086. using alloc_traits = std::allocator_traits<Allocator>;
  27087. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  27088. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  27089. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  27090. template<typename Other>
  27091. [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept {
  27092. return fast_mod(static_cast<size_type>(sparse.second()(value)), bucket_count());
  27093. }
  27094. template<typename Other>
  27095. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) {
  27096. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  27097. if(packed.second()(packed.first()[offset].second, value)) {
  27098. return begin() + static_cast<typename iterator::difference_type>(offset);
  27099. }
  27100. }
  27101. return end();
  27102. }
  27103. template<typename Other>
  27104. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const {
  27105. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  27106. if(packed.second()(packed.first()[offset].second, value)) {
  27107. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  27108. }
  27109. }
  27110. return cend();
  27111. }
  27112. template<typename Other>
  27113. [[nodiscard]] auto insert_or_do_nothing(Other &&value) {
  27114. const auto index = value_to_bucket(value);
  27115. if(auto it = constrained_find(value, index); it != end()) {
  27116. return std::make_pair(it, false);
  27117. }
  27118. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(value));
  27119. sparse.first()[index] = packed.first().size() - 1u;
  27120. rehash_if_required();
  27121. return std::make_pair(--end(), true);
  27122. }
  27123. void move_and_pop(const std::size_t pos) {
  27124. if(const auto last = size() - 1u; pos != last) {
  27125. size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)];
  27126. packed.first()[pos] = std::move(packed.first().back());
  27127. for(; *curr != last; curr = &packed.first()[*curr].first) {}
  27128. *curr = pos;
  27129. }
  27130. packed.first().pop_back();
  27131. }
  27132. void rehash_if_required() {
  27133. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  27134. rehash(bc * 2u);
  27135. }
  27136. }
  27137. public:
  27138. /*! @brief Allocator type. */
  27139. using allocator_type = Allocator;
  27140. /*! @brief Key type of the container. */
  27141. using key_type = Type;
  27142. /*! @brief Value type of the container. */
  27143. using value_type = Type;
  27144. /*! @brief Unsigned integer type. */
  27145. using size_type = std::size_t;
  27146. /*! @brief Signed integer type. */
  27147. using difference_type = std::ptrdiff_t;
  27148. /*! @brief Type of function to use to hash the elements. */
  27149. using hasher = Hash;
  27150. /*! @brief Type of function to use to compare the elements for equality. */
  27151. using key_equal = KeyEqual;
  27152. /*! @brief Random access iterator type. */
  27153. using iterator = internal::dense_set_iterator<typename packed_container_type::iterator>;
  27154. /*! @brief Constant random access iterator type. */
  27155. using const_iterator = internal::dense_set_iterator<typename packed_container_type::const_iterator>;
  27156. /*! @brief Reverse iterator type. */
  27157. using reverse_iterator = std::reverse_iterator<iterator>;
  27158. /*! @brief Constant reverse iterator type. */
  27159. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  27160. /*! @brief Forward iterator type. */
  27161. using local_iterator = internal::dense_set_local_iterator<typename packed_container_type::iterator>;
  27162. /*! @brief Constant forward iterator type. */
  27163. using const_local_iterator = internal::dense_set_local_iterator<typename packed_container_type::const_iterator>;
  27164. /*! @brief Default constructor. */
  27165. dense_set()
  27166. : dense_set{minimum_capacity} {}
  27167. /**
  27168. * @brief Constructs an empty container with a given allocator.
  27169. * @param allocator The allocator to use.
  27170. */
  27171. explicit dense_set(const allocator_type &allocator)
  27172. : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  27173. /**
  27174. * @brief Constructs an empty container with a given allocator and user
  27175. * supplied minimal number of buckets.
  27176. * @param cnt Minimal number of buckets.
  27177. * @param allocator The allocator to use.
  27178. */
  27179. dense_set(const size_type cnt, const allocator_type &allocator)
  27180. : dense_set{cnt, hasher{}, key_equal{}, allocator} {}
  27181. /**
  27182. * @brief Constructs an empty container with a given allocator, hash
  27183. * function and user supplied minimal number of buckets.
  27184. * @param cnt Minimal number of buckets.
  27185. * @param hash Hash function to use.
  27186. * @param allocator The allocator to use.
  27187. */
  27188. dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  27189. : dense_set{cnt, hash, key_equal{}, allocator} {}
  27190. /**
  27191. * @brief Constructs an empty container with a given allocator, hash
  27192. * function, compare function and user supplied minimal number of buckets.
  27193. * @param cnt Minimal number of buckets.
  27194. * @param hash Hash function to use.
  27195. * @param equal Compare function to use.
  27196. * @param allocator The allocator to use.
  27197. */
  27198. explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  27199. : sparse{allocator, hash},
  27200. packed{allocator, equal} {
  27201. rehash(cnt);
  27202. }
  27203. /*! @brief Default copy constructor. */
  27204. dense_set(const dense_set &) = default;
  27205. /**
  27206. * @brief Allocator-extended copy constructor.
  27207. * @param other The instance to copy from.
  27208. * @param allocator The allocator to use.
  27209. */
  27210. dense_set(const dense_set &other, const allocator_type &allocator)
  27211. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  27212. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  27213. threshold{other.threshold} {}
  27214. /*! @brief Default move constructor. */
  27215. dense_set(dense_set &&) noexcept = default;
  27216. /**
  27217. * @brief Allocator-extended move constructor.
  27218. * @param other The instance to move from.
  27219. * @param allocator The allocator to use.
  27220. */
  27221. dense_set(dense_set &&other, const allocator_type &allocator)
  27222. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  27223. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  27224. threshold{other.threshold} {}
  27225. /*! @brief Default destructor. */
  27226. ~dense_set() = default;
  27227. /**
  27228. * @brief Default copy assignment operator.
  27229. * @return This container.
  27230. */
  27231. dense_set &operator=(const dense_set &) = default;
  27232. /**
  27233. * @brief Default move assignment operator.
  27234. * @return This container.
  27235. */
  27236. dense_set &operator=(dense_set &&) noexcept = default;
  27237. /**
  27238. * @brief Exchanges the contents with those of a given container.
  27239. * @param other Container to exchange the content with.
  27240. */
  27241. void swap(dense_set &other) noexcept {
  27242. using std::swap;
  27243. swap(sparse, other.sparse);
  27244. swap(packed, other.packed);
  27245. swap(threshold, other.threshold);
  27246. }
  27247. /**
  27248. * @brief Returns the associated allocator.
  27249. * @return The associated allocator.
  27250. */
  27251. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  27252. return sparse.first().get_allocator();
  27253. }
  27254. /**
  27255. * @brief Returns an iterator to the beginning.
  27256. *
  27257. * If the array is empty, the returned iterator will be equal to `end()`.
  27258. *
  27259. * @return An iterator to the first instance of the internal array.
  27260. */
  27261. [[nodiscard]] const_iterator cbegin() const noexcept {
  27262. return packed.first().begin();
  27263. }
  27264. /*! @copydoc cbegin */
  27265. [[nodiscard]] const_iterator begin() const noexcept {
  27266. return cbegin();
  27267. }
  27268. /*! @copydoc begin */
  27269. [[nodiscard]] iterator begin() noexcept {
  27270. return packed.first().begin();
  27271. }
  27272. /**
  27273. * @brief Returns an iterator to the end.
  27274. * @return An iterator to the element following the last instance of the
  27275. * internal array.
  27276. */
  27277. [[nodiscard]] const_iterator cend() const noexcept {
  27278. return packed.first().end();
  27279. }
  27280. /*! @copydoc cend */
  27281. [[nodiscard]] const_iterator end() const noexcept {
  27282. return cend();
  27283. }
  27284. /*! @copydoc end */
  27285. [[nodiscard]] iterator end() noexcept {
  27286. return packed.first().end();
  27287. }
  27288. /**
  27289. * @brief Returns a reverse iterator to the beginning.
  27290. *
  27291. * If the array is empty, the returned iterator will be equal to `rend()`.
  27292. *
  27293. * @return An iterator to the first instance of the reversed internal array.
  27294. */
  27295. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  27296. return std::make_reverse_iterator(cend());
  27297. }
  27298. /*! @copydoc crbegin */
  27299. [[nodiscard]] const_reverse_iterator rbegin() const noexcept {
  27300. return crbegin();
  27301. }
  27302. /*! @copydoc rbegin */
  27303. [[nodiscard]] reverse_iterator rbegin() noexcept {
  27304. return std::make_reverse_iterator(end());
  27305. }
  27306. /**
  27307. * @brief Returns a reverse iterator to the end.
  27308. * @return An iterator to the element following the last instance of the
  27309. * reversed internal array.
  27310. */
  27311. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  27312. return std::make_reverse_iterator(cbegin());
  27313. }
  27314. /*! @copydoc crend */
  27315. [[nodiscard]] const_reverse_iterator rend() const noexcept {
  27316. return crend();
  27317. }
  27318. /*! @copydoc rend */
  27319. [[nodiscard]] reverse_iterator rend() noexcept {
  27320. return std::make_reverse_iterator(begin());
  27321. }
  27322. /**
  27323. * @brief Checks whether a container is empty.
  27324. * @return True if the container is empty, false otherwise.
  27325. */
  27326. [[nodiscard]] bool empty() const noexcept {
  27327. return packed.first().empty();
  27328. }
  27329. /**
  27330. * @brief Returns the number of elements in a container.
  27331. * @return Number of elements in a container.
  27332. */
  27333. [[nodiscard]] size_type size() const noexcept {
  27334. return packed.first().size();
  27335. }
  27336. /**
  27337. * @brief Returns the maximum possible number of elements.
  27338. * @return Maximum possible number of elements.
  27339. */
  27340. [[nodiscard]] size_type max_size() const noexcept {
  27341. return packed.first().max_size();
  27342. }
  27343. /*! @brief Clears the container. */
  27344. void clear() noexcept {
  27345. sparse.first().clear();
  27346. packed.first().clear();
  27347. rehash(0u);
  27348. }
  27349. /**
  27350. * @brief Inserts an element into the container, if it does not exist.
  27351. * @param value An element to insert into the container.
  27352. * @return A pair consisting of an iterator to the inserted element (or to
  27353. * the element that prevented the insertion) and a bool denoting whether the
  27354. * insertion took place.
  27355. */
  27356. std::pair<iterator, bool> insert(const value_type &value) {
  27357. return insert_or_do_nothing(value);
  27358. }
  27359. /*! @copydoc insert */
  27360. std::pair<iterator, bool> insert(value_type &&value) {
  27361. return insert_or_do_nothing(std::move(value));
  27362. }
  27363. /**
  27364. * @brief Inserts elements into the container, if they do not exist.
  27365. * @tparam It Type of input iterator.
  27366. * @param first An iterator to the first element of the range of elements.
  27367. * @param last An iterator past the last element of the range of elements.
  27368. */
  27369. template<typename It>
  27370. void insert(It first, It last) {
  27371. for(; first != last; ++first) {
  27372. insert(*first);
  27373. }
  27374. }
  27375. /**
  27376. * @brief Constructs an element in-place, if it does not exist.
  27377. *
  27378. * The element is also constructed when the container already has the key,
  27379. * in which case the newly constructed object is destroyed immediately.
  27380. *
  27381. * @tparam Args Types of arguments to forward to the constructor of the
  27382. * element.
  27383. * @param args Arguments to forward to the constructor of the element.
  27384. * @return A pair consisting of an iterator to the inserted element (or to
  27385. * the element that prevented the insertion) and a bool denoting whether the
  27386. * insertion took place.
  27387. */
  27388. template<typename... Args>
  27389. std::pair<iterator, bool> emplace(Args &&...args) {
  27390. if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v<std::decay_t<Args>, value_type>)) {
  27391. return insert_or_do_nothing(std::forward<Args>(args)...);
  27392. } else {
  27393. auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward<Args>(args)...));
  27394. const auto index = value_to_bucket(node.second);
  27395. if(auto it = constrained_find(node.second, index); it != end()) {
  27396. packed.first().pop_back();
  27397. return std::make_pair(it, false);
  27398. }
  27399. std::swap(node.first, sparse.first()[index]);
  27400. rehash_if_required();
  27401. return std::make_pair(--end(), true);
  27402. }
  27403. }
  27404. /**
  27405. * @brief Removes an element from a given position.
  27406. * @param pos An iterator to the element to remove.
  27407. * @return An iterator following the removed element.
  27408. */
  27409. iterator erase(const_iterator pos) {
  27410. const auto diff = pos - cbegin();
  27411. erase(*pos);
  27412. return begin() + diff;
  27413. }
  27414. /**
  27415. * @brief Removes the given elements from a container.
  27416. * @param first An iterator to the first element of the range of elements.
  27417. * @param last An iterator past the last element of the range of elements.
  27418. * @return An iterator following the last removed element.
  27419. */
  27420. iterator erase(const_iterator first, const_iterator last) {
  27421. const auto dist = first - cbegin();
  27422. for(auto from = last - cbegin(); from != dist; --from) {
  27423. erase(packed.first()[static_cast<size_type>(from) - 1u].second);
  27424. }
  27425. return (begin() + dist);
  27426. }
  27427. /**
  27428. * @brief Removes the element associated with a given value.
  27429. * @param value Value of an element to remove.
  27430. * @return Number of elements removed (either 0 or 1).
  27431. */
  27432. size_type erase(const value_type &value) {
  27433. for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) {
  27434. if(packed.second()(packed.first()[*curr].second, value)) {
  27435. const auto index = *curr;
  27436. *curr = packed.first()[*curr].first;
  27437. move_and_pop(index);
  27438. return 1u;
  27439. }
  27440. }
  27441. return 0u;
  27442. }
  27443. /**
  27444. * @brief Returns the number of elements matching a value (either 1 or 0).
  27445. * @param key Key value of an element to search for.
  27446. * @return Number of elements matching the key (either 1 or 0).
  27447. */
  27448. [[nodiscard]] size_type count(const value_type &key) const {
  27449. return find(key) != end();
  27450. }
  27451. /**
  27452. * @brief Returns the number of elements matching a key (either 1 or 0).
  27453. * @tparam Other Type of the key value of an element to search for.
  27454. * @param key Key value of an element to search for.
  27455. * @return Number of elements matching the key (either 1 or 0).
  27456. */
  27457. template<typename Other>
  27458. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  27459. count(const Other &key) const {
  27460. return find(key) != end();
  27461. }
  27462. /**
  27463. * @brief Finds an element with a given value.
  27464. * @param value Value of an element to search for.
  27465. * @return An iterator to an element with the given value. If no such
  27466. * element is found, a past-the-end iterator is returned.
  27467. */
  27468. [[nodiscard]] iterator find(const value_type &value) {
  27469. return constrained_find(value, value_to_bucket(value));
  27470. }
  27471. /*! @copydoc find */
  27472. [[nodiscard]] const_iterator find(const value_type &value) const {
  27473. return constrained_find(value, value_to_bucket(value));
  27474. }
  27475. /**
  27476. * @brief Finds an element that compares _equivalent_ to a given value.
  27477. * @tparam Other Type of an element to search for.
  27478. * @param value Value of an element to search for.
  27479. * @return An iterator to an element with the given value. If no such
  27480. * element is found, a past-the-end iterator is returned.
  27481. */
  27482. template<typename Other>
  27483. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  27484. find(const Other &value) {
  27485. return constrained_find(value, value_to_bucket(value));
  27486. }
  27487. /*! @copydoc find */
  27488. template<typename Other>
  27489. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  27490. find(const Other &value) const {
  27491. return constrained_find(value, value_to_bucket(value));
  27492. }
  27493. /**
  27494. * @brief Returns a range containing all elements with a given value.
  27495. * @param value Value of an element to search for.
  27496. * @return A pair of iterators pointing to the first element and past the
  27497. * last element of the range.
  27498. */
  27499. [[nodiscard]] std::pair<iterator, iterator> equal_range(const value_type &value) {
  27500. const auto it = find(value);
  27501. return {it, it + !(it == end())};
  27502. }
  27503. /*! @copydoc equal_range */
  27504. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const value_type &value) const {
  27505. const auto it = find(value);
  27506. return {it, it + !(it == cend())};
  27507. }
  27508. /**
  27509. * @brief Returns a range containing all elements that compare _equivalent_
  27510. * to a given value.
  27511. * @tparam Other Type of an element to search for.
  27512. * @param value Value of an element to search for.
  27513. * @return A pair of iterators pointing to the first element and past the
  27514. * last element of the range.
  27515. */
  27516. template<typename Other>
  27517. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  27518. equal_range(const Other &value) {
  27519. const auto it = find(value);
  27520. return {it, it + !(it == end())};
  27521. }
  27522. /*! @copydoc equal_range */
  27523. template<typename Other>
  27524. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  27525. equal_range(const Other &value) const {
  27526. const auto it = find(value);
  27527. return {it, it + !(it == cend())};
  27528. }
  27529. /**
  27530. * @brief Checks if the container contains an element with a given value.
  27531. * @param value Value of an element to search for.
  27532. * @return True if there is such an element, false otherwise.
  27533. */
  27534. [[nodiscard]] bool contains(const value_type &value) const {
  27535. return (find(value) != cend());
  27536. }
  27537. /**
  27538. * @brief Checks if the container contains an element that compares
  27539. * _equivalent_ to a given value.
  27540. * @tparam Other Type of an element to search for.
  27541. * @param value Value of an element to search for.
  27542. * @return True if there is such an element, false otherwise.
  27543. */
  27544. template<typename Other>
  27545. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  27546. contains(const Other &value) const {
  27547. return (find(value) != cend());
  27548. }
  27549. /**
  27550. * @brief Returns an iterator to the beginning of a given bucket.
  27551. * @param index An index of a bucket to access.
  27552. * @return An iterator to the beginning of the given bucket.
  27553. */
  27554. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  27555. return {packed.first().begin(), sparse.first()[index]};
  27556. }
  27557. /**
  27558. * @brief Returns an iterator to the beginning of a given bucket.
  27559. * @param index An index of a bucket to access.
  27560. * @return An iterator to the beginning of the given bucket.
  27561. */
  27562. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  27563. return cbegin(index);
  27564. }
  27565. /**
  27566. * @brief Returns an iterator to the beginning of a given bucket.
  27567. * @param index An index of a bucket to access.
  27568. * @return An iterator to the beginning of the given bucket.
  27569. */
  27570. [[nodiscard]] local_iterator begin(const size_type index) {
  27571. return {packed.first().begin(), sparse.first()[index]};
  27572. }
  27573. /**
  27574. * @brief Returns an iterator to the end of a given bucket.
  27575. * @param index An index of a bucket to access.
  27576. * @return An iterator to the end of the given bucket.
  27577. */
  27578. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  27579. return {};
  27580. }
  27581. /**
  27582. * @brief Returns an iterator to the end of a given bucket.
  27583. * @param index An index of a bucket to access.
  27584. * @return An iterator to the end of the given bucket.
  27585. */
  27586. [[nodiscard]] const_local_iterator end(const size_type index) const {
  27587. return cend(index);
  27588. }
  27589. /**
  27590. * @brief Returns an iterator to the end of a given bucket.
  27591. * @param index An index of a bucket to access.
  27592. * @return An iterator to the end of the given bucket.
  27593. */
  27594. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  27595. return {};
  27596. }
  27597. /**
  27598. * @brief Returns the number of buckets.
  27599. * @return The number of buckets.
  27600. */
  27601. [[nodiscard]] size_type bucket_count() const {
  27602. return sparse.first().size();
  27603. }
  27604. /**
  27605. * @brief Returns the maximum number of buckets.
  27606. * @return The maximum number of buckets.
  27607. */
  27608. [[nodiscard]] size_type max_bucket_count() const {
  27609. return sparse.first().max_size();
  27610. }
  27611. /**
  27612. * @brief Returns the number of elements in a given bucket.
  27613. * @param index The index of the bucket to examine.
  27614. * @return The number of elements in the given bucket.
  27615. */
  27616. [[nodiscard]] size_type bucket_size(const size_type index) const {
  27617. return static_cast<size_type>(std::distance(begin(index), end(index)));
  27618. }
  27619. /**
  27620. * @brief Returns the bucket for a given element.
  27621. * @param value The value of the element to examine.
  27622. * @return The bucket for the given element.
  27623. */
  27624. [[nodiscard]] size_type bucket(const value_type &value) const {
  27625. return value_to_bucket(value);
  27626. }
  27627. /**
  27628. * @brief Returns the average number of elements per bucket.
  27629. * @return The average number of elements per bucket.
  27630. */
  27631. [[nodiscard]] float load_factor() const {
  27632. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  27633. }
  27634. /**
  27635. * @brief Returns the maximum average number of elements per bucket.
  27636. * @return The maximum average number of elements per bucket.
  27637. */
  27638. [[nodiscard]] float max_load_factor() const {
  27639. return threshold;
  27640. }
  27641. /**
  27642. * @brief Sets the desired maximum average number of elements per bucket.
  27643. * @param value A desired maximum average number of elements per bucket.
  27644. */
  27645. void max_load_factor(const float value) {
  27646. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  27647. threshold = value;
  27648. rehash(0u);
  27649. }
  27650. /**
  27651. * @brief Reserves at least the specified number of buckets and regenerates
  27652. * the hash table.
  27653. * @param cnt New number of buckets.
  27654. */
  27655. void rehash(const size_type cnt) {
  27656. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  27657. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  27658. value = value > cap ? value : cap;
  27659. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  27660. sparse.first().resize(sz);
  27661. for(auto &&elem: sparse.first()) {
  27662. elem = placeholder_position;
  27663. }
  27664. for(size_type pos{}, last = size(); pos < last; ++pos) {
  27665. const auto index = value_to_bucket(packed.first()[pos].second);
  27666. packed.first()[pos].first = std::exchange(sparse.first()[index], pos);
  27667. }
  27668. }
  27669. }
  27670. /**
  27671. * @brief Reserves space for at least the specified number of elements and
  27672. * regenerates the hash table.
  27673. * @param cnt New number of elements.
  27674. */
  27675. void reserve(const size_type cnt) {
  27676. packed.first().reserve(cnt);
  27677. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  27678. }
  27679. /**
  27680. * @brief Returns the function used to hash the elements.
  27681. * @return The function used to hash the elements.
  27682. */
  27683. [[nodiscard]] hasher hash_function() const {
  27684. return sparse.second();
  27685. }
  27686. /**
  27687. * @brief Returns the function used to compare elements for equality.
  27688. * @return The function used to compare elements for equality.
  27689. */
  27690. [[nodiscard]] key_equal key_eq() const {
  27691. return packed.second();
  27692. }
  27693. private:
  27694. compressed_pair<sparse_container_type, hasher> sparse;
  27695. compressed_pair<packed_container_type, key_equal> packed;
  27696. float threshold{default_threshold};
  27697. };
  27698. } // namespace entt
  27699. #endif
  27700. // #include "../core/compressed_pair.hpp"
  27701. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  27702. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  27703. #include <cstddef>
  27704. #include <tuple>
  27705. #include <type_traits>
  27706. #include <utility>
  27707. // #include "fwd.hpp"
  27708. #ifndef ENTT_CORE_FWD_HPP
  27709. #define ENTT_CORE_FWD_HPP
  27710. #include <cstddef>
  27711. #include <cstdint>
  27712. // #include "../config/config.h"
  27713. namespace entt {
  27714. /*! @brief Possible modes of an any object. */
  27715. enum class any_policy : std::uint8_t {
  27716. /*! @brief Default mode, no element available. */
  27717. empty,
  27718. /*! @brief Owning mode, dynamically allocated element. */
  27719. dynamic,
  27720. /*! @brief Owning mode, embedded element. */
  27721. embedded,
  27722. /*! @brief Aliasing mode, non-const reference. */
  27723. ref,
  27724. /*! @brief Const aliasing mode, const reference. */
  27725. cref
  27726. };
  27727. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  27728. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  27729. class basic_any;
  27730. /*! @brief Alias declaration for type identifiers. */
  27731. using id_type = ENTT_ID_TYPE;
  27732. /*! @brief Alias declaration for the most common use case. */
  27733. using any = basic_any<>;
  27734. template<typename, typename>
  27735. class compressed_pair;
  27736. template<typename>
  27737. class basic_hashed_string;
  27738. /*! @brief Aliases for common character types. */
  27739. using hashed_string = basic_hashed_string<char>;
  27740. /*! @brief Aliases for common character types. */
  27741. using hashed_wstring = basic_hashed_string<wchar_t>;
  27742. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  27743. struct type_info;
  27744. } // namespace entt
  27745. #endif
  27746. // #include "type_traits.hpp"
  27747. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  27748. #define ENTT_CORE_TYPE_TRAITS_HPP
  27749. #include <cstddef>
  27750. #include <iterator>
  27751. #include <tuple>
  27752. #include <type_traits>
  27753. #include <utility>
  27754. // #include "../config/config.h"
  27755. // #include "fwd.hpp"
  27756. namespace entt {
  27757. /**
  27758. * @brief Utility class to disambiguate overloaded functions.
  27759. * @tparam N Number of choices available.
  27760. */
  27761. template<std::size_t N>
  27762. struct choice_t
  27763. // unfortunately, doxygen cannot parse such a construct
  27764. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  27765. {};
  27766. /*! @copybrief choice_t */
  27767. template<>
  27768. struct choice_t<0> {};
  27769. /**
  27770. * @brief Variable template for the choice trick.
  27771. * @tparam N Number of choices available.
  27772. */
  27773. template<std::size_t N>
  27774. inline constexpr choice_t<N> choice{};
  27775. /**
  27776. * @brief Identity type trait.
  27777. *
  27778. * Useful to establish non-deduced contexts in template argument deduction
  27779. * (waiting for C++20) or to provide types through function arguments.
  27780. *
  27781. * @tparam Type A type.
  27782. */
  27783. template<typename Type>
  27784. struct type_identity {
  27785. /*! @brief Identity type. */
  27786. using type = Type;
  27787. };
  27788. /**
  27789. * @brief Helper type.
  27790. * @tparam Type A type.
  27791. */
  27792. template<typename Type>
  27793. using type_identity_t = typename type_identity<Type>::type;
  27794. /**
  27795. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  27796. * @tparam Type The type of which to return the size.
  27797. */
  27798. template<typename Type, typename = void>
  27799. struct size_of: std::integral_constant<std::size_t, 0u> {};
  27800. /*! @copydoc size_of */
  27801. template<typename Type>
  27802. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  27803. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  27804. : std::integral_constant<std::size_t, sizeof(Type)> {};
  27805. /**
  27806. * @brief Helper variable template.
  27807. * @tparam Type The type of which to return the size.
  27808. */
  27809. template<typename Type>
  27810. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  27811. /**
  27812. * @brief Using declaration to be used to _repeat_ the same type a number of
  27813. * times equal to the size of a given parameter pack.
  27814. * @tparam Type A type to repeat.
  27815. */
  27816. template<typename Type, typename>
  27817. using unpack_as_type = Type;
  27818. /**
  27819. * @brief Helper variable template to be used to _repeat_ the same value a
  27820. * number of times equal to the size of a given parameter pack.
  27821. * @tparam Value A value to repeat.
  27822. */
  27823. template<auto Value, typename>
  27824. inline constexpr auto unpack_as_value = Value;
  27825. /**
  27826. * @brief Wraps a static constant.
  27827. * @tparam Value A static constant.
  27828. */
  27829. template<auto Value>
  27830. using integral_constant = std::integral_constant<decltype(Value), Value>;
  27831. /**
  27832. * @brief Alias template to facilitate the creation of named values.
  27833. * @tparam Value A constant value at least convertible to `id_type`.
  27834. */
  27835. template<id_type Value>
  27836. using tag = integral_constant<Value>;
  27837. /**
  27838. * @brief A class to use to push around lists of types, nothing more.
  27839. * @tparam Type Types provided by the type list.
  27840. */
  27841. template<typename... Type>
  27842. struct type_list {
  27843. /*! @brief Type list type. */
  27844. using type = type_list;
  27845. /*! @brief Compile-time number of elements in the type list. */
  27846. static constexpr auto size = sizeof...(Type);
  27847. };
  27848. /*! @brief Primary template isn't defined on purpose. */
  27849. template<std::size_t, typename>
  27850. struct type_list_element;
  27851. /**
  27852. * @brief Provides compile-time indexed access to the types of a type list.
  27853. * @tparam Index Index of the type to return.
  27854. * @tparam First First type provided by the type list.
  27855. * @tparam Other Other types provided by the type list.
  27856. */
  27857. template<std::size_t Index, typename First, typename... Other>
  27858. struct type_list_element<Index, type_list<First, Other...>>
  27859. : type_list_element<Index - 1u, type_list<Other...>> {};
  27860. /**
  27861. * @brief Provides compile-time indexed access to the types of a type list.
  27862. * @tparam First First type provided by the type list.
  27863. * @tparam Other Other types provided by the type list.
  27864. */
  27865. template<typename First, typename... Other>
  27866. struct type_list_element<0u, type_list<First, Other...>> {
  27867. /*! @brief Searched type. */
  27868. using type = First;
  27869. };
  27870. /**
  27871. * @brief Helper type.
  27872. * @tparam Index Index of the type to return.
  27873. * @tparam List Type list to search into.
  27874. */
  27875. template<std::size_t Index, typename List>
  27876. using type_list_element_t = typename type_list_element<Index, List>::type;
  27877. /*! @brief Primary template isn't defined on purpose. */
  27878. template<typename, typename>
  27879. struct type_list_index;
  27880. /**
  27881. * @brief Provides compile-time type access to the types of a type list.
  27882. * @tparam Type Type to look for and for which to return the index.
  27883. * @tparam First First type provided by the type list.
  27884. * @tparam Other Other types provided by the type list.
  27885. */
  27886. template<typename Type, typename First, typename... Other>
  27887. struct type_list_index<Type, type_list<First, Other...>> {
  27888. /*! @brief Unsigned integer type. */
  27889. using value_type = std::size_t;
  27890. /*! @brief Compile-time position of the given type in the sublist. */
  27891. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  27892. };
  27893. /**
  27894. * @brief Provides compile-time type access to the types of a type list.
  27895. * @tparam Type Type to look for and for which to return the index.
  27896. * @tparam Other Other types provided by the type list.
  27897. */
  27898. template<typename Type, typename... Other>
  27899. struct type_list_index<Type, type_list<Type, Other...>> {
  27900. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  27901. /*! @brief Unsigned integer type. */
  27902. using value_type = std::size_t;
  27903. /*! @brief Compile-time position of the given type in the sublist. */
  27904. static constexpr value_type value = 0u;
  27905. };
  27906. /**
  27907. * @brief Provides compile-time type access to the types of a type list.
  27908. * @tparam Type Type to look for and for which to return the index.
  27909. */
  27910. template<typename Type>
  27911. struct type_list_index<Type, type_list<>> {
  27912. /*! @brief Unsigned integer type. */
  27913. using value_type = std::size_t;
  27914. /*! @brief Compile-time position of the given type in the sublist. */
  27915. static constexpr value_type value = 0u;
  27916. };
  27917. /**
  27918. * @brief Helper variable template.
  27919. * @tparam List Type list.
  27920. * @tparam Type Type to look for and for which to return the index.
  27921. */
  27922. template<typename Type, typename List>
  27923. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  27924. /**
  27925. * @brief Concatenates multiple type lists.
  27926. * @tparam Type Types provided by the first type list.
  27927. * @tparam Other Types provided by the second type list.
  27928. * @return A type list composed by the types of both the type lists.
  27929. */
  27930. template<typename... Type, typename... Other>
  27931. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  27932. return {};
  27933. }
  27934. /*! @brief Primary template isn't defined on purpose. */
  27935. template<typename...>
  27936. struct type_list_cat;
  27937. /*! @brief Concatenates multiple type lists. */
  27938. template<>
  27939. struct type_list_cat<> {
  27940. /*! @brief A type list composed by the types of all the type lists. */
  27941. using type = type_list<>;
  27942. };
  27943. /**
  27944. * @brief Concatenates multiple type lists.
  27945. * @tparam Type Types provided by the first type list.
  27946. * @tparam Other Types provided by the second type list.
  27947. * @tparam List Other type lists, if any.
  27948. */
  27949. template<typename... Type, typename... Other, typename... List>
  27950. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  27951. /*! @brief A type list composed by the types of all the type lists. */
  27952. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  27953. };
  27954. /**
  27955. * @brief Concatenates multiple type lists.
  27956. * @tparam Type Types provided by the type list.
  27957. */
  27958. template<typename... Type>
  27959. struct type_list_cat<type_list<Type...>> {
  27960. /*! @brief A type list composed by the types of all the type lists. */
  27961. using type = type_list<Type...>;
  27962. };
  27963. /**
  27964. * @brief Helper type.
  27965. * @tparam List Type lists to concatenate.
  27966. */
  27967. template<typename... List>
  27968. using type_list_cat_t = typename type_list_cat<List...>::type;
  27969. /*! @cond TURN_OFF_DOXYGEN */
  27970. namespace internal {
  27971. template<typename...>
  27972. struct type_list_unique;
  27973. template<typename First, typename... Other, typename... Type>
  27974. struct type_list_unique<type_list<First, Other...>, Type...>
  27975. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  27976. template<typename... Type>
  27977. struct type_list_unique<type_list<>, Type...> {
  27978. using type = type_list<Type...>;
  27979. };
  27980. } // namespace internal
  27981. /*! @endcond */
  27982. /**
  27983. * @brief Removes duplicates types from a type list.
  27984. * @tparam List Type list.
  27985. */
  27986. template<typename List>
  27987. struct type_list_unique {
  27988. /*! @brief A type list without duplicate types. */
  27989. using type = typename internal::type_list_unique<List>::type;
  27990. };
  27991. /**
  27992. * @brief Helper type.
  27993. * @tparam List Type list.
  27994. */
  27995. template<typename List>
  27996. using type_list_unique_t = typename type_list_unique<List>::type;
  27997. /**
  27998. * @brief Provides the member constant `value` to true if a type list contains a
  27999. * given type, false otherwise.
  28000. * @tparam List Type list.
  28001. * @tparam Type Type to look for.
  28002. */
  28003. template<typename List, typename Type>
  28004. struct type_list_contains;
  28005. /**
  28006. * @copybrief type_list_contains
  28007. * @tparam Type Types provided by the type list.
  28008. * @tparam Other Type to look for.
  28009. */
  28010. template<typename... Type, typename Other>
  28011. struct type_list_contains<type_list<Type...>, Other>
  28012. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  28013. /**
  28014. * @brief Helper variable template.
  28015. * @tparam List Type list.
  28016. * @tparam Type Type to look for.
  28017. */
  28018. template<typename List, typename Type>
  28019. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  28020. /*! @brief Primary template isn't defined on purpose. */
  28021. template<typename...>
  28022. struct type_list_diff;
  28023. /**
  28024. * @brief Computes the difference between two type lists.
  28025. * @tparam Type Types provided by the first type list.
  28026. * @tparam Other Types provided by the second type list.
  28027. */
  28028. template<typename... Type, typename... Other>
  28029. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  28030. /*! @brief A type list that is the difference between the two type lists. */
  28031. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  28032. };
  28033. /**
  28034. * @brief Helper type.
  28035. * @tparam List Type lists between which to compute the difference.
  28036. */
  28037. template<typename... List>
  28038. using type_list_diff_t = typename type_list_diff<List...>::type;
  28039. /*! @brief Primary template isn't defined on purpose. */
  28040. template<typename, template<typename...> class>
  28041. struct type_list_transform;
  28042. /**
  28043. * @brief Applies a given _function_ to a type list and generate a new list.
  28044. * @tparam Type Types provided by the type list.
  28045. * @tparam Op Unary operation as template class with a type member named `type`.
  28046. */
  28047. template<typename... Type, template<typename...> class Op>
  28048. struct type_list_transform<type_list<Type...>, Op> {
  28049. /*! @brief Resulting type list after applying the transform function. */
  28050. // NOLINTNEXTLINE(modernize-type-traits)
  28051. using type = type_list<typename Op<Type>::type...>;
  28052. };
  28053. /**
  28054. * @brief Helper type.
  28055. * @tparam List Type list.
  28056. * @tparam Op Unary operation as template class with a type member named `type`.
  28057. */
  28058. template<typename List, template<typename...> class Op>
  28059. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  28060. /**
  28061. * @brief A class to use to push around lists of constant values, nothing more.
  28062. * @tparam Value Values provided by the value list.
  28063. */
  28064. template<auto... Value>
  28065. struct value_list {
  28066. /*! @brief Value list type. */
  28067. using type = value_list;
  28068. /*! @brief Compile-time number of elements in the value list. */
  28069. static constexpr auto size = sizeof...(Value);
  28070. };
  28071. /*! @brief Primary template isn't defined on purpose. */
  28072. template<std::size_t, typename>
  28073. struct value_list_element;
  28074. /**
  28075. * @brief Provides compile-time indexed access to the values of a value list.
  28076. * @tparam Index Index of the value to return.
  28077. * @tparam Value First value provided by the value list.
  28078. * @tparam Other Other values provided by the value list.
  28079. */
  28080. template<std::size_t Index, auto Value, auto... Other>
  28081. struct value_list_element<Index, value_list<Value, Other...>>
  28082. : value_list_element<Index - 1u, value_list<Other...>> {};
  28083. /**
  28084. * @brief Provides compile-time indexed access to the types of a type list.
  28085. * @tparam Value First value provided by the value list.
  28086. * @tparam Other Other values provided by the value list.
  28087. */
  28088. template<auto Value, auto... Other>
  28089. struct value_list_element<0u, value_list<Value, Other...>> {
  28090. /*! @brief Searched type. */
  28091. using type = decltype(Value);
  28092. /*! @brief Searched value. */
  28093. static constexpr auto value = Value;
  28094. };
  28095. /**
  28096. * @brief Helper type.
  28097. * @tparam Index Index of the type to return.
  28098. * @tparam List Value list to search into.
  28099. */
  28100. template<std::size_t Index, typename List>
  28101. using value_list_element_t = typename value_list_element<Index, List>::type;
  28102. /**
  28103. * @brief Helper type.
  28104. * @tparam Index Index of the value to return.
  28105. * @tparam List Value list to search into.
  28106. */
  28107. template<std::size_t Index, typename List>
  28108. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  28109. /*! @brief Primary template isn't defined on purpose. */
  28110. template<auto, typename>
  28111. struct value_list_index;
  28112. /**
  28113. * @brief Provides compile-time type access to the values of a value list.
  28114. * @tparam Value Value to look for and for which to return the index.
  28115. * @tparam First First value provided by the value list.
  28116. * @tparam Other Other values provided by the value list.
  28117. */
  28118. template<auto Value, auto First, auto... Other>
  28119. struct value_list_index<Value, value_list<First, Other...>> {
  28120. /*! @brief Unsigned integer type. */
  28121. using value_type = std::size_t;
  28122. /*! @brief Compile-time position of the given value in the sublist. */
  28123. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  28124. };
  28125. /**
  28126. * @brief Provides compile-time type access to the values of a value list.
  28127. * @tparam Value Value to look for and for which to return the index.
  28128. * @tparam Other Other values provided by the value list.
  28129. */
  28130. template<auto Value, auto... Other>
  28131. struct value_list_index<Value, value_list<Value, Other...>> {
  28132. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  28133. /*! @brief Unsigned integer type. */
  28134. using value_type = std::size_t;
  28135. /*! @brief Compile-time position of the given value in the sublist. */
  28136. static constexpr value_type value = 0u;
  28137. };
  28138. /**
  28139. * @brief Provides compile-time type access to the values of a value list.
  28140. * @tparam Value Value to look for and for which to return the index.
  28141. */
  28142. template<auto Value>
  28143. struct value_list_index<Value, value_list<>> {
  28144. /*! @brief Unsigned integer type. */
  28145. using value_type = std::size_t;
  28146. /*! @brief Compile-time position of the given type in the sublist. */
  28147. static constexpr value_type value = 0u;
  28148. };
  28149. /**
  28150. * @brief Helper variable template.
  28151. * @tparam List Value list.
  28152. * @tparam Value Value to look for and for which to return the index.
  28153. */
  28154. template<auto Value, typename List>
  28155. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  28156. /**
  28157. * @brief Concatenates multiple value lists.
  28158. * @tparam Value Values provided by the first value list.
  28159. * @tparam Other Values provided by the second value list.
  28160. * @return A value list composed by the values of both the value lists.
  28161. */
  28162. template<auto... Value, auto... Other>
  28163. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  28164. return {};
  28165. }
  28166. /*! @brief Primary template isn't defined on purpose. */
  28167. template<typename...>
  28168. struct value_list_cat;
  28169. /*! @brief Concatenates multiple value lists. */
  28170. template<>
  28171. struct value_list_cat<> {
  28172. /*! @brief A value list composed by the values of all the value lists. */
  28173. using type = value_list<>;
  28174. };
  28175. /**
  28176. * @brief Concatenates multiple value lists.
  28177. * @tparam Value Values provided by the first value list.
  28178. * @tparam Other Values provided by the second value list.
  28179. * @tparam List Other value lists, if any.
  28180. */
  28181. template<auto... Value, auto... Other, typename... List>
  28182. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  28183. /*! @brief A value list composed by the values of all the value lists. */
  28184. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  28185. };
  28186. /**
  28187. * @brief Concatenates multiple value lists.
  28188. * @tparam Value Values provided by the value list.
  28189. */
  28190. template<auto... Value>
  28191. struct value_list_cat<value_list<Value...>> {
  28192. /*! @brief A value list composed by the values of all the value lists. */
  28193. using type = value_list<Value...>;
  28194. };
  28195. /**
  28196. * @brief Helper type.
  28197. * @tparam List Value lists to concatenate.
  28198. */
  28199. template<typename... List>
  28200. using value_list_cat_t = typename value_list_cat<List...>::type;
  28201. /*! @brief Primary template isn't defined on purpose. */
  28202. template<typename>
  28203. struct value_list_unique;
  28204. /**
  28205. * @brief Removes duplicates values from a value list.
  28206. * @tparam Value One of the values provided by the given value list.
  28207. * @tparam Other The other values provided by the given value list.
  28208. */
  28209. template<auto Value, auto... Other>
  28210. struct value_list_unique<value_list<Value, Other...>> {
  28211. /*! @brief A value list without duplicate types. */
  28212. using type = std::conditional_t<
  28213. ((Value == Other) || ...),
  28214. typename value_list_unique<value_list<Other...>>::type,
  28215. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  28216. };
  28217. /*! @brief Removes duplicates values from a value list. */
  28218. template<>
  28219. struct value_list_unique<value_list<>> {
  28220. /*! @brief A value list without duplicate types. */
  28221. using type = value_list<>;
  28222. };
  28223. /**
  28224. * @brief Helper type.
  28225. * @tparam Type A value list.
  28226. */
  28227. template<typename Type>
  28228. using value_list_unique_t = typename value_list_unique<Type>::type;
  28229. /**
  28230. * @brief Provides the member constant `value` to true if a value list contains
  28231. * a given value, false otherwise.
  28232. * @tparam List Value list.
  28233. * @tparam Value Value to look for.
  28234. */
  28235. template<typename List, auto Value>
  28236. struct value_list_contains;
  28237. /**
  28238. * @copybrief value_list_contains
  28239. * @tparam Value Values provided by the value list.
  28240. * @tparam Other Value to look for.
  28241. */
  28242. template<auto... Value, auto Other>
  28243. struct value_list_contains<value_list<Value...>, Other>
  28244. : std::bool_constant<((Value == Other) || ...)> {};
  28245. /**
  28246. * @brief Helper variable template.
  28247. * @tparam List Value list.
  28248. * @tparam Value Value to look for.
  28249. */
  28250. template<typename List, auto Value>
  28251. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  28252. /*! @brief Primary template isn't defined on purpose. */
  28253. template<typename...>
  28254. struct value_list_diff;
  28255. /**
  28256. * @brief Computes the difference between two value lists.
  28257. * @tparam Value Values provided by the first value list.
  28258. * @tparam Other Values provided by the second value list.
  28259. */
  28260. template<auto... Value, auto... Other>
  28261. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  28262. /*! @brief A value list that is the difference between the two value lists. */
  28263. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  28264. };
  28265. /**
  28266. * @brief Helper type.
  28267. * @tparam List Value lists between which to compute the difference.
  28268. */
  28269. template<typename... List>
  28270. using value_list_diff_t = typename value_list_diff<List...>::type;
  28271. /*! @brief Same as std::is_invocable, but with tuples. */
  28272. template<typename, typename>
  28273. struct is_applicable: std::false_type {};
  28274. /**
  28275. * @copybrief is_applicable
  28276. * @tparam Func A valid function type.
  28277. * @tparam Tuple Tuple-like type.
  28278. * @tparam Args The list of arguments to use to probe the function type.
  28279. */
  28280. template<typename Func, template<typename...> class Tuple, typename... Args>
  28281. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  28282. /**
  28283. * @copybrief is_applicable
  28284. * @tparam Func A valid function type.
  28285. * @tparam Tuple Tuple-like type.
  28286. * @tparam Args The list of arguments to use to probe the function type.
  28287. */
  28288. template<typename Func, template<typename...> class Tuple, typename... Args>
  28289. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  28290. /**
  28291. * @brief Helper variable template.
  28292. * @tparam Func A valid function type.
  28293. * @tparam Args The list of arguments to use to probe the function type.
  28294. */
  28295. template<typename Func, typename Args>
  28296. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  28297. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  28298. template<typename, typename, typename>
  28299. struct is_applicable_r: std::false_type {};
  28300. /**
  28301. * @copybrief is_applicable_r
  28302. * @tparam Ret The type to which the return type of the function should be
  28303. * convertible.
  28304. * @tparam Func A valid function type.
  28305. * @tparam Args The list of arguments to use to probe the function type.
  28306. */
  28307. template<typename Ret, typename Func, typename... Args>
  28308. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  28309. /**
  28310. * @brief Helper variable template.
  28311. * @tparam Ret The type to which the return type of the function should be
  28312. * convertible.
  28313. * @tparam Func A valid function type.
  28314. * @tparam Args The list of arguments to use to probe the function type.
  28315. */
  28316. template<typename Ret, typename Func, typename Args>
  28317. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  28318. /**
  28319. * @brief Provides the member constant `value` to true if a given type is
  28320. * complete, false otherwise.
  28321. * @tparam Type The type to test.
  28322. */
  28323. template<typename Type, typename = void>
  28324. struct is_complete: std::false_type {};
  28325. /*! @copydoc is_complete */
  28326. template<typename Type>
  28327. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  28328. /**
  28329. * @brief Helper variable template.
  28330. * @tparam Type The type to test.
  28331. */
  28332. template<typename Type>
  28333. inline constexpr bool is_complete_v = is_complete<Type>::value;
  28334. /**
  28335. * @brief Provides the member constant `value` to true if a given type is an
  28336. * iterator, false otherwise.
  28337. * @tparam Type The type to test.
  28338. */
  28339. template<typename Type, typename = void>
  28340. struct is_iterator: std::false_type {};
  28341. /*! @cond TURN_OFF_DOXYGEN */
  28342. namespace internal {
  28343. template<typename, typename = void>
  28344. struct has_iterator_category: std::false_type {};
  28345. template<typename Type>
  28346. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  28347. } // namespace internal
  28348. /*! @endcond */
  28349. /*! @copydoc is_iterator */
  28350. template<typename Type>
  28351. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  28352. : internal::has_iterator_category<Type> {};
  28353. /**
  28354. * @brief Helper variable template.
  28355. * @tparam Type The type to test.
  28356. */
  28357. template<typename Type>
  28358. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  28359. /**
  28360. * @brief Provides the member constant `value` to true if a given type is both
  28361. * an empty and non-final class, false otherwise.
  28362. * @tparam Type The type to test
  28363. */
  28364. template<typename Type>
  28365. struct is_ebco_eligible
  28366. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  28367. /**
  28368. * @brief Helper variable template.
  28369. * @tparam Type The type to test.
  28370. */
  28371. template<typename Type>
  28372. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  28373. /**
  28374. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  28375. * is valid and denotes a type, false otherwise.
  28376. * @tparam Type The type to test.
  28377. */
  28378. template<typename Type, typename = void>
  28379. struct is_transparent: std::false_type {};
  28380. /*! @copydoc is_transparent */
  28381. template<typename Type>
  28382. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  28383. /**
  28384. * @brief Helper variable template.
  28385. * @tparam Type The type to test.
  28386. */
  28387. template<typename Type>
  28388. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  28389. /*! @cond TURN_OFF_DOXYGEN */
  28390. namespace internal {
  28391. template<typename, typename = void>
  28392. struct has_tuple_size_value: std::false_type {};
  28393. template<typename Type>
  28394. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  28395. template<typename, typename = void>
  28396. struct has_value_type: std::false_type {};
  28397. template<typename Type>
  28398. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  28399. template<typename>
  28400. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  28401. template<typename Type, std::size_t... Index>
  28402. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  28403. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  28404. }
  28405. template<typename>
  28406. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  28407. return false;
  28408. }
  28409. template<typename Type>
  28410. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  28411. return true;
  28412. }
  28413. template<typename Type>
  28414. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  28415. // NOLINTBEGIN(modernize-use-transparent-functors)
  28416. if constexpr(std::is_array_v<Type>) {
  28417. return false;
  28418. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  28419. if constexpr(has_tuple_size_value<Type>::value) {
  28420. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  28421. } else {
  28422. return maybe_equality_comparable<Type>(0);
  28423. }
  28424. } else if constexpr(has_value_type<Type>::value) {
  28425. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  28426. return maybe_equality_comparable<Type>(0);
  28427. } else {
  28428. return false;
  28429. }
  28430. } else {
  28431. return maybe_equality_comparable<Type>(0);
  28432. }
  28433. // NOLINTEND(modernize-use-transparent-functors)
  28434. }
  28435. } // namespace internal
  28436. /*! @endcond */
  28437. /**
  28438. * @brief Provides the member constant `value` to true if a given type is
  28439. * equality comparable, false otherwise.
  28440. * @tparam Type The type to test.
  28441. */
  28442. template<typename Type>
  28443. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  28444. /*! @copydoc is_equality_comparable */
  28445. template<typename Type>
  28446. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  28447. /**
  28448. * @brief Helper variable template.
  28449. * @tparam Type The type to test.
  28450. */
  28451. template<typename Type>
  28452. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  28453. /**
  28454. * @brief Transcribes the constness of a type to another type.
  28455. * @tparam To The type to which to transcribe the constness.
  28456. * @tparam From The type from which to transcribe the constness.
  28457. */
  28458. template<typename To, typename From>
  28459. struct constness_as {
  28460. /*! @brief The type resulting from the transcription of the constness. */
  28461. using type = std::remove_const_t<To>;
  28462. };
  28463. /*! @copydoc constness_as */
  28464. template<typename To, typename From>
  28465. struct constness_as<To, const From> {
  28466. /*! @brief The type resulting from the transcription of the constness. */
  28467. using type = const To;
  28468. };
  28469. /**
  28470. * @brief Alias template to facilitate the transcription of the constness.
  28471. * @tparam To The type to which to transcribe the constness.
  28472. * @tparam From The type from which to transcribe the constness.
  28473. */
  28474. template<typename To, typename From>
  28475. using constness_as_t = typename constness_as<To, From>::type;
  28476. /**
  28477. * @brief Extracts the class of a non-static member object or function.
  28478. * @tparam Member A pointer to a non-static member object or function.
  28479. */
  28480. template<typename Member>
  28481. class member_class {
  28482. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  28483. template<typename Class, typename Ret, typename... Args>
  28484. static Class *clazz(Ret (Class::*)(Args...));
  28485. template<typename Class, typename Ret, typename... Args>
  28486. static Class *clazz(Ret (Class::*)(Args...) const);
  28487. template<typename Class, typename Type>
  28488. static Class *clazz(Type Class::*);
  28489. public:
  28490. /*! @brief The class of the given non-static member object or function. */
  28491. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  28492. };
  28493. /**
  28494. * @brief Helper type.
  28495. * @tparam Member A pointer to a non-static member object or function.
  28496. */
  28497. template<typename Member>
  28498. using member_class_t = typename member_class<Member>::type;
  28499. /**
  28500. * @brief Extracts the n-th argument of a _callable_ type.
  28501. * @tparam Index The index of the argument to extract.
  28502. * @tparam Candidate A valid _callable_ type.
  28503. */
  28504. template<std::size_t Index, typename Candidate>
  28505. class nth_argument {
  28506. template<typename Ret, typename... Args>
  28507. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  28508. template<typename Ret, typename Class, typename... Args>
  28509. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  28510. template<typename Ret, typename Class, typename... Args>
  28511. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  28512. template<typename Type, typename Class>
  28513. static constexpr type_list<Type> pick_up(Type Class ::*);
  28514. template<typename Type>
  28515. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  28516. public:
  28517. /*! @brief N-th argument of the _callable_ type. */
  28518. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  28519. };
  28520. /**
  28521. * @brief Helper type.
  28522. * @tparam Index The index of the argument to extract.
  28523. * @tparam Candidate A valid function, member function or data member type.
  28524. */
  28525. template<std::size_t Index, typename Candidate>
  28526. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  28527. } // namespace entt
  28528. template<typename... Type>
  28529. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  28530. template<std::size_t Index, typename... Type>
  28531. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  28532. template<auto... Value>
  28533. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  28534. template<std::size_t Index, auto... Value>
  28535. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  28536. #endif
  28537. namespace entt {
  28538. /*! @cond TURN_OFF_DOXYGEN */
  28539. namespace internal {
  28540. template<typename Type, std::size_t, typename = void>
  28541. struct compressed_pair_element {
  28542. using reference = Type &;
  28543. using const_reference = const Type &;
  28544. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  28545. // NOLINTNEXTLINE(modernize-use-equals-default)
  28546. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  28547. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  28548. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  28549. : value{std::forward<Arg>(arg)} {}
  28550. template<typename... Args, std::size_t... Index>
  28551. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  28552. : value{std::forward<Args>(std::get<Index>(args))...} {}
  28553. [[nodiscard]] constexpr reference get() noexcept {
  28554. return value;
  28555. }
  28556. [[nodiscard]] constexpr const_reference get() const noexcept {
  28557. return value;
  28558. }
  28559. private:
  28560. Type value{};
  28561. };
  28562. template<typename Type, std::size_t Tag>
  28563. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  28564. using reference = Type &;
  28565. using const_reference = const Type &;
  28566. using base_type = Type;
  28567. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  28568. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  28569. : base_type{} {}
  28570. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  28571. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  28572. : base_type{std::forward<Arg>(arg)} {}
  28573. template<typename... Args, std::size_t... Index>
  28574. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  28575. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  28576. [[nodiscard]] constexpr reference get() noexcept {
  28577. return *this;
  28578. }
  28579. [[nodiscard]] constexpr const_reference get() const noexcept {
  28580. return *this;
  28581. }
  28582. };
  28583. } // namespace internal
  28584. /*! @endcond */
  28585. /**
  28586. * @brief A compressed pair.
  28587. *
  28588. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  28589. * reduce its final size to a minimum.
  28590. *
  28591. * @tparam First The type of the first element that the pair stores.
  28592. * @tparam Second The type of the second element that the pair stores.
  28593. */
  28594. template<typename First, typename Second>
  28595. class compressed_pair final
  28596. : internal::compressed_pair_element<First, 0u>,
  28597. internal::compressed_pair_element<Second, 1u> {
  28598. using first_base = internal::compressed_pair_element<First, 0u>;
  28599. using second_base = internal::compressed_pair_element<Second, 1u>;
  28600. public:
  28601. /*! @brief The type of the first element that the pair stores. */
  28602. using first_type = First;
  28603. /*! @brief The type of the second element that the pair stores. */
  28604. using second_type = Second;
  28605. /**
  28606. * @brief Default constructor, conditionally enabled.
  28607. *
  28608. * This constructor is only available when the types that the pair stores
  28609. * are both at least default constructible.
  28610. *
  28611. * @tparam Dummy Dummy template parameter used for internal purposes.
  28612. */
  28613. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  28614. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  28615. : first_base{},
  28616. second_base{} {}
  28617. /**
  28618. * @brief Copy constructor.
  28619. * @param other The instance to copy from.
  28620. */
  28621. constexpr compressed_pair(const compressed_pair &other) = default;
  28622. /**
  28623. * @brief Move constructor.
  28624. * @param other The instance to move from.
  28625. */
  28626. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  28627. /**
  28628. * @brief Constructs a pair from its values.
  28629. * @tparam Arg Type of value to use to initialize the first element.
  28630. * @tparam Other Type of value to use to initialize the second element.
  28631. * @param arg Value to use to initialize the first element.
  28632. * @param other Value to use to initialize the second element.
  28633. */
  28634. template<typename Arg, typename Other>
  28635. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  28636. : first_base{std::forward<Arg>(arg)},
  28637. second_base{std::forward<Other>(other)} {}
  28638. /**
  28639. * @brief Constructs a pair by forwarding the arguments to its parts.
  28640. * @tparam Args Types of arguments to use to initialize the first element.
  28641. * @tparam Other Types of arguments to use to initialize the second element.
  28642. * @param args Arguments to use to initialize the first element.
  28643. * @param other Arguments to use to initialize the second element.
  28644. */
  28645. template<typename... Args, typename... Other>
  28646. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  28647. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  28648. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  28649. /*! @brief Default destructor. */
  28650. ~compressed_pair() = default;
  28651. /**
  28652. * @brief Copy assignment operator.
  28653. * @param other The instance to copy from.
  28654. * @return This compressed pair object.
  28655. */
  28656. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  28657. /**
  28658. * @brief Move assignment operator.
  28659. * @param other The instance to move from.
  28660. * @return This compressed pair object.
  28661. */
  28662. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  28663. /**
  28664. * @brief Returns the first element that a pair stores.
  28665. * @return The first element that a pair stores.
  28666. */
  28667. [[nodiscard]] constexpr first_type &first() noexcept {
  28668. return static_cast<first_base &>(*this).get();
  28669. }
  28670. /*! @copydoc first */
  28671. [[nodiscard]] constexpr const first_type &first() const noexcept {
  28672. return static_cast<const first_base &>(*this).get();
  28673. }
  28674. /**
  28675. * @brief Returns the second element that a pair stores.
  28676. * @return The second element that a pair stores.
  28677. */
  28678. [[nodiscard]] constexpr second_type &second() noexcept {
  28679. return static_cast<second_base &>(*this).get();
  28680. }
  28681. /*! @copydoc second */
  28682. [[nodiscard]] constexpr const second_type &second() const noexcept {
  28683. return static_cast<const second_base &>(*this).get();
  28684. }
  28685. /**
  28686. * @brief Swaps two compressed pair objects.
  28687. * @param other The compressed pair to swap with.
  28688. */
  28689. constexpr void swap(compressed_pair &other) noexcept {
  28690. using std::swap;
  28691. swap(first(), other.first());
  28692. swap(second(), other.second());
  28693. }
  28694. /**
  28695. * @brief Extracts an element from the compressed pair.
  28696. * @tparam Index An integer value that is either 0 or 1.
  28697. * @return Returns a reference to the first element if `Index` is 0 and a
  28698. * reference to the second element if `Index` is 1.
  28699. */
  28700. template<std::size_t Index>
  28701. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  28702. if constexpr(Index == 0u) {
  28703. return first();
  28704. } else {
  28705. static_assert(Index == 1u, "Index out of bounds");
  28706. return second();
  28707. }
  28708. }
  28709. /*! @copydoc get */
  28710. template<std::size_t Index>
  28711. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  28712. if constexpr(Index == 0u) {
  28713. return first();
  28714. } else {
  28715. static_assert(Index == 1u, "Index out of bounds");
  28716. return second();
  28717. }
  28718. }
  28719. };
  28720. /**
  28721. * @brief Deduction guide.
  28722. * @tparam Type Type of value to use to initialize the first element.
  28723. * @tparam Other Type of value to use to initialize the second element.
  28724. */
  28725. template<typename Type, typename Other>
  28726. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  28727. /**
  28728. * @brief Swaps two compressed pair objects.
  28729. * @tparam First The type of the first element that the pairs store.
  28730. * @tparam Second The type of the second element that the pairs store.
  28731. * @param lhs A valid compressed pair object.
  28732. * @param rhs A valid compressed pair object.
  28733. */
  28734. template<typename First, typename Second>
  28735. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  28736. lhs.swap(rhs);
  28737. }
  28738. } // namespace entt
  28739. namespace std {
  28740. /**
  28741. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  28742. * @tparam First The type of the first element that the pair stores.
  28743. * @tparam Second The type of the second element that the pair stores.
  28744. */
  28745. template<typename First, typename Second>
  28746. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  28747. /**
  28748. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  28749. * @tparam Index The index of the type to return.
  28750. * @tparam First The type of the first element that the pair stores.
  28751. * @tparam Second The type of the second element that the pair stores.
  28752. */
  28753. template<size_t Index, typename First, typename Second>
  28754. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  28755. static_assert(Index < 2u, "Index out of bounds");
  28756. };
  28757. } // namespace std
  28758. #endif
  28759. // #include "../core/fwd.hpp"
  28760. // #include "../core/iterator.hpp"
  28761. // #include "../core/utility.hpp"
  28762. #ifndef ENTT_CORE_UTILITY_HPP
  28763. #define ENTT_CORE_UTILITY_HPP
  28764. #include <type_traits>
  28765. #include <utility>
  28766. namespace entt {
  28767. /*! @brief Identity function object (waiting for C++20). */
  28768. struct identity {
  28769. /*! @brief Indicates that this is a transparent function object. */
  28770. using is_transparent = void;
  28771. /**
  28772. * @brief Returns its argument unchanged.
  28773. * @tparam Type Type of the argument.
  28774. * @param value The actual argument.
  28775. * @return The submitted value as-is.
  28776. */
  28777. template<typename Type>
  28778. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  28779. return std::forward<Type>(value);
  28780. }
  28781. };
  28782. /**
  28783. * @brief Constant utility to disambiguate overloaded members of a class.
  28784. * @tparam Type Type of the desired overload.
  28785. * @tparam Class Type of class to which the member belongs.
  28786. * @param member A valid pointer to a member.
  28787. * @return Pointer to the member.
  28788. */
  28789. template<typename Type, typename Class>
  28790. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  28791. return member;
  28792. }
  28793. /**
  28794. * @brief Constant utility to disambiguate overloaded functions.
  28795. * @tparam Func Function type of the desired overload.
  28796. * @param func A valid pointer to a function.
  28797. * @return Pointer to the function.
  28798. */
  28799. template<typename Func>
  28800. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  28801. return func;
  28802. }
  28803. /**
  28804. * @brief Helper type for visitors.
  28805. * @tparam Func Types of function objects.
  28806. */
  28807. template<typename... Func>
  28808. struct overloaded: Func... {
  28809. using Func::operator()...;
  28810. };
  28811. /**
  28812. * @brief Deduction guide.
  28813. * @tparam Func Types of function objects.
  28814. */
  28815. template<typename... Func>
  28816. overloaded(Func...) -> overloaded<Func...>;
  28817. /**
  28818. * @brief Basic implementation of a y-combinator.
  28819. * @tparam Func Type of a potentially recursive function.
  28820. */
  28821. template<typename Func>
  28822. struct y_combinator {
  28823. /**
  28824. * @brief Constructs a y-combinator from a given function.
  28825. * @param recursive A potentially recursive function.
  28826. */
  28827. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  28828. : func{std::move(recursive)} {}
  28829. /**
  28830. * @brief Invokes a y-combinator and therefore its underlying function.
  28831. * @tparam Args Types of arguments to use to invoke the underlying function.
  28832. * @param args Parameters to use to invoke the underlying function.
  28833. * @return Return value of the underlying function, if any.
  28834. */
  28835. template<typename... Args>
  28836. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  28837. return func(*this, std::forward<Args>(args)...);
  28838. }
  28839. /*! @copydoc operator()() */
  28840. template<typename... Args>
  28841. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  28842. return func(*this, std::forward<Args>(args)...);
  28843. }
  28844. private:
  28845. Func func;
  28846. };
  28847. } // namespace entt
  28848. #endif
  28849. // #include "adjacency_matrix.hpp"
  28850. #ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  28851. #define ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  28852. #include <cstddef>
  28853. #include <iterator>
  28854. #include <memory>
  28855. #include <type_traits>
  28856. #include <utility>
  28857. #include <vector>
  28858. // #include "../config/config.h"
  28859. // #include "../core/iterator.hpp"
  28860. // #include "fwd.hpp"
  28861. namespace entt {
  28862. /*! @cond TURN_OFF_DOXYGEN */
  28863. namespace internal {
  28864. template<typename It>
  28865. class edge_iterator {
  28866. using size_type = std::size_t;
  28867. void find_next() noexcept {
  28868. for(; pos != last && !it[static_cast<typename It::difference_type>(pos)]; pos += offset) {}
  28869. }
  28870. public:
  28871. using value_type = std::pair<size_type, size_type>;
  28872. using pointer = input_iterator_pointer<value_type>;
  28873. using reference = value_type;
  28874. using difference_type = std::ptrdiff_t;
  28875. using iterator_category = std::input_iterator_tag;
  28876. using iterator_concept = std::forward_iterator_tag;
  28877. constexpr edge_iterator() noexcept = default;
  28878. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
  28879. constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept
  28880. : it{std::move(base)},
  28881. vert{vertices},
  28882. pos{from},
  28883. last{to},
  28884. offset{step} {
  28885. find_next();
  28886. }
  28887. constexpr edge_iterator &operator++() noexcept {
  28888. pos += offset;
  28889. find_next();
  28890. return *this;
  28891. }
  28892. constexpr edge_iterator operator++(int) noexcept {
  28893. const edge_iterator orig = *this;
  28894. return ++(*this), orig;
  28895. }
  28896. [[nodiscard]] constexpr reference operator*() const noexcept {
  28897. return *operator->();
  28898. }
  28899. [[nodiscard]] constexpr pointer operator->() const noexcept {
  28900. return std::make_pair<size_type>(pos / vert, pos % vert);
  28901. }
  28902. template<typename Type>
  28903. friend constexpr bool operator==(const edge_iterator<Type> &, const edge_iterator<Type> &) noexcept;
  28904. private:
  28905. It it{};
  28906. size_type vert{};
  28907. size_type pos{};
  28908. size_type last{};
  28909. size_type offset{};
  28910. };
  28911. template<typename Container>
  28912. [[nodiscard]] constexpr bool operator==(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  28913. return lhs.pos == rhs.pos;
  28914. }
  28915. template<typename Container>
  28916. [[nodiscard]] constexpr bool operator!=(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  28917. return !(lhs == rhs);
  28918. }
  28919. } // namespace internal
  28920. /*! @endcond */
  28921. /**
  28922. * @brief Basic implementation of a directed adjacency matrix.
  28923. * @tparam Category Either a directed or undirected category tag.
  28924. * @tparam Allocator Type of allocator used to manage memory and elements.
  28925. */
  28926. template<typename Category, typename Allocator>
  28927. class adjacency_matrix {
  28928. using alloc_traits = std::allocator_traits<Allocator>;
  28929. static_assert(std::is_base_of_v<directed_tag, Category>, "Invalid graph category");
  28930. static_assert(std::is_same_v<typename alloc_traits::value_type, std::size_t>, "Invalid value type");
  28931. using container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  28932. public:
  28933. /*! @brief Allocator type. */
  28934. using allocator_type = Allocator;
  28935. /*! @brief Unsigned integer type. */
  28936. using size_type = std::size_t;
  28937. /*! @brief Vertex type. */
  28938. using vertex_type = size_type;
  28939. /*! @brief Edge type. */
  28940. using edge_type = std::pair<vertex_type, vertex_type>;
  28941. /*! @brief Vertex iterator type. */
  28942. using vertex_iterator = iota_iterator<vertex_type>;
  28943. /*! @brief Edge iterator type. */
  28944. using edge_iterator = internal::edge_iterator<typename container_type::const_iterator>;
  28945. /*! @brief Out-edge iterator type. */
  28946. using out_edge_iterator = edge_iterator;
  28947. /*! @brief In-edge iterator type. */
  28948. using in_edge_iterator = edge_iterator;
  28949. /*! @brief Graph category tag. */
  28950. using graph_category = Category;
  28951. /*! @brief Default constructor. */
  28952. adjacency_matrix() noexcept(noexcept(allocator_type{}))
  28953. : adjacency_matrix{0u} {
  28954. }
  28955. /**
  28956. * @brief Constructs an empty container with a given allocator.
  28957. * @param allocator The allocator to use.
  28958. */
  28959. explicit adjacency_matrix(const allocator_type &allocator) noexcept
  28960. : adjacency_matrix{0u, allocator} {}
  28961. /**
  28962. * @brief Constructs an empty container with a given allocator and user
  28963. * supplied number of vertices.
  28964. * @param vertices Number of vertices.
  28965. * @param allocator The allocator to use.
  28966. */
  28967. adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{})
  28968. : matrix{vertices * vertices, allocator},
  28969. vert{vertices} {}
  28970. /*! @brief Default copy constructor. */
  28971. adjacency_matrix(const adjacency_matrix &) = default;
  28972. /**
  28973. * @brief Allocator-extended copy constructor.
  28974. * @param other The instance to copy from.
  28975. * @param allocator The allocator to use.
  28976. */
  28977. adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator)
  28978. : matrix{other.matrix, allocator},
  28979. vert{other.vert} {}
  28980. /*! @brief Default move constructor. */
  28981. adjacency_matrix(adjacency_matrix &&) noexcept = default;
  28982. /**
  28983. * @brief Allocator-extended move constructor.
  28984. * @param other The instance to move from.
  28985. * @param allocator The allocator to use.
  28986. */
  28987. adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator)
  28988. : matrix{std::move(other.matrix), allocator},
  28989. vert{other.vert} {}
  28990. /*! @brief Default destructor. */
  28991. ~adjacency_matrix() = default;
  28992. /**
  28993. * @brief Default copy assignment operator.
  28994. * @return This container.
  28995. */
  28996. adjacency_matrix &operator=(const adjacency_matrix &) = default;
  28997. /**
  28998. * @brief Default move assignment operator.
  28999. * @return This container.
  29000. */
  29001. adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default;
  29002. /**
  29003. * @brief Exchanges the contents with those of a given adjacency matrix.
  29004. * @param other Adjacency matrix to exchange the content with.
  29005. */
  29006. void swap(adjacency_matrix &other) noexcept {
  29007. using std::swap;
  29008. swap(matrix, other.matrix);
  29009. swap(vert, other.vert);
  29010. }
  29011. /**
  29012. * @brief Returns the associated allocator.
  29013. * @return The associated allocator.
  29014. */
  29015. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  29016. return matrix.get_allocator();
  29017. }
  29018. /*! @brief Clears the adjacency matrix. */
  29019. void clear() noexcept {
  29020. matrix.clear();
  29021. vert = {};
  29022. }
  29023. /**
  29024. * @brief Returns true if an adjacency matrix is empty, false otherwise.
  29025. *
  29026. * @warning
  29027. * Potentially expensive, try to avoid it on hot paths.
  29028. *
  29029. * @return True if the adjacency matrix is empty, false otherwise.
  29030. */
  29031. [[nodiscard]] bool empty() const noexcept {
  29032. const auto iterable = edges();
  29033. return (iterable.begin() == iterable.end());
  29034. }
  29035. /**
  29036. * @brief Returns the number of vertices.
  29037. * @return The number of vertices.
  29038. */
  29039. [[nodiscard]] size_type size() const noexcept {
  29040. return vert;
  29041. }
  29042. /**
  29043. * @brief Returns an iterable object to visit all vertices of a matrix.
  29044. * @return An iterable object to visit all vertices of a matrix.
  29045. */
  29046. [[nodiscard]] iterable_adaptor<vertex_iterator> vertices() const noexcept {
  29047. return {0u, vert};
  29048. }
  29049. /**
  29050. * @brief Returns an iterable object to visit all edges of a matrix.
  29051. * @return An iterable object to visit all edges of a matrix.
  29052. */
  29053. [[nodiscard]] iterable_adaptor<edge_iterator> edges() const noexcept {
  29054. const auto it = matrix.cbegin();
  29055. const auto sz = matrix.size();
  29056. return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}};
  29057. }
  29058. /**
  29059. * @brief Returns an iterable object to visit all out-edges of a vertex.
  29060. * @param vertex The vertex of which to return all out-edges.
  29061. * @return An iterable object to visit all out-edges of a vertex.
  29062. */
  29063. [[nodiscard]] iterable_adaptor<out_edge_iterator> out_edges(const vertex_type vertex) const noexcept {
  29064. const auto it = matrix.cbegin();
  29065. const auto from = vertex * vert;
  29066. const auto to = from + vert;
  29067. return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}};
  29068. }
  29069. /**
  29070. * @brief Returns an iterable object to visit all in-edges of a vertex.
  29071. * @param vertex The vertex of which to return all in-edges.
  29072. * @return An iterable object to visit all in-edges of a vertex.
  29073. */
  29074. [[nodiscard]] iterable_adaptor<in_edge_iterator> in_edges(const vertex_type vertex) const noexcept {
  29075. const auto it = matrix.cbegin();
  29076. const auto from = vertex;
  29077. const auto to = vert * vert + from;
  29078. return {{it, vert, from, to, vert}, {it, vert, to, to, vert}};
  29079. }
  29080. /**
  29081. * @brief Resizes an adjacency matrix.
  29082. * @param vertices The new number of vertices.
  29083. */
  29084. void resize(const size_type vertices) {
  29085. adjacency_matrix other{vertices, get_allocator()};
  29086. for(auto [lhs, rhs]: edges()) {
  29087. other.insert(lhs, rhs);
  29088. }
  29089. other.swap(*this);
  29090. }
  29091. /**
  29092. * @brief Inserts an edge into the adjacency matrix, if it does not exist.
  29093. * @param lhs The left hand vertex of the edge.
  29094. * @param rhs The right hand vertex of the edge.
  29095. * @return A pair consisting of an iterator to the inserted element (or to
  29096. * the element that prevented the insertion) and a bool denoting whether the
  29097. * insertion took place.
  29098. */
  29099. std::pair<edge_iterator, bool> insert(const vertex_type lhs, const vertex_type rhs) {
  29100. const auto pos = lhs * vert + rhs;
  29101. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  29102. const auto rev = rhs * vert + lhs;
  29103. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  29104. matrix[rev] = 1u;
  29105. }
  29106. const auto inserted = !std::exchange(matrix[pos], 1u);
  29107. return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted};
  29108. }
  29109. /**
  29110. * @brief Removes the edge associated with a pair of given vertices.
  29111. * @param lhs The left hand vertex of the edge.
  29112. * @param rhs The right hand vertex of the edge.
  29113. * @return Number of elements removed (either 0 or 1).
  29114. */
  29115. size_type erase(const vertex_type lhs, const vertex_type rhs) {
  29116. const auto pos = lhs * vert + rhs;
  29117. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  29118. const auto rev = rhs * vert + lhs;
  29119. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  29120. matrix[rev] = 0u;
  29121. }
  29122. return std::exchange(matrix[pos], 0u);
  29123. }
  29124. /**
  29125. * @brief Checks if an adjacency matrix contains a given edge.
  29126. * @param lhs The left hand vertex of the edge.
  29127. * @param rhs The right hand vertex of the edge.
  29128. * @return True if there is such an edge, false otherwise.
  29129. */
  29130. [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const {
  29131. const auto pos = lhs * vert + rhs;
  29132. return pos < matrix.size() && matrix[pos];
  29133. }
  29134. private:
  29135. container_type matrix;
  29136. size_type vert;
  29137. };
  29138. } // namespace entt
  29139. #endif
  29140. // #include "fwd.hpp"
  29141. namespace entt {
  29142. /**
  29143. * @brief Utility class for creating task graphs.
  29144. * @tparam Allocator Type of allocator used to manage memory and elements.
  29145. */
  29146. template<typename Allocator>
  29147. class basic_flow {
  29148. using alloc_traits = std::allocator_traits<Allocator>;
  29149. static_assert(std::is_same_v<typename alloc_traits::value_type, id_type>, "Invalid value type");
  29150. using task_container_type = dense_set<id_type, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc<id_type>>;
  29151. using ro_rw_container_type = std::vector<std::pair<std::size_t, bool>, typename alloc_traits::template rebind_alloc<std::pair<std::size_t, bool>>>;
  29152. using deps_container_type = dense_map<id_type, ro_rw_container_type, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc<std::pair<const id_type, ro_rw_container_type>>>;
  29153. using adjacency_matrix_type = adjacency_matrix<directed_tag, typename alloc_traits::template rebind_alloc<std::size_t>>;
  29154. void emplace(const id_type res, const bool is_rw) {
  29155. ENTT_ASSERT(index.first() < vertices.size(), "Invalid node");
  29156. if(!deps.contains(res) && sync_on != vertices.size()) {
  29157. deps[res].emplace_back(sync_on, true);
  29158. }
  29159. deps[res].emplace_back(index.first(), is_rw);
  29160. }
  29161. void setup_graph(adjacency_matrix_type &matrix) const {
  29162. for(const auto &elem: deps) {
  29163. const auto last = elem.second.cend();
  29164. auto it = elem.second.cbegin();
  29165. while(it != last) {
  29166. if(it->second) {
  29167. // rw item
  29168. if(auto curr = it++; it != last) {
  29169. if(it->second) {
  29170. matrix.insert(curr->first, it->first);
  29171. } else if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) {
  29172. for(; it != next; ++it) {
  29173. matrix.insert(curr->first, it->first);
  29174. matrix.insert(it->first, next->first);
  29175. }
  29176. } else {
  29177. for(; it != next; ++it) {
  29178. matrix.insert(curr->first, it->first);
  29179. }
  29180. }
  29181. }
  29182. } else {
  29183. // ro item (first iteration only)
  29184. if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) {
  29185. for(; it != next; ++it) {
  29186. matrix.insert(it->first, next->first);
  29187. }
  29188. } else {
  29189. it = last;
  29190. }
  29191. }
  29192. }
  29193. }
  29194. }
  29195. void transitive_closure(adjacency_matrix_type &matrix) const {
  29196. const auto length = matrix.size();
  29197. for(std::size_t vk{}; vk < length; ++vk) {
  29198. for(std::size_t vi{}; vi < length; ++vi) {
  29199. for(std::size_t vj{}; vj < length; ++vj) {
  29200. if(matrix.contains(vi, vk) && matrix.contains(vk, vj)) {
  29201. matrix.insert(vi, vj);
  29202. }
  29203. }
  29204. }
  29205. }
  29206. }
  29207. void transitive_reduction(adjacency_matrix_type &matrix) const {
  29208. const auto length = matrix.size();
  29209. for(std::size_t vert{}; vert < length; ++vert) {
  29210. matrix.erase(vert, vert);
  29211. }
  29212. for(std::size_t vj{}; vj < length; ++vj) {
  29213. for(std::size_t vi{}; vi < length; ++vi) {
  29214. if(matrix.contains(vi, vj)) {
  29215. for(std::size_t vk{}; vk < length; ++vk) {
  29216. if(matrix.contains(vj, vk)) {
  29217. matrix.erase(vi, vk);
  29218. }
  29219. }
  29220. }
  29221. }
  29222. }
  29223. }
  29224. public:
  29225. /*! @brief Allocator type. */
  29226. using allocator_type = Allocator;
  29227. /*! @brief Unsigned integer type. */
  29228. using size_type = std::size_t;
  29229. /*! @brief Iterable task list. */
  29230. using iterable = iterable_adaptor<typename task_container_type::const_iterator>;
  29231. /*! @brief Adjacency matrix type. */
  29232. using graph_type = adjacency_matrix_type;
  29233. /*! @brief Default constructor. */
  29234. basic_flow()
  29235. : basic_flow{allocator_type{}} {}
  29236. /**
  29237. * @brief Constructs a flow builder with a given allocator.
  29238. * @param allocator The allocator to use.
  29239. */
  29240. explicit basic_flow(const allocator_type &allocator)
  29241. : index{0u, allocator},
  29242. vertices{allocator},
  29243. deps{allocator} {}
  29244. /*! @brief Default copy constructor. */
  29245. basic_flow(const basic_flow &) = default;
  29246. /**
  29247. * @brief Allocator-extended copy constructor.
  29248. * @param other The instance to copy from.
  29249. * @param allocator The allocator to use.
  29250. */
  29251. basic_flow(const basic_flow &other, const allocator_type &allocator)
  29252. : index{other.index.first(), allocator},
  29253. vertices{other.vertices, allocator},
  29254. deps{other.deps, allocator},
  29255. sync_on{other.sync_on} {}
  29256. /*! @brief Default move constructor. */
  29257. basic_flow(basic_flow &&) noexcept = default;
  29258. /**
  29259. * @brief Allocator-extended move constructor.
  29260. * @param other The instance to move from.
  29261. * @param allocator The allocator to use.
  29262. */
  29263. basic_flow(basic_flow &&other, const allocator_type &allocator)
  29264. : index{other.index.first(), allocator},
  29265. vertices{std::move(other.vertices), allocator},
  29266. deps{std::move(other.deps), allocator},
  29267. sync_on{other.sync_on} {}
  29268. /*! @brief Default destructor. */
  29269. ~basic_flow() = default;
  29270. /**
  29271. * @brief Default copy assignment operator.
  29272. * @return This flow builder.
  29273. */
  29274. basic_flow &operator=(const basic_flow &) = default;
  29275. /**
  29276. * @brief Default move assignment operator.
  29277. * @return This flow builder.
  29278. */
  29279. basic_flow &operator=(basic_flow &&) noexcept = default;
  29280. /**
  29281. * @brief Exchanges the contents with those of a given flow builder.
  29282. * @param other Flow builder to exchange the content with.
  29283. */
  29284. void swap(basic_flow &other) noexcept {
  29285. using std::swap;
  29286. std::swap(index, other.index);
  29287. std::swap(vertices, other.vertices);
  29288. std::swap(deps, other.deps);
  29289. std::swap(sync_on, other.sync_on);
  29290. }
  29291. /**
  29292. * @brief Returns the associated allocator.
  29293. * @return The associated allocator.
  29294. */
  29295. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  29296. return allocator_type{index.second()};
  29297. }
  29298. /**
  29299. * @brief Returns the identifier at specified location.
  29300. * @param pos Position of the identifier to return.
  29301. * @return The requested identifier.
  29302. */
  29303. [[nodiscard]] id_type operator[](const size_type pos) const {
  29304. return vertices.cbegin()[static_cast<typename task_container_type::difference_type>(pos)];
  29305. }
  29306. /*! @brief Clears the flow builder. */
  29307. void clear() noexcept {
  29308. index.first() = {};
  29309. vertices.clear();
  29310. deps.clear();
  29311. sync_on = {};
  29312. }
  29313. /**
  29314. * @brief Returns true if a flow builder contains no tasks, false otherwise.
  29315. * @return True if the flow builder contains no tasks, false otherwise.
  29316. */
  29317. [[nodiscard]] bool empty() const noexcept {
  29318. return vertices.empty();
  29319. }
  29320. /**
  29321. * @brief Returns the number of tasks.
  29322. * @return The number of tasks.
  29323. */
  29324. [[nodiscard]] size_type size() const noexcept {
  29325. return vertices.size();
  29326. }
  29327. /**
  29328. * @brief Binds a task to a flow builder.
  29329. * @param value Task identifier.
  29330. * @return This flow builder.
  29331. */
  29332. basic_flow &bind(const id_type value) {
  29333. sync_on += (sync_on == vertices.size());
  29334. const auto it = vertices.emplace(value).first;
  29335. index.first() = size_type(it - vertices.begin());
  29336. return *this;
  29337. }
  29338. /**
  29339. * @brief Turns the current task into a sync point.
  29340. * @return This flow builder.
  29341. */
  29342. basic_flow &sync() {
  29343. ENTT_ASSERT(index.first() < vertices.size(), "Invalid node");
  29344. sync_on = index.first();
  29345. for(const auto &elem: deps) {
  29346. elem.second.emplace_back(sync_on, true);
  29347. }
  29348. return *this;
  29349. }
  29350. /**
  29351. * @brief Assigns a resource to the current task with a given access mode.
  29352. * @param res Resource identifier.
  29353. * @param is_rw Access mode.
  29354. * @return This flow builder.
  29355. */
  29356. basic_flow &set(const id_type res, bool is_rw = false) {
  29357. emplace(res, is_rw);
  29358. return *this;
  29359. }
  29360. /**
  29361. * @brief Assigns a read-only resource to the current task.
  29362. * @param res Resource identifier.
  29363. * @return This flow builder.
  29364. */
  29365. basic_flow &ro(const id_type res) {
  29366. emplace(res, false);
  29367. return *this;
  29368. }
  29369. /**
  29370. * @brief Assigns a range of read-only resources to the current task.
  29371. * @tparam It Type of input iterator.
  29372. * @param first An iterator to the first element of the range of elements.
  29373. * @param last An iterator past the last element of the range of elements.
  29374. * @return This flow builder.
  29375. */
  29376. template<typename It>
  29377. std::enable_if_t<std::is_same_v<std::remove_const_t<typename std::iterator_traits<It>::value_type>, id_type>, basic_flow &>
  29378. ro(It first, It last) {
  29379. for(; first != last; ++first) {
  29380. emplace(*first, false);
  29381. }
  29382. return *this;
  29383. }
  29384. /**
  29385. * @brief Assigns a writable resource to the current task.
  29386. * @param res Resource identifier.
  29387. * @return This flow builder.
  29388. */
  29389. basic_flow &rw(const id_type res) {
  29390. emplace(res, true);
  29391. return *this;
  29392. }
  29393. /**
  29394. * @brief Assigns a range of writable resources to the current task.
  29395. * @tparam It Type of input iterator.
  29396. * @param first An iterator to the first element of the range of elements.
  29397. * @param last An iterator past the last element of the range of elements.
  29398. * @return This flow builder.
  29399. */
  29400. template<typename It>
  29401. std::enable_if_t<std::is_same_v<std::remove_const_t<typename std::iterator_traits<It>::value_type>, id_type>, basic_flow &>
  29402. rw(It first, It last) {
  29403. for(; first != last; ++first) {
  29404. emplace(*first, true);
  29405. }
  29406. return *this;
  29407. }
  29408. /**
  29409. * @brief Generates a task graph for the current content.
  29410. * @return The adjacency matrix of the task graph.
  29411. */
  29412. [[nodiscard]] graph_type graph() const {
  29413. graph_type matrix{vertices.size(), get_allocator()};
  29414. setup_graph(matrix);
  29415. transitive_closure(matrix);
  29416. transitive_reduction(matrix);
  29417. return matrix;
  29418. }
  29419. private:
  29420. compressed_pair<size_type, allocator_type> index;
  29421. task_container_type vertices;
  29422. deps_container_type deps;
  29423. size_type sync_on{};
  29424. };
  29425. } // namespace entt
  29426. #endif
  29427. // #include "fwd.hpp"
  29428. // #include "helper.hpp"
  29429. #ifndef ENTT_ENTITY_HELPER_HPP
  29430. #define ENTT_ENTITY_HELPER_HPP
  29431. #include <memory>
  29432. #include <type_traits>
  29433. #include <utility>
  29434. // #include "../core/fwd.hpp"
  29435. // #include "../core/type_traits.hpp"
  29436. // #include "component.hpp"
  29437. // #include "fwd.hpp"
  29438. // #include "group.hpp"
  29439. // #include "storage.hpp"
  29440. // #include "view.hpp"
  29441. namespace entt {
  29442. /**
  29443. * @brief Converts a registry to a view.
  29444. * @tparam Registry Basic registry type.
  29445. */
  29446. template<typename Registry>
  29447. class as_view {
  29448. template<typename... Get, typename... Exclude>
  29449. [[nodiscard]] auto dispatch(get_t<Get...>, exclude_t<Exclude...>) const {
  29450. return reg->template view<constness_as_t<typename Get::element_type, Get>...>(exclude_t<constness_as_t<typename Exclude::element_type, Exclude>...>{});
  29451. }
  29452. public:
  29453. /*! @brief Type of registry to convert. */
  29454. using registry_type = Registry;
  29455. /*! @brief Underlying entity identifier. */
  29456. using entity_type = typename registry_type::entity_type;
  29457. /**
  29458. * @brief Constructs a converter for a given registry.
  29459. * @param source A valid reference to a registry.
  29460. */
  29461. as_view(registry_type &source) noexcept
  29462. : reg{&source} {}
  29463. /**
  29464. * @brief Conversion function from a registry to a view.
  29465. * @tparam Get Type of storage used to construct the view.
  29466. * @tparam Exclude Types of storage used to filter the view.
  29467. * @return A newly created view.
  29468. */
  29469. template<typename Get, typename Exclude>
  29470. operator basic_view<Get, Exclude>() const {
  29471. return dispatch(Get{}, Exclude{});
  29472. }
  29473. private:
  29474. registry_type *reg;
  29475. };
  29476. /**
  29477. * @brief Converts a registry to a group.
  29478. * @tparam Registry Basic registry type.
  29479. */
  29480. template<typename Registry>
  29481. class as_group {
  29482. template<typename... Owned, typename... Get, typename... Exclude>
  29483. [[nodiscard]] auto dispatch(owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>) const {
  29484. if constexpr(std::is_const_v<registry_type>) {
  29485. return reg->template group_if_exists<typename Owned::element_type...>(get_t<typename Get::element_type...>{}, exclude_t<typename Exclude::element_type...>{});
  29486. } else {
  29487. return reg->template group<constness_as_t<typename Owned::element_type, Owned>...>(get_t<constness_as_t<typename Get::element_type, Get>...>{}, exclude_t<constness_as_t<typename Exclude::element_type, Exclude>...>{});
  29488. }
  29489. }
  29490. public:
  29491. /*! @brief Type of registry to convert. */
  29492. using registry_type = Registry;
  29493. /*! @brief Underlying entity identifier. */
  29494. using entity_type = typename registry_type::entity_type;
  29495. /**
  29496. * @brief Constructs a converter for a given registry.
  29497. * @param source A valid reference to a registry.
  29498. */
  29499. as_group(registry_type &source) noexcept
  29500. : reg{&source} {}
  29501. /**
  29502. * @brief Conversion function from a registry to a group.
  29503. * @tparam Owned Types of _owned_ by the group.
  29504. * @tparam Get Types of storage _observed_ by the group.
  29505. * @tparam Exclude Types of storage used to filter the group.
  29506. * @return A newly created group.
  29507. */
  29508. template<typename Owned, typename Get, typename Exclude>
  29509. operator basic_group<Owned, Get, Exclude>() const {
  29510. return dispatch(Owned{}, Get{}, Exclude{});
  29511. }
  29512. private:
  29513. registry_type *reg;
  29514. };
  29515. /**
  29516. * @brief Helper to create a listener that directly invokes a member function.
  29517. * @tparam Member Member function to invoke on an element of the given type.
  29518. * @tparam Registry Basic registry type.
  29519. * @param reg A registry that contains the given entity and its elements.
  29520. * @param entt Entity from which to get the element.
  29521. */
  29522. template<auto Member, typename Registry = std::decay_t<nth_argument_t<0u, decltype(Member)>>>
  29523. void invoke(Registry &reg, const typename Registry::entity_type entt) {
  29524. static_assert(std::is_member_function_pointer_v<decltype(Member)>, "Invalid pointer to non-static member function");
  29525. (reg.template get<member_class_t<decltype(Member)>>(entt).*Member)(reg, entt);
  29526. }
  29527. /**
  29528. * @brief Returns the entity associated with a given element.
  29529. *
  29530. * @warning
  29531. * Currently, this function only works correctly with the default storage as it
  29532. * makes assumptions about how the elements are laid out.
  29533. *
  29534. * @tparam Args Storage type template parameters.
  29535. * @param storage A storage that contains the given element.
  29536. * @param instance A valid element instance.
  29537. * @return The entity associated with the given element.
  29538. */
  29539. template<typename... Args>
  29540. typename basic_storage<Args...>::entity_type to_entity(const basic_storage<Args...> &storage, const typename basic_storage<Args...>::value_type &instance) {
  29541. using traits_type = component_traits<typename basic_storage<Args...>::value_type, typename basic_storage<Args...>::entity_type>;
  29542. static_assert(traits_type::page_size != 0u, "Unexpected page size");
  29543. const auto *page = storage.raw();
  29544. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  29545. for(std::size_t pos{}, count = storage.size(); pos < count; pos += traits_type::page_size, ++page) {
  29546. if(const auto dist = (std::addressof(instance) - *page); dist >= 0 && dist < static_cast<decltype(dist)>(traits_type::page_size)) {
  29547. return *(static_cast<const typename basic_storage<Args...>::base_type &>(storage).rbegin() + static_cast<decltype(dist)>(pos) + dist);
  29548. }
  29549. }
  29550. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  29551. return null;
  29552. }
  29553. /*! @brief Primary template isn't defined on purpose. */
  29554. template<typename...>
  29555. struct sigh_helper;
  29556. /**
  29557. * @brief Signal connection helper for registries.
  29558. * @tparam Registry Basic registry type.
  29559. */
  29560. template<typename Registry>
  29561. struct sigh_helper<Registry> {
  29562. /*! @brief Registry type. */
  29563. using registry_type = Registry;
  29564. /**
  29565. * @brief Constructs a helper for a given registry.
  29566. * @param ref A valid reference to a registry.
  29567. */
  29568. sigh_helper(registry_type &ref)
  29569. : bucket{&ref} {}
  29570. /**
  29571. * @brief Binds a properly initialized helper to a given signal type.
  29572. * @tparam Type Type of signal to bind the helper to.
  29573. * @param id Optional name for the underlying storage to use.
  29574. * @return A helper for a given registry and signal type.
  29575. */
  29576. template<typename Type>
  29577. auto with(const id_type id = type_hash<Type>::value()) noexcept {
  29578. return sigh_helper<registry_type, Type>{*bucket, id};
  29579. }
  29580. /**
  29581. * @brief Returns a reference to the underlying registry.
  29582. * @return A reference to the underlying registry.
  29583. */
  29584. [[nodiscard]] registry_type &registry() noexcept {
  29585. return *bucket;
  29586. }
  29587. private:
  29588. registry_type *bucket;
  29589. };
  29590. /**
  29591. * @brief Signal connection helper for registries.
  29592. * @tparam Registry Basic registry type.
  29593. * @tparam Type Type of signal to connect listeners to.
  29594. */
  29595. template<typename Registry, typename Type>
  29596. struct sigh_helper<Registry, Type> final: sigh_helper<Registry> {
  29597. /*! @brief Registry type. */
  29598. using registry_type = Registry;
  29599. /**
  29600. * @brief Constructs a helper for a given registry.
  29601. * @param ref A valid reference to a registry.
  29602. * @param id Optional name for the underlying storage to use.
  29603. */
  29604. sigh_helper(registry_type &ref, const id_type id = type_hash<Type>::value())
  29605. : sigh_helper<Registry>{ref},
  29606. name{id} {}
  29607. /**
  29608. * @brief Forwards the call to `on_construct` on the underlying storage.
  29609. * @tparam Candidate Function or member to connect.
  29610. * @tparam Args Type of class or type of payload, if any.
  29611. * @param args A valid object that fits the purpose, if any.
  29612. * @return This helper.
  29613. */
  29614. template<auto Candidate, typename... Args>
  29615. auto on_construct(Args &&...args) {
  29616. this->registry().template on_construct<Type>(name).template connect<Candidate>(std::forward<Args>(args)...);
  29617. return *this;
  29618. }
  29619. /**
  29620. * @brief Forwards the call to `on_update` on the underlying storage.
  29621. * @tparam Candidate Function or member to connect.
  29622. * @tparam Args Type of class or type of payload, if any.
  29623. * @param args A valid object that fits the purpose, if any.
  29624. * @return This helper.
  29625. */
  29626. template<auto Candidate, typename... Args>
  29627. auto on_update(Args &&...args) {
  29628. this->registry().template on_update<Type>(name).template connect<Candidate>(std::forward<Args>(args)...);
  29629. return *this;
  29630. }
  29631. /**
  29632. * @brief Forwards the call to `on_destroy` on the underlying storage.
  29633. * @tparam Candidate Function or member to connect.
  29634. * @tparam Args Type of class or type of payload, if any.
  29635. * @param args A valid object that fits the purpose, if any.
  29636. * @return This helper.
  29637. */
  29638. template<auto Candidate, typename... Args>
  29639. auto on_destroy(Args &&...args) {
  29640. this->registry().template on_destroy<Type>(name).template connect<Candidate>(std::forward<Args>(args)...);
  29641. return *this;
  29642. }
  29643. private:
  29644. id_type name;
  29645. };
  29646. /**
  29647. * @brief Deduction guide.
  29648. * @tparam Registry Basic registry type.
  29649. */
  29650. template<typename Registry>
  29651. sigh_helper(Registry &) -> sigh_helper<Registry>;
  29652. } // namespace entt
  29653. #endif
  29654. namespace entt {
  29655. /*! @cond TURN_OFF_DOXYGEN */
  29656. namespace internal {
  29657. template<typename>
  29658. struct is_view: std::false_type {};
  29659. template<typename... Args>
  29660. struct is_view<basic_view<Args...>>: std::true_type {};
  29661. template<typename Type>
  29662. inline constexpr bool is_view_v = is_view<Type>::value;
  29663. template<typename>
  29664. struct is_group: std::false_type {};
  29665. template<typename... Args>
  29666. struct is_group<basic_group<Args...>>: std::true_type {};
  29667. template<typename Type>
  29668. inline constexpr bool is_group_v = is_group<Type>::value;
  29669. template<typename Type, typename Override>
  29670. struct unpack_type {
  29671. using ro = std::conditional_t<
  29672. type_list_contains_v<Override, const Type> || (std::is_const_v<Type> && !type_list_contains_v<Override, std::remove_const_t<Type>>),
  29673. type_list<std::remove_const_t<Type>>,
  29674. type_list<>>;
  29675. using rw = std::conditional_t<
  29676. type_list_contains_v<Override, std::remove_const_t<Type>> || (!std::is_const_v<Type> && !type_list_contains_v<Override, const Type>),
  29677. type_list<Type>,
  29678. type_list<>>;
  29679. };
  29680. template<typename... Args, typename... Override>
  29681. struct unpack_type<basic_registry<Args...>, type_list<Override...>> {
  29682. using ro = type_list<>;
  29683. using rw = type_list<>;
  29684. };
  29685. template<typename... Args, typename... Override>
  29686. struct unpack_type<const basic_registry<Args...>, type_list<Override...>>
  29687. : unpack_type<basic_registry<Args...>, type_list<Override...>> {};
  29688. template<typename... Get, typename... Exclude, typename... Override>
  29689. struct unpack_type<basic_view<get_t<Get...>, exclude_t<Exclude...>>, type_list<Override...>> {
  29690. using ro = type_list_cat_t<type_list<typename Exclude::element_type...>, typename unpack_type<constness_as_t<typename Get::element_type, Get>, type_list<Override...>>::ro...>;
  29691. using rw = type_list_cat_t<typename unpack_type<constness_as_t<typename Get::element_type, Get>, type_list<Override...>>::rw...>;
  29692. };
  29693. template<typename... Get, typename... Exclude, typename... Override>
  29694. struct unpack_type<const basic_view<get_t<Get...>, exclude_t<Exclude...>>, type_list<Override...>>
  29695. : unpack_type<basic_view<get_t<Get...>, exclude_t<Exclude...>>, type_list<Override...>> {};
  29696. template<typename... Owned, typename... Get, typename... Exclude, typename... Override>
  29697. struct unpack_type<basic_group<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>>, type_list<Override...>> {
  29698. using ro = type_list_cat_t<type_list<typename Exclude::element_type...>, typename unpack_type<constness_as_t<typename Get::element_type, Get>, type_list<Override...>>::ro..., typename unpack_type<constness_as_t<typename Owned::element_type, Owned>, type_list<Override...>>::ro...>;
  29699. using rw = type_list_cat_t<typename unpack_type<constness_as_t<typename Get::element_type, Get>, type_list<Override...>>::rw..., typename unpack_type<constness_as_t<typename Owned::element_type, Owned>, type_list<Override...>>::rw...>;
  29700. };
  29701. template<typename... Owned, typename... Get, typename... Exclude, typename... Override>
  29702. struct unpack_type<const basic_group<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>>, type_list<Override...>>
  29703. : unpack_type<basic_group<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>>, type_list<Override...>> {};
  29704. template<typename, typename, typename>
  29705. struct resource_traits;
  29706. template<typename Registry, typename... Args, typename... Req>
  29707. struct resource_traits<Registry, type_list<Args...>, type_list<Req...>> {
  29708. using args = type_list<std::remove_const_t<Args>...>;
  29709. using ro = type_list_cat_t<typename unpack_type<Args, type_list<Req...>>::ro..., typename unpack_type<Req, type_list<>>::ro...>;
  29710. using rw = type_list_cat_t<typename unpack_type<Args, type_list<Req...>>::rw..., typename unpack_type<Req, type_list<>>::rw...>;
  29711. static constexpr auto sync_point = (std::is_same_v<Args, Registry> || ...);
  29712. };
  29713. template<typename Registry, typename... Req, typename Ret, typename... Args>
  29714. resource_traits<Registry, type_list<std::remove_reference_t<Args>...>, type_list<Req...>> free_function_to_resource_traits(Ret (*)(Args...));
  29715. template<typename Registry, typename... Req, typename Ret, typename Type, typename... Args>
  29716. resource_traits<Registry, type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource_traits(Ret (*)(Type &, Args...));
  29717. template<typename Registry, typename... Req, typename Ret, typename Class, typename... Args>
  29718. resource_traits<Registry, type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource_traits(Ret (Class::*)(Args...));
  29719. template<typename Registry, typename... Req, typename Ret, typename Class, typename... Args>
  29720. resource_traits<Registry, type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource_traits(Ret (Class::*)(Args...) const);
  29721. } // namespace internal
  29722. /*! @endcond */
  29723. /**
  29724. * @brief Utility class for creating a static task graph.
  29725. *
  29726. * This class offers minimal support (but sufficient in many cases) for creating
  29727. * an execution graph from functions and their requirements on resources.<br/>
  29728. * Note that the resulting tasks aren't executed in any case. This isn't the
  29729. * goal of the tool. Instead, they are returned to the user in the form of a
  29730. * graph that allows for safe execution.
  29731. *
  29732. * @tparam Registry Basic registry type.
  29733. */
  29734. template<typename Registry>
  29735. class basic_organizer final {
  29736. using callback_type = void(const void *, Registry &);
  29737. using prepare_type = void(Registry &);
  29738. using dependency_type = std::size_t(const bool, const type_info **, const std::size_t);
  29739. struct vertex_data final {
  29740. std::size_t ro_count{};
  29741. std::size_t rw_count{};
  29742. const char *name{};
  29743. const void *payload{};
  29744. callback_type *callback{};
  29745. dependency_type *dependency{};
  29746. prepare_type *prepare{};
  29747. const type_info *info{};
  29748. };
  29749. template<typename Type>
  29750. [[nodiscard]] static decltype(auto) extract(Registry &reg) {
  29751. if constexpr(std::is_same_v<Type, Registry>) {
  29752. return reg;
  29753. } else if constexpr(internal::is_view_v<Type>) {
  29754. return static_cast<Type>(as_view{reg});
  29755. } else if constexpr(internal::is_group_v<Type>) {
  29756. return static_cast<Type>(as_group{reg});
  29757. } else {
  29758. return reg.ctx().template emplace<std::remove_reference_t<Type>>();
  29759. }
  29760. }
  29761. template<typename... Args>
  29762. [[nodiscard]] static auto to_args(Registry &reg, type_list<Args...>) {
  29763. return std::tuple<decltype(extract<Args>(reg))...>(extract<Args>(reg)...);
  29764. }
  29765. template<typename... Type>
  29766. [[nodiscard]] static std::size_t fill_dependencies(type_list<Type...>, [[maybe_unused]] const type_info **buffer, [[maybe_unused]] const std::size_t count) {
  29767. if constexpr(sizeof...(Type) == 0u) {
  29768. return {};
  29769. } else {
  29770. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  29771. const type_info *info[]{&type_id<Type>()...};
  29772. const auto length = count < sizeof...(Type) ? count : sizeof...(Type);
  29773. for(std::size_t pos{}; pos < length; ++pos) {
  29774. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  29775. buffer[pos] = info[pos];
  29776. }
  29777. return length;
  29778. }
  29779. }
  29780. template<typename... RO, typename... RW>
  29781. void track_dependencies(std::size_t index, const bool sync_point, type_list<RO...>, type_list<RW...>) {
  29782. builder.bind(static_cast<id_type>(index));
  29783. builder.set(type_hash<Registry>::value(), sync_point || (sizeof...(RO) + sizeof...(RW) == 0u));
  29784. (builder.ro(type_hash<RO>::value()), ...);
  29785. (builder.rw(type_hash<RW>::value()), ...);
  29786. }
  29787. public:
  29788. /*! Basic registry type. */
  29789. using registry_type = Registry;
  29790. /*! @brief Underlying entity identifier. */
  29791. using entity_type = typename registry_type::entity_type;
  29792. /*! @brief Unsigned integer type. */
  29793. using size_type = std::size_t;
  29794. /*! @brief Raw task function type. */
  29795. using function_type = callback_type;
  29796. /*! @brief Vertex type of a task graph defined as an adjacency list. */
  29797. struct vertex {
  29798. /**
  29799. * @brief Constructs a vertex of the task graph.
  29800. * @param data The data associated with the vertex.
  29801. * @param from List of in-edges of the vertex.
  29802. * @param to List of out-edges of the vertex.
  29803. */
  29804. vertex(vertex_data data, std::vector<std::size_t> from, std::vector<std::size_t> to)
  29805. : node{std::move(data)},
  29806. in{std::move(from)},
  29807. out{std::move(to)} {}
  29808. /**
  29809. * @brief Fills a buffer with the type info objects for the writable
  29810. * resources of a vertex.
  29811. * @param buffer A buffer pre-allocated by the user.
  29812. * @param length The length of the user-supplied buffer.
  29813. * @return The number of type info objects written to the buffer.
  29814. */
  29815. [[nodiscard]] size_type ro_dependency(const type_info **buffer, const std::size_t length) const noexcept {
  29816. return node.dependency(false, buffer, length);
  29817. }
  29818. /**
  29819. * @brief Fills a buffer with the type info objects for the read-only
  29820. * resources of a vertex.
  29821. * @param buffer A buffer pre-allocated by the user.
  29822. * @param length The length of the user-supplied buffer.
  29823. * @return The number of type info objects written to the buffer.
  29824. */
  29825. [[nodiscard]] size_type rw_dependency(const type_info **buffer, const std::size_t length) const noexcept {
  29826. return node.dependency(true, buffer, length);
  29827. }
  29828. /**
  29829. * @brief Returns the number of read-only resources of a vertex.
  29830. * @return The number of read-only resources of the vertex.
  29831. */
  29832. [[nodiscard]] size_type ro_count() const noexcept {
  29833. return node.ro_count;
  29834. }
  29835. /**
  29836. * @brief Returns the number of writable resources of a vertex.
  29837. * @return The number of writable resources of the vertex.
  29838. */
  29839. [[nodiscard]] size_type rw_count() const noexcept {
  29840. return node.rw_count;
  29841. }
  29842. /**
  29843. * @brief Checks if a vertex is also a top-level one.
  29844. * @return True if the vertex is a top-level one, false otherwise.
  29845. */
  29846. [[nodiscard]] bool top_level() const noexcept {
  29847. return in.empty();
  29848. }
  29849. /**
  29850. * @brief Returns a type info object associated with a vertex.
  29851. * @return A properly initialized type info object.
  29852. */
  29853. [[nodiscard]] const type_info &info() const noexcept {
  29854. return *node.info;
  29855. }
  29856. /**
  29857. * @brief Returns a user defined name associated with a vertex, if any.
  29858. * @return The user defined name associated with the vertex, if any.
  29859. */
  29860. [[nodiscard]] const char *name() const noexcept {
  29861. return node.name;
  29862. }
  29863. /**
  29864. * @brief Returns the function associated with a vertex.
  29865. * @return The function associated with the vertex.
  29866. */
  29867. [[nodiscard]] function_type *callback() const noexcept {
  29868. return node.callback;
  29869. }
  29870. /**
  29871. * @brief Returns the payload associated with a vertex, if any.
  29872. * @return The payload associated with the vertex, if any.
  29873. */
  29874. [[nodiscard]] const void *data() const noexcept {
  29875. return node.payload;
  29876. }
  29877. /**
  29878. * @brief Returns the list of in-edges of a vertex.
  29879. * @return The list of in-edges of a vertex.
  29880. */
  29881. [[nodiscard]] const std::vector<std::size_t> &in_edges() const noexcept {
  29882. return in;
  29883. }
  29884. /**
  29885. * @brief Returns the list of out-edges of a vertex.
  29886. * @return The list of out-edges of a vertex.
  29887. */
  29888. [[nodiscard]] const std::vector<std::size_t> &out_edges() const noexcept {
  29889. return out;
  29890. }
  29891. /**
  29892. * @brief Prepares a registry and assures that all required resources
  29893. * are properly instantiated before using them.
  29894. * @param reg A valid registry.
  29895. */
  29896. void prepare(registry_type &reg) const {
  29897. node.prepare ? node.prepare(reg) : void();
  29898. }
  29899. private:
  29900. vertex_data node;
  29901. std::vector<std::size_t> in;
  29902. std::vector<std::size_t> out;
  29903. };
  29904. /**
  29905. * @brief Adds a free function to the task list.
  29906. * @tparam Candidate Function to add to the task list.
  29907. * @tparam Req Additional requirements and/or override resource access mode.
  29908. * @param name Optional name to associate with the task.
  29909. */
  29910. template<auto Candidate, typename... Req>
  29911. void emplace(const char *name = nullptr) {
  29912. using resource_type = decltype(internal::free_function_to_resource_traits<registry_type, Req...>(Candidate));
  29913. callback_type *callback = +[](const void *, registry_type &reg) {
  29914. std::apply(Candidate, to_args(reg, typename resource_type::args{}));
  29915. };
  29916. vertex_data vdata{
  29917. resource_type::ro::size,
  29918. resource_type::rw::size,
  29919. name,
  29920. nullptr,
  29921. callback,
  29922. +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
  29923. +[](registry_type &reg) { void(to_args(reg, typename resource_type::args{})); },
  29924. &type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
  29925. track_dependencies(vertices.size(), resource_type::sync_point, typename resource_type::ro{}, typename resource_type::rw{});
  29926. vertices.push_back(std::move(vdata));
  29927. }
  29928. /**
  29929. * @brief Adds a free function with payload or a member function with an
  29930. * instance to the task list.
  29931. * @tparam Candidate Function or member to add to the task list.
  29932. * @tparam Req Additional requirements and/or override resource access mode.
  29933. * @tparam Type Type of class or type of payload.
  29934. * @param value_or_instance A valid object that fits the purpose.
  29935. * @param name Optional name to associate with the task.
  29936. */
  29937. template<auto Candidate, typename... Req, typename Type>
  29938. void emplace(Type &value_or_instance, const char *name = nullptr) {
  29939. using resource_type = decltype(internal::constrained_function_to_resource_traits<registry_type, Req...>(Candidate));
  29940. callback_type *callback = +[](const void *payload, registry_type &reg) {
  29941. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  29942. std::apply(Candidate, std::tuple_cat(std::forward_as_tuple(*curr), to_args(reg, typename resource_type::args{})));
  29943. };
  29944. vertex_data vdata{
  29945. resource_type::ro::size,
  29946. resource_type::rw::size,
  29947. name,
  29948. &value_or_instance,
  29949. callback,
  29950. +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
  29951. +[](registry_type &reg) { void(to_args(reg, typename resource_type::args{})); },
  29952. &type_id<std::integral_constant<decltype(Candidate), Candidate>>()};
  29953. track_dependencies(vertices.size(), resource_type::sync_point, typename resource_type::ro{}, typename resource_type::rw{});
  29954. vertices.push_back(std::move(vdata));
  29955. }
  29956. /**
  29957. * @brief Adds an user defined function with optional payload to the task
  29958. * list.
  29959. * @tparam Req Additional requirements and/or override resource access mode.
  29960. * @param func Function to add to the task list.
  29961. * @param payload User defined arbitrary data.
  29962. * @param name Optional name to associate with the task.
  29963. */
  29964. template<typename... Req>
  29965. void emplace(function_type *func, const void *payload = nullptr, const char *name = nullptr) {
  29966. using resource_type = internal::resource_traits<registry_type, type_list<>, type_list<Req...>>;
  29967. track_dependencies(vertices.size(), true, typename resource_type::ro{}, typename resource_type::rw{});
  29968. vertex_data vdata{
  29969. resource_type::ro::size,
  29970. resource_type::rw::size,
  29971. name,
  29972. payload,
  29973. func,
  29974. +[](const bool rw, const type_info **buffer, const std::size_t length) { return rw ? fill_dependencies(typename resource_type::rw{}, buffer, length) : fill_dependencies(typename resource_type::ro{}, buffer, length); },
  29975. nullptr,
  29976. &type_id<void>()};
  29977. vertices.push_back(std::move(vdata));
  29978. }
  29979. /**
  29980. * @brief Generates a task graph for the current content.
  29981. * @return The adjacency list of the task graph.
  29982. */
  29983. [[nodiscard]] std::vector<vertex> graph() const {
  29984. std::vector<vertex> adjacency_list{};
  29985. adjacency_list.reserve(vertices.size());
  29986. auto adjacency_matrix = builder.graph();
  29987. for(auto curr: adjacency_matrix.vertices()) {
  29988. std::vector<std::size_t> in{};
  29989. std::vector<std::size_t> out{};
  29990. for(auto &&edge: adjacency_matrix.in_edges(curr)) {
  29991. in.push_back(edge.first);
  29992. }
  29993. for(auto &&edge: adjacency_matrix.out_edges(curr)) {
  29994. out.push_back(edge.second);
  29995. }
  29996. adjacency_list.emplace_back(vertices[curr], std::move(in), std::move(out));
  29997. }
  29998. return adjacency_list;
  29999. }
  30000. /*! @brief Erases all elements from a container. */
  30001. void clear() {
  30002. builder.clear();
  30003. vertices.clear();
  30004. }
  30005. private:
  30006. std::vector<vertex_data> vertices;
  30007. flow builder;
  30008. };
  30009. } // namespace entt
  30010. #endif
  30011. // #include "entity/ranges.hpp"
  30012. #ifndef ENTT_ENTITY_RANGES_HPP
  30013. #define ENTT_ENTITY_RANGES_HPP
  30014. #if __has_include(<version>)
  30015. # include <version>
  30016. #
  30017. # if defined(__cpp_lib_ranges)
  30018. # include <ranges>
  30019. // # include "fwd.hpp"
  30020. template<class... Args>
  30021. inline constexpr bool std::ranges::enable_borrowed_range<entt::basic_view<Args...>>{true};
  30022. template<class... Args>
  30023. inline constexpr bool std::ranges::enable_borrowed_range<entt::basic_group<Args...>>{true};
  30024. template<class... Args>
  30025. inline constexpr bool std::ranges::enable_view<entt::basic_view<Args...>>{true};
  30026. template<class... Args>
  30027. inline constexpr bool std::ranges::enable_view<entt::basic_group<Args...>>{true};
  30028. # endif
  30029. #endif
  30030. #endif
  30031. // #include "entity/registry.hpp"
  30032. #ifndef ENTT_ENTITY_REGISTRY_HPP
  30033. #define ENTT_ENTITY_REGISTRY_HPP
  30034. #include <algorithm>
  30035. #include <array>
  30036. #include <cstddef>
  30037. #include <functional>
  30038. #include <iterator>
  30039. #include <memory>
  30040. #include <tuple>
  30041. #include <type_traits>
  30042. #include <utility>
  30043. #include <vector>
  30044. // #include "../config/config.h"
  30045. // #include "../container/dense_map.hpp"
  30046. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  30047. #define ENTT_CONTAINER_DENSE_MAP_HPP
  30048. #include <cmath>
  30049. #include <cstddef>
  30050. #include <functional>
  30051. #include <iterator>
  30052. #include <limits>
  30053. #include <memory>
  30054. #include <tuple>
  30055. #include <type_traits>
  30056. #include <utility>
  30057. #include <vector>
  30058. // #include "../config/config.h"
  30059. #ifndef ENTT_CONFIG_CONFIG_H
  30060. #define ENTT_CONFIG_CONFIG_H
  30061. // #include "version.h"
  30062. #ifndef ENTT_CONFIG_VERSION_H
  30063. #define ENTT_CONFIG_VERSION_H
  30064. // #include "macro.h"
  30065. #ifndef ENTT_CONFIG_MACRO_H
  30066. #define ENTT_CONFIG_MACRO_H
  30067. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  30068. #define ENTT_STR(arg) #arg
  30069. #define ENTT_XSTR(arg) ENTT_STR(arg)
  30070. // NOLINTEND(cppcoreguidelines-macro-usage)
  30071. #endif
  30072. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  30073. #define ENTT_VERSION_MAJOR 3
  30074. #define ENTT_VERSION_MINOR 16
  30075. #define ENTT_VERSION_PATCH 0
  30076. #define ENTT_VERSION \
  30077. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  30078. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  30079. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  30080. #endif
  30081. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  30082. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  30083. # define ENTT_CONSTEXPR
  30084. # define ENTT_THROW throw
  30085. # define ENTT_TRY try
  30086. # define ENTT_CATCH catch(...)
  30087. #else
  30088. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  30089. # define ENTT_THROW
  30090. # define ENTT_TRY if(true)
  30091. # define ENTT_CATCH if(false)
  30092. #endif
  30093. #if __has_include(<version>)
  30094. # include <version>
  30095. #
  30096. # if defined(__cpp_consteval)
  30097. # define ENTT_CONSTEVAL consteval
  30098. # endif
  30099. #endif
  30100. #ifndef ENTT_CONSTEVAL
  30101. # define ENTT_CONSTEVAL constexpr
  30102. #endif
  30103. #ifdef ENTT_USE_ATOMIC
  30104. # include <atomic>
  30105. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  30106. #else
  30107. # define ENTT_MAYBE_ATOMIC(Type) Type
  30108. #endif
  30109. #ifndef ENTT_ID_TYPE
  30110. # include <cstdint>
  30111. # define ENTT_ID_TYPE std::uint32_t
  30112. #else
  30113. # include <cstdint> // provides coverage for types in the std namespace
  30114. #endif
  30115. #ifndef ENTT_SPARSE_PAGE
  30116. # define ENTT_SPARSE_PAGE 4096
  30117. #endif
  30118. #ifndef ENTT_PACKED_PAGE
  30119. # define ENTT_PACKED_PAGE 1024
  30120. #endif
  30121. #ifdef ENTT_DISABLE_ASSERT
  30122. # undef ENTT_ASSERT
  30123. # define ENTT_ASSERT(condition, msg) (void(0))
  30124. #elif !defined ENTT_ASSERT
  30125. # include <cassert>
  30126. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  30127. #endif
  30128. #ifdef ENTT_DISABLE_ASSERT
  30129. # undef ENTT_ASSERT_CONSTEXPR
  30130. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  30131. #elif !defined ENTT_ASSERT_CONSTEXPR
  30132. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  30133. #endif
  30134. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  30135. #ifdef ENTT_NO_ETO
  30136. # define ENTT_ETO_TYPE(Type) void
  30137. #else
  30138. # define ENTT_ETO_TYPE(Type) Type
  30139. #endif
  30140. #ifdef ENTT_NO_MIXIN
  30141. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  30142. #else
  30143. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  30144. #endif
  30145. #ifdef ENTT_STANDARD_CPP
  30146. # define ENTT_NONSTD false
  30147. #else
  30148. # define ENTT_NONSTD true
  30149. # if defined __clang__ || defined __GNUC__
  30150. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  30151. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  30152. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  30153. # elif defined _MSC_VER
  30154. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  30155. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  30156. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  30157. # endif
  30158. #endif
  30159. #ifndef ENTT_EXPORT
  30160. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  30161. # define ENTT_EXPORT __declspec(dllexport)
  30162. # define ENTT_IMPORT __declspec(dllimport)
  30163. # define ENTT_HIDDEN
  30164. # elif defined __GNUC__ && __GNUC__ >= 4
  30165. # define ENTT_EXPORT __attribute__((visibility("default")))
  30166. # define ENTT_IMPORT __attribute__((visibility("default")))
  30167. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  30168. # else /* Unsupported compiler */
  30169. # define ENTT_EXPORT
  30170. # define ENTT_IMPORT
  30171. # define ENTT_HIDDEN
  30172. # endif
  30173. #endif
  30174. #ifndef ENTT_API
  30175. # if defined ENTT_API_EXPORT
  30176. # define ENTT_API ENTT_EXPORT
  30177. # elif defined ENTT_API_IMPORT
  30178. # define ENTT_API ENTT_IMPORT
  30179. # else /* No API */
  30180. # define ENTT_API
  30181. # endif
  30182. #endif
  30183. #if defined _MSC_VER
  30184. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  30185. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  30186. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  30187. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  30188. #endif
  30189. // NOLINTEND(cppcoreguidelines-macro-usage)
  30190. #endif
  30191. // #include "../core/bit.hpp"
  30192. #ifndef ENTT_CORE_BIT_HPP
  30193. #define ENTT_CORE_BIT_HPP
  30194. #include <cstddef>
  30195. #include <limits>
  30196. #include <type_traits>
  30197. // #include "../config/config.h"
  30198. #ifndef ENTT_CONFIG_CONFIG_H
  30199. #define ENTT_CONFIG_CONFIG_H
  30200. // #include "version.h"
  30201. #ifndef ENTT_CONFIG_VERSION_H
  30202. #define ENTT_CONFIG_VERSION_H
  30203. // #include "macro.h"
  30204. #ifndef ENTT_CONFIG_MACRO_H
  30205. #define ENTT_CONFIG_MACRO_H
  30206. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  30207. #define ENTT_STR(arg) #arg
  30208. #define ENTT_XSTR(arg) ENTT_STR(arg)
  30209. // NOLINTEND(cppcoreguidelines-macro-usage)
  30210. #endif
  30211. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  30212. #define ENTT_VERSION_MAJOR 3
  30213. #define ENTT_VERSION_MINOR 16
  30214. #define ENTT_VERSION_PATCH 0
  30215. #define ENTT_VERSION \
  30216. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  30217. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  30218. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  30219. #endif
  30220. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  30221. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  30222. # define ENTT_CONSTEXPR
  30223. # define ENTT_THROW throw
  30224. # define ENTT_TRY try
  30225. # define ENTT_CATCH catch(...)
  30226. #else
  30227. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  30228. # define ENTT_THROW
  30229. # define ENTT_TRY if(true)
  30230. # define ENTT_CATCH if(false)
  30231. #endif
  30232. #if __has_include(<version>)
  30233. # include <version>
  30234. #
  30235. # if defined(__cpp_consteval)
  30236. # define ENTT_CONSTEVAL consteval
  30237. # endif
  30238. #endif
  30239. #ifndef ENTT_CONSTEVAL
  30240. # define ENTT_CONSTEVAL constexpr
  30241. #endif
  30242. #ifdef ENTT_USE_ATOMIC
  30243. # include <atomic>
  30244. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  30245. #else
  30246. # define ENTT_MAYBE_ATOMIC(Type) Type
  30247. #endif
  30248. #ifndef ENTT_ID_TYPE
  30249. # include <cstdint>
  30250. # define ENTT_ID_TYPE std::uint32_t
  30251. #else
  30252. # include <cstdint> // provides coverage for types in the std namespace
  30253. #endif
  30254. #ifndef ENTT_SPARSE_PAGE
  30255. # define ENTT_SPARSE_PAGE 4096
  30256. #endif
  30257. #ifndef ENTT_PACKED_PAGE
  30258. # define ENTT_PACKED_PAGE 1024
  30259. #endif
  30260. #ifdef ENTT_DISABLE_ASSERT
  30261. # undef ENTT_ASSERT
  30262. # define ENTT_ASSERT(condition, msg) (void(0))
  30263. #elif !defined ENTT_ASSERT
  30264. # include <cassert>
  30265. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  30266. #endif
  30267. #ifdef ENTT_DISABLE_ASSERT
  30268. # undef ENTT_ASSERT_CONSTEXPR
  30269. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  30270. #elif !defined ENTT_ASSERT_CONSTEXPR
  30271. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  30272. #endif
  30273. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  30274. #ifdef ENTT_NO_ETO
  30275. # define ENTT_ETO_TYPE(Type) void
  30276. #else
  30277. # define ENTT_ETO_TYPE(Type) Type
  30278. #endif
  30279. #ifdef ENTT_NO_MIXIN
  30280. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  30281. #else
  30282. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  30283. #endif
  30284. #ifdef ENTT_STANDARD_CPP
  30285. # define ENTT_NONSTD false
  30286. #else
  30287. # define ENTT_NONSTD true
  30288. # if defined __clang__ || defined __GNUC__
  30289. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  30290. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  30291. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  30292. # elif defined _MSC_VER
  30293. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  30294. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  30295. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  30296. # endif
  30297. #endif
  30298. #ifndef ENTT_EXPORT
  30299. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  30300. # define ENTT_EXPORT __declspec(dllexport)
  30301. # define ENTT_IMPORT __declspec(dllimport)
  30302. # define ENTT_HIDDEN
  30303. # elif defined __GNUC__ && __GNUC__ >= 4
  30304. # define ENTT_EXPORT __attribute__((visibility("default")))
  30305. # define ENTT_IMPORT __attribute__((visibility("default")))
  30306. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  30307. # else /* Unsupported compiler */
  30308. # define ENTT_EXPORT
  30309. # define ENTT_IMPORT
  30310. # define ENTT_HIDDEN
  30311. # endif
  30312. #endif
  30313. #ifndef ENTT_API
  30314. # if defined ENTT_API_EXPORT
  30315. # define ENTT_API ENTT_EXPORT
  30316. # elif defined ENTT_API_IMPORT
  30317. # define ENTT_API ENTT_IMPORT
  30318. # else /* No API */
  30319. # define ENTT_API
  30320. # endif
  30321. #endif
  30322. #if defined _MSC_VER
  30323. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  30324. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  30325. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  30326. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  30327. #endif
  30328. // NOLINTEND(cppcoreguidelines-macro-usage)
  30329. #endif
  30330. namespace entt {
  30331. /**
  30332. * @brief Returns the number of set bits in a value (waiting for C++20 and
  30333. * `std::popcount`).
  30334. * @tparam Type Unsigned integer type.
  30335. * @param value A value of unsigned integer type.
  30336. * @return The number of set bits in the value.
  30337. */
  30338. template<typename Type>
  30339. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  30340. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  30341. }
  30342. /**
  30343. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  30344. * `std::has_single_bit`).
  30345. * @tparam Type Unsigned integer type.
  30346. * @param value A value of unsigned integer type.
  30347. * @return True if the value is a power of two, false otherwise.
  30348. */
  30349. template<typename Type>
  30350. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  30351. return value && ((value & (value - 1)) == 0);
  30352. }
  30353. /**
  30354. * @brief Computes the smallest power of two greater than or equal to a value
  30355. * (waiting for C++20 and `std::bit_ceil`).
  30356. * @tparam Type Unsigned integer type.
  30357. * @param value A value of unsigned integer type.
  30358. * @return The smallest power of two greater than or equal to the given value.
  30359. */
  30360. template<typename Type>
  30361. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  30362. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  30363. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  30364. Type curr = value - (value != 0u);
  30365. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  30366. curr |= (curr >> next);
  30367. }
  30368. return ++curr;
  30369. }
  30370. /**
  30371. * @brief Fast module utility function (powers of two only).
  30372. * @tparam Type Unsigned integer type.
  30373. * @param value A value of unsigned integer type.
  30374. * @param mod _Modulus_, it must be a power of two.
  30375. * @return The common remainder.
  30376. */
  30377. template<typename Type>
  30378. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  30379. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  30380. return static_cast<Type>(value & (mod - 1u));
  30381. }
  30382. } // namespace entt
  30383. #endif
  30384. // #include "../core/compressed_pair.hpp"
  30385. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  30386. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  30387. #include <cstddef>
  30388. #include <tuple>
  30389. #include <type_traits>
  30390. #include <utility>
  30391. // #include "fwd.hpp"
  30392. #ifndef ENTT_CORE_FWD_HPP
  30393. #define ENTT_CORE_FWD_HPP
  30394. #include <cstddef>
  30395. #include <cstdint>
  30396. // #include "../config/config.h"
  30397. namespace entt {
  30398. /*! @brief Possible modes of an any object. */
  30399. enum class any_policy : std::uint8_t {
  30400. /*! @brief Default mode, no element available. */
  30401. empty,
  30402. /*! @brief Owning mode, dynamically allocated element. */
  30403. dynamic,
  30404. /*! @brief Owning mode, embedded element. */
  30405. embedded,
  30406. /*! @brief Aliasing mode, non-const reference. */
  30407. ref,
  30408. /*! @brief Const aliasing mode, const reference. */
  30409. cref
  30410. };
  30411. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  30412. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  30413. class basic_any;
  30414. /*! @brief Alias declaration for type identifiers. */
  30415. using id_type = ENTT_ID_TYPE;
  30416. /*! @brief Alias declaration for the most common use case. */
  30417. using any = basic_any<>;
  30418. template<typename, typename>
  30419. class compressed_pair;
  30420. template<typename>
  30421. class basic_hashed_string;
  30422. /*! @brief Aliases for common character types. */
  30423. using hashed_string = basic_hashed_string<char>;
  30424. /*! @brief Aliases for common character types. */
  30425. using hashed_wstring = basic_hashed_string<wchar_t>;
  30426. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  30427. struct type_info;
  30428. } // namespace entt
  30429. #endif
  30430. // #include "type_traits.hpp"
  30431. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  30432. #define ENTT_CORE_TYPE_TRAITS_HPP
  30433. #include <cstddef>
  30434. #include <iterator>
  30435. #include <tuple>
  30436. #include <type_traits>
  30437. #include <utility>
  30438. // #include "../config/config.h"
  30439. // #include "fwd.hpp"
  30440. namespace entt {
  30441. /**
  30442. * @brief Utility class to disambiguate overloaded functions.
  30443. * @tparam N Number of choices available.
  30444. */
  30445. template<std::size_t N>
  30446. struct choice_t
  30447. // unfortunately, doxygen cannot parse such a construct
  30448. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  30449. {};
  30450. /*! @copybrief choice_t */
  30451. template<>
  30452. struct choice_t<0> {};
  30453. /**
  30454. * @brief Variable template for the choice trick.
  30455. * @tparam N Number of choices available.
  30456. */
  30457. template<std::size_t N>
  30458. inline constexpr choice_t<N> choice{};
  30459. /**
  30460. * @brief Identity type trait.
  30461. *
  30462. * Useful to establish non-deduced contexts in template argument deduction
  30463. * (waiting for C++20) or to provide types through function arguments.
  30464. *
  30465. * @tparam Type A type.
  30466. */
  30467. template<typename Type>
  30468. struct type_identity {
  30469. /*! @brief Identity type. */
  30470. using type = Type;
  30471. };
  30472. /**
  30473. * @brief Helper type.
  30474. * @tparam Type A type.
  30475. */
  30476. template<typename Type>
  30477. using type_identity_t = typename type_identity<Type>::type;
  30478. /**
  30479. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  30480. * @tparam Type The type of which to return the size.
  30481. */
  30482. template<typename Type, typename = void>
  30483. struct size_of: std::integral_constant<std::size_t, 0u> {};
  30484. /*! @copydoc size_of */
  30485. template<typename Type>
  30486. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  30487. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  30488. : std::integral_constant<std::size_t, sizeof(Type)> {};
  30489. /**
  30490. * @brief Helper variable template.
  30491. * @tparam Type The type of which to return the size.
  30492. */
  30493. template<typename Type>
  30494. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  30495. /**
  30496. * @brief Using declaration to be used to _repeat_ the same type a number of
  30497. * times equal to the size of a given parameter pack.
  30498. * @tparam Type A type to repeat.
  30499. */
  30500. template<typename Type, typename>
  30501. using unpack_as_type = Type;
  30502. /**
  30503. * @brief Helper variable template to be used to _repeat_ the same value a
  30504. * number of times equal to the size of a given parameter pack.
  30505. * @tparam Value A value to repeat.
  30506. */
  30507. template<auto Value, typename>
  30508. inline constexpr auto unpack_as_value = Value;
  30509. /**
  30510. * @brief Wraps a static constant.
  30511. * @tparam Value A static constant.
  30512. */
  30513. template<auto Value>
  30514. using integral_constant = std::integral_constant<decltype(Value), Value>;
  30515. /**
  30516. * @brief Alias template to facilitate the creation of named values.
  30517. * @tparam Value A constant value at least convertible to `id_type`.
  30518. */
  30519. template<id_type Value>
  30520. using tag = integral_constant<Value>;
  30521. /**
  30522. * @brief A class to use to push around lists of types, nothing more.
  30523. * @tparam Type Types provided by the type list.
  30524. */
  30525. template<typename... Type>
  30526. struct type_list {
  30527. /*! @brief Type list type. */
  30528. using type = type_list;
  30529. /*! @brief Compile-time number of elements in the type list. */
  30530. static constexpr auto size = sizeof...(Type);
  30531. };
  30532. /*! @brief Primary template isn't defined on purpose. */
  30533. template<std::size_t, typename>
  30534. struct type_list_element;
  30535. /**
  30536. * @brief Provides compile-time indexed access to the types of a type list.
  30537. * @tparam Index Index of the type to return.
  30538. * @tparam First First type provided by the type list.
  30539. * @tparam Other Other types provided by the type list.
  30540. */
  30541. template<std::size_t Index, typename First, typename... Other>
  30542. struct type_list_element<Index, type_list<First, Other...>>
  30543. : type_list_element<Index - 1u, type_list<Other...>> {};
  30544. /**
  30545. * @brief Provides compile-time indexed access to the types of a type list.
  30546. * @tparam First First type provided by the type list.
  30547. * @tparam Other Other types provided by the type list.
  30548. */
  30549. template<typename First, typename... Other>
  30550. struct type_list_element<0u, type_list<First, Other...>> {
  30551. /*! @brief Searched type. */
  30552. using type = First;
  30553. };
  30554. /**
  30555. * @brief Helper type.
  30556. * @tparam Index Index of the type to return.
  30557. * @tparam List Type list to search into.
  30558. */
  30559. template<std::size_t Index, typename List>
  30560. using type_list_element_t = typename type_list_element<Index, List>::type;
  30561. /*! @brief Primary template isn't defined on purpose. */
  30562. template<typename, typename>
  30563. struct type_list_index;
  30564. /**
  30565. * @brief Provides compile-time type access to the types of a type list.
  30566. * @tparam Type Type to look for and for which to return the index.
  30567. * @tparam First First type provided by the type list.
  30568. * @tparam Other Other types provided by the type list.
  30569. */
  30570. template<typename Type, typename First, typename... Other>
  30571. struct type_list_index<Type, type_list<First, Other...>> {
  30572. /*! @brief Unsigned integer type. */
  30573. using value_type = std::size_t;
  30574. /*! @brief Compile-time position of the given type in the sublist. */
  30575. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  30576. };
  30577. /**
  30578. * @brief Provides compile-time type access to the types of a type list.
  30579. * @tparam Type Type to look for and for which to return the index.
  30580. * @tparam Other Other types provided by the type list.
  30581. */
  30582. template<typename Type, typename... Other>
  30583. struct type_list_index<Type, type_list<Type, Other...>> {
  30584. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  30585. /*! @brief Unsigned integer type. */
  30586. using value_type = std::size_t;
  30587. /*! @brief Compile-time position of the given type in the sublist. */
  30588. static constexpr value_type value = 0u;
  30589. };
  30590. /**
  30591. * @brief Provides compile-time type access to the types of a type list.
  30592. * @tparam Type Type to look for and for which to return the index.
  30593. */
  30594. template<typename Type>
  30595. struct type_list_index<Type, type_list<>> {
  30596. /*! @brief Unsigned integer type. */
  30597. using value_type = std::size_t;
  30598. /*! @brief Compile-time position of the given type in the sublist. */
  30599. static constexpr value_type value = 0u;
  30600. };
  30601. /**
  30602. * @brief Helper variable template.
  30603. * @tparam List Type list.
  30604. * @tparam Type Type to look for and for which to return the index.
  30605. */
  30606. template<typename Type, typename List>
  30607. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  30608. /**
  30609. * @brief Concatenates multiple type lists.
  30610. * @tparam Type Types provided by the first type list.
  30611. * @tparam Other Types provided by the second type list.
  30612. * @return A type list composed by the types of both the type lists.
  30613. */
  30614. template<typename... Type, typename... Other>
  30615. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  30616. return {};
  30617. }
  30618. /*! @brief Primary template isn't defined on purpose. */
  30619. template<typename...>
  30620. struct type_list_cat;
  30621. /*! @brief Concatenates multiple type lists. */
  30622. template<>
  30623. struct type_list_cat<> {
  30624. /*! @brief A type list composed by the types of all the type lists. */
  30625. using type = type_list<>;
  30626. };
  30627. /**
  30628. * @brief Concatenates multiple type lists.
  30629. * @tparam Type Types provided by the first type list.
  30630. * @tparam Other Types provided by the second type list.
  30631. * @tparam List Other type lists, if any.
  30632. */
  30633. template<typename... Type, typename... Other, typename... List>
  30634. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  30635. /*! @brief A type list composed by the types of all the type lists. */
  30636. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  30637. };
  30638. /**
  30639. * @brief Concatenates multiple type lists.
  30640. * @tparam Type Types provided by the type list.
  30641. */
  30642. template<typename... Type>
  30643. struct type_list_cat<type_list<Type...>> {
  30644. /*! @brief A type list composed by the types of all the type lists. */
  30645. using type = type_list<Type...>;
  30646. };
  30647. /**
  30648. * @brief Helper type.
  30649. * @tparam List Type lists to concatenate.
  30650. */
  30651. template<typename... List>
  30652. using type_list_cat_t = typename type_list_cat<List...>::type;
  30653. /*! @cond TURN_OFF_DOXYGEN */
  30654. namespace internal {
  30655. template<typename...>
  30656. struct type_list_unique;
  30657. template<typename First, typename... Other, typename... Type>
  30658. struct type_list_unique<type_list<First, Other...>, Type...>
  30659. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  30660. template<typename... Type>
  30661. struct type_list_unique<type_list<>, Type...> {
  30662. using type = type_list<Type...>;
  30663. };
  30664. } // namespace internal
  30665. /*! @endcond */
  30666. /**
  30667. * @brief Removes duplicates types from a type list.
  30668. * @tparam List Type list.
  30669. */
  30670. template<typename List>
  30671. struct type_list_unique {
  30672. /*! @brief A type list without duplicate types. */
  30673. using type = typename internal::type_list_unique<List>::type;
  30674. };
  30675. /**
  30676. * @brief Helper type.
  30677. * @tparam List Type list.
  30678. */
  30679. template<typename List>
  30680. using type_list_unique_t = typename type_list_unique<List>::type;
  30681. /**
  30682. * @brief Provides the member constant `value` to true if a type list contains a
  30683. * given type, false otherwise.
  30684. * @tparam List Type list.
  30685. * @tparam Type Type to look for.
  30686. */
  30687. template<typename List, typename Type>
  30688. struct type_list_contains;
  30689. /**
  30690. * @copybrief type_list_contains
  30691. * @tparam Type Types provided by the type list.
  30692. * @tparam Other Type to look for.
  30693. */
  30694. template<typename... Type, typename Other>
  30695. struct type_list_contains<type_list<Type...>, Other>
  30696. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  30697. /**
  30698. * @brief Helper variable template.
  30699. * @tparam List Type list.
  30700. * @tparam Type Type to look for.
  30701. */
  30702. template<typename List, typename Type>
  30703. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  30704. /*! @brief Primary template isn't defined on purpose. */
  30705. template<typename...>
  30706. struct type_list_diff;
  30707. /**
  30708. * @brief Computes the difference between two type lists.
  30709. * @tparam Type Types provided by the first type list.
  30710. * @tparam Other Types provided by the second type list.
  30711. */
  30712. template<typename... Type, typename... Other>
  30713. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  30714. /*! @brief A type list that is the difference between the two type lists. */
  30715. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  30716. };
  30717. /**
  30718. * @brief Helper type.
  30719. * @tparam List Type lists between which to compute the difference.
  30720. */
  30721. template<typename... List>
  30722. using type_list_diff_t = typename type_list_diff<List...>::type;
  30723. /*! @brief Primary template isn't defined on purpose. */
  30724. template<typename, template<typename...> class>
  30725. struct type_list_transform;
  30726. /**
  30727. * @brief Applies a given _function_ to a type list and generate a new list.
  30728. * @tparam Type Types provided by the type list.
  30729. * @tparam Op Unary operation as template class with a type member named `type`.
  30730. */
  30731. template<typename... Type, template<typename...> class Op>
  30732. struct type_list_transform<type_list<Type...>, Op> {
  30733. /*! @brief Resulting type list after applying the transform function. */
  30734. // NOLINTNEXTLINE(modernize-type-traits)
  30735. using type = type_list<typename Op<Type>::type...>;
  30736. };
  30737. /**
  30738. * @brief Helper type.
  30739. * @tparam List Type list.
  30740. * @tparam Op Unary operation as template class with a type member named `type`.
  30741. */
  30742. template<typename List, template<typename...> class Op>
  30743. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  30744. /**
  30745. * @brief A class to use to push around lists of constant values, nothing more.
  30746. * @tparam Value Values provided by the value list.
  30747. */
  30748. template<auto... Value>
  30749. struct value_list {
  30750. /*! @brief Value list type. */
  30751. using type = value_list;
  30752. /*! @brief Compile-time number of elements in the value list. */
  30753. static constexpr auto size = sizeof...(Value);
  30754. };
  30755. /*! @brief Primary template isn't defined on purpose. */
  30756. template<std::size_t, typename>
  30757. struct value_list_element;
  30758. /**
  30759. * @brief Provides compile-time indexed access to the values of a value list.
  30760. * @tparam Index Index of the value to return.
  30761. * @tparam Value First value provided by the value list.
  30762. * @tparam Other Other values provided by the value list.
  30763. */
  30764. template<std::size_t Index, auto Value, auto... Other>
  30765. struct value_list_element<Index, value_list<Value, Other...>>
  30766. : value_list_element<Index - 1u, value_list<Other...>> {};
  30767. /**
  30768. * @brief Provides compile-time indexed access to the types of a type list.
  30769. * @tparam Value First value provided by the value list.
  30770. * @tparam Other Other values provided by the value list.
  30771. */
  30772. template<auto Value, auto... Other>
  30773. struct value_list_element<0u, value_list<Value, Other...>> {
  30774. /*! @brief Searched type. */
  30775. using type = decltype(Value);
  30776. /*! @brief Searched value. */
  30777. static constexpr auto value = Value;
  30778. };
  30779. /**
  30780. * @brief Helper type.
  30781. * @tparam Index Index of the type to return.
  30782. * @tparam List Value list to search into.
  30783. */
  30784. template<std::size_t Index, typename List>
  30785. using value_list_element_t = typename value_list_element<Index, List>::type;
  30786. /**
  30787. * @brief Helper type.
  30788. * @tparam Index Index of the value to return.
  30789. * @tparam List Value list to search into.
  30790. */
  30791. template<std::size_t Index, typename List>
  30792. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  30793. /*! @brief Primary template isn't defined on purpose. */
  30794. template<auto, typename>
  30795. struct value_list_index;
  30796. /**
  30797. * @brief Provides compile-time type access to the values of a value list.
  30798. * @tparam Value Value to look for and for which to return the index.
  30799. * @tparam First First value provided by the value list.
  30800. * @tparam Other Other values provided by the value list.
  30801. */
  30802. template<auto Value, auto First, auto... Other>
  30803. struct value_list_index<Value, value_list<First, Other...>> {
  30804. /*! @brief Unsigned integer type. */
  30805. using value_type = std::size_t;
  30806. /*! @brief Compile-time position of the given value in the sublist. */
  30807. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  30808. };
  30809. /**
  30810. * @brief Provides compile-time type access to the values of a value list.
  30811. * @tparam Value Value to look for and for which to return the index.
  30812. * @tparam Other Other values provided by the value list.
  30813. */
  30814. template<auto Value, auto... Other>
  30815. struct value_list_index<Value, value_list<Value, Other...>> {
  30816. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  30817. /*! @brief Unsigned integer type. */
  30818. using value_type = std::size_t;
  30819. /*! @brief Compile-time position of the given value in the sublist. */
  30820. static constexpr value_type value = 0u;
  30821. };
  30822. /**
  30823. * @brief Provides compile-time type access to the values of a value list.
  30824. * @tparam Value Value to look for and for which to return the index.
  30825. */
  30826. template<auto Value>
  30827. struct value_list_index<Value, value_list<>> {
  30828. /*! @brief Unsigned integer type. */
  30829. using value_type = std::size_t;
  30830. /*! @brief Compile-time position of the given type in the sublist. */
  30831. static constexpr value_type value = 0u;
  30832. };
  30833. /**
  30834. * @brief Helper variable template.
  30835. * @tparam List Value list.
  30836. * @tparam Value Value to look for and for which to return the index.
  30837. */
  30838. template<auto Value, typename List>
  30839. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  30840. /**
  30841. * @brief Concatenates multiple value lists.
  30842. * @tparam Value Values provided by the first value list.
  30843. * @tparam Other Values provided by the second value list.
  30844. * @return A value list composed by the values of both the value lists.
  30845. */
  30846. template<auto... Value, auto... Other>
  30847. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  30848. return {};
  30849. }
  30850. /*! @brief Primary template isn't defined on purpose. */
  30851. template<typename...>
  30852. struct value_list_cat;
  30853. /*! @brief Concatenates multiple value lists. */
  30854. template<>
  30855. struct value_list_cat<> {
  30856. /*! @brief A value list composed by the values of all the value lists. */
  30857. using type = value_list<>;
  30858. };
  30859. /**
  30860. * @brief Concatenates multiple value lists.
  30861. * @tparam Value Values provided by the first value list.
  30862. * @tparam Other Values provided by the second value list.
  30863. * @tparam List Other value lists, if any.
  30864. */
  30865. template<auto... Value, auto... Other, typename... List>
  30866. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  30867. /*! @brief A value list composed by the values of all the value lists. */
  30868. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  30869. };
  30870. /**
  30871. * @brief Concatenates multiple value lists.
  30872. * @tparam Value Values provided by the value list.
  30873. */
  30874. template<auto... Value>
  30875. struct value_list_cat<value_list<Value...>> {
  30876. /*! @brief A value list composed by the values of all the value lists. */
  30877. using type = value_list<Value...>;
  30878. };
  30879. /**
  30880. * @brief Helper type.
  30881. * @tparam List Value lists to concatenate.
  30882. */
  30883. template<typename... List>
  30884. using value_list_cat_t = typename value_list_cat<List...>::type;
  30885. /*! @brief Primary template isn't defined on purpose. */
  30886. template<typename>
  30887. struct value_list_unique;
  30888. /**
  30889. * @brief Removes duplicates values from a value list.
  30890. * @tparam Value One of the values provided by the given value list.
  30891. * @tparam Other The other values provided by the given value list.
  30892. */
  30893. template<auto Value, auto... Other>
  30894. struct value_list_unique<value_list<Value, Other...>> {
  30895. /*! @brief A value list without duplicate types. */
  30896. using type = std::conditional_t<
  30897. ((Value == Other) || ...),
  30898. typename value_list_unique<value_list<Other...>>::type,
  30899. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  30900. };
  30901. /*! @brief Removes duplicates values from a value list. */
  30902. template<>
  30903. struct value_list_unique<value_list<>> {
  30904. /*! @brief A value list without duplicate types. */
  30905. using type = value_list<>;
  30906. };
  30907. /**
  30908. * @brief Helper type.
  30909. * @tparam Type A value list.
  30910. */
  30911. template<typename Type>
  30912. using value_list_unique_t = typename value_list_unique<Type>::type;
  30913. /**
  30914. * @brief Provides the member constant `value` to true if a value list contains
  30915. * a given value, false otherwise.
  30916. * @tparam List Value list.
  30917. * @tparam Value Value to look for.
  30918. */
  30919. template<typename List, auto Value>
  30920. struct value_list_contains;
  30921. /**
  30922. * @copybrief value_list_contains
  30923. * @tparam Value Values provided by the value list.
  30924. * @tparam Other Value to look for.
  30925. */
  30926. template<auto... Value, auto Other>
  30927. struct value_list_contains<value_list<Value...>, Other>
  30928. : std::bool_constant<((Value == Other) || ...)> {};
  30929. /**
  30930. * @brief Helper variable template.
  30931. * @tparam List Value list.
  30932. * @tparam Value Value to look for.
  30933. */
  30934. template<typename List, auto Value>
  30935. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  30936. /*! @brief Primary template isn't defined on purpose. */
  30937. template<typename...>
  30938. struct value_list_diff;
  30939. /**
  30940. * @brief Computes the difference between two value lists.
  30941. * @tparam Value Values provided by the first value list.
  30942. * @tparam Other Values provided by the second value list.
  30943. */
  30944. template<auto... Value, auto... Other>
  30945. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  30946. /*! @brief A value list that is the difference between the two value lists. */
  30947. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  30948. };
  30949. /**
  30950. * @brief Helper type.
  30951. * @tparam List Value lists between which to compute the difference.
  30952. */
  30953. template<typename... List>
  30954. using value_list_diff_t = typename value_list_diff<List...>::type;
  30955. /*! @brief Same as std::is_invocable, but with tuples. */
  30956. template<typename, typename>
  30957. struct is_applicable: std::false_type {};
  30958. /**
  30959. * @copybrief is_applicable
  30960. * @tparam Func A valid function type.
  30961. * @tparam Tuple Tuple-like type.
  30962. * @tparam Args The list of arguments to use to probe the function type.
  30963. */
  30964. template<typename Func, template<typename...> class Tuple, typename... Args>
  30965. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  30966. /**
  30967. * @copybrief is_applicable
  30968. * @tparam Func A valid function type.
  30969. * @tparam Tuple Tuple-like type.
  30970. * @tparam Args The list of arguments to use to probe the function type.
  30971. */
  30972. template<typename Func, template<typename...> class Tuple, typename... Args>
  30973. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  30974. /**
  30975. * @brief Helper variable template.
  30976. * @tparam Func A valid function type.
  30977. * @tparam Args The list of arguments to use to probe the function type.
  30978. */
  30979. template<typename Func, typename Args>
  30980. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  30981. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  30982. template<typename, typename, typename>
  30983. struct is_applicable_r: std::false_type {};
  30984. /**
  30985. * @copybrief is_applicable_r
  30986. * @tparam Ret The type to which the return type of the function should be
  30987. * convertible.
  30988. * @tparam Func A valid function type.
  30989. * @tparam Args The list of arguments to use to probe the function type.
  30990. */
  30991. template<typename Ret, typename Func, typename... Args>
  30992. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  30993. /**
  30994. * @brief Helper variable template.
  30995. * @tparam Ret The type to which the return type of the function should be
  30996. * convertible.
  30997. * @tparam Func A valid function type.
  30998. * @tparam Args The list of arguments to use to probe the function type.
  30999. */
  31000. template<typename Ret, typename Func, typename Args>
  31001. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  31002. /**
  31003. * @brief Provides the member constant `value` to true if a given type is
  31004. * complete, false otherwise.
  31005. * @tparam Type The type to test.
  31006. */
  31007. template<typename Type, typename = void>
  31008. struct is_complete: std::false_type {};
  31009. /*! @copydoc is_complete */
  31010. template<typename Type>
  31011. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  31012. /**
  31013. * @brief Helper variable template.
  31014. * @tparam Type The type to test.
  31015. */
  31016. template<typename Type>
  31017. inline constexpr bool is_complete_v = is_complete<Type>::value;
  31018. /**
  31019. * @brief Provides the member constant `value` to true if a given type is an
  31020. * iterator, false otherwise.
  31021. * @tparam Type The type to test.
  31022. */
  31023. template<typename Type, typename = void>
  31024. struct is_iterator: std::false_type {};
  31025. /*! @cond TURN_OFF_DOXYGEN */
  31026. namespace internal {
  31027. template<typename, typename = void>
  31028. struct has_iterator_category: std::false_type {};
  31029. template<typename Type>
  31030. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  31031. } // namespace internal
  31032. /*! @endcond */
  31033. /*! @copydoc is_iterator */
  31034. template<typename Type>
  31035. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  31036. : internal::has_iterator_category<Type> {};
  31037. /**
  31038. * @brief Helper variable template.
  31039. * @tparam Type The type to test.
  31040. */
  31041. template<typename Type>
  31042. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  31043. /**
  31044. * @brief Provides the member constant `value` to true if a given type is both
  31045. * an empty and non-final class, false otherwise.
  31046. * @tparam Type The type to test
  31047. */
  31048. template<typename Type>
  31049. struct is_ebco_eligible
  31050. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  31051. /**
  31052. * @brief Helper variable template.
  31053. * @tparam Type The type to test.
  31054. */
  31055. template<typename Type>
  31056. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  31057. /**
  31058. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  31059. * is valid and denotes a type, false otherwise.
  31060. * @tparam Type The type to test.
  31061. */
  31062. template<typename Type, typename = void>
  31063. struct is_transparent: std::false_type {};
  31064. /*! @copydoc is_transparent */
  31065. template<typename Type>
  31066. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  31067. /**
  31068. * @brief Helper variable template.
  31069. * @tparam Type The type to test.
  31070. */
  31071. template<typename Type>
  31072. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  31073. /*! @cond TURN_OFF_DOXYGEN */
  31074. namespace internal {
  31075. template<typename, typename = void>
  31076. struct has_tuple_size_value: std::false_type {};
  31077. template<typename Type>
  31078. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  31079. template<typename, typename = void>
  31080. struct has_value_type: std::false_type {};
  31081. template<typename Type>
  31082. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  31083. template<typename>
  31084. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  31085. template<typename Type, std::size_t... Index>
  31086. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  31087. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  31088. }
  31089. template<typename>
  31090. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  31091. return false;
  31092. }
  31093. template<typename Type>
  31094. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  31095. return true;
  31096. }
  31097. template<typename Type>
  31098. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  31099. // NOLINTBEGIN(modernize-use-transparent-functors)
  31100. if constexpr(std::is_array_v<Type>) {
  31101. return false;
  31102. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  31103. if constexpr(has_tuple_size_value<Type>::value) {
  31104. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  31105. } else {
  31106. return maybe_equality_comparable<Type>(0);
  31107. }
  31108. } else if constexpr(has_value_type<Type>::value) {
  31109. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  31110. return maybe_equality_comparable<Type>(0);
  31111. } else {
  31112. return false;
  31113. }
  31114. } else {
  31115. return maybe_equality_comparable<Type>(0);
  31116. }
  31117. // NOLINTEND(modernize-use-transparent-functors)
  31118. }
  31119. } // namespace internal
  31120. /*! @endcond */
  31121. /**
  31122. * @brief Provides the member constant `value` to true if a given type is
  31123. * equality comparable, false otherwise.
  31124. * @tparam Type The type to test.
  31125. */
  31126. template<typename Type>
  31127. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  31128. /*! @copydoc is_equality_comparable */
  31129. template<typename Type>
  31130. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  31131. /**
  31132. * @brief Helper variable template.
  31133. * @tparam Type The type to test.
  31134. */
  31135. template<typename Type>
  31136. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  31137. /**
  31138. * @brief Transcribes the constness of a type to another type.
  31139. * @tparam To The type to which to transcribe the constness.
  31140. * @tparam From The type from which to transcribe the constness.
  31141. */
  31142. template<typename To, typename From>
  31143. struct constness_as {
  31144. /*! @brief The type resulting from the transcription of the constness. */
  31145. using type = std::remove_const_t<To>;
  31146. };
  31147. /*! @copydoc constness_as */
  31148. template<typename To, typename From>
  31149. struct constness_as<To, const From> {
  31150. /*! @brief The type resulting from the transcription of the constness. */
  31151. using type = const To;
  31152. };
  31153. /**
  31154. * @brief Alias template to facilitate the transcription of the constness.
  31155. * @tparam To The type to which to transcribe the constness.
  31156. * @tparam From The type from which to transcribe the constness.
  31157. */
  31158. template<typename To, typename From>
  31159. using constness_as_t = typename constness_as<To, From>::type;
  31160. /**
  31161. * @brief Extracts the class of a non-static member object or function.
  31162. * @tparam Member A pointer to a non-static member object or function.
  31163. */
  31164. template<typename Member>
  31165. class member_class {
  31166. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  31167. template<typename Class, typename Ret, typename... Args>
  31168. static Class *clazz(Ret (Class::*)(Args...));
  31169. template<typename Class, typename Ret, typename... Args>
  31170. static Class *clazz(Ret (Class::*)(Args...) const);
  31171. template<typename Class, typename Type>
  31172. static Class *clazz(Type Class::*);
  31173. public:
  31174. /*! @brief The class of the given non-static member object or function. */
  31175. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  31176. };
  31177. /**
  31178. * @brief Helper type.
  31179. * @tparam Member A pointer to a non-static member object or function.
  31180. */
  31181. template<typename Member>
  31182. using member_class_t = typename member_class<Member>::type;
  31183. /**
  31184. * @brief Extracts the n-th argument of a _callable_ type.
  31185. * @tparam Index The index of the argument to extract.
  31186. * @tparam Candidate A valid _callable_ type.
  31187. */
  31188. template<std::size_t Index, typename Candidate>
  31189. class nth_argument {
  31190. template<typename Ret, typename... Args>
  31191. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  31192. template<typename Ret, typename Class, typename... Args>
  31193. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  31194. template<typename Ret, typename Class, typename... Args>
  31195. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  31196. template<typename Type, typename Class>
  31197. static constexpr type_list<Type> pick_up(Type Class ::*);
  31198. template<typename Type>
  31199. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  31200. public:
  31201. /*! @brief N-th argument of the _callable_ type. */
  31202. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  31203. };
  31204. /**
  31205. * @brief Helper type.
  31206. * @tparam Index The index of the argument to extract.
  31207. * @tparam Candidate A valid function, member function or data member type.
  31208. */
  31209. template<std::size_t Index, typename Candidate>
  31210. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  31211. } // namespace entt
  31212. template<typename... Type>
  31213. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  31214. template<std::size_t Index, typename... Type>
  31215. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  31216. template<auto... Value>
  31217. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  31218. template<std::size_t Index, auto... Value>
  31219. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  31220. #endif
  31221. namespace entt {
  31222. /*! @cond TURN_OFF_DOXYGEN */
  31223. namespace internal {
  31224. template<typename Type, std::size_t, typename = void>
  31225. struct compressed_pair_element {
  31226. using reference = Type &;
  31227. using const_reference = const Type &;
  31228. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  31229. // NOLINTNEXTLINE(modernize-use-equals-default)
  31230. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  31231. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  31232. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  31233. : value{std::forward<Arg>(arg)} {}
  31234. template<typename... Args, std::size_t... Index>
  31235. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  31236. : value{std::forward<Args>(std::get<Index>(args))...} {}
  31237. [[nodiscard]] constexpr reference get() noexcept {
  31238. return value;
  31239. }
  31240. [[nodiscard]] constexpr const_reference get() const noexcept {
  31241. return value;
  31242. }
  31243. private:
  31244. Type value{};
  31245. };
  31246. template<typename Type, std::size_t Tag>
  31247. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  31248. using reference = Type &;
  31249. using const_reference = const Type &;
  31250. using base_type = Type;
  31251. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  31252. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  31253. : base_type{} {}
  31254. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  31255. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  31256. : base_type{std::forward<Arg>(arg)} {}
  31257. template<typename... Args, std::size_t... Index>
  31258. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  31259. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  31260. [[nodiscard]] constexpr reference get() noexcept {
  31261. return *this;
  31262. }
  31263. [[nodiscard]] constexpr const_reference get() const noexcept {
  31264. return *this;
  31265. }
  31266. };
  31267. } // namespace internal
  31268. /*! @endcond */
  31269. /**
  31270. * @brief A compressed pair.
  31271. *
  31272. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  31273. * reduce its final size to a minimum.
  31274. *
  31275. * @tparam First The type of the first element that the pair stores.
  31276. * @tparam Second The type of the second element that the pair stores.
  31277. */
  31278. template<typename First, typename Second>
  31279. class compressed_pair final
  31280. : internal::compressed_pair_element<First, 0u>,
  31281. internal::compressed_pair_element<Second, 1u> {
  31282. using first_base = internal::compressed_pair_element<First, 0u>;
  31283. using second_base = internal::compressed_pair_element<Second, 1u>;
  31284. public:
  31285. /*! @brief The type of the first element that the pair stores. */
  31286. using first_type = First;
  31287. /*! @brief The type of the second element that the pair stores. */
  31288. using second_type = Second;
  31289. /**
  31290. * @brief Default constructor, conditionally enabled.
  31291. *
  31292. * This constructor is only available when the types that the pair stores
  31293. * are both at least default constructible.
  31294. *
  31295. * @tparam Dummy Dummy template parameter used for internal purposes.
  31296. */
  31297. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  31298. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  31299. : first_base{},
  31300. second_base{} {}
  31301. /**
  31302. * @brief Copy constructor.
  31303. * @param other The instance to copy from.
  31304. */
  31305. constexpr compressed_pair(const compressed_pair &other) = default;
  31306. /**
  31307. * @brief Move constructor.
  31308. * @param other The instance to move from.
  31309. */
  31310. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  31311. /**
  31312. * @brief Constructs a pair from its values.
  31313. * @tparam Arg Type of value to use to initialize the first element.
  31314. * @tparam Other Type of value to use to initialize the second element.
  31315. * @param arg Value to use to initialize the first element.
  31316. * @param other Value to use to initialize the second element.
  31317. */
  31318. template<typename Arg, typename Other>
  31319. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  31320. : first_base{std::forward<Arg>(arg)},
  31321. second_base{std::forward<Other>(other)} {}
  31322. /**
  31323. * @brief Constructs a pair by forwarding the arguments to its parts.
  31324. * @tparam Args Types of arguments to use to initialize the first element.
  31325. * @tparam Other Types of arguments to use to initialize the second element.
  31326. * @param args Arguments to use to initialize the first element.
  31327. * @param other Arguments to use to initialize the second element.
  31328. */
  31329. template<typename... Args, typename... Other>
  31330. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  31331. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  31332. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  31333. /*! @brief Default destructor. */
  31334. ~compressed_pair() = default;
  31335. /**
  31336. * @brief Copy assignment operator.
  31337. * @param other The instance to copy from.
  31338. * @return This compressed pair object.
  31339. */
  31340. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  31341. /**
  31342. * @brief Move assignment operator.
  31343. * @param other The instance to move from.
  31344. * @return This compressed pair object.
  31345. */
  31346. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  31347. /**
  31348. * @brief Returns the first element that a pair stores.
  31349. * @return The first element that a pair stores.
  31350. */
  31351. [[nodiscard]] constexpr first_type &first() noexcept {
  31352. return static_cast<first_base &>(*this).get();
  31353. }
  31354. /*! @copydoc first */
  31355. [[nodiscard]] constexpr const first_type &first() const noexcept {
  31356. return static_cast<const first_base &>(*this).get();
  31357. }
  31358. /**
  31359. * @brief Returns the second element that a pair stores.
  31360. * @return The second element that a pair stores.
  31361. */
  31362. [[nodiscard]] constexpr second_type &second() noexcept {
  31363. return static_cast<second_base &>(*this).get();
  31364. }
  31365. /*! @copydoc second */
  31366. [[nodiscard]] constexpr const second_type &second() const noexcept {
  31367. return static_cast<const second_base &>(*this).get();
  31368. }
  31369. /**
  31370. * @brief Swaps two compressed pair objects.
  31371. * @param other The compressed pair to swap with.
  31372. */
  31373. constexpr void swap(compressed_pair &other) noexcept {
  31374. using std::swap;
  31375. swap(first(), other.first());
  31376. swap(second(), other.second());
  31377. }
  31378. /**
  31379. * @brief Extracts an element from the compressed pair.
  31380. * @tparam Index An integer value that is either 0 or 1.
  31381. * @return Returns a reference to the first element if `Index` is 0 and a
  31382. * reference to the second element if `Index` is 1.
  31383. */
  31384. template<std::size_t Index>
  31385. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  31386. if constexpr(Index == 0u) {
  31387. return first();
  31388. } else {
  31389. static_assert(Index == 1u, "Index out of bounds");
  31390. return second();
  31391. }
  31392. }
  31393. /*! @copydoc get */
  31394. template<std::size_t Index>
  31395. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  31396. if constexpr(Index == 0u) {
  31397. return first();
  31398. } else {
  31399. static_assert(Index == 1u, "Index out of bounds");
  31400. return second();
  31401. }
  31402. }
  31403. };
  31404. /**
  31405. * @brief Deduction guide.
  31406. * @tparam Type Type of value to use to initialize the first element.
  31407. * @tparam Other Type of value to use to initialize the second element.
  31408. */
  31409. template<typename Type, typename Other>
  31410. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  31411. /**
  31412. * @brief Swaps two compressed pair objects.
  31413. * @tparam First The type of the first element that the pairs store.
  31414. * @tparam Second The type of the second element that the pairs store.
  31415. * @param lhs A valid compressed pair object.
  31416. * @param rhs A valid compressed pair object.
  31417. */
  31418. template<typename First, typename Second>
  31419. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  31420. lhs.swap(rhs);
  31421. }
  31422. } // namespace entt
  31423. namespace std {
  31424. /**
  31425. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  31426. * @tparam First The type of the first element that the pair stores.
  31427. * @tparam Second The type of the second element that the pair stores.
  31428. */
  31429. template<typename First, typename Second>
  31430. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  31431. /**
  31432. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  31433. * @tparam Index The index of the type to return.
  31434. * @tparam First The type of the first element that the pair stores.
  31435. * @tparam Second The type of the second element that the pair stores.
  31436. */
  31437. template<size_t Index, typename First, typename Second>
  31438. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  31439. static_assert(Index < 2u, "Index out of bounds");
  31440. };
  31441. } // namespace std
  31442. #endif
  31443. // #include "../core/iterator.hpp"
  31444. #ifndef ENTT_CORE_ITERATOR_HPP
  31445. #define ENTT_CORE_ITERATOR_HPP
  31446. #include <iterator>
  31447. #include <memory>
  31448. #include <type_traits>
  31449. #include <utility>
  31450. namespace entt {
  31451. /**
  31452. * @brief Helper type to use as pointer with input iterators.
  31453. * @tparam Type of wrapped value.
  31454. */
  31455. template<typename Type>
  31456. struct input_iterator_pointer final {
  31457. /*! @brief Value type. */
  31458. using value_type = Type;
  31459. /*! @brief Pointer type. */
  31460. using pointer = Type *;
  31461. /*! @brief Reference type. */
  31462. using reference = Type &;
  31463. /**
  31464. * @brief Constructs a proxy object by move.
  31465. * @param val Value to use to initialize the proxy object.
  31466. */
  31467. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  31468. : value{std::move(val)} {}
  31469. /**
  31470. * @brief Access operator for accessing wrapped values.
  31471. * @return A pointer to the wrapped value.
  31472. */
  31473. [[nodiscard]] constexpr pointer operator->() noexcept {
  31474. return std::addressof(value);
  31475. }
  31476. /**
  31477. * @brief Dereference operator for accessing wrapped values.
  31478. * @return A reference to the wrapped value.
  31479. */
  31480. [[nodiscard]] constexpr reference operator*() noexcept {
  31481. return value;
  31482. }
  31483. private:
  31484. Type value;
  31485. };
  31486. /**
  31487. * @brief Plain iota iterator (waiting for C++20).
  31488. * @tparam Type Value type.
  31489. */
  31490. template<typename Type>
  31491. class iota_iterator final {
  31492. static_assert(std::is_integral_v<Type>, "Not an integral type");
  31493. public:
  31494. /*! @brief Value type, likely an integral one. */
  31495. using value_type = Type;
  31496. /*! @brief Invalid pointer type. */
  31497. using pointer = void;
  31498. /*! @brief Non-reference type, same as value type. */
  31499. using reference = value_type;
  31500. /*! @brief Difference type. */
  31501. using difference_type = std::ptrdiff_t;
  31502. /*! @brief Iterator category. */
  31503. using iterator_category = std::input_iterator_tag;
  31504. /*! @brief Default constructor. */
  31505. constexpr iota_iterator() noexcept
  31506. : current{} {}
  31507. /**
  31508. * @brief Constructs an iota iterator from a given value.
  31509. * @param init The initial value assigned to the iota iterator.
  31510. */
  31511. constexpr iota_iterator(const value_type init) noexcept
  31512. : current{init} {}
  31513. /**
  31514. * @brief Pre-increment operator.
  31515. * @return This iota iterator.
  31516. */
  31517. constexpr iota_iterator &operator++() noexcept {
  31518. return ++current, *this;
  31519. }
  31520. /**
  31521. * @brief Post-increment operator.
  31522. * @return This iota iterator.
  31523. */
  31524. constexpr iota_iterator operator++(int) noexcept {
  31525. const iota_iterator orig = *this;
  31526. return ++(*this), orig;
  31527. }
  31528. /**
  31529. * @brief Dereference operator.
  31530. * @return The underlying value.
  31531. */
  31532. [[nodiscard]] constexpr reference operator*() const noexcept {
  31533. return current;
  31534. }
  31535. private:
  31536. value_type current;
  31537. };
  31538. /**
  31539. * @brief Comparison operator.
  31540. * @tparam Type Value type of the iota iterator.
  31541. * @param lhs A properly initialized iota iterator.
  31542. * @param rhs A properly initialized iota iterator.
  31543. * @return True if the two iterators are identical, false otherwise.
  31544. */
  31545. template<typename Type>
  31546. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  31547. return *lhs == *rhs;
  31548. }
  31549. /**
  31550. * @brief Comparison operator.
  31551. * @tparam Type Value type of the iota iterator.
  31552. * @param lhs A properly initialized iota iterator.
  31553. * @param rhs A properly initialized iota iterator.
  31554. * @return True if the two iterators differ, false otherwise.
  31555. */
  31556. template<typename Type>
  31557. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  31558. return !(lhs == rhs);
  31559. }
  31560. /**
  31561. * @brief Utility class to create an iterable object from a pair of iterators.
  31562. * @tparam It Type of iterator.
  31563. * @tparam Sentinel Type of sentinel.
  31564. */
  31565. template<typename It, typename Sentinel = It>
  31566. struct iterable_adaptor final {
  31567. /*! @brief Value type. */
  31568. using value_type = typename std::iterator_traits<It>::value_type;
  31569. /*! @brief Iterator type. */
  31570. using iterator = It;
  31571. /*! @brief Sentinel type. */
  31572. using sentinel = Sentinel;
  31573. /*! @brief Default constructor. */
  31574. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  31575. : first{},
  31576. last{} {}
  31577. /**
  31578. * @brief Creates an iterable object from a pair of iterators.
  31579. * @param from Begin iterator.
  31580. * @param to End iterator.
  31581. */
  31582. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  31583. : first{std::move(from)},
  31584. last{std::move(to)} {}
  31585. /**
  31586. * @brief Returns an iterator to the beginning.
  31587. * @return An iterator to the first element of the range.
  31588. */
  31589. [[nodiscard]] constexpr iterator begin() const noexcept {
  31590. return first;
  31591. }
  31592. /**
  31593. * @brief Returns an iterator to the end.
  31594. * @return An iterator to the element following the last element of the
  31595. * range.
  31596. */
  31597. [[nodiscard]] constexpr sentinel end() const noexcept {
  31598. return last;
  31599. }
  31600. /*! @copydoc begin */
  31601. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  31602. return begin();
  31603. }
  31604. /*! @copydoc end */
  31605. [[nodiscard]] constexpr sentinel cend() const noexcept {
  31606. return end();
  31607. }
  31608. private:
  31609. It first;
  31610. Sentinel last;
  31611. };
  31612. } // namespace entt
  31613. #endif
  31614. // #include "../core/memory.hpp"
  31615. #ifndef ENTT_CORE_MEMORY_HPP
  31616. #define ENTT_CORE_MEMORY_HPP
  31617. #include <cstddef>
  31618. #include <memory>
  31619. #include <tuple>
  31620. #include <type_traits>
  31621. #include <utility>
  31622. // #include "../config/config.h"
  31623. namespace entt {
  31624. /**
  31625. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  31626. * @tparam Type Pointer type.
  31627. * @param ptr Fancy or raw pointer.
  31628. * @return A raw pointer that represents the address of the original pointer.
  31629. */
  31630. template<typename Type>
  31631. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  31632. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  31633. return ptr;
  31634. } else {
  31635. return to_address(std::forward<Type>(ptr).operator->());
  31636. }
  31637. }
  31638. /**
  31639. * @brief Utility function to design allocation-aware containers.
  31640. * @tparam Allocator Type of allocator.
  31641. * @param lhs A valid allocator.
  31642. * @param rhs Another valid allocator.
  31643. */
  31644. template<typename Allocator>
  31645. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  31646. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  31647. lhs = rhs;
  31648. }
  31649. }
  31650. /**
  31651. * @brief Utility function to design allocation-aware containers.
  31652. * @tparam Allocator Type of allocator.
  31653. * @param lhs A valid allocator.
  31654. * @param rhs Another valid allocator.
  31655. */
  31656. template<typename Allocator>
  31657. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  31658. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  31659. lhs = std::move(rhs);
  31660. }
  31661. }
  31662. /**
  31663. * @brief Utility function to design allocation-aware containers.
  31664. * @tparam Allocator Type of allocator.
  31665. * @param lhs A valid allocator.
  31666. * @param rhs Another valid allocator.
  31667. */
  31668. template<typename Allocator>
  31669. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  31670. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  31671. using std::swap;
  31672. swap(lhs, rhs);
  31673. } else {
  31674. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  31675. }
  31676. }
  31677. /**
  31678. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  31679. * @tparam Allocator Type of allocator used to manage memory and elements.
  31680. */
  31681. template<typename Allocator>
  31682. struct allocation_deleter: private Allocator {
  31683. /*! @brief Allocator type. */
  31684. using allocator_type = Allocator;
  31685. /*! @brief Pointer type. */
  31686. using pointer = typename std::allocator_traits<Allocator>::pointer;
  31687. /**
  31688. * @brief Inherited constructors.
  31689. * @param alloc The allocator to use.
  31690. */
  31691. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  31692. : Allocator{alloc} {}
  31693. /**
  31694. * @brief Destroys the pointed object and deallocates its memory.
  31695. * @param ptr A valid pointer to an object of the given type.
  31696. */
  31697. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  31698. using alloc_traits = std::allocator_traits<Allocator>;
  31699. alloc_traits::destroy(*this, to_address(ptr));
  31700. alloc_traits::deallocate(*this, ptr, 1u);
  31701. }
  31702. };
  31703. /**
  31704. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  31705. * @tparam Type Type of object to allocate for and to construct.
  31706. * @tparam Allocator Type of allocator used to manage memory and elements.
  31707. * @tparam Args Types of arguments to use to construct the object.
  31708. * @param allocator The allocator to use.
  31709. * @param args Parameters to use to construct the object.
  31710. * @return A properly initialized unique pointer with a custom deleter.
  31711. */
  31712. template<typename Type, typename Allocator, typename... Args>
  31713. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  31714. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  31715. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  31716. using allocator_type = typename alloc_traits::allocator_type;
  31717. allocator_type alloc{allocator};
  31718. auto ptr = alloc_traits::allocate(alloc, 1u);
  31719. ENTT_TRY {
  31720. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  31721. }
  31722. ENTT_CATCH {
  31723. alloc_traits::deallocate(alloc, ptr, 1u);
  31724. ENTT_THROW;
  31725. }
  31726. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  31727. }
  31728. /*! @cond TURN_OFF_DOXYGEN */
  31729. namespace internal {
  31730. template<typename Type>
  31731. struct uses_allocator_construction {
  31732. template<typename Allocator, typename... Params>
  31733. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  31734. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  31735. return std::forward_as_tuple(std::forward<Params>(params)...);
  31736. } else {
  31737. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  31738. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  31739. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  31740. } else {
  31741. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  31742. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  31743. }
  31744. }
  31745. }
  31746. };
  31747. template<typename Type, typename Other>
  31748. struct uses_allocator_construction<std::pair<Type, Other>> {
  31749. using type = std::pair<Type, Other>;
  31750. template<typename Allocator, typename First, typename Second>
  31751. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  31752. return std::make_tuple(
  31753. std::piecewise_construct,
  31754. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  31755. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  31756. }
  31757. template<typename Allocator>
  31758. static constexpr auto args(const Allocator &allocator) noexcept {
  31759. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  31760. }
  31761. template<typename Allocator, typename First, typename Second>
  31762. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  31763. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  31764. }
  31765. template<typename Allocator, typename First, typename Second>
  31766. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  31767. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  31768. }
  31769. template<typename Allocator, typename First, typename Second>
  31770. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  31771. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  31772. }
  31773. };
  31774. } // namespace internal
  31775. /*! @endcond */
  31776. /**
  31777. * @brief Uses-allocator construction utility (waiting for C++20).
  31778. *
  31779. * Primarily intended for internal use. Prepares the argument list needed to
  31780. * create an object of a given type by means of uses-allocator construction.
  31781. *
  31782. * @tparam Type Type to return arguments for.
  31783. * @tparam Allocator Type of allocator used to manage memory and elements.
  31784. * @tparam Args Types of arguments to use to construct the object.
  31785. * @param allocator The allocator to use.
  31786. * @param args Parameters to use to construct the object.
  31787. * @return The arguments needed to create an object of the given type.
  31788. */
  31789. template<typename Type, typename Allocator, typename... Args>
  31790. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  31791. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  31792. }
  31793. /**
  31794. * @brief Uses-allocator construction utility (waiting for C++20).
  31795. *
  31796. * Primarily intended for internal use. Creates an object of a given type by
  31797. * means of uses-allocator construction.
  31798. *
  31799. * @tparam Type Type of object to create.
  31800. * @tparam Allocator Type of allocator used to manage memory and elements.
  31801. * @tparam Args Types of arguments to use to construct the object.
  31802. * @param allocator The allocator to use.
  31803. * @param args Parameters to use to construct the object.
  31804. * @return A newly created object of the given type.
  31805. */
  31806. template<typename Type, typename Allocator, typename... Args>
  31807. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  31808. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  31809. }
  31810. /**
  31811. * @brief Uses-allocator construction utility (waiting for C++20).
  31812. *
  31813. * Primarily intended for internal use. Creates an object of a given type by
  31814. * means of uses-allocator construction at an uninitialized memory location.
  31815. *
  31816. * @tparam Type Type of object to create.
  31817. * @tparam Allocator Type of allocator used to manage memory and elements.
  31818. * @tparam Args Types of arguments to use to construct the object.
  31819. * @param value Memory location in which to place the object.
  31820. * @param allocator The allocator to use.
  31821. * @param args Parameters to use to construct the object.
  31822. * @return A pointer to the newly created object of the given type.
  31823. */
  31824. template<typename Type, typename Allocator, typename... Args>
  31825. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  31826. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  31827. }
  31828. } // namespace entt
  31829. #endif
  31830. // #include "../core/type_traits.hpp"
  31831. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  31832. #define ENTT_CORE_TYPE_TRAITS_HPP
  31833. #include <cstddef>
  31834. #include <iterator>
  31835. #include <tuple>
  31836. #include <type_traits>
  31837. #include <utility>
  31838. // #include "../config/config.h"
  31839. // #include "fwd.hpp"
  31840. namespace entt {
  31841. /**
  31842. * @brief Utility class to disambiguate overloaded functions.
  31843. * @tparam N Number of choices available.
  31844. */
  31845. template<std::size_t N>
  31846. struct choice_t
  31847. // unfortunately, doxygen cannot parse such a construct
  31848. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  31849. {};
  31850. /*! @copybrief choice_t */
  31851. template<>
  31852. struct choice_t<0> {};
  31853. /**
  31854. * @brief Variable template for the choice trick.
  31855. * @tparam N Number of choices available.
  31856. */
  31857. template<std::size_t N>
  31858. inline constexpr choice_t<N> choice{};
  31859. /**
  31860. * @brief Identity type trait.
  31861. *
  31862. * Useful to establish non-deduced contexts in template argument deduction
  31863. * (waiting for C++20) or to provide types through function arguments.
  31864. *
  31865. * @tparam Type A type.
  31866. */
  31867. template<typename Type>
  31868. struct type_identity {
  31869. /*! @brief Identity type. */
  31870. using type = Type;
  31871. };
  31872. /**
  31873. * @brief Helper type.
  31874. * @tparam Type A type.
  31875. */
  31876. template<typename Type>
  31877. using type_identity_t = typename type_identity<Type>::type;
  31878. /**
  31879. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  31880. * @tparam Type The type of which to return the size.
  31881. */
  31882. template<typename Type, typename = void>
  31883. struct size_of: std::integral_constant<std::size_t, 0u> {};
  31884. /*! @copydoc size_of */
  31885. template<typename Type>
  31886. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  31887. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  31888. : std::integral_constant<std::size_t, sizeof(Type)> {};
  31889. /**
  31890. * @brief Helper variable template.
  31891. * @tparam Type The type of which to return the size.
  31892. */
  31893. template<typename Type>
  31894. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  31895. /**
  31896. * @brief Using declaration to be used to _repeat_ the same type a number of
  31897. * times equal to the size of a given parameter pack.
  31898. * @tparam Type A type to repeat.
  31899. */
  31900. template<typename Type, typename>
  31901. using unpack_as_type = Type;
  31902. /**
  31903. * @brief Helper variable template to be used to _repeat_ the same value a
  31904. * number of times equal to the size of a given parameter pack.
  31905. * @tparam Value A value to repeat.
  31906. */
  31907. template<auto Value, typename>
  31908. inline constexpr auto unpack_as_value = Value;
  31909. /**
  31910. * @brief Wraps a static constant.
  31911. * @tparam Value A static constant.
  31912. */
  31913. template<auto Value>
  31914. using integral_constant = std::integral_constant<decltype(Value), Value>;
  31915. /**
  31916. * @brief Alias template to facilitate the creation of named values.
  31917. * @tparam Value A constant value at least convertible to `id_type`.
  31918. */
  31919. template<id_type Value>
  31920. using tag = integral_constant<Value>;
  31921. /**
  31922. * @brief A class to use to push around lists of types, nothing more.
  31923. * @tparam Type Types provided by the type list.
  31924. */
  31925. template<typename... Type>
  31926. struct type_list {
  31927. /*! @brief Type list type. */
  31928. using type = type_list;
  31929. /*! @brief Compile-time number of elements in the type list. */
  31930. static constexpr auto size = sizeof...(Type);
  31931. };
  31932. /*! @brief Primary template isn't defined on purpose. */
  31933. template<std::size_t, typename>
  31934. struct type_list_element;
  31935. /**
  31936. * @brief Provides compile-time indexed access to the types of a type list.
  31937. * @tparam Index Index of the type to return.
  31938. * @tparam First First type provided by the type list.
  31939. * @tparam Other Other types provided by the type list.
  31940. */
  31941. template<std::size_t Index, typename First, typename... Other>
  31942. struct type_list_element<Index, type_list<First, Other...>>
  31943. : type_list_element<Index - 1u, type_list<Other...>> {};
  31944. /**
  31945. * @brief Provides compile-time indexed access to the types of a type list.
  31946. * @tparam First First type provided by the type list.
  31947. * @tparam Other Other types provided by the type list.
  31948. */
  31949. template<typename First, typename... Other>
  31950. struct type_list_element<0u, type_list<First, Other...>> {
  31951. /*! @brief Searched type. */
  31952. using type = First;
  31953. };
  31954. /**
  31955. * @brief Helper type.
  31956. * @tparam Index Index of the type to return.
  31957. * @tparam List Type list to search into.
  31958. */
  31959. template<std::size_t Index, typename List>
  31960. using type_list_element_t = typename type_list_element<Index, List>::type;
  31961. /*! @brief Primary template isn't defined on purpose. */
  31962. template<typename, typename>
  31963. struct type_list_index;
  31964. /**
  31965. * @brief Provides compile-time type access to the types of a type list.
  31966. * @tparam Type Type to look for and for which to return the index.
  31967. * @tparam First First type provided by the type list.
  31968. * @tparam Other Other types provided by the type list.
  31969. */
  31970. template<typename Type, typename First, typename... Other>
  31971. struct type_list_index<Type, type_list<First, Other...>> {
  31972. /*! @brief Unsigned integer type. */
  31973. using value_type = std::size_t;
  31974. /*! @brief Compile-time position of the given type in the sublist. */
  31975. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  31976. };
  31977. /**
  31978. * @brief Provides compile-time type access to the types of a type list.
  31979. * @tparam Type Type to look for and for which to return the index.
  31980. * @tparam Other Other types provided by the type list.
  31981. */
  31982. template<typename Type, typename... Other>
  31983. struct type_list_index<Type, type_list<Type, Other...>> {
  31984. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  31985. /*! @brief Unsigned integer type. */
  31986. using value_type = std::size_t;
  31987. /*! @brief Compile-time position of the given type in the sublist. */
  31988. static constexpr value_type value = 0u;
  31989. };
  31990. /**
  31991. * @brief Provides compile-time type access to the types of a type list.
  31992. * @tparam Type Type to look for and for which to return the index.
  31993. */
  31994. template<typename Type>
  31995. struct type_list_index<Type, type_list<>> {
  31996. /*! @brief Unsigned integer type. */
  31997. using value_type = std::size_t;
  31998. /*! @brief Compile-time position of the given type in the sublist. */
  31999. static constexpr value_type value = 0u;
  32000. };
  32001. /**
  32002. * @brief Helper variable template.
  32003. * @tparam List Type list.
  32004. * @tparam Type Type to look for and for which to return the index.
  32005. */
  32006. template<typename Type, typename List>
  32007. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  32008. /**
  32009. * @brief Concatenates multiple type lists.
  32010. * @tparam Type Types provided by the first type list.
  32011. * @tparam Other Types provided by the second type list.
  32012. * @return A type list composed by the types of both the type lists.
  32013. */
  32014. template<typename... Type, typename... Other>
  32015. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  32016. return {};
  32017. }
  32018. /*! @brief Primary template isn't defined on purpose. */
  32019. template<typename...>
  32020. struct type_list_cat;
  32021. /*! @brief Concatenates multiple type lists. */
  32022. template<>
  32023. struct type_list_cat<> {
  32024. /*! @brief A type list composed by the types of all the type lists. */
  32025. using type = type_list<>;
  32026. };
  32027. /**
  32028. * @brief Concatenates multiple type lists.
  32029. * @tparam Type Types provided by the first type list.
  32030. * @tparam Other Types provided by the second type list.
  32031. * @tparam List Other type lists, if any.
  32032. */
  32033. template<typename... Type, typename... Other, typename... List>
  32034. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  32035. /*! @brief A type list composed by the types of all the type lists. */
  32036. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  32037. };
  32038. /**
  32039. * @brief Concatenates multiple type lists.
  32040. * @tparam Type Types provided by the type list.
  32041. */
  32042. template<typename... Type>
  32043. struct type_list_cat<type_list<Type...>> {
  32044. /*! @brief A type list composed by the types of all the type lists. */
  32045. using type = type_list<Type...>;
  32046. };
  32047. /**
  32048. * @brief Helper type.
  32049. * @tparam List Type lists to concatenate.
  32050. */
  32051. template<typename... List>
  32052. using type_list_cat_t = typename type_list_cat<List...>::type;
  32053. /*! @cond TURN_OFF_DOXYGEN */
  32054. namespace internal {
  32055. template<typename...>
  32056. struct type_list_unique;
  32057. template<typename First, typename... Other, typename... Type>
  32058. struct type_list_unique<type_list<First, Other...>, Type...>
  32059. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  32060. template<typename... Type>
  32061. struct type_list_unique<type_list<>, Type...> {
  32062. using type = type_list<Type...>;
  32063. };
  32064. } // namespace internal
  32065. /*! @endcond */
  32066. /**
  32067. * @brief Removes duplicates types from a type list.
  32068. * @tparam List Type list.
  32069. */
  32070. template<typename List>
  32071. struct type_list_unique {
  32072. /*! @brief A type list without duplicate types. */
  32073. using type = typename internal::type_list_unique<List>::type;
  32074. };
  32075. /**
  32076. * @brief Helper type.
  32077. * @tparam List Type list.
  32078. */
  32079. template<typename List>
  32080. using type_list_unique_t = typename type_list_unique<List>::type;
  32081. /**
  32082. * @brief Provides the member constant `value` to true if a type list contains a
  32083. * given type, false otherwise.
  32084. * @tparam List Type list.
  32085. * @tparam Type Type to look for.
  32086. */
  32087. template<typename List, typename Type>
  32088. struct type_list_contains;
  32089. /**
  32090. * @copybrief type_list_contains
  32091. * @tparam Type Types provided by the type list.
  32092. * @tparam Other Type to look for.
  32093. */
  32094. template<typename... Type, typename Other>
  32095. struct type_list_contains<type_list<Type...>, Other>
  32096. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  32097. /**
  32098. * @brief Helper variable template.
  32099. * @tparam List Type list.
  32100. * @tparam Type Type to look for.
  32101. */
  32102. template<typename List, typename Type>
  32103. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  32104. /*! @brief Primary template isn't defined on purpose. */
  32105. template<typename...>
  32106. struct type_list_diff;
  32107. /**
  32108. * @brief Computes the difference between two type lists.
  32109. * @tparam Type Types provided by the first type list.
  32110. * @tparam Other Types provided by the second type list.
  32111. */
  32112. template<typename... Type, typename... Other>
  32113. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  32114. /*! @brief A type list that is the difference between the two type lists. */
  32115. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  32116. };
  32117. /**
  32118. * @brief Helper type.
  32119. * @tparam List Type lists between which to compute the difference.
  32120. */
  32121. template<typename... List>
  32122. using type_list_diff_t = typename type_list_diff<List...>::type;
  32123. /*! @brief Primary template isn't defined on purpose. */
  32124. template<typename, template<typename...> class>
  32125. struct type_list_transform;
  32126. /**
  32127. * @brief Applies a given _function_ to a type list and generate a new list.
  32128. * @tparam Type Types provided by the type list.
  32129. * @tparam Op Unary operation as template class with a type member named `type`.
  32130. */
  32131. template<typename... Type, template<typename...> class Op>
  32132. struct type_list_transform<type_list<Type...>, Op> {
  32133. /*! @brief Resulting type list after applying the transform function. */
  32134. // NOLINTNEXTLINE(modernize-type-traits)
  32135. using type = type_list<typename Op<Type>::type...>;
  32136. };
  32137. /**
  32138. * @brief Helper type.
  32139. * @tparam List Type list.
  32140. * @tparam Op Unary operation as template class with a type member named `type`.
  32141. */
  32142. template<typename List, template<typename...> class Op>
  32143. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  32144. /**
  32145. * @brief A class to use to push around lists of constant values, nothing more.
  32146. * @tparam Value Values provided by the value list.
  32147. */
  32148. template<auto... Value>
  32149. struct value_list {
  32150. /*! @brief Value list type. */
  32151. using type = value_list;
  32152. /*! @brief Compile-time number of elements in the value list. */
  32153. static constexpr auto size = sizeof...(Value);
  32154. };
  32155. /*! @brief Primary template isn't defined on purpose. */
  32156. template<std::size_t, typename>
  32157. struct value_list_element;
  32158. /**
  32159. * @brief Provides compile-time indexed access to the values of a value list.
  32160. * @tparam Index Index of the value to return.
  32161. * @tparam Value First value provided by the value list.
  32162. * @tparam Other Other values provided by the value list.
  32163. */
  32164. template<std::size_t Index, auto Value, auto... Other>
  32165. struct value_list_element<Index, value_list<Value, Other...>>
  32166. : value_list_element<Index - 1u, value_list<Other...>> {};
  32167. /**
  32168. * @brief Provides compile-time indexed access to the types of a type list.
  32169. * @tparam Value First value provided by the value list.
  32170. * @tparam Other Other values provided by the value list.
  32171. */
  32172. template<auto Value, auto... Other>
  32173. struct value_list_element<0u, value_list<Value, Other...>> {
  32174. /*! @brief Searched type. */
  32175. using type = decltype(Value);
  32176. /*! @brief Searched value. */
  32177. static constexpr auto value = Value;
  32178. };
  32179. /**
  32180. * @brief Helper type.
  32181. * @tparam Index Index of the type to return.
  32182. * @tparam List Value list to search into.
  32183. */
  32184. template<std::size_t Index, typename List>
  32185. using value_list_element_t = typename value_list_element<Index, List>::type;
  32186. /**
  32187. * @brief Helper type.
  32188. * @tparam Index Index of the value to return.
  32189. * @tparam List Value list to search into.
  32190. */
  32191. template<std::size_t Index, typename List>
  32192. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  32193. /*! @brief Primary template isn't defined on purpose. */
  32194. template<auto, typename>
  32195. struct value_list_index;
  32196. /**
  32197. * @brief Provides compile-time type access to the values of a value list.
  32198. * @tparam Value Value to look for and for which to return the index.
  32199. * @tparam First First value provided by the value list.
  32200. * @tparam Other Other values provided by the value list.
  32201. */
  32202. template<auto Value, auto First, auto... Other>
  32203. struct value_list_index<Value, value_list<First, Other...>> {
  32204. /*! @brief Unsigned integer type. */
  32205. using value_type = std::size_t;
  32206. /*! @brief Compile-time position of the given value in the sublist. */
  32207. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  32208. };
  32209. /**
  32210. * @brief Provides compile-time type access to the values of a value list.
  32211. * @tparam Value Value to look for and for which to return the index.
  32212. * @tparam Other Other values provided by the value list.
  32213. */
  32214. template<auto Value, auto... Other>
  32215. struct value_list_index<Value, value_list<Value, Other...>> {
  32216. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  32217. /*! @brief Unsigned integer type. */
  32218. using value_type = std::size_t;
  32219. /*! @brief Compile-time position of the given value in the sublist. */
  32220. static constexpr value_type value = 0u;
  32221. };
  32222. /**
  32223. * @brief Provides compile-time type access to the values of a value list.
  32224. * @tparam Value Value to look for and for which to return the index.
  32225. */
  32226. template<auto Value>
  32227. struct value_list_index<Value, value_list<>> {
  32228. /*! @brief Unsigned integer type. */
  32229. using value_type = std::size_t;
  32230. /*! @brief Compile-time position of the given type in the sublist. */
  32231. static constexpr value_type value = 0u;
  32232. };
  32233. /**
  32234. * @brief Helper variable template.
  32235. * @tparam List Value list.
  32236. * @tparam Value Value to look for and for which to return the index.
  32237. */
  32238. template<auto Value, typename List>
  32239. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  32240. /**
  32241. * @brief Concatenates multiple value lists.
  32242. * @tparam Value Values provided by the first value list.
  32243. * @tparam Other Values provided by the second value list.
  32244. * @return A value list composed by the values of both the value lists.
  32245. */
  32246. template<auto... Value, auto... Other>
  32247. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  32248. return {};
  32249. }
  32250. /*! @brief Primary template isn't defined on purpose. */
  32251. template<typename...>
  32252. struct value_list_cat;
  32253. /*! @brief Concatenates multiple value lists. */
  32254. template<>
  32255. struct value_list_cat<> {
  32256. /*! @brief A value list composed by the values of all the value lists. */
  32257. using type = value_list<>;
  32258. };
  32259. /**
  32260. * @brief Concatenates multiple value lists.
  32261. * @tparam Value Values provided by the first value list.
  32262. * @tparam Other Values provided by the second value list.
  32263. * @tparam List Other value lists, if any.
  32264. */
  32265. template<auto... Value, auto... Other, typename... List>
  32266. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  32267. /*! @brief A value list composed by the values of all the value lists. */
  32268. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  32269. };
  32270. /**
  32271. * @brief Concatenates multiple value lists.
  32272. * @tparam Value Values provided by the value list.
  32273. */
  32274. template<auto... Value>
  32275. struct value_list_cat<value_list<Value...>> {
  32276. /*! @brief A value list composed by the values of all the value lists. */
  32277. using type = value_list<Value...>;
  32278. };
  32279. /**
  32280. * @brief Helper type.
  32281. * @tparam List Value lists to concatenate.
  32282. */
  32283. template<typename... List>
  32284. using value_list_cat_t = typename value_list_cat<List...>::type;
  32285. /*! @brief Primary template isn't defined on purpose. */
  32286. template<typename>
  32287. struct value_list_unique;
  32288. /**
  32289. * @brief Removes duplicates values from a value list.
  32290. * @tparam Value One of the values provided by the given value list.
  32291. * @tparam Other The other values provided by the given value list.
  32292. */
  32293. template<auto Value, auto... Other>
  32294. struct value_list_unique<value_list<Value, Other...>> {
  32295. /*! @brief A value list without duplicate types. */
  32296. using type = std::conditional_t<
  32297. ((Value == Other) || ...),
  32298. typename value_list_unique<value_list<Other...>>::type,
  32299. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  32300. };
  32301. /*! @brief Removes duplicates values from a value list. */
  32302. template<>
  32303. struct value_list_unique<value_list<>> {
  32304. /*! @brief A value list without duplicate types. */
  32305. using type = value_list<>;
  32306. };
  32307. /**
  32308. * @brief Helper type.
  32309. * @tparam Type A value list.
  32310. */
  32311. template<typename Type>
  32312. using value_list_unique_t = typename value_list_unique<Type>::type;
  32313. /**
  32314. * @brief Provides the member constant `value` to true if a value list contains
  32315. * a given value, false otherwise.
  32316. * @tparam List Value list.
  32317. * @tparam Value Value to look for.
  32318. */
  32319. template<typename List, auto Value>
  32320. struct value_list_contains;
  32321. /**
  32322. * @copybrief value_list_contains
  32323. * @tparam Value Values provided by the value list.
  32324. * @tparam Other Value to look for.
  32325. */
  32326. template<auto... Value, auto Other>
  32327. struct value_list_contains<value_list<Value...>, Other>
  32328. : std::bool_constant<((Value == Other) || ...)> {};
  32329. /**
  32330. * @brief Helper variable template.
  32331. * @tparam List Value list.
  32332. * @tparam Value Value to look for.
  32333. */
  32334. template<typename List, auto Value>
  32335. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  32336. /*! @brief Primary template isn't defined on purpose. */
  32337. template<typename...>
  32338. struct value_list_diff;
  32339. /**
  32340. * @brief Computes the difference between two value lists.
  32341. * @tparam Value Values provided by the first value list.
  32342. * @tparam Other Values provided by the second value list.
  32343. */
  32344. template<auto... Value, auto... Other>
  32345. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  32346. /*! @brief A value list that is the difference between the two value lists. */
  32347. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  32348. };
  32349. /**
  32350. * @brief Helper type.
  32351. * @tparam List Value lists between which to compute the difference.
  32352. */
  32353. template<typename... List>
  32354. using value_list_diff_t = typename value_list_diff<List...>::type;
  32355. /*! @brief Same as std::is_invocable, but with tuples. */
  32356. template<typename, typename>
  32357. struct is_applicable: std::false_type {};
  32358. /**
  32359. * @copybrief is_applicable
  32360. * @tparam Func A valid function type.
  32361. * @tparam Tuple Tuple-like type.
  32362. * @tparam Args The list of arguments to use to probe the function type.
  32363. */
  32364. template<typename Func, template<typename...> class Tuple, typename... Args>
  32365. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  32366. /**
  32367. * @copybrief is_applicable
  32368. * @tparam Func A valid function type.
  32369. * @tparam Tuple Tuple-like type.
  32370. * @tparam Args The list of arguments to use to probe the function type.
  32371. */
  32372. template<typename Func, template<typename...> class Tuple, typename... Args>
  32373. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  32374. /**
  32375. * @brief Helper variable template.
  32376. * @tparam Func A valid function type.
  32377. * @tparam Args The list of arguments to use to probe the function type.
  32378. */
  32379. template<typename Func, typename Args>
  32380. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  32381. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  32382. template<typename, typename, typename>
  32383. struct is_applicable_r: std::false_type {};
  32384. /**
  32385. * @copybrief is_applicable_r
  32386. * @tparam Ret The type to which the return type of the function should be
  32387. * convertible.
  32388. * @tparam Func A valid function type.
  32389. * @tparam Args The list of arguments to use to probe the function type.
  32390. */
  32391. template<typename Ret, typename Func, typename... Args>
  32392. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  32393. /**
  32394. * @brief Helper variable template.
  32395. * @tparam Ret The type to which the return type of the function should be
  32396. * convertible.
  32397. * @tparam Func A valid function type.
  32398. * @tparam Args The list of arguments to use to probe the function type.
  32399. */
  32400. template<typename Ret, typename Func, typename Args>
  32401. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  32402. /**
  32403. * @brief Provides the member constant `value` to true if a given type is
  32404. * complete, false otherwise.
  32405. * @tparam Type The type to test.
  32406. */
  32407. template<typename Type, typename = void>
  32408. struct is_complete: std::false_type {};
  32409. /*! @copydoc is_complete */
  32410. template<typename Type>
  32411. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  32412. /**
  32413. * @brief Helper variable template.
  32414. * @tparam Type The type to test.
  32415. */
  32416. template<typename Type>
  32417. inline constexpr bool is_complete_v = is_complete<Type>::value;
  32418. /**
  32419. * @brief Provides the member constant `value` to true if a given type is an
  32420. * iterator, false otherwise.
  32421. * @tparam Type The type to test.
  32422. */
  32423. template<typename Type, typename = void>
  32424. struct is_iterator: std::false_type {};
  32425. /*! @cond TURN_OFF_DOXYGEN */
  32426. namespace internal {
  32427. template<typename, typename = void>
  32428. struct has_iterator_category: std::false_type {};
  32429. template<typename Type>
  32430. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  32431. } // namespace internal
  32432. /*! @endcond */
  32433. /*! @copydoc is_iterator */
  32434. template<typename Type>
  32435. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  32436. : internal::has_iterator_category<Type> {};
  32437. /**
  32438. * @brief Helper variable template.
  32439. * @tparam Type The type to test.
  32440. */
  32441. template<typename Type>
  32442. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  32443. /**
  32444. * @brief Provides the member constant `value` to true if a given type is both
  32445. * an empty and non-final class, false otherwise.
  32446. * @tparam Type The type to test
  32447. */
  32448. template<typename Type>
  32449. struct is_ebco_eligible
  32450. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  32451. /**
  32452. * @brief Helper variable template.
  32453. * @tparam Type The type to test.
  32454. */
  32455. template<typename Type>
  32456. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  32457. /**
  32458. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  32459. * is valid and denotes a type, false otherwise.
  32460. * @tparam Type The type to test.
  32461. */
  32462. template<typename Type, typename = void>
  32463. struct is_transparent: std::false_type {};
  32464. /*! @copydoc is_transparent */
  32465. template<typename Type>
  32466. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  32467. /**
  32468. * @brief Helper variable template.
  32469. * @tparam Type The type to test.
  32470. */
  32471. template<typename Type>
  32472. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  32473. /*! @cond TURN_OFF_DOXYGEN */
  32474. namespace internal {
  32475. template<typename, typename = void>
  32476. struct has_tuple_size_value: std::false_type {};
  32477. template<typename Type>
  32478. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  32479. template<typename, typename = void>
  32480. struct has_value_type: std::false_type {};
  32481. template<typename Type>
  32482. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  32483. template<typename>
  32484. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  32485. template<typename Type, std::size_t... Index>
  32486. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  32487. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  32488. }
  32489. template<typename>
  32490. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  32491. return false;
  32492. }
  32493. template<typename Type>
  32494. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  32495. return true;
  32496. }
  32497. template<typename Type>
  32498. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  32499. // NOLINTBEGIN(modernize-use-transparent-functors)
  32500. if constexpr(std::is_array_v<Type>) {
  32501. return false;
  32502. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  32503. if constexpr(has_tuple_size_value<Type>::value) {
  32504. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  32505. } else {
  32506. return maybe_equality_comparable<Type>(0);
  32507. }
  32508. } else if constexpr(has_value_type<Type>::value) {
  32509. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  32510. return maybe_equality_comparable<Type>(0);
  32511. } else {
  32512. return false;
  32513. }
  32514. } else {
  32515. return maybe_equality_comparable<Type>(0);
  32516. }
  32517. // NOLINTEND(modernize-use-transparent-functors)
  32518. }
  32519. } // namespace internal
  32520. /*! @endcond */
  32521. /**
  32522. * @brief Provides the member constant `value` to true if a given type is
  32523. * equality comparable, false otherwise.
  32524. * @tparam Type The type to test.
  32525. */
  32526. template<typename Type>
  32527. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  32528. /*! @copydoc is_equality_comparable */
  32529. template<typename Type>
  32530. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  32531. /**
  32532. * @brief Helper variable template.
  32533. * @tparam Type The type to test.
  32534. */
  32535. template<typename Type>
  32536. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  32537. /**
  32538. * @brief Transcribes the constness of a type to another type.
  32539. * @tparam To The type to which to transcribe the constness.
  32540. * @tparam From The type from which to transcribe the constness.
  32541. */
  32542. template<typename To, typename From>
  32543. struct constness_as {
  32544. /*! @brief The type resulting from the transcription of the constness. */
  32545. using type = std::remove_const_t<To>;
  32546. };
  32547. /*! @copydoc constness_as */
  32548. template<typename To, typename From>
  32549. struct constness_as<To, const From> {
  32550. /*! @brief The type resulting from the transcription of the constness. */
  32551. using type = const To;
  32552. };
  32553. /**
  32554. * @brief Alias template to facilitate the transcription of the constness.
  32555. * @tparam To The type to which to transcribe the constness.
  32556. * @tparam From The type from which to transcribe the constness.
  32557. */
  32558. template<typename To, typename From>
  32559. using constness_as_t = typename constness_as<To, From>::type;
  32560. /**
  32561. * @brief Extracts the class of a non-static member object or function.
  32562. * @tparam Member A pointer to a non-static member object or function.
  32563. */
  32564. template<typename Member>
  32565. class member_class {
  32566. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  32567. template<typename Class, typename Ret, typename... Args>
  32568. static Class *clazz(Ret (Class::*)(Args...));
  32569. template<typename Class, typename Ret, typename... Args>
  32570. static Class *clazz(Ret (Class::*)(Args...) const);
  32571. template<typename Class, typename Type>
  32572. static Class *clazz(Type Class::*);
  32573. public:
  32574. /*! @brief The class of the given non-static member object or function. */
  32575. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  32576. };
  32577. /**
  32578. * @brief Helper type.
  32579. * @tparam Member A pointer to a non-static member object or function.
  32580. */
  32581. template<typename Member>
  32582. using member_class_t = typename member_class<Member>::type;
  32583. /**
  32584. * @brief Extracts the n-th argument of a _callable_ type.
  32585. * @tparam Index The index of the argument to extract.
  32586. * @tparam Candidate A valid _callable_ type.
  32587. */
  32588. template<std::size_t Index, typename Candidate>
  32589. class nth_argument {
  32590. template<typename Ret, typename... Args>
  32591. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  32592. template<typename Ret, typename Class, typename... Args>
  32593. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  32594. template<typename Ret, typename Class, typename... Args>
  32595. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  32596. template<typename Type, typename Class>
  32597. static constexpr type_list<Type> pick_up(Type Class ::*);
  32598. template<typename Type>
  32599. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  32600. public:
  32601. /*! @brief N-th argument of the _callable_ type. */
  32602. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  32603. };
  32604. /**
  32605. * @brief Helper type.
  32606. * @tparam Index The index of the argument to extract.
  32607. * @tparam Candidate A valid function, member function or data member type.
  32608. */
  32609. template<std::size_t Index, typename Candidate>
  32610. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  32611. } // namespace entt
  32612. template<typename... Type>
  32613. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  32614. template<std::size_t Index, typename... Type>
  32615. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  32616. template<auto... Value>
  32617. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  32618. template<std::size_t Index, auto... Value>
  32619. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  32620. #endif
  32621. // #include "fwd.hpp"
  32622. #ifndef ENTT_CONTAINER_FWD_HPP
  32623. #define ENTT_CONTAINER_FWD_HPP
  32624. #include <functional>
  32625. #include <memory>
  32626. #include <utility>
  32627. #include <vector>
  32628. namespace entt {
  32629. template<
  32630. typename Key,
  32631. typename Type,
  32632. typename = std::hash<Key>,
  32633. typename = std::equal_to<>,
  32634. typename = std::allocator<std::pair<const Key, Type>>>
  32635. class dense_map;
  32636. template<
  32637. typename Type,
  32638. typename = std::hash<Type>,
  32639. typename = std::equal_to<>,
  32640. typename = std::allocator<Type>>
  32641. class dense_set;
  32642. template<typename...>
  32643. class basic_table;
  32644. /**
  32645. * @brief Alias declaration for the most common use case.
  32646. * @tparam Type Element types.
  32647. */
  32648. template<typename... Type>
  32649. using table = basic_table<std::vector<Type>...>;
  32650. } // namespace entt
  32651. #endif
  32652. namespace entt {
  32653. /*! @cond TURN_OFF_DOXYGEN */
  32654. namespace internal {
  32655. static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  32656. template<typename Key, typename Type>
  32657. struct dense_map_node final {
  32658. using value_type = std::pair<Key, Type>;
  32659. template<typename... Args>
  32660. dense_map_node(const std::size_t pos, Args &&...args)
  32661. : next{pos},
  32662. element{std::forward<Args>(args)...} {}
  32663. template<typename Allocator, typename... Args>
  32664. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  32665. : next{pos},
  32666. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  32667. template<typename Allocator>
  32668. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  32669. : next{other.next},
  32670. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  32671. template<typename Allocator>
  32672. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  32673. : next{other.next},
  32674. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  32675. std::size_t next;
  32676. value_type element;
  32677. };
  32678. template<typename It>
  32679. class dense_map_iterator final {
  32680. template<typename>
  32681. friend class dense_map_iterator;
  32682. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  32683. using second_type = decltype((std::declval<It>()->element.second));
  32684. public:
  32685. using value_type = std::pair<first_type, second_type>;
  32686. using pointer = input_iterator_pointer<value_type>;
  32687. using reference = value_type;
  32688. using difference_type = std::ptrdiff_t;
  32689. using iterator_category = std::input_iterator_tag;
  32690. using iterator_concept = std::random_access_iterator_tag;
  32691. constexpr dense_map_iterator() noexcept
  32692. : it{} {}
  32693. constexpr dense_map_iterator(const It iter) noexcept
  32694. : it{iter} {}
  32695. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  32696. constexpr dense_map_iterator(const dense_map_iterator<Other> &other) noexcept
  32697. : it{other.it} {}
  32698. constexpr dense_map_iterator &operator++() noexcept {
  32699. return ++it, *this;
  32700. }
  32701. constexpr dense_map_iterator operator++(int) noexcept {
  32702. const dense_map_iterator orig = *this;
  32703. return ++(*this), orig;
  32704. }
  32705. constexpr dense_map_iterator &operator--() noexcept {
  32706. return --it, *this;
  32707. }
  32708. constexpr dense_map_iterator operator--(int) noexcept {
  32709. const dense_map_iterator orig = *this;
  32710. return operator--(), orig;
  32711. }
  32712. constexpr dense_map_iterator &operator+=(const difference_type value) noexcept {
  32713. it += value;
  32714. return *this;
  32715. }
  32716. constexpr dense_map_iterator operator+(const difference_type value) const noexcept {
  32717. dense_map_iterator copy = *this;
  32718. return (copy += value);
  32719. }
  32720. constexpr dense_map_iterator &operator-=(const difference_type value) noexcept {
  32721. return (*this += -value);
  32722. }
  32723. constexpr dense_map_iterator operator-(const difference_type value) const noexcept {
  32724. return (*this + -value);
  32725. }
  32726. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  32727. return {it[value].element.first, it[value].element.second};
  32728. }
  32729. [[nodiscard]] constexpr pointer operator->() const noexcept {
  32730. return operator*();
  32731. }
  32732. [[nodiscard]] constexpr reference operator*() const noexcept {
  32733. return operator[](0);
  32734. }
  32735. template<typename Lhs, typename Rhs>
  32736. friend constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  32737. template<typename Lhs, typename Rhs>
  32738. friend constexpr bool operator==(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  32739. template<typename Lhs, typename Rhs>
  32740. friend constexpr bool operator<(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  32741. private:
  32742. It it;
  32743. };
  32744. template<typename Lhs, typename Rhs>
  32745. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  32746. return lhs.it - rhs.it;
  32747. }
  32748. template<typename Lhs, typename Rhs>
  32749. [[nodiscard]] constexpr bool operator==(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  32750. return lhs.it == rhs.it;
  32751. }
  32752. template<typename Lhs, typename Rhs>
  32753. [[nodiscard]] constexpr bool operator!=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  32754. return !(lhs == rhs);
  32755. }
  32756. template<typename Lhs, typename Rhs>
  32757. [[nodiscard]] constexpr bool operator<(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  32758. return lhs.it < rhs.it;
  32759. }
  32760. template<typename Lhs, typename Rhs>
  32761. [[nodiscard]] constexpr bool operator>(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  32762. return rhs < lhs;
  32763. }
  32764. template<typename Lhs, typename Rhs>
  32765. [[nodiscard]] constexpr bool operator<=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  32766. return !(lhs > rhs);
  32767. }
  32768. template<typename Lhs, typename Rhs>
  32769. [[nodiscard]] constexpr bool operator>=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  32770. return !(lhs < rhs);
  32771. }
  32772. template<typename It>
  32773. class dense_map_local_iterator final {
  32774. template<typename>
  32775. friend class dense_map_local_iterator;
  32776. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  32777. using second_type = decltype((std::declval<It>()->element.second));
  32778. public:
  32779. using value_type = std::pair<first_type, second_type>;
  32780. using pointer = input_iterator_pointer<value_type>;
  32781. using reference = value_type;
  32782. using difference_type = std::ptrdiff_t;
  32783. using iterator_category = std::input_iterator_tag;
  32784. using iterator_concept = std::forward_iterator_tag;
  32785. constexpr dense_map_local_iterator() noexcept = default;
  32786. constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept
  32787. : it{iter},
  32788. offset{pos} {}
  32789. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  32790. constexpr dense_map_local_iterator(const dense_map_local_iterator<Other> &other) noexcept
  32791. : it{other.it},
  32792. offset{other.offset} {}
  32793. constexpr dense_map_local_iterator &operator++() noexcept {
  32794. return (offset = it[static_cast<typename It::difference_type>(offset)].next), *this;
  32795. }
  32796. constexpr dense_map_local_iterator operator++(int) noexcept {
  32797. const dense_map_local_iterator orig = *this;
  32798. return ++(*this), orig;
  32799. }
  32800. [[nodiscard]] constexpr pointer operator->() const noexcept {
  32801. return operator*();
  32802. }
  32803. [[nodiscard]] constexpr reference operator*() const noexcept {
  32804. const auto idx = static_cast<typename It::difference_type>(offset);
  32805. return {it[idx].element.first, it[idx].element.second};
  32806. }
  32807. [[nodiscard]] constexpr std::size_t index() const noexcept {
  32808. return offset;
  32809. }
  32810. private:
  32811. It it{};
  32812. std::size_t offset{dense_map_placeholder_position};
  32813. };
  32814. template<typename Lhs, typename Rhs>
  32815. [[nodiscard]] constexpr bool operator==(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  32816. return lhs.index() == rhs.index();
  32817. }
  32818. template<typename Lhs, typename Rhs>
  32819. [[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  32820. return !(lhs == rhs);
  32821. }
  32822. } // namespace internal
  32823. /*! @endcond */
  32824. /**
  32825. * @brief Associative container for key-value pairs with unique keys.
  32826. *
  32827. * Internally, elements are organized into buckets. Which bucket an element is
  32828. * placed into depends entirely on the hash of its key. Keys with the same hash
  32829. * code appear in the same bucket.
  32830. *
  32831. * @tparam Key Key type of the associative container.
  32832. * @tparam Type Mapped type of the associative container.
  32833. * @tparam Hash Type of function to use to hash the keys.
  32834. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  32835. * @tparam Allocator Type of allocator used to manage memory and elements.
  32836. */
  32837. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  32838. class dense_map {
  32839. static constexpr float default_threshold = 0.875f;
  32840. static constexpr std::size_t minimum_capacity = 8u;
  32841. static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position;
  32842. using node_type = internal::dense_map_node<Key, Type>;
  32843. using alloc_traits = std::allocator_traits<Allocator>;
  32844. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  32845. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  32846. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  32847. template<typename Other>
  32848. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept {
  32849. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  32850. return fast_mod(static_cast<size_type>(sparse.second()(key)), bucket_count());
  32851. }
  32852. template<typename Other>
  32853. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) {
  32854. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  32855. if(packed.second()(packed.first()[offset].element.first, key)) {
  32856. return begin() + static_cast<typename iterator::difference_type>(offset);
  32857. }
  32858. }
  32859. return end();
  32860. }
  32861. template<typename Other>
  32862. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const {
  32863. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  32864. if(packed.second()(packed.first()[offset].element.first, key)) {
  32865. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  32866. }
  32867. }
  32868. return cend();
  32869. }
  32870. template<typename Other, typename... Args>
  32871. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  32872. const auto index = key_to_bucket(key);
  32873. if(auto it = constrained_find(key, index); it != end()) {
  32874. return std::make_pair(it, false);
  32875. }
  32876. packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward<Other>(key)), std::forward_as_tuple(std::forward<Args>(args)...));
  32877. sparse.first()[index] = packed.first().size() - 1u;
  32878. rehash_if_required();
  32879. return std::make_pair(--end(), true);
  32880. }
  32881. template<typename Other, typename Arg>
  32882. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  32883. const auto index = key_to_bucket(key);
  32884. if(auto it = constrained_find(key, index); it != end()) {
  32885. it->second = std::forward<Arg>(value);
  32886. return std::make_pair(it, false);
  32887. }
  32888. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  32889. sparse.first()[index] = packed.first().size() - 1u;
  32890. rehash_if_required();
  32891. return std::make_pair(--end(), true);
  32892. }
  32893. void move_and_pop(const std::size_t pos) {
  32894. if(const auto last = size() - 1u; pos != last) {
  32895. size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)];
  32896. packed.first()[pos] = std::move(packed.first().back());
  32897. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  32898. *curr = pos;
  32899. }
  32900. packed.first().pop_back();
  32901. }
  32902. void rehash_if_required() {
  32903. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  32904. rehash(bc * 2u);
  32905. }
  32906. }
  32907. public:
  32908. /*! @brief Allocator type. */
  32909. using allocator_type = Allocator;
  32910. /*! @brief Key type of the container. */
  32911. using key_type = Key;
  32912. /*! @brief Mapped type of the container. */
  32913. using mapped_type = Type;
  32914. /*! @brief Key-value type of the container. */
  32915. using value_type = std::pair<const Key, Type>;
  32916. /*! @brief Unsigned integer type. */
  32917. using size_type = std::size_t;
  32918. /*! @brief Signed integer type. */
  32919. using difference_type = std::ptrdiff_t;
  32920. /*! @brief Type of function to use to hash the keys. */
  32921. using hasher = Hash;
  32922. /*! @brief Type of function to use to compare the keys for equality. */
  32923. using key_equal = KeyEqual;
  32924. /*! @brief Input iterator type. */
  32925. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  32926. /*! @brief Constant input iterator type. */
  32927. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  32928. /*! @brief Input iterator type. */
  32929. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  32930. /*! @brief Constant input iterator type. */
  32931. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  32932. /*! @brief Default constructor. */
  32933. dense_map()
  32934. : dense_map{minimum_capacity} {}
  32935. /**
  32936. * @brief Constructs an empty container with a given allocator.
  32937. * @param allocator The allocator to use.
  32938. */
  32939. explicit dense_map(const allocator_type &allocator)
  32940. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  32941. /**
  32942. * @brief Constructs an empty container with a given allocator and user
  32943. * supplied minimal number of buckets.
  32944. * @param cnt Minimal number of buckets.
  32945. * @param allocator The allocator to use.
  32946. */
  32947. dense_map(const size_type cnt, const allocator_type &allocator)
  32948. : dense_map{cnt, hasher{}, key_equal{}, allocator} {}
  32949. /**
  32950. * @brief Constructs an empty container with a given allocator, hash
  32951. * function and user supplied minimal number of buckets.
  32952. * @param cnt Minimal number of buckets.
  32953. * @param hash Hash function to use.
  32954. * @param allocator The allocator to use.
  32955. */
  32956. dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  32957. : dense_map{cnt, hash, key_equal{}, allocator} {}
  32958. /**
  32959. * @brief Constructs an empty container with a given allocator, hash
  32960. * function, compare function and user supplied minimal number of buckets.
  32961. * @param cnt Minimal number of buckets.
  32962. * @param hash Hash function to use.
  32963. * @param equal Compare function to use.
  32964. * @param allocator The allocator to use.
  32965. */
  32966. explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  32967. : sparse{allocator, hash},
  32968. packed{allocator, equal} {
  32969. rehash(cnt);
  32970. }
  32971. /*! @brief Default copy constructor. */
  32972. dense_map(const dense_map &) = default;
  32973. /**
  32974. * @brief Allocator-extended copy constructor.
  32975. * @param other The instance to copy from.
  32976. * @param allocator The allocator to use.
  32977. */
  32978. dense_map(const dense_map &other, const allocator_type &allocator)
  32979. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  32980. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  32981. threshold{other.threshold} {}
  32982. /*! @brief Default move constructor. */
  32983. dense_map(dense_map &&) noexcept = default;
  32984. /**
  32985. * @brief Allocator-extended move constructor.
  32986. * @param other The instance to move from.
  32987. * @param allocator The allocator to use.
  32988. */
  32989. dense_map(dense_map &&other, const allocator_type &allocator)
  32990. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  32991. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  32992. threshold{other.threshold} {}
  32993. /*! @brief Default destructor. */
  32994. ~dense_map() = default;
  32995. /**
  32996. * @brief Default copy assignment operator.
  32997. * @return This container.
  32998. */
  32999. dense_map &operator=(const dense_map &) = default;
  33000. /**
  33001. * @brief Default move assignment operator.
  33002. * @return This container.
  33003. */
  33004. dense_map &operator=(dense_map &&) noexcept = default;
  33005. /**
  33006. * @brief Exchanges the contents with those of a given container.
  33007. * @param other Container to exchange the content with.
  33008. */
  33009. void swap(dense_map &other) noexcept {
  33010. using std::swap;
  33011. swap(sparse, other.sparse);
  33012. swap(packed, other.packed);
  33013. swap(threshold, other.threshold);
  33014. }
  33015. /**
  33016. * @brief Returns the associated allocator.
  33017. * @return The associated allocator.
  33018. */
  33019. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  33020. return sparse.first().get_allocator();
  33021. }
  33022. /**
  33023. * @brief Returns an iterator to the beginning.
  33024. *
  33025. * If the array is empty, the returned iterator will be equal to `end()`.
  33026. *
  33027. * @return An iterator to the first instance of the internal array.
  33028. */
  33029. [[nodiscard]] const_iterator cbegin() const noexcept {
  33030. return packed.first().begin();
  33031. }
  33032. /*! @copydoc cbegin */
  33033. [[nodiscard]] const_iterator begin() const noexcept {
  33034. return cbegin();
  33035. }
  33036. /*! @copydoc begin */
  33037. [[nodiscard]] iterator begin() noexcept {
  33038. return packed.first().begin();
  33039. }
  33040. /**
  33041. * @brief Returns an iterator to the end.
  33042. * @return An iterator to the element following the last instance of the
  33043. * internal array.
  33044. */
  33045. [[nodiscard]] const_iterator cend() const noexcept {
  33046. return packed.first().end();
  33047. }
  33048. /*! @copydoc cend */
  33049. [[nodiscard]] const_iterator end() const noexcept {
  33050. return cend();
  33051. }
  33052. /*! @copydoc end */
  33053. [[nodiscard]] iterator end() noexcept {
  33054. return packed.first().end();
  33055. }
  33056. /**
  33057. * @brief Checks whether a container is empty.
  33058. * @return True if the container is empty, false otherwise.
  33059. */
  33060. [[nodiscard]] bool empty() const noexcept {
  33061. return packed.first().empty();
  33062. }
  33063. /**
  33064. * @brief Returns the number of elements in a container.
  33065. * @return Number of elements in a container.
  33066. */
  33067. [[nodiscard]] size_type size() const noexcept {
  33068. return packed.first().size();
  33069. }
  33070. /**
  33071. * @brief Returns the maximum possible number of elements.
  33072. * @return Maximum possible number of elements.
  33073. */
  33074. [[nodiscard]] size_type max_size() const noexcept {
  33075. return packed.first().max_size();
  33076. }
  33077. /*! @brief Clears the container. */
  33078. void clear() noexcept {
  33079. sparse.first().clear();
  33080. packed.first().clear();
  33081. rehash(0u);
  33082. }
  33083. /**
  33084. * @brief Inserts an element into the container, if the key does not exist.
  33085. * @param value A key-value pair eventually convertible to the value type.
  33086. * @return A pair consisting of an iterator to the inserted element (or to
  33087. * the element that prevented the insertion) and a bool denoting whether the
  33088. * insertion took place.
  33089. */
  33090. std::pair<iterator, bool> insert(const value_type &value) {
  33091. return insert_or_do_nothing(value.first, value.second);
  33092. }
  33093. /*! @copydoc insert */
  33094. std::pair<iterator, bool> insert(value_type &&value) {
  33095. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  33096. }
  33097. /**
  33098. * @copydoc insert
  33099. * @tparam Arg Type of the key-value pair to insert into the container.
  33100. */
  33101. template<typename Arg>
  33102. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  33103. insert(Arg &&value) {
  33104. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  33105. }
  33106. /**
  33107. * @brief Inserts elements into the container, if their keys do not exist.
  33108. * @tparam It Type of input iterator.
  33109. * @param first An iterator to the first element of the range of elements.
  33110. * @param last An iterator past the last element of the range of elements.
  33111. */
  33112. template<typename It>
  33113. void insert(It first, It last) {
  33114. for(; first != last; ++first) {
  33115. insert(*first);
  33116. }
  33117. }
  33118. /**
  33119. * @brief Inserts an element into the container or assigns to the current
  33120. * element if the key already exists.
  33121. * @tparam Arg Type of the value to insert or assign.
  33122. * @param key A key used both to look up and to insert if not found.
  33123. * @param value A value to insert or assign.
  33124. * @return A pair consisting of an iterator to the element and a bool
  33125. * denoting whether the insertion took place.
  33126. */
  33127. template<typename Arg>
  33128. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  33129. return insert_or_overwrite(key, std::forward<Arg>(value));
  33130. }
  33131. /*! @copydoc insert_or_assign */
  33132. template<typename Arg>
  33133. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  33134. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  33135. }
  33136. /**
  33137. * @brief Constructs an element in-place, if the key does not exist.
  33138. *
  33139. * The element is also constructed when the container already has the key,
  33140. * in which case the newly constructed object is destroyed immediately.
  33141. *
  33142. * @tparam Args Types of arguments to forward to the constructor of the
  33143. * element.
  33144. * @param args Arguments to forward to the constructor of the element.
  33145. * @return A pair consisting of an iterator to the inserted element (or to
  33146. * the element that prevented the insertion) and a bool denoting whether the
  33147. * insertion took place.
  33148. */
  33149. template<typename... Args>
  33150. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  33151. if constexpr(sizeof...(Args) == 0u) {
  33152. return insert_or_do_nothing(key_type{});
  33153. } else if constexpr(sizeof...(Args) == 1u) {
  33154. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  33155. } else if constexpr(sizeof...(Args) == 2u) {
  33156. return insert_or_do_nothing(std::forward<Args>(args)...);
  33157. } else {
  33158. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  33159. const auto index = key_to_bucket(node.element.first);
  33160. if(auto it = constrained_find(node.element.first, index); it != end()) {
  33161. packed.first().pop_back();
  33162. return std::make_pair(it, false);
  33163. }
  33164. std::swap(node.next, sparse.first()[index]);
  33165. rehash_if_required();
  33166. return std::make_pair(--end(), true);
  33167. }
  33168. }
  33169. /**
  33170. * @brief Inserts in-place if the key does not exist, does nothing if the
  33171. * key exists.
  33172. * @tparam Args Types of arguments to forward to the constructor of the
  33173. * element.
  33174. * @param key A key used both to look up and to insert if not found.
  33175. * @param args Arguments to forward to the constructor of the element.
  33176. * @return A pair consisting of an iterator to the inserted element (or to
  33177. * the element that prevented the insertion) and a bool denoting whether the
  33178. * insertion took place.
  33179. */
  33180. template<typename... Args>
  33181. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  33182. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  33183. }
  33184. /*! @copydoc try_emplace */
  33185. template<typename... Args>
  33186. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  33187. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  33188. }
  33189. /**
  33190. * @brief Removes an element from a given position.
  33191. * @param pos An iterator to the element to remove.
  33192. * @return An iterator following the removed element.
  33193. */
  33194. iterator erase(const_iterator pos) {
  33195. const auto diff = pos - cbegin();
  33196. erase(pos->first);
  33197. return begin() + diff;
  33198. }
  33199. /**
  33200. * @brief Removes the given elements from a container.
  33201. * @param first An iterator to the first element of the range of elements.
  33202. * @param last An iterator past the last element of the range of elements.
  33203. * @return An iterator following the last removed element.
  33204. */
  33205. iterator erase(const_iterator first, const_iterator last) {
  33206. const auto dist = first - cbegin();
  33207. for(auto from = last - cbegin(); from != dist; --from) {
  33208. erase(packed.first()[static_cast<size_type>(from) - 1u].element.first);
  33209. }
  33210. return (begin() + dist);
  33211. }
  33212. /**
  33213. * @brief Removes the element associated with a given key.
  33214. * @param key A key value of an element to remove.
  33215. * @return Number of elements removed (either 0 or 1).
  33216. */
  33217. size_type erase(const key_type &key) {
  33218. for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) {
  33219. if(packed.second()(packed.first()[*curr].element.first, key)) {
  33220. const auto index = *curr;
  33221. *curr = packed.first()[*curr].next;
  33222. move_and_pop(index);
  33223. return 1u;
  33224. }
  33225. }
  33226. return 0u;
  33227. }
  33228. /**
  33229. * @brief Accesses a given element with bounds checking.
  33230. * @param key A key of an element to find.
  33231. * @return A reference to the mapped value of the requested element.
  33232. */
  33233. [[nodiscard]] mapped_type &at(const key_type &key) {
  33234. auto it = find(key);
  33235. ENTT_ASSERT(it != end(), "Invalid key");
  33236. return it->second;
  33237. }
  33238. /*! @copydoc at */
  33239. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  33240. auto it = find(key);
  33241. ENTT_ASSERT(it != cend(), "Invalid key");
  33242. return it->second;
  33243. }
  33244. /**
  33245. * @brief Accesses a given element with bounds checking.
  33246. * @tparam Other Type of the key of an element to find.
  33247. * @param key A key of an element to find.
  33248. * @return A reference to the mapped value of the requested element.
  33249. */
  33250. template<typename Other>
  33251. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type const &>>
  33252. at(const Other &key) const {
  33253. auto it = find(key);
  33254. ENTT_ASSERT(it != cend(), "Invalid key");
  33255. return it->second;
  33256. }
  33257. /*! @copydoc at */
  33258. template<typename Other>
  33259. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type &>>
  33260. at(const Other &key) {
  33261. auto it = find(key);
  33262. ENTT_ASSERT(it != end(), "Invalid key");
  33263. return it->second;
  33264. }
  33265. /**
  33266. * @brief Accesses or inserts a given element.
  33267. * @param key A key of an element to find or insert.
  33268. * @return A reference to the mapped value of the requested element.
  33269. */
  33270. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  33271. return insert_or_do_nothing(key).first->second;
  33272. }
  33273. /**
  33274. * @brief Accesses or inserts a given element.
  33275. * @param key A key of an element to find or insert.
  33276. * @return A reference to the mapped value of the requested element.
  33277. */
  33278. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  33279. return insert_or_do_nothing(std::move(key)).first->second;
  33280. }
  33281. /**
  33282. * @brief Returns the number of elements matching a key (either 1 or 0).
  33283. * @param key Key value of an element to search for.
  33284. * @return Number of elements matching the key (either 1 or 0).
  33285. */
  33286. [[nodiscard]] size_type count(const key_type &key) const {
  33287. return find(key) != end();
  33288. }
  33289. /**
  33290. * @brief Returns the number of elements matching a key (either 1 or 0).
  33291. * @tparam Other Type of the key value of an element to search for.
  33292. * @param key Key value of an element to search for.
  33293. * @return Number of elements matching the key (either 1 or 0).
  33294. */
  33295. template<typename Other>
  33296. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  33297. count(const Other &key) const {
  33298. return find(key) != end();
  33299. }
  33300. /**
  33301. * @brief Finds an element with a given key.
  33302. * @param key Key value of an element to search for.
  33303. * @return An iterator to an element with the given key. If no such element
  33304. * is found, a past-the-end iterator is returned.
  33305. */
  33306. [[nodiscard]] iterator find(const key_type &key) {
  33307. return constrained_find(key, key_to_bucket(key));
  33308. }
  33309. /*! @copydoc find */
  33310. [[nodiscard]] const_iterator find(const key_type &key) const {
  33311. return constrained_find(key, key_to_bucket(key));
  33312. }
  33313. /**
  33314. * @brief Finds an element with a key that compares _equivalent_ to a given
  33315. * key.
  33316. * @tparam Other Type of the key value of an element to search for.
  33317. * @param key Key value of an element to search for.
  33318. * @return An iterator to an element with the given key. If no such element
  33319. * is found, a past-the-end iterator is returned.
  33320. */
  33321. template<typename Other>
  33322. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  33323. find(const Other &key) {
  33324. return constrained_find(key, key_to_bucket(key));
  33325. }
  33326. /*! @copydoc find */
  33327. template<typename Other>
  33328. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  33329. find(const Other &key) const {
  33330. return constrained_find(key, key_to_bucket(key));
  33331. }
  33332. /**
  33333. * @brief Returns a range containing all elements with a given key.
  33334. * @param key Key value of an element to search for.
  33335. * @return A pair of iterators pointing to the first element and past the
  33336. * last element of the range.
  33337. */
  33338. [[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
  33339. const auto it = find(key);
  33340. return {it, it + !(it == end())};
  33341. }
  33342. /*! @copydoc equal_range */
  33343. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
  33344. const auto it = find(key);
  33345. return {it, it + !(it == cend())};
  33346. }
  33347. /**
  33348. * @brief Returns a range containing all elements that compare _equivalent_
  33349. * to a given key.
  33350. * @tparam Other Type of an element to search for.
  33351. * @param key Key value of an element to search for.
  33352. * @return A pair of iterators pointing to the first element and past the
  33353. * last element of the range.
  33354. */
  33355. template<typename Other>
  33356. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  33357. equal_range(const Other &key) {
  33358. const auto it = find(key);
  33359. return {it, it + !(it == end())};
  33360. }
  33361. /*! @copydoc equal_range */
  33362. template<typename Other>
  33363. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  33364. equal_range(const Other &key) const {
  33365. const auto it = find(key);
  33366. return {it, it + !(it == cend())};
  33367. }
  33368. /**
  33369. * @brief Checks if the container contains an element with a given key.
  33370. * @param key Key value of an element to search for.
  33371. * @return True if there is such an element, false otherwise.
  33372. */
  33373. [[nodiscard]] bool contains(const key_type &key) const {
  33374. return (find(key) != cend());
  33375. }
  33376. /**
  33377. * @brief Checks if the container contains an element with a key that
  33378. * compares _equivalent_ to a given value.
  33379. * @tparam Other Type of the key value of an element to search for.
  33380. * @param key Key value of an element to search for.
  33381. * @return True if there is such an element, false otherwise.
  33382. */
  33383. template<typename Other>
  33384. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  33385. contains(const Other &key) const {
  33386. return (find(key) != cend());
  33387. }
  33388. /**
  33389. * @brief Returns an iterator to the beginning of a given bucket.
  33390. * @param index An index of a bucket to access.
  33391. * @return An iterator to the beginning of the given bucket.
  33392. */
  33393. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  33394. return {packed.first().begin(), sparse.first()[index]};
  33395. }
  33396. /**
  33397. * @brief Returns an iterator to the beginning of a given bucket.
  33398. * @param index An index of a bucket to access.
  33399. * @return An iterator to the beginning of the given bucket.
  33400. */
  33401. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  33402. return cbegin(index);
  33403. }
  33404. /**
  33405. * @brief Returns an iterator to the beginning of a given bucket.
  33406. * @param index An index of a bucket to access.
  33407. * @return An iterator to the beginning of the given bucket.
  33408. */
  33409. [[nodiscard]] local_iterator begin(const size_type index) {
  33410. return {packed.first().begin(), sparse.first()[index]};
  33411. }
  33412. /**
  33413. * @brief Returns an iterator to the end of a given bucket.
  33414. * @param index An index of a bucket to access.
  33415. * @return An iterator to the end of the given bucket.
  33416. */
  33417. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  33418. return {};
  33419. }
  33420. /**
  33421. * @brief Returns an iterator to the end of a given bucket.
  33422. * @param index An index of a bucket to access.
  33423. * @return An iterator to the end of the given bucket.
  33424. */
  33425. [[nodiscard]] const_local_iterator end(const size_type index) const {
  33426. return cend(index);
  33427. }
  33428. /**
  33429. * @brief Returns an iterator to the end of a given bucket.
  33430. * @param index An index of a bucket to access.
  33431. * @return An iterator to the end of the given bucket.
  33432. */
  33433. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  33434. return {};
  33435. }
  33436. /**
  33437. * @brief Returns the number of buckets.
  33438. * @return The number of buckets.
  33439. */
  33440. [[nodiscard]] size_type bucket_count() const {
  33441. return sparse.first().size();
  33442. }
  33443. /**
  33444. * @brief Returns the maximum number of buckets.
  33445. * @return The maximum number of buckets.
  33446. */
  33447. [[nodiscard]] size_type max_bucket_count() const {
  33448. return sparse.first().max_size();
  33449. }
  33450. /**
  33451. * @brief Returns the number of elements in a given bucket.
  33452. * @param index The index of the bucket to examine.
  33453. * @return The number of elements in the given bucket.
  33454. */
  33455. [[nodiscard]] size_type bucket_size(const size_type index) const {
  33456. return static_cast<size_type>(std::distance(begin(index), end(index)));
  33457. }
  33458. /**
  33459. * @brief Returns the bucket for a given key.
  33460. * @param key The value of the key to examine.
  33461. * @return The bucket for the given key.
  33462. */
  33463. [[nodiscard]] size_type bucket(const key_type &key) const {
  33464. return key_to_bucket(key);
  33465. }
  33466. /**
  33467. * @brief Returns the average number of elements per bucket.
  33468. * @return The average number of elements per bucket.
  33469. */
  33470. [[nodiscard]] float load_factor() const {
  33471. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  33472. }
  33473. /**
  33474. * @brief Returns the maximum average number of elements per bucket.
  33475. * @return The maximum average number of elements per bucket.
  33476. */
  33477. [[nodiscard]] float max_load_factor() const {
  33478. return threshold;
  33479. }
  33480. /**
  33481. * @brief Sets the desired maximum average number of elements per bucket.
  33482. * @param value A desired maximum average number of elements per bucket.
  33483. */
  33484. void max_load_factor(const float value) {
  33485. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  33486. threshold = value;
  33487. rehash(0u);
  33488. }
  33489. /**
  33490. * @brief Reserves at least the specified number of buckets and regenerates
  33491. * the hash table.
  33492. * @param cnt New number of buckets.
  33493. */
  33494. void rehash(const size_type cnt) {
  33495. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  33496. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  33497. value = value > cap ? value : cap;
  33498. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  33499. sparse.first().resize(sz);
  33500. for(auto &&elem: sparse.first()) {
  33501. elem = placeholder_position;
  33502. }
  33503. for(size_type pos{}, last = size(); pos < last; ++pos) {
  33504. const auto index = key_to_bucket(packed.first()[pos].element.first);
  33505. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  33506. }
  33507. }
  33508. }
  33509. /**
  33510. * @brief Reserves space for at least the specified number of elements and
  33511. * regenerates the hash table.
  33512. * @param cnt New number of elements.
  33513. */
  33514. void reserve(const size_type cnt) {
  33515. packed.first().reserve(cnt);
  33516. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  33517. }
  33518. /**
  33519. * @brief Returns the function used to hash the keys.
  33520. * @return The function used to hash the keys.
  33521. */
  33522. [[nodiscard]] hasher hash_function() const {
  33523. return sparse.second();
  33524. }
  33525. /**
  33526. * @brief Returns the function used to compare keys for equality.
  33527. * @return The function used to compare keys for equality.
  33528. */
  33529. [[nodiscard]] key_equal key_eq() const {
  33530. return packed.second();
  33531. }
  33532. private:
  33533. compressed_pair<sparse_container_type, hasher> sparse;
  33534. compressed_pair<packed_container_type, key_equal> packed;
  33535. float threshold{default_threshold};
  33536. };
  33537. } // namespace entt
  33538. /*! @cond TURN_OFF_DOXYGEN */
  33539. namespace std {
  33540. template<typename Key, typename Value, typename Allocator>
  33541. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  33542. : std::true_type {};
  33543. } // namespace std
  33544. /*! @endcond */
  33545. #endif
  33546. // #include "../core/algorithm.hpp"
  33547. // #include "../core/any.hpp"
  33548. // #include "../core/fwd.hpp"
  33549. // #include "../core/iterator.hpp"
  33550. // #include "../core/memory.hpp"
  33551. // #include "../core/type_info.hpp"
  33552. // #include "../core/type_traits.hpp"
  33553. // #include "../core/utility.hpp"
  33554. // #include "entity.hpp"
  33555. // #include "fwd.hpp"
  33556. // #include "group.hpp"
  33557. // #include "mixin.hpp"
  33558. #ifndef ENTT_ENTITY_MIXIN_HPP
  33559. #define ENTT_ENTITY_MIXIN_HPP
  33560. #include <type_traits>
  33561. #include <utility>
  33562. // #include "../config/config.h"
  33563. // #include "../core/any.hpp"
  33564. // #include "../core/type_info.hpp"
  33565. // #include "../signal/sigh.hpp"
  33566. // #include "entity.hpp"
  33567. // #include "fwd.hpp"
  33568. namespace entt {
  33569. /*! @cond TURN_OFF_DOXYGEN */
  33570. namespace internal {
  33571. template<typename, typename, typename = void>
  33572. struct has_on_construct final: std::false_type {};
  33573. template<typename Type, typename Registry>
  33574. struct has_on_construct<Type, Registry, std::void_t<decltype(Type::on_construct(std::declval<Registry &>(), std::declval<Registry>().create()))>>
  33575. : std::true_type {};
  33576. template<typename, typename, typename = void>
  33577. struct has_on_update final: std::false_type {};
  33578. template<typename Type, typename Registry>
  33579. struct has_on_update<Type, Registry, std::void_t<decltype(Type::on_update(std::declval<Registry &>(), std::declval<Registry>().create()))>>
  33580. : std::true_type {};
  33581. template<typename, typename, typename = void>
  33582. struct has_on_destroy final: std::false_type {};
  33583. template<typename Type, typename Registry>
  33584. struct has_on_destroy<Type, Registry, std::void_t<decltype(Type::on_destroy(std::declval<Registry &>(), std::declval<Registry>().create()))>>
  33585. : std::true_type {};
  33586. } // namespace internal
  33587. /*! @endcond */
  33588. /**
  33589. * @brief Mixin type used to add signal support to storage types.
  33590. *
  33591. * The function type of a listener is equivalent to:
  33592. *
  33593. * @code{.cpp}
  33594. * void(basic_registry<entity_type> &, entity_type);
  33595. * @endcode
  33596. *
  33597. * This applies to all signals made available.
  33598. *
  33599. * @tparam Type Underlying storage type.
  33600. * @tparam Registry Basic registry type.
  33601. */
  33602. template<typename Type, typename Registry>
  33603. class basic_sigh_mixin final: public Type {
  33604. using underlying_type = Type;
  33605. using owner_type = Registry;
  33606. using basic_registry_type = basic_registry<typename owner_type::entity_type, typename owner_type::allocator_type>;
  33607. using sigh_type = sigh<void(owner_type &, const typename underlying_type::entity_type), typename underlying_type::allocator_type>;
  33608. using underlying_iterator = typename underlying_type::base_type::basic_iterator;
  33609. static_assert(std::is_base_of_v<basic_registry_type, owner_type>, "Invalid registry type");
  33610. [[nodiscard]] auto &owner_or_assert() const noexcept {
  33611. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  33612. return static_cast<owner_type &>(*owner);
  33613. }
  33614. private:
  33615. void pop(underlying_iterator first, underlying_iterator last) final {
  33616. if(auto &reg = owner_or_assert(); destruction.empty()) {
  33617. underlying_type::pop(first, last);
  33618. } else {
  33619. for(; first != last; ++first) {
  33620. const auto entt = *first;
  33621. destruction.publish(reg, entt);
  33622. const auto it = underlying_type::find(entt);
  33623. underlying_type::pop(it, it + 1u);
  33624. }
  33625. }
  33626. }
  33627. void pop_all() final {
  33628. if(auto &reg = owner_or_assert(); !destruction.empty()) {
  33629. if constexpr(std::is_same_v<typename underlying_type::element_type, entity_type>) {
  33630. for(typename underlying_type::size_type pos{}, last = underlying_type::free_list(); pos < last; ++pos) {
  33631. destruction.publish(reg, underlying_type::base_type::operator[](pos));
  33632. }
  33633. } else {
  33634. for(auto entt: static_cast<typename underlying_type::base_type &>(*this)) {
  33635. if constexpr(underlying_type::storage_policy == deletion_policy::in_place) {
  33636. if(entt != tombstone) {
  33637. destruction.publish(reg, entt);
  33638. }
  33639. } else {
  33640. destruction.publish(reg, entt);
  33641. }
  33642. }
  33643. }
  33644. }
  33645. underlying_type::pop_all();
  33646. }
  33647. underlying_iterator try_emplace(const typename underlying_type::entity_type entt, const bool force_back, const void *value) final {
  33648. const auto it = underlying_type::try_emplace(entt, force_back, value);
  33649. if(auto &reg = owner_or_assert(); it != underlying_type::base_type::end()) {
  33650. construction.publish(reg, *it);
  33651. }
  33652. return it;
  33653. }
  33654. void bind_any(any value) noexcept final {
  33655. owner = any_cast<basic_registry_type>(&value);
  33656. if constexpr(!std::is_same_v<registry_type, basic_registry_type>) {
  33657. if(owner == nullptr) {
  33658. owner = any_cast<registry_type>(&value);
  33659. }
  33660. }
  33661. underlying_type::bind_any(std::move(value));
  33662. }
  33663. public:
  33664. /*! @brief Allocator type. */
  33665. using allocator_type = typename underlying_type::allocator_type;
  33666. /*! @brief Underlying entity identifier. */
  33667. using entity_type = typename underlying_type::entity_type;
  33668. /*! @brief Expected registry type. */
  33669. using registry_type = owner_type;
  33670. /*! @brief Default constructor. */
  33671. basic_sigh_mixin()
  33672. : basic_sigh_mixin{allocator_type{}} {}
  33673. /**
  33674. * @brief Constructs an empty storage with a given allocator.
  33675. * @param allocator The allocator to use.
  33676. */
  33677. explicit basic_sigh_mixin(const allocator_type &allocator)
  33678. : underlying_type{allocator},
  33679. owner{},
  33680. construction{allocator},
  33681. destruction{allocator},
  33682. update{allocator} {
  33683. if constexpr(internal::has_on_construct<typename underlying_type::element_type, Registry>::value) {
  33684. sink{construction}.template connect<&underlying_type::element_type::on_construct>();
  33685. }
  33686. if constexpr(internal::has_on_update<typename underlying_type::element_type, Registry>::value) {
  33687. sink{update}.template connect<&underlying_type::element_type::on_update>();
  33688. }
  33689. if constexpr(internal::has_on_destroy<typename underlying_type::element_type, Registry>::value) {
  33690. sink{destruction}.template connect<&underlying_type::element_type::on_destroy>();
  33691. }
  33692. }
  33693. /*! @brief Default copy constructor, deleted on purpose. */
  33694. basic_sigh_mixin(const basic_sigh_mixin &) = delete;
  33695. /**
  33696. * @brief Move constructor.
  33697. * @param other The instance to move from.
  33698. */
  33699. basic_sigh_mixin(basic_sigh_mixin &&other) noexcept
  33700. : underlying_type{static_cast<underlying_type &&>(other)},
  33701. owner{other.owner},
  33702. construction{std::move(other.construction)},
  33703. destruction{std::move(other.destruction)},
  33704. update{std::move(other.update)} {}
  33705. /**
  33706. * @brief Allocator-extended move constructor.
  33707. * @param other The instance to move from.
  33708. * @param allocator The allocator to use.
  33709. */
  33710. basic_sigh_mixin(basic_sigh_mixin &&other, const allocator_type &allocator)
  33711. : underlying_type{static_cast<underlying_type &&>(other), allocator},
  33712. owner{other.owner},
  33713. construction{std::move(other.construction), allocator},
  33714. destruction{std::move(other.destruction), allocator},
  33715. update{std::move(other.update), allocator} {}
  33716. /*! @brief Default destructor. */
  33717. ~basic_sigh_mixin() override = default;
  33718. /**
  33719. * @brief Default copy assignment operator, deleted on purpose.
  33720. * @return This mixin.
  33721. */
  33722. basic_sigh_mixin &operator=(const basic_sigh_mixin &) = delete;
  33723. /**
  33724. * @brief Move assignment operator.
  33725. * @param other The instance to move from.
  33726. * @return This mixin.
  33727. */
  33728. basic_sigh_mixin &operator=(basic_sigh_mixin &&other) noexcept {
  33729. swap(other);
  33730. return *this;
  33731. }
  33732. /**
  33733. * @brief Exchanges the contents with those of a given storage.
  33734. * @param other Storage to exchange the content with.
  33735. */
  33736. void swap(basic_sigh_mixin &other) noexcept {
  33737. using std::swap;
  33738. swap(owner, other.owner);
  33739. swap(construction, other.construction);
  33740. swap(destruction, other.destruction);
  33741. swap(update, other.update);
  33742. underlying_type::swap(other);
  33743. }
  33744. /**
  33745. * @brief Returns a sink object.
  33746. *
  33747. * The sink returned by this function can be used to receive notifications
  33748. * whenever a new instance is created and assigned to an entity.<br/>
  33749. * Listeners are invoked after the object has been assigned to the entity.
  33750. *
  33751. * @sa sink
  33752. *
  33753. * @return A temporary sink object.
  33754. */
  33755. [[nodiscard]] auto on_construct() noexcept {
  33756. return sink{construction};
  33757. }
  33758. /**
  33759. * @brief Returns a sink object.
  33760. *
  33761. * The sink returned by this function can be used to receive notifications
  33762. * whenever an instance is explicitly updated.<br/>
  33763. * Listeners are invoked after the object has been updated.
  33764. *
  33765. * @sa sink
  33766. *
  33767. * @return A temporary sink object.
  33768. */
  33769. [[nodiscard]] auto on_update() noexcept {
  33770. return sink{update};
  33771. }
  33772. /**
  33773. * @brief Returns a sink object.
  33774. *
  33775. * The sink returned by this function can be used to receive notifications
  33776. * whenever an instance is removed from an entity and thus destroyed.<br/>
  33777. * Listeners are invoked before the object has been removed from the entity.
  33778. *
  33779. * @sa sink
  33780. *
  33781. * @return A temporary sink object.
  33782. */
  33783. [[nodiscard]] auto on_destroy() noexcept {
  33784. return sink{destruction};
  33785. }
  33786. /**
  33787. * @brief Checks if a mixin refers to a valid registry.
  33788. * @return True if the mixin refers to a valid registry, false otherwise.
  33789. */
  33790. [[nodiscard]] explicit operator bool() const noexcept {
  33791. return (owner != nullptr);
  33792. }
  33793. /**
  33794. * @brief Returns a pointer to the underlying registry, if any.
  33795. * @return A pointer to the underlying registry, if any.
  33796. */
  33797. [[nodiscard]] const registry_type &registry() const noexcept {
  33798. return owner_or_assert();
  33799. }
  33800. /*! @copydoc registry */
  33801. [[nodiscard]] registry_type &registry() noexcept {
  33802. return owner_or_assert();
  33803. }
  33804. /**
  33805. * @brief Creates a new identifier or recycles a destroyed one.
  33806. * @return A valid identifier.
  33807. */
  33808. auto generate() {
  33809. const auto entt = underlying_type::generate();
  33810. construction.publish(owner_or_assert(), entt);
  33811. return entt;
  33812. }
  33813. /**
  33814. * @brief Creates a new identifier or recycles a destroyed one.
  33815. * @param hint Required identifier.
  33816. * @return A valid identifier.
  33817. */
  33818. entity_type generate(const entity_type hint) {
  33819. const auto entt = underlying_type::generate(hint);
  33820. construction.publish(owner_or_assert(), entt);
  33821. return entt;
  33822. }
  33823. /**
  33824. * @brief Assigns each element in a range an identifier.
  33825. * @tparam It Type of mutable forward iterator.
  33826. * @param first An iterator to the first element of the range to generate.
  33827. * @param last An iterator past the last element of the range to generate.
  33828. */
  33829. template<typename It>
  33830. void generate(It first, It last) {
  33831. underlying_type::generate(first, last);
  33832. if(auto &reg = owner_or_assert(); !construction.empty()) {
  33833. for(; first != last; ++first) {
  33834. construction.publish(reg, *first);
  33835. }
  33836. }
  33837. }
  33838. /**
  33839. * @brief Assigns an entity to a storage and constructs its object.
  33840. * @tparam Args Types of arguments to forward to the underlying storage.
  33841. * @param entt A valid identifier.
  33842. * @param args Parameters to forward to the underlying storage.
  33843. * @return A reference to the newly created object.
  33844. */
  33845. template<typename... Args>
  33846. decltype(auto) emplace(const entity_type entt, Args &&...args) {
  33847. underlying_type::emplace(entt, std::forward<Args>(args)...);
  33848. construction.publish(owner_or_assert(), entt);
  33849. return this->get(entt);
  33850. }
  33851. /**
  33852. * @brief Updates the instance assigned to a given entity in-place.
  33853. * @tparam Func Types of the function objects to invoke.
  33854. * @param entt A valid identifier.
  33855. * @param func Valid function objects.
  33856. * @return A reference to the patched instance.
  33857. */
  33858. template<typename... Func>
  33859. decltype(auto) patch(const entity_type entt, Func &&...func) {
  33860. underlying_type::patch(entt, std::forward<Func>(func)...);
  33861. update.publish(owner_or_assert(), entt);
  33862. return this->get(entt);
  33863. }
  33864. /**
  33865. * @brief Assigns one or more entities to a storage and constructs their
  33866. * objects from a given instance.
  33867. * @tparam It Type of input iterator.
  33868. * @tparam Args Types of arguments to forward to the underlying storage.
  33869. * @param first An iterator to the first element of the range of entities.
  33870. * @param last An iterator past the last element of the range of entities.
  33871. * @param args Parameters to use to forward to the underlying storage.
  33872. */
  33873. template<typename It, typename... Args>
  33874. void insert(It first, It last, Args &&...args) {
  33875. auto from = underlying_type::size();
  33876. underlying_type::insert(first, last, std::forward<Args>(args)...);
  33877. if(auto &reg = owner_or_assert(); !construction.empty()) {
  33878. // fine as long as insert passes force_back true to try_emplace
  33879. for(const auto to = underlying_type::size(); from != to; ++from) {
  33880. construction.publish(reg, underlying_type::operator[](from));
  33881. }
  33882. }
  33883. }
  33884. private:
  33885. basic_registry_type *owner;
  33886. sigh_type construction;
  33887. sigh_type destruction;
  33888. sigh_type update;
  33889. };
  33890. /**
  33891. * @brief Mixin type used to add _reactive_ support to storage types.
  33892. * @tparam Type Underlying storage type.
  33893. * @tparam Registry Basic registry type.
  33894. */
  33895. template<typename Type, typename Registry>
  33896. class basic_reactive_mixin final: public Type {
  33897. using underlying_type = Type;
  33898. using owner_type = Registry;
  33899. using alloc_traits = std::allocator_traits<typename underlying_type::allocator_type>;
  33900. using basic_registry_type = basic_registry<typename owner_type::entity_type, typename owner_type::allocator_type>;
  33901. using container_type = std::vector<connection, typename alloc_traits::template rebind_alloc<connection>>;
  33902. static_assert(std::is_base_of_v<basic_registry_type, owner_type>, "Invalid registry type");
  33903. [[nodiscard]] auto &owner_or_assert() const noexcept {
  33904. ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
  33905. return static_cast<owner_type &>(*owner);
  33906. }
  33907. void emplace_element(const Registry &, typename underlying_type::entity_type entity) {
  33908. if(!underlying_type::contains(entity)) {
  33909. underlying_type::emplace(entity);
  33910. }
  33911. }
  33912. private:
  33913. void bind_any(any value) noexcept final {
  33914. owner = any_cast<basic_registry_type>(&value);
  33915. if constexpr(!std::is_same_v<registry_type, basic_registry_type>) {
  33916. if(owner == nullptr) {
  33917. owner = any_cast<registry_type>(&value);
  33918. }
  33919. }
  33920. underlying_type::bind_any(std::move(value));
  33921. }
  33922. public:
  33923. /*! @brief Allocator type. */
  33924. using allocator_type = typename underlying_type::allocator_type;
  33925. /*! @brief Underlying entity identifier. */
  33926. using entity_type = typename underlying_type::entity_type;
  33927. /*! @brief Expected registry type. */
  33928. using registry_type = owner_type;
  33929. /*! @brief Default constructor. */
  33930. basic_reactive_mixin()
  33931. : basic_reactive_mixin{allocator_type{}} {}
  33932. /**
  33933. * @brief Constructs an empty storage with a given allocator.
  33934. * @param allocator The allocator to use.
  33935. */
  33936. explicit basic_reactive_mixin(const allocator_type &allocator)
  33937. : underlying_type{allocator},
  33938. owner{},
  33939. conn{allocator} {
  33940. }
  33941. /*! @brief Default copy constructor, deleted on purpose. */
  33942. basic_reactive_mixin(const basic_reactive_mixin &) = delete;
  33943. /**
  33944. * @brief Move constructor.
  33945. * @param other The instance to move from.
  33946. */
  33947. basic_reactive_mixin(basic_reactive_mixin &&other) noexcept
  33948. : underlying_type{static_cast<underlying_type &&>(other)},
  33949. owner{other.owner},
  33950. conn{std::move(other.conn)} {
  33951. }
  33952. /**
  33953. * @brief Allocator-extended move constructor.
  33954. * @param other The instance to move from.
  33955. * @param allocator The allocator to use.
  33956. */
  33957. basic_reactive_mixin(basic_reactive_mixin &&other, const allocator_type &allocator)
  33958. : underlying_type{static_cast<underlying_type &&>(other), allocator},
  33959. owner{other.owner},
  33960. conn{std::move(other.conn), allocator} {
  33961. }
  33962. /*! @brief Default destructor. */
  33963. ~basic_reactive_mixin() override = default;
  33964. /**
  33965. * @brief Default copy assignment operator, deleted on purpose.
  33966. * @return This mixin.
  33967. */
  33968. basic_reactive_mixin &operator=(const basic_reactive_mixin &) = delete;
  33969. /**
  33970. * @brief Move assignment operator.
  33971. * @param other The instance to move from.
  33972. * @return This mixin.
  33973. */
  33974. basic_reactive_mixin &operator=(basic_reactive_mixin &&other) noexcept {
  33975. underlying_type::swap(other);
  33976. return *this;
  33977. }
  33978. /**
  33979. * @brief Makes storage _react_ to creation of objects of the given type.
  33980. * @tparam Clazz Type of element to _react_ to.
  33981. * @tparam Candidate Function to use to _react_ to the event.
  33982. * @param id Optional name used to map the storage within the registry.
  33983. * @return This mixin.
  33984. */
  33985. template<typename Clazz, auto Candidate = &basic_reactive_mixin::emplace_element>
  33986. basic_reactive_mixin &on_construct(const id_type id = type_hash<Clazz>::value()) {
  33987. auto curr = owner_or_assert().template storage<Clazz>(id).on_construct().template connect<Candidate>(*this);
  33988. conn.push_back(std::move(curr));
  33989. return *this;
  33990. }
  33991. /**
  33992. * @brief Makes storage _react_ to update of objects of the given type.
  33993. * @tparam Clazz Type of element to _react_ to.
  33994. * @tparam Candidate Function to use to _react_ to the event.
  33995. * @param id Optional name used to map the storage within the registry.
  33996. * @return This mixin.
  33997. */
  33998. template<typename Clazz, auto Candidate = &basic_reactive_mixin::emplace_element>
  33999. basic_reactive_mixin &on_update(const id_type id = type_hash<Clazz>::value()) {
  34000. auto curr = owner_or_assert().template storage<Clazz>(id).on_update().template connect<Candidate>(*this);
  34001. conn.push_back(std::move(curr));
  34002. return *this;
  34003. }
  34004. /**
  34005. * @brief Makes storage _react_ to destruction of objects of the given type.
  34006. * @tparam Clazz Type of element to _react_ to.
  34007. * @tparam Candidate Function to use to _react_ to the event.
  34008. * @param id Optional name used to map the storage within the registry.
  34009. * @return This mixin.
  34010. */
  34011. template<typename Clazz, auto Candidate = &basic_reactive_mixin::emplace_element>
  34012. basic_reactive_mixin &on_destroy(const id_type id = type_hash<Clazz>::value()) {
  34013. auto curr = owner_or_assert().template storage<Clazz>(id).on_destroy().template connect<Candidate>(*this);
  34014. conn.push_back(std::move(curr));
  34015. return *this;
  34016. }
  34017. /**
  34018. * @brief Checks if a mixin refers to a valid registry.
  34019. * @return True if the mixin refers to a valid registry, false otherwise.
  34020. */
  34021. [[nodiscard]] explicit operator bool() const noexcept {
  34022. return (owner != nullptr);
  34023. }
  34024. /**
  34025. * @brief Returns a pointer to the underlying registry, if any.
  34026. * @return A pointer to the underlying registry, if any.
  34027. */
  34028. [[nodiscard]] const registry_type &registry() const noexcept {
  34029. return owner_or_assert();
  34030. }
  34031. /*! @copydoc registry */
  34032. [[nodiscard]] registry_type &registry() noexcept {
  34033. return owner_or_assert();
  34034. }
  34035. /**
  34036. * @brief Returns a view that is filtered by the underlying storage.
  34037. * @tparam Get Types of elements used to construct the view.
  34038. * @tparam Exclude Types of elements used to filter the view.
  34039. * @return A newly created view.
  34040. */
  34041. template<typename... Get, typename... Exclude>
  34042. [[nodiscard]] basic_view<get_t<const basic_reactive_mixin, typename basic_registry_type::template storage_for_type<const Get>...>, exclude_t<typename basic_registry_type::template storage_for_type<const Exclude>...>>
  34043. view(exclude_t<Exclude...> = exclude_t{}) const {
  34044. const owner_type &parent = owner_or_assert();
  34045. basic_view<get_t<const basic_reactive_mixin, typename basic_registry_type::template storage_for_type<const Get>...>, exclude_t<typename basic_registry_type::template storage_for_type<const Exclude>...>> elem{};
  34046. [&elem](const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }(parent.template storage<std::remove_const_t<Exclude>>()..., parent.template storage<std::remove_const_t<Get>>()..., this);
  34047. return elem;
  34048. }
  34049. /*! @copydoc view */
  34050. template<typename... Get, typename... Exclude>
  34051. [[nodiscard]] basic_view<get_t<const basic_reactive_mixin, typename basic_registry_type::template storage_for_type<Get>...>, exclude_t<typename basic_registry_type::template storage_for_type<Exclude>...>>
  34052. view(exclude_t<Exclude...> = exclude_t{}) {
  34053. std::conditional_t<((std::is_const_v<Get> && ...) && (std::is_const_v<Exclude> && ...)), const owner_type, owner_type> &parent = owner_or_assert();
  34054. return {*this, parent.template storage<std::remove_const_t<Get>>()..., parent.template storage<std::remove_const_t<Exclude>>()...};
  34055. }
  34056. /*! @brief Releases all connections to the underlying registry, if any. */
  34057. void reset() {
  34058. for(auto &&curr: conn) {
  34059. curr.release();
  34060. }
  34061. conn.clear();
  34062. }
  34063. private:
  34064. basic_registry_type *owner;
  34065. container_type conn;
  34066. };
  34067. } // namespace entt
  34068. #endif
  34069. // #include "sparse_set.hpp"
  34070. // #include "storage.hpp"
  34071. // #include "view.hpp"
  34072. namespace entt {
  34073. /*! @cond TURN_OFF_DOXYGEN */
  34074. namespace internal {
  34075. template<typename It>
  34076. class registry_storage_iterator final {
  34077. template<typename Other>
  34078. friend class registry_storage_iterator;
  34079. using mapped_type = std::remove_reference_t<decltype(std::declval<It>()->second)>;
  34080. public:
  34081. using value_type = std::pair<id_type, constness_as_t<typename mapped_type::element_type, mapped_type> &>;
  34082. using pointer = input_iterator_pointer<value_type>;
  34083. using reference = value_type;
  34084. using difference_type = std::ptrdiff_t;
  34085. using iterator_category = std::input_iterator_tag;
  34086. using iterator_concept = std::random_access_iterator_tag;
  34087. constexpr registry_storage_iterator() noexcept
  34088. : it{} {}
  34089. constexpr registry_storage_iterator(It iter) noexcept
  34090. : it{iter} {}
  34091. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  34092. constexpr registry_storage_iterator(const registry_storage_iterator<Other> &other) noexcept
  34093. : registry_storage_iterator{other.it} {}
  34094. constexpr registry_storage_iterator &operator++() noexcept {
  34095. return ++it, *this;
  34096. }
  34097. constexpr registry_storage_iterator operator++(int) noexcept {
  34098. const registry_storage_iterator orig = *this;
  34099. return ++(*this), orig;
  34100. }
  34101. constexpr registry_storage_iterator &operator--() noexcept {
  34102. return --it, *this;
  34103. }
  34104. constexpr registry_storage_iterator operator--(int) noexcept {
  34105. const registry_storage_iterator orig = *this;
  34106. return operator--(), orig;
  34107. }
  34108. constexpr registry_storage_iterator &operator+=(const difference_type value) noexcept {
  34109. it += value;
  34110. return *this;
  34111. }
  34112. constexpr registry_storage_iterator operator+(const difference_type value) const noexcept {
  34113. registry_storage_iterator copy = *this;
  34114. return (copy += value);
  34115. }
  34116. constexpr registry_storage_iterator &operator-=(const difference_type value) noexcept {
  34117. return (*this += -value);
  34118. }
  34119. constexpr registry_storage_iterator operator-(const difference_type value) const noexcept {
  34120. return (*this + -value);
  34121. }
  34122. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  34123. return {it[value].first, *it[value].second};
  34124. }
  34125. [[nodiscard]] constexpr reference operator*() const noexcept {
  34126. return operator[](0);
  34127. }
  34128. [[nodiscard]] constexpr pointer operator->() const noexcept {
  34129. return operator*();
  34130. }
  34131. template<typename Lhs, typename Rhs>
  34132. friend constexpr std::ptrdiff_t operator-(const registry_storage_iterator<Lhs> &, const registry_storage_iterator<Rhs> &) noexcept;
  34133. template<typename Lhs, typename Rhs>
  34134. friend constexpr bool operator==(const registry_storage_iterator<Lhs> &, const registry_storage_iterator<Rhs> &) noexcept;
  34135. template<typename Lhs, typename Rhs>
  34136. friend constexpr bool operator<(const registry_storage_iterator<Lhs> &, const registry_storage_iterator<Rhs> &) noexcept;
  34137. private:
  34138. It it;
  34139. };
  34140. template<typename Lhs, typename Rhs>
  34141. [[nodiscard]] constexpr std::ptrdiff_t operator-(const registry_storage_iterator<Lhs> &lhs, const registry_storage_iterator<Rhs> &rhs) noexcept {
  34142. return lhs.it - rhs.it;
  34143. }
  34144. template<typename Lhs, typename Rhs>
  34145. [[nodiscard]] constexpr bool operator==(const registry_storage_iterator<Lhs> &lhs, const registry_storage_iterator<Rhs> &rhs) noexcept {
  34146. return lhs.it == rhs.it;
  34147. }
  34148. template<typename Lhs, typename Rhs>
  34149. [[nodiscard]] constexpr bool operator!=(const registry_storage_iterator<Lhs> &lhs, const registry_storage_iterator<Rhs> &rhs) noexcept {
  34150. return !(lhs == rhs);
  34151. }
  34152. template<typename Lhs, typename Rhs>
  34153. [[nodiscard]] constexpr bool operator<(const registry_storage_iterator<Lhs> &lhs, const registry_storage_iterator<Rhs> &rhs) noexcept {
  34154. return lhs.it < rhs.it;
  34155. }
  34156. template<typename Lhs, typename Rhs>
  34157. [[nodiscard]] constexpr bool operator>(const registry_storage_iterator<Lhs> &lhs, const registry_storage_iterator<Rhs> &rhs) noexcept {
  34158. return rhs < lhs;
  34159. }
  34160. template<typename Lhs, typename Rhs>
  34161. [[nodiscard]] constexpr bool operator<=(const registry_storage_iterator<Lhs> &lhs, const registry_storage_iterator<Rhs> &rhs) noexcept {
  34162. return !(lhs > rhs);
  34163. }
  34164. template<typename Lhs, typename Rhs>
  34165. [[nodiscard]] constexpr bool operator>=(const registry_storage_iterator<Lhs> &lhs, const registry_storage_iterator<Rhs> &rhs) noexcept {
  34166. return !(lhs < rhs);
  34167. }
  34168. template<typename Allocator>
  34169. class registry_context {
  34170. using alloc_traits = std::allocator_traits<Allocator>;
  34171. using allocator_type = typename alloc_traits::template rebind_alloc<std::pair<const id_type, basic_any<0u>>>;
  34172. public:
  34173. explicit registry_context(const allocator_type &allocator)
  34174. : ctx{allocator} {}
  34175. void clear() noexcept {
  34176. ctx.clear();
  34177. }
  34178. template<typename Type, typename... Args>
  34179. Type &emplace_as(const id_type id, Args &&...args) {
  34180. return any_cast<Type &>(ctx.try_emplace(id, std::in_place_type<Type>, std::forward<Args>(args)...).first->second);
  34181. }
  34182. template<typename Type, typename... Args>
  34183. Type &emplace(Args &&...args) {
  34184. return emplace_as<Type>(type_id<Type>().hash(), std::forward<Args>(args)...);
  34185. }
  34186. template<typename Type>
  34187. Type &insert_or_assign(const id_type id, Type &&value) {
  34188. return any_cast<std::remove_const_t<std::remove_reference_t<Type>> &>(ctx.insert_or_assign(id, std::forward<Type>(value)).first->second);
  34189. }
  34190. template<typename Type>
  34191. Type &insert_or_assign(Type &&value) {
  34192. return insert_or_assign(type_id<Type>().hash(), std::forward<Type>(value));
  34193. }
  34194. template<typename Type>
  34195. bool erase(const id_type id = type_id<Type>().hash()) {
  34196. const auto it = ctx.find(id);
  34197. return it != ctx.end() && it->second.info() == type_id<Type>() ? (ctx.erase(it), true) : false;
  34198. }
  34199. template<typename Type>
  34200. [[nodiscard]] const Type &get(const id_type id = type_id<Type>().hash()) const {
  34201. return any_cast<const Type &>(ctx.at(id));
  34202. }
  34203. template<typename Type>
  34204. [[nodiscard]] Type &get(const id_type id = type_id<Type>().hash()) {
  34205. return any_cast<Type &>(ctx.at(id));
  34206. }
  34207. template<typename Type>
  34208. [[nodiscard]] const Type *find(const id_type id = type_id<Type>().hash()) const {
  34209. const auto it = ctx.find(id);
  34210. return it != ctx.cend() ? any_cast<const Type>(&it->second) : nullptr;
  34211. }
  34212. template<typename Type>
  34213. [[nodiscard]] Type *find(const id_type id = type_id<Type>().hash()) {
  34214. const auto it = ctx.find(id);
  34215. return it != ctx.end() ? any_cast<Type>(&it->second) : nullptr;
  34216. }
  34217. template<typename Type>
  34218. [[nodiscard]] bool contains(const id_type id = type_id<Type>().hash()) const {
  34219. const auto it = ctx.find(id);
  34220. return it != ctx.cend() && it->second.info() == type_id<Type>();
  34221. }
  34222. private:
  34223. dense_map<id_type, basic_any<0u>, identity, std::equal_to<>, allocator_type> ctx;
  34224. };
  34225. } // namespace internal
  34226. /*! @endcond */
  34227. /**
  34228. * @brief Fast and reliable entity-component system.
  34229. * @tparam Entity A valid entity type.
  34230. * @tparam Allocator Type of allocator used to manage memory and elements.
  34231. */
  34232. template<typename Entity, typename Allocator>
  34233. class basic_registry {
  34234. using base_type = basic_sparse_set<Entity, Allocator>;
  34235. using alloc_traits = std::allocator_traits<Allocator>;
  34236. static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");
  34237. // std::shared_ptr because of its type erased allocator which is useful here
  34238. using pool_container_type = dense_map<id_type, std::shared_ptr<base_type>, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc<std::pair<const id_type, std::shared_ptr<base_type>>>>;
  34239. using group_container_type = dense_map<id_type, std::shared_ptr<internal::group_descriptor>, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc<std::pair<const id_type, std::shared_ptr<internal::group_descriptor>>>>;
  34240. using traits_type = entt_traits<Entity>;
  34241. template<typename Type>
  34242. [[nodiscard]] auto &assure([[maybe_unused]] const id_type id = type_hash<Type>::value()) {
  34243. static_assert(std::is_same_v<Type, std::decay_t<Type>>, "Non-decayed types not allowed");
  34244. if constexpr(std::is_same_v<Type, entity_type>) {
  34245. ENTT_ASSERT(id == type_hash<Type>::value(), "User entity storage not allowed");
  34246. return entities;
  34247. } else {
  34248. using storage_type = storage_for_type<Type>;
  34249. if(auto it = pools.find(id); it != pools.cend()) {
  34250. ENTT_ASSERT(it->second->info() == type_id<Type>(), "Unexpected type");
  34251. return static_cast<storage_type &>(*it->second);
  34252. }
  34253. using alloc_type = typename storage_type::allocator_type;
  34254. typename pool_container_type::mapped_type cpool{};
  34255. if constexpr(std::is_void_v<Type> && !std::is_constructible_v<alloc_type, allocator_type>) {
  34256. // std::allocator<void> has no cross constructors (waiting for C++20)
  34257. cpool = std::allocate_shared<storage_type>(get_allocator(), alloc_type{});
  34258. } else {
  34259. cpool = std::allocate_shared<storage_type>(get_allocator(), get_allocator());
  34260. }
  34261. pools.emplace(id, cpool);
  34262. cpool->bind(*this);
  34263. return static_cast<storage_type &>(*cpool);
  34264. }
  34265. }
  34266. template<typename Type>
  34267. [[nodiscard]] const auto *assure([[maybe_unused]] const id_type id = type_hash<Type>::value()) const {
  34268. static_assert(std::is_same_v<Type, std::decay_t<Type>>, "Non-decayed types not allowed");
  34269. if constexpr(std::is_same_v<Type, entity_type>) {
  34270. ENTT_ASSERT(id == type_hash<Type>::value(), "User entity storage not allowed");
  34271. return &entities;
  34272. } else {
  34273. if(const auto it = pools.find(id); it != pools.cend()) {
  34274. ENTT_ASSERT(it->second->info() == type_id<Type>(), "Unexpected type");
  34275. return static_cast<const storage_for_type<Type> *>(it->second.get());
  34276. }
  34277. return static_cast<const storage_for_type<Type> *>(nullptr);
  34278. }
  34279. }
  34280. void rebind() {
  34281. entities.bind(*this);
  34282. for(auto &&curr: pools) {
  34283. curr.second->bind(*this);
  34284. }
  34285. }
  34286. public:
  34287. /*! @brief Allocator type. */
  34288. using allocator_type = Allocator;
  34289. /*! @brief Underlying entity identifier. */
  34290. using entity_type = typename traits_type::value_type;
  34291. /*! @brief Underlying version type. */
  34292. using version_type = typename traits_type::version_type;
  34293. /*! @brief Unsigned integer type. */
  34294. using size_type = std::size_t;
  34295. /*! @brief Common type among all storage types. */
  34296. using common_type = base_type;
  34297. /*! @brief Context type. */
  34298. using context = internal::registry_context<allocator_type>;
  34299. /*! @brief Iterable registry type. */
  34300. using iterable = iterable_adaptor<internal::registry_storage_iterator<typename pool_container_type::iterator>>;
  34301. /*! @brief Constant iterable registry type. */
  34302. using const_iterable = iterable_adaptor<internal::registry_storage_iterator<typename pool_container_type::const_iterator>>;
  34303. /**
  34304. * @copybrief storage_for
  34305. * @tparam Type Storage value type, eventually const.
  34306. */
  34307. template<typename Type>
  34308. using storage_for_type = typename storage_for<Type, Entity, typename alloc_traits::template rebind_alloc<std::remove_const_t<Type>>>::type;
  34309. /*! @brief Default constructor. */
  34310. basic_registry()
  34311. : basic_registry{allocator_type{}} {}
  34312. /**
  34313. * @brief Constructs an empty registry with a given allocator.
  34314. * @param allocator The allocator to use.
  34315. */
  34316. explicit basic_registry(const allocator_type &allocator)
  34317. : basic_registry{0u, allocator} {}
  34318. /**
  34319. * @brief Allocates enough memory upon construction to store `count` pools.
  34320. * @param count The number of pools to allocate memory for.
  34321. * @param allocator The allocator to use.
  34322. */
  34323. basic_registry(const size_type count, const allocator_type &allocator = allocator_type{})
  34324. : vars{allocator},
  34325. pools{allocator},
  34326. groups{allocator},
  34327. entities{allocator} {
  34328. pools.reserve(count);
  34329. rebind();
  34330. }
  34331. /*! @brief Default copy constructor, deleted on purpose. */
  34332. basic_registry(const basic_registry &) = delete;
  34333. /**
  34334. * @brief Move constructor.
  34335. * @param other The instance to move from.
  34336. */
  34337. basic_registry(basic_registry &&other) noexcept
  34338. : vars{std::move(other.vars)},
  34339. pools{std::move(other.pools)},
  34340. groups{std::move(other.groups)},
  34341. entities{std::move(other.entities)} {
  34342. rebind();
  34343. }
  34344. /*! @brief Default destructor. */
  34345. ~basic_registry() = default;
  34346. /**
  34347. * @brief Default copy assignment operator, deleted on purpose.
  34348. * @return This mixin.
  34349. */
  34350. basic_registry &operator=(const basic_registry &) = delete;
  34351. /**
  34352. * @brief Move assignment operator.
  34353. * @param other The instance to move from.
  34354. * @return This registry.
  34355. */
  34356. basic_registry &operator=(basic_registry &&other) noexcept {
  34357. swap(other);
  34358. return *this;
  34359. }
  34360. /**
  34361. * @brief Exchanges the contents with those of a given registry.
  34362. * @param other Registry to exchange the content with.
  34363. */
  34364. void swap(basic_registry &other) noexcept {
  34365. using std::swap;
  34366. swap(vars, other.vars);
  34367. swap(pools, other.pools);
  34368. swap(groups, other.groups);
  34369. swap(entities, other.entities);
  34370. rebind();
  34371. other.rebind();
  34372. }
  34373. /**
  34374. * @brief Returns the associated allocator.
  34375. * @return The associated allocator.
  34376. */
  34377. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  34378. return entities.get_allocator();
  34379. }
  34380. /**
  34381. * @brief Returns an iterable object to use to _visit_ a registry.
  34382. *
  34383. * The iterable object returns a pair that contains the name and a reference
  34384. * to the current storage.
  34385. *
  34386. * @return An iterable object to use to _visit_ the registry.
  34387. */
  34388. [[nodiscard]] iterable storage() noexcept {
  34389. return iterable{pools.begin(), pools.end()};
  34390. }
  34391. /*! @copydoc storage */
  34392. [[nodiscard]] const_iterable storage() const noexcept {
  34393. return const_iterable{pools.cbegin(), pools.cend()};
  34394. }
  34395. /**
  34396. * @brief Finds the storage associated with a given name, if any.
  34397. * @param id Name used to map the storage within the registry.
  34398. * @return A pointer to the storage if it exists, a null pointer otherwise.
  34399. */
  34400. [[nodiscard]] common_type *storage(const id_type id) {
  34401. return const_cast<common_type *>(std::as_const(*this).storage(id));
  34402. }
  34403. /**
  34404. * @brief Finds the storage associated with a given name, if any.
  34405. * @param id Name used to map the storage within the registry.
  34406. * @return A pointer to the storage if it exists, a null pointer otherwise.
  34407. */
  34408. [[nodiscard]] const common_type *storage(const id_type id) const {
  34409. const auto it = pools.find(id);
  34410. return it == pools.cend() ? nullptr : it->second.get();
  34411. }
  34412. /**
  34413. * @brief Returns the storage for a given element type.
  34414. * @tparam Type Type of element of which to return the storage.
  34415. * @param id Optional name used to map the storage within the registry.
  34416. * @return The storage for the given element type.
  34417. */
  34418. template<typename Type>
  34419. storage_for_type<Type> &storage(const id_type id = type_hash<Type>::value()) {
  34420. return assure<std::remove_const_t<Type>>(id);
  34421. }
  34422. /**
  34423. * @brief Returns the storage for a given element type, if any.
  34424. * @tparam Type Type of element of which to return the storage.
  34425. * @param id Optional name used to map the storage within the registry.
  34426. * @return The storage for the given element type.
  34427. */
  34428. template<typename Type>
  34429. [[nodiscard]] const storage_for_type<Type> *storage(const id_type id = type_hash<Type>::value()) const {
  34430. return assure<std::remove_const_t<Type>>(id);
  34431. }
  34432. /**
  34433. * @brief Discards the storage associated with a given name, if any.
  34434. * @param id Name used to map the storage within the registry.
  34435. * @return True in case of success, false otherwise.
  34436. */
  34437. bool reset(const id_type id) {
  34438. ENTT_ASSERT(id != type_hash<entity_type>::value(), "Cannot reset entity storage");
  34439. return !(pools.erase(id) == 0u);
  34440. }
  34441. /**
  34442. * @brief Checks if an identifier refers to a valid entity.
  34443. * @param entt An identifier, either valid or not.
  34444. * @return True if the identifier is valid, false otherwise.
  34445. */
  34446. [[nodiscard]] bool valid(const entity_type entt) const {
  34447. return static_cast<size_type>(entities.find(entt).index()) < entities.free_list();
  34448. }
  34449. /**
  34450. * @brief Returns the actual version for an identifier.
  34451. * @param entt A valid identifier.
  34452. * @return The version for the given identifier if valid, the tombstone
  34453. * version otherwise.
  34454. */
  34455. [[nodiscard]] version_type current(const entity_type entt) const {
  34456. return entities.current(entt);
  34457. }
  34458. /**
  34459. * @brief Creates a new entity or recycles a destroyed one.
  34460. * @return A valid identifier.
  34461. */
  34462. [[nodiscard]] entity_type create() {
  34463. return entities.generate();
  34464. }
  34465. /**
  34466. * @copybrief create
  34467. *
  34468. * If the requested entity isn't in use, the suggested identifier is used.
  34469. * Otherwise, a new identifier is generated.
  34470. *
  34471. * @param hint Required identifier.
  34472. * @return A valid identifier.
  34473. */
  34474. [[nodiscard]] entity_type create(const entity_type hint) {
  34475. return entities.generate(hint);
  34476. }
  34477. /**
  34478. * @brief Assigns each element in a range an identifier.
  34479. *
  34480. * @sa create
  34481. *
  34482. * @tparam It Type of forward iterator.
  34483. * @param first An iterator to the first element of the range to generate.
  34484. * @param last An iterator past the last element of the range to generate.
  34485. */
  34486. template<typename It>
  34487. void create(It first, It last) {
  34488. entities.generate(std::move(first), std::move(last));
  34489. }
  34490. /**
  34491. * @brief Destroys an entity and releases its identifier.
  34492. *
  34493. * @warning
  34494. * Adding or removing elements to an entity that is being destroyed can
  34495. * result in undefined behavior.
  34496. *
  34497. * @param entt A valid identifier.
  34498. * @return The version of the recycled entity.
  34499. */
  34500. version_type destroy(const entity_type entt) {
  34501. for(size_type pos = pools.size(); pos != 0u; --pos) {
  34502. pools.begin()[static_cast<typename pool_container_type::difference_type>(pos - 1u)].second->remove(entt);
  34503. }
  34504. entities.erase(entt);
  34505. return entities.current(entt);
  34506. }
  34507. /**
  34508. * @brief Destroys an entity and releases its identifier.
  34509. *
  34510. * The suggested version or the valid version closest to the suggested one
  34511. * is used instead of the implicitly generated version.
  34512. *
  34513. * @sa destroy
  34514. *
  34515. * @param entt A valid identifier.
  34516. * @param version A desired version upon destruction.
  34517. * @return The version actually assigned to the entity.
  34518. */
  34519. version_type destroy(const entity_type entt, const version_type version) {
  34520. destroy(entt);
  34521. const auto elem = traits_type::construct(traits_type::to_entity(entt), version);
  34522. return entities.bump((elem == tombstone) ? traits_type::next(elem) : elem);
  34523. }
  34524. /**
  34525. * @brief Destroys all entities in a range and releases their identifiers.
  34526. *
  34527. * @sa destroy
  34528. *
  34529. * @tparam It Type of input iterator.
  34530. * @param first An iterator to the first element of the range of entities.
  34531. * @param last An iterator past the last element of the range of entities.
  34532. */
  34533. template<typename It>
  34534. void destroy(It first, It last) {
  34535. const auto to = entities.sort_as(first, last);
  34536. const auto from = entities.cend() - static_cast<typename common_type::difference_type>(entities.free_list());
  34537. for(auto &&curr: pools) {
  34538. curr.second->remove(from, to);
  34539. }
  34540. entities.erase(from, to);
  34541. }
  34542. /**
  34543. * @brief Assigns the given element to an entity.
  34544. *
  34545. * The element must have a proper constructor or be of aggregate type.
  34546. *
  34547. * @warning
  34548. * Attempting to assign an element to an entity that already owns it results
  34549. * in undefined behavior.
  34550. *
  34551. * @tparam Type Type of element to create.
  34552. * @tparam Args Types of arguments to use to construct the element.
  34553. * @param entt A valid identifier.
  34554. * @param args Parameters to use to initialize the element.
  34555. * @return A reference to the newly created element.
  34556. */
  34557. template<typename Type, typename... Args>
  34558. decltype(auto) emplace(const entity_type entt, Args &&...args) {
  34559. ENTT_ASSERT(valid(entt), "Invalid entity");
  34560. return assure<Type>().emplace(entt, std::forward<Args>(args)...);
  34561. }
  34562. /**
  34563. * @brief Assigns each entity in a range the given element.
  34564. *
  34565. * @sa emplace
  34566. *
  34567. * @tparam Type Type of element to create.
  34568. * @tparam It Type of input iterator.
  34569. * @param first An iterator to the first element of the range of entities.
  34570. * @param last An iterator past the last element of the range of entities.
  34571. */
  34572. template<typename Type, typename It>
  34573. void insert(It first, It last) {
  34574. ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
  34575. assure<Type>().insert(std::move(first), std::move(last));
  34576. }
  34577. /**
  34578. * @brief Assigns each entity in a range the given element.
  34579. *
  34580. * @sa emplace
  34581. *
  34582. * @tparam Type Type of element to create.
  34583. * @tparam It Type of input iterator.
  34584. * @param first An iterator to the first element of the range of entities.
  34585. * @param last An iterator past the last element of the range of entities.
  34586. * @param value An instance of the element to assign.
  34587. */
  34588. template<typename Type, typename It>
  34589. void insert(It first, It last, const Type &value) {
  34590. ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
  34591. assure<Type>().insert(std::move(first), std::move(last), value);
  34592. }
  34593. /**
  34594. * @brief Assigns each entity in a range the given elements.
  34595. *
  34596. * @sa emplace
  34597. *
  34598. * @tparam Type Type of element to create.
  34599. * @tparam EIt Type of input iterator.
  34600. * @tparam CIt Type of input iterator.
  34601. * @param first An iterator to the first element of the range of entities.
  34602. * @param last An iterator past the last element of the range of entities.
  34603. * @param from An iterator to the first element of the range of elements.
  34604. */
  34605. template<typename Type, typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, Type>>>
  34606. void insert(EIt first, EIt last, CIt from) {
  34607. ENTT_ASSERT(std::all_of(first, last, [this](const auto entt) { return valid(entt); }), "Invalid entity");
  34608. assure<Type>().insert(first, last, from);
  34609. }
  34610. /**
  34611. * @brief Assigns or replaces the given element for an entity.
  34612. *
  34613. * @sa emplace
  34614. * @sa replace
  34615. *
  34616. * @tparam Type Type of element to assign or replace.
  34617. * @tparam Args Types of arguments to use to construct the element.
  34618. * @param entt A valid identifier.
  34619. * @param args Parameters to use to initialize the element.
  34620. * @return A reference to the newly created element.
  34621. */
  34622. template<typename Type, typename... Args>
  34623. decltype(auto) emplace_or_replace(const entity_type entt, Args &&...args) {
  34624. auto &cpool = assure<Type>();
  34625. ENTT_ASSERT(valid(entt), "Invalid entity");
  34626. return cpool.contains(entt) ? cpool.patch(entt, [&args...](auto &...curr) { ((curr = Type{std::forward<Args>(args)...}), ...); }) : cpool.emplace(entt, std::forward<Args>(args)...);
  34627. }
  34628. /**
  34629. * @brief Patches the given element for an entity.
  34630. *
  34631. * The signature of the function should be equivalent to the following:
  34632. *
  34633. * @code{.cpp}
  34634. * void(Type &);
  34635. * @endcode
  34636. *
  34637. * @warning
  34638. * Attempting to patch an element of an entity that doesn't own it results
  34639. * in undefined behavior.
  34640. *
  34641. * @tparam Type Type of element to patch.
  34642. * @tparam Func Types of the function objects to invoke.
  34643. * @param entt A valid identifier.
  34644. * @param func Valid function objects.
  34645. * @return A reference to the patched element.
  34646. */
  34647. template<typename Type, typename... Func>
  34648. decltype(auto) patch(const entity_type entt, Func &&...func) {
  34649. return assure<Type>().patch(entt, std::forward<Func>(func)...);
  34650. }
  34651. /**
  34652. * @brief Replaces the given element for an entity.
  34653. *
  34654. * The element must have a proper constructor or be of aggregate type.
  34655. *
  34656. * @warning
  34657. * Attempting to replace an element of an entity that doesn't own it results
  34658. * in undefined behavior.
  34659. *
  34660. * @tparam Type Type of element to replace.
  34661. * @tparam Args Types of arguments to use to construct the element.
  34662. * @param entt A valid identifier.
  34663. * @param args Parameters to use to initialize the element.
  34664. * @return A reference to the element being replaced.
  34665. */
  34666. template<typename Type, typename... Args>
  34667. decltype(auto) replace(const entity_type entt, Args &&...args) {
  34668. return patch<Type>(entt, [&args...](auto &...curr) { ((curr = Type{std::forward<Args>(args)...}), ...); });
  34669. }
  34670. /**
  34671. * @brief Removes the given elements from an entity.
  34672. * @tparam Type Type of element to remove.
  34673. * @tparam Other Other types of elements to remove.
  34674. * @param entt A valid identifier.
  34675. * @return The number of elements actually removed.
  34676. */
  34677. template<typename Type, typename... Other>
  34678. size_type remove(const entity_type entt) {
  34679. return (assure<Type>().remove(entt) + ... + assure<Other>().remove(entt));
  34680. }
  34681. /**
  34682. * @brief Removes the given elements from all the entities in a range.
  34683. *
  34684. * @sa remove
  34685. *
  34686. * @tparam Type Type of element to remove.
  34687. * @tparam Other Other types of elements to remove.
  34688. * @tparam It Type of input iterator.
  34689. * @param first An iterator to the first element of the range of entities.
  34690. * @param last An iterator past the last element of the range of entities.
  34691. * @return The number of elements actually removed.
  34692. */
  34693. template<typename Type, typename... Other, typename It>
  34694. size_type remove(It first, It last) {
  34695. size_type count{};
  34696. if constexpr(std::is_same_v<It, typename common_type::iterator>) {
  34697. std::array cpools{static_cast<common_type *>(&assure<Type>()), static_cast<common_type *>(&assure<Other>())...};
  34698. for(auto from = cpools.begin(), to = cpools.end(); from != to; ++from) {
  34699. if constexpr(sizeof...(Other) != 0u) {
  34700. if((*from)->data() == first.data()) {
  34701. std::swap((*from), cpools.back());
  34702. }
  34703. }
  34704. count += (*from)->remove(first, last);
  34705. }
  34706. } else {
  34707. for(auto cpools = std::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
  34708. count += std::apply([entt = *first](auto &...curr) { return (curr.remove(entt) + ... + 0u); }, cpools);
  34709. }
  34710. }
  34711. return count;
  34712. }
  34713. /**
  34714. * @brief Erases the given elements from an entity.
  34715. *
  34716. * @warning
  34717. * Attempting to erase an element from an entity that doesn't own it results
  34718. * in undefined behavior.
  34719. *
  34720. * @tparam Type Types of elements to erase.
  34721. * @tparam Other Other types of elements to erase.
  34722. * @param entt A valid identifier.
  34723. */
  34724. template<typename Type, typename... Other>
  34725. void erase(const entity_type entt) {
  34726. (assure<Type>().erase(entt), (assure<Other>().erase(entt), ...));
  34727. }
  34728. /**
  34729. * @brief Erases the given elements from all the entities in a range.
  34730. *
  34731. * @sa erase
  34732. *
  34733. * @tparam Type Types of elements to erase.
  34734. * @tparam Other Other types of elements to erase.
  34735. * @tparam It Type of input iterator.
  34736. * @param first An iterator to the first element of the range of entities.
  34737. * @param last An iterator past the last element of the range of entities.
  34738. */
  34739. template<typename Type, typename... Other, typename It>
  34740. void erase(It first, It last) {
  34741. if constexpr(std::is_same_v<It, typename common_type::iterator>) {
  34742. std::array cpools{static_cast<common_type *>(&assure<Type>()), static_cast<common_type *>(&assure<Other>())...};
  34743. for(auto from = cpools.begin(), to = cpools.end(); from != to; ++from) {
  34744. if constexpr(sizeof...(Other) != 0u) {
  34745. if((*from)->data() == first.data()) {
  34746. std::swap(*from, cpools.back());
  34747. }
  34748. }
  34749. (*from)->erase(first, last);
  34750. }
  34751. } else {
  34752. for(auto cpools = std::forward_as_tuple(assure<Type>(), assure<Other>()...); first != last; ++first) {
  34753. std::apply([entt = *first](auto &...curr) { (curr.erase(entt), ...); }, cpools);
  34754. }
  34755. }
  34756. }
  34757. /**
  34758. * @brief Erases elements satisfying specific criteria from an entity.
  34759. *
  34760. * The function type is equivalent to:
  34761. *
  34762. * @code{.cpp}
  34763. * void(const id_type, typename basic_registry<Entity>::common_type &);
  34764. * @endcode
  34765. *
  34766. * Only storage where the entity exists are passed to the function.
  34767. *
  34768. * @tparam Func Type of the function object to invoke.
  34769. * @param entt A valid identifier.
  34770. * @param func A valid function object.
  34771. */
  34772. template<typename Func>
  34773. void erase_if(const entity_type entt, Func func) {
  34774. for(auto [id, cpool]: storage()) {
  34775. if(cpool.contains(entt) && func(id, std::as_const(cpool))) {
  34776. cpool.erase(entt);
  34777. }
  34778. }
  34779. }
  34780. /**
  34781. * @brief Removes all tombstones from a registry or only the pools for the
  34782. * given elements.
  34783. * @tparam Type Types of elements for which to clear all tombstones.
  34784. */
  34785. template<typename... Type>
  34786. void compact() {
  34787. if constexpr(sizeof...(Type) == 0u) {
  34788. for(auto &&curr: pools) {
  34789. curr.second->compact();
  34790. }
  34791. } else {
  34792. (assure<Type>().compact(), ...);
  34793. }
  34794. }
  34795. /**
  34796. * @brief Check if an entity is part of all the given storage.
  34797. * @tparam Type Type of storage to check for.
  34798. * @param entt A valid identifier.
  34799. * @return True if the entity is part of all the storage, false otherwise.
  34800. */
  34801. template<typename... Type>
  34802. [[nodiscard]] bool all_of([[maybe_unused]] const entity_type entt) const {
  34803. if constexpr(sizeof...(Type) == 1u) {
  34804. auto *cpool = assure<std::remove_const_t<Type>...>();
  34805. return cpool && cpool->contains(entt);
  34806. } else {
  34807. return (all_of<Type>(entt) && ...);
  34808. }
  34809. }
  34810. /**
  34811. * @brief Check if an entity is part of at least one given storage.
  34812. * @tparam Type Type of storage to check for.
  34813. * @param entt A valid identifier.
  34814. * @return True if the entity is part of at least one storage, false
  34815. * otherwise.
  34816. */
  34817. template<typename... Type>
  34818. [[nodiscard]] bool any_of([[maybe_unused]] const entity_type entt) const {
  34819. return (all_of<Type>(entt) || ...);
  34820. }
  34821. /**
  34822. * @brief Returns references to the given elements for an entity.
  34823. *
  34824. * @warning
  34825. * Attempting to get an element from an entity that doesn't own it results
  34826. * in undefined behavior.
  34827. *
  34828. * @tparam Type Types of elements to get.
  34829. * @param entt A valid identifier.
  34830. * @return References to the elements owned by the entity.
  34831. */
  34832. template<typename... Type>
  34833. [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entt) const {
  34834. if constexpr(sizeof...(Type) == 1u) {
  34835. return (assure<std::remove_const_t<Type>>()->get(entt), ...);
  34836. } else {
  34837. return std::forward_as_tuple(get<Type>(entt)...);
  34838. }
  34839. }
  34840. /*! @copydoc get */
  34841. template<typename... Type>
  34842. [[nodiscard]] decltype(auto) get([[maybe_unused]] const entity_type entt) {
  34843. if constexpr(sizeof...(Type) == 1u) {
  34844. return (static_cast<storage_for_type<Type> &>(assure<std::remove_const_t<Type>>()).get(entt), ...);
  34845. } else {
  34846. return std::forward_as_tuple(get<Type>(entt)...);
  34847. }
  34848. }
  34849. /**
  34850. * @brief Returns a reference to the given element for an entity.
  34851. *
  34852. * In case the entity doesn't own the element, the parameters provided are
  34853. * used to construct it.
  34854. *
  34855. * @sa get
  34856. * @sa emplace
  34857. *
  34858. * @tparam Type Type of element to get.
  34859. * @tparam Args Types of arguments to use to construct the element.
  34860. * @param entt A valid identifier.
  34861. * @param args Parameters to use to initialize the element.
  34862. * @return Reference to the element owned by the entity.
  34863. */
  34864. template<typename Type, typename... Args>
  34865. [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entt, Args &&...args) {
  34866. auto &cpool = assure<Type>();
  34867. ENTT_ASSERT(valid(entt), "Invalid entity");
  34868. return cpool.contains(entt) ? cpool.get(entt) : cpool.emplace(entt, std::forward<Args>(args)...);
  34869. }
  34870. /**
  34871. * @brief Returns pointers to the given elements for an entity.
  34872. *
  34873. * @note
  34874. * The registry retains ownership of the pointed-to elements.
  34875. *
  34876. * @tparam Type Types of elements to get.
  34877. * @param entt A valid identifier.
  34878. * @return Pointers to the elements owned by the entity.
  34879. */
  34880. template<typename... Type>
  34881. [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entt) const {
  34882. if constexpr(sizeof...(Type) == 1u) {
  34883. const auto *cpool = assure<std::remove_const_t<Type>...>();
  34884. return (cpool && cpool->contains(entt)) ? std::addressof(cpool->get(entt)) : nullptr;
  34885. } else {
  34886. return std::make_tuple(try_get<Type>(entt)...);
  34887. }
  34888. }
  34889. /*! @copydoc try_get */
  34890. template<typename... Type>
  34891. [[nodiscard]] auto try_get([[maybe_unused]] const entity_type entt) {
  34892. if constexpr(sizeof...(Type) == 1u) {
  34893. return (const_cast<Type *>(std::as_const(*this).template try_get<Type>(entt)), ...);
  34894. } else {
  34895. return std::make_tuple(try_get<Type>(entt)...);
  34896. }
  34897. }
  34898. /**
  34899. * @brief Clears a whole registry or the pools for the given elements.
  34900. * @tparam Type Types of elements to remove from their entities.
  34901. */
  34902. template<typename... Type>
  34903. void clear() {
  34904. if constexpr(sizeof...(Type) == 0u) {
  34905. for(size_type pos = pools.size(); pos; --pos) {
  34906. pools.begin()[static_cast<typename pool_container_type::difference_type>(pos - 1u)].second->clear();
  34907. }
  34908. const auto elem = entities.each();
  34909. entities.erase(elem.begin().base(), elem.end().base());
  34910. } else {
  34911. (assure<Type>().clear(), ...);
  34912. }
  34913. }
  34914. /**
  34915. * @brief Checks if an entity has elements assigned.
  34916. * @param entt A valid identifier.
  34917. * @return True if the entity has no elements assigned, false otherwise.
  34918. */
  34919. [[nodiscard]] bool orphan(const entity_type entt) const {
  34920. return std::none_of(pools.cbegin(), pools.cend(), [entt](auto &&curr) { return curr.second->contains(entt); });
  34921. }
  34922. /**
  34923. * @brief Returns a sink object for the given element.
  34924. *
  34925. * Use this function to receive notifications whenever a new instance of the
  34926. * given element is created and assigned to an entity.<br/>
  34927. * The function type for a listener is equivalent to:
  34928. *
  34929. * @code{.cpp}
  34930. * void(basic_registry<Entity> &, Entity);
  34931. * @endcode
  34932. *
  34933. * Listeners are invoked **after** assigning the element to the entity.
  34934. *
  34935. * @sa sink
  34936. *
  34937. * @tparam Type Type of element of which to get the sink.
  34938. * @param id Optional name used to map the storage within the registry.
  34939. * @return A temporary sink object.
  34940. */
  34941. template<typename Type>
  34942. [[nodiscard]] auto on_construct(const id_type id = type_hash<Type>::value()) {
  34943. return assure<Type>(id).on_construct();
  34944. }
  34945. /**
  34946. * @brief Returns a sink object for the given element.
  34947. *
  34948. * Use this function to receive notifications whenever an instance of the
  34949. * given element is explicitly updated.<br/>
  34950. * The function type for a listener is equivalent to:
  34951. *
  34952. * @code{.cpp}
  34953. * void(basic_registry<Entity> &, Entity);
  34954. * @endcode
  34955. *
  34956. * Listeners are invoked **after** updating the element.
  34957. *
  34958. * @sa sink
  34959. *
  34960. * @tparam Type Type of element of which to get the sink.
  34961. * @param id Optional name used to map the storage within the registry.
  34962. * @return A temporary sink object.
  34963. */
  34964. template<typename Type>
  34965. [[nodiscard]] auto on_update(const id_type id = type_hash<Type>::value()) {
  34966. return assure<Type>(id).on_update();
  34967. }
  34968. /**
  34969. * @brief Returns a sink object for the given element.
  34970. *
  34971. * Use this function to receive notifications whenever an instance of the
  34972. * given element is removed from an entity and thus destroyed.<br/>
  34973. * The function type for a listener is equivalent to:
  34974. *
  34975. * @code{.cpp}
  34976. * void(basic_registry<Entity> &, Entity);
  34977. * @endcode
  34978. *
  34979. * Listeners are invoked **before** removing the element from the entity.
  34980. *
  34981. * @sa sink
  34982. *
  34983. * @tparam Type Type of element of which to get the sink.
  34984. * @param id Optional name used to map the storage within the registry.
  34985. * @return A temporary sink object.
  34986. */
  34987. template<typename Type>
  34988. [[nodiscard]] auto on_destroy(const id_type id = type_hash<Type>::value()) {
  34989. return assure<Type>(id).on_destroy();
  34990. }
  34991. /**
  34992. * @brief Returns a view for the given elements.
  34993. * @tparam Type Type of element used to construct the view.
  34994. * @tparam Other Other types of elements used to construct the view.
  34995. * @tparam Exclude Types of elements used to filter the view.
  34996. * @return A newly created view.
  34997. */
  34998. template<typename Type, typename... Other, typename... Exclude>
  34999. [[nodiscard]] basic_view<get_t<storage_for_type<const Type>, storage_for_type<const Other>...>, exclude_t<storage_for_type<const Exclude>...>>
  35000. view(exclude_t<Exclude...> = exclude_t{}) const {
  35001. basic_view<get_t<storage_for_type<const Type>, storage_for_type<const Other>...>, exclude_t<storage_for_type<const Exclude>...>> elem{};
  35002. [&elem](const auto *...curr) { ((curr ? elem.storage(*curr) : void()), ...); }(assure<std::remove_const_t<Exclude>>()..., assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Type>>());
  35003. return elem;
  35004. }
  35005. /*! @copydoc view */
  35006. template<typename Type, typename... Other, typename... Exclude>
  35007. [[nodiscard]] basic_view<get_t<storage_for_type<Type>, storage_for_type<Other>...>, exclude_t<storage_for_type<Exclude>...>>
  35008. view(exclude_t<Exclude...> = exclude_t{}) {
  35009. return {assure<std::remove_const_t<Type>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...};
  35010. }
  35011. /**
  35012. * @brief Returns a group for the given elements.
  35013. * @tparam Owned Types of storage _owned_ by the group.
  35014. * @tparam Get Types of storage _observed_ by the group, if any.
  35015. * @tparam Exclude Types of storage used to filter the group, if any.
  35016. * @return A newly created group.
  35017. */
  35018. template<typename... Owned, typename... Get, typename... Exclude>
  35019. basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>
  35020. group(get_t<Get...> = get_t{}, exclude_t<Exclude...> = exclude_t{}) {
  35021. using group_type = basic_group<owned_t<storage_for_type<Owned>...>, get_t<storage_for_type<Get>...>, exclude_t<storage_for_type<Exclude>...>>;
  35022. using handler_type = typename group_type::handler;
  35023. if(auto it = groups.find(group_type::group_id()); it != groups.cend()) {
  35024. return {*std::static_pointer_cast<handler_type>(it->second)};
  35025. }
  35026. std::shared_ptr<handler_type> handler{};
  35027. if constexpr(sizeof...(Owned) == 0u) {
  35028. handler = std::allocate_shared<handler_type>(get_allocator(), get_allocator(), std::forward_as_tuple(assure<std::remove_const_t<Get>>()...), std::forward_as_tuple(assure<std::remove_const_t<Exclude>>()...));
  35029. } else {
  35030. handler = std::allocate_shared<handler_type>(get_allocator(), std::forward_as_tuple(assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()...), std::forward_as_tuple(assure<std::remove_const_t<Exclude>>()...));
  35031. ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [](const auto &data) { return !(data.second->owned(type_id<Owned>().hash()) || ...); }), "Conflicting groups");
  35032. }
  35033. groups.emplace(group_type::group_id(), handler);
  35034. return {*handler};
  35035. }
  35036. /*! @copydoc group */
  35037. template<typename... Owned, typename... Get, typename... Exclude>
  35038. [[nodiscard]] basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>>
  35039. group_if_exists(get_t<Get...> = get_t{}, exclude_t<Exclude...> = exclude_t{}) const {
  35040. using group_type = basic_group<owned_t<storage_for_type<const Owned>...>, get_t<storage_for_type<const Get>...>, exclude_t<storage_for_type<const Exclude>...>>;
  35041. using handler_type = typename group_type::handler;
  35042. if(auto it = groups.find(group_type::group_id()); it != groups.cend()) {
  35043. return {*std::static_pointer_cast<handler_type>(it->second)};
  35044. }
  35045. return {};
  35046. }
  35047. /**
  35048. * @brief Checks whether the given elements belong to any group.
  35049. * @tparam Type Types of elements in which one is interested.
  35050. * @return True if the pools of the given elements are _free_, false
  35051. * otherwise.
  35052. */
  35053. template<typename... Type>
  35054. [[nodiscard]] bool owned() const {
  35055. return std::any_of(groups.cbegin(), groups.cend(), [](auto &&data) { return (data.second->owned(type_id<Type>().hash()) || ...); });
  35056. }
  35057. /**
  35058. * @brief Sorts the elements of a given element.
  35059. *
  35060. * The comparison function object returns `true` if the first element is
  35061. * _less_ than the second one, `false` otherwise. Its signature is also
  35062. * equivalent to one of the following:
  35063. *
  35064. * @code{.cpp}
  35065. * bool(const Entity, const Entity);
  35066. * bool(const Type &, const Type &);
  35067. * @endcode
  35068. *
  35069. * Moreover, it shall induce a _strict weak ordering_ on the values.<br/>
  35070. * The sort function object offers an `operator()` that accepts:
  35071. *
  35072. * * An iterator to the first element of the range to sort.
  35073. * * An iterator past the last element of the range to sort.
  35074. * * A comparison function object to use to compare the elements.
  35075. *
  35076. * The comparison function object hasn't necessarily the type of the one
  35077. * passed along with the other parameters to this member function.
  35078. *
  35079. * @warning
  35080. * Pools of elements owned by a group cannot be sorted.
  35081. *
  35082. * @tparam Type Type of elements to sort.
  35083. * @tparam Compare Type of comparison function object.
  35084. * @tparam Sort Type of sort function object.
  35085. * @tparam Args Types of arguments to forward to the sort function object.
  35086. * @param compare A valid comparison function object.
  35087. * @param algo A valid sort function object.
  35088. * @param args Arguments to forward to the sort function object, if any.
  35089. */
  35090. template<typename Type, typename Compare, typename Sort = std_sort, typename... Args>
  35091. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  35092. ENTT_ASSERT(!owned<Type>(), "Cannot sort owned storage");
  35093. auto &cpool = assure<Type>();
  35094. if constexpr(std::is_invocable_v<Compare, decltype(cpool.get({})), decltype(cpool.get({}))>) {
  35095. auto comp = [&cpool, compare = std::move(compare)](const auto lhs, const auto rhs) { return compare(std::as_const(cpool.get(lhs)), std::as_const(cpool.get(rhs))); };
  35096. cpool.sort(std::move(comp), std::move(algo), std::forward<Args>(args)...);
  35097. } else {
  35098. cpool.sort(std::move(compare), std::move(algo), std::forward<Args>(args)...);
  35099. }
  35100. }
  35101. /**
  35102. * @brief Sorts two pools of elements in the same way.
  35103. *
  35104. * Entities and elements in `To` which are part of both storage are sorted
  35105. * internally with the order they have in `From`. The others follow in no
  35106. * particular order.
  35107. *
  35108. * @warning
  35109. * Pools of elements owned by a group cannot be sorted.
  35110. *
  35111. * @tparam To Type of elements to sort.
  35112. * @tparam From Type of elements to use to sort.
  35113. */
  35114. template<typename To, typename From>
  35115. void sort() {
  35116. ENTT_ASSERT(!owned<To>(), "Cannot sort owned storage");
  35117. const base_type &cpool = assure<From>();
  35118. assure<To>().sort_as(cpool.begin(), cpool.end());
  35119. }
  35120. /**
  35121. * @brief Returns the context object, that is, a general purpose container.
  35122. * @return The context object, that is, a general purpose container.
  35123. */
  35124. [[nodiscard]] context &ctx() noexcept {
  35125. return vars;
  35126. }
  35127. /*! @copydoc ctx */
  35128. [[nodiscard]] const context &ctx() const noexcept {
  35129. return vars;
  35130. }
  35131. private:
  35132. context vars;
  35133. pool_container_type pools;
  35134. group_container_type groups;
  35135. storage_for_type<entity_type> entities;
  35136. };
  35137. } // namespace entt
  35138. #endif
  35139. // #include "entity/runtime_view.hpp"
  35140. #ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
  35141. #define ENTT_ENTITY_RUNTIME_VIEW_HPP
  35142. #include <algorithm>
  35143. #include <cstddef>
  35144. #include <iterator>
  35145. #include <utility>
  35146. #include <vector>
  35147. // #include "entity.hpp"
  35148. // #include "fwd.hpp"
  35149. namespace entt {
  35150. /*! @cond TURN_OFF_DOXYGEN */
  35151. namespace internal {
  35152. template<typename Set>
  35153. class runtime_view_iterator final {
  35154. using iterator_type = typename Set::iterator;
  35155. using iterator_traits = std::iterator_traits<iterator_type>;
  35156. [[nodiscard]] bool valid() const {
  35157. return (!tombstone_check || *it != tombstone)
  35158. && std::all_of(++pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
  35159. && std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
  35160. }
  35161. public:
  35162. using value_type = typename iterator_traits::value_type;
  35163. using pointer = typename iterator_traits::pointer;
  35164. using reference = typename iterator_traits::reference;
  35165. using difference_type = typename iterator_traits::difference_type;
  35166. using iterator_category = std::bidirectional_iterator_tag;
  35167. constexpr runtime_view_iterator() noexcept
  35168. : pools{},
  35169. filter{},
  35170. it{},
  35171. tombstone_check{} {}
  35172. runtime_view_iterator(const std::vector<Set *> &cpools, iterator_type curr, const std::vector<Set *> &ignore) noexcept
  35173. : pools{&cpools},
  35174. filter{&ignore},
  35175. it{curr},
  35176. tombstone_check{pools->size() == 1u && (*pools)[0u]->policy() == deletion_policy::in_place} {
  35177. if(it != (*pools)[0]->end() && !valid()) {
  35178. ++(*this);
  35179. }
  35180. }
  35181. runtime_view_iterator &operator++() {
  35182. ++it;
  35183. for(const auto last = (*pools)[0]->end(); it != last && !valid(); ++it) {}
  35184. return *this;
  35185. }
  35186. runtime_view_iterator operator++(int) {
  35187. const runtime_view_iterator orig = *this;
  35188. return ++(*this), orig;
  35189. }
  35190. runtime_view_iterator &operator--() {
  35191. --it;
  35192. for(const auto first = (*pools)[0]->begin(); it != first && !valid(); --it) {}
  35193. return *this;
  35194. }
  35195. runtime_view_iterator operator--(int) {
  35196. const runtime_view_iterator orig = *this;
  35197. return operator--(), orig;
  35198. }
  35199. [[nodiscard]] pointer operator->() const noexcept {
  35200. return it.operator->();
  35201. }
  35202. [[nodiscard]] reference operator*() const noexcept {
  35203. return *operator->();
  35204. }
  35205. [[nodiscard]] constexpr bool operator==(const runtime_view_iterator &other) const noexcept {
  35206. return it == other.it;
  35207. }
  35208. [[nodiscard]] constexpr bool operator!=(const runtime_view_iterator &other) const noexcept {
  35209. return !(*this == other);
  35210. }
  35211. private:
  35212. const std::vector<Set *> *pools;
  35213. const std::vector<Set *> *filter;
  35214. iterator_type it;
  35215. bool tombstone_check;
  35216. };
  35217. } // namespace internal
  35218. /*! @endcond */
  35219. /**
  35220. * @brief Generic runtime view.
  35221. *
  35222. * Runtime views iterate over those entities that are at least in the given
  35223. * storage. During initialization, a runtime view looks at the number of
  35224. * entities available for each element and uses the smallest set in order to get
  35225. * a performance boost when iterating.
  35226. *
  35227. * @b Important
  35228. *
  35229. * Iterators aren't invalidated if:
  35230. *
  35231. * * New elements are added to the storage.
  35232. * * The entity currently pointed is modified (for example, elements are added
  35233. * or removed from it).
  35234. * * The entity currently pointed is destroyed.
  35235. *
  35236. * In all other cases, modifying the storage iterated by the view in any way
  35237. * invalidates all the iterators.
  35238. *
  35239. * @tparam Type Common base type.
  35240. * @tparam Allocator Type of allocator used to manage memory and elements.
  35241. */
  35242. template<typename Type, typename Allocator>
  35243. class basic_runtime_view {
  35244. using alloc_traits = std::allocator_traits<Allocator>;
  35245. static_assert(std::is_same_v<typename alloc_traits::value_type, Type *>, "Invalid value type");
  35246. using container_type = std::vector<Type *, Allocator>;
  35247. [[nodiscard]] auto offset() const noexcept {
  35248. ENTT_ASSERT(!pools.empty(), "Invalid view");
  35249. const auto &leading = *pools.front();
  35250. return (leading.policy() == deletion_policy::swap_only) ? leading.free_list() : leading.size();
  35251. }
  35252. public:
  35253. /*! @brief Allocator type. */
  35254. using allocator_type = Allocator;
  35255. /*! @brief Underlying entity identifier. */
  35256. using entity_type = typename Type::entity_type;
  35257. /*! @brief Unsigned integer type. */
  35258. using size_type = std::size_t;
  35259. /*! @brief Signed integer type. */
  35260. using difference_type = std::ptrdiff_t;
  35261. /*! @brief Common type among all storage types. */
  35262. using common_type = Type;
  35263. /*! @brief Bidirectional iterator type. */
  35264. using iterator = internal::runtime_view_iterator<common_type>;
  35265. /*! @brief Default constructor to use to create empty, invalid views. */
  35266. basic_runtime_view() noexcept
  35267. : basic_runtime_view{allocator_type{}} {}
  35268. /**
  35269. * @brief Constructs an empty, invalid view with a given allocator.
  35270. * @param allocator The allocator to use.
  35271. */
  35272. explicit basic_runtime_view(const allocator_type &allocator)
  35273. : pools{allocator},
  35274. filter{allocator} {}
  35275. /*! @brief Default copy constructor. */
  35276. basic_runtime_view(const basic_runtime_view &) = default;
  35277. /**
  35278. * @brief Allocator-extended copy constructor.
  35279. * @param other The instance to copy from.
  35280. * @param allocator The allocator to use.
  35281. */
  35282. basic_runtime_view(const basic_runtime_view &other, const allocator_type &allocator)
  35283. : pools{other.pools, allocator},
  35284. filter{other.filter, allocator} {}
  35285. /*! @brief Default move constructor. */
  35286. basic_runtime_view(basic_runtime_view &&) noexcept = default;
  35287. /**
  35288. * @brief Allocator-extended move constructor.
  35289. * @param other The instance to move from.
  35290. * @param allocator The allocator to use.
  35291. */
  35292. basic_runtime_view(basic_runtime_view &&other, const allocator_type &allocator)
  35293. : pools{std::move(other.pools), allocator},
  35294. filter{std::move(other.filter), allocator} {}
  35295. /*! @brief Default destructor. */
  35296. ~basic_runtime_view() = default;
  35297. /**
  35298. * @brief Default copy assignment operator.
  35299. * @return This runtime view.
  35300. */
  35301. basic_runtime_view &operator=(const basic_runtime_view &) = default;
  35302. /**
  35303. * @brief Default move assignment operator.
  35304. * @return This runtime view.
  35305. */
  35306. basic_runtime_view &operator=(basic_runtime_view &&) noexcept = default;
  35307. /**
  35308. * @brief Exchanges the contents with those of a given view.
  35309. * @param other View to exchange the content with.
  35310. */
  35311. void swap(basic_runtime_view &other) noexcept {
  35312. using std::swap;
  35313. swap(pools, other.pools);
  35314. swap(filter, other.filter);
  35315. }
  35316. /**
  35317. * @brief Returns the associated allocator.
  35318. * @return The associated allocator.
  35319. */
  35320. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  35321. return pools.get_allocator();
  35322. }
  35323. /*! @brief Clears the view. */
  35324. void clear() {
  35325. pools.clear();
  35326. filter.clear();
  35327. }
  35328. /**
  35329. * @brief Appends an opaque storage object to a runtime view.
  35330. * @param base An opaque reference to a storage object.
  35331. * @return This runtime view.
  35332. */
  35333. basic_runtime_view &iterate(common_type &base) {
  35334. if(pools.empty() || !(base.size() < pools.front()->size())) {
  35335. pools.push_back(&base);
  35336. } else {
  35337. pools.push_back(std::exchange(pools.front(), &base));
  35338. }
  35339. return *this;
  35340. }
  35341. /**
  35342. * @brief Adds an opaque storage object as a filter of a runtime view.
  35343. * @param base An opaque reference to a storage object.
  35344. * @return This runtime view.
  35345. */
  35346. basic_runtime_view &exclude(common_type &base) {
  35347. filter.push_back(&base);
  35348. return *this;
  35349. }
  35350. /**
  35351. * @brief Estimates the number of entities iterated by the view.
  35352. * @return Estimated number of entities iterated by the view.
  35353. */
  35354. [[nodiscard]] size_type size_hint() const {
  35355. return pools.empty() ? size_type{} : offset();
  35356. }
  35357. /**
  35358. * @brief Returns an iterator to the first entity that has the given
  35359. * elements.
  35360. *
  35361. * If the view is empty, the returned iterator will be equal to `end()`.
  35362. *
  35363. * @return An iterator to the first entity that has the given elements.
  35364. */
  35365. [[nodiscard]] iterator begin() const {
  35366. return pools.empty() ? iterator{} : iterator{pools, pools.front()->end() - static_cast<difference_type>(offset()), filter};
  35367. }
  35368. /**
  35369. * @brief Returns an iterator that is past the last entity that has the
  35370. * given elements.
  35371. * @return An iterator to the entity following the last entity that has the
  35372. * given elements.
  35373. */
  35374. [[nodiscard]] iterator end() const {
  35375. return pools.empty() ? iterator{} : iterator{pools, pools.front()->end(), filter};
  35376. }
  35377. /**
  35378. * @brief Checks whether a view is initialized or not.
  35379. * @return True if the view is initialized, false otherwise.
  35380. */
  35381. [[nodiscard]] explicit operator bool() const noexcept {
  35382. return !(pools.empty() && filter.empty());
  35383. }
  35384. /**
  35385. * @brief Checks if a view contains an entity.
  35386. * @param entt A valid identifier.
  35387. * @return True if the view contains the given entity, false otherwise.
  35388. */
  35389. [[nodiscard]] bool contains(const entity_type entt) const {
  35390. return !pools.empty()
  35391. && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); })
  35392. && std::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); })
  35393. && pools.front()->index(entt) < offset();
  35394. }
  35395. /**
  35396. * @brief Iterates entities and applies the given function object to them.
  35397. *
  35398. * The function object is invoked for each entity. It is provided only with
  35399. * the entity itself.<br/>
  35400. * The signature of the function should be equivalent to the following:
  35401. *
  35402. * @code{.cpp}
  35403. * void(const entity_type);
  35404. * @endcode
  35405. *
  35406. * @tparam Func Type of the function object to invoke.
  35407. * @param func A valid function object.
  35408. */
  35409. template<typename Func>
  35410. void each(Func func) const {
  35411. for(const auto entity: *this) {
  35412. func(entity);
  35413. }
  35414. }
  35415. private:
  35416. container_type pools;
  35417. container_type filter;
  35418. };
  35419. } // namespace entt
  35420. #endif
  35421. // #include "entity/snapshot.hpp"
  35422. #ifndef ENTT_ENTITY_SNAPSHOT_HPP
  35423. #define ENTT_ENTITY_SNAPSHOT_HPP
  35424. #include <cstddef>
  35425. #include <iterator>
  35426. #include <tuple>
  35427. #include <type_traits>
  35428. #include <utility>
  35429. #include <vector>
  35430. // #include "../config/config.h"
  35431. // #include "../container/dense_map.hpp"
  35432. // #include "../core/type_traits.hpp"
  35433. // #include "entity.hpp"
  35434. // #include "fwd.hpp"
  35435. // #include "view.hpp"
  35436. namespace entt {
  35437. /*! @cond TURN_OFF_DOXYGEN */
  35438. namespace internal {
  35439. template<typename Registry>
  35440. void orphans(Registry &registry) {
  35441. auto &storage = registry.template storage<typename Registry::entity_type>();
  35442. for(auto entt: storage) {
  35443. if(registry.orphan(entt)) {
  35444. storage.erase(entt);
  35445. }
  35446. }
  35447. }
  35448. } // namespace internal
  35449. /*! @endcond */
  35450. /**
  35451. * @brief Utility class to create snapshots from a registry.
  35452. *
  35453. * A _snapshot_ can be either a dump of the entire registry or a narrower
  35454. * selection of elements of interest.<br/>
  35455. * This type can be used in both cases if provided with a correctly configured
  35456. * output archive.
  35457. *
  35458. * @tparam Registry Basic registry type.
  35459. */
  35460. template<typename Registry>
  35461. class basic_snapshot {
  35462. static_assert(!std::is_const_v<Registry>, "Non-const registry type required");
  35463. using traits_type = entt_traits<typename Registry::entity_type>;
  35464. public:
  35465. /*! Basic registry type. */
  35466. using registry_type = Registry;
  35467. /*! @brief Underlying entity identifier. */
  35468. using entity_type = typename registry_type::entity_type;
  35469. /**
  35470. * @brief Constructs an instance that is bound to a given registry.
  35471. * @param source A valid reference to a registry.
  35472. */
  35473. basic_snapshot(const registry_type &source) noexcept
  35474. : reg{&source} {}
  35475. /*! @brief Default copy constructor, deleted on purpose. */
  35476. basic_snapshot(const basic_snapshot &) = delete;
  35477. /*! @brief Default move constructor. */
  35478. basic_snapshot(basic_snapshot &&) noexcept = default;
  35479. /*! @brief Default destructor. */
  35480. ~basic_snapshot() = default;
  35481. /**
  35482. * @brief Default copy assignment operator, deleted on purpose.
  35483. * @return This snapshot.
  35484. */
  35485. basic_snapshot &operator=(const basic_snapshot &) = delete;
  35486. /**
  35487. * @brief Default move assignment operator.
  35488. * @return This snapshot.
  35489. */
  35490. basic_snapshot &operator=(basic_snapshot &&) noexcept = default;
  35491. /**
  35492. * @brief Serializes all elements of a type with associated identifiers.
  35493. * @tparam Type Type of elements to serialize.
  35494. * @tparam Archive Type of output archive.
  35495. * @param archive A valid reference to an output archive.
  35496. * @param id Optional name used to map the storage within the registry.
  35497. * @return An object of this type to continue creating the snapshot.
  35498. */
  35499. template<typename Type, typename Archive>
  35500. const basic_snapshot &get(Archive &archive, const id_type id = type_hash<Type>::value()) const {
  35501. if(const auto *storage = reg->template storage<Type>(id); storage) {
  35502. const typename registry_type::common_type &base = *storage;
  35503. archive(static_cast<typename traits_type::entity_type>(storage->size()));
  35504. if constexpr(std::is_same_v<Type, entity_type>) {
  35505. archive(static_cast<typename traits_type::entity_type>(storage->free_list()));
  35506. for(auto first = base.rbegin(), last = base.rend(); first != last; ++first) {
  35507. archive(*first);
  35508. }
  35509. } else if constexpr(registry_type::template storage_for_type<Type>::storage_policy == deletion_policy::in_place) {
  35510. for(auto it = base.rbegin(), last = base.rend(); it != last; ++it) {
  35511. if(const auto entt = *it; entt == tombstone) {
  35512. archive(static_cast<entity_type>(null));
  35513. } else {
  35514. archive(entt);
  35515. std::apply([&archive](auto &&...args) { (archive(std::forward<decltype(args)>(args)), ...); }, storage->get_as_tuple(entt));
  35516. }
  35517. }
  35518. } else {
  35519. for(auto elem: storage->reach()) {
  35520. std::apply([&archive](auto &&...args) { (archive(std::forward<decltype(args)>(args)), ...); }, elem);
  35521. }
  35522. }
  35523. } else {
  35524. archive(typename traits_type::entity_type{});
  35525. }
  35526. return *this;
  35527. }
  35528. /**
  35529. * @brief Serializes all elements of a type with associated identifiers for
  35530. * the entities in a range.
  35531. * @tparam Type Type of elements to serialize.
  35532. * @tparam Archive Type of output archive.
  35533. * @tparam It Type of input iterator.
  35534. * @param archive A valid reference to an output archive.
  35535. * @param first An iterator to the first element of the range to serialize.
  35536. * @param last An iterator past the last element of the range to serialize.
  35537. * @param id Optional name used to map the storage within the registry.
  35538. * @return An object of this type to continue creating the snapshot.
  35539. */
  35540. template<typename Type, typename Archive, typename It>
  35541. const basic_snapshot &get(Archive &archive, It first, It last, const id_type id = type_hash<Type>::value()) const {
  35542. static_assert(!std::is_same_v<Type, entity_type>, "Entity types not supported");
  35543. if(const auto *storage = reg->template storage<Type>(id); storage && !storage->empty()) {
  35544. archive(static_cast<typename traits_type::entity_type>(std::distance(first, last)));
  35545. for(; first != last; ++first) {
  35546. if(const auto entt = *first; storage->contains(entt)) {
  35547. archive(entt);
  35548. std::apply([&archive](auto &&...args) { (archive(std::forward<decltype(args)>(args)), ...); }, storage->get_as_tuple(entt));
  35549. } else {
  35550. archive(static_cast<entity_type>(null));
  35551. }
  35552. }
  35553. } else {
  35554. archive(typename traits_type::entity_type{});
  35555. }
  35556. return *this;
  35557. }
  35558. private:
  35559. const registry_type *reg;
  35560. };
  35561. /**
  35562. * @brief Utility class to restore a snapshot as a whole.
  35563. *
  35564. * A snapshot loader requires that the destination registry be empty and loads
  35565. * all the data at once while keeping intact the identifiers that the entities
  35566. * originally had.<br/>
  35567. * An example of use is the implementation of a save/restore utility.
  35568. *
  35569. * @tparam Registry Basic registry type.
  35570. */
  35571. template<typename Registry>
  35572. class basic_snapshot_loader {
  35573. static_assert(!std::is_const_v<Registry>, "Non-const registry type required");
  35574. using traits_type = entt_traits<typename Registry::entity_type>;
  35575. public:
  35576. /*! Basic registry type. */
  35577. using registry_type = Registry;
  35578. /*! @brief Underlying entity identifier. */
  35579. using entity_type = typename registry_type::entity_type;
  35580. /**
  35581. * @brief Constructs an instance that is bound to a given registry.
  35582. * @param source A valid reference to a registry.
  35583. */
  35584. basic_snapshot_loader(registry_type &source) noexcept
  35585. : reg{&source} {
  35586. // restoring a snapshot as a whole requires a clean registry
  35587. ENTT_ASSERT(reg->template storage<entity_type>().free_list() == 0u, "Registry must be empty");
  35588. }
  35589. /*! @brief Default copy constructor, deleted on purpose. */
  35590. basic_snapshot_loader(const basic_snapshot_loader &) = delete;
  35591. /*! @brief Default move constructor. */
  35592. basic_snapshot_loader(basic_snapshot_loader &&) noexcept = default;
  35593. /*! @brief Default destructor. */
  35594. ~basic_snapshot_loader() = default;
  35595. /**
  35596. * @brief Default copy assignment operator, deleted on purpose.
  35597. * @return This loader.
  35598. */
  35599. basic_snapshot_loader &operator=(const basic_snapshot_loader &) = delete;
  35600. /**
  35601. * @brief Default move assignment operator.
  35602. * @return This loader.
  35603. */
  35604. basic_snapshot_loader &operator=(basic_snapshot_loader &&) noexcept = default;
  35605. /**
  35606. * @brief Restores all elements of a type with associated identifiers.
  35607. * @tparam Type Type of elements to restore.
  35608. * @tparam Archive Type of input archive.
  35609. * @param archive A valid reference to an input archive.
  35610. * @param id Optional name used to map the storage within the registry.
  35611. * @return A valid loader to continue restoring data.
  35612. */
  35613. template<typename Type, typename Archive>
  35614. basic_snapshot_loader &get(Archive &archive, const id_type id = type_hash<Type>::value()) {
  35615. auto &storage = reg->template storage<Type>(id);
  35616. typename traits_type::entity_type length{};
  35617. archive(length);
  35618. if constexpr(std::is_same_v<Type, entity_type>) {
  35619. typename traits_type::entity_type count{};
  35620. entity_type placeholder{};
  35621. storage.reserve(length);
  35622. archive(count);
  35623. for(entity_type entity = null; length; --length) {
  35624. archive(entity);
  35625. storage.generate(entity);
  35626. placeholder = (entity > placeholder) ? entity : placeholder;
  35627. }
  35628. storage.start_from(traits_type::next(placeholder));
  35629. storage.free_list(count);
  35630. } else {
  35631. auto &other = reg->template storage<entity_type>();
  35632. entity_type entt{null};
  35633. while(length--) {
  35634. if(archive(entt); entt != null) {
  35635. const auto entity = other.contains(entt) ? entt : other.generate(entt);
  35636. ENTT_ASSERT(entity == entt, "Entity not available for use");
  35637. if constexpr(std::tuple_size_v<decltype(storage.get_as_tuple({}))> == 0u) {
  35638. storage.emplace(entity);
  35639. } else {
  35640. Type elem{};
  35641. archive(elem);
  35642. storage.emplace(entity, std::move(elem));
  35643. }
  35644. }
  35645. }
  35646. }
  35647. return *this;
  35648. }
  35649. /**
  35650. * @brief Destroys those entities that have no elements.
  35651. *
  35652. * In case all the entities were serialized but only part of the elements
  35653. * was saved, it could happen that some of the entities have no elements
  35654. * once restored.<br/>
  35655. * This function helps to identify and destroy those entities.
  35656. *
  35657. * @return A valid loader to continue restoring data.
  35658. */
  35659. basic_snapshot_loader &orphans() {
  35660. internal::orphans(*reg);
  35661. return *this;
  35662. }
  35663. private:
  35664. registry_type *reg;
  35665. };
  35666. /**
  35667. * @brief Utility class for _continuous loading_.
  35668. *
  35669. * A _continuous loader_ is designed to load data from a source registry to a
  35670. * (possibly) non-empty destination. The loader can accommodate in a registry
  35671. * more than one snapshot in a sort of _continuous loading_ that updates the
  35672. * destination one step at a time.<br/>
  35673. * Identifiers that entities originally had are not transferred to the target.
  35674. * Instead, the loader maps remote identifiers to local ones while restoring a
  35675. * snapshot.<br/>
  35676. * An example of use is the implementation of a client-server application with
  35677. * the requirement of transferring somehow parts of the representation side to
  35678. * side.
  35679. *
  35680. * @tparam Registry Basic registry type.
  35681. */
  35682. template<typename Registry>
  35683. class basic_continuous_loader {
  35684. static_assert(!std::is_const_v<Registry>, "Non-const registry type required");
  35685. using traits_type = entt_traits<typename Registry::entity_type>;
  35686. void restore(typename Registry::entity_type entt) {
  35687. if(const auto entity = to_entity(entt); remloc.contains(entity) && remloc[entity].first == entt) {
  35688. if(!reg->valid(remloc[entity].second)) {
  35689. remloc[entity].second = reg->create();
  35690. }
  35691. } else {
  35692. remloc.insert_or_assign(entity, std::make_pair(entt, reg->create()));
  35693. }
  35694. }
  35695. template<typename Container>
  35696. auto update(int, Container &container) -> decltype(typename Container::mapped_type{}, void()) {
  35697. // map like container
  35698. Container other;
  35699. for(auto &&pair: container) {
  35700. using first_type = std::remove_const_t<typename std::decay_t<decltype(pair)>::first_type>;
  35701. using second_type = typename std::decay_t<decltype(pair)>::second_type;
  35702. if constexpr(std::is_same_v<first_type, entity_type> && std::is_same_v<second_type, entity_type>) {
  35703. other.emplace(map(pair.first), map(pair.second));
  35704. } else if constexpr(std::is_same_v<first_type, entity_type>) {
  35705. other.emplace(map(pair.first), std::move(pair.second));
  35706. } else {
  35707. static_assert(std::is_same_v<second_type, entity_type>, "Neither the key nor the value are of entity type");
  35708. other.emplace(std::move(pair.first), map(pair.second));
  35709. }
  35710. }
  35711. using std::swap;
  35712. swap(container, other);
  35713. }
  35714. template<typename Container>
  35715. auto update(char, Container &container) -> decltype(typename Container::value_type{}, void()) {
  35716. // vector like container
  35717. static_assert(std::is_same_v<typename Container::value_type, entity_type>, "Invalid value type");
  35718. for(auto &&entt: container) {
  35719. entt = map(entt);
  35720. }
  35721. }
  35722. template<typename Component, typename Other, typename Member>
  35723. void update([[maybe_unused]] Component &instance, [[maybe_unused]] Member Other::*member) {
  35724. if constexpr(!std::is_same_v<Component, Other>) {
  35725. return;
  35726. } else if constexpr(std::is_same_v<Member, entity_type>) {
  35727. instance.*member = map(instance.*member);
  35728. } else {
  35729. // maybe a container? let's try...
  35730. update(0, instance.*member);
  35731. }
  35732. }
  35733. public:
  35734. /*! Basic registry type. */
  35735. using registry_type = Registry;
  35736. /*! @brief Underlying entity identifier. */
  35737. using entity_type = typename registry_type::entity_type;
  35738. /**
  35739. * @brief Constructs an instance that is bound to a given registry.
  35740. * @param source A valid reference to a registry.
  35741. */
  35742. basic_continuous_loader(registry_type &source) noexcept
  35743. : remloc{source.get_allocator()},
  35744. reg{&source} {}
  35745. /*! @brief Default copy constructor, deleted on purpose. */
  35746. basic_continuous_loader(const basic_continuous_loader &) = delete;
  35747. /*! @brief Default move constructor. */
  35748. basic_continuous_loader(basic_continuous_loader &&) noexcept = default;
  35749. /*! @brief Default destructor. */
  35750. ~basic_continuous_loader() = default;
  35751. /**
  35752. * @brief Default copy assignment operator, deleted on purpose.
  35753. * @return This loader.
  35754. */
  35755. basic_continuous_loader &operator=(const basic_continuous_loader &) = delete;
  35756. /**
  35757. * @brief Default move assignment operator.
  35758. * @return This loader.
  35759. */
  35760. basic_continuous_loader &operator=(basic_continuous_loader &&) noexcept = default;
  35761. /**
  35762. * @brief Restores all elements of a type with associated identifiers.
  35763. *
  35764. * It creates local counterparts for remote elements as needed.<br/>
  35765. * Members are either data members of type entity_type or containers of
  35766. * entities. In both cases, a loader visits them and replaces entities with
  35767. * their local counterpart.
  35768. *
  35769. * @tparam Type Type of elements to restore.
  35770. * @tparam Archive Type of input archive.
  35771. * @param archive A valid reference to an input archive.
  35772. * @param id Optional name used to map the storage within the registry.
  35773. * @return A valid loader to continue restoring data.
  35774. */
  35775. template<typename Type, typename Archive>
  35776. basic_continuous_loader &get(Archive &archive, const id_type id = type_hash<Type>::value()) {
  35777. auto &storage = reg->template storage<Type>(id);
  35778. typename traits_type::entity_type length{};
  35779. entity_type entt{null};
  35780. archive(length);
  35781. if constexpr(std::is_same_v<Type, entity_type>) {
  35782. typename traits_type::entity_type in_use{};
  35783. storage.reserve(length);
  35784. archive(in_use);
  35785. for(std::size_t pos{}; pos < in_use; ++pos) {
  35786. archive(entt);
  35787. restore(entt);
  35788. }
  35789. for(std::size_t pos = in_use; pos < length; ++pos) {
  35790. archive(entt);
  35791. if(const auto entity = to_entity(entt); remloc.contains(entity)) {
  35792. if(reg->valid(remloc[entity].second)) {
  35793. reg->destroy(remloc[entity].second);
  35794. }
  35795. remloc.erase(entity);
  35796. }
  35797. }
  35798. } else {
  35799. for(auto &&ref: remloc) {
  35800. storage.remove(ref.second.second);
  35801. }
  35802. while(length--) {
  35803. if(archive(entt); entt != null) {
  35804. restore(entt);
  35805. if constexpr(std::tuple_size_v<decltype(storage.get_as_tuple({}))> == 0u) {
  35806. storage.emplace(map(entt));
  35807. } else {
  35808. Type elem{};
  35809. archive(elem);
  35810. storage.emplace(map(entt), std::move(elem));
  35811. }
  35812. }
  35813. }
  35814. }
  35815. return *this;
  35816. }
  35817. /**
  35818. * @brief Destroys those entities that have no elements.
  35819. *
  35820. * In case all the entities were serialized but only part of the elements
  35821. * was saved, it could happen that some of the entities have no elements
  35822. * once restored.<br/>
  35823. * This function helps to identify and destroy those entities.
  35824. *
  35825. * @return A non-const reference to this loader.
  35826. */
  35827. basic_continuous_loader &orphans() {
  35828. internal::orphans(*reg);
  35829. return *this;
  35830. }
  35831. /**
  35832. * @brief Tests if a loader knows about a given entity.
  35833. * @param entt A valid identifier.
  35834. * @return True if `entity` is managed by the loader, false otherwise.
  35835. */
  35836. [[nodiscard]] bool contains(entity_type entt) const noexcept {
  35837. const auto it = remloc.find(to_entity(entt));
  35838. return it != remloc.cend() && it->second.first == entt;
  35839. }
  35840. /**
  35841. * @brief Returns the identifier to which an entity refers.
  35842. * @param entt A valid identifier.
  35843. * @return The local identifier if any, the null entity otherwise.
  35844. */
  35845. [[nodiscard]] entity_type map(entity_type entt) const noexcept {
  35846. if(const auto it = remloc.find(to_entity(entt)); it != remloc.cend() && it->second.first == entt) {
  35847. return it->second.second;
  35848. }
  35849. return null;
  35850. }
  35851. private:
  35852. dense_map<typename traits_type::entity_type, std::pair<entity_type, entity_type>> remloc;
  35853. registry_type *reg;
  35854. };
  35855. } // namespace entt
  35856. #endif
  35857. // #include "entity/sparse_set.hpp"
  35858. #ifndef ENTT_ENTITY_SPARSE_SET_HPP
  35859. #define ENTT_ENTITY_SPARSE_SET_HPP
  35860. #include <cstddef>
  35861. #include <iterator>
  35862. #include <memory>
  35863. #include <type_traits>
  35864. #include <utility>
  35865. #include <vector>
  35866. // #include "../config/config.h"
  35867. // #include "../core/algorithm.hpp"
  35868. // #include "../core/any.hpp"
  35869. // #include "../core/bit.hpp"
  35870. // #include "../core/type_info.hpp"
  35871. // #include "entity.hpp"
  35872. // #include "fwd.hpp"
  35873. namespace entt {
  35874. /*! @cond TURN_OFF_DOXYGEN */
  35875. namespace internal {
  35876. template<typename Container>
  35877. struct sparse_set_iterator final {
  35878. using value_type = typename Container::value_type;
  35879. using pointer = typename Container::const_pointer;
  35880. using reference = typename Container::const_reference;
  35881. using difference_type = typename Container::difference_type;
  35882. using iterator_category = std::random_access_iterator_tag;
  35883. constexpr sparse_set_iterator() noexcept
  35884. : packed{},
  35885. offset{} {}
  35886. constexpr sparse_set_iterator(const Container &ref, const difference_type idx) noexcept
  35887. : packed{&ref},
  35888. offset{idx} {}
  35889. constexpr sparse_set_iterator &operator++() noexcept {
  35890. return --offset, *this;
  35891. }
  35892. constexpr sparse_set_iterator operator++(int) noexcept {
  35893. const sparse_set_iterator orig = *this;
  35894. return ++(*this), orig;
  35895. }
  35896. constexpr sparse_set_iterator &operator--() noexcept {
  35897. return ++offset, *this;
  35898. }
  35899. constexpr sparse_set_iterator operator--(int) noexcept {
  35900. const sparse_set_iterator orig = *this;
  35901. return operator--(), orig;
  35902. }
  35903. constexpr sparse_set_iterator &operator+=(const difference_type value) noexcept {
  35904. offset -= value;
  35905. return *this;
  35906. }
  35907. constexpr sparse_set_iterator operator+(const difference_type value) const noexcept {
  35908. sparse_set_iterator copy = *this;
  35909. return (copy += value);
  35910. }
  35911. constexpr sparse_set_iterator &operator-=(const difference_type value) noexcept {
  35912. return (*this += -value);
  35913. }
  35914. constexpr sparse_set_iterator operator-(const difference_type value) const noexcept {
  35915. return (*this + -value);
  35916. }
  35917. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  35918. return (*packed)[static_cast<typename Container::size_type>(index() - value)];
  35919. }
  35920. [[nodiscard]] constexpr pointer operator->() const noexcept {
  35921. return std::addressof(operator[](0));
  35922. }
  35923. [[nodiscard]] constexpr reference operator*() const noexcept {
  35924. return operator[](0);
  35925. }
  35926. [[nodiscard]] constexpr pointer data() const noexcept {
  35927. return packed ? packed->data() : nullptr;
  35928. }
  35929. [[nodiscard]] constexpr difference_type index() const noexcept {
  35930. return offset - 1;
  35931. }
  35932. private:
  35933. const Container *packed;
  35934. difference_type offset;
  35935. };
  35936. template<typename Container>
  35937. [[nodiscard]] constexpr std::ptrdiff_t operator-(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  35938. return rhs.index() - lhs.index();
  35939. }
  35940. template<typename Container>
  35941. [[nodiscard]] constexpr bool operator==(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  35942. return lhs.index() == rhs.index();
  35943. }
  35944. template<typename Container>
  35945. [[nodiscard]] constexpr bool operator!=(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  35946. return !(lhs == rhs);
  35947. }
  35948. template<typename Container>
  35949. [[nodiscard]] constexpr bool operator<(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  35950. return lhs.index() > rhs.index();
  35951. }
  35952. template<typename Container>
  35953. [[nodiscard]] constexpr bool operator>(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  35954. return rhs < lhs;
  35955. }
  35956. template<typename Container>
  35957. [[nodiscard]] constexpr bool operator<=(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  35958. return !(lhs > rhs);
  35959. }
  35960. template<typename Container>
  35961. [[nodiscard]] constexpr bool operator>=(const sparse_set_iterator<Container> &lhs, const sparse_set_iterator<Container> &rhs) noexcept {
  35962. return !(lhs < rhs);
  35963. }
  35964. } // namespace internal
  35965. /*! @endcond */
  35966. /**
  35967. * @brief Sparse set implementation.
  35968. *
  35969. * Sparse set or packed array or whatever is the name users give it.<br/>
  35970. * Two arrays: an _external_ one and an _internal_ one; a _sparse_ one and a
  35971. * _packed_ one; one used for direct access through contiguous memory, the other
  35972. * one used to get the data through an extra level of indirection.<br/>
  35973. * This type of data structure is widely documented in the literature and on the
  35974. * web. This is nothing more than a customized implementation suitable for the
  35975. * purpose of the framework.
  35976. *
  35977. * @note
  35978. * Internal data structures arrange elements to maximize performance. There are
  35979. * no guarantees that entities are returned in the insertion order when iterate
  35980. * a sparse set. Do not make assumption on the order in any case.
  35981. *
  35982. * @tparam Entity A valid entity type.
  35983. * @tparam Allocator Type of allocator used to manage memory and elements.
  35984. */
  35985. template<typename Entity, typename Allocator>
  35986. class basic_sparse_set {
  35987. using alloc_traits = std::allocator_traits<Allocator>;
  35988. static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");
  35989. using sparse_container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  35990. using packed_container_type = std::vector<Entity, Allocator>;
  35991. using traits_type = entt_traits<Entity>;
  35992. static constexpr auto max_size = static_cast<std::size_t>(traits_type::to_entity(null));
  35993. // it could be auto but gcc complains and emits a warning due to a false positive
  35994. [[nodiscard]] std::size_t policy_to_head() const noexcept {
  35995. return static_cast<size_type>(max_size * static_cast<std::remove_const_t<decltype(max_size)>>(mode != deletion_policy::swap_only));
  35996. }
  35997. [[nodiscard]] auto entity_to_pos(const Entity entt) const noexcept {
  35998. return static_cast<size_type>(traits_type::to_entity(entt));
  35999. }
  36000. [[nodiscard]] auto pos_to_page(const std::size_t pos) const noexcept {
  36001. return static_cast<size_type>(pos / traits_type::page_size);
  36002. }
  36003. [[nodiscard]] auto sparse_ptr(const Entity entt) const {
  36004. const auto pos = entity_to_pos(entt);
  36005. const auto page = pos_to_page(pos);
  36006. return (page < sparse.size() && sparse[page]) ? (sparse[page] + fast_mod(pos, traits_type::page_size)) : nullptr;
  36007. }
  36008. [[nodiscard]] auto &sparse_ref(const Entity entt) const {
  36009. ENTT_ASSERT(sparse_ptr(entt), "Invalid element");
  36010. const auto pos = entity_to_pos(entt);
  36011. return sparse[pos_to_page(pos)][fast_mod(pos, traits_type::page_size)];
  36012. }
  36013. [[nodiscard]] auto to_iterator(const Entity entt) const {
  36014. return --(end() - static_cast<difference_type>(index(entt)));
  36015. }
  36016. [[nodiscard]] auto &assure_at_least(const Entity entt) {
  36017. const auto pos = entity_to_pos(entt);
  36018. const auto page = pos_to_page(pos);
  36019. if(!(page < sparse.size())) {
  36020. sparse.resize(page + 1u, nullptr);
  36021. }
  36022. if(!sparse[page]) {
  36023. constexpr entity_type init = null;
  36024. auto page_allocator{packed.get_allocator()};
  36025. sparse[page] = alloc_traits::allocate(page_allocator, traits_type::page_size);
  36026. std::uninitialized_fill(sparse[page], sparse[page] + traits_type::page_size, init);
  36027. }
  36028. return sparse[page][fast_mod(pos, traits_type::page_size)];
  36029. }
  36030. void release_sparse_pages() {
  36031. auto page_allocator{packed.get_allocator()};
  36032. for(auto &&page: sparse) {
  36033. if(page != nullptr) {
  36034. std::destroy(page, page + traits_type::page_size);
  36035. alloc_traits::deallocate(page_allocator, page, traits_type::page_size);
  36036. page = nullptr;
  36037. }
  36038. }
  36039. }
  36040. void swap_at(const std::size_t lhs, const std::size_t rhs) {
  36041. auto &from = packed[lhs];
  36042. auto &to = packed[rhs];
  36043. sparse_ref(from) = traits_type::combine(static_cast<typename traits_type::entity_type>(rhs), traits_type::to_integral(from));
  36044. sparse_ref(to) = traits_type::combine(static_cast<typename traits_type::entity_type>(lhs), traits_type::to_integral(to));
  36045. std::swap(from, to);
  36046. }
  36047. private:
  36048. [[nodiscard]] virtual const void *get_at(const std::size_t) const {
  36049. return nullptr;
  36050. }
  36051. virtual void swap_or_move([[maybe_unused]] const std::size_t lhs, [[maybe_unused]] const std::size_t rhs) {
  36052. ENTT_ASSERT((mode != deletion_policy::swap_only) || ((lhs < head) == (rhs < head)), "Cross swapping is not supported");
  36053. }
  36054. protected:
  36055. /*! @brief Random access iterator type. */
  36056. using basic_iterator = internal::sparse_set_iterator<packed_container_type>;
  36057. /**
  36058. * @brief Erases an entity from a sparse set.
  36059. * @param it An iterator to the element to pop.
  36060. */
  36061. void swap_only(const basic_iterator it) {
  36062. ENTT_ASSERT(mode == deletion_policy::swap_only, "Deletion policy mismatch");
  36063. const auto pos = index(*it);
  36064. bump(traits_type::next(*it));
  36065. swap_at(pos, head -= (pos < head));
  36066. }
  36067. /**
  36068. * @brief Erases an entity from a sparse set.
  36069. * @param it An iterator to the element to pop.
  36070. */
  36071. void swap_and_pop(const basic_iterator it) {
  36072. ENTT_ASSERT(mode == deletion_policy::swap_and_pop, "Deletion policy mismatch");
  36073. auto &self = sparse_ref(*it);
  36074. const auto entt = traits_type::to_entity(self);
  36075. sparse_ref(packed.back()) = traits_type::combine(entt, traits_type::to_integral(packed.back()));
  36076. packed[static_cast<size_type>(entt)] = packed.back();
  36077. // unnecessary but it helps to detect nasty bugs
  36078. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  36079. ENTT_ASSERT((packed.back() = null, true), "");
  36080. // lazy self-assignment guard
  36081. self = null;
  36082. packed.pop_back();
  36083. }
  36084. /**
  36085. * @brief Erases an entity from a sparse set.
  36086. * @param it An iterator to the element to pop.
  36087. */
  36088. void in_place_pop(const basic_iterator it) {
  36089. ENTT_ASSERT(mode == deletion_policy::in_place, "Deletion policy mismatch");
  36090. const auto pos = entity_to_pos(std::exchange(sparse_ref(*it), null));
  36091. packed[pos] = traits_type::combine(static_cast<typename traits_type::entity_type>(std::exchange(head, pos)), tombstone);
  36092. }
  36093. /**
  36094. * @brief Erases entities from a sparse set.
  36095. * @param first An iterator to the first element of the range of entities.
  36096. * @param last An iterator past the last element of the range of entities.
  36097. */
  36098. virtual void pop(basic_iterator first, basic_iterator last) {
  36099. switch(mode) {
  36100. case deletion_policy::swap_and_pop:
  36101. for(; first != last; ++first) {
  36102. swap_and_pop(first);
  36103. }
  36104. break;
  36105. case deletion_policy::in_place:
  36106. for(; first != last; ++first) {
  36107. in_place_pop(first);
  36108. }
  36109. break;
  36110. case deletion_policy::swap_only:
  36111. for(; first != last; ++first) {
  36112. swap_only(first);
  36113. }
  36114. break;
  36115. }
  36116. }
  36117. /*! @brief Erases all entities of a sparse set. */
  36118. virtual void pop_all() {
  36119. switch(mode) {
  36120. case deletion_policy::in_place:
  36121. if(head != max_size) {
  36122. for(auto &&elem: packed) {
  36123. if(elem != tombstone) {
  36124. sparse_ref(elem) = null;
  36125. }
  36126. }
  36127. break;
  36128. }
  36129. [[fallthrough]];
  36130. case deletion_policy::swap_only:
  36131. case deletion_policy::swap_and_pop:
  36132. for(auto &&elem: packed) {
  36133. sparse_ref(elem) = null;
  36134. }
  36135. break;
  36136. }
  36137. head = policy_to_head();
  36138. packed.clear();
  36139. }
  36140. /**
  36141. * @brief Assigns an entity to a sparse set.
  36142. * @param entt A valid identifier.
  36143. * @param force_back Force back insertion.
  36144. * @return Iterator pointing to the emplaced element.
  36145. */
  36146. virtual basic_iterator try_emplace(const Entity entt, const bool force_back, const void * = nullptr) {
  36147. ENTT_ASSERT(entt != null && entt != tombstone, "Invalid element");
  36148. auto &elem = assure_at_least(entt);
  36149. auto pos = size();
  36150. switch(mode) {
  36151. case deletion_policy::in_place:
  36152. if(head != max_size && !force_back) {
  36153. pos = head;
  36154. ENTT_ASSERT(elem == null, "Slot not available");
  36155. elem = traits_type::combine(static_cast<typename traits_type::entity_type>(head), traits_type::to_integral(entt));
  36156. head = entity_to_pos(std::exchange(packed[pos], entt));
  36157. break;
  36158. }
  36159. [[fallthrough]];
  36160. case deletion_policy::swap_and_pop:
  36161. packed.push_back(entt);
  36162. ENTT_ASSERT(elem == null, "Slot not available");
  36163. elem = traits_type::combine(static_cast<typename traits_type::entity_type>(packed.size() - 1u), traits_type::to_integral(entt));
  36164. break;
  36165. case deletion_policy::swap_only:
  36166. if(elem == null) {
  36167. packed.push_back(entt);
  36168. elem = traits_type::combine(static_cast<typename traits_type::entity_type>(packed.size() - 1u), traits_type::to_integral(entt));
  36169. } else {
  36170. ENTT_ASSERT(!(entity_to_pos(elem) < head), "Slot not available");
  36171. bump(entt);
  36172. }
  36173. pos = head++;
  36174. swap_at(entity_to_pos(elem), pos);
  36175. break;
  36176. }
  36177. return iterator{packed, static_cast<difference_type>(++pos)};
  36178. }
  36179. /*! @brief Forwards variables to derived classes, if any. */
  36180. // NOLINTNEXTLINE(performance-unnecessary-value-param)
  36181. virtual void bind_any(any) noexcept {}
  36182. public:
  36183. /*! @brief Allocator type. */
  36184. using allocator_type = Allocator;
  36185. /*! @brief Underlying entity identifier. */
  36186. using entity_type = typename traits_type::value_type;
  36187. /*! @brief Underlying version type. */
  36188. using version_type = typename traits_type::version_type;
  36189. /*! @brief Unsigned integer type. */
  36190. using size_type = std::size_t;
  36191. /*! @brief Signed integer type. */
  36192. using difference_type = std::ptrdiff_t;
  36193. /*! @brief Pointer type to contained entities. */
  36194. using pointer = typename packed_container_type::const_pointer;
  36195. /*! @brief Random access iterator type. */
  36196. using iterator = basic_iterator;
  36197. /*! @brief Constant random access iterator type. */
  36198. using const_iterator = iterator;
  36199. /*! @brief Reverse iterator type. */
  36200. using reverse_iterator = std::reverse_iterator<iterator>;
  36201. /*! @brief Constant reverse iterator type. */
  36202. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  36203. /*! @brief Default constructor. */
  36204. basic_sparse_set()
  36205. : basic_sparse_set{type_id<void>()} {}
  36206. /**
  36207. * @brief Constructs an empty container with a given allocator.
  36208. * @param allocator The allocator to use.
  36209. */
  36210. explicit basic_sparse_set(const allocator_type &allocator)
  36211. : basic_sparse_set{deletion_policy::swap_and_pop, allocator} {}
  36212. /**
  36213. * @brief Constructs an empty container with the given policy and allocator.
  36214. * @param pol Type of deletion policy.
  36215. * @param allocator The allocator to use (possibly default-constructed).
  36216. */
  36217. explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {})
  36218. : basic_sparse_set{type_id<void>(), pol, allocator} {}
  36219. /**
  36220. * @brief Constructs an empty container with the given value type, policy
  36221. * and allocator.
  36222. * @param elem Returned value type, if any.
  36223. * @param pol Type of deletion policy.
  36224. * @param allocator The allocator to use (possibly default-constructed).
  36225. */
  36226. explicit basic_sparse_set(const type_info &elem, deletion_policy pol = deletion_policy::swap_and_pop, const allocator_type &allocator = {})
  36227. : sparse{allocator},
  36228. packed{allocator},
  36229. descriptor{&elem},
  36230. mode{pol},
  36231. head{policy_to_head()} {
  36232. ENTT_ASSERT(traits_type::version_mask || mode != deletion_policy::in_place, "Policy does not support zero-sized versions");
  36233. }
  36234. /*! @brief Default copy constructor, deleted on purpose. */
  36235. basic_sparse_set(const basic_sparse_set &) = delete;
  36236. /**
  36237. * @brief Move constructor.
  36238. * @param other The instance to move from.
  36239. */
  36240. basic_sparse_set(basic_sparse_set &&other) noexcept
  36241. : sparse{std::move(other.sparse)},
  36242. packed{std::move(other.packed)},
  36243. descriptor{other.descriptor},
  36244. mode{other.mode},
  36245. head{std::exchange(other.head, policy_to_head())} {}
  36246. /**
  36247. * @brief Allocator-extended move constructor.
  36248. * @param other The instance to move from.
  36249. * @param allocator The allocator to use.
  36250. */
  36251. basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator)
  36252. : sparse{std::move(other.sparse), allocator},
  36253. packed{std::move(other.packed), allocator},
  36254. descriptor{other.descriptor},
  36255. mode{other.mode},
  36256. head{std::exchange(other.head, policy_to_head())} {
  36257. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed");
  36258. }
  36259. /*! @brief Default destructor. */
  36260. virtual ~basic_sparse_set() {
  36261. release_sparse_pages();
  36262. }
  36263. /**
  36264. * @brief Default copy assignment operator, deleted on purpose.
  36265. * @return This sparse set.
  36266. */
  36267. basic_sparse_set &operator=(const basic_sparse_set &) = delete;
  36268. /**
  36269. * @brief Move assignment operator.
  36270. * @param other The instance to move from.
  36271. * @return This sparse set.
  36272. */
  36273. basic_sparse_set &operator=(basic_sparse_set &&other) noexcept {
  36274. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a sparse set is not allowed");
  36275. swap(other);
  36276. return *this;
  36277. }
  36278. /**
  36279. * @brief Exchanges the contents with those of a given sparse set.
  36280. * @param other Sparse set to exchange the content with.
  36281. */
  36282. void swap(basic_sparse_set &other) noexcept {
  36283. using std::swap;
  36284. swap(sparse, other.sparse);
  36285. swap(packed, other.packed);
  36286. swap(descriptor, other.descriptor);
  36287. swap(mode, other.mode);
  36288. swap(head, other.head);
  36289. }
  36290. /**
  36291. * @brief Returns the associated allocator.
  36292. * @return The associated allocator.
  36293. */
  36294. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  36295. return packed.get_allocator();
  36296. }
  36297. /**
  36298. * @brief Returns the deletion policy of a sparse set.
  36299. * @return The deletion policy of the sparse set.
  36300. */
  36301. [[nodiscard]] deletion_policy policy() const noexcept {
  36302. return mode;
  36303. }
  36304. /**
  36305. * @brief Returns data on the free list whose meaning depends on the mode.
  36306. * @return Free list information that is mode dependent.
  36307. */
  36308. [[nodiscard]] size_type free_list() const noexcept {
  36309. return head;
  36310. }
  36311. /**
  36312. * @brief Sets data on the free list whose meaning depends on the mode.
  36313. * @param value Free list information that is mode dependent.
  36314. */
  36315. void free_list(const size_type value) noexcept {
  36316. ENTT_ASSERT((mode == deletion_policy::swap_only) && !(value > packed.size()), "Invalid value");
  36317. head = value;
  36318. }
  36319. /**
  36320. * @brief Increases the capacity of a sparse set.
  36321. *
  36322. * If the new capacity is greater than the current capacity, new storage is
  36323. * allocated, otherwise the method does nothing.
  36324. *
  36325. * @param cap Desired capacity.
  36326. */
  36327. virtual void reserve(const size_type cap) {
  36328. packed.reserve(cap);
  36329. }
  36330. /**
  36331. * @brief Returns the number of elements that a sparse set has currently
  36332. * allocated space for.
  36333. * @return Capacity of the sparse set.
  36334. */
  36335. [[nodiscard]] virtual size_type capacity() const noexcept {
  36336. return packed.capacity();
  36337. }
  36338. /*! @brief Requests the removal of unused capacity. */
  36339. virtual void shrink_to_fit() {
  36340. sparse_container_type other{sparse.get_allocator()};
  36341. const auto len = sparse.size();
  36342. size_type cnt{};
  36343. other.reserve(len);
  36344. for(auto &&elem: std::as_const(packed)) {
  36345. if(elem != tombstone) {
  36346. if(const auto page = pos_to_page(entity_to_pos(elem)); sparse[page] != nullptr) {
  36347. if(const auto sz = page + 1u; sz > other.size()) {
  36348. other.resize(sz, nullptr);
  36349. }
  36350. other[page] = std::exchange(sparse[page], nullptr);
  36351. if(++cnt == len) {
  36352. // early exit due to lack of pages
  36353. break;
  36354. }
  36355. }
  36356. }
  36357. }
  36358. release_sparse_pages();
  36359. sparse.swap(other);
  36360. sparse.shrink_to_fit();
  36361. packed.shrink_to_fit();
  36362. }
  36363. /**
  36364. * @brief Returns the extent of a sparse set.
  36365. *
  36366. * The extent of a sparse set is also the size of the internal sparse array.
  36367. * There is no guarantee that all pages have been allocated, nor that the
  36368. * internal packed array is be the same size.
  36369. *
  36370. * @return Extent of the sparse set.
  36371. */
  36372. [[nodiscard]] size_type extent() const noexcept {
  36373. return sparse.size() * traits_type::page_size;
  36374. }
  36375. /**
  36376. * @brief Returns the number of elements in a sparse set.
  36377. *
  36378. * The number of elements is also the size of the internal packed array.
  36379. * There is no guarantee that the internal sparse array has the same size.
  36380. * Usually the size of the internal sparse array is equal or greater than
  36381. * the one of the internal packed array.
  36382. *
  36383. * @return Number of elements.
  36384. */
  36385. [[nodiscard]] size_type size() const noexcept {
  36386. return packed.size();
  36387. }
  36388. /**
  36389. * @brief Checks whether a sparse set is empty.
  36390. * @return True if the sparse set is empty, false otherwise.
  36391. */
  36392. [[nodiscard]] bool empty() const noexcept {
  36393. return packed.empty();
  36394. }
  36395. /**
  36396. * @brief Checks whether a sparse set is fully packed.
  36397. * @return True if the sparse set is fully packed, false otherwise.
  36398. */
  36399. [[nodiscard]] bool contiguous() const noexcept {
  36400. return (mode != deletion_policy::in_place) || (head == max_size);
  36401. }
  36402. /**
  36403. * @brief Direct access to the internal packed array.
  36404. * @return A pointer to the internal packed array.
  36405. */
  36406. [[nodiscard]] pointer data() const noexcept {
  36407. return packed.data();
  36408. }
  36409. /**
  36410. * @brief Returns an iterator to the beginning.
  36411. *
  36412. * If the sparse set is empty, the returned iterator will be equal to
  36413. * `end()`.
  36414. *
  36415. * @return An iterator to the first entity of the sparse set.
  36416. */
  36417. [[nodiscard]] iterator begin() const noexcept {
  36418. const auto pos = static_cast<difference_type>(packed.size());
  36419. return iterator{packed, pos};
  36420. }
  36421. /*! @copydoc begin */
  36422. [[nodiscard]] const_iterator cbegin() const noexcept {
  36423. return begin();
  36424. }
  36425. /**
  36426. * @brief Returns an iterator to the end.
  36427. * @return An iterator to the element following the last entity of a sparse
  36428. * set.
  36429. */
  36430. [[nodiscard]] iterator end() const noexcept {
  36431. return iterator{packed, {}};
  36432. }
  36433. /*! @copydoc end */
  36434. [[nodiscard]] const_iterator cend() const noexcept {
  36435. return end();
  36436. }
  36437. /**
  36438. * @brief Returns a reverse iterator to the beginning.
  36439. *
  36440. * If the sparse set is empty, the returned iterator will be equal to
  36441. * `rend()`.
  36442. *
  36443. * @return An iterator to the first entity of the reversed internal packed
  36444. * array.
  36445. */
  36446. [[nodiscard]] reverse_iterator rbegin() const noexcept {
  36447. return std::make_reverse_iterator(end());
  36448. }
  36449. /*! @copydoc rbegin */
  36450. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  36451. return rbegin();
  36452. }
  36453. /**
  36454. * @brief Returns a reverse iterator to the end.
  36455. * @return An iterator to the element following the last entity of the
  36456. * reversed sparse set.
  36457. */
  36458. [[nodiscard]] reverse_iterator rend() const noexcept {
  36459. return std::make_reverse_iterator(begin());
  36460. }
  36461. /*! @copydoc rend */
  36462. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  36463. return rend();
  36464. }
  36465. /**
  36466. * @brief Finds an entity.
  36467. * @param entt A valid identifier.
  36468. * @return An iterator to the given entity if it's found, past the end
  36469. * iterator otherwise.
  36470. */
  36471. [[nodiscard]] const_iterator find(const entity_type entt) const noexcept {
  36472. return contains(entt) ? to_iterator(entt) : end();
  36473. }
  36474. /**
  36475. * @brief Checks if a sparse set contains an entity.
  36476. * @param entt A valid identifier.
  36477. * @return True if the sparse set contains the entity, false otherwise.
  36478. */
  36479. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  36480. const auto *elem = sparse_ptr(entt);
  36481. constexpr auto cap = traits_type::entity_mask;
  36482. constexpr auto mask = traits_type::to_integral(null) & ~cap;
  36483. // testing versions permits to avoid accessing the packed array
  36484. return elem && (((mask & traits_type::to_integral(entt)) ^ traits_type::to_integral(*elem)) < cap);
  36485. }
  36486. /**
  36487. * @brief Returns the contained version for an identifier.
  36488. * @param entt A valid identifier.
  36489. * @return The version for the given identifier if present, the tombstone
  36490. * version otherwise.
  36491. */
  36492. [[nodiscard]] version_type current(const entity_type entt) const noexcept {
  36493. const auto *elem = sparse_ptr(entt);
  36494. constexpr auto fallback = traits_type::to_version(tombstone);
  36495. return elem ? traits_type::to_version(*elem) : fallback;
  36496. }
  36497. /**
  36498. * @brief Returns the position of an entity in a sparse set.
  36499. *
  36500. * @warning
  36501. * Attempting to get the position of an entity that doesn't belong to the
  36502. * sparse set results in undefined behavior.
  36503. *
  36504. * @param entt A valid identifier.
  36505. * @return The position of the entity in the sparse set.
  36506. */
  36507. [[nodiscard]] size_type index(const entity_type entt) const noexcept {
  36508. ENTT_ASSERT(contains(entt), "Set does not contain entity");
  36509. return entity_to_pos(sparse_ref(entt));
  36510. }
  36511. /**
  36512. * @brief Returns the entity at specified location.
  36513. * @param pos The position for which to return the entity.
  36514. * @return The entity at specified location.
  36515. */
  36516. [[nodiscard]] entity_type operator[](const size_type pos) const noexcept {
  36517. ENTT_ASSERT(pos < packed.size(), "Index out of bounds");
  36518. return packed[pos];
  36519. }
  36520. /**
  36521. * @brief Returns the element assigned to an entity, if any.
  36522. *
  36523. * @warning
  36524. * Attempting to use an entity that doesn't belong to the sparse set results
  36525. * in undefined behavior.
  36526. *
  36527. * @param entt A valid identifier.
  36528. * @return An opaque pointer to the element assigned to the entity, if any.
  36529. */
  36530. [[nodiscard]] const void *value(const entity_type entt) const noexcept {
  36531. return get_at(index(entt));
  36532. }
  36533. /*! @copydoc value */
  36534. [[nodiscard]] void *value(const entity_type entt) noexcept {
  36535. return const_cast<void *>(std::as_const(*this).value(entt));
  36536. }
  36537. /**
  36538. * @brief Assigns an entity to a sparse set.
  36539. *
  36540. * @warning
  36541. * Attempting to assign an entity that already belongs to the sparse set
  36542. * results in undefined behavior.
  36543. *
  36544. * @param entt A valid identifier.
  36545. * @param elem Optional opaque element to forward to mixins, if any.
  36546. * @return Iterator pointing to the emplaced element in case of success, the
  36547. * `end()` iterator otherwise.
  36548. */
  36549. iterator push(const entity_type entt, const void *elem = nullptr) {
  36550. return try_emplace(entt, false, elem);
  36551. }
  36552. /**
  36553. * @brief Assigns one or more entities to a sparse set.
  36554. *
  36555. * @warning
  36556. * Attempting to assign an entity that already belongs to the sparse set
  36557. * results in undefined behavior.
  36558. *
  36559. * @tparam It Type of input iterator.
  36560. * @param first An iterator to the first element of the range of entities.
  36561. * @param last An iterator past the last element of the range of entities.
  36562. * @return Iterator pointing to the first element inserted in case of
  36563. * success, the `end()` iterator otherwise.
  36564. */
  36565. template<typename It>
  36566. iterator push(It first, It last) {
  36567. auto curr = end();
  36568. for(; first != last; ++first) {
  36569. curr = try_emplace(*first, true);
  36570. }
  36571. return curr;
  36572. }
  36573. /**
  36574. * @brief Bump the version number of an entity.
  36575. *
  36576. * @warning
  36577. * Attempting to bump the version of an entity that doesn't belong to the
  36578. * sparse set results in undefined behavior.
  36579. *
  36580. * @param entt A valid identifier.
  36581. * @return The version of the given identifier.
  36582. */
  36583. version_type bump(const entity_type entt) {
  36584. auto &elem = sparse_ref(entt);
  36585. ENTT_ASSERT(entt != null && elem != tombstone, "Cannot set the required version");
  36586. elem = traits_type::combine(traits_type::to_integral(elem), traits_type::to_integral(entt));
  36587. packed[entity_to_pos(elem)] = entt;
  36588. return traits_type::to_version(entt);
  36589. }
  36590. /**
  36591. * @brief Erases an entity from a sparse set.
  36592. *
  36593. * @warning
  36594. * Attempting to erase an entity that doesn't belong to the sparse set
  36595. * results in undefined behavior.
  36596. *
  36597. * @param entt A valid identifier.
  36598. */
  36599. void erase(const entity_type entt) {
  36600. const auto it = to_iterator(entt);
  36601. pop(it, it + 1u);
  36602. }
  36603. /**
  36604. * @brief Erases entities from a set.
  36605. *
  36606. * @sa erase
  36607. *
  36608. * @tparam It Type of input iterator.
  36609. * @param first An iterator to the first element of the range of entities.
  36610. * @param last An iterator past the last element of the range of entities.
  36611. */
  36612. template<typename It>
  36613. void erase(It first, It last) {
  36614. if constexpr(std::is_same_v<It, basic_iterator>) {
  36615. pop(first, last);
  36616. } else {
  36617. for(; first != last; ++first) {
  36618. erase(*first);
  36619. }
  36620. }
  36621. }
  36622. /**
  36623. * @brief Removes an entity from a sparse set if it exists.
  36624. * @param entt A valid identifier.
  36625. * @return True if the entity is actually removed, false otherwise.
  36626. */
  36627. bool remove(const entity_type entt) {
  36628. return contains(entt) && (erase(entt), true);
  36629. }
  36630. /**
  36631. * @brief Removes entities from a sparse set if they exist.
  36632. * @tparam It Type of input iterator.
  36633. * @param first An iterator to the first element of the range of entities.
  36634. * @param last An iterator past the last element of the range of entities.
  36635. * @return The number of entities actually removed.
  36636. */
  36637. template<typename It>
  36638. size_type remove(It first, It last) {
  36639. size_type count{};
  36640. if constexpr(std::is_same_v<It, basic_iterator>) {
  36641. while(first != last) {
  36642. while(first != last && !contains(*first)) {
  36643. ++first;
  36644. }
  36645. const auto it = first;
  36646. while(first != last && contains(*first)) {
  36647. ++first;
  36648. }
  36649. count += static_cast<size_type>(std::distance(it, first));
  36650. erase(it, first);
  36651. }
  36652. } else {
  36653. for(; first != last; ++first) {
  36654. count += remove(*first);
  36655. }
  36656. }
  36657. return count;
  36658. }
  36659. /*! @brief Removes all tombstones from a sparse set. */
  36660. void compact() {
  36661. if(mode == deletion_policy::in_place) {
  36662. size_type from = packed.size();
  36663. size_type pos = std::exchange(head, max_size);
  36664. for(; from && packed[from - 1u] == tombstone; --from) {}
  36665. while(pos != max_size) {
  36666. if(const auto to = std::exchange(pos, entity_to_pos(packed[pos])); to < from) {
  36667. --from;
  36668. swap_or_move(from, to);
  36669. packed[to] = packed[from];
  36670. const auto elem = static_cast<typename traits_type::entity_type>(to);
  36671. sparse_ref(packed[to]) = traits_type::combine(elem, traits_type::to_integral(packed[to]));
  36672. for(; from && packed[from - 1u] == tombstone; --from) {}
  36673. }
  36674. }
  36675. packed.erase(packed.begin() + static_cast<difference_type>(from), packed.end());
  36676. }
  36677. }
  36678. /**
  36679. * @brief Swaps two entities in a sparse set.
  36680. *
  36681. * For what it's worth, this function affects both the internal sparse array
  36682. * and the internal packed array. Users should not care of that anyway.
  36683. *
  36684. * @warning
  36685. * Attempting to swap entities that don't belong to the sparse set results
  36686. * in undefined behavior.
  36687. *
  36688. * @param lhs A valid identifier.
  36689. * @param rhs A valid identifier.
  36690. */
  36691. void swap_elements(const entity_type lhs, const entity_type rhs) {
  36692. const auto from = index(lhs);
  36693. const auto to = index(rhs);
  36694. // basic no-leak guarantee if swapping throws
  36695. swap_or_move(from, to);
  36696. swap_at(from, to);
  36697. }
  36698. /**
  36699. * @brief Sort the first count elements according to the given comparison
  36700. * function.
  36701. *
  36702. * The comparison function object must return `true` if the first element
  36703. * is _less_ than the second one, `false` otherwise. The signature of the
  36704. * comparison function should be equivalent to the following:
  36705. *
  36706. * @code{.cpp}
  36707. * bool(const Entity, const Entity);
  36708. * @endcode
  36709. *
  36710. * Moreover, the comparison function object shall induce a
  36711. * _strict weak ordering_ on the values.
  36712. *
  36713. * The sort function object must offer a member function template
  36714. * `operator()` that accepts three arguments:
  36715. *
  36716. * * An iterator to the first element of the range to sort.
  36717. * * An iterator past the last element of the range to sort.
  36718. * * A comparison function to use to compare the elements.
  36719. *
  36720. * @tparam Compare Type of comparison function object.
  36721. * @tparam Sort Type of sort function object.
  36722. * @tparam Args Types of arguments to forward to the sort function object.
  36723. * @param length Number of elements to sort.
  36724. * @param compare A valid comparison function object.
  36725. * @param algo A valid sort function object.
  36726. * @param args Arguments to forward to the sort function object, if any.
  36727. */
  36728. template<typename Compare, typename Sort = std_sort, typename... Args>
  36729. void sort_n(const size_type length, Compare compare, Sort algo = Sort{}, Args &&...args) {
  36730. ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed");
  36731. ENTT_ASSERT(!(length > packed.size()), "Length exceeds the number of elements");
  36732. algo(packed.rend() - static_cast<difference_type>(length), packed.rend(), std::move(compare), std::forward<Args>(args)...);
  36733. for(size_type pos{}; pos < length; ++pos) {
  36734. auto curr = pos;
  36735. auto next = index(packed[curr]);
  36736. while(curr != next) {
  36737. const auto idx = index(packed[next]);
  36738. const auto entt = packed[curr];
  36739. swap_or_move(next, idx);
  36740. const auto elem = static_cast<typename traits_type::entity_type>(curr);
  36741. sparse_ref(entt) = traits_type::combine(elem, traits_type::to_integral(packed[curr]));
  36742. curr = std::exchange(next, idx);
  36743. }
  36744. }
  36745. }
  36746. /**
  36747. * @brief Sort all elements according to the given comparison function.
  36748. *
  36749. * @sa sort_n
  36750. *
  36751. * @tparam Compare Type of comparison function object.
  36752. * @tparam Sort Type of sort function object.
  36753. * @tparam Args Types of arguments to forward to the sort function object.
  36754. * @param compare A valid comparison function object.
  36755. * @param algo A valid sort function object.
  36756. * @param args Arguments to forward to the sort function object, if any.
  36757. */
  36758. template<typename Compare, typename Sort = std_sort, typename... Args>
  36759. void sort(Compare compare, Sort algo = Sort{}, Args &&...args) {
  36760. const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size();
  36761. sort_n(len, std::move(compare), std::move(algo), std::forward<Args>(args)...);
  36762. }
  36763. /**
  36764. * @brief Sort entities according to their order in a range.
  36765. *
  36766. * Entities that are part of both the sparse set and the range are ordered
  36767. * internally according to the order they have in the range.<br/>
  36768. * All other entities goes to the end of the sparse set and there are no
  36769. * guarantees on their order.
  36770. *
  36771. * @tparam It Type of input iterator.
  36772. * @param first An iterator to the first element of the range of entities.
  36773. * @param last An iterator past the last element of the range of entities.
  36774. * @return An iterator past the last of the elements actually shared.
  36775. */
  36776. template<typename It>
  36777. iterator sort_as(It first, It last) {
  36778. ENTT_ASSERT((mode != deletion_policy::in_place) || (head == max_size), "Sorting with tombstones not allowed");
  36779. const size_type len = (mode == deletion_policy::swap_only) ? head : packed.size();
  36780. auto it = end() - static_cast<difference_type>(len);
  36781. for(const auto other = end(); (it != other) && (first != last); ++first) {
  36782. if(const auto curr = *first; contains(curr)) {
  36783. if(const auto entt = *it; entt != curr) {
  36784. // basic no-leak guarantee (with invalid state) if swapping throws
  36785. swap_elements(entt, curr);
  36786. }
  36787. ++it;
  36788. }
  36789. }
  36790. return it;
  36791. }
  36792. /*! @brief Clears a sparse set. */
  36793. void clear() {
  36794. pop_all();
  36795. // sanity check to avoid subtle issues due to storage classes
  36796. ENTT_ASSERT((compact(), size()) == 0u, "Non-empty set");
  36797. head = policy_to_head();
  36798. packed.clear();
  36799. }
  36800. /**
  36801. * @brief Returns a type info object for the value type, if any.
  36802. * @return A type info object for the value type, if any.
  36803. */
  36804. [[nodiscard]] const type_info &info() const noexcept {
  36805. return *descriptor;
  36806. }
  36807. /*! @copydoc info */
  36808. [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept {
  36809. return info();
  36810. }
  36811. /**
  36812. * @brief Forwards variables to derived classes, if any.
  36813. * @tparam Type Type of the element to forward.
  36814. * @param value The element to forward.
  36815. */
  36816. template<typename Type>
  36817. void bind(Type &&value) noexcept {
  36818. bind_any(forward_as_any(std::forward<Type>(value)));
  36819. }
  36820. private:
  36821. sparse_container_type sparse;
  36822. packed_container_type packed;
  36823. const type_info *descriptor;
  36824. deletion_policy mode;
  36825. size_type head;
  36826. };
  36827. } // namespace entt
  36828. #endif
  36829. // #include "entity/storage.hpp"
  36830. #ifndef ENTT_ENTITY_STORAGE_HPP
  36831. #define ENTT_ENTITY_STORAGE_HPP
  36832. #include <cstddef>
  36833. #include <iterator>
  36834. #include <memory>
  36835. #include <tuple>
  36836. #include <type_traits>
  36837. #include <utility>
  36838. #include <vector>
  36839. // #include "../config/config.h"
  36840. // #include "../core/bit.hpp"
  36841. // #include "../core/iterator.hpp"
  36842. // #include "../core/memory.hpp"
  36843. // #include "../core/type_info.hpp"
  36844. // #include "component.hpp"
  36845. // #include "entity.hpp"
  36846. // #include "fwd.hpp"
  36847. // #include "sparse_set.hpp"
  36848. namespace entt {
  36849. /*! @cond TURN_OFF_DOXYGEN */
  36850. namespace internal {
  36851. template<typename Container, auto Page>
  36852. class storage_iterator final {
  36853. friend storage_iterator<const Container, Page>;
  36854. using container_type = std::remove_const_t<Container>;
  36855. using alloc_traits = std::allocator_traits<typename container_type::allocator_type>;
  36856. using iterator_traits = std::iterator_traits<std::conditional_t<
  36857. std::is_const_v<Container>,
  36858. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::const_pointer,
  36859. typename alloc_traits::template rebind_traits<typename std::pointer_traits<typename container_type::value_type>::element_type>::pointer>>;
  36860. public:
  36861. using value_type = typename iterator_traits::value_type;
  36862. using pointer = typename iterator_traits::pointer;
  36863. using reference = typename iterator_traits::reference;
  36864. using difference_type = typename iterator_traits::difference_type;
  36865. using iterator_category = std::random_access_iterator_tag;
  36866. constexpr storage_iterator() noexcept = default;
  36867. constexpr storage_iterator(Container *ref, const difference_type idx) noexcept
  36868. : payload{ref},
  36869. offset{idx} {}
  36870. template<bool Const = std::is_const_v<Container>, typename = std::enable_if_t<Const>>
  36871. constexpr storage_iterator(const storage_iterator<std::remove_const_t<Container>, Page> &other) noexcept
  36872. : storage_iterator{other.payload, other.offset} {}
  36873. constexpr storage_iterator &operator++() noexcept {
  36874. return --offset, *this;
  36875. }
  36876. constexpr storage_iterator operator++(int) noexcept {
  36877. const storage_iterator orig = *this;
  36878. return ++(*this), orig;
  36879. }
  36880. constexpr storage_iterator &operator--() noexcept {
  36881. return ++offset, *this;
  36882. }
  36883. constexpr storage_iterator operator--(int) noexcept {
  36884. const storage_iterator orig = *this;
  36885. return operator--(), orig;
  36886. }
  36887. constexpr storage_iterator &operator+=(const difference_type value) noexcept {
  36888. offset -= value;
  36889. return *this;
  36890. }
  36891. constexpr storage_iterator operator+(const difference_type value) const noexcept {
  36892. storage_iterator copy = *this;
  36893. return (copy += value);
  36894. }
  36895. constexpr storage_iterator &operator-=(const difference_type value) noexcept {
  36896. return (*this += -value);
  36897. }
  36898. constexpr storage_iterator operator-(const difference_type value) const noexcept {
  36899. return (*this + -value);
  36900. }
  36901. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  36902. const auto pos = static_cast<typename Container::size_type>(index() - value);
  36903. return (*payload)[pos / Page][fast_mod(static_cast<std::size_t>(pos), Page)];
  36904. }
  36905. [[nodiscard]] constexpr pointer operator->() const noexcept {
  36906. return std::addressof(operator[](0));
  36907. }
  36908. [[nodiscard]] constexpr reference operator*() const noexcept {
  36909. return operator[](0);
  36910. }
  36911. [[nodiscard]] constexpr difference_type index() const noexcept {
  36912. return offset - 1;
  36913. }
  36914. private:
  36915. Container *payload;
  36916. difference_type offset;
  36917. };
  36918. template<typename Lhs, typename Rhs, auto Page>
  36919. [[nodiscard]] constexpr std::ptrdiff_t operator-(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  36920. return rhs.index() - lhs.index();
  36921. }
  36922. template<typename Lhs, typename Rhs, auto Page>
  36923. [[nodiscard]] constexpr bool operator==(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  36924. return lhs.index() == rhs.index();
  36925. }
  36926. template<typename Lhs, typename Rhs, auto Page>
  36927. [[nodiscard]] constexpr bool operator!=(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  36928. return !(lhs == rhs);
  36929. }
  36930. template<typename Lhs, typename Rhs, auto Page>
  36931. [[nodiscard]] constexpr bool operator<(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  36932. return lhs.index() > rhs.index();
  36933. }
  36934. template<typename Lhs, typename Rhs, auto Page>
  36935. [[nodiscard]] constexpr bool operator>(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  36936. return rhs < lhs;
  36937. }
  36938. template<typename Lhs, typename Rhs, auto Page>
  36939. [[nodiscard]] constexpr bool operator<=(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  36940. return !(lhs > rhs);
  36941. }
  36942. template<typename Lhs, typename Rhs, auto Page>
  36943. [[nodiscard]] constexpr bool operator>=(const storage_iterator<Lhs, Page> &lhs, const storage_iterator<Rhs, Page> &rhs) noexcept {
  36944. return !(lhs < rhs);
  36945. }
  36946. template<typename It, typename... Other>
  36947. class extended_storage_iterator final {
  36948. template<typename Iter, typename... Args>
  36949. friend class extended_storage_iterator;
  36950. public:
  36951. using iterator_type = It;
  36952. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::forward_as_tuple(*std::declval<Other>()...)));
  36953. using pointer = input_iterator_pointer<value_type>;
  36954. using reference = value_type;
  36955. using difference_type = std::ptrdiff_t;
  36956. using iterator_category = std::input_iterator_tag;
  36957. using iterator_concept = std::forward_iterator_tag;
  36958. constexpr extended_storage_iterator()
  36959. : it{} {}
  36960. constexpr extended_storage_iterator(iterator_type base, Other... other)
  36961. : it{base, other...} {}
  36962. template<typename... Args, typename = std::enable_if_t<(!std::is_same_v<Other, Args> && ...) && (std::is_constructible_v<Other, Args> && ...)>>
  36963. constexpr extended_storage_iterator(const extended_storage_iterator<It, Args...> &other)
  36964. : it{other.it} {}
  36965. constexpr extended_storage_iterator &operator++() noexcept {
  36966. return ++std::get<It>(it), (++std::get<Other>(it), ...), *this;
  36967. }
  36968. constexpr extended_storage_iterator operator++(int) noexcept {
  36969. const extended_storage_iterator orig = *this;
  36970. return ++(*this), orig;
  36971. }
  36972. [[nodiscard]] constexpr pointer operator->() const noexcept {
  36973. return operator*();
  36974. }
  36975. [[nodiscard]] constexpr reference operator*() const noexcept {
  36976. return {*std::get<It>(it), *std::get<Other>(it)...};
  36977. }
  36978. [[nodiscard]] constexpr iterator_type base() const noexcept {
  36979. return std::get<It>(it);
  36980. }
  36981. template<typename... Lhs, typename... Rhs>
  36982. friend constexpr bool operator==(const extended_storage_iterator<Lhs...> &, const extended_storage_iterator<Rhs...> &) noexcept;
  36983. private:
  36984. std::tuple<It, Other...> it;
  36985. };
  36986. template<typename... Lhs, typename... Rhs>
  36987. [[nodiscard]] constexpr bool operator==(const extended_storage_iterator<Lhs...> &lhs, const extended_storage_iterator<Rhs...> &rhs) noexcept {
  36988. return std::get<0>(lhs.it) == std::get<0>(rhs.it);
  36989. }
  36990. template<typename... Lhs, typename... Rhs>
  36991. [[nodiscard]] constexpr bool operator!=(const extended_storage_iterator<Lhs...> &lhs, const extended_storage_iterator<Rhs...> &rhs) noexcept {
  36992. return !(lhs == rhs);
  36993. }
  36994. } // namespace internal
  36995. /*! @endcond */
  36996. /**
  36997. * @brief Storage implementation.
  36998. *
  36999. * Internal data structures arrange elements to maximize performance. There are
  37000. * no guarantees that objects are returned in the insertion order when iterate
  37001. * a storage. Do not make assumption on the order in any case.
  37002. *
  37003. * @warning
  37004. * Empty types aren't explicitly instantiated. Therefore, many of the functions
  37005. * normally available for non-empty types will not be available for empty ones.
  37006. *
  37007. * @tparam Type Element type.
  37008. * @tparam Entity A valid entity type.
  37009. * @tparam Allocator Type of allocator used to manage memory and elements.
  37010. */
  37011. template<typename Type, typename Entity, typename Allocator, typename>
  37012. class basic_storage: public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  37013. using alloc_traits = std::allocator_traits<Allocator>;
  37014. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  37015. using container_type = std::vector<typename alloc_traits::pointer, typename alloc_traits::template rebind_alloc<typename alloc_traits::pointer>>;
  37016. using underlying_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  37017. using underlying_iterator = typename underlying_type::basic_iterator;
  37018. using traits_type = component_traits<Type, Entity>;
  37019. [[nodiscard]] auto &element_at(const std::size_t pos) const {
  37020. return payload[pos / traits_type::page_size][fast_mod(pos, traits_type::page_size)];
  37021. }
  37022. auto assure_at_least(const std::size_t pos) {
  37023. const auto idx = pos / traits_type::page_size;
  37024. if(!(idx < payload.size())) {
  37025. auto curr = payload.size();
  37026. allocator_type allocator{get_allocator()};
  37027. payload.resize(idx + 1u, nullptr);
  37028. ENTT_TRY {
  37029. for(const auto last = payload.size(); curr < last; ++curr) {
  37030. payload[curr] = alloc_traits::allocate(allocator, traits_type::page_size);
  37031. }
  37032. }
  37033. ENTT_CATCH {
  37034. payload.resize(curr);
  37035. ENTT_THROW;
  37036. }
  37037. }
  37038. return payload[idx] + fast_mod(pos, traits_type::page_size);
  37039. }
  37040. template<typename... Args>
  37041. auto emplace_element(const Entity entt, const bool force_back, Args &&...args) {
  37042. const auto it = base_type::try_emplace(entt, force_back);
  37043. ENTT_TRY {
  37044. auto *elem = to_address(assure_at_least(static_cast<size_type>(it.index())));
  37045. entt::uninitialized_construct_using_allocator(elem, get_allocator(), std::forward<Args>(args)...);
  37046. }
  37047. ENTT_CATCH {
  37048. base_type::pop(it, it + 1u);
  37049. ENTT_THROW;
  37050. }
  37051. return it;
  37052. }
  37053. void shrink_to_size(const std::size_t sz) {
  37054. const auto from = (sz + traits_type::page_size - 1u) / traits_type::page_size;
  37055. allocator_type allocator{get_allocator()};
  37056. for(auto pos = sz, length = base_type::size(); pos < length; ++pos) {
  37057. if constexpr(traits_type::in_place_delete) {
  37058. if(base_type::data()[pos] != tombstone) {
  37059. alloc_traits::destroy(allocator, std::addressof(element_at(pos)));
  37060. }
  37061. } else {
  37062. alloc_traits::destroy(allocator, std::addressof(element_at(pos)));
  37063. }
  37064. }
  37065. for(auto pos = from, last = payload.size(); pos < last; ++pos) {
  37066. alloc_traits::deallocate(allocator, payload[pos], traits_type::page_size);
  37067. }
  37068. payload.resize(from);
  37069. payload.shrink_to_fit();
  37070. }
  37071. void swap_at(const std::size_t lhs, const std::size_t rhs) {
  37072. using std::swap;
  37073. swap(element_at(lhs), element_at(rhs));
  37074. }
  37075. void move_to(const std::size_t lhs, const std::size_t rhs) {
  37076. auto &elem = element_at(lhs);
  37077. allocator_type allocator{get_allocator()};
  37078. entt::uninitialized_construct_using_allocator(to_address(assure_at_least(rhs)), allocator, std::move(elem));
  37079. alloc_traits::destroy(allocator, std::addressof(elem));
  37080. }
  37081. private:
  37082. [[nodiscard]] const void *get_at(const std::size_t pos) const final {
  37083. return std::addressof(element_at(pos));
  37084. }
  37085. void swap_or_move([[maybe_unused]] const std::size_t from, [[maybe_unused]] const std::size_t to) override {
  37086. static constexpr bool is_pinned_type = !(std::is_move_constructible_v<Type> && std::is_move_assignable_v<Type>);
  37087. // use a runtime value to avoid compile-time suppression that drives the code coverage tool crazy
  37088. ENTT_ASSERT((from + 1u) && !is_pinned_type, "Pinned type");
  37089. if constexpr(!is_pinned_type) {
  37090. if constexpr(traits_type::in_place_delete) {
  37091. (base_type::operator[](to) == tombstone) ? move_to(from, to) : swap_at(from, to);
  37092. } else {
  37093. swap_at(from, to);
  37094. }
  37095. }
  37096. }
  37097. protected:
  37098. /**
  37099. * @brief Erases entities from a storage.
  37100. * @param first An iterator to the first element of the range of entities.
  37101. * @param last An iterator past the last element of the range of entities.
  37102. */
  37103. void pop(underlying_iterator first, underlying_iterator last) override {
  37104. for(allocator_type allocator{get_allocator()}; first != last; ++first) {
  37105. // cannot use first.index() because it would break with cross iterators
  37106. auto &elem = element_at(base_type::index(*first));
  37107. if constexpr(traits_type::in_place_delete) {
  37108. base_type::in_place_pop(first);
  37109. alloc_traits::destroy(allocator, std::addressof(elem));
  37110. } else {
  37111. auto &other = element_at(base_type::size() - 1u);
  37112. // destroying on exit allows reentrant destructors
  37113. [[maybe_unused]] auto unused = std::exchange(elem, std::move(other));
  37114. alloc_traits::destroy(allocator, std::addressof(other));
  37115. base_type::swap_and_pop(first);
  37116. }
  37117. }
  37118. }
  37119. /*! @brief Erases all entities of a storage. */
  37120. void pop_all() override {
  37121. allocator_type allocator{get_allocator()};
  37122. for(auto first = base_type::begin(); !(first.index() < 0); ++first) {
  37123. if constexpr(traits_type::in_place_delete) {
  37124. if(*first != tombstone) {
  37125. base_type::in_place_pop(first);
  37126. alloc_traits::destroy(allocator, std::addressof(element_at(static_cast<size_type>(first.index()))));
  37127. }
  37128. } else {
  37129. base_type::swap_and_pop(first);
  37130. alloc_traits::destroy(allocator, std::addressof(element_at(static_cast<size_type>(first.index()))));
  37131. }
  37132. }
  37133. }
  37134. /**
  37135. * @brief Assigns an entity to a storage.
  37136. * @param entt A valid identifier.
  37137. * @param value Optional opaque value.
  37138. * @param force_back Force back insertion.
  37139. * @return Iterator pointing to the emplaced element.
  37140. */
  37141. underlying_iterator try_emplace([[maybe_unused]] const Entity entt, [[maybe_unused]] const bool force_back, const void *value) override {
  37142. if(value != nullptr) {
  37143. if constexpr(std::is_copy_constructible_v<element_type>) {
  37144. return emplace_element(entt, force_back, *static_cast<const element_type *>(value));
  37145. } else {
  37146. return base_type::end();
  37147. }
  37148. } else {
  37149. if constexpr(std::is_default_constructible_v<element_type>) {
  37150. return emplace_element(entt, force_back);
  37151. } else {
  37152. return base_type::end();
  37153. }
  37154. }
  37155. }
  37156. public:
  37157. /*! @brief Allocator type. */
  37158. using allocator_type = Allocator;
  37159. /*! @brief Base type. */
  37160. using base_type = underlying_type;
  37161. /*! @brief Element type. */
  37162. using element_type = Type;
  37163. /*! @brief Type of the objects assigned to entities. */
  37164. using value_type = element_type;
  37165. /*! @brief Underlying entity identifier. */
  37166. using entity_type = Entity;
  37167. /*! @brief Unsigned integer type. */
  37168. using size_type = std::size_t;
  37169. /*! @brief Signed integer type. */
  37170. using difference_type = std::ptrdiff_t;
  37171. /*! @brief Pointer type to contained elements. */
  37172. using pointer = typename container_type::pointer;
  37173. /*! @brief Constant pointer type to contained elements. */
  37174. using const_pointer = typename alloc_traits::template rebind_traits<typename alloc_traits::const_pointer>::const_pointer;
  37175. /*! @brief Random access iterator type. */
  37176. using iterator = internal::storage_iterator<container_type, traits_type::page_size>;
  37177. /*! @brief Constant random access iterator type. */
  37178. using const_iterator = internal::storage_iterator<const container_type, traits_type::page_size>;
  37179. /*! @brief Reverse iterator type. */
  37180. using reverse_iterator = std::reverse_iterator<iterator>;
  37181. /*! @brief Constant reverse iterator type. */
  37182. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  37183. /*! @brief Extended iterable storage proxy. */
  37184. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator, iterator>>;
  37185. /*! @brief Constant extended iterable storage proxy. */
  37186. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator, const_iterator>>;
  37187. /*! @brief Extended reverse iterable storage proxy. */
  37188. using reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::reverse_iterator, reverse_iterator>>;
  37189. /*! @brief Constant extended reverse iterable storage proxy. */
  37190. using const_reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_reverse_iterator, const_reverse_iterator>>;
  37191. /*! @brief Storage deletion policy. */
  37192. static constexpr deletion_policy storage_policy{traits_type::in_place_delete};
  37193. /*! @brief Default constructor. */
  37194. basic_storage()
  37195. : basic_storage{allocator_type{}} {}
  37196. /**
  37197. * @brief Constructs an empty storage with a given allocator.
  37198. * @param allocator The allocator to use.
  37199. */
  37200. explicit basic_storage(const allocator_type &allocator)
  37201. : base_type{type_id<element_type>(), storage_policy, allocator},
  37202. payload{allocator} {}
  37203. /*! @brief Default copy constructor, deleted on purpose. */
  37204. basic_storage(const basic_storage &) = delete;
  37205. /**
  37206. * @brief Move constructor.
  37207. * @param other The instance to move from.
  37208. */
  37209. basic_storage(basic_storage &&other) noexcept
  37210. : base_type{static_cast<base_type &&>(other)},
  37211. payload{std::move(other.payload)} {}
  37212. /**
  37213. * @brief Allocator-extended move constructor.
  37214. * @param other The instance to move from.
  37215. * @param allocator The allocator to use.
  37216. */
  37217. basic_storage(basic_storage &&other, const allocator_type &allocator)
  37218. : base_type{static_cast<base_type &&>(other), allocator},
  37219. payload{std::move(other.payload), allocator} {
  37220. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed");
  37221. }
  37222. /*! @brief Default destructor. */
  37223. // NOLINTNEXTLINE(bugprone-exception-escape)
  37224. ~basic_storage() override {
  37225. shrink_to_size(0u);
  37226. }
  37227. /**
  37228. * @brief Default copy assignment operator, deleted on purpose.
  37229. * @return This storage.
  37230. */
  37231. basic_storage &operator=(const basic_storage &) = delete;
  37232. /**
  37233. * @brief Move assignment operator.
  37234. * @param other The instance to move from.
  37235. * @return This storage.
  37236. */
  37237. basic_storage &operator=(basic_storage &&other) noexcept {
  37238. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a storage is not allowed");
  37239. swap(other);
  37240. return *this;
  37241. }
  37242. /**
  37243. * @brief Exchanges the contents with those of a given storage.
  37244. * @param other Storage to exchange the content with.
  37245. */
  37246. void swap(basic_storage &other) noexcept {
  37247. using std::swap;
  37248. swap(payload, other.payload);
  37249. base_type::swap(other);
  37250. }
  37251. /**
  37252. * @brief Returns the associated allocator.
  37253. * @return The associated allocator.
  37254. */
  37255. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  37256. return payload.get_allocator();
  37257. }
  37258. /**
  37259. * @brief Increases the capacity of a storage.
  37260. *
  37261. * If the new capacity is greater than the current capacity, new storage is
  37262. * allocated, otherwise the method does nothing.
  37263. *
  37264. * @param cap Desired capacity.
  37265. */
  37266. void reserve(const size_type cap) override {
  37267. if(cap != 0u) {
  37268. base_type::reserve(cap);
  37269. assure_at_least(cap - 1u);
  37270. }
  37271. }
  37272. /**
  37273. * @brief Returns the number of elements that a storage has currently
  37274. * allocated space for.
  37275. * @return Capacity of the storage.
  37276. */
  37277. [[nodiscard]] size_type capacity() const noexcept override {
  37278. return payload.size() * traits_type::page_size;
  37279. }
  37280. /*! @brief Requests the removal of unused capacity. */
  37281. void shrink_to_fit() override {
  37282. base_type::shrink_to_fit();
  37283. shrink_to_size(base_type::size());
  37284. }
  37285. /**
  37286. * @brief Direct access to the array of objects.
  37287. * @return A pointer to the array of objects.
  37288. */
  37289. [[nodiscard]] const_pointer raw() const noexcept {
  37290. return payload.data();
  37291. }
  37292. /*! @copydoc raw */
  37293. [[nodiscard]] pointer raw() noexcept {
  37294. return payload.data();
  37295. }
  37296. /**
  37297. * @brief Returns an iterator to the beginning.
  37298. *
  37299. * If the storage is empty, the returned iterator will be equal to `end()`.
  37300. *
  37301. * @return An iterator to the first instance of the internal array.
  37302. */
  37303. [[nodiscard]] const_iterator cbegin() const noexcept {
  37304. const auto pos = static_cast<difference_type>(base_type::size());
  37305. return const_iterator{&payload, pos};
  37306. }
  37307. /*! @copydoc cbegin */
  37308. [[nodiscard]] const_iterator begin() const noexcept {
  37309. return cbegin();
  37310. }
  37311. /*! @copydoc begin */
  37312. [[nodiscard]] iterator begin() noexcept {
  37313. const auto pos = static_cast<difference_type>(base_type::size());
  37314. return iterator{&payload, pos};
  37315. }
  37316. /**
  37317. * @brief Returns an iterator to the end.
  37318. * @return An iterator to the element following the last instance of the
  37319. * internal array.
  37320. */
  37321. [[nodiscard]] const_iterator cend() const noexcept {
  37322. return const_iterator{&payload, {}};
  37323. }
  37324. /*! @copydoc cend */
  37325. [[nodiscard]] const_iterator end() const noexcept {
  37326. return cend();
  37327. }
  37328. /*! @copydoc end */
  37329. [[nodiscard]] iterator end() noexcept {
  37330. return iterator{&payload, {}};
  37331. }
  37332. /**
  37333. * @brief Returns a reverse iterator to the beginning.
  37334. *
  37335. * If the storage is empty, the returned iterator will be equal to `rend()`.
  37336. *
  37337. * @return An iterator to the first instance of the reversed internal array.
  37338. */
  37339. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  37340. return std::make_reverse_iterator(cend());
  37341. }
  37342. /*! @copydoc crbegin */
  37343. [[nodiscard]] const_reverse_iterator rbegin() const noexcept {
  37344. return crbegin();
  37345. }
  37346. /*! @copydoc rbegin */
  37347. [[nodiscard]] reverse_iterator rbegin() noexcept {
  37348. return std::make_reverse_iterator(end());
  37349. }
  37350. /**
  37351. * @brief Returns a reverse iterator to the end.
  37352. * @return An iterator to the element following the last instance of the
  37353. * reversed internal array.
  37354. */
  37355. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  37356. return std::make_reverse_iterator(cbegin());
  37357. }
  37358. /*! @copydoc crend */
  37359. [[nodiscard]] const_reverse_iterator rend() const noexcept {
  37360. return crend();
  37361. }
  37362. /*! @copydoc rend */
  37363. [[nodiscard]] reverse_iterator rend() noexcept {
  37364. return std::make_reverse_iterator(begin());
  37365. }
  37366. /**
  37367. * @brief Returns the object assigned to an entity.
  37368. *
  37369. * @warning
  37370. * Attempting to use an entity that doesn't belong to the storage results in
  37371. * undefined behavior.
  37372. *
  37373. * @param entt A valid identifier.
  37374. * @return The object assigned to the entity.
  37375. */
  37376. [[nodiscard]] const value_type &get(const entity_type entt) const noexcept {
  37377. return element_at(base_type::index(entt));
  37378. }
  37379. /*! @copydoc get */
  37380. [[nodiscard]] value_type &get(const entity_type entt) noexcept {
  37381. return const_cast<value_type &>(std::as_const(*this).get(entt));
  37382. }
  37383. /**
  37384. * @brief Returns the object assigned to an entity as a tuple.
  37385. * @param entt A valid identifier.
  37386. * @return The object assigned to the entity as a tuple.
  37387. */
  37388. [[nodiscard]] std::tuple<const value_type &> get_as_tuple(const entity_type entt) const noexcept {
  37389. return std::forward_as_tuple(get(entt));
  37390. }
  37391. /*! @copydoc get_as_tuple */
  37392. [[nodiscard]] std::tuple<value_type &> get_as_tuple(const entity_type entt) noexcept {
  37393. return std::forward_as_tuple(get(entt));
  37394. }
  37395. /**
  37396. * @brief Assigns an entity to a storage and constructs its object.
  37397. *
  37398. * @warning
  37399. * Attempting to use an entity that already belongs to the storage results
  37400. * in undefined behavior.
  37401. *
  37402. * @tparam Args Types of arguments to use to construct the object.
  37403. * @param entt A valid identifier.
  37404. * @param args Parameters to use to construct an object for the entity.
  37405. * @return A reference to the newly created object.
  37406. */
  37407. template<typename... Args>
  37408. value_type &emplace(const entity_type entt, Args &&...args) {
  37409. if constexpr(std::is_aggregate_v<value_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<value_type>)) {
  37410. const auto it = emplace_element(entt, false, Type{std::forward<Args>(args)...});
  37411. return element_at(static_cast<size_type>(it.index()));
  37412. } else {
  37413. const auto it = emplace_element(entt, false, std::forward<Args>(args)...);
  37414. return element_at(static_cast<size_type>(it.index()));
  37415. }
  37416. }
  37417. /**
  37418. * @brief Updates the instance assigned to a given entity in-place.
  37419. * @tparam Func Types of the function objects to invoke.
  37420. * @param entt A valid identifier.
  37421. * @param func Valid function objects.
  37422. * @return A reference to the updated instance.
  37423. */
  37424. template<typename... Func>
  37425. value_type &patch(const entity_type entt, Func &&...func) {
  37426. const auto idx = base_type::index(entt);
  37427. auto &elem = element_at(idx);
  37428. (std::forward<Func>(func)(elem), ...);
  37429. return elem;
  37430. }
  37431. /**
  37432. * @brief Assigns one or more entities to a storage and constructs their
  37433. * objects from a given instance.
  37434. *
  37435. * @warning
  37436. * Attempting to assign an entity that already belongs to the storage
  37437. * results in undefined behavior.
  37438. *
  37439. * @tparam It Type of input iterator.
  37440. * @param first An iterator to the first element of the range of entities.
  37441. * @param last An iterator past the last element of the range of entities.
  37442. * @param value An instance of the object to construct.
  37443. * @return Iterator pointing to the first element inserted, if any.
  37444. */
  37445. template<typename It>
  37446. iterator insert(It first, It last, const value_type &value = {}) {
  37447. for(; first != last; ++first) {
  37448. emplace_element(*first, true, value);
  37449. }
  37450. return begin();
  37451. }
  37452. /**
  37453. * @brief Assigns one or more entities to a storage and constructs their
  37454. * objects from a given range.
  37455. *
  37456. * @sa construct
  37457. *
  37458. * @tparam EIt Type of input iterator.
  37459. * @tparam CIt Type of input iterator.
  37460. * @param first An iterator to the first element of the range of entities.
  37461. * @param last An iterator past the last element of the range of entities.
  37462. * @param from An iterator to the first element of the range of objects.
  37463. * @return Iterator pointing to the first element inserted, if any.
  37464. */
  37465. template<typename EIt, typename CIt, typename = std::enable_if_t<std::is_same_v<typename std::iterator_traits<CIt>::value_type, value_type>>>
  37466. iterator insert(EIt first, EIt last, CIt from) {
  37467. for(; first != last; ++first, ++from) {
  37468. emplace_element(*first, true, *from);
  37469. }
  37470. return begin();
  37471. }
  37472. /**
  37473. * @brief Returns an iterable object to use to _visit_ a storage.
  37474. *
  37475. * The iterable object returns a tuple that contains the current entity and
  37476. * a reference to its element.
  37477. *
  37478. * @return An iterable object to use to _visit_ the storage.
  37479. */
  37480. [[nodiscard]] iterable each() noexcept {
  37481. return iterable{{base_type::begin(), begin()}, {base_type::end(), end()}};
  37482. }
  37483. /*! @copydoc each */
  37484. [[nodiscard]] const_iterable each() const noexcept {
  37485. return const_iterable{{base_type::cbegin(), cbegin()}, {base_type::cend(), cend()}};
  37486. }
  37487. /**
  37488. * @brief Returns a reverse iterable object to use to _visit_ a storage.
  37489. *
  37490. * @sa each
  37491. *
  37492. * @return A reverse iterable object to use to _visit_ the storage.
  37493. */
  37494. [[nodiscard]] reverse_iterable reach() noexcept {
  37495. return reverse_iterable{{base_type::rbegin(), rbegin()}, {base_type::rend(), rend()}};
  37496. }
  37497. /*! @copydoc reach */
  37498. [[nodiscard]] const_reverse_iterable reach() const noexcept {
  37499. return const_reverse_iterable{{base_type::crbegin(), crbegin()}, {base_type::crend(), crend()}};
  37500. }
  37501. private:
  37502. container_type payload;
  37503. };
  37504. /*! @copydoc basic_storage */
  37505. template<typename Type, typename Entity, typename Allocator>
  37506. class basic_storage<Type, Entity, Allocator, std::enable_if_t<component_traits<Type, Entity>::page_size == 0u>>
  37507. : public basic_sparse_set<Entity, typename std::allocator_traits<Allocator>::template rebind_alloc<Entity>> {
  37508. using alloc_traits = std::allocator_traits<Allocator>;
  37509. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  37510. using traits_type = component_traits<Type, Entity>;
  37511. public:
  37512. /*! @brief Allocator type. */
  37513. using allocator_type = Allocator;
  37514. /*! @brief Base type. */
  37515. using base_type = basic_sparse_set<Entity, typename alloc_traits::template rebind_alloc<Entity>>;
  37516. /*! @brief Element type. */
  37517. using element_type = Type;
  37518. /*! @brief Type of the objects assigned to entities. */
  37519. using value_type = void;
  37520. /*! @brief Underlying entity identifier. */
  37521. using entity_type = Entity;
  37522. /*! @brief Unsigned integer type. */
  37523. using size_type = std::size_t;
  37524. /*! @brief Signed integer type. */
  37525. using difference_type = std::ptrdiff_t;
  37526. /*! @brief Extended iterable storage proxy. */
  37527. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator>>;
  37528. /*! @brief Constant extended iterable storage proxy. */
  37529. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator>>;
  37530. /*! @brief Extended reverse iterable storage proxy. */
  37531. using reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::reverse_iterator>>;
  37532. /*! @brief Constant extended reverse iterable storage proxy. */
  37533. using const_reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_reverse_iterator>>;
  37534. /*! @brief Storage deletion policy. */
  37535. static constexpr deletion_policy storage_policy{traits_type::in_place_delete};
  37536. /*! @brief Default constructor. */
  37537. basic_storage()
  37538. : basic_storage{allocator_type{}} {}
  37539. /**
  37540. * @brief Constructs an empty container with a given allocator.
  37541. * @param allocator The allocator to use.
  37542. */
  37543. explicit basic_storage(const allocator_type &allocator)
  37544. : base_type{type_id<element_type>(), storage_policy, allocator} {}
  37545. /*! @brief Default copy constructor, deleted on purpose. */
  37546. basic_storage(const basic_storage &) = delete;
  37547. /**
  37548. * @brief Move constructor.
  37549. * @param other The instance to move from.
  37550. */
  37551. basic_storage(basic_storage &&other) noexcept = default;
  37552. /**
  37553. * @brief Allocator-extended move constructor.
  37554. * @param other The instance to move from.
  37555. * @param allocator The allocator to use.
  37556. */
  37557. basic_storage(basic_storage &&other, const allocator_type &allocator)
  37558. : base_type{std::move(other), allocator} {}
  37559. /*! @brief Default destructor. */
  37560. ~basic_storage() override = default;
  37561. /**
  37562. * @brief Default copy assignment operator, deleted on purpose.
  37563. * @return This storage.
  37564. */
  37565. basic_storage &operator=(const basic_storage &) = delete;
  37566. /**
  37567. * @brief Move assignment operator.
  37568. * @param other The instance to move from.
  37569. * @return This storage.
  37570. */
  37571. basic_storage &operator=(basic_storage &&other) noexcept = default;
  37572. /**
  37573. * @brief Returns the associated allocator.
  37574. * @return The associated allocator.
  37575. */
  37576. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  37577. // std::allocator<void> has no cross constructors (waiting for C++20)
  37578. if constexpr(std::is_void_v<element_type> && !std::is_constructible_v<allocator_type, typename base_type::allocator_type>) {
  37579. return allocator_type{};
  37580. } else {
  37581. return allocator_type{base_type::get_allocator()};
  37582. }
  37583. }
  37584. /**
  37585. * @brief Returns the object assigned to an entity, that is `void`.
  37586. *
  37587. * @warning
  37588. * Attempting to use an entity that doesn't belong to the storage results in
  37589. * undefined behavior.
  37590. *
  37591. * @param entt A valid identifier.
  37592. */
  37593. void get([[maybe_unused]] const entity_type entt) const noexcept {
  37594. ENTT_ASSERT(base_type::contains(entt), "Invalid entity");
  37595. }
  37596. /**
  37597. * @brief Returns an empty tuple.
  37598. * @param entt A valid identifier.
  37599. * @return Returns an empty tuple.
  37600. */
  37601. [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept {
  37602. ENTT_ASSERT(base_type::contains(entt), "Invalid entity");
  37603. return std::tuple{};
  37604. }
  37605. /**
  37606. * @brief Assigns an entity to a storage and constructs its object.
  37607. *
  37608. * @warning
  37609. * Attempting to use an entity that already belongs to the storage results
  37610. * in undefined behavior.
  37611. *
  37612. * @param entt A valid identifier.
  37613. */
  37614. void emplace(const entity_type entt) {
  37615. base_type::try_emplace(entt, false);
  37616. }
  37617. /**
  37618. * @brief Updates the instance assigned to a given entity in-place.
  37619. * @tparam Func Types of the function objects to invoke.
  37620. * @param entt A valid identifier.
  37621. * @param func Valid function objects.
  37622. */
  37623. template<typename... Func>
  37624. void patch([[maybe_unused]] const entity_type entt, Func &&...func) {
  37625. ENTT_ASSERT(base_type::contains(entt), "Invalid entity");
  37626. (std::forward<Func>(func)(), ...);
  37627. }
  37628. /**
  37629. * @brief Assigns entities to a storage.
  37630. * @tparam It Type of input iterator.
  37631. * @param first An iterator to the first element of the range of entities.
  37632. * @param last An iterator past the last element of the range of entities.
  37633. */
  37634. template<typename It>
  37635. void insert(It first, It last) {
  37636. for(; first != last; ++first) {
  37637. base_type::try_emplace(*first, true);
  37638. }
  37639. }
  37640. /**
  37641. * @brief Returns an iterable object to use to _visit_ a storage.
  37642. *
  37643. * The iterable object returns a tuple that contains the current entity.
  37644. *
  37645. * @return An iterable object to use to _visit_ the storage.
  37646. */
  37647. [[nodiscard]] iterable each() noexcept {
  37648. return iterable{base_type::begin(), base_type::end()};
  37649. }
  37650. /*! @copydoc each */
  37651. [[nodiscard]] const_iterable each() const noexcept {
  37652. return const_iterable{base_type::cbegin(), base_type::cend()};
  37653. }
  37654. /**
  37655. * @brief Returns a reverse iterable object to use to _visit_ a storage.
  37656. *
  37657. * @sa each
  37658. *
  37659. * @return A reverse iterable object to use to _visit_ the storage.
  37660. */
  37661. [[nodiscard]] reverse_iterable reach() noexcept {
  37662. return reverse_iterable{{base_type::rbegin()}, {base_type::rend()}};
  37663. }
  37664. /*! @copydoc reach */
  37665. [[nodiscard]] const_reverse_iterable reach() const noexcept {
  37666. return const_reverse_iterable{{base_type::crbegin()}, {base_type::crend()}};
  37667. }
  37668. };
  37669. /**
  37670. * @brief Swap-only entity storage specialization.
  37671. * @tparam Entity A valid entity type.
  37672. * @tparam Allocator Type of allocator used to manage memory and elements.
  37673. */
  37674. template<typename Entity, typename Allocator>
  37675. class basic_storage<Entity, Entity, Allocator>
  37676. : public basic_sparse_set<Entity, Allocator> {
  37677. using alloc_traits = std::allocator_traits<Allocator>;
  37678. static_assert(std::is_same_v<typename alloc_traits::value_type, Entity>, "Invalid value type");
  37679. using underlying_iterator = typename basic_sparse_set<Entity, Allocator>::basic_iterator;
  37680. using traits_type = entt_traits<Entity>;
  37681. auto from_placeholder() noexcept {
  37682. const auto entt = traits_type::combine(static_cast<typename traits_type::entity_type>(placeholder), {});
  37683. ENTT_ASSERT(entt != null, "No more entities available");
  37684. placeholder += static_cast<size_type>(entt != null);
  37685. return entt;
  37686. }
  37687. auto next() noexcept {
  37688. entity_type entt = from_placeholder();
  37689. while(base_type::current(entt) != traits_type::to_version(tombstone) && entt != null) {
  37690. entt = from_placeholder();
  37691. }
  37692. return entt;
  37693. }
  37694. protected:
  37695. /*! @brief Erases all entities of a storage. */
  37696. void pop_all() override {
  37697. base_type::pop_all();
  37698. placeholder = {};
  37699. }
  37700. /**
  37701. * @brief Assigns an entity to a storage.
  37702. * @param hint A valid identifier.
  37703. * @return Iterator pointing to the emplaced element.
  37704. */
  37705. underlying_iterator try_emplace(const Entity hint, const bool, const void *) override {
  37706. return base_type::find(generate(hint));
  37707. }
  37708. public:
  37709. /*! @brief Allocator type. */
  37710. using allocator_type = Allocator;
  37711. /*! @brief Base type. */
  37712. using base_type = basic_sparse_set<Entity, Allocator>;
  37713. /*! @brief Element type. */
  37714. using element_type = Entity;
  37715. /*! @brief Type of the objects assigned to entities. */
  37716. using value_type = void;
  37717. /*! @brief Underlying entity identifier. */
  37718. using entity_type = Entity;
  37719. /*! @brief Unsigned integer type. */
  37720. using size_type = std::size_t;
  37721. /*! @brief Signed integer type. */
  37722. using difference_type = std::ptrdiff_t;
  37723. /*! @brief Extended iterable storage proxy. */
  37724. using iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::iterator>>;
  37725. /*! @brief Constant extended iterable storage proxy. */
  37726. using const_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_iterator>>;
  37727. /*! @brief Extended reverse iterable storage proxy. */
  37728. using reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::reverse_iterator>>;
  37729. /*! @brief Constant extended reverse iterable storage proxy. */
  37730. using const_reverse_iterable = iterable_adaptor<internal::extended_storage_iterator<typename base_type::const_reverse_iterator>>;
  37731. /*! @brief Storage deletion policy. */
  37732. static constexpr deletion_policy storage_policy = deletion_policy::swap_only;
  37733. /*! @brief Default constructor. */
  37734. basic_storage()
  37735. : basic_storage{allocator_type{}} {
  37736. }
  37737. /**
  37738. * @brief Constructs an empty container with a given allocator.
  37739. * @param allocator The allocator to use.
  37740. */
  37741. explicit basic_storage(const allocator_type &allocator)
  37742. : base_type{type_id<void>(), storage_policy, allocator} {}
  37743. /*! @brief Default copy constructor, deleted on purpose. */
  37744. basic_storage(const basic_storage &) = delete;
  37745. /**
  37746. * @brief Move constructor.
  37747. * @param other The instance to move from.
  37748. */
  37749. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  37750. basic_storage(basic_storage &&other) noexcept
  37751. : base_type{static_cast<base_type &&>(other)},
  37752. placeholder{other.placeholder} {}
  37753. /**
  37754. * @brief Allocator-extended move constructor.
  37755. * @param other The instance to move from.
  37756. * @param allocator The allocator to use.
  37757. */
  37758. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  37759. basic_storage(basic_storage &&other, const allocator_type &allocator)
  37760. : base_type{static_cast<base_type &&>(other), allocator},
  37761. placeholder{other.placeholder} {}
  37762. /*! @brief Default destructor. */
  37763. ~basic_storage() override = default;
  37764. /**
  37765. * @brief Default copy assignment operator, deleted on purpose.
  37766. * @return This storage.
  37767. */
  37768. basic_storage &operator=(const basic_storage &) = delete;
  37769. /**
  37770. * @brief Move assignment operator.
  37771. * @param other The instance to move from.
  37772. * @return This storage.
  37773. */
  37774. basic_storage &operator=(basic_storage &&other) noexcept {
  37775. placeholder = other.placeholder;
  37776. base_type::operator=(std::move(other));
  37777. return *this;
  37778. }
  37779. /**
  37780. * @brief Exchanges the contents with those of a given storage.
  37781. * @param other Storage to exchange the content with.
  37782. */
  37783. void swap(basic_storage &other) noexcept {
  37784. using std::swap;
  37785. swap(placeholder, other.placeholder);
  37786. base_type::swap(other);
  37787. }
  37788. /**
  37789. * @brief Returns the object assigned to an entity, that is `void`.
  37790. *
  37791. * @warning
  37792. * Attempting to use an entity that doesn't belong to the storage results in
  37793. * undefined behavior.
  37794. *
  37795. * @param entt A valid identifier.
  37796. */
  37797. void get([[maybe_unused]] const entity_type entt) const noexcept {
  37798. ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one");
  37799. }
  37800. /**
  37801. * @brief Returns an empty tuple.
  37802. * @param entt A valid identifier.
  37803. * @return Returns an empty tuple.
  37804. */
  37805. [[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept {
  37806. ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one");
  37807. return std::tuple{};
  37808. }
  37809. /**
  37810. * @brief Creates a new identifier or recycles a destroyed one.
  37811. * @return A valid identifier.
  37812. */
  37813. entity_type generate() {
  37814. const auto len = base_type::free_list();
  37815. const auto entt = (len == base_type::size()) ? next() : base_type::data()[len];
  37816. return *base_type::try_emplace(entt, true);
  37817. }
  37818. /**
  37819. * @brief Creates a new identifier or recycles a destroyed one.
  37820. *
  37821. * If the requested identifier isn't in use, the suggested one is used.
  37822. * Otherwise, a new identifier is returned.
  37823. *
  37824. * @param hint Required identifier.
  37825. * @return A valid identifier.
  37826. */
  37827. entity_type generate(const entity_type hint) {
  37828. if(hint != null && hint != tombstone) {
  37829. if(const auto curr = traits_type::construct(traits_type::to_entity(hint), base_type::current(hint)); curr == tombstone || !(base_type::index(curr) < base_type::free_list())) {
  37830. return *base_type::try_emplace(hint, true);
  37831. }
  37832. }
  37833. return generate();
  37834. }
  37835. /**
  37836. * @brief Assigns each element in a range an identifier.
  37837. * @tparam It Type of mutable forward iterator.
  37838. * @param first An iterator to the first element of the range to generate.
  37839. * @param last An iterator past the last element of the range to generate.
  37840. */
  37841. template<typename It>
  37842. void generate(It first, It last) {
  37843. for(const auto sz = base_type::size(); first != last && base_type::free_list() != sz; ++first) {
  37844. *first = *base_type::try_emplace(base_type::data()[base_type::free_list()], true);
  37845. }
  37846. for(; first != last; ++first) {
  37847. *first = *base_type::try_emplace(next(), true);
  37848. }
  37849. }
  37850. /**
  37851. * @brief Updates a given identifier.
  37852. * @tparam Func Types of the function objects to invoke.
  37853. * @param entt A valid identifier.
  37854. * @param func Valid function objects.
  37855. */
  37856. template<typename... Func>
  37857. void patch([[maybe_unused]] const entity_type entt, Func &&...func) {
  37858. ENTT_ASSERT(base_type::index(entt) < base_type::free_list(), "The requested entity is not a live one");
  37859. (std::forward<Func>(func)(), ...);
  37860. }
  37861. /**
  37862. * @brief Returns an iterable object to use to _visit_ a storage.
  37863. *
  37864. * The iterable object returns a tuple that contains the current entity.
  37865. *
  37866. * @return An iterable object to use to _visit_ the storage.
  37867. */
  37868. [[nodiscard]] iterable each() noexcept {
  37869. return std::as_const(*this).each();
  37870. }
  37871. /*! @copydoc each */
  37872. [[nodiscard]] const_iterable each() const noexcept {
  37873. const auto it = base_type::cend();
  37874. const auto offset = static_cast<difference_type>(base_type::free_list());
  37875. return const_iterable{it - offset, it};
  37876. }
  37877. /**
  37878. * @brief Returns a reverse iterable object to use to _visit_ a storage.
  37879. *
  37880. * @sa each
  37881. *
  37882. * @return A reverse iterable object to use to _visit_ the storage.
  37883. */
  37884. [[nodiscard]] reverse_iterable reach() noexcept {
  37885. return std::as_const(*this).reach();
  37886. }
  37887. /*! @copydoc reach */
  37888. [[nodiscard]] const_reverse_iterable reach() const noexcept {
  37889. const auto it = base_type::crbegin();
  37890. const auto offset = static_cast<difference_type>(base_type::free_list());
  37891. return const_reverse_iterable{it, it + offset};
  37892. }
  37893. /**
  37894. * @brief Sets the starting identifier for generation.
  37895. *
  37896. * The version is ignored, regardless of the value.
  37897. *
  37898. * @param hint A valid identifier.
  37899. */
  37900. void start_from(const entity_type hint) {
  37901. placeholder = static_cast<size_type>(traits_type::to_entity(hint));
  37902. }
  37903. private:
  37904. size_type placeholder{};
  37905. };
  37906. } // namespace entt
  37907. #endif
  37908. // #include "entity/view.hpp"
  37909. #ifndef ENTT_ENTITY_VIEW_HPP
  37910. #define ENTT_ENTITY_VIEW_HPP
  37911. #include <array>
  37912. #include <cstddef>
  37913. #include <iterator>
  37914. #include <tuple>
  37915. #include <type_traits>
  37916. #include <utility>
  37917. // #include "../config/config.h"
  37918. // #include "../core/iterator.hpp"
  37919. // #include "../core/type_traits.hpp"
  37920. // #include "entity.hpp"
  37921. // #include "fwd.hpp"
  37922. namespace entt {
  37923. /*! @cond TURN_OFF_DOXYGEN */
  37924. namespace internal {
  37925. template<typename... Type>
  37926. // NOLINTNEXTLINE(misc-redundant-expression)
  37927. static constexpr bool tombstone_check_v = ((sizeof...(Type) == 1u) && ... && (Type::storage_policy == deletion_policy::in_place));
  37928. template<typename Type>
  37929. const Type *view_placeholder() {
  37930. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Unexpected type");
  37931. static const Type placeholder{};
  37932. return &placeholder;
  37933. }
  37934. template<typename It, typename Entity>
  37935. [[nodiscard]] bool all_of(It first, const It last, const Entity entt) noexcept {
  37936. for(; (first != last) && (*first)->contains(entt); ++first) {}
  37937. return first == last;
  37938. }
  37939. template<typename It, typename Entity>
  37940. [[nodiscard]] bool none_of(It first, const It last, const Entity entt) noexcept {
  37941. for(; (first != last) && !(*first)->contains(entt); ++first) {}
  37942. return first == last;
  37943. }
  37944. template<typename It>
  37945. [[nodiscard]] bool fully_initialized(It first, const It last, const std::remove_pointer_t<typename std::iterator_traits<It>::value_type> *placeholder) noexcept {
  37946. for(; (first != last) && *first != placeholder; ++first) {}
  37947. return first == last;
  37948. }
  37949. template<typename Result, typename View, typename Other, std::size_t... GLhs, std::size_t... ELhs, std::size_t... GRhs, std::size_t... ERhs>
  37950. [[nodiscard]] Result view_pack(const View &view, const Other &other, std::index_sequence<GLhs...>, std::index_sequence<ELhs...>, std::index_sequence<GRhs...>, std::index_sequence<ERhs...>) {
  37951. Result elem{};
  37952. // friend-initialization, avoid multiple calls to refresh
  37953. elem.pools = {view.template storage<GLhs>()..., other.template storage<GRhs>()...};
  37954. auto filter_or_placeholder = [placeholder = elem.placeholder](auto *value) { return (value == nullptr) ? placeholder : value; };
  37955. elem.filter = {filter_or_placeholder(view.template storage<sizeof...(GLhs) + ELhs>())..., filter_or_placeholder(other.template storage<sizeof...(GRhs) + ERhs>())...};
  37956. elem.refresh();
  37957. return elem;
  37958. }
  37959. template<typename Type, bool Checked, std::size_t Get, std::size_t Exclude>
  37960. class view_iterator final {
  37961. template<typename, typename...>
  37962. friend class extended_view_iterator;
  37963. using iterator_type = typename Type::const_iterator;
  37964. using iterator_traits = std::iterator_traits<iterator_type>;
  37965. [[nodiscard]] bool valid(const typename iterator_traits::value_type entt) const noexcept {
  37966. return (!Checked || (entt != tombstone))
  37967. && ((Get == 1u) || (internal::all_of(pools.begin(), pools.begin() + index, entt) && internal::all_of(pools.begin() + index + 1, pools.end(), entt)))
  37968. && ((Exclude == 0u) || internal::none_of(filter.begin(), filter.end(), entt));
  37969. }
  37970. void seek_next() {
  37971. for(constexpr iterator_type sentinel{}; it != sentinel && !valid(*it); ++it) {}
  37972. }
  37973. public:
  37974. using value_type = typename iterator_traits::value_type;
  37975. using pointer = typename iterator_traits::pointer;
  37976. using reference = typename iterator_traits::reference;
  37977. using difference_type = typename iterator_traits::difference_type;
  37978. using iterator_category = std::forward_iterator_tag;
  37979. constexpr view_iterator() noexcept
  37980. : it{},
  37981. pools{},
  37982. filter{},
  37983. index{} {}
  37984. view_iterator(iterator_type first, std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl, const std::size_t idx) noexcept
  37985. : it{first},
  37986. pools{value},
  37987. filter{excl},
  37988. index{static_cast<difference_type>(idx)} {
  37989. ENTT_ASSERT((Get != 1u) || (Exclude != 0u) || pools[0u]->policy() == deletion_policy::in_place, "Non in-place storage view iterator");
  37990. seek_next();
  37991. }
  37992. view_iterator &operator++() noexcept {
  37993. ++it;
  37994. seek_next();
  37995. return *this;
  37996. }
  37997. view_iterator operator++(int) noexcept {
  37998. const view_iterator orig = *this;
  37999. return ++(*this), orig;
  38000. }
  38001. [[nodiscard]] pointer operator->() const noexcept {
  38002. return &*it;
  38003. }
  38004. [[nodiscard]] reference operator*() const noexcept {
  38005. return *operator->();
  38006. }
  38007. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  38008. friend constexpr bool operator==(const view_iterator<LhsType, LhsArgs...> &, const view_iterator<RhsType, RhsArgs...> &) noexcept;
  38009. private:
  38010. iterator_type it;
  38011. std::array<const Type *, Get> pools;
  38012. std::array<const Type *, Exclude> filter;
  38013. difference_type index;
  38014. };
  38015. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  38016. [[nodiscard]] constexpr bool operator==(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) noexcept {
  38017. return lhs.it == rhs.it;
  38018. }
  38019. template<typename LhsType, auto... LhsArgs, typename RhsType, auto... RhsArgs>
  38020. [[nodiscard]] constexpr bool operator!=(const view_iterator<LhsType, LhsArgs...> &lhs, const view_iterator<RhsType, RhsArgs...> &rhs) noexcept {
  38021. return !(lhs == rhs);
  38022. }
  38023. template<typename It, typename... Get>
  38024. class extended_view_iterator final {
  38025. template<std::size_t... Index>
  38026. [[nodiscard]] auto dereference(std::index_sequence<Index...>) const noexcept {
  38027. return std::tuple_cat(std::make_tuple(*it), static_cast<Get *>(const_cast<constness_as_t<typename Get::base_type, Get> *>(std::get<Index>(it.pools)))->get_as_tuple(*it)...);
  38028. }
  38029. public:
  38030. using iterator_type = It;
  38031. using value_type = decltype(std::tuple_cat(std::make_tuple(*std::declval<It>()), std::declval<Get>().get_as_tuple({})...));
  38032. using pointer = input_iterator_pointer<value_type>;
  38033. using reference = value_type;
  38034. using difference_type = std::ptrdiff_t;
  38035. using iterator_category = std::input_iterator_tag;
  38036. using iterator_concept = std::forward_iterator_tag;
  38037. constexpr extended_view_iterator()
  38038. : it{} {}
  38039. extended_view_iterator(iterator_type from)
  38040. : it{from} {}
  38041. extended_view_iterator &operator++() noexcept {
  38042. return ++it, *this;
  38043. }
  38044. extended_view_iterator operator++(int) noexcept {
  38045. const extended_view_iterator orig = *this;
  38046. return ++(*this), orig;
  38047. }
  38048. [[nodiscard]] reference operator*() const noexcept {
  38049. return dereference(std::index_sequence_for<Get...>{});
  38050. }
  38051. [[nodiscard]] pointer operator->() const noexcept {
  38052. return operator*();
  38053. }
  38054. [[nodiscard]] constexpr iterator_type base() const noexcept {
  38055. return it;
  38056. }
  38057. template<typename... Lhs, typename... Rhs>
  38058. friend bool constexpr operator==(const extended_view_iterator<Lhs...> &, const extended_view_iterator<Rhs...> &) noexcept;
  38059. private:
  38060. It it;
  38061. };
  38062. template<typename... Lhs, typename... Rhs>
  38063. [[nodiscard]] constexpr bool operator==(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) noexcept {
  38064. return lhs.it == rhs.it;
  38065. }
  38066. template<typename... Lhs, typename... Rhs>
  38067. [[nodiscard]] constexpr bool operator!=(const extended_view_iterator<Lhs...> &lhs, const extended_view_iterator<Rhs...> &rhs) noexcept {
  38068. return !(lhs == rhs);
  38069. }
  38070. } // namespace internal
  38071. /*! @endcond */
  38072. /**
  38073. * @brief View implementation.
  38074. *
  38075. * Primary template isn't defined on purpose. All the specializations give a
  38076. * compile-time error, but for a few reasonable cases.
  38077. *
  38078. * @b Important
  38079. *
  38080. * View iterators aren't invalidated if:
  38081. *
  38082. * * New elements are added to the storage iterated by the view.
  38083. * * The entity currently returned is modified (for example, elements are added
  38084. * or removed from it).
  38085. * * The entity currently returned is destroyed.
  38086. *
  38087. * In all other cases, modifying the storage iterated by a view in any way can
  38088. * invalidate all iterators.
  38089. */
  38090. template<typename, typename, typename>
  38091. class basic_view;
  38092. /**
  38093. * @brief Basic storage view implementation.
  38094. * @warning For internal use only, backward compatibility not guaranteed.
  38095. * @tparam Type Common type among all storage types.
  38096. * @tparam Checked True to enable the tombstone check, false otherwise.
  38097. * @tparam Get Number of storage iterated by the view.
  38098. * @tparam Exclude Number of storage used to filter the view.
  38099. */
  38100. template<typename Type, bool Checked, std::size_t Get, std::size_t Exclude>
  38101. class basic_common_view {
  38102. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Unexpected type");
  38103. template<typename Return, typename View, typename Other, std::size_t... GLhs, std::size_t... ELhs, std::size_t... GRhs, std::size_t... ERhs>
  38104. friend Return internal::view_pack(const View &, const Other &, std::index_sequence<GLhs...>, std::index_sequence<ELhs...>, std::index_sequence<GRhs...>, std::index_sequence<ERhs...>);
  38105. [[nodiscard]] auto offset() const noexcept {
  38106. ENTT_ASSERT(index != Get, "Invalid view");
  38107. return (pools[index]->policy() == deletion_policy::swap_only) ? pools[index]->free_list() : pools[index]->size();
  38108. }
  38109. void unchecked_refresh() noexcept {
  38110. index = 0u;
  38111. if constexpr(Get > 1u) {
  38112. for(size_type pos{1u}; pos < Get; ++pos) {
  38113. if(pools[pos]->size() < pools[index]->size()) {
  38114. index = pos;
  38115. }
  38116. }
  38117. }
  38118. }
  38119. protected:
  38120. /*! @cond TURN_OFF_DOXYGEN */
  38121. basic_common_view() noexcept {
  38122. for(size_type pos{}, last = filter.size(); pos < last; ++pos) {
  38123. filter[pos] = placeholder;
  38124. }
  38125. }
  38126. basic_common_view(std::array<const Type *, Get> value, std::array<const Type *, Exclude> excl) noexcept
  38127. : pools{value},
  38128. filter{excl},
  38129. index{Get} {
  38130. unchecked_refresh();
  38131. }
  38132. [[nodiscard]] const Type *pool_at(const std::size_t pos) const noexcept {
  38133. return pools[pos];
  38134. }
  38135. void pool_at(const std::size_t pos, const Type *elem) noexcept {
  38136. ENTT_ASSERT(elem != nullptr, "Unexpected element");
  38137. pools[pos] = elem;
  38138. refresh();
  38139. }
  38140. [[nodiscard]] const Type *filter_at(const std::size_t pos) const noexcept {
  38141. return (filter[pos] == placeholder) ? nullptr : filter[pos];
  38142. }
  38143. void filter_at(const std::size_t pos, const Type *elem) noexcept {
  38144. ENTT_ASSERT(elem != nullptr, "Unexpected element");
  38145. filter[pos] = elem;
  38146. }
  38147. [[nodiscard]] bool none_of(const typename Type::entity_type entt) const noexcept {
  38148. return internal::none_of(filter.begin(), filter.end(), entt);
  38149. }
  38150. void use(const std::size_t pos) noexcept {
  38151. index = (index != Get) ? pos : Get;
  38152. }
  38153. /*! @endcond */
  38154. public:
  38155. /*! @brief Common type among all storage types. */
  38156. using common_type = Type;
  38157. /*! @brief Underlying entity identifier. */
  38158. using entity_type = typename Type::entity_type;
  38159. /*! @brief Unsigned integer type. */
  38160. using size_type = std::size_t;
  38161. /*! @brief Signed integer type. */
  38162. using difference_type = std::ptrdiff_t;
  38163. /*! @brief Forward iterator type. */
  38164. using iterator = internal::view_iterator<common_type, Checked, Get, Exclude>;
  38165. /*! @brief Updates the internal leading view if required. */
  38166. void refresh() noexcept {
  38167. size_type pos = static_cast<size_type>(index != Get) * Get;
  38168. for(; pos < Get && pools[pos] != nullptr; ++pos) {}
  38169. if(pos == Get) {
  38170. unchecked_refresh();
  38171. }
  38172. }
  38173. /**
  38174. * @brief Returns the leading storage of a view, if any.
  38175. * @return The leading storage of the view.
  38176. */
  38177. [[nodiscard]] const common_type *handle() const noexcept {
  38178. return (index != Get) ? pools[index] : nullptr;
  38179. }
  38180. /**
  38181. * @brief Estimates the number of entities iterated by the view.
  38182. * @return Estimated number of entities iterated by the view.
  38183. */
  38184. [[nodiscard]] size_type size_hint() const noexcept {
  38185. return (index != Get) ? offset() : size_type{};
  38186. }
  38187. /**
  38188. * @brief Returns an iterator to the first entity of the view.
  38189. *
  38190. * If the view is empty, the returned iterator will be equal to `end()`.
  38191. *
  38192. * @return An iterator to the first entity of the view.
  38193. */
  38194. [[nodiscard]] iterator begin() const noexcept {
  38195. return (index != Get) ? iterator{pools[index]->end() - static_cast<difference_type>(offset()), pools, filter, index} : iterator{};
  38196. }
  38197. /**
  38198. * @brief Returns an iterator that is past the last entity of the view.
  38199. * @return An iterator to the entity following the last entity of the view.
  38200. */
  38201. [[nodiscard]] iterator end() const noexcept {
  38202. return (index != Get) ? iterator{pools[index]->end(), pools, filter, index} : iterator{};
  38203. }
  38204. /**
  38205. * @brief Returns the first entity of the view, if any.
  38206. * @return The first entity of the view if one exists, the null entity
  38207. * otherwise.
  38208. */
  38209. [[nodiscard]] entity_type front() const noexcept {
  38210. const auto it = begin();
  38211. return it != end() ? *it : null;
  38212. }
  38213. /**
  38214. * @brief Returns the last entity of the view, if any.
  38215. * @return The last entity of the view if one exists, the null entity
  38216. * otherwise.
  38217. */
  38218. [[nodiscard]] entity_type back() const noexcept {
  38219. if(index != Get) {
  38220. auto it = pools[index]->rbegin();
  38221. const auto last = it + static_cast<difference_type>(offset());
  38222. for(const auto idx = static_cast<difference_type>(index); it != last && !(internal::all_of(pools.begin(), pools.begin() + idx, *it) && internal::all_of(pools.begin() + idx + 1, pools.end(), *it) && internal::none_of(filter.begin(), filter.end(), *it)); ++it) {}
  38223. return it == last ? null : *it;
  38224. }
  38225. return null;
  38226. }
  38227. /**
  38228. * @brief Finds an entity.
  38229. * @param entt A valid identifier.
  38230. * @return An iterator to the given entity if it's found, past the end
  38231. * iterator otherwise.
  38232. */
  38233. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  38234. return contains(entt) ? iterator{pools[index]->find(entt), pools, filter, index} : end();
  38235. }
  38236. /**
  38237. * @brief Checks if a view is fully initialized.
  38238. * @return True if the view is fully initialized, false otherwise.
  38239. */
  38240. [[nodiscard]] explicit operator bool() const noexcept {
  38241. return (index != Get) && internal::fully_initialized(filter.begin(), filter.end(), placeholder);
  38242. }
  38243. /**
  38244. * @brief Checks if a view contains an entity.
  38245. * @param entt A valid identifier.
  38246. * @return True if the view contains the given entity, false otherwise.
  38247. */
  38248. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  38249. return (index != Get)
  38250. && internal::all_of(pools.begin(), pools.end(), entt)
  38251. && internal::none_of(filter.begin(), filter.end(), entt)
  38252. && pools[index]->index(entt) < offset();
  38253. }
  38254. private:
  38255. std::array<const common_type *, Get> pools{};
  38256. std::array<const common_type *, Exclude> filter{};
  38257. const common_type *placeholder{internal::view_placeholder<common_type>()};
  38258. size_type index{Get};
  38259. };
  38260. /**
  38261. * @brief General purpose view.
  38262. *
  38263. * This view visits all entities that are at least in the given storage. During
  38264. * initialization, it also looks at the number of elements available for each
  38265. * storage and uses the smallest set in order to get a performance boost.
  38266. *
  38267. * @sa basic_view
  38268. *
  38269. * @tparam Get Types of storage iterated by the view.
  38270. * @tparam Exclude Types of storage used to filter the view.
  38271. */
  38272. template<typename... Get, typename... Exclude>
  38273. class basic_view<get_t<Get...>, exclude_t<Exclude...>, std::enable_if_t<(sizeof...(Get) != 0u)>>
  38274. : public basic_common_view<std::common_type_t<typename Get::base_type...>, internal::tombstone_check_v<Get...>, sizeof...(Get), sizeof...(Exclude)> {
  38275. using base_type = basic_common_view<std::common_type_t<typename Get::base_type...>, internal::tombstone_check_v<Get...>, sizeof...(Get), sizeof...(Exclude)>;
  38276. template<std::size_t Index>
  38277. using element_at = type_list_element_t<Index, type_list<Get..., Exclude...>>;
  38278. template<typename Type>
  38279. static constexpr std::size_t index_of = type_list_index_v<std::remove_const_t<Type>, type_list<typename Get::element_type..., typename Exclude::element_type...>>;
  38280. template<std::size_t... Index>
  38281. [[nodiscard]] auto get(const typename base_type::entity_type entt, std::index_sequence<Index...>) const noexcept {
  38282. return std::tuple_cat(storage<Index>()->get_as_tuple(entt)...);
  38283. }
  38284. template<std::size_t Curr, std::size_t Other, typename... Args>
  38285. [[nodiscard]] auto dispatch_get(const std::tuple<typename base_type::entity_type, Args...> &curr) const {
  38286. if constexpr(Curr == Other) {
  38287. return std::forward_as_tuple(std::get<Args>(curr)...);
  38288. } else {
  38289. return storage<Other>()->get_as_tuple(std::get<0>(curr));
  38290. }
  38291. }
  38292. template<std::size_t Curr, typename Func, std::size_t... Index>
  38293. void each(Func &func, std::index_sequence<Index...>) const {
  38294. for(const auto curr: storage<Curr>()->each()) {
  38295. if(const auto entt = std::get<0>(curr); (!internal::tombstone_check_v<Get...> || (entt != tombstone)) && ((Curr == Index || base_type::pool_at(Index)->contains(entt)) && ...) && base_type::none_of(entt)) {
  38296. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
  38297. std::apply(func, std::tuple_cat(std::make_tuple(entt), dispatch_get<Curr, Index>(curr)...));
  38298. } else {
  38299. std::apply(func, std::tuple_cat(dispatch_get<Curr, Index>(curr)...));
  38300. }
  38301. }
  38302. }
  38303. }
  38304. template<typename Func, std::size_t... Index>
  38305. void pick_and_each(Func &func, std::index_sequence<Index...> seq) const {
  38306. if(const auto *view = base_type::handle(); view != nullptr) {
  38307. ((view == base_type::pool_at(Index) ? each<Index>(func, seq) : void()), ...);
  38308. }
  38309. }
  38310. public:
  38311. /*! @brief Common type among all storage types. */
  38312. using common_type = typename base_type::common_type;
  38313. /*! @brief Underlying entity identifier. */
  38314. using entity_type = typename base_type::entity_type;
  38315. /*! @brief Unsigned integer type. */
  38316. using size_type = typename base_type::size_type;
  38317. /*! @brief Signed integer type. */
  38318. using difference_type = std::ptrdiff_t;
  38319. /*! @brief Forward iterator type. */
  38320. using iterator = typename base_type::iterator;
  38321. /*! @brief Iterable view type. */
  38322. using iterable = iterable_adaptor<internal::extended_view_iterator<iterator, Get...>>;
  38323. /*! @brief Default constructor to use to create empty, invalid views. */
  38324. basic_view() noexcept
  38325. : base_type{} {}
  38326. /**
  38327. * @brief Constructs a view from a set of storage classes.
  38328. * @param value The storage for the types to iterate.
  38329. * @param excl The storage for the types used to filter the view.
  38330. */
  38331. basic_view(Get &...value, Exclude &...excl) noexcept
  38332. : base_type{{&value...}, {&excl...}} {
  38333. }
  38334. /**
  38335. * @brief Constructs a view from a set of storage classes.
  38336. * @param value The storage for the types to iterate.
  38337. * @param excl The storage for the types used to filter the view.
  38338. */
  38339. basic_view(std::tuple<Get &...> value, std::tuple<Exclude &...> excl = {}) noexcept
  38340. : basic_view{std::make_from_tuple<basic_view>(std::tuple_cat(value, excl))} {}
  38341. /**
  38342. * @brief Forces a view to use a given element to drive iterations
  38343. * @tparam Type Type of element to use to drive iterations.
  38344. */
  38345. template<typename Type>
  38346. void use() noexcept {
  38347. use<index_of<Type>>();
  38348. }
  38349. /**
  38350. * @brief Forces a view to use a given element to drive iterations
  38351. * @tparam Index Index of the element to use to drive iterations.
  38352. */
  38353. template<std::size_t Index>
  38354. void use() noexcept {
  38355. base_type::use(Index);
  38356. }
  38357. /**
  38358. * @brief Returns the storage for a given element type, if any.
  38359. * @tparam Type Type of element of which to return the storage.
  38360. * @return The storage for the given element type.
  38361. */
  38362. template<typename Type>
  38363. [[nodiscard]] auto *storage() const noexcept {
  38364. return storage<index_of<Type>>();
  38365. }
  38366. /**
  38367. * @brief Returns the storage for a given index, if any.
  38368. * @tparam Index Index of the storage to return.
  38369. * @return The storage for the given index.
  38370. */
  38371. template<std::size_t Index>
  38372. [[nodiscard]] auto *storage() const noexcept {
  38373. if constexpr(Index < sizeof...(Get)) {
  38374. return static_cast<element_at<Index> *>(const_cast<constness_as_t<common_type, element_at<Index>> *>(base_type::pool_at(Index)));
  38375. } else {
  38376. return static_cast<element_at<Index> *>(const_cast<constness_as_t<common_type, element_at<Index>> *>(base_type::filter_at(Index - sizeof...(Get))));
  38377. }
  38378. }
  38379. /**
  38380. * @brief Assigns a storage to a view.
  38381. * @tparam Type Type of storage to assign to the view.
  38382. * @param elem A storage to assign to the view.
  38383. */
  38384. template<typename Type>
  38385. void storage(Type &elem) noexcept {
  38386. storage<index_of<typename Type::element_type>>(elem);
  38387. }
  38388. /**
  38389. * @brief Assigns a storage to a view.
  38390. * @tparam Index Index of the storage to assign to the view.
  38391. * @tparam Type Type of storage to assign to the view.
  38392. * @param elem A storage to assign to the view.
  38393. */
  38394. template<std::size_t Index, typename Type>
  38395. void storage(Type &elem) noexcept {
  38396. static_assert(std::is_convertible_v<Type &, element_at<Index> &>, "Unexpected type");
  38397. if constexpr(Index < sizeof...(Get)) {
  38398. base_type::pool_at(Index, &elem);
  38399. } else {
  38400. base_type::filter_at(Index - sizeof...(Get), &elem);
  38401. }
  38402. }
  38403. /**
  38404. * @brief Returns the elements assigned to the given entity.
  38405. * @param entt A valid identifier.
  38406. * @return The elements assigned to the given entity.
  38407. */
  38408. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  38409. return get(entt);
  38410. }
  38411. /**
  38412. * @brief Returns the elements assigned to the given entity.
  38413. * @tparam Type Type of the element to get.
  38414. * @tparam Other Other types of elements to get.
  38415. * @param entt A valid identifier.
  38416. * @return The elements assigned to the entity.
  38417. */
  38418. template<typename Type, typename... Other>
  38419. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  38420. return get<index_of<Type>, index_of<Other>...>(entt);
  38421. }
  38422. /**
  38423. * @brief Returns the elements assigned to the given entity.
  38424. * @tparam Index Indexes of the elements to get.
  38425. * @param entt A valid identifier.
  38426. * @return The elements assigned to the entity.
  38427. */
  38428. template<std::size_t... Index>
  38429. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  38430. if constexpr(sizeof...(Index) == 0) {
  38431. return get(entt, std::index_sequence_for<Get...>{});
  38432. } else if constexpr(sizeof...(Index) == 1) {
  38433. return (storage<Index>()->get(entt), ...);
  38434. } else {
  38435. return std::tuple_cat(storage<Index>()->get_as_tuple(entt)...);
  38436. }
  38437. }
  38438. /**
  38439. * @brief Iterates entities and elements and applies the given function
  38440. * object to them.
  38441. *
  38442. * The signature of the function must be equivalent to one of the following
  38443. * (non-empty types only, constness as requested):
  38444. *
  38445. * @code{.cpp}
  38446. * void(const entity_type, Type &...);
  38447. * void(Type &...);
  38448. * @endcode
  38449. *
  38450. * @tparam Func Type of the function object to invoke.
  38451. * @param func A valid function object.
  38452. */
  38453. template<typename Func>
  38454. void each(Func func) const {
  38455. pick_and_each(func, std::index_sequence_for<Get...>{});
  38456. }
  38457. /**
  38458. * @brief Returns an iterable object to use to _visit_ a view.
  38459. *
  38460. * The iterable object returns a tuple that contains the current entity and
  38461. * a set of references to its non-empty elements. The _constness_ of the
  38462. * elements is as requested.
  38463. *
  38464. * @return An iterable object to use to _visit_ the view.
  38465. */
  38466. [[nodiscard]] iterable each() const noexcept {
  38467. return iterable{base_type::begin(), base_type::end()};
  38468. }
  38469. /**
  38470. * @brief Combines a view and a storage in _more specific_ view.
  38471. * @tparam OGet Type of storage to combine the view with.
  38472. * @param other The storage for the type to combine the view with.
  38473. * @return A more specific view.
  38474. */
  38475. template<typename OGet>
  38476. [[nodiscard]] std::enable_if_t<std::is_base_of_v<common_type, OGet>, basic_view<get_t<Get..., OGet>, exclude_t<Exclude...>>> operator|(OGet &other) const noexcept {
  38477. return *this | basic_view<get_t<OGet>, exclude_t<>>{other};
  38478. }
  38479. /**
  38480. * @brief Combines two views in a _more specific_ one.
  38481. * @tparam OGet Element list of the view to combine with.
  38482. * @tparam OExclude Filter list of the view to combine with.
  38483. * @param other The view to combine with.
  38484. * @return A more specific view.
  38485. */
  38486. template<typename... OGet, typename... OExclude>
  38487. [[nodiscard]] auto operator|(const basic_view<get_t<OGet...>, exclude_t<OExclude...>> &other) const noexcept {
  38488. return internal::view_pack<basic_view<get_t<Get..., OGet...>, exclude_t<Exclude..., OExclude...>>>(
  38489. *this, other, std::index_sequence_for<Get...>{}, std::index_sequence_for<Exclude...>{}, std::index_sequence_for<OGet...>{}, std::index_sequence_for<OExclude...>{});
  38490. }
  38491. };
  38492. /**
  38493. * @brief Basic storage view implementation.
  38494. * @warning For internal use only, backward compatibility not guaranteed.
  38495. * @tparam Type Common type among all storage types.
  38496. * @tparam Policy Storage policy.
  38497. */
  38498. template<typename Type, deletion_policy Policy>
  38499. class basic_storage_view {
  38500. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Unexpected type");
  38501. protected:
  38502. /*! @cond TURN_OFF_DOXYGEN */
  38503. basic_storage_view() noexcept = default;
  38504. basic_storage_view(const Type *value) noexcept
  38505. : leading{value} {
  38506. ENTT_ASSERT(leading->policy() == Policy, "Unexpected storage policy");
  38507. }
  38508. /*! @endcond */
  38509. public:
  38510. /*! @brief Common type among all storage types. */
  38511. using common_type = Type;
  38512. /*! @brief Underlying entity identifier. */
  38513. using entity_type = typename common_type::entity_type;
  38514. /*! @brief Unsigned integer type. */
  38515. using size_type = std::size_t;
  38516. /*! @brief Signed integer type. */
  38517. using difference_type = std::ptrdiff_t;
  38518. /*! @brief Random access iterator type. */
  38519. using iterator = std::conditional_t<Policy == deletion_policy::in_place, internal::view_iterator<common_type, true, 1u, 0u>, typename common_type::iterator>;
  38520. /*! @brief Reverse iterator type. */
  38521. using reverse_iterator = std::conditional_t<Policy == deletion_policy::in_place, void, typename common_type::reverse_iterator>;
  38522. /**
  38523. * @brief Returns the leading storage of a view, if any.
  38524. * @return The leading storage of the view.
  38525. */
  38526. [[nodiscard]] const common_type *handle() const noexcept {
  38527. return leading;
  38528. }
  38529. /**
  38530. * @brief Returns the number of entities that have the given element.
  38531. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  38532. * @return Number of entities that have the given element.
  38533. */
  38534. template<typename..., deletion_policy Pol = Policy>
  38535. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, size_type> size() const noexcept {
  38536. if constexpr(Policy == deletion_policy::swap_and_pop) {
  38537. return leading ? leading->size() : size_type{};
  38538. } else {
  38539. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  38540. return leading ? leading->free_list() : size_type{};
  38541. }
  38542. }
  38543. /**
  38544. * @brief Estimates the number of entities iterated by the view.
  38545. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  38546. * @return Estimated number of entities iterated by the view.
  38547. */
  38548. template<typename..., deletion_policy Pol = Policy>
  38549. [[nodiscard]] std::enable_if_t<Pol == deletion_policy::in_place, size_type> size_hint() const noexcept {
  38550. return leading ? leading->size() : size_type{};
  38551. }
  38552. /**
  38553. * @brief Checks whether a view is empty.
  38554. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  38555. * @return True if the view is empty, false otherwise.
  38556. */
  38557. template<typename..., deletion_policy Pol = Policy>
  38558. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, bool> empty() const noexcept {
  38559. if constexpr(Policy == deletion_policy::swap_and_pop) {
  38560. return !leading || leading->empty();
  38561. } else {
  38562. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  38563. return !leading || (leading->free_list() == 0u);
  38564. }
  38565. }
  38566. /**
  38567. * @brief Returns an iterator to the first entity of the view.
  38568. *
  38569. * If the view is empty, the returned iterator will be equal to `end()`.
  38570. *
  38571. * @return An iterator to the first entity of the view.
  38572. */
  38573. [[nodiscard]] iterator begin() const noexcept {
  38574. if constexpr(Policy == deletion_policy::swap_and_pop) {
  38575. return leading ? leading->begin() : iterator{};
  38576. } else if constexpr(Policy == deletion_policy::swap_only) {
  38577. return leading ? (leading->end() - static_cast<difference_type>(leading->free_list())) : iterator{};
  38578. } else {
  38579. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  38580. return leading ? iterator{leading->begin(), {leading}, {}, 0u} : iterator{};
  38581. }
  38582. }
  38583. /**
  38584. * @brief Returns an iterator that is past the last entity of the view.
  38585. * @return An iterator to the entity following the last entity of the view.
  38586. */
  38587. [[nodiscard]] iterator end() const noexcept {
  38588. if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) {
  38589. return leading ? leading->end() : iterator{};
  38590. } else {
  38591. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  38592. return leading ? iterator{leading->end(), {leading}, {}, 0u} : iterator{};
  38593. }
  38594. }
  38595. /**
  38596. * @brief Returns an iterator to the first entity of the reversed view.
  38597. *
  38598. * If the view is empty, the returned iterator will be equal to `rend()`.
  38599. *
  38600. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  38601. * @return An iterator to the first entity of the reversed view.
  38602. */
  38603. template<typename..., deletion_policy Pol = Policy>
  38604. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, reverse_iterator> rbegin() const noexcept {
  38605. return leading ? leading->rbegin() : reverse_iterator{};
  38606. }
  38607. /**
  38608. * @brief Returns an iterator that is past the last entity of the reversed
  38609. * view.
  38610. * @tparam Pol Dummy template parameter used for sfinae purposes only.
  38611. * @return An iterator to the entity following the last entity of the
  38612. * reversed view.
  38613. */
  38614. template<typename..., deletion_policy Pol = Policy>
  38615. [[nodiscard]] std::enable_if_t<Pol != deletion_policy::in_place, reverse_iterator> rend() const noexcept {
  38616. if constexpr(Policy == deletion_policy::swap_and_pop) {
  38617. return leading ? leading->rend() : reverse_iterator{};
  38618. } else {
  38619. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  38620. return leading ? (leading->rbegin() + static_cast<difference_type>(leading->free_list())) : reverse_iterator{};
  38621. }
  38622. }
  38623. /**
  38624. * @brief Returns the first entity of the view, if any.
  38625. * @return The first entity of the view if one exists, the null entity
  38626. * otherwise.
  38627. */
  38628. [[nodiscard]] entity_type front() const noexcept {
  38629. if constexpr(Policy == deletion_policy::swap_and_pop) {
  38630. return empty() ? null : *leading->begin();
  38631. } else if constexpr(Policy == deletion_policy::swap_only) {
  38632. return empty() ? null : *(leading->end() - static_cast<difference_type>(leading->free_list()));
  38633. } else {
  38634. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  38635. const auto it = begin();
  38636. return (it == end()) ? null : *it;
  38637. }
  38638. }
  38639. /**
  38640. * @brief Returns the last entity of the view, if any.
  38641. * @return The last entity of the view if one exists, the null entity
  38642. * otherwise.
  38643. */
  38644. [[nodiscard]] entity_type back() const noexcept {
  38645. if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::swap_only) {
  38646. return empty() ? null : *leading->rbegin();
  38647. } else {
  38648. static_assert(Policy == deletion_policy::in_place, "Unexpected storage policy");
  38649. if(leading) {
  38650. auto it = leading->rbegin();
  38651. const auto last = leading->rend();
  38652. for(; (it != last) && (*it == tombstone); ++it) {}
  38653. return it == last ? null : *it;
  38654. }
  38655. return null;
  38656. }
  38657. }
  38658. /**
  38659. * @brief Finds an entity.
  38660. * @param entt A valid identifier.
  38661. * @return An iterator to the given entity if it's found, past the end
  38662. * iterator otherwise.
  38663. */
  38664. [[nodiscard]] iterator find(const entity_type entt) const noexcept {
  38665. if constexpr(Policy == deletion_policy::swap_and_pop) {
  38666. return leading ? leading->find(entt) : iterator{};
  38667. } else if constexpr(Policy == deletion_policy::swap_only) {
  38668. const auto it = leading ? leading->find(entt) : iterator{};
  38669. return leading && (static_cast<size_type>(it.index()) < leading->free_list()) ? it : iterator{};
  38670. } else {
  38671. return leading ? iterator{leading->find(entt), {leading}, {}, 0u} : iterator{};
  38672. }
  38673. }
  38674. /**
  38675. * @brief Checks if a view is fully initialized.
  38676. * @return True if the view is fully initialized, false otherwise.
  38677. */
  38678. [[nodiscard]] explicit operator bool() const noexcept {
  38679. return (leading != nullptr);
  38680. }
  38681. /**
  38682. * @brief Checks if a view contains an entity.
  38683. * @param entt A valid identifier.
  38684. * @return True if the view contains the given entity, false otherwise.
  38685. */
  38686. [[nodiscard]] bool contains(const entity_type entt) const noexcept {
  38687. if constexpr(Policy == deletion_policy::swap_and_pop || Policy == deletion_policy::in_place) {
  38688. return leading && leading->contains(entt);
  38689. } else {
  38690. static_assert(Policy == deletion_policy::swap_only, "Unexpected storage policy");
  38691. return leading && leading->contains(entt) && (leading->index(entt) < leading->free_list());
  38692. }
  38693. }
  38694. private:
  38695. const common_type *leading{};
  38696. };
  38697. /**
  38698. * @brief Storage view specialization.
  38699. *
  38700. * This specialization offers a boost in terms of performance. It can access the
  38701. * underlying data structure directly and avoid superfluous checks.
  38702. *
  38703. * @sa basic_view
  38704. *
  38705. * @tparam Get Type of storage iterated by the view.
  38706. */
  38707. template<typename Get>
  38708. class basic_view<get_t<Get>, exclude_t<>>
  38709. : public basic_storage_view<typename Get::base_type, Get::storage_policy> {
  38710. using base_type = basic_storage_view<typename Get::base_type, Get::storage_policy>;
  38711. public:
  38712. /*! @brief Common type among all storage types. */
  38713. using common_type = typename base_type::common_type;
  38714. /*! @brief Underlying entity identifier. */
  38715. using entity_type = typename base_type::entity_type;
  38716. /*! @brief Unsigned integer type. */
  38717. using size_type = typename base_type::size_type;
  38718. /*! @brief Signed integer type. */
  38719. using difference_type = std::ptrdiff_t;
  38720. /*! @brief Random access iterator type. */
  38721. using iterator = typename base_type::iterator;
  38722. /*! @brief Reverse iterator type. */
  38723. using reverse_iterator = typename base_type::reverse_iterator;
  38724. /*! @brief Iterable view type. */
  38725. using iterable = std::conditional_t<Get::storage_policy == deletion_policy::in_place, iterable_adaptor<internal::extended_view_iterator<iterator, Get>>, decltype(std::declval<Get>().each())>;
  38726. /*! @brief Default constructor to use to create empty, invalid views. */
  38727. basic_view() noexcept
  38728. : base_type{} {}
  38729. /**
  38730. * @brief Constructs a view from a storage class.
  38731. * @param value The storage for the type to iterate.
  38732. */
  38733. basic_view(Get &value) noexcept
  38734. : base_type{&value} {
  38735. }
  38736. /**
  38737. * @brief Constructs a view from a storage class.
  38738. * @param value The storage for the type to iterate.
  38739. */
  38740. basic_view(std::tuple<Get &> value, std::tuple<> = {}) noexcept
  38741. : basic_view{std::get<0>(value)} {}
  38742. /**
  38743. * @brief Returns the storage for a given element type, if any.
  38744. * @tparam Type Type of element of which to return the storage.
  38745. * @return The storage for the given element type.
  38746. */
  38747. template<typename Type = typename Get::element_type>
  38748. [[nodiscard]] auto *storage() const noexcept {
  38749. static_assert(std::is_same_v<std::remove_const_t<Type>, typename Get::element_type>, "Invalid element type");
  38750. return storage<0>();
  38751. }
  38752. /**
  38753. * @brief Returns the storage for a given index, if any.
  38754. * @tparam Index Index of the storage to return.
  38755. * @return The storage for the given index.
  38756. */
  38757. template<std::size_t Index>
  38758. [[nodiscard]] auto *storage() const noexcept {
  38759. static_assert(Index == 0u, "Index out of bounds");
  38760. return static_cast<Get *>(const_cast<constness_as_t<common_type, Get> *>(base_type::handle()));
  38761. }
  38762. /**
  38763. * @brief Assigns a storage to a view.
  38764. * @param elem A storage to assign to the view.
  38765. */
  38766. void storage(Get &elem) noexcept {
  38767. storage<0>(elem);
  38768. }
  38769. /**
  38770. * @brief Assigns a storage to a view.
  38771. * @tparam Index Index of the storage to assign to the view.
  38772. * @param elem A storage to assign to the view.
  38773. */
  38774. template<std::size_t Index>
  38775. void storage(Get &elem) noexcept {
  38776. static_assert(Index == 0u, "Index out of bounds");
  38777. *this = basic_view{elem};
  38778. }
  38779. /**
  38780. * @brief Returns a pointer to the underlying storage.
  38781. * @return A pointer to the underlying storage.
  38782. */
  38783. [[nodiscard]] Get *operator->() const noexcept {
  38784. return storage();
  38785. }
  38786. /**
  38787. * @brief Returns the element assigned to the given entity.
  38788. * @param entt A valid identifier.
  38789. * @return The element assigned to the given entity.
  38790. */
  38791. [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
  38792. return storage()->get(entt);
  38793. }
  38794. /**
  38795. * @brief Returns the element assigned to the given entity.
  38796. * @tparam Elem Type of the element to get.
  38797. * @param entt A valid identifier.
  38798. * @return The element assigned to the entity.
  38799. */
  38800. template<typename Elem>
  38801. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  38802. static_assert(std::is_same_v<std::remove_const_t<Elem>, typename Get::element_type>, "Invalid element type");
  38803. return get<0>(entt);
  38804. }
  38805. /**
  38806. * @brief Returns the element assigned to the given entity.
  38807. * @tparam Index Index of the element to get.
  38808. * @param entt A valid identifier.
  38809. * @return The element assigned to the entity.
  38810. */
  38811. template<std::size_t... Index>
  38812. [[nodiscard]] decltype(auto) get(const entity_type entt) const {
  38813. if constexpr(sizeof...(Index) == 0) {
  38814. return storage()->get_as_tuple(entt);
  38815. } else {
  38816. return storage<Index...>()->get(entt);
  38817. }
  38818. }
  38819. /**
  38820. * @brief Iterates entities and elements and applies the given function
  38821. * object to them.
  38822. *
  38823. * The signature of the function must be equivalent to one of the following
  38824. * (non-empty types only, constness as requested):
  38825. *
  38826. * @code{.cpp}
  38827. * void(const entity_type, Type &);
  38828. * void(typename Type &);
  38829. * @endcode
  38830. *
  38831. * @tparam Func Type of the function object to invoke.
  38832. * @param func A valid function object.
  38833. */
  38834. template<typename Func>
  38835. void each(Func func) const {
  38836. if constexpr(is_applicable_v<Func, decltype(std::tuple_cat(std::tuple<entity_type>{}, std::declval<basic_view>().get({})))>) {
  38837. for(const auto pack: each()) {
  38838. std::apply(func, pack);
  38839. }
  38840. } else if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) {
  38841. if constexpr(std::is_void_v<typename Get::value_type>) {
  38842. for(size_type pos = base_type::size(); pos; --pos) {
  38843. func();
  38844. }
  38845. } else {
  38846. if(const auto len = static_cast<difference_type>(base_type::size()); len != 0) {
  38847. for(auto last = storage()->end(), first = last - len; first != last; ++first) {
  38848. func(*first);
  38849. }
  38850. }
  38851. }
  38852. } else {
  38853. static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy");
  38854. for(const auto pack: each()) {
  38855. std::apply([&func](const auto, auto &&...elem) { func(std::forward<decltype(elem)>(elem)...); }, pack);
  38856. }
  38857. }
  38858. }
  38859. /**
  38860. * @brief Returns an iterable object to use to _visit_ a view.
  38861. *
  38862. * The iterable object returns a tuple that contains the current entity and
  38863. * a reference to its element if it's a non-empty one. The _constness_ of
  38864. * the element is as requested.
  38865. *
  38866. * @return An iterable object to use to _visit_ the view.
  38867. */
  38868. [[nodiscard]] iterable each() const noexcept {
  38869. if constexpr(Get::storage_policy == deletion_policy::swap_and_pop || Get::storage_policy == deletion_policy::swap_only) {
  38870. return base_type::handle() ? storage()->each() : iterable{};
  38871. } else {
  38872. static_assert(Get::storage_policy == deletion_policy::in_place, "Unexpected storage policy");
  38873. return iterable{base_type::begin(), base_type::end()};
  38874. }
  38875. }
  38876. /**
  38877. * @brief Combines a view and a storage in _more specific_ view.
  38878. * @tparam OGet Type of storage to combine the view with.
  38879. * @param other The storage for the type to combine the view with.
  38880. * @return A more specific view.
  38881. */
  38882. template<typename OGet>
  38883. [[nodiscard]] std::enable_if_t<std::is_base_of_v<common_type, OGet>, basic_view<get_t<Get, OGet>, exclude_t<>>> operator|(OGet &other) const noexcept {
  38884. return *this | basic_view<get_t<OGet>, exclude_t<>>{other};
  38885. }
  38886. /**
  38887. * @brief Combines two views in a _more specific_ one.
  38888. * @tparam OGet Element list of the view to combine with.
  38889. * @tparam OExclude Filter list of the view to combine with.
  38890. * @param other The view to combine with.
  38891. * @return A more specific view.
  38892. */
  38893. template<typename... OGet, typename... OExclude>
  38894. [[nodiscard]] auto operator|(const basic_view<get_t<OGet...>, exclude_t<OExclude...>> &other) const noexcept {
  38895. return internal::view_pack<basic_view<get_t<Get, OGet...>, exclude_t<OExclude...>>>(
  38896. *this, other, std::index_sequence_for<Get>{}, std::index_sequence_for<>{}, std::index_sequence_for<OGet...>{}, std::index_sequence_for<OExclude...>{});
  38897. }
  38898. };
  38899. /**
  38900. * @brief Deduction guide.
  38901. * @tparam Type Type of storage classes used to create the view.
  38902. * @param storage The storage for the types to iterate.
  38903. */
  38904. template<typename... Type>
  38905. basic_view(Type &...storage) -> basic_view<get_t<Type...>, exclude_t<>>;
  38906. /**
  38907. * @brief Deduction guide.
  38908. * @tparam Get Types of elements iterated by the view.
  38909. * @tparam Exclude Types of elements used to filter the view.
  38910. */
  38911. template<typename... Get, typename... Exclude>
  38912. basic_view(std::tuple<Get &...>, std::tuple<Exclude &...> = {}) -> basic_view<get_t<Get...>, exclude_t<Exclude...>>;
  38913. } // namespace entt
  38914. #endif
  38915. // #include "graph/adjacency_matrix.hpp"
  38916. #ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  38917. #define ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  38918. #include <cstddef>
  38919. #include <iterator>
  38920. #include <memory>
  38921. #include <type_traits>
  38922. #include <utility>
  38923. #include <vector>
  38924. // #include "../config/config.h"
  38925. #ifndef ENTT_CONFIG_CONFIG_H
  38926. #define ENTT_CONFIG_CONFIG_H
  38927. // #include "version.h"
  38928. #ifndef ENTT_CONFIG_VERSION_H
  38929. #define ENTT_CONFIG_VERSION_H
  38930. // #include "macro.h"
  38931. #ifndef ENTT_CONFIG_MACRO_H
  38932. #define ENTT_CONFIG_MACRO_H
  38933. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  38934. #define ENTT_STR(arg) #arg
  38935. #define ENTT_XSTR(arg) ENTT_STR(arg)
  38936. // NOLINTEND(cppcoreguidelines-macro-usage)
  38937. #endif
  38938. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  38939. #define ENTT_VERSION_MAJOR 3
  38940. #define ENTT_VERSION_MINOR 16
  38941. #define ENTT_VERSION_PATCH 0
  38942. #define ENTT_VERSION \
  38943. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  38944. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  38945. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  38946. #endif
  38947. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  38948. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  38949. # define ENTT_CONSTEXPR
  38950. # define ENTT_THROW throw
  38951. # define ENTT_TRY try
  38952. # define ENTT_CATCH catch(...)
  38953. #else
  38954. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  38955. # define ENTT_THROW
  38956. # define ENTT_TRY if(true)
  38957. # define ENTT_CATCH if(false)
  38958. #endif
  38959. #if __has_include(<version>)
  38960. # include <version>
  38961. #
  38962. # if defined(__cpp_consteval)
  38963. # define ENTT_CONSTEVAL consteval
  38964. # endif
  38965. #endif
  38966. #ifndef ENTT_CONSTEVAL
  38967. # define ENTT_CONSTEVAL constexpr
  38968. #endif
  38969. #ifdef ENTT_USE_ATOMIC
  38970. # include <atomic>
  38971. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  38972. #else
  38973. # define ENTT_MAYBE_ATOMIC(Type) Type
  38974. #endif
  38975. #ifndef ENTT_ID_TYPE
  38976. # include <cstdint>
  38977. # define ENTT_ID_TYPE std::uint32_t
  38978. #else
  38979. # include <cstdint> // provides coverage for types in the std namespace
  38980. #endif
  38981. #ifndef ENTT_SPARSE_PAGE
  38982. # define ENTT_SPARSE_PAGE 4096
  38983. #endif
  38984. #ifndef ENTT_PACKED_PAGE
  38985. # define ENTT_PACKED_PAGE 1024
  38986. #endif
  38987. #ifdef ENTT_DISABLE_ASSERT
  38988. # undef ENTT_ASSERT
  38989. # define ENTT_ASSERT(condition, msg) (void(0))
  38990. #elif !defined ENTT_ASSERT
  38991. # include <cassert>
  38992. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  38993. #endif
  38994. #ifdef ENTT_DISABLE_ASSERT
  38995. # undef ENTT_ASSERT_CONSTEXPR
  38996. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  38997. #elif !defined ENTT_ASSERT_CONSTEXPR
  38998. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  38999. #endif
  39000. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  39001. #ifdef ENTT_NO_ETO
  39002. # define ENTT_ETO_TYPE(Type) void
  39003. #else
  39004. # define ENTT_ETO_TYPE(Type) Type
  39005. #endif
  39006. #ifdef ENTT_NO_MIXIN
  39007. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  39008. #else
  39009. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  39010. #endif
  39011. #ifdef ENTT_STANDARD_CPP
  39012. # define ENTT_NONSTD false
  39013. #else
  39014. # define ENTT_NONSTD true
  39015. # if defined __clang__ || defined __GNUC__
  39016. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  39017. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  39018. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  39019. # elif defined _MSC_VER
  39020. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  39021. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  39022. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  39023. # endif
  39024. #endif
  39025. #ifndef ENTT_EXPORT
  39026. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  39027. # define ENTT_EXPORT __declspec(dllexport)
  39028. # define ENTT_IMPORT __declspec(dllimport)
  39029. # define ENTT_HIDDEN
  39030. # elif defined __GNUC__ && __GNUC__ >= 4
  39031. # define ENTT_EXPORT __attribute__((visibility("default")))
  39032. # define ENTT_IMPORT __attribute__((visibility("default")))
  39033. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  39034. # else /* Unsupported compiler */
  39035. # define ENTT_EXPORT
  39036. # define ENTT_IMPORT
  39037. # define ENTT_HIDDEN
  39038. # endif
  39039. #endif
  39040. #ifndef ENTT_API
  39041. # if defined ENTT_API_EXPORT
  39042. # define ENTT_API ENTT_EXPORT
  39043. # elif defined ENTT_API_IMPORT
  39044. # define ENTT_API ENTT_IMPORT
  39045. # else /* No API */
  39046. # define ENTT_API
  39047. # endif
  39048. #endif
  39049. #if defined _MSC_VER
  39050. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  39051. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  39052. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  39053. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  39054. #endif
  39055. // NOLINTEND(cppcoreguidelines-macro-usage)
  39056. #endif
  39057. // #include "../core/iterator.hpp"
  39058. #ifndef ENTT_CORE_ITERATOR_HPP
  39059. #define ENTT_CORE_ITERATOR_HPP
  39060. #include <iterator>
  39061. #include <memory>
  39062. #include <type_traits>
  39063. #include <utility>
  39064. namespace entt {
  39065. /**
  39066. * @brief Helper type to use as pointer with input iterators.
  39067. * @tparam Type of wrapped value.
  39068. */
  39069. template<typename Type>
  39070. struct input_iterator_pointer final {
  39071. /*! @brief Value type. */
  39072. using value_type = Type;
  39073. /*! @brief Pointer type. */
  39074. using pointer = Type *;
  39075. /*! @brief Reference type. */
  39076. using reference = Type &;
  39077. /**
  39078. * @brief Constructs a proxy object by move.
  39079. * @param val Value to use to initialize the proxy object.
  39080. */
  39081. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  39082. : value{std::move(val)} {}
  39083. /**
  39084. * @brief Access operator for accessing wrapped values.
  39085. * @return A pointer to the wrapped value.
  39086. */
  39087. [[nodiscard]] constexpr pointer operator->() noexcept {
  39088. return std::addressof(value);
  39089. }
  39090. /**
  39091. * @brief Dereference operator for accessing wrapped values.
  39092. * @return A reference to the wrapped value.
  39093. */
  39094. [[nodiscard]] constexpr reference operator*() noexcept {
  39095. return value;
  39096. }
  39097. private:
  39098. Type value;
  39099. };
  39100. /**
  39101. * @brief Plain iota iterator (waiting for C++20).
  39102. * @tparam Type Value type.
  39103. */
  39104. template<typename Type>
  39105. class iota_iterator final {
  39106. static_assert(std::is_integral_v<Type>, "Not an integral type");
  39107. public:
  39108. /*! @brief Value type, likely an integral one. */
  39109. using value_type = Type;
  39110. /*! @brief Invalid pointer type. */
  39111. using pointer = void;
  39112. /*! @brief Non-reference type, same as value type. */
  39113. using reference = value_type;
  39114. /*! @brief Difference type. */
  39115. using difference_type = std::ptrdiff_t;
  39116. /*! @brief Iterator category. */
  39117. using iterator_category = std::input_iterator_tag;
  39118. /*! @brief Default constructor. */
  39119. constexpr iota_iterator() noexcept
  39120. : current{} {}
  39121. /**
  39122. * @brief Constructs an iota iterator from a given value.
  39123. * @param init The initial value assigned to the iota iterator.
  39124. */
  39125. constexpr iota_iterator(const value_type init) noexcept
  39126. : current{init} {}
  39127. /**
  39128. * @brief Pre-increment operator.
  39129. * @return This iota iterator.
  39130. */
  39131. constexpr iota_iterator &operator++() noexcept {
  39132. return ++current, *this;
  39133. }
  39134. /**
  39135. * @brief Post-increment operator.
  39136. * @return This iota iterator.
  39137. */
  39138. constexpr iota_iterator operator++(int) noexcept {
  39139. const iota_iterator orig = *this;
  39140. return ++(*this), orig;
  39141. }
  39142. /**
  39143. * @brief Dereference operator.
  39144. * @return The underlying value.
  39145. */
  39146. [[nodiscard]] constexpr reference operator*() const noexcept {
  39147. return current;
  39148. }
  39149. private:
  39150. value_type current;
  39151. };
  39152. /**
  39153. * @brief Comparison operator.
  39154. * @tparam Type Value type of the iota iterator.
  39155. * @param lhs A properly initialized iota iterator.
  39156. * @param rhs A properly initialized iota iterator.
  39157. * @return True if the two iterators are identical, false otherwise.
  39158. */
  39159. template<typename Type>
  39160. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  39161. return *lhs == *rhs;
  39162. }
  39163. /**
  39164. * @brief Comparison operator.
  39165. * @tparam Type Value type of the iota iterator.
  39166. * @param lhs A properly initialized iota iterator.
  39167. * @param rhs A properly initialized iota iterator.
  39168. * @return True if the two iterators differ, false otherwise.
  39169. */
  39170. template<typename Type>
  39171. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  39172. return !(lhs == rhs);
  39173. }
  39174. /**
  39175. * @brief Utility class to create an iterable object from a pair of iterators.
  39176. * @tparam It Type of iterator.
  39177. * @tparam Sentinel Type of sentinel.
  39178. */
  39179. template<typename It, typename Sentinel = It>
  39180. struct iterable_adaptor final {
  39181. /*! @brief Value type. */
  39182. using value_type = typename std::iterator_traits<It>::value_type;
  39183. /*! @brief Iterator type. */
  39184. using iterator = It;
  39185. /*! @brief Sentinel type. */
  39186. using sentinel = Sentinel;
  39187. /*! @brief Default constructor. */
  39188. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  39189. : first{},
  39190. last{} {}
  39191. /**
  39192. * @brief Creates an iterable object from a pair of iterators.
  39193. * @param from Begin iterator.
  39194. * @param to End iterator.
  39195. */
  39196. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  39197. : first{std::move(from)},
  39198. last{std::move(to)} {}
  39199. /**
  39200. * @brief Returns an iterator to the beginning.
  39201. * @return An iterator to the first element of the range.
  39202. */
  39203. [[nodiscard]] constexpr iterator begin() const noexcept {
  39204. return first;
  39205. }
  39206. /**
  39207. * @brief Returns an iterator to the end.
  39208. * @return An iterator to the element following the last element of the
  39209. * range.
  39210. */
  39211. [[nodiscard]] constexpr sentinel end() const noexcept {
  39212. return last;
  39213. }
  39214. /*! @copydoc begin */
  39215. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  39216. return begin();
  39217. }
  39218. /*! @copydoc end */
  39219. [[nodiscard]] constexpr sentinel cend() const noexcept {
  39220. return end();
  39221. }
  39222. private:
  39223. It first;
  39224. Sentinel last;
  39225. };
  39226. } // namespace entt
  39227. #endif
  39228. // #include "fwd.hpp"
  39229. #ifndef ENTT_GRAPH_FWD_HPP
  39230. #define ENTT_GRAPH_FWD_HPP
  39231. #include <cstddef>
  39232. #include <memory>
  39233. // #include "../core/fwd.hpp"
  39234. #ifndef ENTT_CORE_FWD_HPP
  39235. #define ENTT_CORE_FWD_HPP
  39236. #include <cstddef>
  39237. #include <cstdint>
  39238. // #include "../config/config.h"
  39239. #ifndef ENTT_CONFIG_CONFIG_H
  39240. #define ENTT_CONFIG_CONFIG_H
  39241. // #include "version.h"
  39242. #ifndef ENTT_CONFIG_VERSION_H
  39243. #define ENTT_CONFIG_VERSION_H
  39244. // #include "macro.h"
  39245. #ifndef ENTT_CONFIG_MACRO_H
  39246. #define ENTT_CONFIG_MACRO_H
  39247. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  39248. #define ENTT_STR(arg) #arg
  39249. #define ENTT_XSTR(arg) ENTT_STR(arg)
  39250. // NOLINTEND(cppcoreguidelines-macro-usage)
  39251. #endif
  39252. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  39253. #define ENTT_VERSION_MAJOR 3
  39254. #define ENTT_VERSION_MINOR 16
  39255. #define ENTT_VERSION_PATCH 0
  39256. #define ENTT_VERSION \
  39257. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  39258. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  39259. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  39260. #endif
  39261. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  39262. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  39263. # define ENTT_CONSTEXPR
  39264. # define ENTT_THROW throw
  39265. # define ENTT_TRY try
  39266. # define ENTT_CATCH catch(...)
  39267. #else
  39268. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  39269. # define ENTT_THROW
  39270. # define ENTT_TRY if(true)
  39271. # define ENTT_CATCH if(false)
  39272. #endif
  39273. #if __has_include(<version>)
  39274. # include <version>
  39275. #
  39276. # if defined(__cpp_consteval)
  39277. # define ENTT_CONSTEVAL consteval
  39278. # endif
  39279. #endif
  39280. #ifndef ENTT_CONSTEVAL
  39281. # define ENTT_CONSTEVAL constexpr
  39282. #endif
  39283. #ifdef ENTT_USE_ATOMIC
  39284. # include <atomic>
  39285. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  39286. #else
  39287. # define ENTT_MAYBE_ATOMIC(Type) Type
  39288. #endif
  39289. #ifndef ENTT_ID_TYPE
  39290. # include <cstdint>
  39291. # define ENTT_ID_TYPE std::uint32_t
  39292. #else
  39293. # include <cstdint> // provides coverage for types in the std namespace
  39294. #endif
  39295. #ifndef ENTT_SPARSE_PAGE
  39296. # define ENTT_SPARSE_PAGE 4096
  39297. #endif
  39298. #ifndef ENTT_PACKED_PAGE
  39299. # define ENTT_PACKED_PAGE 1024
  39300. #endif
  39301. #ifdef ENTT_DISABLE_ASSERT
  39302. # undef ENTT_ASSERT
  39303. # define ENTT_ASSERT(condition, msg) (void(0))
  39304. #elif !defined ENTT_ASSERT
  39305. # include <cassert>
  39306. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  39307. #endif
  39308. #ifdef ENTT_DISABLE_ASSERT
  39309. # undef ENTT_ASSERT_CONSTEXPR
  39310. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  39311. #elif !defined ENTT_ASSERT_CONSTEXPR
  39312. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  39313. #endif
  39314. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  39315. #ifdef ENTT_NO_ETO
  39316. # define ENTT_ETO_TYPE(Type) void
  39317. #else
  39318. # define ENTT_ETO_TYPE(Type) Type
  39319. #endif
  39320. #ifdef ENTT_NO_MIXIN
  39321. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  39322. #else
  39323. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  39324. #endif
  39325. #ifdef ENTT_STANDARD_CPP
  39326. # define ENTT_NONSTD false
  39327. #else
  39328. # define ENTT_NONSTD true
  39329. # if defined __clang__ || defined __GNUC__
  39330. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  39331. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  39332. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  39333. # elif defined _MSC_VER
  39334. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  39335. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  39336. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  39337. # endif
  39338. #endif
  39339. #ifndef ENTT_EXPORT
  39340. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  39341. # define ENTT_EXPORT __declspec(dllexport)
  39342. # define ENTT_IMPORT __declspec(dllimport)
  39343. # define ENTT_HIDDEN
  39344. # elif defined __GNUC__ && __GNUC__ >= 4
  39345. # define ENTT_EXPORT __attribute__((visibility("default")))
  39346. # define ENTT_IMPORT __attribute__((visibility("default")))
  39347. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  39348. # else /* Unsupported compiler */
  39349. # define ENTT_EXPORT
  39350. # define ENTT_IMPORT
  39351. # define ENTT_HIDDEN
  39352. # endif
  39353. #endif
  39354. #ifndef ENTT_API
  39355. # if defined ENTT_API_EXPORT
  39356. # define ENTT_API ENTT_EXPORT
  39357. # elif defined ENTT_API_IMPORT
  39358. # define ENTT_API ENTT_IMPORT
  39359. # else /* No API */
  39360. # define ENTT_API
  39361. # endif
  39362. #endif
  39363. #if defined _MSC_VER
  39364. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  39365. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  39366. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  39367. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  39368. #endif
  39369. // NOLINTEND(cppcoreguidelines-macro-usage)
  39370. #endif
  39371. namespace entt {
  39372. /*! @brief Possible modes of an any object. */
  39373. enum class any_policy : std::uint8_t {
  39374. /*! @brief Default mode, no element available. */
  39375. empty,
  39376. /*! @brief Owning mode, dynamically allocated element. */
  39377. dynamic,
  39378. /*! @brief Owning mode, embedded element. */
  39379. embedded,
  39380. /*! @brief Aliasing mode, non-const reference. */
  39381. ref,
  39382. /*! @brief Const aliasing mode, const reference. */
  39383. cref
  39384. };
  39385. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  39386. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  39387. class basic_any;
  39388. /*! @brief Alias declaration for type identifiers. */
  39389. using id_type = ENTT_ID_TYPE;
  39390. /*! @brief Alias declaration for the most common use case. */
  39391. using any = basic_any<>;
  39392. template<typename, typename>
  39393. class compressed_pair;
  39394. template<typename>
  39395. class basic_hashed_string;
  39396. /*! @brief Aliases for common character types. */
  39397. using hashed_string = basic_hashed_string<char>;
  39398. /*! @brief Aliases for common character types. */
  39399. using hashed_wstring = basic_hashed_string<wchar_t>;
  39400. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  39401. struct type_info;
  39402. } // namespace entt
  39403. #endif
  39404. namespace entt {
  39405. /*! @brief Undirected graph category tag. */
  39406. struct directed_tag {};
  39407. /*! @brief Directed graph category tag. */
  39408. struct undirected_tag: directed_tag {};
  39409. template<typename, typename = std::allocator<std::size_t>>
  39410. class adjacency_matrix;
  39411. template<typename = std::allocator<id_type>>
  39412. class basic_flow;
  39413. /*! @brief Alias declaration for the most common use case. */
  39414. using flow = basic_flow<>;
  39415. } // namespace entt
  39416. #endif
  39417. namespace entt {
  39418. /*! @cond TURN_OFF_DOXYGEN */
  39419. namespace internal {
  39420. template<typename It>
  39421. class edge_iterator {
  39422. using size_type = std::size_t;
  39423. void find_next() noexcept {
  39424. for(; pos != last && !it[static_cast<typename It::difference_type>(pos)]; pos += offset) {}
  39425. }
  39426. public:
  39427. using value_type = std::pair<size_type, size_type>;
  39428. using pointer = input_iterator_pointer<value_type>;
  39429. using reference = value_type;
  39430. using difference_type = std::ptrdiff_t;
  39431. using iterator_category = std::input_iterator_tag;
  39432. using iterator_concept = std::forward_iterator_tag;
  39433. constexpr edge_iterator() noexcept = default;
  39434. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
  39435. constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept
  39436. : it{std::move(base)},
  39437. vert{vertices},
  39438. pos{from},
  39439. last{to},
  39440. offset{step} {
  39441. find_next();
  39442. }
  39443. constexpr edge_iterator &operator++() noexcept {
  39444. pos += offset;
  39445. find_next();
  39446. return *this;
  39447. }
  39448. constexpr edge_iterator operator++(int) noexcept {
  39449. const edge_iterator orig = *this;
  39450. return ++(*this), orig;
  39451. }
  39452. [[nodiscard]] constexpr reference operator*() const noexcept {
  39453. return *operator->();
  39454. }
  39455. [[nodiscard]] constexpr pointer operator->() const noexcept {
  39456. return std::make_pair<size_type>(pos / vert, pos % vert);
  39457. }
  39458. template<typename Type>
  39459. friend constexpr bool operator==(const edge_iterator<Type> &, const edge_iterator<Type> &) noexcept;
  39460. private:
  39461. It it{};
  39462. size_type vert{};
  39463. size_type pos{};
  39464. size_type last{};
  39465. size_type offset{};
  39466. };
  39467. template<typename Container>
  39468. [[nodiscard]] constexpr bool operator==(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  39469. return lhs.pos == rhs.pos;
  39470. }
  39471. template<typename Container>
  39472. [[nodiscard]] constexpr bool operator!=(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  39473. return !(lhs == rhs);
  39474. }
  39475. } // namespace internal
  39476. /*! @endcond */
  39477. /**
  39478. * @brief Basic implementation of a directed adjacency matrix.
  39479. * @tparam Category Either a directed or undirected category tag.
  39480. * @tparam Allocator Type of allocator used to manage memory and elements.
  39481. */
  39482. template<typename Category, typename Allocator>
  39483. class adjacency_matrix {
  39484. using alloc_traits = std::allocator_traits<Allocator>;
  39485. static_assert(std::is_base_of_v<directed_tag, Category>, "Invalid graph category");
  39486. static_assert(std::is_same_v<typename alloc_traits::value_type, std::size_t>, "Invalid value type");
  39487. using container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  39488. public:
  39489. /*! @brief Allocator type. */
  39490. using allocator_type = Allocator;
  39491. /*! @brief Unsigned integer type. */
  39492. using size_type = std::size_t;
  39493. /*! @brief Vertex type. */
  39494. using vertex_type = size_type;
  39495. /*! @brief Edge type. */
  39496. using edge_type = std::pair<vertex_type, vertex_type>;
  39497. /*! @brief Vertex iterator type. */
  39498. using vertex_iterator = iota_iterator<vertex_type>;
  39499. /*! @brief Edge iterator type. */
  39500. using edge_iterator = internal::edge_iterator<typename container_type::const_iterator>;
  39501. /*! @brief Out-edge iterator type. */
  39502. using out_edge_iterator = edge_iterator;
  39503. /*! @brief In-edge iterator type. */
  39504. using in_edge_iterator = edge_iterator;
  39505. /*! @brief Graph category tag. */
  39506. using graph_category = Category;
  39507. /*! @brief Default constructor. */
  39508. adjacency_matrix() noexcept(noexcept(allocator_type{}))
  39509. : adjacency_matrix{0u} {
  39510. }
  39511. /**
  39512. * @brief Constructs an empty container with a given allocator.
  39513. * @param allocator The allocator to use.
  39514. */
  39515. explicit adjacency_matrix(const allocator_type &allocator) noexcept
  39516. : adjacency_matrix{0u, allocator} {}
  39517. /**
  39518. * @brief Constructs an empty container with a given allocator and user
  39519. * supplied number of vertices.
  39520. * @param vertices Number of vertices.
  39521. * @param allocator The allocator to use.
  39522. */
  39523. adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{})
  39524. : matrix{vertices * vertices, allocator},
  39525. vert{vertices} {}
  39526. /*! @brief Default copy constructor. */
  39527. adjacency_matrix(const adjacency_matrix &) = default;
  39528. /**
  39529. * @brief Allocator-extended copy constructor.
  39530. * @param other The instance to copy from.
  39531. * @param allocator The allocator to use.
  39532. */
  39533. adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator)
  39534. : matrix{other.matrix, allocator},
  39535. vert{other.vert} {}
  39536. /*! @brief Default move constructor. */
  39537. adjacency_matrix(adjacency_matrix &&) noexcept = default;
  39538. /**
  39539. * @brief Allocator-extended move constructor.
  39540. * @param other The instance to move from.
  39541. * @param allocator The allocator to use.
  39542. */
  39543. adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator)
  39544. : matrix{std::move(other.matrix), allocator},
  39545. vert{other.vert} {}
  39546. /*! @brief Default destructor. */
  39547. ~adjacency_matrix() = default;
  39548. /**
  39549. * @brief Default copy assignment operator.
  39550. * @return This container.
  39551. */
  39552. adjacency_matrix &operator=(const adjacency_matrix &) = default;
  39553. /**
  39554. * @brief Default move assignment operator.
  39555. * @return This container.
  39556. */
  39557. adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default;
  39558. /**
  39559. * @brief Exchanges the contents with those of a given adjacency matrix.
  39560. * @param other Adjacency matrix to exchange the content with.
  39561. */
  39562. void swap(adjacency_matrix &other) noexcept {
  39563. using std::swap;
  39564. swap(matrix, other.matrix);
  39565. swap(vert, other.vert);
  39566. }
  39567. /**
  39568. * @brief Returns the associated allocator.
  39569. * @return The associated allocator.
  39570. */
  39571. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  39572. return matrix.get_allocator();
  39573. }
  39574. /*! @brief Clears the adjacency matrix. */
  39575. void clear() noexcept {
  39576. matrix.clear();
  39577. vert = {};
  39578. }
  39579. /**
  39580. * @brief Returns true if an adjacency matrix is empty, false otherwise.
  39581. *
  39582. * @warning
  39583. * Potentially expensive, try to avoid it on hot paths.
  39584. *
  39585. * @return True if the adjacency matrix is empty, false otherwise.
  39586. */
  39587. [[nodiscard]] bool empty() const noexcept {
  39588. const auto iterable = edges();
  39589. return (iterable.begin() == iterable.end());
  39590. }
  39591. /**
  39592. * @brief Returns the number of vertices.
  39593. * @return The number of vertices.
  39594. */
  39595. [[nodiscard]] size_type size() const noexcept {
  39596. return vert;
  39597. }
  39598. /**
  39599. * @brief Returns an iterable object to visit all vertices of a matrix.
  39600. * @return An iterable object to visit all vertices of a matrix.
  39601. */
  39602. [[nodiscard]] iterable_adaptor<vertex_iterator> vertices() const noexcept {
  39603. return {0u, vert};
  39604. }
  39605. /**
  39606. * @brief Returns an iterable object to visit all edges of a matrix.
  39607. * @return An iterable object to visit all edges of a matrix.
  39608. */
  39609. [[nodiscard]] iterable_adaptor<edge_iterator> edges() const noexcept {
  39610. const auto it = matrix.cbegin();
  39611. const auto sz = matrix.size();
  39612. return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}};
  39613. }
  39614. /**
  39615. * @brief Returns an iterable object to visit all out-edges of a vertex.
  39616. * @param vertex The vertex of which to return all out-edges.
  39617. * @return An iterable object to visit all out-edges of a vertex.
  39618. */
  39619. [[nodiscard]] iterable_adaptor<out_edge_iterator> out_edges(const vertex_type vertex) const noexcept {
  39620. const auto it = matrix.cbegin();
  39621. const auto from = vertex * vert;
  39622. const auto to = from + vert;
  39623. return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}};
  39624. }
  39625. /**
  39626. * @brief Returns an iterable object to visit all in-edges of a vertex.
  39627. * @param vertex The vertex of which to return all in-edges.
  39628. * @return An iterable object to visit all in-edges of a vertex.
  39629. */
  39630. [[nodiscard]] iterable_adaptor<in_edge_iterator> in_edges(const vertex_type vertex) const noexcept {
  39631. const auto it = matrix.cbegin();
  39632. const auto from = vertex;
  39633. const auto to = vert * vert + from;
  39634. return {{it, vert, from, to, vert}, {it, vert, to, to, vert}};
  39635. }
  39636. /**
  39637. * @brief Resizes an adjacency matrix.
  39638. * @param vertices The new number of vertices.
  39639. */
  39640. void resize(const size_type vertices) {
  39641. adjacency_matrix other{vertices, get_allocator()};
  39642. for(auto [lhs, rhs]: edges()) {
  39643. other.insert(lhs, rhs);
  39644. }
  39645. other.swap(*this);
  39646. }
  39647. /**
  39648. * @brief Inserts an edge into the adjacency matrix, if it does not exist.
  39649. * @param lhs The left hand vertex of the edge.
  39650. * @param rhs The right hand vertex of the edge.
  39651. * @return A pair consisting of an iterator to the inserted element (or to
  39652. * the element that prevented the insertion) and a bool denoting whether the
  39653. * insertion took place.
  39654. */
  39655. std::pair<edge_iterator, bool> insert(const vertex_type lhs, const vertex_type rhs) {
  39656. const auto pos = lhs * vert + rhs;
  39657. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  39658. const auto rev = rhs * vert + lhs;
  39659. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  39660. matrix[rev] = 1u;
  39661. }
  39662. const auto inserted = !std::exchange(matrix[pos], 1u);
  39663. return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted};
  39664. }
  39665. /**
  39666. * @brief Removes the edge associated with a pair of given vertices.
  39667. * @param lhs The left hand vertex of the edge.
  39668. * @param rhs The right hand vertex of the edge.
  39669. * @return Number of elements removed (either 0 or 1).
  39670. */
  39671. size_type erase(const vertex_type lhs, const vertex_type rhs) {
  39672. const auto pos = lhs * vert + rhs;
  39673. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  39674. const auto rev = rhs * vert + lhs;
  39675. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  39676. matrix[rev] = 0u;
  39677. }
  39678. return std::exchange(matrix[pos], 0u);
  39679. }
  39680. /**
  39681. * @brief Checks if an adjacency matrix contains a given edge.
  39682. * @param lhs The left hand vertex of the edge.
  39683. * @param rhs The right hand vertex of the edge.
  39684. * @return True if there is such an edge, false otherwise.
  39685. */
  39686. [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const {
  39687. const auto pos = lhs * vert + rhs;
  39688. return pos < matrix.size() && matrix[pos];
  39689. }
  39690. private:
  39691. container_type matrix;
  39692. size_type vert;
  39693. };
  39694. } // namespace entt
  39695. #endif
  39696. // #include "graph/dot.hpp"
  39697. #ifndef ENTT_GRAPH_DOT_HPP
  39698. #define ENTT_GRAPH_DOT_HPP
  39699. #include <ostream>
  39700. #include <type_traits>
  39701. // #include "fwd.hpp"
  39702. namespace entt {
  39703. /**
  39704. * @brief Outputs a graph in dot format.
  39705. * @tparam Graph Graph type, valid as long as it exposes edges and vertices.
  39706. * @tparam Writer Vertex decorator type.
  39707. * @param out A standard output stream.
  39708. * @param graph The graph to output.
  39709. * @param writer Vertex decorator object.
  39710. */
  39711. template<typename Graph, typename Writer>
  39712. void dot(std::ostream &out, const Graph &graph, Writer writer) {
  39713. static_assert(std::is_base_of_v<directed_tag, typename Graph::graph_category>, "Invalid graph category");
  39714. if constexpr(std::is_same_v<typename Graph::graph_category, undirected_tag>) {
  39715. out << "graph{";
  39716. } else {
  39717. out << "digraph{";
  39718. }
  39719. for(auto &&vertex: graph.vertices()) {
  39720. out << vertex << "[";
  39721. writer(out, vertex);
  39722. out << "];";
  39723. }
  39724. for(auto [lhs, rhs]: graph.edges()) {
  39725. if constexpr(std::is_same_v<typename Graph::graph_category, undirected_tag>) {
  39726. out << lhs << "--" << rhs << ";";
  39727. } else {
  39728. out << lhs << "->" << rhs << ";";
  39729. }
  39730. }
  39731. out << "}";
  39732. }
  39733. /**
  39734. * @brief Outputs a graph in dot format.
  39735. * @tparam Graph Graph type, valid as long as it exposes edges and vertices.
  39736. * @param out A standard output stream.
  39737. * @param graph The graph to output.
  39738. */
  39739. template<typename Graph>
  39740. void dot(std::ostream &out, const Graph &graph) {
  39741. return dot(out, graph, [](auto &&...) {});
  39742. }
  39743. } // namespace entt
  39744. #endif
  39745. // #include "graph/flow.hpp"
  39746. #ifndef ENTT_GRAPH_FLOW_HPP
  39747. #define ENTT_GRAPH_FLOW_HPP
  39748. #include <algorithm>
  39749. #include <cstddef>
  39750. #include <functional>
  39751. #include <iterator>
  39752. #include <memory>
  39753. #include <type_traits>
  39754. #include <utility>
  39755. #include <vector>
  39756. // #include "../config/config.h"
  39757. // #include "../container/dense_map.hpp"
  39758. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  39759. #define ENTT_CONTAINER_DENSE_MAP_HPP
  39760. #include <cmath>
  39761. #include <cstddef>
  39762. #include <functional>
  39763. #include <iterator>
  39764. #include <limits>
  39765. #include <memory>
  39766. #include <tuple>
  39767. #include <type_traits>
  39768. #include <utility>
  39769. #include <vector>
  39770. // #include "../config/config.h"
  39771. #ifndef ENTT_CONFIG_CONFIG_H
  39772. #define ENTT_CONFIG_CONFIG_H
  39773. // #include "version.h"
  39774. #ifndef ENTT_CONFIG_VERSION_H
  39775. #define ENTT_CONFIG_VERSION_H
  39776. // #include "macro.h"
  39777. #ifndef ENTT_CONFIG_MACRO_H
  39778. #define ENTT_CONFIG_MACRO_H
  39779. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  39780. #define ENTT_STR(arg) #arg
  39781. #define ENTT_XSTR(arg) ENTT_STR(arg)
  39782. // NOLINTEND(cppcoreguidelines-macro-usage)
  39783. #endif
  39784. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  39785. #define ENTT_VERSION_MAJOR 3
  39786. #define ENTT_VERSION_MINOR 16
  39787. #define ENTT_VERSION_PATCH 0
  39788. #define ENTT_VERSION \
  39789. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  39790. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  39791. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  39792. #endif
  39793. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  39794. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  39795. # define ENTT_CONSTEXPR
  39796. # define ENTT_THROW throw
  39797. # define ENTT_TRY try
  39798. # define ENTT_CATCH catch(...)
  39799. #else
  39800. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  39801. # define ENTT_THROW
  39802. # define ENTT_TRY if(true)
  39803. # define ENTT_CATCH if(false)
  39804. #endif
  39805. #if __has_include(<version>)
  39806. # include <version>
  39807. #
  39808. # if defined(__cpp_consteval)
  39809. # define ENTT_CONSTEVAL consteval
  39810. # endif
  39811. #endif
  39812. #ifndef ENTT_CONSTEVAL
  39813. # define ENTT_CONSTEVAL constexpr
  39814. #endif
  39815. #ifdef ENTT_USE_ATOMIC
  39816. # include <atomic>
  39817. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  39818. #else
  39819. # define ENTT_MAYBE_ATOMIC(Type) Type
  39820. #endif
  39821. #ifndef ENTT_ID_TYPE
  39822. # include <cstdint>
  39823. # define ENTT_ID_TYPE std::uint32_t
  39824. #else
  39825. # include <cstdint> // provides coverage for types in the std namespace
  39826. #endif
  39827. #ifndef ENTT_SPARSE_PAGE
  39828. # define ENTT_SPARSE_PAGE 4096
  39829. #endif
  39830. #ifndef ENTT_PACKED_PAGE
  39831. # define ENTT_PACKED_PAGE 1024
  39832. #endif
  39833. #ifdef ENTT_DISABLE_ASSERT
  39834. # undef ENTT_ASSERT
  39835. # define ENTT_ASSERT(condition, msg) (void(0))
  39836. #elif !defined ENTT_ASSERT
  39837. # include <cassert>
  39838. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  39839. #endif
  39840. #ifdef ENTT_DISABLE_ASSERT
  39841. # undef ENTT_ASSERT_CONSTEXPR
  39842. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  39843. #elif !defined ENTT_ASSERT_CONSTEXPR
  39844. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  39845. #endif
  39846. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  39847. #ifdef ENTT_NO_ETO
  39848. # define ENTT_ETO_TYPE(Type) void
  39849. #else
  39850. # define ENTT_ETO_TYPE(Type) Type
  39851. #endif
  39852. #ifdef ENTT_NO_MIXIN
  39853. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  39854. #else
  39855. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  39856. #endif
  39857. #ifdef ENTT_STANDARD_CPP
  39858. # define ENTT_NONSTD false
  39859. #else
  39860. # define ENTT_NONSTD true
  39861. # if defined __clang__ || defined __GNUC__
  39862. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  39863. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  39864. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  39865. # elif defined _MSC_VER
  39866. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  39867. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  39868. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  39869. # endif
  39870. #endif
  39871. #ifndef ENTT_EXPORT
  39872. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  39873. # define ENTT_EXPORT __declspec(dllexport)
  39874. # define ENTT_IMPORT __declspec(dllimport)
  39875. # define ENTT_HIDDEN
  39876. # elif defined __GNUC__ && __GNUC__ >= 4
  39877. # define ENTT_EXPORT __attribute__((visibility("default")))
  39878. # define ENTT_IMPORT __attribute__((visibility("default")))
  39879. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  39880. # else /* Unsupported compiler */
  39881. # define ENTT_EXPORT
  39882. # define ENTT_IMPORT
  39883. # define ENTT_HIDDEN
  39884. # endif
  39885. #endif
  39886. #ifndef ENTT_API
  39887. # if defined ENTT_API_EXPORT
  39888. # define ENTT_API ENTT_EXPORT
  39889. # elif defined ENTT_API_IMPORT
  39890. # define ENTT_API ENTT_IMPORT
  39891. # else /* No API */
  39892. # define ENTT_API
  39893. # endif
  39894. #endif
  39895. #if defined _MSC_VER
  39896. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  39897. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  39898. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  39899. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  39900. #endif
  39901. // NOLINTEND(cppcoreguidelines-macro-usage)
  39902. #endif
  39903. // #include "../core/bit.hpp"
  39904. #ifndef ENTT_CORE_BIT_HPP
  39905. #define ENTT_CORE_BIT_HPP
  39906. #include <cstddef>
  39907. #include <limits>
  39908. #include <type_traits>
  39909. // #include "../config/config.h"
  39910. #ifndef ENTT_CONFIG_CONFIG_H
  39911. #define ENTT_CONFIG_CONFIG_H
  39912. // #include "version.h"
  39913. #ifndef ENTT_CONFIG_VERSION_H
  39914. #define ENTT_CONFIG_VERSION_H
  39915. // #include "macro.h"
  39916. #ifndef ENTT_CONFIG_MACRO_H
  39917. #define ENTT_CONFIG_MACRO_H
  39918. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  39919. #define ENTT_STR(arg) #arg
  39920. #define ENTT_XSTR(arg) ENTT_STR(arg)
  39921. // NOLINTEND(cppcoreguidelines-macro-usage)
  39922. #endif
  39923. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  39924. #define ENTT_VERSION_MAJOR 3
  39925. #define ENTT_VERSION_MINOR 16
  39926. #define ENTT_VERSION_PATCH 0
  39927. #define ENTT_VERSION \
  39928. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  39929. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  39930. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  39931. #endif
  39932. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  39933. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  39934. # define ENTT_CONSTEXPR
  39935. # define ENTT_THROW throw
  39936. # define ENTT_TRY try
  39937. # define ENTT_CATCH catch(...)
  39938. #else
  39939. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  39940. # define ENTT_THROW
  39941. # define ENTT_TRY if(true)
  39942. # define ENTT_CATCH if(false)
  39943. #endif
  39944. #if __has_include(<version>)
  39945. # include <version>
  39946. #
  39947. # if defined(__cpp_consteval)
  39948. # define ENTT_CONSTEVAL consteval
  39949. # endif
  39950. #endif
  39951. #ifndef ENTT_CONSTEVAL
  39952. # define ENTT_CONSTEVAL constexpr
  39953. #endif
  39954. #ifdef ENTT_USE_ATOMIC
  39955. # include <atomic>
  39956. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  39957. #else
  39958. # define ENTT_MAYBE_ATOMIC(Type) Type
  39959. #endif
  39960. #ifndef ENTT_ID_TYPE
  39961. # include <cstdint>
  39962. # define ENTT_ID_TYPE std::uint32_t
  39963. #else
  39964. # include <cstdint> // provides coverage for types in the std namespace
  39965. #endif
  39966. #ifndef ENTT_SPARSE_PAGE
  39967. # define ENTT_SPARSE_PAGE 4096
  39968. #endif
  39969. #ifndef ENTT_PACKED_PAGE
  39970. # define ENTT_PACKED_PAGE 1024
  39971. #endif
  39972. #ifdef ENTT_DISABLE_ASSERT
  39973. # undef ENTT_ASSERT
  39974. # define ENTT_ASSERT(condition, msg) (void(0))
  39975. #elif !defined ENTT_ASSERT
  39976. # include <cassert>
  39977. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  39978. #endif
  39979. #ifdef ENTT_DISABLE_ASSERT
  39980. # undef ENTT_ASSERT_CONSTEXPR
  39981. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  39982. #elif !defined ENTT_ASSERT_CONSTEXPR
  39983. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  39984. #endif
  39985. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  39986. #ifdef ENTT_NO_ETO
  39987. # define ENTT_ETO_TYPE(Type) void
  39988. #else
  39989. # define ENTT_ETO_TYPE(Type) Type
  39990. #endif
  39991. #ifdef ENTT_NO_MIXIN
  39992. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  39993. #else
  39994. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  39995. #endif
  39996. #ifdef ENTT_STANDARD_CPP
  39997. # define ENTT_NONSTD false
  39998. #else
  39999. # define ENTT_NONSTD true
  40000. # if defined __clang__ || defined __GNUC__
  40001. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  40002. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  40003. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  40004. # elif defined _MSC_VER
  40005. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  40006. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  40007. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  40008. # endif
  40009. #endif
  40010. #ifndef ENTT_EXPORT
  40011. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  40012. # define ENTT_EXPORT __declspec(dllexport)
  40013. # define ENTT_IMPORT __declspec(dllimport)
  40014. # define ENTT_HIDDEN
  40015. # elif defined __GNUC__ && __GNUC__ >= 4
  40016. # define ENTT_EXPORT __attribute__((visibility("default")))
  40017. # define ENTT_IMPORT __attribute__((visibility("default")))
  40018. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  40019. # else /* Unsupported compiler */
  40020. # define ENTT_EXPORT
  40021. # define ENTT_IMPORT
  40022. # define ENTT_HIDDEN
  40023. # endif
  40024. #endif
  40025. #ifndef ENTT_API
  40026. # if defined ENTT_API_EXPORT
  40027. # define ENTT_API ENTT_EXPORT
  40028. # elif defined ENTT_API_IMPORT
  40029. # define ENTT_API ENTT_IMPORT
  40030. # else /* No API */
  40031. # define ENTT_API
  40032. # endif
  40033. #endif
  40034. #if defined _MSC_VER
  40035. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  40036. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  40037. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  40038. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  40039. #endif
  40040. // NOLINTEND(cppcoreguidelines-macro-usage)
  40041. #endif
  40042. namespace entt {
  40043. /**
  40044. * @brief Returns the number of set bits in a value (waiting for C++20 and
  40045. * `std::popcount`).
  40046. * @tparam Type Unsigned integer type.
  40047. * @param value A value of unsigned integer type.
  40048. * @return The number of set bits in the value.
  40049. */
  40050. template<typename Type>
  40051. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  40052. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  40053. }
  40054. /**
  40055. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  40056. * `std::has_single_bit`).
  40057. * @tparam Type Unsigned integer type.
  40058. * @param value A value of unsigned integer type.
  40059. * @return True if the value is a power of two, false otherwise.
  40060. */
  40061. template<typename Type>
  40062. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  40063. return value && ((value & (value - 1)) == 0);
  40064. }
  40065. /**
  40066. * @brief Computes the smallest power of two greater than or equal to a value
  40067. * (waiting for C++20 and `std::bit_ceil`).
  40068. * @tparam Type Unsigned integer type.
  40069. * @param value A value of unsigned integer type.
  40070. * @return The smallest power of two greater than or equal to the given value.
  40071. */
  40072. template<typename Type>
  40073. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  40074. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  40075. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  40076. Type curr = value - (value != 0u);
  40077. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  40078. curr |= (curr >> next);
  40079. }
  40080. return ++curr;
  40081. }
  40082. /**
  40083. * @brief Fast module utility function (powers of two only).
  40084. * @tparam Type Unsigned integer type.
  40085. * @param value A value of unsigned integer type.
  40086. * @param mod _Modulus_, it must be a power of two.
  40087. * @return The common remainder.
  40088. */
  40089. template<typename Type>
  40090. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  40091. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  40092. return static_cast<Type>(value & (mod - 1u));
  40093. }
  40094. } // namespace entt
  40095. #endif
  40096. // #include "../core/compressed_pair.hpp"
  40097. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  40098. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  40099. #include <cstddef>
  40100. #include <tuple>
  40101. #include <type_traits>
  40102. #include <utility>
  40103. // #include "fwd.hpp"
  40104. #ifndef ENTT_CORE_FWD_HPP
  40105. #define ENTT_CORE_FWD_HPP
  40106. #include <cstddef>
  40107. #include <cstdint>
  40108. // #include "../config/config.h"
  40109. namespace entt {
  40110. /*! @brief Possible modes of an any object. */
  40111. enum class any_policy : std::uint8_t {
  40112. /*! @brief Default mode, no element available. */
  40113. empty,
  40114. /*! @brief Owning mode, dynamically allocated element. */
  40115. dynamic,
  40116. /*! @brief Owning mode, embedded element. */
  40117. embedded,
  40118. /*! @brief Aliasing mode, non-const reference. */
  40119. ref,
  40120. /*! @brief Const aliasing mode, const reference. */
  40121. cref
  40122. };
  40123. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  40124. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  40125. class basic_any;
  40126. /*! @brief Alias declaration for type identifiers. */
  40127. using id_type = ENTT_ID_TYPE;
  40128. /*! @brief Alias declaration for the most common use case. */
  40129. using any = basic_any<>;
  40130. template<typename, typename>
  40131. class compressed_pair;
  40132. template<typename>
  40133. class basic_hashed_string;
  40134. /*! @brief Aliases for common character types. */
  40135. using hashed_string = basic_hashed_string<char>;
  40136. /*! @brief Aliases for common character types. */
  40137. using hashed_wstring = basic_hashed_string<wchar_t>;
  40138. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  40139. struct type_info;
  40140. } // namespace entt
  40141. #endif
  40142. // #include "type_traits.hpp"
  40143. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  40144. #define ENTT_CORE_TYPE_TRAITS_HPP
  40145. #include <cstddef>
  40146. #include <iterator>
  40147. #include <tuple>
  40148. #include <type_traits>
  40149. #include <utility>
  40150. // #include "../config/config.h"
  40151. // #include "fwd.hpp"
  40152. namespace entt {
  40153. /**
  40154. * @brief Utility class to disambiguate overloaded functions.
  40155. * @tparam N Number of choices available.
  40156. */
  40157. template<std::size_t N>
  40158. struct choice_t
  40159. // unfortunately, doxygen cannot parse such a construct
  40160. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  40161. {};
  40162. /*! @copybrief choice_t */
  40163. template<>
  40164. struct choice_t<0> {};
  40165. /**
  40166. * @brief Variable template for the choice trick.
  40167. * @tparam N Number of choices available.
  40168. */
  40169. template<std::size_t N>
  40170. inline constexpr choice_t<N> choice{};
  40171. /**
  40172. * @brief Identity type trait.
  40173. *
  40174. * Useful to establish non-deduced contexts in template argument deduction
  40175. * (waiting for C++20) or to provide types through function arguments.
  40176. *
  40177. * @tparam Type A type.
  40178. */
  40179. template<typename Type>
  40180. struct type_identity {
  40181. /*! @brief Identity type. */
  40182. using type = Type;
  40183. };
  40184. /**
  40185. * @brief Helper type.
  40186. * @tparam Type A type.
  40187. */
  40188. template<typename Type>
  40189. using type_identity_t = typename type_identity<Type>::type;
  40190. /**
  40191. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  40192. * @tparam Type The type of which to return the size.
  40193. */
  40194. template<typename Type, typename = void>
  40195. struct size_of: std::integral_constant<std::size_t, 0u> {};
  40196. /*! @copydoc size_of */
  40197. template<typename Type>
  40198. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  40199. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  40200. : std::integral_constant<std::size_t, sizeof(Type)> {};
  40201. /**
  40202. * @brief Helper variable template.
  40203. * @tparam Type The type of which to return the size.
  40204. */
  40205. template<typename Type>
  40206. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  40207. /**
  40208. * @brief Using declaration to be used to _repeat_ the same type a number of
  40209. * times equal to the size of a given parameter pack.
  40210. * @tparam Type A type to repeat.
  40211. */
  40212. template<typename Type, typename>
  40213. using unpack_as_type = Type;
  40214. /**
  40215. * @brief Helper variable template to be used to _repeat_ the same value a
  40216. * number of times equal to the size of a given parameter pack.
  40217. * @tparam Value A value to repeat.
  40218. */
  40219. template<auto Value, typename>
  40220. inline constexpr auto unpack_as_value = Value;
  40221. /**
  40222. * @brief Wraps a static constant.
  40223. * @tparam Value A static constant.
  40224. */
  40225. template<auto Value>
  40226. using integral_constant = std::integral_constant<decltype(Value), Value>;
  40227. /**
  40228. * @brief Alias template to facilitate the creation of named values.
  40229. * @tparam Value A constant value at least convertible to `id_type`.
  40230. */
  40231. template<id_type Value>
  40232. using tag = integral_constant<Value>;
  40233. /**
  40234. * @brief A class to use to push around lists of types, nothing more.
  40235. * @tparam Type Types provided by the type list.
  40236. */
  40237. template<typename... Type>
  40238. struct type_list {
  40239. /*! @brief Type list type. */
  40240. using type = type_list;
  40241. /*! @brief Compile-time number of elements in the type list. */
  40242. static constexpr auto size = sizeof...(Type);
  40243. };
  40244. /*! @brief Primary template isn't defined on purpose. */
  40245. template<std::size_t, typename>
  40246. struct type_list_element;
  40247. /**
  40248. * @brief Provides compile-time indexed access to the types of a type list.
  40249. * @tparam Index Index of the type to return.
  40250. * @tparam First First type provided by the type list.
  40251. * @tparam Other Other types provided by the type list.
  40252. */
  40253. template<std::size_t Index, typename First, typename... Other>
  40254. struct type_list_element<Index, type_list<First, Other...>>
  40255. : type_list_element<Index - 1u, type_list<Other...>> {};
  40256. /**
  40257. * @brief Provides compile-time indexed access to the types of a type list.
  40258. * @tparam First First type provided by the type list.
  40259. * @tparam Other Other types provided by the type list.
  40260. */
  40261. template<typename First, typename... Other>
  40262. struct type_list_element<0u, type_list<First, Other...>> {
  40263. /*! @brief Searched type. */
  40264. using type = First;
  40265. };
  40266. /**
  40267. * @brief Helper type.
  40268. * @tparam Index Index of the type to return.
  40269. * @tparam List Type list to search into.
  40270. */
  40271. template<std::size_t Index, typename List>
  40272. using type_list_element_t = typename type_list_element<Index, List>::type;
  40273. /*! @brief Primary template isn't defined on purpose. */
  40274. template<typename, typename>
  40275. struct type_list_index;
  40276. /**
  40277. * @brief Provides compile-time type access to the types of a type list.
  40278. * @tparam Type Type to look for and for which to return the index.
  40279. * @tparam First First type provided by the type list.
  40280. * @tparam Other Other types provided by the type list.
  40281. */
  40282. template<typename Type, typename First, typename... Other>
  40283. struct type_list_index<Type, type_list<First, Other...>> {
  40284. /*! @brief Unsigned integer type. */
  40285. using value_type = std::size_t;
  40286. /*! @brief Compile-time position of the given type in the sublist. */
  40287. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  40288. };
  40289. /**
  40290. * @brief Provides compile-time type access to the types of a type list.
  40291. * @tparam Type Type to look for and for which to return the index.
  40292. * @tparam Other Other types provided by the type list.
  40293. */
  40294. template<typename Type, typename... Other>
  40295. struct type_list_index<Type, type_list<Type, Other...>> {
  40296. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  40297. /*! @brief Unsigned integer type. */
  40298. using value_type = std::size_t;
  40299. /*! @brief Compile-time position of the given type in the sublist. */
  40300. static constexpr value_type value = 0u;
  40301. };
  40302. /**
  40303. * @brief Provides compile-time type access to the types of a type list.
  40304. * @tparam Type Type to look for and for which to return the index.
  40305. */
  40306. template<typename Type>
  40307. struct type_list_index<Type, type_list<>> {
  40308. /*! @brief Unsigned integer type. */
  40309. using value_type = std::size_t;
  40310. /*! @brief Compile-time position of the given type in the sublist. */
  40311. static constexpr value_type value = 0u;
  40312. };
  40313. /**
  40314. * @brief Helper variable template.
  40315. * @tparam List Type list.
  40316. * @tparam Type Type to look for and for which to return the index.
  40317. */
  40318. template<typename Type, typename List>
  40319. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  40320. /**
  40321. * @brief Concatenates multiple type lists.
  40322. * @tparam Type Types provided by the first type list.
  40323. * @tparam Other Types provided by the second type list.
  40324. * @return A type list composed by the types of both the type lists.
  40325. */
  40326. template<typename... Type, typename... Other>
  40327. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  40328. return {};
  40329. }
  40330. /*! @brief Primary template isn't defined on purpose. */
  40331. template<typename...>
  40332. struct type_list_cat;
  40333. /*! @brief Concatenates multiple type lists. */
  40334. template<>
  40335. struct type_list_cat<> {
  40336. /*! @brief A type list composed by the types of all the type lists. */
  40337. using type = type_list<>;
  40338. };
  40339. /**
  40340. * @brief Concatenates multiple type lists.
  40341. * @tparam Type Types provided by the first type list.
  40342. * @tparam Other Types provided by the second type list.
  40343. * @tparam List Other type lists, if any.
  40344. */
  40345. template<typename... Type, typename... Other, typename... List>
  40346. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  40347. /*! @brief A type list composed by the types of all the type lists. */
  40348. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  40349. };
  40350. /**
  40351. * @brief Concatenates multiple type lists.
  40352. * @tparam Type Types provided by the type list.
  40353. */
  40354. template<typename... Type>
  40355. struct type_list_cat<type_list<Type...>> {
  40356. /*! @brief A type list composed by the types of all the type lists. */
  40357. using type = type_list<Type...>;
  40358. };
  40359. /**
  40360. * @brief Helper type.
  40361. * @tparam List Type lists to concatenate.
  40362. */
  40363. template<typename... List>
  40364. using type_list_cat_t = typename type_list_cat<List...>::type;
  40365. /*! @cond TURN_OFF_DOXYGEN */
  40366. namespace internal {
  40367. template<typename...>
  40368. struct type_list_unique;
  40369. template<typename First, typename... Other, typename... Type>
  40370. struct type_list_unique<type_list<First, Other...>, Type...>
  40371. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  40372. template<typename... Type>
  40373. struct type_list_unique<type_list<>, Type...> {
  40374. using type = type_list<Type...>;
  40375. };
  40376. } // namespace internal
  40377. /*! @endcond */
  40378. /**
  40379. * @brief Removes duplicates types from a type list.
  40380. * @tparam List Type list.
  40381. */
  40382. template<typename List>
  40383. struct type_list_unique {
  40384. /*! @brief A type list without duplicate types. */
  40385. using type = typename internal::type_list_unique<List>::type;
  40386. };
  40387. /**
  40388. * @brief Helper type.
  40389. * @tparam List Type list.
  40390. */
  40391. template<typename List>
  40392. using type_list_unique_t = typename type_list_unique<List>::type;
  40393. /**
  40394. * @brief Provides the member constant `value` to true if a type list contains a
  40395. * given type, false otherwise.
  40396. * @tparam List Type list.
  40397. * @tparam Type Type to look for.
  40398. */
  40399. template<typename List, typename Type>
  40400. struct type_list_contains;
  40401. /**
  40402. * @copybrief type_list_contains
  40403. * @tparam Type Types provided by the type list.
  40404. * @tparam Other Type to look for.
  40405. */
  40406. template<typename... Type, typename Other>
  40407. struct type_list_contains<type_list<Type...>, Other>
  40408. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  40409. /**
  40410. * @brief Helper variable template.
  40411. * @tparam List Type list.
  40412. * @tparam Type Type to look for.
  40413. */
  40414. template<typename List, typename Type>
  40415. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  40416. /*! @brief Primary template isn't defined on purpose. */
  40417. template<typename...>
  40418. struct type_list_diff;
  40419. /**
  40420. * @brief Computes the difference between two type lists.
  40421. * @tparam Type Types provided by the first type list.
  40422. * @tparam Other Types provided by the second type list.
  40423. */
  40424. template<typename... Type, typename... Other>
  40425. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  40426. /*! @brief A type list that is the difference between the two type lists. */
  40427. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  40428. };
  40429. /**
  40430. * @brief Helper type.
  40431. * @tparam List Type lists between which to compute the difference.
  40432. */
  40433. template<typename... List>
  40434. using type_list_diff_t = typename type_list_diff<List...>::type;
  40435. /*! @brief Primary template isn't defined on purpose. */
  40436. template<typename, template<typename...> class>
  40437. struct type_list_transform;
  40438. /**
  40439. * @brief Applies a given _function_ to a type list and generate a new list.
  40440. * @tparam Type Types provided by the type list.
  40441. * @tparam Op Unary operation as template class with a type member named `type`.
  40442. */
  40443. template<typename... Type, template<typename...> class Op>
  40444. struct type_list_transform<type_list<Type...>, Op> {
  40445. /*! @brief Resulting type list after applying the transform function. */
  40446. // NOLINTNEXTLINE(modernize-type-traits)
  40447. using type = type_list<typename Op<Type>::type...>;
  40448. };
  40449. /**
  40450. * @brief Helper type.
  40451. * @tparam List Type list.
  40452. * @tparam Op Unary operation as template class with a type member named `type`.
  40453. */
  40454. template<typename List, template<typename...> class Op>
  40455. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  40456. /**
  40457. * @brief A class to use to push around lists of constant values, nothing more.
  40458. * @tparam Value Values provided by the value list.
  40459. */
  40460. template<auto... Value>
  40461. struct value_list {
  40462. /*! @brief Value list type. */
  40463. using type = value_list;
  40464. /*! @brief Compile-time number of elements in the value list. */
  40465. static constexpr auto size = sizeof...(Value);
  40466. };
  40467. /*! @brief Primary template isn't defined on purpose. */
  40468. template<std::size_t, typename>
  40469. struct value_list_element;
  40470. /**
  40471. * @brief Provides compile-time indexed access to the values of a value list.
  40472. * @tparam Index Index of the value to return.
  40473. * @tparam Value First value provided by the value list.
  40474. * @tparam Other Other values provided by the value list.
  40475. */
  40476. template<std::size_t Index, auto Value, auto... Other>
  40477. struct value_list_element<Index, value_list<Value, Other...>>
  40478. : value_list_element<Index - 1u, value_list<Other...>> {};
  40479. /**
  40480. * @brief Provides compile-time indexed access to the types of a type list.
  40481. * @tparam Value First value provided by the value list.
  40482. * @tparam Other Other values provided by the value list.
  40483. */
  40484. template<auto Value, auto... Other>
  40485. struct value_list_element<0u, value_list<Value, Other...>> {
  40486. /*! @brief Searched type. */
  40487. using type = decltype(Value);
  40488. /*! @brief Searched value. */
  40489. static constexpr auto value = Value;
  40490. };
  40491. /**
  40492. * @brief Helper type.
  40493. * @tparam Index Index of the type to return.
  40494. * @tparam List Value list to search into.
  40495. */
  40496. template<std::size_t Index, typename List>
  40497. using value_list_element_t = typename value_list_element<Index, List>::type;
  40498. /**
  40499. * @brief Helper type.
  40500. * @tparam Index Index of the value to return.
  40501. * @tparam List Value list to search into.
  40502. */
  40503. template<std::size_t Index, typename List>
  40504. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  40505. /*! @brief Primary template isn't defined on purpose. */
  40506. template<auto, typename>
  40507. struct value_list_index;
  40508. /**
  40509. * @brief Provides compile-time type access to the values of a value list.
  40510. * @tparam Value Value to look for and for which to return the index.
  40511. * @tparam First First value provided by the value list.
  40512. * @tparam Other Other values provided by the value list.
  40513. */
  40514. template<auto Value, auto First, auto... Other>
  40515. struct value_list_index<Value, value_list<First, Other...>> {
  40516. /*! @brief Unsigned integer type. */
  40517. using value_type = std::size_t;
  40518. /*! @brief Compile-time position of the given value in the sublist. */
  40519. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  40520. };
  40521. /**
  40522. * @brief Provides compile-time type access to the values of a value list.
  40523. * @tparam Value Value to look for and for which to return the index.
  40524. * @tparam Other Other values provided by the value list.
  40525. */
  40526. template<auto Value, auto... Other>
  40527. struct value_list_index<Value, value_list<Value, Other...>> {
  40528. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  40529. /*! @brief Unsigned integer type. */
  40530. using value_type = std::size_t;
  40531. /*! @brief Compile-time position of the given value in the sublist. */
  40532. static constexpr value_type value = 0u;
  40533. };
  40534. /**
  40535. * @brief Provides compile-time type access to the values of a value list.
  40536. * @tparam Value Value to look for and for which to return the index.
  40537. */
  40538. template<auto Value>
  40539. struct value_list_index<Value, value_list<>> {
  40540. /*! @brief Unsigned integer type. */
  40541. using value_type = std::size_t;
  40542. /*! @brief Compile-time position of the given type in the sublist. */
  40543. static constexpr value_type value = 0u;
  40544. };
  40545. /**
  40546. * @brief Helper variable template.
  40547. * @tparam List Value list.
  40548. * @tparam Value Value to look for and for which to return the index.
  40549. */
  40550. template<auto Value, typename List>
  40551. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  40552. /**
  40553. * @brief Concatenates multiple value lists.
  40554. * @tparam Value Values provided by the first value list.
  40555. * @tparam Other Values provided by the second value list.
  40556. * @return A value list composed by the values of both the value lists.
  40557. */
  40558. template<auto... Value, auto... Other>
  40559. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  40560. return {};
  40561. }
  40562. /*! @brief Primary template isn't defined on purpose. */
  40563. template<typename...>
  40564. struct value_list_cat;
  40565. /*! @brief Concatenates multiple value lists. */
  40566. template<>
  40567. struct value_list_cat<> {
  40568. /*! @brief A value list composed by the values of all the value lists. */
  40569. using type = value_list<>;
  40570. };
  40571. /**
  40572. * @brief Concatenates multiple value lists.
  40573. * @tparam Value Values provided by the first value list.
  40574. * @tparam Other Values provided by the second value list.
  40575. * @tparam List Other value lists, if any.
  40576. */
  40577. template<auto... Value, auto... Other, typename... List>
  40578. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  40579. /*! @brief A value list composed by the values of all the value lists. */
  40580. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  40581. };
  40582. /**
  40583. * @brief Concatenates multiple value lists.
  40584. * @tparam Value Values provided by the value list.
  40585. */
  40586. template<auto... Value>
  40587. struct value_list_cat<value_list<Value...>> {
  40588. /*! @brief A value list composed by the values of all the value lists. */
  40589. using type = value_list<Value...>;
  40590. };
  40591. /**
  40592. * @brief Helper type.
  40593. * @tparam List Value lists to concatenate.
  40594. */
  40595. template<typename... List>
  40596. using value_list_cat_t = typename value_list_cat<List...>::type;
  40597. /*! @brief Primary template isn't defined on purpose. */
  40598. template<typename>
  40599. struct value_list_unique;
  40600. /**
  40601. * @brief Removes duplicates values from a value list.
  40602. * @tparam Value One of the values provided by the given value list.
  40603. * @tparam Other The other values provided by the given value list.
  40604. */
  40605. template<auto Value, auto... Other>
  40606. struct value_list_unique<value_list<Value, Other...>> {
  40607. /*! @brief A value list without duplicate types. */
  40608. using type = std::conditional_t<
  40609. ((Value == Other) || ...),
  40610. typename value_list_unique<value_list<Other...>>::type,
  40611. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  40612. };
  40613. /*! @brief Removes duplicates values from a value list. */
  40614. template<>
  40615. struct value_list_unique<value_list<>> {
  40616. /*! @brief A value list without duplicate types. */
  40617. using type = value_list<>;
  40618. };
  40619. /**
  40620. * @brief Helper type.
  40621. * @tparam Type A value list.
  40622. */
  40623. template<typename Type>
  40624. using value_list_unique_t = typename value_list_unique<Type>::type;
  40625. /**
  40626. * @brief Provides the member constant `value` to true if a value list contains
  40627. * a given value, false otherwise.
  40628. * @tparam List Value list.
  40629. * @tparam Value Value to look for.
  40630. */
  40631. template<typename List, auto Value>
  40632. struct value_list_contains;
  40633. /**
  40634. * @copybrief value_list_contains
  40635. * @tparam Value Values provided by the value list.
  40636. * @tparam Other Value to look for.
  40637. */
  40638. template<auto... Value, auto Other>
  40639. struct value_list_contains<value_list<Value...>, Other>
  40640. : std::bool_constant<((Value == Other) || ...)> {};
  40641. /**
  40642. * @brief Helper variable template.
  40643. * @tparam List Value list.
  40644. * @tparam Value Value to look for.
  40645. */
  40646. template<typename List, auto Value>
  40647. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  40648. /*! @brief Primary template isn't defined on purpose. */
  40649. template<typename...>
  40650. struct value_list_diff;
  40651. /**
  40652. * @brief Computes the difference between two value lists.
  40653. * @tparam Value Values provided by the first value list.
  40654. * @tparam Other Values provided by the second value list.
  40655. */
  40656. template<auto... Value, auto... Other>
  40657. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  40658. /*! @brief A value list that is the difference between the two value lists. */
  40659. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  40660. };
  40661. /**
  40662. * @brief Helper type.
  40663. * @tparam List Value lists between which to compute the difference.
  40664. */
  40665. template<typename... List>
  40666. using value_list_diff_t = typename value_list_diff<List...>::type;
  40667. /*! @brief Same as std::is_invocable, but with tuples. */
  40668. template<typename, typename>
  40669. struct is_applicable: std::false_type {};
  40670. /**
  40671. * @copybrief is_applicable
  40672. * @tparam Func A valid function type.
  40673. * @tparam Tuple Tuple-like type.
  40674. * @tparam Args The list of arguments to use to probe the function type.
  40675. */
  40676. template<typename Func, template<typename...> class Tuple, typename... Args>
  40677. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  40678. /**
  40679. * @copybrief is_applicable
  40680. * @tparam Func A valid function type.
  40681. * @tparam Tuple Tuple-like type.
  40682. * @tparam Args The list of arguments to use to probe the function type.
  40683. */
  40684. template<typename Func, template<typename...> class Tuple, typename... Args>
  40685. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  40686. /**
  40687. * @brief Helper variable template.
  40688. * @tparam Func A valid function type.
  40689. * @tparam Args The list of arguments to use to probe the function type.
  40690. */
  40691. template<typename Func, typename Args>
  40692. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  40693. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  40694. template<typename, typename, typename>
  40695. struct is_applicable_r: std::false_type {};
  40696. /**
  40697. * @copybrief is_applicable_r
  40698. * @tparam Ret The type to which the return type of the function should be
  40699. * convertible.
  40700. * @tparam Func A valid function type.
  40701. * @tparam Args The list of arguments to use to probe the function type.
  40702. */
  40703. template<typename Ret, typename Func, typename... Args>
  40704. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  40705. /**
  40706. * @brief Helper variable template.
  40707. * @tparam Ret The type to which the return type of the function should be
  40708. * convertible.
  40709. * @tparam Func A valid function type.
  40710. * @tparam Args The list of arguments to use to probe the function type.
  40711. */
  40712. template<typename Ret, typename Func, typename Args>
  40713. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  40714. /**
  40715. * @brief Provides the member constant `value` to true if a given type is
  40716. * complete, false otherwise.
  40717. * @tparam Type The type to test.
  40718. */
  40719. template<typename Type, typename = void>
  40720. struct is_complete: std::false_type {};
  40721. /*! @copydoc is_complete */
  40722. template<typename Type>
  40723. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  40724. /**
  40725. * @brief Helper variable template.
  40726. * @tparam Type The type to test.
  40727. */
  40728. template<typename Type>
  40729. inline constexpr bool is_complete_v = is_complete<Type>::value;
  40730. /**
  40731. * @brief Provides the member constant `value` to true if a given type is an
  40732. * iterator, false otherwise.
  40733. * @tparam Type The type to test.
  40734. */
  40735. template<typename Type, typename = void>
  40736. struct is_iterator: std::false_type {};
  40737. /*! @cond TURN_OFF_DOXYGEN */
  40738. namespace internal {
  40739. template<typename, typename = void>
  40740. struct has_iterator_category: std::false_type {};
  40741. template<typename Type>
  40742. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  40743. } // namespace internal
  40744. /*! @endcond */
  40745. /*! @copydoc is_iterator */
  40746. template<typename Type>
  40747. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  40748. : internal::has_iterator_category<Type> {};
  40749. /**
  40750. * @brief Helper variable template.
  40751. * @tparam Type The type to test.
  40752. */
  40753. template<typename Type>
  40754. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  40755. /**
  40756. * @brief Provides the member constant `value` to true if a given type is both
  40757. * an empty and non-final class, false otherwise.
  40758. * @tparam Type The type to test
  40759. */
  40760. template<typename Type>
  40761. struct is_ebco_eligible
  40762. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  40763. /**
  40764. * @brief Helper variable template.
  40765. * @tparam Type The type to test.
  40766. */
  40767. template<typename Type>
  40768. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  40769. /**
  40770. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  40771. * is valid and denotes a type, false otherwise.
  40772. * @tparam Type The type to test.
  40773. */
  40774. template<typename Type, typename = void>
  40775. struct is_transparent: std::false_type {};
  40776. /*! @copydoc is_transparent */
  40777. template<typename Type>
  40778. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  40779. /**
  40780. * @brief Helper variable template.
  40781. * @tparam Type The type to test.
  40782. */
  40783. template<typename Type>
  40784. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  40785. /*! @cond TURN_OFF_DOXYGEN */
  40786. namespace internal {
  40787. template<typename, typename = void>
  40788. struct has_tuple_size_value: std::false_type {};
  40789. template<typename Type>
  40790. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  40791. template<typename, typename = void>
  40792. struct has_value_type: std::false_type {};
  40793. template<typename Type>
  40794. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  40795. template<typename>
  40796. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  40797. template<typename Type, std::size_t... Index>
  40798. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  40799. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  40800. }
  40801. template<typename>
  40802. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  40803. return false;
  40804. }
  40805. template<typename Type>
  40806. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  40807. return true;
  40808. }
  40809. template<typename Type>
  40810. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  40811. // NOLINTBEGIN(modernize-use-transparent-functors)
  40812. if constexpr(std::is_array_v<Type>) {
  40813. return false;
  40814. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  40815. if constexpr(has_tuple_size_value<Type>::value) {
  40816. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  40817. } else {
  40818. return maybe_equality_comparable<Type>(0);
  40819. }
  40820. } else if constexpr(has_value_type<Type>::value) {
  40821. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  40822. return maybe_equality_comparable<Type>(0);
  40823. } else {
  40824. return false;
  40825. }
  40826. } else {
  40827. return maybe_equality_comparable<Type>(0);
  40828. }
  40829. // NOLINTEND(modernize-use-transparent-functors)
  40830. }
  40831. } // namespace internal
  40832. /*! @endcond */
  40833. /**
  40834. * @brief Provides the member constant `value` to true if a given type is
  40835. * equality comparable, false otherwise.
  40836. * @tparam Type The type to test.
  40837. */
  40838. template<typename Type>
  40839. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  40840. /*! @copydoc is_equality_comparable */
  40841. template<typename Type>
  40842. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  40843. /**
  40844. * @brief Helper variable template.
  40845. * @tparam Type The type to test.
  40846. */
  40847. template<typename Type>
  40848. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  40849. /**
  40850. * @brief Transcribes the constness of a type to another type.
  40851. * @tparam To The type to which to transcribe the constness.
  40852. * @tparam From The type from which to transcribe the constness.
  40853. */
  40854. template<typename To, typename From>
  40855. struct constness_as {
  40856. /*! @brief The type resulting from the transcription of the constness. */
  40857. using type = std::remove_const_t<To>;
  40858. };
  40859. /*! @copydoc constness_as */
  40860. template<typename To, typename From>
  40861. struct constness_as<To, const From> {
  40862. /*! @brief The type resulting from the transcription of the constness. */
  40863. using type = const To;
  40864. };
  40865. /**
  40866. * @brief Alias template to facilitate the transcription of the constness.
  40867. * @tparam To The type to which to transcribe the constness.
  40868. * @tparam From The type from which to transcribe the constness.
  40869. */
  40870. template<typename To, typename From>
  40871. using constness_as_t = typename constness_as<To, From>::type;
  40872. /**
  40873. * @brief Extracts the class of a non-static member object or function.
  40874. * @tparam Member A pointer to a non-static member object or function.
  40875. */
  40876. template<typename Member>
  40877. class member_class {
  40878. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  40879. template<typename Class, typename Ret, typename... Args>
  40880. static Class *clazz(Ret (Class::*)(Args...));
  40881. template<typename Class, typename Ret, typename... Args>
  40882. static Class *clazz(Ret (Class::*)(Args...) const);
  40883. template<typename Class, typename Type>
  40884. static Class *clazz(Type Class::*);
  40885. public:
  40886. /*! @brief The class of the given non-static member object or function. */
  40887. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  40888. };
  40889. /**
  40890. * @brief Helper type.
  40891. * @tparam Member A pointer to a non-static member object or function.
  40892. */
  40893. template<typename Member>
  40894. using member_class_t = typename member_class<Member>::type;
  40895. /**
  40896. * @brief Extracts the n-th argument of a _callable_ type.
  40897. * @tparam Index The index of the argument to extract.
  40898. * @tparam Candidate A valid _callable_ type.
  40899. */
  40900. template<std::size_t Index, typename Candidate>
  40901. class nth_argument {
  40902. template<typename Ret, typename... Args>
  40903. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  40904. template<typename Ret, typename Class, typename... Args>
  40905. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  40906. template<typename Ret, typename Class, typename... Args>
  40907. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  40908. template<typename Type, typename Class>
  40909. static constexpr type_list<Type> pick_up(Type Class ::*);
  40910. template<typename Type>
  40911. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  40912. public:
  40913. /*! @brief N-th argument of the _callable_ type. */
  40914. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  40915. };
  40916. /**
  40917. * @brief Helper type.
  40918. * @tparam Index The index of the argument to extract.
  40919. * @tparam Candidate A valid function, member function or data member type.
  40920. */
  40921. template<std::size_t Index, typename Candidate>
  40922. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  40923. } // namespace entt
  40924. template<typename... Type>
  40925. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  40926. template<std::size_t Index, typename... Type>
  40927. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  40928. template<auto... Value>
  40929. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  40930. template<std::size_t Index, auto... Value>
  40931. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  40932. #endif
  40933. namespace entt {
  40934. /*! @cond TURN_OFF_DOXYGEN */
  40935. namespace internal {
  40936. template<typename Type, std::size_t, typename = void>
  40937. struct compressed_pair_element {
  40938. using reference = Type &;
  40939. using const_reference = const Type &;
  40940. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  40941. // NOLINTNEXTLINE(modernize-use-equals-default)
  40942. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  40943. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  40944. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  40945. : value{std::forward<Arg>(arg)} {}
  40946. template<typename... Args, std::size_t... Index>
  40947. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  40948. : value{std::forward<Args>(std::get<Index>(args))...} {}
  40949. [[nodiscard]] constexpr reference get() noexcept {
  40950. return value;
  40951. }
  40952. [[nodiscard]] constexpr const_reference get() const noexcept {
  40953. return value;
  40954. }
  40955. private:
  40956. Type value{};
  40957. };
  40958. template<typename Type, std::size_t Tag>
  40959. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  40960. using reference = Type &;
  40961. using const_reference = const Type &;
  40962. using base_type = Type;
  40963. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  40964. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  40965. : base_type{} {}
  40966. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  40967. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  40968. : base_type{std::forward<Arg>(arg)} {}
  40969. template<typename... Args, std::size_t... Index>
  40970. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  40971. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  40972. [[nodiscard]] constexpr reference get() noexcept {
  40973. return *this;
  40974. }
  40975. [[nodiscard]] constexpr const_reference get() const noexcept {
  40976. return *this;
  40977. }
  40978. };
  40979. } // namespace internal
  40980. /*! @endcond */
  40981. /**
  40982. * @brief A compressed pair.
  40983. *
  40984. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  40985. * reduce its final size to a minimum.
  40986. *
  40987. * @tparam First The type of the first element that the pair stores.
  40988. * @tparam Second The type of the second element that the pair stores.
  40989. */
  40990. template<typename First, typename Second>
  40991. class compressed_pair final
  40992. : internal::compressed_pair_element<First, 0u>,
  40993. internal::compressed_pair_element<Second, 1u> {
  40994. using first_base = internal::compressed_pair_element<First, 0u>;
  40995. using second_base = internal::compressed_pair_element<Second, 1u>;
  40996. public:
  40997. /*! @brief The type of the first element that the pair stores. */
  40998. using first_type = First;
  40999. /*! @brief The type of the second element that the pair stores. */
  41000. using second_type = Second;
  41001. /**
  41002. * @brief Default constructor, conditionally enabled.
  41003. *
  41004. * This constructor is only available when the types that the pair stores
  41005. * are both at least default constructible.
  41006. *
  41007. * @tparam Dummy Dummy template parameter used for internal purposes.
  41008. */
  41009. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  41010. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  41011. : first_base{},
  41012. second_base{} {}
  41013. /**
  41014. * @brief Copy constructor.
  41015. * @param other The instance to copy from.
  41016. */
  41017. constexpr compressed_pair(const compressed_pair &other) = default;
  41018. /**
  41019. * @brief Move constructor.
  41020. * @param other The instance to move from.
  41021. */
  41022. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  41023. /**
  41024. * @brief Constructs a pair from its values.
  41025. * @tparam Arg Type of value to use to initialize the first element.
  41026. * @tparam Other Type of value to use to initialize the second element.
  41027. * @param arg Value to use to initialize the first element.
  41028. * @param other Value to use to initialize the second element.
  41029. */
  41030. template<typename Arg, typename Other>
  41031. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  41032. : first_base{std::forward<Arg>(arg)},
  41033. second_base{std::forward<Other>(other)} {}
  41034. /**
  41035. * @brief Constructs a pair by forwarding the arguments to its parts.
  41036. * @tparam Args Types of arguments to use to initialize the first element.
  41037. * @tparam Other Types of arguments to use to initialize the second element.
  41038. * @param args Arguments to use to initialize the first element.
  41039. * @param other Arguments to use to initialize the second element.
  41040. */
  41041. template<typename... Args, typename... Other>
  41042. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  41043. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  41044. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  41045. /*! @brief Default destructor. */
  41046. ~compressed_pair() = default;
  41047. /**
  41048. * @brief Copy assignment operator.
  41049. * @param other The instance to copy from.
  41050. * @return This compressed pair object.
  41051. */
  41052. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  41053. /**
  41054. * @brief Move assignment operator.
  41055. * @param other The instance to move from.
  41056. * @return This compressed pair object.
  41057. */
  41058. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  41059. /**
  41060. * @brief Returns the first element that a pair stores.
  41061. * @return The first element that a pair stores.
  41062. */
  41063. [[nodiscard]] constexpr first_type &first() noexcept {
  41064. return static_cast<first_base &>(*this).get();
  41065. }
  41066. /*! @copydoc first */
  41067. [[nodiscard]] constexpr const first_type &first() const noexcept {
  41068. return static_cast<const first_base &>(*this).get();
  41069. }
  41070. /**
  41071. * @brief Returns the second element that a pair stores.
  41072. * @return The second element that a pair stores.
  41073. */
  41074. [[nodiscard]] constexpr second_type &second() noexcept {
  41075. return static_cast<second_base &>(*this).get();
  41076. }
  41077. /*! @copydoc second */
  41078. [[nodiscard]] constexpr const second_type &second() const noexcept {
  41079. return static_cast<const second_base &>(*this).get();
  41080. }
  41081. /**
  41082. * @brief Swaps two compressed pair objects.
  41083. * @param other The compressed pair to swap with.
  41084. */
  41085. constexpr void swap(compressed_pair &other) noexcept {
  41086. using std::swap;
  41087. swap(first(), other.first());
  41088. swap(second(), other.second());
  41089. }
  41090. /**
  41091. * @brief Extracts an element from the compressed pair.
  41092. * @tparam Index An integer value that is either 0 or 1.
  41093. * @return Returns a reference to the first element if `Index` is 0 and a
  41094. * reference to the second element if `Index` is 1.
  41095. */
  41096. template<std::size_t Index>
  41097. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  41098. if constexpr(Index == 0u) {
  41099. return first();
  41100. } else {
  41101. static_assert(Index == 1u, "Index out of bounds");
  41102. return second();
  41103. }
  41104. }
  41105. /*! @copydoc get */
  41106. template<std::size_t Index>
  41107. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  41108. if constexpr(Index == 0u) {
  41109. return first();
  41110. } else {
  41111. static_assert(Index == 1u, "Index out of bounds");
  41112. return second();
  41113. }
  41114. }
  41115. };
  41116. /**
  41117. * @brief Deduction guide.
  41118. * @tparam Type Type of value to use to initialize the first element.
  41119. * @tparam Other Type of value to use to initialize the second element.
  41120. */
  41121. template<typename Type, typename Other>
  41122. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  41123. /**
  41124. * @brief Swaps two compressed pair objects.
  41125. * @tparam First The type of the first element that the pairs store.
  41126. * @tparam Second The type of the second element that the pairs store.
  41127. * @param lhs A valid compressed pair object.
  41128. * @param rhs A valid compressed pair object.
  41129. */
  41130. template<typename First, typename Second>
  41131. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  41132. lhs.swap(rhs);
  41133. }
  41134. } // namespace entt
  41135. namespace std {
  41136. /**
  41137. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  41138. * @tparam First The type of the first element that the pair stores.
  41139. * @tparam Second The type of the second element that the pair stores.
  41140. */
  41141. template<typename First, typename Second>
  41142. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  41143. /**
  41144. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  41145. * @tparam Index The index of the type to return.
  41146. * @tparam First The type of the first element that the pair stores.
  41147. * @tparam Second The type of the second element that the pair stores.
  41148. */
  41149. template<size_t Index, typename First, typename Second>
  41150. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  41151. static_assert(Index < 2u, "Index out of bounds");
  41152. };
  41153. } // namespace std
  41154. #endif
  41155. // #include "../core/iterator.hpp"
  41156. #ifndef ENTT_CORE_ITERATOR_HPP
  41157. #define ENTT_CORE_ITERATOR_HPP
  41158. #include <iterator>
  41159. #include <memory>
  41160. #include <type_traits>
  41161. #include <utility>
  41162. namespace entt {
  41163. /**
  41164. * @brief Helper type to use as pointer with input iterators.
  41165. * @tparam Type of wrapped value.
  41166. */
  41167. template<typename Type>
  41168. struct input_iterator_pointer final {
  41169. /*! @brief Value type. */
  41170. using value_type = Type;
  41171. /*! @brief Pointer type. */
  41172. using pointer = Type *;
  41173. /*! @brief Reference type. */
  41174. using reference = Type &;
  41175. /**
  41176. * @brief Constructs a proxy object by move.
  41177. * @param val Value to use to initialize the proxy object.
  41178. */
  41179. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  41180. : value{std::move(val)} {}
  41181. /**
  41182. * @brief Access operator for accessing wrapped values.
  41183. * @return A pointer to the wrapped value.
  41184. */
  41185. [[nodiscard]] constexpr pointer operator->() noexcept {
  41186. return std::addressof(value);
  41187. }
  41188. /**
  41189. * @brief Dereference operator for accessing wrapped values.
  41190. * @return A reference to the wrapped value.
  41191. */
  41192. [[nodiscard]] constexpr reference operator*() noexcept {
  41193. return value;
  41194. }
  41195. private:
  41196. Type value;
  41197. };
  41198. /**
  41199. * @brief Plain iota iterator (waiting for C++20).
  41200. * @tparam Type Value type.
  41201. */
  41202. template<typename Type>
  41203. class iota_iterator final {
  41204. static_assert(std::is_integral_v<Type>, "Not an integral type");
  41205. public:
  41206. /*! @brief Value type, likely an integral one. */
  41207. using value_type = Type;
  41208. /*! @brief Invalid pointer type. */
  41209. using pointer = void;
  41210. /*! @brief Non-reference type, same as value type. */
  41211. using reference = value_type;
  41212. /*! @brief Difference type. */
  41213. using difference_type = std::ptrdiff_t;
  41214. /*! @brief Iterator category. */
  41215. using iterator_category = std::input_iterator_tag;
  41216. /*! @brief Default constructor. */
  41217. constexpr iota_iterator() noexcept
  41218. : current{} {}
  41219. /**
  41220. * @brief Constructs an iota iterator from a given value.
  41221. * @param init The initial value assigned to the iota iterator.
  41222. */
  41223. constexpr iota_iterator(const value_type init) noexcept
  41224. : current{init} {}
  41225. /**
  41226. * @brief Pre-increment operator.
  41227. * @return This iota iterator.
  41228. */
  41229. constexpr iota_iterator &operator++() noexcept {
  41230. return ++current, *this;
  41231. }
  41232. /**
  41233. * @brief Post-increment operator.
  41234. * @return This iota iterator.
  41235. */
  41236. constexpr iota_iterator operator++(int) noexcept {
  41237. const iota_iterator orig = *this;
  41238. return ++(*this), orig;
  41239. }
  41240. /**
  41241. * @brief Dereference operator.
  41242. * @return The underlying value.
  41243. */
  41244. [[nodiscard]] constexpr reference operator*() const noexcept {
  41245. return current;
  41246. }
  41247. private:
  41248. value_type current;
  41249. };
  41250. /**
  41251. * @brief Comparison operator.
  41252. * @tparam Type Value type of the iota iterator.
  41253. * @param lhs A properly initialized iota iterator.
  41254. * @param rhs A properly initialized iota iterator.
  41255. * @return True if the two iterators are identical, false otherwise.
  41256. */
  41257. template<typename Type>
  41258. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  41259. return *lhs == *rhs;
  41260. }
  41261. /**
  41262. * @brief Comparison operator.
  41263. * @tparam Type Value type of the iota iterator.
  41264. * @param lhs A properly initialized iota iterator.
  41265. * @param rhs A properly initialized iota iterator.
  41266. * @return True if the two iterators differ, false otherwise.
  41267. */
  41268. template<typename Type>
  41269. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  41270. return !(lhs == rhs);
  41271. }
  41272. /**
  41273. * @brief Utility class to create an iterable object from a pair of iterators.
  41274. * @tparam It Type of iterator.
  41275. * @tparam Sentinel Type of sentinel.
  41276. */
  41277. template<typename It, typename Sentinel = It>
  41278. struct iterable_adaptor final {
  41279. /*! @brief Value type. */
  41280. using value_type = typename std::iterator_traits<It>::value_type;
  41281. /*! @brief Iterator type. */
  41282. using iterator = It;
  41283. /*! @brief Sentinel type. */
  41284. using sentinel = Sentinel;
  41285. /*! @brief Default constructor. */
  41286. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  41287. : first{},
  41288. last{} {}
  41289. /**
  41290. * @brief Creates an iterable object from a pair of iterators.
  41291. * @param from Begin iterator.
  41292. * @param to End iterator.
  41293. */
  41294. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  41295. : first{std::move(from)},
  41296. last{std::move(to)} {}
  41297. /**
  41298. * @brief Returns an iterator to the beginning.
  41299. * @return An iterator to the first element of the range.
  41300. */
  41301. [[nodiscard]] constexpr iterator begin() const noexcept {
  41302. return first;
  41303. }
  41304. /**
  41305. * @brief Returns an iterator to the end.
  41306. * @return An iterator to the element following the last element of the
  41307. * range.
  41308. */
  41309. [[nodiscard]] constexpr sentinel end() const noexcept {
  41310. return last;
  41311. }
  41312. /*! @copydoc begin */
  41313. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  41314. return begin();
  41315. }
  41316. /*! @copydoc end */
  41317. [[nodiscard]] constexpr sentinel cend() const noexcept {
  41318. return end();
  41319. }
  41320. private:
  41321. It first;
  41322. Sentinel last;
  41323. };
  41324. } // namespace entt
  41325. #endif
  41326. // #include "../core/memory.hpp"
  41327. #ifndef ENTT_CORE_MEMORY_HPP
  41328. #define ENTT_CORE_MEMORY_HPP
  41329. #include <cstddef>
  41330. #include <memory>
  41331. #include <tuple>
  41332. #include <type_traits>
  41333. #include <utility>
  41334. // #include "../config/config.h"
  41335. namespace entt {
  41336. /**
  41337. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  41338. * @tparam Type Pointer type.
  41339. * @param ptr Fancy or raw pointer.
  41340. * @return A raw pointer that represents the address of the original pointer.
  41341. */
  41342. template<typename Type>
  41343. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  41344. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  41345. return ptr;
  41346. } else {
  41347. return to_address(std::forward<Type>(ptr).operator->());
  41348. }
  41349. }
  41350. /**
  41351. * @brief Utility function to design allocation-aware containers.
  41352. * @tparam Allocator Type of allocator.
  41353. * @param lhs A valid allocator.
  41354. * @param rhs Another valid allocator.
  41355. */
  41356. template<typename Allocator>
  41357. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  41358. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  41359. lhs = rhs;
  41360. }
  41361. }
  41362. /**
  41363. * @brief Utility function to design allocation-aware containers.
  41364. * @tparam Allocator Type of allocator.
  41365. * @param lhs A valid allocator.
  41366. * @param rhs Another valid allocator.
  41367. */
  41368. template<typename Allocator>
  41369. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  41370. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  41371. lhs = std::move(rhs);
  41372. }
  41373. }
  41374. /**
  41375. * @brief Utility function to design allocation-aware containers.
  41376. * @tparam Allocator Type of allocator.
  41377. * @param lhs A valid allocator.
  41378. * @param rhs Another valid allocator.
  41379. */
  41380. template<typename Allocator>
  41381. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  41382. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  41383. using std::swap;
  41384. swap(lhs, rhs);
  41385. } else {
  41386. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  41387. }
  41388. }
  41389. /**
  41390. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  41391. * @tparam Allocator Type of allocator used to manage memory and elements.
  41392. */
  41393. template<typename Allocator>
  41394. struct allocation_deleter: private Allocator {
  41395. /*! @brief Allocator type. */
  41396. using allocator_type = Allocator;
  41397. /*! @brief Pointer type. */
  41398. using pointer = typename std::allocator_traits<Allocator>::pointer;
  41399. /**
  41400. * @brief Inherited constructors.
  41401. * @param alloc The allocator to use.
  41402. */
  41403. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  41404. : Allocator{alloc} {}
  41405. /**
  41406. * @brief Destroys the pointed object and deallocates its memory.
  41407. * @param ptr A valid pointer to an object of the given type.
  41408. */
  41409. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  41410. using alloc_traits = std::allocator_traits<Allocator>;
  41411. alloc_traits::destroy(*this, to_address(ptr));
  41412. alloc_traits::deallocate(*this, ptr, 1u);
  41413. }
  41414. };
  41415. /**
  41416. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  41417. * @tparam Type Type of object to allocate for and to construct.
  41418. * @tparam Allocator Type of allocator used to manage memory and elements.
  41419. * @tparam Args Types of arguments to use to construct the object.
  41420. * @param allocator The allocator to use.
  41421. * @param args Parameters to use to construct the object.
  41422. * @return A properly initialized unique pointer with a custom deleter.
  41423. */
  41424. template<typename Type, typename Allocator, typename... Args>
  41425. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  41426. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  41427. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  41428. using allocator_type = typename alloc_traits::allocator_type;
  41429. allocator_type alloc{allocator};
  41430. auto ptr = alloc_traits::allocate(alloc, 1u);
  41431. ENTT_TRY {
  41432. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  41433. }
  41434. ENTT_CATCH {
  41435. alloc_traits::deallocate(alloc, ptr, 1u);
  41436. ENTT_THROW;
  41437. }
  41438. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  41439. }
  41440. /*! @cond TURN_OFF_DOXYGEN */
  41441. namespace internal {
  41442. template<typename Type>
  41443. struct uses_allocator_construction {
  41444. template<typename Allocator, typename... Params>
  41445. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  41446. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  41447. return std::forward_as_tuple(std::forward<Params>(params)...);
  41448. } else {
  41449. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  41450. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  41451. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  41452. } else {
  41453. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  41454. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  41455. }
  41456. }
  41457. }
  41458. };
  41459. template<typename Type, typename Other>
  41460. struct uses_allocator_construction<std::pair<Type, Other>> {
  41461. using type = std::pair<Type, Other>;
  41462. template<typename Allocator, typename First, typename Second>
  41463. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  41464. return std::make_tuple(
  41465. std::piecewise_construct,
  41466. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  41467. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  41468. }
  41469. template<typename Allocator>
  41470. static constexpr auto args(const Allocator &allocator) noexcept {
  41471. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  41472. }
  41473. template<typename Allocator, typename First, typename Second>
  41474. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  41475. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  41476. }
  41477. template<typename Allocator, typename First, typename Second>
  41478. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  41479. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  41480. }
  41481. template<typename Allocator, typename First, typename Second>
  41482. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  41483. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  41484. }
  41485. };
  41486. } // namespace internal
  41487. /*! @endcond */
  41488. /**
  41489. * @brief Uses-allocator construction utility (waiting for C++20).
  41490. *
  41491. * Primarily intended for internal use. Prepares the argument list needed to
  41492. * create an object of a given type by means of uses-allocator construction.
  41493. *
  41494. * @tparam Type Type to return arguments for.
  41495. * @tparam Allocator Type of allocator used to manage memory and elements.
  41496. * @tparam Args Types of arguments to use to construct the object.
  41497. * @param allocator The allocator to use.
  41498. * @param args Parameters to use to construct the object.
  41499. * @return The arguments needed to create an object of the given type.
  41500. */
  41501. template<typename Type, typename Allocator, typename... Args>
  41502. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  41503. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  41504. }
  41505. /**
  41506. * @brief Uses-allocator construction utility (waiting for C++20).
  41507. *
  41508. * Primarily intended for internal use. Creates an object of a given type by
  41509. * means of uses-allocator construction.
  41510. *
  41511. * @tparam Type Type of object to create.
  41512. * @tparam Allocator Type of allocator used to manage memory and elements.
  41513. * @tparam Args Types of arguments to use to construct the object.
  41514. * @param allocator The allocator to use.
  41515. * @param args Parameters to use to construct the object.
  41516. * @return A newly created object of the given type.
  41517. */
  41518. template<typename Type, typename Allocator, typename... Args>
  41519. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  41520. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  41521. }
  41522. /**
  41523. * @brief Uses-allocator construction utility (waiting for C++20).
  41524. *
  41525. * Primarily intended for internal use. Creates an object of a given type by
  41526. * means of uses-allocator construction at an uninitialized memory location.
  41527. *
  41528. * @tparam Type Type of object to create.
  41529. * @tparam Allocator Type of allocator used to manage memory and elements.
  41530. * @tparam Args Types of arguments to use to construct the object.
  41531. * @param value Memory location in which to place the object.
  41532. * @param allocator The allocator to use.
  41533. * @param args Parameters to use to construct the object.
  41534. * @return A pointer to the newly created object of the given type.
  41535. */
  41536. template<typename Type, typename Allocator, typename... Args>
  41537. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  41538. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  41539. }
  41540. } // namespace entt
  41541. #endif
  41542. // #include "../core/type_traits.hpp"
  41543. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  41544. #define ENTT_CORE_TYPE_TRAITS_HPP
  41545. #include <cstddef>
  41546. #include <iterator>
  41547. #include <tuple>
  41548. #include <type_traits>
  41549. #include <utility>
  41550. // #include "../config/config.h"
  41551. // #include "fwd.hpp"
  41552. namespace entt {
  41553. /**
  41554. * @brief Utility class to disambiguate overloaded functions.
  41555. * @tparam N Number of choices available.
  41556. */
  41557. template<std::size_t N>
  41558. struct choice_t
  41559. // unfortunately, doxygen cannot parse such a construct
  41560. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  41561. {};
  41562. /*! @copybrief choice_t */
  41563. template<>
  41564. struct choice_t<0> {};
  41565. /**
  41566. * @brief Variable template for the choice trick.
  41567. * @tparam N Number of choices available.
  41568. */
  41569. template<std::size_t N>
  41570. inline constexpr choice_t<N> choice{};
  41571. /**
  41572. * @brief Identity type trait.
  41573. *
  41574. * Useful to establish non-deduced contexts in template argument deduction
  41575. * (waiting for C++20) or to provide types through function arguments.
  41576. *
  41577. * @tparam Type A type.
  41578. */
  41579. template<typename Type>
  41580. struct type_identity {
  41581. /*! @brief Identity type. */
  41582. using type = Type;
  41583. };
  41584. /**
  41585. * @brief Helper type.
  41586. * @tparam Type A type.
  41587. */
  41588. template<typename Type>
  41589. using type_identity_t = typename type_identity<Type>::type;
  41590. /**
  41591. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  41592. * @tparam Type The type of which to return the size.
  41593. */
  41594. template<typename Type, typename = void>
  41595. struct size_of: std::integral_constant<std::size_t, 0u> {};
  41596. /*! @copydoc size_of */
  41597. template<typename Type>
  41598. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  41599. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  41600. : std::integral_constant<std::size_t, sizeof(Type)> {};
  41601. /**
  41602. * @brief Helper variable template.
  41603. * @tparam Type The type of which to return the size.
  41604. */
  41605. template<typename Type>
  41606. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  41607. /**
  41608. * @brief Using declaration to be used to _repeat_ the same type a number of
  41609. * times equal to the size of a given parameter pack.
  41610. * @tparam Type A type to repeat.
  41611. */
  41612. template<typename Type, typename>
  41613. using unpack_as_type = Type;
  41614. /**
  41615. * @brief Helper variable template to be used to _repeat_ the same value a
  41616. * number of times equal to the size of a given parameter pack.
  41617. * @tparam Value A value to repeat.
  41618. */
  41619. template<auto Value, typename>
  41620. inline constexpr auto unpack_as_value = Value;
  41621. /**
  41622. * @brief Wraps a static constant.
  41623. * @tparam Value A static constant.
  41624. */
  41625. template<auto Value>
  41626. using integral_constant = std::integral_constant<decltype(Value), Value>;
  41627. /**
  41628. * @brief Alias template to facilitate the creation of named values.
  41629. * @tparam Value A constant value at least convertible to `id_type`.
  41630. */
  41631. template<id_type Value>
  41632. using tag = integral_constant<Value>;
  41633. /**
  41634. * @brief A class to use to push around lists of types, nothing more.
  41635. * @tparam Type Types provided by the type list.
  41636. */
  41637. template<typename... Type>
  41638. struct type_list {
  41639. /*! @brief Type list type. */
  41640. using type = type_list;
  41641. /*! @brief Compile-time number of elements in the type list. */
  41642. static constexpr auto size = sizeof...(Type);
  41643. };
  41644. /*! @brief Primary template isn't defined on purpose. */
  41645. template<std::size_t, typename>
  41646. struct type_list_element;
  41647. /**
  41648. * @brief Provides compile-time indexed access to the types of a type list.
  41649. * @tparam Index Index of the type to return.
  41650. * @tparam First First type provided by the type list.
  41651. * @tparam Other Other types provided by the type list.
  41652. */
  41653. template<std::size_t Index, typename First, typename... Other>
  41654. struct type_list_element<Index, type_list<First, Other...>>
  41655. : type_list_element<Index - 1u, type_list<Other...>> {};
  41656. /**
  41657. * @brief Provides compile-time indexed access to the types of a type list.
  41658. * @tparam First First type provided by the type list.
  41659. * @tparam Other Other types provided by the type list.
  41660. */
  41661. template<typename First, typename... Other>
  41662. struct type_list_element<0u, type_list<First, Other...>> {
  41663. /*! @brief Searched type. */
  41664. using type = First;
  41665. };
  41666. /**
  41667. * @brief Helper type.
  41668. * @tparam Index Index of the type to return.
  41669. * @tparam List Type list to search into.
  41670. */
  41671. template<std::size_t Index, typename List>
  41672. using type_list_element_t = typename type_list_element<Index, List>::type;
  41673. /*! @brief Primary template isn't defined on purpose. */
  41674. template<typename, typename>
  41675. struct type_list_index;
  41676. /**
  41677. * @brief Provides compile-time type access to the types of a type list.
  41678. * @tparam Type Type to look for and for which to return the index.
  41679. * @tparam First First type provided by the type list.
  41680. * @tparam Other Other types provided by the type list.
  41681. */
  41682. template<typename Type, typename First, typename... Other>
  41683. struct type_list_index<Type, type_list<First, Other...>> {
  41684. /*! @brief Unsigned integer type. */
  41685. using value_type = std::size_t;
  41686. /*! @brief Compile-time position of the given type in the sublist. */
  41687. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  41688. };
  41689. /**
  41690. * @brief Provides compile-time type access to the types of a type list.
  41691. * @tparam Type Type to look for and for which to return the index.
  41692. * @tparam Other Other types provided by the type list.
  41693. */
  41694. template<typename Type, typename... Other>
  41695. struct type_list_index<Type, type_list<Type, Other...>> {
  41696. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  41697. /*! @brief Unsigned integer type. */
  41698. using value_type = std::size_t;
  41699. /*! @brief Compile-time position of the given type in the sublist. */
  41700. static constexpr value_type value = 0u;
  41701. };
  41702. /**
  41703. * @brief Provides compile-time type access to the types of a type list.
  41704. * @tparam Type Type to look for and for which to return the index.
  41705. */
  41706. template<typename Type>
  41707. struct type_list_index<Type, type_list<>> {
  41708. /*! @brief Unsigned integer type. */
  41709. using value_type = std::size_t;
  41710. /*! @brief Compile-time position of the given type in the sublist. */
  41711. static constexpr value_type value = 0u;
  41712. };
  41713. /**
  41714. * @brief Helper variable template.
  41715. * @tparam List Type list.
  41716. * @tparam Type Type to look for and for which to return the index.
  41717. */
  41718. template<typename Type, typename List>
  41719. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  41720. /**
  41721. * @brief Concatenates multiple type lists.
  41722. * @tparam Type Types provided by the first type list.
  41723. * @tparam Other Types provided by the second type list.
  41724. * @return A type list composed by the types of both the type lists.
  41725. */
  41726. template<typename... Type, typename... Other>
  41727. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  41728. return {};
  41729. }
  41730. /*! @brief Primary template isn't defined on purpose. */
  41731. template<typename...>
  41732. struct type_list_cat;
  41733. /*! @brief Concatenates multiple type lists. */
  41734. template<>
  41735. struct type_list_cat<> {
  41736. /*! @brief A type list composed by the types of all the type lists. */
  41737. using type = type_list<>;
  41738. };
  41739. /**
  41740. * @brief Concatenates multiple type lists.
  41741. * @tparam Type Types provided by the first type list.
  41742. * @tparam Other Types provided by the second type list.
  41743. * @tparam List Other type lists, if any.
  41744. */
  41745. template<typename... Type, typename... Other, typename... List>
  41746. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  41747. /*! @brief A type list composed by the types of all the type lists. */
  41748. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  41749. };
  41750. /**
  41751. * @brief Concatenates multiple type lists.
  41752. * @tparam Type Types provided by the type list.
  41753. */
  41754. template<typename... Type>
  41755. struct type_list_cat<type_list<Type...>> {
  41756. /*! @brief A type list composed by the types of all the type lists. */
  41757. using type = type_list<Type...>;
  41758. };
  41759. /**
  41760. * @brief Helper type.
  41761. * @tparam List Type lists to concatenate.
  41762. */
  41763. template<typename... List>
  41764. using type_list_cat_t = typename type_list_cat<List...>::type;
  41765. /*! @cond TURN_OFF_DOXYGEN */
  41766. namespace internal {
  41767. template<typename...>
  41768. struct type_list_unique;
  41769. template<typename First, typename... Other, typename... Type>
  41770. struct type_list_unique<type_list<First, Other...>, Type...>
  41771. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  41772. template<typename... Type>
  41773. struct type_list_unique<type_list<>, Type...> {
  41774. using type = type_list<Type...>;
  41775. };
  41776. } // namespace internal
  41777. /*! @endcond */
  41778. /**
  41779. * @brief Removes duplicates types from a type list.
  41780. * @tparam List Type list.
  41781. */
  41782. template<typename List>
  41783. struct type_list_unique {
  41784. /*! @brief A type list without duplicate types. */
  41785. using type = typename internal::type_list_unique<List>::type;
  41786. };
  41787. /**
  41788. * @brief Helper type.
  41789. * @tparam List Type list.
  41790. */
  41791. template<typename List>
  41792. using type_list_unique_t = typename type_list_unique<List>::type;
  41793. /**
  41794. * @brief Provides the member constant `value` to true if a type list contains a
  41795. * given type, false otherwise.
  41796. * @tparam List Type list.
  41797. * @tparam Type Type to look for.
  41798. */
  41799. template<typename List, typename Type>
  41800. struct type_list_contains;
  41801. /**
  41802. * @copybrief type_list_contains
  41803. * @tparam Type Types provided by the type list.
  41804. * @tparam Other Type to look for.
  41805. */
  41806. template<typename... Type, typename Other>
  41807. struct type_list_contains<type_list<Type...>, Other>
  41808. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  41809. /**
  41810. * @brief Helper variable template.
  41811. * @tparam List Type list.
  41812. * @tparam Type Type to look for.
  41813. */
  41814. template<typename List, typename Type>
  41815. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  41816. /*! @brief Primary template isn't defined on purpose. */
  41817. template<typename...>
  41818. struct type_list_diff;
  41819. /**
  41820. * @brief Computes the difference between two type lists.
  41821. * @tparam Type Types provided by the first type list.
  41822. * @tparam Other Types provided by the second type list.
  41823. */
  41824. template<typename... Type, typename... Other>
  41825. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  41826. /*! @brief A type list that is the difference between the two type lists. */
  41827. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  41828. };
  41829. /**
  41830. * @brief Helper type.
  41831. * @tparam List Type lists between which to compute the difference.
  41832. */
  41833. template<typename... List>
  41834. using type_list_diff_t = typename type_list_diff<List...>::type;
  41835. /*! @brief Primary template isn't defined on purpose. */
  41836. template<typename, template<typename...> class>
  41837. struct type_list_transform;
  41838. /**
  41839. * @brief Applies a given _function_ to a type list and generate a new list.
  41840. * @tparam Type Types provided by the type list.
  41841. * @tparam Op Unary operation as template class with a type member named `type`.
  41842. */
  41843. template<typename... Type, template<typename...> class Op>
  41844. struct type_list_transform<type_list<Type...>, Op> {
  41845. /*! @brief Resulting type list after applying the transform function. */
  41846. // NOLINTNEXTLINE(modernize-type-traits)
  41847. using type = type_list<typename Op<Type>::type...>;
  41848. };
  41849. /**
  41850. * @brief Helper type.
  41851. * @tparam List Type list.
  41852. * @tparam Op Unary operation as template class with a type member named `type`.
  41853. */
  41854. template<typename List, template<typename...> class Op>
  41855. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  41856. /**
  41857. * @brief A class to use to push around lists of constant values, nothing more.
  41858. * @tparam Value Values provided by the value list.
  41859. */
  41860. template<auto... Value>
  41861. struct value_list {
  41862. /*! @brief Value list type. */
  41863. using type = value_list;
  41864. /*! @brief Compile-time number of elements in the value list. */
  41865. static constexpr auto size = sizeof...(Value);
  41866. };
  41867. /*! @brief Primary template isn't defined on purpose. */
  41868. template<std::size_t, typename>
  41869. struct value_list_element;
  41870. /**
  41871. * @brief Provides compile-time indexed access to the values of a value list.
  41872. * @tparam Index Index of the value to return.
  41873. * @tparam Value First value provided by the value list.
  41874. * @tparam Other Other values provided by the value list.
  41875. */
  41876. template<std::size_t Index, auto Value, auto... Other>
  41877. struct value_list_element<Index, value_list<Value, Other...>>
  41878. : value_list_element<Index - 1u, value_list<Other...>> {};
  41879. /**
  41880. * @brief Provides compile-time indexed access to the types of a type list.
  41881. * @tparam Value First value provided by the value list.
  41882. * @tparam Other Other values provided by the value list.
  41883. */
  41884. template<auto Value, auto... Other>
  41885. struct value_list_element<0u, value_list<Value, Other...>> {
  41886. /*! @brief Searched type. */
  41887. using type = decltype(Value);
  41888. /*! @brief Searched value. */
  41889. static constexpr auto value = Value;
  41890. };
  41891. /**
  41892. * @brief Helper type.
  41893. * @tparam Index Index of the type to return.
  41894. * @tparam List Value list to search into.
  41895. */
  41896. template<std::size_t Index, typename List>
  41897. using value_list_element_t = typename value_list_element<Index, List>::type;
  41898. /**
  41899. * @brief Helper type.
  41900. * @tparam Index Index of the value to return.
  41901. * @tparam List Value list to search into.
  41902. */
  41903. template<std::size_t Index, typename List>
  41904. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  41905. /*! @brief Primary template isn't defined on purpose. */
  41906. template<auto, typename>
  41907. struct value_list_index;
  41908. /**
  41909. * @brief Provides compile-time type access to the values of a value list.
  41910. * @tparam Value Value to look for and for which to return the index.
  41911. * @tparam First First value provided by the value list.
  41912. * @tparam Other Other values provided by the value list.
  41913. */
  41914. template<auto Value, auto First, auto... Other>
  41915. struct value_list_index<Value, value_list<First, Other...>> {
  41916. /*! @brief Unsigned integer type. */
  41917. using value_type = std::size_t;
  41918. /*! @brief Compile-time position of the given value in the sublist. */
  41919. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  41920. };
  41921. /**
  41922. * @brief Provides compile-time type access to the values of a value list.
  41923. * @tparam Value Value to look for and for which to return the index.
  41924. * @tparam Other Other values provided by the value list.
  41925. */
  41926. template<auto Value, auto... Other>
  41927. struct value_list_index<Value, value_list<Value, Other...>> {
  41928. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  41929. /*! @brief Unsigned integer type. */
  41930. using value_type = std::size_t;
  41931. /*! @brief Compile-time position of the given value in the sublist. */
  41932. static constexpr value_type value = 0u;
  41933. };
  41934. /**
  41935. * @brief Provides compile-time type access to the values of a value list.
  41936. * @tparam Value Value to look for and for which to return the index.
  41937. */
  41938. template<auto Value>
  41939. struct value_list_index<Value, value_list<>> {
  41940. /*! @brief Unsigned integer type. */
  41941. using value_type = std::size_t;
  41942. /*! @brief Compile-time position of the given type in the sublist. */
  41943. static constexpr value_type value = 0u;
  41944. };
  41945. /**
  41946. * @brief Helper variable template.
  41947. * @tparam List Value list.
  41948. * @tparam Value Value to look for and for which to return the index.
  41949. */
  41950. template<auto Value, typename List>
  41951. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  41952. /**
  41953. * @brief Concatenates multiple value lists.
  41954. * @tparam Value Values provided by the first value list.
  41955. * @tparam Other Values provided by the second value list.
  41956. * @return A value list composed by the values of both the value lists.
  41957. */
  41958. template<auto... Value, auto... Other>
  41959. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  41960. return {};
  41961. }
  41962. /*! @brief Primary template isn't defined on purpose. */
  41963. template<typename...>
  41964. struct value_list_cat;
  41965. /*! @brief Concatenates multiple value lists. */
  41966. template<>
  41967. struct value_list_cat<> {
  41968. /*! @brief A value list composed by the values of all the value lists. */
  41969. using type = value_list<>;
  41970. };
  41971. /**
  41972. * @brief Concatenates multiple value lists.
  41973. * @tparam Value Values provided by the first value list.
  41974. * @tparam Other Values provided by the second value list.
  41975. * @tparam List Other value lists, if any.
  41976. */
  41977. template<auto... Value, auto... Other, typename... List>
  41978. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  41979. /*! @brief A value list composed by the values of all the value lists. */
  41980. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  41981. };
  41982. /**
  41983. * @brief Concatenates multiple value lists.
  41984. * @tparam Value Values provided by the value list.
  41985. */
  41986. template<auto... Value>
  41987. struct value_list_cat<value_list<Value...>> {
  41988. /*! @brief A value list composed by the values of all the value lists. */
  41989. using type = value_list<Value...>;
  41990. };
  41991. /**
  41992. * @brief Helper type.
  41993. * @tparam List Value lists to concatenate.
  41994. */
  41995. template<typename... List>
  41996. using value_list_cat_t = typename value_list_cat<List...>::type;
  41997. /*! @brief Primary template isn't defined on purpose. */
  41998. template<typename>
  41999. struct value_list_unique;
  42000. /**
  42001. * @brief Removes duplicates values from a value list.
  42002. * @tparam Value One of the values provided by the given value list.
  42003. * @tparam Other The other values provided by the given value list.
  42004. */
  42005. template<auto Value, auto... Other>
  42006. struct value_list_unique<value_list<Value, Other...>> {
  42007. /*! @brief A value list without duplicate types. */
  42008. using type = std::conditional_t<
  42009. ((Value == Other) || ...),
  42010. typename value_list_unique<value_list<Other...>>::type,
  42011. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  42012. };
  42013. /*! @brief Removes duplicates values from a value list. */
  42014. template<>
  42015. struct value_list_unique<value_list<>> {
  42016. /*! @brief A value list without duplicate types. */
  42017. using type = value_list<>;
  42018. };
  42019. /**
  42020. * @brief Helper type.
  42021. * @tparam Type A value list.
  42022. */
  42023. template<typename Type>
  42024. using value_list_unique_t = typename value_list_unique<Type>::type;
  42025. /**
  42026. * @brief Provides the member constant `value` to true if a value list contains
  42027. * a given value, false otherwise.
  42028. * @tparam List Value list.
  42029. * @tparam Value Value to look for.
  42030. */
  42031. template<typename List, auto Value>
  42032. struct value_list_contains;
  42033. /**
  42034. * @copybrief value_list_contains
  42035. * @tparam Value Values provided by the value list.
  42036. * @tparam Other Value to look for.
  42037. */
  42038. template<auto... Value, auto Other>
  42039. struct value_list_contains<value_list<Value...>, Other>
  42040. : std::bool_constant<((Value == Other) || ...)> {};
  42041. /**
  42042. * @brief Helper variable template.
  42043. * @tparam List Value list.
  42044. * @tparam Value Value to look for.
  42045. */
  42046. template<typename List, auto Value>
  42047. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  42048. /*! @brief Primary template isn't defined on purpose. */
  42049. template<typename...>
  42050. struct value_list_diff;
  42051. /**
  42052. * @brief Computes the difference between two value lists.
  42053. * @tparam Value Values provided by the first value list.
  42054. * @tparam Other Values provided by the second value list.
  42055. */
  42056. template<auto... Value, auto... Other>
  42057. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  42058. /*! @brief A value list that is the difference between the two value lists. */
  42059. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  42060. };
  42061. /**
  42062. * @brief Helper type.
  42063. * @tparam List Value lists between which to compute the difference.
  42064. */
  42065. template<typename... List>
  42066. using value_list_diff_t = typename value_list_diff<List...>::type;
  42067. /*! @brief Same as std::is_invocable, but with tuples. */
  42068. template<typename, typename>
  42069. struct is_applicable: std::false_type {};
  42070. /**
  42071. * @copybrief is_applicable
  42072. * @tparam Func A valid function type.
  42073. * @tparam Tuple Tuple-like type.
  42074. * @tparam Args The list of arguments to use to probe the function type.
  42075. */
  42076. template<typename Func, template<typename...> class Tuple, typename... Args>
  42077. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  42078. /**
  42079. * @copybrief is_applicable
  42080. * @tparam Func A valid function type.
  42081. * @tparam Tuple Tuple-like type.
  42082. * @tparam Args The list of arguments to use to probe the function type.
  42083. */
  42084. template<typename Func, template<typename...> class Tuple, typename... Args>
  42085. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  42086. /**
  42087. * @brief Helper variable template.
  42088. * @tparam Func A valid function type.
  42089. * @tparam Args The list of arguments to use to probe the function type.
  42090. */
  42091. template<typename Func, typename Args>
  42092. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  42093. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  42094. template<typename, typename, typename>
  42095. struct is_applicable_r: std::false_type {};
  42096. /**
  42097. * @copybrief is_applicable_r
  42098. * @tparam Ret The type to which the return type of the function should be
  42099. * convertible.
  42100. * @tparam Func A valid function type.
  42101. * @tparam Args The list of arguments to use to probe the function type.
  42102. */
  42103. template<typename Ret, typename Func, typename... Args>
  42104. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  42105. /**
  42106. * @brief Helper variable template.
  42107. * @tparam Ret The type to which the return type of the function should be
  42108. * convertible.
  42109. * @tparam Func A valid function type.
  42110. * @tparam Args The list of arguments to use to probe the function type.
  42111. */
  42112. template<typename Ret, typename Func, typename Args>
  42113. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  42114. /**
  42115. * @brief Provides the member constant `value` to true if a given type is
  42116. * complete, false otherwise.
  42117. * @tparam Type The type to test.
  42118. */
  42119. template<typename Type, typename = void>
  42120. struct is_complete: std::false_type {};
  42121. /*! @copydoc is_complete */
  42122. template<typename Type>
  42123. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  42124. /**
  42125. * @brief Helper variable template.
  42126. * @tparam Type The type to test.
  42127. */
  42128. template<typename Type>
  42129. inline constexpr bool is_complete_v = is_complete<Type>::value;
  42130. /**
  42131. * @brief Provides the member constant `value` to true if a given type is an
  42132. * iterator, false otherwise.
  42133. * @tparam Type The type to test.
  42134. */
  42135. template<typename Type, typename = void>
  42136. struct is_iterator: std::false_type {};
  42137. /*! @cond TURN_OFF_DOXYGEN */
  42138. namespace internal {
  42139. template<typename, typename = void>
  42140. struct has_iterator_category: std::false_type {};
  42141. template<typename Type>
  42142. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  42143. } // namespace internal
  42144. /*! @endcond */
  42145. /*! @copydoc is_iterator */
  42146. template<typename Type>
  42147. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  42148. : internal::has_iterator_category<Type> {};
  42149. /**
  42150. * @brief Helper variable template.
  42151. * @tparam Type The type to test.
  42152. */
  42153. template<typename Type>
  42154. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  42155. /**
  42156. * @brief Provides the member constant `value` to true if a given type is both
  42157. * an empty and non-final class, false otherwise.
  42158. * @tparam Type The type to test
  42159. */
  42160. template<typename Type>
  42161. struct is_ebco_eligible
  42162. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  42163. /**
  42164. * @brief Helper variable template.
  42165. * @tparam Type The type to test.
  42166. */
  42167. template<typename Type>
  42168. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  42169. /**
  42170. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  42171. * is valid and denotes a type, false otherwise.
  42172. * @tparam Type The type to test.
  42173. */
  42174. template<typename Type, typename = void>
  42175. struct is_transparent: std::false_type {};
  42176. /*! @copydoc is_transparent */
  42177. template<typename Type>
  42178. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  42179. /**
  42180. * @brief Helper variable template.
  42181. * @tparam Type The type to test.
  42182. */
  42183. template<typename Type>
  42184. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  42185. /*! @cond TURN_OFF_DOXYGEN */
  42186. namespace internal {
  42187. template<typename, typename = void>
  42188. struct has_tuple_size_value: std::false_type {};
  42189. template<typename Type>
  42190. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  42191. template<typename, typename = void>
  42192. struct has_value_type: std::false_type {};
  42193. template<typename Type>
  42194. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  42195. template<typename>
  42196. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  42197. template<typename Type, std::size_t... Index>
  42198. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  42199. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  42200. }
  42201. template<typename>
  42202. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  42203. return false;
  42204. }
  42205. template<typename Type>
  42206. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  42207. return true;
  42208. }
  42209. template<typename Type>
  42210. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  42211. // NOLINTBEGIN(modernize-use-transparent-functors)
  42212. if constexpr(std::is_array_v<Type>) {
  42213. return false;
  42214. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  42215. if constexpr(has_tuple_size_value<Type>::value) {
  42216. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  42217. } else {
  42218. return maybe_equality_comparable<Type>(0);
  42219. }
  42220. } else if constexpr(has_value_type<Type>::value) {
  42221. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  42222. return maybe_equality_comparable<Type>(0);
  42223. } else {
  42224. return false;
  42225. }
  42226. } else {
  42227. return maybe_equality_comparable<Type>(0);
  42228. }
  42229. // NOLINTEND(modernize-use-transparent-functors)
  42230. }
  42231. } // namespace internal
  42232. /*! @endcond */
  42233. /**
  42234. * @brief Provides the member constant `value` to true if a given type is
  42235. * equality comparable, false otherwise.
  42236. * @tparam Type The type to test.
  42237. */
  42238. template<typename Type>
  42239. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  42240. /*! @copydoc is_equality_comparable */
  42241. template<typename Type>
  42242. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  42243. /**
  42244. * @brief Helper variable template.
  42245. * @tparam Type The type to test.
  42246. */
  42247. template<typename Type>
  42248. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  42249. /**
  42250. * @brief Transcribes the constness of a type to another type.
  42251. * @tparam To The type to which to transcribe the constness.
  42252. * @tparam From The type from which to transcribe the constness.
  42253. */
  42254. template<typename To, typename From>
  42255. struct constness_as {
  42256. /*! @brief The type resulting from the transcription of the constness. */
  42257. using type = std::remove_const_t<To>;
  42258. };
  42259. /*! @copydoc constness_as */
  42260. template<typename To, typename From>
  42261. struct constness_as<To, const From> {
  42262. /*! @brief The type resulting from the transcription of the constness. */
  42263. using type = const To;
  42264. };
  42265. /**
  42266. * @brief Alias template to facilitate the transcription of the constness.
  42267. * @tparam To The type to which to transcribe the constness.
  42268. * @tparam From The type from which to transcribe the constness.
  42269. */
  42270. template<typename To, typename From>
  42271. using constness_as_t = typename constness_as<To, From>::type;
  42272. /**
  42273. * @brief Extracts the class of a non-static member object or function.
  42274. * @tparam Member A pointer to a non-static member object or function.
  42275. */
  42276. template<typename Member>
  42277. class member_class {
  42278. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  42279. template<typename Class, typename Ret, typename... Args>
  42280. static Class *clazz(Ret (Class::*)(Args...));
  42281. template<typename Class, typename Ret, typename... Args>
  42282. static Class *clazz(Ret (Class::*)(Args...) const);
  42283. template<typename Class, typename Type>
  42284. static Class *clazz(Type Class::*);
  42285. public:
  42286. /*! @brief The class of the given non-static member object or function. */
  42287. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  42288. };
  42289. /**
  42290. * @brief Helper type.
  42291. * @tparam Member A pointer to a non-static member object or function.
  42292. */
  42293. template<typename Member>
  42294. using member_class_t = typename member_class<Member>::type;
  42295. /**
  42296. * @brief Extracts the n-th argument of a _callable_ type.
  42297. * @tparam Index The index of the argument to extract.
  42298. * @tparam Candidate A valid _callable_ type.
  42299. */
  42300. template<std::size_t Index, typename Candidate>
  42301. class nth_argument {
  42302. template<typename Ret, typename... Args>
  42303. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  42304. template<typename Ret, typename Class, typename... Args>
  42305. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  42306. template<typename Ret, typename Class, typename... Args>
  42307. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  42308. template<typename Type, typename Class>
  42309. static constexpr type_list<Type> pick_up(Type Class ::*);
  42310. template<typename Type>
  42311. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  42312. public:
  42313. /*! @brief N-th argument of the _callable_ type. */
  42314. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  42315. };
  42316. /**
  42317. * @brief Helper type.
  42318. * @tparam Index The index of the argument to extract.
  42319. * @tparam Candidate A valid function, member function or data member type.
  42320. */
  42321. template<std::size_t Index, typename Candidate>
  42322. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  42323. } // namespace entt
  42324. template<typename... Type>
  42325. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  42326. template<std::size_t Index, typename... Type>
  42327. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  42328. template<auto... Value>
  42329. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  42330. template<std::size_t Index, auto... Value>
  42331. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  42332. #endif
  42333. // #include "fwd.hpp"
  42334. #ifndef ENTT_CONTAINER_FWD_HPP
  42335. #define ENTT_CONTAINER_FWD_HPP
  42336. #include <functional>
  42337. #include <memory>
  42338. #include <utility>
  42339. #include <vector>
  42340. namespace entt {
  42341. template<
  42342. typename Key,
  42343. typename Type,
  42344. typename = std::hash<Key>,
  42345. typename = std::equal_to<>,
  42346. typename = std::allocator<std::pair<const Key, Type>>>
  42347. class dense_map;
  42348. template<
  42349. typename Type,
  42350. typename = std::hash<Type>,
  42351. typename = std::equal_to<>,
  42352. typename = std::allocator<Type>>
  42353. class dense_set;
  42354. template<typename...>
  42355. class basic_table;
  42356. /**
  42357. * @brief Alias declaration for the most common use case.
  42358. * @tparam Type Element types.
  42359. */
  42360. template<typename... Type>
  42361. using table = basic_table<std::vector<Type>...>;
  42362. } // namespace entt
  42363. #endif
  42364. namespace entt {
  42365. /*! @cond TURN_OFF_DOXYGEN */
  42366. namespace internal {
  42367. static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  42368. template<typename Key, typename Type>
  42369. struct dense_map_node final {
  42370. using value_type = std::pair<Key, Type>;
  42371. template<typename... Args>
  42372. dense_map_node(const std::size_t pos, Args &&...args)
  42373. : next{pos},
  42374. element{std::forward<Args>(args)...} {}
  42375. template<typename Allocator, typename... Args>
  42376. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  42377. : next{pos},
  42378. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  42379. template<typename Allocator>
  42380. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  42381. : next{other.next},
  42382. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  42383. template<typename Allocator>
  42384. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  42385. : next{other.next},
  42386. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  42387. std::size_t next;
  42388. value_type element;
  42389. };
  42390. template<typename It>
  42391. class dense_map_iterator final {
  42392. template<typename>
  42393. friend class dense_map_iterator;
  42394. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  42395. using second_type = decltype((std::declval<It>()->element.second));
  42396. public:
  42397. using value_type = std::pair<first_type, second_type>;
  42398. using pointer = input_iterator_pointer<value_type>;
  42399. using reference = value_type;
  42400. using difference_type = std::ptrdiff_t;
  42401. using iterator_category = std::input_iterator_tag;
  42402. using iterator_concept = std::random_access_iterator_tag;
  42403. constexpr dense_map_iterator() noexcept
  42404. : it{} {}
  42405. constexpr dense_map_iterator(const It iter) noexcept
  42406. : it{iter} {}
  42407. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  42408. constexpr dense_map_iterator(const dense_map_iterator<Other> &other) noexcept
  42409. : it{other.it} {}
  42410. constexpr dense_map_iterator &operator++() noexcept {
  42411. return ++it, *this;
  42412. }
  42413. constexpr dense_map_iterator operator++(int) noexcept {
  42414. const dense_map_iterator orig = *this;
  42415. return ++(*this), orig;
  42416. }
  42417. constexpr dense_map_iterator &operator--() noexcept {
  42418. return --it, *this;
  42419. }
  42420. constexpr dense_map_iterator operator--(int) noexcept {
  42421. const dense_map_iterator orig = *this;
  42422. return operator--(), orig;
  42423. }
  42424. constexpr dense_map_iterator &operator+=(const difference_type value) noexcept {
  42425. it += value;
  42426. return *this;
  42427. }
  42428. constexpr dense_map_iterator operator+(const difference_type value) const noexcept {
  42429. dense_map_iterator copy = *this;
  42430. return (copy += value);
  42431. }
  42432. constexpr dense_map_iterator &operator-=(const difference_type value) noexcept {
  42433. return (*this += -value);
  42434. }
  42435. constexpr dense_map_iterator operator-(const difference_type value) const noexcept {
  42436. return (*this + -value);
  42437. }
  42438. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  42439. return {it[value].element.first, it[value].element.second};
  42440. }
  42441. [[nodiscard]] constexpr pointer operator->() const noexcept {
  42442. return operator*();
  42443. }
  42444. [[nodiscard]] constexpr reference operator*() const noexcept {
  42445. return operator[](0);
  42446. }
  42447. template<typename Lhs, typename Rhs>
  42448. friend constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  42449. template<typename Lhs, typename Rhs>
  42450. friend constexpr bool operator==(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  42451. template<typename Lhs, typename Rhs>
  42452. friend constexpr bool operator<(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  42453. private:
  42454. It it;
  42455. };
  42456. template<typename Lhs, typename Rhs>
  42457. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  42458. return lhs.it - rhs.it;
  42459. }
  42460. template<typename Lhs, typename Rhs>
  42461. [[nodiscard]] constexpr bool operator==(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  42462. return lhs.it == rhs.it;
  42463. }
  42464. template<typename Lhs, typename Rhs>
  42465. [[nodiscard]] constexpr bool operator!=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  42466. return !(lhs == rhs);
  42467. }
  42468. template<typename Lhs, typename Rhs>
  42469. [[nodiscard]] constexpr bool operator<(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  42470. return lhs.it < rhs.it;
  42471. }
  42472. template<typename Lhs, typename Rhs>
  42473. [[nodiscard]] constexpr bool operator>(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  42474. return rhs < lhs;
  42475. }
  42476. template<typename Lhs, typename Rhs>
  42477. [[nodiscard]] constexpr bool operator<=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  42478. return !(lhs > rhs);
  42479. }
  42480. template<typename Lhs, typename Rhs>
  42481. [[nodiscard]] constexpr bool operator>=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  42482. return !(lhs < rhs);
  42483. }
  42484. template<typename It>
  42485. class dense_map_local_iterator final {
  42486. template<typename>
  42487. friend class dense_map_local_iterator;
  42488. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  42489. using second_type = decltype((std::declval<It>()->element.second));
  42490. public:
  42491. using value_type = std::pair<first_type, second_type>;
  42492. using pointer = input_iterator_pointer<value_type>;
  42493. using reference = value_type;
  42494. using difference_type = std::ptrdiff_t;
  42495. using iterator_category = std::input_iterator_tag;
  42496. using iterator_concept = std::forward_iterator_tag;
  42497. constexpr dense_map_local_iterator() noexcept = default;
  42498. constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept
  42499. : it{iter},
  42500. offset{pos} {}
  42501. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  42502. constexpr dense_map_local_iterator(const dense_map_local_iterator<Other> &other) noexcept
  42503. : it{other.it},
  42504. offset{other.offset} {}
  42505. constexpr dense_map_local_iterator &operator++() noexcept {
  42506. return (offset = it[static_cast<typename It::difference_type>(offset)].next), *this;
  42507. }
  42508. constexpr dense_map_local_iterator operator++(int) noexcept {
  42509. const dense_map_local_iterator orig = *this;
  42510. return ++(*this), orig;
  42511. }
  42512. [[nodiscard]] constexpr pointer operator->() const noexcept {
  42513. return operator*();
  42514. }
  42515. [[nodiscard]] constexpr reference operator*() const noexcept {
  42516. const auto idx = static_cast<typename It::difference_type>(offset);
  42517. return {it[idx].element.first, it[idx].element.second};
  42518. }
  42519. [[nodiscard]] constexpr std::size_t index() const noexcept {
  42520. return offset;
  42521. }
  42522. private:
  42523. It it{};
  42524. std::size_t offset{dense_map_placeholder_position};
  42525. };
  42526. template<typename Lhs, typename Rhs>
  42527. [[nodiscard]] constexpr bool operator==(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  42528. return lhs.index() == rhs.index();
  42529. }
  42530. template<typename Lhs, typename Rhs>
  42531. [[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  42532. return !(lhs == rhs);
  42533. }
  42534. } // namespace internal
  42535. /*! @endcond */
  42536. /**
  42537. * @brief Associative container for key-value pairs with unique keys.
  42538. *
  42539. * Internally, elements are organized into buckets. Which bucket an element is
  42540. * placed into depends entirely on the hash of its key. Keys with the same hash
  42541. * code appear in the same bucket.
  42542. *
  42543. * @tparam Key Key type of the associative container.
  42544. * @tparam Type Mapped type of the associative container.
  42545. * @tparam Hash Type of function to use to hash the keys.
  42546. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  42547. * @tparam Allocator Type of allocator used to manage memory and elements.
  42548. */
  42549. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  42550. class dense_map {
  42551. static constexpr float default_threshold = 0.875f;
  42552. static constexpr std::size_t minimum_capacity = 8u;
  42553. static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position;
  42554. using node_type = internal::dense_map_node<Key, Type>;
  42555. using alloc_traits = std::allocator_traits<Allocator>;
  42556. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  42557. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  42558. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  42559. template<typename Other>
  42560. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept {
  42561. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  42562. return fast_mod(static_cast<size_type>(sparse.second()(key)), bucket_count());
  42563. }
  42564. template<typename Other>
  42565. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) {
  42566. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  42567. if(packed.second()(packed.first()[offset].element.first, key)) {
  42568. return begin() + static_cast<typename iterator::difference_type>(offset);
  42569. }
  42570. }
  42571. return end();
  42572. }
  42573. template<typename Other>
  42574. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const {
  42575. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  42576. if(packed.second()(packed.first()[offset].element.first, key)) {
  42577. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  42578. }
  42579. }
  42580. return cend();
  42581. }
  42582. template<typename Other, typename... Args>
  42583. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  42584. const auto index = key_to_bucket(key);
  42585. if(auto it = constrained_find(key, index); it != end()) {
  42586. return std::make_pair(it, false);
  42587. }
  42588. packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward<Other>(key)), std::forward_as_tuple(std::forward<Args>(args)...));
  42589. sparse.first()[index] = packed.first().size() - 1u;
  42590. rehash_if_required();
  42591. return std::make_pair(--end(), true);
  42592. }
  42593. template<typename Other, typename Arg>
  42594. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  42595. const auto index = key_to_bucket(key);
  42596. if(auto it = constrained_find(key, index); it != end()) {
  42597. it->second = std::forward<Arg>(value);
  42598. return std::make_pair(it, false);
  42599. }
  42600. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  42601. sparse.first()[index] = packed.first().size() - 1u;
  42602. rehash_if_required();
  42603. return std::make_pair(--end(), true);
  42604. }
  42605. void move_and_pop(const std::size_t pos) {
  42606. if(const auto last = size() - 1u; pos != last) {
  42607. size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)];
  42608. packed.first()[pos] = std::move(packed.first().back());
  42609. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  42610. *curr = pos;
  42611. }
  42612. packed.first().pop_back();
  42613. }
  42614. void rehash_if_required() {
  42615. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  42616. rehash(bc * 2u);
  42617. }
  42618. }
  42619. public:
  42620. /*! @brief Allocator type. */
  42621. using allocator_type = Allocator;
  42622. /*! @brief Key type of the container. */
  42623. using key_type = Key;
  42624. /*! @brief Mapped type of the container. */
  42625. using mapped_type = Type;
  42626. /*! @brief Key-value type of the container. */
  42627. using value_type = std::pair<const Key, Type>;
  42628. /*! @brief Unsigned integer type. */
  42629. using size_type = std::size_t;
  42630. /*! @brief Signed integer type. */
  42631. using difference_type = std::ptrdiff_t;
  42632. /*! @brief Type of function to use to hash the keys. */
  42633. using hasher = Hash;
  42634. /*! @brief Type of function to use to compare the keys for equality. */
  42635. using key_equal = KeyEqual;
  42636. /*! @brief Input iterator type. */
  42637. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  42638. /*! @brief Constant input iterator type. */
  42639. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  42640. /*! @brief Input iterator type. */
  42641. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  42642. /*! @brief Constant input iterator type. */
  42643. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  42644. /*! @brief Default constructor. */
  42645. dense_map()
  42646. : dense_map{minimum_capacity} {}
  42647. /**
  42648. * @brief Constructs an empty container with a given allocator.
  42649. * @param allocator The allocator to use.
  42650. */
  42651. explicit dense_map(const allocator_type &allocator)
  42652. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  42653. /**
  42654. * @brief Constructs an empty container with a given allocator and user
  42655. * supplied minimal number of buckets.
  42656. * @param cnt Minimal number of buckets.
  42657. * @param allocator The allocator to use.
  42658. */
  42659. dense_map(const size_type cnt, const allocator_type &allocator)
  42660. : dense_map{cnt, hasher{}, key_equal{}, allocator} {}
  42661. /**
  42662. * @brief Constructs an empty container with a given allocator, hash
  42663. * function and user supplied minimal number of buckets.
  42664. * @param cnt Minimal number of buckets.
  42665. * @param hash Hash function to use.
  42666. * @param allocator The allocator to use.
  42667. */
  42668. dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  42669. : dense_map{cnt, hash, key_equal{}, allocator} {}
  42670. /**
  42671. * @brief Constructs an empty container with a given allocator, hash
  42672. * function, compare function and user supplied minimal number of buckets.
  42673. * @param cnt Minimal number of buckets.
  42674. * @param hash Hash function to use.
  42675. * @param equal Compare function to use.
  42676. * @param allocator The allocator to use.
  42677. */
  42678. explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  42679. : sparse{allocator, hash},
  42680. packed{allocator, equal} {
  42681. rehash(cnt);
  42682. }
  42683. /*! @brief Default copy constructor. */
  42684. dense_map(const dense_map &) = default;
  42685. /**
  42686. * @brief Allocator-extended copy constructor.
  42687. * @param other The instance to copy from.
  42688. * @param allocator The allocator to use.
  42689. */
  42690. dense_map(const dense_map &other, const allocator_type &allocator)
  42691. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  42692. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  42693. threshold{other.threshold} {}
  42694. /*! @brief Default move constructor. */
  42695. dense_map(dense_map &&) noexcept = default;
  42696. /**
  42697. * @brief Allocator-extended move constructor.
  42698. * @param other The instance to move from.
  42699. * @param allocator The allocator to use.
  42700. */
  42701. dense_map(dense_map &&other, const allocator_type &allocator)
  42702. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  42703. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  42704. threshold{other.threshold} {}
  42705. /*! @brief Default destructor. */
  42706. ~dense_map() = default;
  42707. /**
  42708. * @brief Default copy assignment operator.
  42709. * @return This container.
  42710. */
  42711. dense_map &operator=(const dense_map &) = default;
  42712. /**
  42713. * @brief Default move assignment operator.
  42714. * @return This container.
  42715. */
  42716. dense_map &operator=(dense_map &&) noexcept = default;
  42717. /**
  42718. * @brief Exchanges the contents with those of a given container.
  42719. * @param other Container to exchange the content with.
  42720. */
  42721. void swap(dense_map &other) noexcept {
  42722. using std::swap;
  42723. swap(sparse, other.sparse);
  42724. swap(packed, other.packed);
  42725. swap(threshold, other.threshold);
  42726. }
  42727. /**
  42728. * @brief Returns the associated allocator.
  42729. * @return The associated allocator.
  42730. */
  42731. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  42732. return sparse.first().get_allocator();
  42733. }
  42734. /**
  42735. * @brief Returns an iterator to the beginning.
  42736. *
  42737. * If the array is empty, the returned iterator will be equal to `end()`.
  42738. *
  42739. * @return An iterator to the first instance of the internal array.
  42740. */
  42741. [[nodiscard]] const_iterator cbegin() const noexcept {
  42742. return packed.first().begin();
  42743. }
  42744. /*! @copydoc cbegin */
  42745. [[nodiscard]] const_iterator begin() const noexcept {
  42746. return cbegin();
  42747. }
  42748. /*! @copydoc begin */
  42749. [[nodiscard]] iterator begin() noexcept {
  42750. return packed.first().begin();
  42751. }
  42752. /**
  42753. * @brief Returns an iterator to the end.
  42754. * @return An iterator to the element following the last instance of the
  42755. * internal array.
  42756. */
  42757. [[nodiscard]] const_iterator cend() const noexcept {
  42758. return packed.first().end();
  42759. }
  42760. /*! @copydoc cend */
  42761. [[nodiscard]] const_iterator end() const noexcept {
  42762. return cend();
  42763. }
  42764. /*! @copydoc end */
  42765. [[nodiscard]] iterator end() noexcept {
  42766. return packed.first().end();
  42767. }
  42768. /**
  42769. * @brief Checks whether a container is empty.
  42770. * @return True if the container is empty, false otherwise.
  42771. */
  42772. [[nodiscard]] bool empty() const noexcept {
  42773. return packed.first().empty();
  42774. }
  42775. /**
  42776. * @brief Returns the number of elements in a container.
  42777. * @return Number of elements in a container.
  42778. */
  42779. [[nodiscard]] size_type size() const noexcept {
  42780. return packed.first().size();
  42781. }
  42782. /**
  42783. * @brief Returns the maximum possible number of elements.
  42784. * @return Maximum possible number of elements.
  42785. */
  42786. [[nodiscard]] size_type max_size() const noexcept {
  42787. return packed.first().max_size();
  42788. }
  42789. /*! @brief Clears the container. */
  42790. void clear() noexcept {
  42791. sparse.first().clear();
  42792. packed.first().clear();
  42793. rehash(0u);
  42794. }
  42795. /**
  42796. * @brief Inserts an element into the container, if the key does not exist.
  42797. * @param value A key-value pair eventually convertible to the value type.
  42798. * @return A pair consisting of an iterator to the inserted element (or to
  42799. * the element that prevented the insertion) and a bool denoting whether the
  42800. * insertion took place.
  42801. */
  42802. std::pair<iterator, bool> insert(const value_type &value) {
  42803. return insert_or_do_nothing(value.first, value.second);
  42804. }
  42805. /*! @copydoc insert */
  42806. std::pair<iterator, bool> insert(value_type &&value) {
  42807. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  42808. }
  42809. /**
  42810. * @copydoc insert
  42811. * @tparam Arg Type of the key-value pair to insert into the container.
  42812. */
  42813. template<typename Arg>
  42814. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  42815. insert(Arg &&value) {
  42816. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  42817. }
  42818. /**
  42819. * @brief Inserts elements into the container, if their keys do not exist.
  42820. * @tparam It Type of input iterator.
  42821. * @param first An iterator to the first element of the range of elements.
  42822. * @param last An iterator past the last element of the range of elements.
  42823. */
  42824. template<typename It>
  42825. void insert(It first, It last) {
  42826. for(; first != last; ++first) {
  42827. insert(*first);
  42828. }
  42829. }
  42830. /**
  42831. * @brief Inserts an element into the container or assigns to the current
  42832. * element if the key already exists.
  42833. * @tparam Arg Type of the value to insert or assign.
  42834. * @param key A key used both to look up and to insert if not found.
  42835. * @param value A value to insert or assign.
  42836. * @return A pair consisting of an iterator to the element and a bool
  42837. * denoting whether the insertion took place.
  42838. */
  42839. template<typename Arg>
  42840. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  42841. return insert_or_overwrite(key, std::forward<Arg>(value));
  42842. }
  42843. /*! @copydoc insert_or_assign */
  42844. template<typename Arg>
  42845. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  42846. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  42847. }
  42848. /**
  42849. * @brief Constructs an element in-place, if the key does not exist.
  42850. *
  42851. * The element is also constructed when the container already has the key,
  42852. * in which case the newly constructed object is destroyed immediately.
  42853. *
  42854. * @tparam Args Types of arguments to forward to the constructor of the
  42855. * element.
  42856. * @param args Arguments to forward to the constructor of the element.
  42857. * @return A pair consisting of an iterator to the inserted element (or to
  42858. * the element that prevented the insertion) and a bool denoting whether the
  42859. * insertion took place.
  42860. */
  42861. template<typename... Args>
  42862. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  42863. if constexpr(sizeof...(Args) == 0u) {
  42864. return insert_or_do_nothing(key_type{});
  42865. } else if constexpr(sizeof...(Args) == 1u) {
  42866. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  42867. } else if constexpr(sizeof...(Args) == 2u) {
  42868. return insert_or_do_nothing(std::forward<Args>(args)...);
  42869. } else {
  42870. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  42871. const auto index = key_to_bucket(node.element.first);
  42872. if(auto it = constrained_find(node.element.first, index); it != end()) {
  42873. packed.first().pop_back();
  42874. return std::make_pair(it, false);
  42875. }
  42876. std::swap(node.next, sparse.first()[index]);
  42877. rehash_if_required();
  42878. return std::make_pair(--end(), true);
  42879. }
  42880. }
  42881. /**
  42882. * @brief Inserts in-place if the key does not exist, does nothing if the
  42883. * key exists.
  42884. * @tparam Args Types of arguments to forward to the constructor of the
  42885. * element.
  42886. * @param key A key used both to look up and to insert if not found.
  42887. * @param args Arguments to forward to the constructor of the element.
  42888. * @return A pair consisting of an iterator to the inserted element (or to
  42889. * the element that prevented the insertion) and a bool denoting whether the
  42890. * insertion took place.
  42891. */
  42892. template<typename... Args>
  42893. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  42894. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  42895. }
  42896. /*! @copydoc try_emplace */
  42897. template<typename... Args>
  42898. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  42899. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  42900. }
  42901. /**
  42902. * @brief Removes an element from a given position.
  42903. * @param pos An iterator to the element to remove.
  42904. * @return An iterator following the removed element.
  42905. */
  42906. iterator erase(const_iterator pos) {
  42907. const auto diff = pos - cbegin();
  42908. erase(pos->first);
  42909. return begin() + diff;
  42910. }
  42911. /**
  42912. * @brief Removes the given elements from a container.
  42913. * @param first An iterator to the first element of the range of elements.
  42914. * @param last An iterator past the last element of the range of elements.
  42915. * @return An iterator following the last removed element.
  42916. */
  42917. iterator erase(const_iterator first, const_iterator last) {
  42918. const auto dist = first - cbegin();
  42919. for(auto from = last - cbegin(); from != dist; --from) {
  42920. erase(packed.first()[static_cast<size_type>(from) - 1u].element.first);
  42921. }
  42922. return (begin() + dist);
  42923. }
  42924. /**
  42925. * @brief Removes the element associated with a given key.
  42926. * @param key A key value of an element to remove.
  42927. * @return Number of elements removed (either 0 or 1).
  42928. */
  42929. size_type erase(const key_type &key) {
  42930. for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) {
  42931. if(packed.second()(packed.first()[*curr].element.first, key)) {
  42932. const auto index = *curr;
  42933. *curr = packed.first()[*curr].next;
  42934. move_and_pop(index);
  42935. return 1u;
  42936. }
  42937. }
  42938. return 0u;
  42939. }
  42940. /**
  42941. * @brief Accesses a given element with bounds checking.
  42942. * @param key A key of an element to find.
  42943. * @return A reference to the mapped value of the requested element.
  42944. */
  42945. [[nodiscard]] mapped_type &at(const key_type &key) {
  42946. auto it = find(key);
  42947. ENTT_ASSERT(it != end(), "Invalid key");
  42948. return it->second;
  42949. }
  42950. /*! @copydoc at */
  42951. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  42952. auto it = find(key);
  42953. ENTT_ASSERT(it != cend(), "Invalid key");
  42954. return it->second;
  42955. }
  42956. /**
  42957. * @brief Accesses a given element with bounds checking.
  42958. * @tparam Other Type of the key of an element to find.
  42959. * @param key A key of an element to find.
  42960. * @return A reference to the mapped value of the requested element.
  42961. */
  42962. template<typename Other>
  42963. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type const &>>
  42964. at(const Other &key) const {
  42965. auto it = find(key);
  42966. ENTT_ASSERT(it != cend(), "Invalid key");
  42967. return it->second;
  42968. }
  42969. /*! @copydoc at */
  42970. template<typename Other>
  42971. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type &>>
  42972. at(const Other &key) {
  42973. auto it = find(key);
  42974. ENTT_ASSERT(it != end(), "Invalid key");
  42975. return it->second;
  42976. }
  42977. /**
  42978. * @brief Accesses or inserts a given element.
  42979. * @param key A key of an element to find or insert.
  42980. * @return A reference to the mapped value of the requested element.
  42981. */
  42982. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  42983. return insert_or_do_nothing(key).first->second;
  42984. }
  42985. /**
  42986. * @brief Accesses or inserts a given element.
  42987. * @param key A key of an element to find or insert.
  42988. * @return A reference to the mapped value of the requested element.
  42989. */
  42990. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  42991. return insert_or_do_nothing(std::move(key)).first->second;
  42992. }
  42993. /**
  42994. * @brief Returns the number of elements matching a key (either 1 or 0).
  42995. * @param key Key value of an element to search for.
  42996. * @return Number of elements matching the key (either 1 or 0).
  42997. */
  42998. [[nodiscard]] size_type count(const key_type &key) const {
  42999. return find(key) != end();
  43000. }
  43001. /**
  43002. * @brief Returns the number of elements matching a key (either 1 or 0).
  43003. * @tparam Other Type of the key value of an element to search for.
  43004. * @param key Key value of an element to search for.
  43005. * @return Number of elements matching the key (either 1 or 0).
  43006. */
  43007. template<typename Other>
  43008. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  43009. count(const Other &key) const {
  43010. return find(key) != end();
  43011. }
  43012. /**
  43013. * @brief Finds an element with a given key.
  43014. * @param key Key value of an element to search for.
  43015. * @return An iterator to an element with the given key. If no such element
  43016. * is found, a past-the-end iterator is returned.
  43017. */
  43018. [[nodiscard]] iterator find(const key_type &key) {
  43019. return constrained_find(key, key_to_bucket(key));
  43020. }
  43021. /*! @copydoc find */
  43022. [[nodiscard]] const_iterator find(const key_type &key) const {
  43023. return constrained_find(key, key_to_bucket(key));
  43024. }
  43025. /**
  43026. * @brief Finds an element with a key that compares _equivalent_ to a given
  43027. * key.
  43028. * @tparam Other Type of the key value of an element to search for.
  43029. * @param key Key value of an element to search for.
  43030. * @return An iterator to an element with the given key. If no such element
  43031. * is found, a past-the-end iterator is returned.
  43032. */
  43033. template<typename Other>
  43034. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  43035. find(const Other &key) {
  43036. return constrained_find(key, key_to_bucket(key));
  43037. }
  43038. /*! @copydoc find */
  43039. template<typename Other>
  43040. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  43041. find(const Other &key) const {
  43042. return constrained_find(key, key_to_bucket(key));
  43043. }
  43044. /**
  43045. * @brief Returns a range containing all elements with a given key.
  43046. * @param key Key value of an element to search for.
  43047. * @return A pair of iterators pointing to the first element and past the
  43048. * last element of the range.
  43049. */
  43050. [[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
  43051. const auto it = find(key);
  43052. return {it, it + !(it == end())};
  43053. }
  43054. /*! @copydoc equal_range */
  43055. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
  43056. const auto it = find(key);
  43057. return {it, it + !(it == cend())};
  43058. }
  43059. /**
  43060. * @brief Returns a range containing all elements that compare _equivalent_
  43061. * to a given key.
  43062. * @tparam Other Type of an element to search for.
  43063. * @param key Key value of an element to search for.
  43064. * @return A pair of iterators pointing to the first element and past the
  43065. * last element of the range.
  43066. */
  43067. template<typename Other>
  43068. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  43069. equal_range(const Other &key) {
  43070. const auto it = find(key);
  43071. return {it, it + !(it == end())};
  43072. }
  43073. /*! @copydoc equal_range */
  43074. template<typename Other>
  43075. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  43076. equal_range(const Other &key) const {
  43077. const auto it = find(key);
  43078. return {it, it + !(it == cend())};
  43079. }
  43080. /**
  43081. * @brief Checks if the container contains an element with a given key.
  43082. * @param key Key value of an element to search for.
  43083. * @return True if there is such an element, false otherwise.
  43084. */
  43085. [[nodiscard]] bool contains(const key_type &key) const {
  43086. return (find(key) != cend());
  43087. }
  43088. /**
  43089. * @brief Checks if the container contains an element with a key that
  43090. * compares _equivalent_ to a given value.
  43091. * @tparam Other Type of the key value of an element to search for.
  43092. * @param key Key value of an element to search for.
  43093. * @return True if there is such an element, false otherwise.
  43094. */
  43095. template<typename Other>
  43096. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  43097. contains(const Other &key) const {
  43098. return (find(key) != cend());
  43099. }
  43100. /**
  43101. * @brief Returns an iterator to the beginning of a given bucket.
  43102. * @param index An index of a bucket to access.
  43103. * @return An iterator to the beginning of the given bucket.
  43104. */
  43105. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  43106. return {packed.first().begin(), sparse.first()[index]};
  43107. }
  43108. /**
  43109. * @brief Returns an iterator to the beginning of a given bucket.
  43110. * @param index An index of a bucket to access.
  43111. * @return An iterator to the beginning of the given bucket.
  43112. */
  43113. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  43114. return cbegin(index);
  43115. }
  43116. /**
  43117. * @brief Returns an iterator to the beginning of a given bucket.
  43118. * @param index An index of a bucket to access.
  43119. * @return An iterator to the beginning of the given bucket.
  43120. */
  43121. [[nodiscard]] local_iterator begin(const size_type index) {
  43122. return {packed.first().begin(), sparse.first()[index]};
  43123. }
  43124. /**
  43125. * @brief Returns an iterator to the end of a given bucket.
  43126. * @param index An index of a bucket to access.
  43127. * @return An iterator to the end of the given bucket.
  43128. */
  43129. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  43130. return {};
  43131. }
  43132. /**
  43133. * @brief Returns an iterator to the end of a given bucket.
  43134. * @param index An index of a bucket to access.
  43135. * @return An iterator to the end of the given bucket.
  43136. */
  43137. [[nodiscard]] const_local_iterator end(const size_type index) const {
  43138. return cend(index);
  43139. }
  43140. /**
  43141. * @brief Returns an iterator to the end of a given bucket.
  43142. * @param index An index of a bucket to access.
  43143. * @return An iterator to the end of the given bucket.
  43144. */
  43145. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  43146. return {};
  43147. }
  43148. /**
  43149. * @brief Returns the number of buckets.
  43150. * @return The number of buckets.
  43151. */
  43152. [[nodiscard]] size_type bucket_count() const {
  43153. return sparse.first().size();
  43154. }
  43155. /**
  43156. * @brief Returns the maximum number of buckets.
  43157. * @return The maximum number of buckets.
  43158. */
  43159. [[nodiscard]] size_type max_bucket_count() const {
  43160. return sparse.first().max_size();
  43161. }
  43162. /**
  43163. * @brief Returns the number of elements in a given bucket.
  43164. * @param index The index of the bucket to examine.
  43165. * @return The number of elements in the given bucket.
  43166. */
  43167. [[nodiscard]] size_type bucket_size(const size_type index) const {
  43168. return static_cast<size_type>(std::distance(begin(index), end(index)));
  43169. }
  43170. /**
  43171. * @brief Returns the bucket for a given key.
  43172. * @param key The value of the key to examine.
  43173. * @return The bucket for the given key.
  43174. */
  43175. [[nodiscard]] size_type bucket(const key_type &key) const {
  43176. return key_to_bucket(key);
  43177. }
  43178. /**
  43179. * @brief Returns the average number of elements per bucket.
  43180. * @return The average number of elements per bucket.
  43181. */
  43182. [[nodiscard]] float load_factor() const {
  43183. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  43184. }
  43185. /**
  43186. * @brief Returns the maximum average number of elements per bucket.
  43187. * @return The maximum average number of elements per bucket.
  43188. */
  43189. [[nodiscard]] float max_load_factor() const {
  43190. return threshold;
  43191. }
  43192. /**
  43193. * @brief Sets the desired maximum average number of elements per bucket.
  43194. * @param value A desired maximum average number of elements per bucket.
  43195. */
  43196. void max_load_factor(const float value) {
  43197. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  43198. threshold = value;
  43199. rehash(0u);
  43200. }
  43201. /**
  43202. * @brief Reserves at least the specified number of buckets and regenerates
  43203. * the hash table.
  43204. * @param cnt New number of buckets.
  43205. */
  43206. void rehash(const size_type cnt) {
  43207. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  43208. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  43209. value = value > cap ? value : cap;
  43210. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  43211. sparse.first().resize(sz);
  43212. for(auto &&elem: sparse.first()) {
  43213. elem = placeholder_position;
  43214. }
  43215. for(size_type pos{}, last = size(); pos < last; ++pos) {
  43216. const auto index = key_to_bucket(packed.first()[pos].element.first);
  43217. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  43218. }
  43219. }
  43220. }
  43221. /**
  43222. * @brief Reserves space for at least the specified number of elements and
  43223. * regenerates the hash table.
  43224. * @param cnt New number of elements.
  43225. */
  43226. void reserve(const size_type cnt) {
  43227. packed.first().reserve(cnt);
  43228. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  43229. }
  43230. /**
  43231. * @brief Returns the function used to hash the keys.
  43232. * @return The function used to hash the keys.
  43233. */
  43234. [[nodiscard]] hasher hash_function() const {
  43235. return sparse.second();
  43236. }
  43237. /**
  43238. * @brief Returns the function used to compare keys for equality.
  43239. * @return The function used to compare keys for equality.
  43240. */
  43241. [[nodiscard]] key_equal key_eq() const {
  43242. return packed.second();
  43243. }
  43244. private:
  43245. compressed_pair<sparse_container_type, hasher> sparse;
  43246. compressed_pair<packed_container_type, key_equal> packed;
  43247. float threshold{default_threshold};
  43248. };
  43249. } // namespace entt
  43250. /*! @cond TURN_OFF_DOXYGEN */
  43251. namespace std {
  43252. template<typename Key, typename Value, typename Allocator>
  43253. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  43254. : std::true_type {};
  43255. } // namespace std
  43256. /*! @endcond */
  43257. #endif
  43258. // #include "../container/dense_set.hpp"
  43259. #ifndef ENTT_CONTAINER_DENSE_SET_HPP
  43260. #define ENTT_CONTAINER_DENSE_SET_HPP
  43261. #include <cmath>
  43262. #include <cstddef>
  43263. #include <functional>
  43264. #include <iterator>
  43265. #include <limits>
  43266. #include <memory>
  43267. #include <tuple>
  43268. #include <type_traits>
  43269. #include <utility>
  43270. #include <vector>
  43271. // #include "../config/config.h"
  43272. // #include "../core/bit.hpp"
  43273. // #include "../core/compressed_pair.hpp"
  43274. // #include "../core/type_traits.hpp"
  43275. // #include "fwd.hpp"
  43276. namespace entt {
  43277. /*! @cond TURN_OFF_DOXYGEN */
  43278. namespace internal {
  43279. static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  43280. template<typename It>
  43281. class dense_set_iterator final {
  43282. template<typename>
  43283. friend class dense_set_iterator;
  43284. public:
  43285. using value_type = typename It::value_type::second_type;
  43286. using pointer = const value_type *;
  43287. using reference = const value_type &;
  43288. using difference_type = std::ptrdiff_t;
  43289. using iterator_category = std::random_access_iterator_tag;
  43290. constexpr dense_set_iterator() noexcept
  43291. : it{} {}
  43292. constexpr dense_set_iterator(const It iter) noexcept
  43293. : it{iter} {}
  43294. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  43295. constexpr dense_set_iterator(const dense_set_iterator<Other> &other) noexcept
  43296. : it{other.it} {}
  43297. constexpr dense_set_iterator &operator++() noexcept {
  43298. return ++it, *this;
  43299. }
  43300. constexpr dense_set_iterator operator++(int) noexcept {
  43301. const dense_set_iterator orig = *this;
  43302. return ++(*this), orig;
  43303. }
  43304. constexpr dense_set_iterator &operator--() noexcept {
  43305. return --it, *this;
  43306. }
  43307. constexpr dense_set_iterator operator--(int) noexcept {
  43308. const dense_set_iterator orig = *this;
  43309. return operator--(), orig;
  43310. }
  43311. constexpr dense_set_iterator &operator+=(const difference_type value) noexcept {
  43312. it += value;
  43313. return *this;
  43314. }
  43315. constexpr dense_set_iterator operator+(const difference_type value) const noexcept {
  43316. dense_set_iterator copy = *this;
  43317. return (copy += value);
  43318. }
  43319. constexpr dense_set_iterator &operator-=(const difference_type value) noexcept {
  43320. return (*this += -value);
  43321. }
  43322. constexpr dense_set_iterator operator-(const difference_type value) const noexcept {
  43323. return (*this + -value);
  43324. }
  43325. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  43326. return it[value].second;
  43327. }
  43328. [[nodiscard]] constexpr pointer operator->() const noexcept {
  43329. return std::addressof(operator[](0));
  43330. }
  43331. [[nodiscard]] constexpr reference operator*() const noexcept {
  43332. return operator[](0);
  43333. }
  43334. template<typename Lhs, typename Rhs>
  43335. friend constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  43336. template<typename Lhs, typename Rhs>
  43337. friend constexpr bool operator==(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  43338. template<typename Lhs, typename Rhs>
  43339. friend constexpr bool operator<(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  43340. private:
  43341. It it;
  43342. };
  43343. template<typename Lhs, typename Rhs>
  43344. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  43345. return lhs.it - rhs.it;
  43346. }
  43347. template<typename Lhs, typename Rhs>
  43348. [[nodiscard]] constexpr bool operator==(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  43349. return lhs.it == rhs.it;
  43350. }
  43351. template<typename Lhs, typename Rhs>
  43352. [[nodiscard]] constexpr bool operator!=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  43353. return !(lhs == rhs);
  43354. }
  43355. template<typename Lhs, typename Rhs>
  43356. [[nodiscard]] constexpr bool operator<(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  43357. return lhs.it < rhs.it;
  43358. }
  43359. template<typename Lhs, typename Rhs>
  43360. [[nodiscard]] constexpr bool operator>(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  43361. return rhs < lhs;
  43362. }
  43363. template<typename Lhs, typename Rhs>
  43364. [[nodiscard]] constexpr bool operator<=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  43365. return !(lhs > rhs);
  43366. }
  43367. template<typename Lhs, typename Rhs>
  43368. [[nodiscard]] constexpr bool operator>=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  43369. return !(lhs < rhs);
  43370. }
  43371. template<typename It>
  43372. class dense_set_local_iterator final {
  43373. template<typename>
  43374. friend class dense_set_local_iterator;
  43375. public:
  43376. using value_type = typename It::value_type::second_type;
  43377. using pointer = const value_type *;
  43378. using reference = const value_type &;
  43379. using difference_type = std::ptrdiff_t;
  43380. using iterator_category = std::forward_iterator_tag;
  43381. constexpr dense_set_local_iterator() noexcept = default;
  43382. constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept
  43383. : it{iter},
  43384. offset{pos} {}
  43385. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  43386. constexpr dense_set_local_iterator(const dense_set_local_iterator<Other> &other) noexcept
  43387. : it{other.it},
  43388. offset{other.offset} {}
  43389. constexpr dense_set_local_iterator &operator++() noexcept {
  43390. return offset = it[static_cast<typename It::difference_type>(offset)].first, *this;
  43391. }
  43392. constexpr dense_set_local_iterator operator++(int) noexcept {
  43393. const dense_set_local_iterator orig = *this;
  43394. return ++(*this), orig;
  43395. }
  43396. [[nodiscard]] constexpr pointer operator->() const noexcept {
  43397. return std::addressof(it[static_cast<typename It::difference_type>(offset)].second);
  43398. }
  43399. [[nodiscard]] constexpr reference operator*() const noexcept {
  43400. return *operator->();
  43401. }
  43402. [[nodiscard]] constexpr std::size_t index() const noexcept {
  43403. return offset;
  43404. }
  43405. private:
  43406. It it{};
  43407. std::size_t offset{dense_set_placeholder_position};
  43408. };
  43409. template<typename Lhs, typename Rhs>
  43410. [[nodiscard]] constexpr bool operator==(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  43411. return lhs.index() == rhs.index();
  43412. }
  43413. template<typename Lhs, typename Rhs>
  43414. [[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  43415. return !(lhs == rhs);
  43416. }
  43417. } // namespace internal
  43418. /*! @endcond */
  43419. /**
  43420. * @brief Associative container for unique objects of a given type.
  43421. *
  43422. * Internally, elements are organized into buckets. Which bucket an element is
  43423. * placed into depends entirely on its hash. Elements with the same hash code
  43424. * appear in the same bucket.
  43425. *
  43426. * @tparam Type Value type of the associative container.
  43427. * @tparam Hash Type of function to use to hash the values.
  43428. * @tparam KeyEqual Type of function to use to compare the values for equality.
  43429. * @tparam Allocator Type of allocator used to manage memory and elements.
  43430. */
  43431. template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
  43432. class dense_set {
  43433. static constexpr float default_threshold = 0.875f;
  43434. static constexpr std::size_t minimum_capacity = 8u;
  43435. static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position;
  43436. using node_type = std::pair<std::size_t, Type>;
  43437. using alloc_traits = std::allocator_traits<Allocator>;
  43438. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  43439. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  43440. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  43441. template<typename Other>
  43442. [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept {
  43443. return fast_mod(static_cast<size_type>(sparse.second()(value)), bucket_count());
  43444. }
  43445. template<typename Other>
  43446. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) {
  43447. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  43448. if(packed.second()(packed.first()[offset].second, value)) {
  43449. return begin() + static_cast<typename iterator::difference_type>(offset);
  43450. }
  43451. }
  43452. return end();
  43453. }
  43454. template<typename Other>
  43455. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const {
  43456. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  43457. if(packed.second()(packed.first()[offset].second, value)) {
  43458. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  43459. }
  43460. }
  43461. return cend();
  43462. }
  43463. template<typename Other>
  43464. [[nodiscard]] auto insert_or_do_nothing(Other &&value) {
  43465. const auto index = value_to_bucket(value);
  43466. if(auto it = constrained_find(value, index); it != end()) {
  43467. return std::make_pair(it, false);
  43468. }
  43469. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(value));
  43470. sparse.first()[index] = packed.first().size() - 1u;
  43471. rehash_if_required();
  43472. return std::make_pair(--end(), true);
  43473. }
  43474. void move_and_pop(const std::size_t pos) {
  43475. if(const auto last = size() - 1u; pos != last) {
  43476. size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)];
  43477. packed.first()[pos] = std::move(packed.first().back());
  43478. for(; *curr != last; curr = &packed.first()[*curr].first) {}
  43479. *curr = pos;
  43480. }
  43481. packed.first().pop_back();
  43482. }
  43483. void rehash_if_required() {
  43484. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  43485. rehash(bc * 2u);
  43486. }
  43487. }
  43488. public:
  43489. /*! @brief Allocator type. */
  43490. using allocator_type = Allocator;
  43491. /*! @brief Key type of the container. */
  43492. using key_type = Type;
  43493. /*! @brief Value type of the container. */
  43494. using value_type = Type;
  43495. /*! @brief Unsigned integer type. */
  43496. using size_type = std::size_t;
  43497. /*! @brief Signed integer type. */
  43498. using difference_type = std::ptrdiff_t;
  43499. /*! @brief Type of function to use to hash the elements. */
  43500. using hasher = Hash;
  43501. /*! @brief Type of function to use to compare the elements for equality. */
  43502. using key_equal = KeyEqual;
  43503. /*! @brief Random access iterator type. */
  43504. using iterator = internal::dense_set_iterator<typename packed_container_type::iterator>;
  43505. /*! @brief Constant random access iterator type. */
  43506. using const_iterator = internal::dense_set_iterator<typename packed_container_type::const_iterator>;
  43507. /*! @brief Reverse iterator type. */
  43508. using reverse_iterator = std::reverse_iterator<iterator>;
  43509. /*! @brief Constant reverse iterator type. */
  43510. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  43511. /*! @brief Forward iterator type. */
  43512. using local_iterator = internal::dense_set_local_iterator<typename packed_container_type::iterator>;
  43513. /*! @brief Constant forward iterator type. */
  43514. using const_local_iterator = internal::dense_set_local_iterator<typename packed_container_type::const_iterator>;
  43515. /*! @brief Default constructor. */
  43516. dense_set()
  43517. : dense_set{minimum_capacity} {}
  43518. /**
  43519. * @brief Constructs an empty container with a given allocator.
  43520. * @param allocator The allocator to use.
  43521. */
  43522. explicit dense_set(const allocator_type &allocator)
  43523. : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  43524. /**
  43525. * @brief Constructs an empty container with a given allocator and user
  43526. * supplied minimal number of buckets.
  43527. * @param cnt Minimal number of buckets.
  43528. * @param allocator The allocator to use.
  43529. */
  43530. dense_set(const size_type cnt, const allocator_type &allocator)
  43531. : dense_set{cnt, hasher{}, key_equal{}, allocator} {}
  43532. /**
  43533. * @brief Constructs an empty container with a given allocator, hash
  43534. * function and user supplied minimal number of buckets.
  43535. * @param cnt Minimal number of buckets.
  43536. * @param hash Hash function to use.
  43537. * @param allocator The allocator to use.
  43538. */
  43539. dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  43540. : dense_set{cnt, hash, key_equal{}, allocator} {}
  43541. /**
  43542. * @brief Constructs an empty container with a given allocator, hash
  43543. * function, compare function and user supplied minimal number of buckets.
  43544. * @param cnt Minimal number of buckets.
  43545. * @param hash Hash function to use.
  43546. * @param equal Compare function to use.
  43547. * @param allocator The allocator to use.
  43548. */
  43549. explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  43550. : sparse{allocator, hash},
  43551. packed{allocator, equal} {
  43552. rehash(cnt);
  43553. }
  43554. /*! @brief Default copy constructor. */
  43555. dense_set(const dense_set &) = default;
  43556. /**
  43557. * @brief Allocator-extended copy constructor.
  43558. * @param other The instance to copy from.
  43559. * @param allocator The allocator to use.
  43560. */
  43561. dense_set(const dense_set &other, const allocator_type &allocator)
  43562. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  43563. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  43564. threshold{other.threshold} {}
  43565. /*! @brief Default move constructor. */
  43566. dense_set(dense_set &&) noexcept = default;
  43567. /**
  43568. * @brief Allocator-extended move constructor.
  43569. * @param other The instance to move from.
  43570. * @param allocator The allocator to use.
  43571. */
  43572. dense_set(dense_set &&other, const allocator_type &allocator)
  43573. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  43574. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  43575. threshold{other.threshold} {}
  43576. /*! @brief Default destructor. */
  43577. ~dense_set() = default;
  43578. /**
  43579. * @brief Default copy assignment operator.
  43580. * @return This container.
  43581. */
  43582. dense_set &operator=(const dense_set &) = default;
  43583. /**
  43584. * @brief Default move assignment operator.
  43585. * @return This container.
  43586. */
  43587. dense_set &operator=(dense_set &&) noexcept = default;
  43588. /**
  43589. * @brief Exchanges the contents with those of a given container.
  43590. * @param other Container to exchange the content with.
  43591. */
  43592. void swap(dense_set &other) noexcept {
  43593. using std::swap;
  43594. swap(sparse, other.sparse);
  43595. swap(packed, other.packed);
  43596. swap(threshold, other.threshold);
  43597. }
  43598. /**
  43599. * @brief Returns the associated allocator.
  43600. * @return The associated allocator.
  43601. */
  43602. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  43603. return sparse.first().get_allocator();
  43604. }
  43605. /**
  43606. * @brief Returns an iterator to the beginning.
  43607. *
  43608. * If the array is empty, the returned iterator will be equal to `end()`.
  43609. *
  43610. * @return An iterator to the first instance of the internal array.
  43611. */
  43612. [[nodiscard]] const_iterator cbegin() const noexcept {
  43613. return packed.first().begin();
  43614. }
  43615. /*! @copydoc cbegin */
  43616. [[nodiscard]] const_iterator begin() const noexcept {
  43617. return cbegin();
  43618. }
  43619. /*! @copydoc begin */
  43620. [[nodiscard]] iterator begin() noexcept {
  43621. return packed.first().begin();
  43622. }
  43623. /**
  43624. * @brief Returns an iterator to the end.
  43625. * @return An iterator to the element following the last instance of the
  43626. * internal array.
  43627. */
  43628. [[nodiscard]] const_iterator cend() const noexcept {
  43629. return packed.first().end();
  43630. }
  43631. /*! @copydoc cend */
  43632. [[nodiscard]] const_iterator end() const noexcept {
  43633. return cend();
  43634. }
  43635. /*! @copydoc end */
  43636. [[nodiscard]] iterator end() noexcept {
  43637. return packed.first().end();
  43638. }
  43639. /**
  43640. * @brief Returns a reverse iterator to the beginning.
  43641. *
  43642. * If the array is empty, the returned iterator will be equal to `rend()`.
  43643. *
  43644. * @return An iterator to the first instance of the reversed internal array.
  43645. */
  43646. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  43647. return std::make_reverse_iterator(cend());
  43648. }
  43649. /*! @copydoc crbegin */
  43650. [[nodiscard]] const_reverse_iterator rbegin() const noexcept {
  43651. return crbegin();
  43652. }
  43653. /*! @copydoc rbegin */
  43654. [[nodiscard]] reverse_iterator rbegin() noexcept {
  43655. return std::make_reverse_iterator(end());
  43656. }
  43657. /**
  43658. * @brief Returns a reverse iterator to the end.
  43659. * @return An iterator to the element following the last instance of the
  43660. * reversed internal array.
  43661. */
  43662. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  43663. return std::make_reverse_iterator(cbegin());
  43664. }
  43665. /*! @copydoc crend */
  43666. [[nodiscard]] const_reverse_iterator rend() const noexcept {
  43667. return crend();
  43668. }
  43669. /*! @copydoc rend */
  43670. [[nodiscard]] reverse_iterator rend() noexcept {
  43671. return std::make_reverse_iterator(begin());
  43672. }
  43673. /**
  43674. * @brief Checks whether a container is empty.
  43675. * @return True if the container is empty, false otherwise.
  43676. */
  43677. [[nodiscard]] bool empty() const noexcept {
  43678. return packed.first().empty();
  43679. }
  43680. /**
  43681. * @brief Returns the number of elements in a container.
  43682. * @return Number of elements in a container.
  43683. */
  43684. [[nodiscard]] size_type size() const noexcept {
  43685. return packed.first().size();
  43686. }
  43687. /**
  43688. * @brief Returns the maximum possible number of elements.
  43689. * @return Maximum possible number of elements.
  43690. */
  43691. [[nodiscard]] size_type max_size() const noexcept {
  43692. return packed.first().max_size();
  43693. }
  43694. /*! @brief Clears the container. */
  43695. void clear() noexcept {
  43696. sparse.first().clear();
  43697. packed.first().clear();
  43698. rehash(0u);
  43699. }
  43700. /**
  43701. * @brief Inserts an element into the container, if it does not exist.
  43702. * @param value An element to insert into the container.
  43703. * @return A pair consisting of an iterator to the inserted element (or to
  43704. * the element that prevented the insertion) and a bool denoting whether the
  43705. * insertion took place.
  43706. */
  43707. std::pair<iterator, bool> insert(const value_type &value) {
  43708. return insert_or_do_nothing(value);
  43709. }
  43710. /*! @copydoc insert */
  43711. std::pair<iterator, bool> insert(value_type &&value) {
  43712. return insert_or_do_nothing(std::move(value));
  43713. }
  43714. /**
  43715. * @brief Inserts elements into the container, if they do not exist.
  43716. * @tparam It Type of input iterator.
  43717. * @param first An iterator to the first element of the range of elements.
  43718. * @param last An iterator past the last element of the range of elements.
  43719. */
  43720. template<typename It>
  43721. void insert(It first, It last) {
  43722. for(; first != last; ++first) {
  43723. insert(*first);
  43724. }
  43725. }
  43726. /**
  43727. * @brief Constructs an element in-place, if it does not exist.
  43728. *
  43729. * The element is also constructed when the container already has the key,
  43730. * in which case the newly constructed object is destroyed immediately.
  43731. *
  43732. * @tparam Args Types of arguments to forward to the constructor of the
  43733. * element.
  43734. * @param args Arguments to forward to the constructor of the element.
  43735. * @return A pair consisting of an iterator to the inserted element (or to
  43736. * the element that prevented the insertion) and a bool denoting whether the
  43737. * insertion took place.
  43738. */
  43739. template<typename... Args>
  43740. std::pair<iterator, bool> emplace(Args &&...args) {
  43741. if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v<std::decay_t<Args>, value_type>)) {
  43742. return insert_or_do_nothing(std::forward<Args>(args)...);
  43743. } else {
  43744. auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward<Args>(args)...));
  43745. const auto index = value_to_bucket(node.second);
  43746. if(auto it = constrained_find(node.second, index); it != end()) {
  43747. packed.first().pop_back();
  43748. return std::make_pair(it, false);
  43749. }
  43750. std::swap(node.first, sparse.first()[index]);
  43751. rehash_if_required();
  43752. return std::make_pair(--end(), true);
  43753. }
  43754. }
  43755. /**
  43756. * @brief Removes an element from a given position.
  43757. * @param pos An iterator to the element to remove.
  43758. * @return An iterator following the removed element.
  43759. */
  43760. iterator erase(const_iterator pos) {
  43761. const auto diff = pos - cbegin();
  43762. erase(*pos);
  43763. return begin() + diff;
  43764. }
  43765. /**
  43766. * @brief Removes the given elements from a container.
  43767. * @param first An iterator to the first element of the range of elements.
  43768. * @param last An iterator past the last element of the range of elements.
  43769. * @return An iterator following the last removed element.
  43770. */
  43771. iterator erase(const_iterator first, const_iterator last) {
  43772. const auto dist = first - cbegin();
  43773. for(auto from = last - cbegin(); from != dist; --from) {
  43774. erase(packed.first()[static_cast<size_type>(from) - 1u].second);
  43775. }
  43776. return (begin() + dist);
  43777. }
  43778. /**
  43779. * @brief Removes the element associated with a given value.
  43780. * @param value Value of an element to remove.
  43781. * @return Number of elements removed (either 0 or 1).
  43782. */
  43783. size_type erase(const value_type &value) {
  43784. for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) {
  43785. if(packed.second()(packed.first()[*curr].second, value)) {
  43786. const auto index = *curr;
  43787. *curr = packed.first()[*curr].first;
  43788. move_and_pop(index);
  43789. return 1u;
  43790. }
  43791. }
  43792. return 0u;
  43793. }
  43794. /**
  43795. * @brief Returns the number of elements matching a value (either 1 or 0).
  43796. * @param key Key value of an element to search for.
  43797. * @return Number of elements matching the key (either 1 or 0).
  43798. */
  43799. [[nodiscard]] size_type count(const value_type &key) const {
  43800. return find(key) != end();
  43801. }
  43802. /**
  43803. * @brief Returns the number of elements matching a key (either 1 or 0).
  43804. * @tparam Other Type of the key value of an element to search for.
  43805. * @param key Key value of an element to search for.
  43806. * @return Number of elements matching the key (either 1 or 0).
  43807. */
  43808. template<typename Other>
  43809. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  43810. count(const Other &key) const {
  43811. return find(key) != end();
  43812. }
  43813. /**
  43814. * @brief Finds an element with a given value.
  43815. * @param value Value of an element to search for.
  43816. * @return An iterator to an element with the given value. If no such
  43817. * element is found, a past-the-end iterator is returned.
  43818. */
  43819. [[nodiscard]] iterator find(const value_type &value) {
  43820. return constrained_find(value, value_to_bucket(value));
  43821. }
  43822. /*! @copydoc find */
  43823. [[nodiscard]] const_iterator find(const value_type &value) const {
  43824. return constrained_find(value, value_to_bucket(value));
  43825. }
  43826. /**
  43827. * @brief Finds an element that compares _equivalent_ to a given value.
  43828. * @tparam Other Type of an element to search for.
  43829. * @param value Value of an element to search for.
  43830. * @return An iterator to an element with the given value. If no such
  43831. * element is found, a past-the-end iterator is returned.
  43832. */
  43833. template<typename Other>
  43834. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  43835. find(const Other &value) {
  43836. return constrained_find(value, value_to_bucket(value));
  43837. }
  43838. /*! @copydoc find */
  43839. template<typename Other>
  43840. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  43841. find(const Other &value) const {
  43842. return constrained_find(value, value_to_bucket(value));
  43843. }
  43844. /**
  43845. * @brief Returns a range containing all elements with a given value.
  43846. * @param value Value of an element to search for.
  43847. * @return A pair of iterators pointing to the first element and past the
  43848. * last element of the range.
  43849. */
  43850. [[nodiscard]] std::pair<iterator, iterator> equal_range(const value_type &value) {
  43851. const auto it = find(value);
  43852. return {it, it + !(it == end())};
  43853. }
  43854. /*! @copydoc equal_range */
  43855. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const value_type &value) const {
  43856. const auto it = find(value);
  43857. return {it, it + !(it == cend())};
  43858. }
  43859. /**
  43860. * @brief Returns a range containing all elements that compare _equivalent_
  43861. * to a given value.
  43862. * @tparam Other Type of an element to search for.
  43863. * @param value Value of an element to search for.
  43864. * @return A pair of iterators pointing to the first element and past the
  43865. * last element of the range.
  43866. */
  43867. template<typename Other>
  43868. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  43869. equal_range(const Other &value) {
  43870. const auto it = find(value);
  43871. return {it, it + !(it == end())};
  43872. }
  43873. /*! @copydoc equal_range */
  43874. template<typename Other>
  43875. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  43876. equal_range(const Other &value) const {
  43877. const auto it = find(value);
  43878. return {it, it + !(it == cend())};
  43879. }
  43880. /**
  43881. * @brief Checks if the container contains an element with a given value.
  43882. * @param value Value of an element to search for.
  43883. * @return True if there is such an element, false otherwise.
  43884. */
  43885. [[nodiscard]] bool contains(const value_type &value) const {
  43886. return (find(value) != cend());
  43887. }
  43888. /**
  43889. * @brief Checks if the container contains an element that compares
  43890. * _equivalent_ to a given value.
  43891. * @tparam Other Type of an element to search for.
  43892. * @param value Value of an element to search for.
  43893. * @return True if there is such an element, false otherwise.
  43894. */
  43895. template<typename Other>
  43896. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  43897. contains(const Other &value) const {
  43898. return (find(value) != cend());
  43899. }
  43900. /**
  43901. * @brief Returns an iterator to the beginning of a given bucket.
  43902. * @param index An index of a bucket to access.
  43903. * @return An iterator to the beginning of the given bucket.
  43904. */
  43905. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  43906. return {packed.first().begin(), sparse.first()[index]};
  43907. }
  43908. /**
  43909. * @brief Returns an iterator to the beginning of a given bucket.
  43910. * @param index An index of a bucket to access.
  43911. * @return An iterator to the beginning of the given bucket.
  43912. */
  43913. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  43914. return cbegin(index);
  43915. }
  43916. /**
  43917. * @brief Returns an iterator to the beginning of a given bucket.
  43918. * @param index An index of a bucket to access.
  43919. * @return An iterator to the beginning of the given bucket.
  43920. */
  43921. [[nodiscard]] local_iterator begin(const size_type index) {
  43922. return {packed.first().begin(), sparse.first()[index]};
  43923. }
  43924. /**
  43925. * @brief Returns an iterator to the end of a given bucket.
  43926. * @param index An index of a bucket to access.
  43927. * @return An iterator to the end of the given bucket.
  43928. */
  43929. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  43930. return {};
  43931. }
  43932. /**
  43933. * @brief Returns an iterator to the end of a given bucket.
  43934. * @param index An index of a bucket to access.
  43935. * @return An iterator to the end of the given bucket.
  43936. */
  43937. [[nodiscard]] const_local_iterator end(const size_type index) const {
  43938. return cend(index);
  43939. }
  43940. /**
  43941. * @brief Returns an iterator to the end of a given bucket.
  43942. * @param index An index of a bucket to access.
  43943. * @return An iterator to the end of the given bucket.
  43944. */
  43945. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  43946. return {};
  43947. }
  43948. /**
  43949. * @brief Returns the number of buckets.
  43950. * @return The number of buckets.
  43951. */
  43952. [[nodiscard]] size_type bucket_count() const {
  43953. return sparse.first().size();
  43954. }
  43955. /**
  43956. * @brief Returns the maximum number of buckets.
  43957. * @return The maximum number of buckets.
  43958. */
  43959. [[nodiscard]] size_type max_bucket_count() const {
  43960. return sparse.first().max_size();
  43961. }
  43962. /**
  43963. * @brief Returns the number of elements in a given bucket.
  43964. * @param index The index of the bucket to examine.
  43965. * @return The number of elements in the given bucket.
  43966. */
  43967. [[nodiscard]] size_type bucket_size(const size_type index) const {
  43968. return static_cast<size_type>(std::distance(begin(index), end(index)));
  43969. }
  43970. /**
  43971. * @brief Returns the bucket for a given element.
  43972. * @param value The value of the element to examine.
  43973. * @return The bucket for the given element.
  43974. */
  43975. [[nodiscard]] size_type bucket(const value_type &value) const {
  43976. return value_to_bucket(value);
  43977. }
  43978. /**
  43979. * @brief Returns the average number of elements per bucket.
  43980. * @return The average number of elements per bucket.
  43981. */
  43982. [[nodiscard]] float load_factor() const {
  43983. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  43984. }
  43985. /**
  43986. * @brief Returns the maximum average number of elements per bucket.
  43987. * @return The maximum average number of elements per bucket.
  43988. */
  43989. [[nodiscard]] float max_load_factor() const {
  43990. return threshold;
  43991. }
  43992. /**
  43993. * @brief Sets the desired maximum average number of elements per bucket.
  43994. * @param value A desired maximum average number of elements per bucket.
  43995. */
  43996. void max_load_factor(const float value) {
  43997. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  43998. threshold = value;
  43999. rehash(0u);
  44000. }
  44001. /**
  44002. * @brief Reserves at least the specified number of buckets and regenerates
  44003. * the hash table.
  44004. * @param cnt New number of buckets.
  44005. */
  44006. void rehash(const size_type cnt) {
  44007. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  44008. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  44009. value = value > cap ? value : cap;
  44010. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  44011. sparse.first().resize(sz);
  44012. for(auto &&elem: sparse.first()) {
  44013. elem = placeholder_position;
  44014. }
  44015. for(size_type pos{}, last = size(); pos < last; ++pos) {
  44016. const auto index = value_to_bucket(packed.first()[pos].second);
  44017. packed.first()[pos].first = std::exchange(sparse.first()[index], pos);
  44018. }
  44019. }
  44020. }
  44021. /**
  44022. * @brief Reserves space for at least the specified number of elements and
  44023. * regenerates the hash table.
  44024. * @param cnt New number of elements.
  44025. */
  44026. void reserve(const size_type cnt) {
  44027. packed.first().reserve(cnt);
  44028. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  44029. }
  44030. /**
  44031. * @brief Returns the function used to hash the elements.
  44032. * @return The function used to hash the elements.
  44033. */
  44034. [[nodiscard]] hasher hash_function() const {
  44035. return sparse.second();
  44036. }
  44037. /**
  44038. * @brief Returns the function used to compare elements for equality.
  44039. * @return The function used to compare elements for equality.
  44040. */
  44041. [[nodiscard]] key_equal key_eq() const {
  44042. return packed.second();
  44043. }
  44044. private:
  44045. compressed_pair<sparse_container_type, hasher> sparse;
  44046. compressed_pair<packed_container_type, key_equal> packed;
  44047. float threshold{default_threshold};
  44048. };
  44049. } // namespace entt
  44050. #endif
  44051. // #include "../core/compressed_pair.hpp"
  44052. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  44053. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  44054. #include <cstddef>
  44055. #include <tuple>
  44056. #include <type_traits>
  44057. #include <utility>
  44058. // #include "fwd.hpp"
  44059. #ifndef ENTT_CORE_FWD_HPP
  44060. #define ENTT_CORE_FWD_HPP
  44061. #include <cstddef>
  44062. #include <cstdint>
  44063. // #include "../config/config.h"
  44064. namespace entt {
  44065. /*! @brief Possible modes of an any object. */
  44066. enum class any_policy : std::uint8_t {
  44067. /*! @brief Default mode, no element available. */
  44068. empty,
  44069. /*! @brief Owning mode, dynamically allocated element. */
  44070. dynamic,
  44071. /*! @brief Owning mode, embedded element. */
  44072. embedded,
  44073. /*! @brief Aliasing mode, non-const reference. */
  44074. ref,
  44075. /*! @brief Const aliasing mode, const reference. */
  44076. cref
  44077. };
  44078. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  44079. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  44080. class basic_any;
  44081. /*! @brief Alias declaration for type identifiers. */
  44082. using id_type = ENTT_ID_TYPE;
  44083. /*! @brief Alias declaration for the most common use case. */
  44084. using any = basic_any<>;
  44085. template<typename, typename>
  44086. class compressed_pair;
  44087. template<typename>
  44088. class basic_hashed_string;
  44089. /*! @brief Aliases for common character types. */
  44090. using hashed_string = basic_hashed_string<char>;
  44091. /*! @brief Aliases for common character types. */
  44092. using hashed_wstring = basic_hashed_string<wchar_t>;
  44093. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  44094. struct type_info;
  44095. } // namespace entt
  44096. #endif
  44097. // #include "type_traits.hpp"
  44098. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  44099. #define ENTT_CORE_TYPE_TRAITS_HPP
  44100. #include <cstddef>
  44101. #include <iterator>
  44102. #include <tuple>
  44103. #include <type_traits>
  44104. #include <utility>
  44105. // #include "../config/config.h"
  44106. // #include "fwd.hpp"
  44107. namespace entt {
  44108. /**
  44109. * @brief Utility class to disambiguate overloaded functions.
  44110. * @tparam N Number of choices available.
  44111. */
  44112. template<std::size_t N>
  44113. struct choice_t
  44114. // unfortunately, doxygen cannot parse such a construct
  44115. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  44116. {};
  44117. /*! @copybrief choice_t */
  44118. template<>
  44119. struct choice_t<0> {};
  44120. /**
  44121. * @brief Variable template for the choice trick.
  44122. * @tparam N Number of choices available.
  44123. */
  44124. template<std::size_t N>
  44125. inline constexpr choice_t<N> choice{};
  44126. /**
  44127. * @brief Identity type trait.
  44128. *
  44129. * Useful to establish non-deduced contexts in template argument deduction
  44130. * (waiting for C++20) or to provide types through function arguments.
  44131. *
  44132. * @tparam Type A type.
  44133. */
  44134. template<typename Type>
  44135. struct type_identity {
  44136. /*! @brief Identity type. */
  44137. using type = Type;
  44138. };
  44139. /**
  44140. * @brief Helper type.
  44141. * @tparam Type A type.
  44142. */
  44143. template<typename Type>
  44144. using type_identity_t = typename type_identity<Type>::type;
  44145. /**
  44146. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  44147. * @tparam Type The type of which to return the size.
  44148. */
  44149. template<typename Type, typename = void>
  44150. struct size_of: std::integral_constant<std::size_t, 0u> {};
  44151. /*! @copydoc size_of */
  44152. template<typename Type>
  44153. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  44154. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  44155. : std::integral_constant<std::size_t, sizeof(Type)> {};
  44156. /**
  44157. * @brief Helper variable template.
  44158. * @tparam Type The type of which to return the size.
  44159. */
  44160. template<typename Type>
  44161. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  44162. /**
  44163. * @brief Using declaration to be used to _repeat_ the same type a number of
  44164. * times equal to the size of a given parameter pack.
  44165. * @tparam Type A type to repeat.
  44166. */
  44167. template<typename Type, typename>
  44168. using unpack_as_type = Type;
  44169. /**
  44170. * @brief Helper variable template to be used to _repeat_ the same value a
  44171. * number of times equal to the size of a given parameter pack.
  44172. * @tparam Value A value to repeat.
  44173. */
  44174. template<auto Value, typename>
  44175. inline constexpr auto unpack_as_value = Value;
  44176. /**
  44177. * @brief Wraps a static constant.
  44178. * @tparam Value A static constant.
  44179. */
  44180. template<auto Value>
  44181. using integral_constant = std::integral_constant<decltype(Value), Value>;
  44182. /**
  44183. * @brief Alias template to facilitate the creation of named values.
  44184. * @tparam Value A constant value at least convertible to `id_type`.
  44185. */
  44186. template<id_type Value>
  44187. using tag = integral_constant<Value>;
  44188. /**
  44189. * @brief A class to use to push around lists of types, nothing more.
  44190. * @tparam Type Types provided by the type list.
  44191. */
  44192. template<typename... Type>
  44193. struct type_list {
  44194. /*! @brief Type list type. */
  44195. using type = type_list;
  44196. /*! @brief Compile-time number of elements in the type list. */
  44197. static constexpr auto size = sizeof...(Type);
  44198. };
  44199. /*! @brief Primary template isn't defined on purpose. */
  44200. template<std::size_t, typename>
  44201. struct type_list_element;
  44202. /**
  44203. * @brief Provides compile-time indexed access to the types of a type list.
  44204. * @tparam Index Index of the type to return.
  44205. * @tparam First First type provided by the type list.
  44206. * @tparam Other Other types provided by the type list.
  44207. */
  44208. template<std::size_t Index, typename First, typename... Other>
  44209. struct type_list_element<Index, type_list<First, Other...>>
  44210. : type_list_element<Index - 1u, type_list<Other...>> {};
  44211. /**
  44212. * @brief Provides compile-time indexed access to the types of a type list.
  44213. * @tparam First First type provided by the type list.
  44214. * @tparam Other Other types provided by the type list.
  44215. */
  44216. template<typename First, typename... Other>
  44217. struct type_list_element<0u, type_list<First, Other...>> {
  44218. /*! @brief Searched type. */
  44219. using type = First;
  44220. };
  44221. /**
  44222. * @brief Helper type.
  44223. * @tparam Index Index of the type to return.
  44224. * @tparam List Type list to search into.
  44225. */
  44226. template<std::size_t Index, typename List>
  44227. using type_list_element_t = typename type_list_element<Index, List>::type;
  44228. /*! @brief Primary template isn't defined on purpose. */
  44229. template<typename, typename>
  44230. struct type_list_index;
  44231. /**
  44232. * @brief Provides compile-time type access to the types of a type list.
  44233. * @tparam Type Type to look for and for which to return the index.
  44234. * @tparam First First type provided by the type list.
  44235. * @tparam Other Other types provided by the type list.
  44236. */
  44237. template<typename Type, typename First, typename... Other>
  44238. struct type_list_index<Type, type_list<First, Other...>> {
  44239. /*! @brief Unsigned integer type. */
  44240. using value_type = std::size_t;
  44241. /*! @brief Compile-time position of the given type in the sublist. */
  44242. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  44243. };
  44244. /**
  44245. * @brief Provides compile-time type access to the types of a type list.
  44246. * @tparam Type Type to look for and for which to return the index.
  44247. * @tparam Other Other types provided by the type list.
  44248. */
  44249. template<typename Type, typename... Other>
  44250. struct type_list_index<Type, type_list<Type, Other...>> {
  44251. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  44252. /*! @brief Unsigned integer type. */
  44253. using value_type = std::size_t;
  44254. /*! @brief Compile-time position of the given type in the sublist. */
  44255. static constexpr value_type value = 0u;
  44256. };
  44257. /**
  44258. * @brief Provides compile-time type access to the types of a type list.
  44259. * @tparam Type Type to look for and for which to return the index.
  44260. */
  44261. template<typename Type>
  44262. struct type_list_index<Type, type_list<>> {
  44263. /*! @brief Unsigned integer type. */
  44264. using value_type = std::size_t;
  44265. /*! @brief Compile-time position of the given type in the sublist. */
  44266. static constexpr value_type value = 0u;
  44267. };
  44268. /**
  44269. * @brief Helper variable template.
  44270. * @tparam List Type list.
  44271. * @tparam Type Type to look for and for which to return the index.
  44272. */
  44273. template<typename Type, typename List>
  44274. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  44275. /**
  44276. * @brief Concatenates multiple type lists.
  44277. * @tparam Type Types provided by the first type list.
  44278. * @tparam Other Types provided by the second type list.
  44279. * @return A type list composed by the types of both the type lists.
  44280. */
  44281. template<typename... Type, typename... Other>
  44282. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  44283. return {};
  44284. }
  44285. /*! @brief Primary template isn't defined on purpose. */
  44286. template<typename...>
  44287. struct type_list_cat;
  44288. /*! @brief Concatenates multiple type lists. */
  44289. template<>
  44290. struct type_list_cat<> {
  44291. /*! @brief A type list composed by the types of all the type lists. */
  44292. using type = type_list<>;
  44293. };
  44294. /**
  44295. * @brief Concatenates multiple type lists.
  44296. * @tparam Type Types provided by the first type list.
  44297. * @tparam Other Types provided by the second type list.
  44298. * @tparam List Other type lists, if any.
  44299. */
  44300. template<typename... Type, typename... Other, typename... List>
  44301. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  44302. /*! @brief A type list composed by the types of all the type lists. */
  44303. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  44304. };
  44305. /**
  44306. * @brief Concatenates multiple type lists.
  44307. * @tparam Type Types provided by the type list.
  44308. */
  44309. template<typename... Type>
  44310. struct type_list_cat<type_list<Type...>> {
  44311. /*! @brief A type list composed by the types of all the type lists. */
  44312. using type = type_list<Type...>;
  44313. };
  44314. /**
  44315. * @brief Helper type.
  44316. * @tparam List Type lists to concatenate.
  44317. */
  44318. template<typename... List>
  44319. using type_list_cat_t = typename type_list_cat<List...>::type;
  44320. /*! @cond TURN_OFF_DOXYGEN */
  44321. namespace internal {
  44322. template<typename...>
  44323. struct type_list_unique;
  44324. template<typename First, typename... Other, typename... Type>
  44325. struct type_list_unique<type_list<First, Other...>, Type...>
  44326. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  44327. template<typename... Type>
  44328. struct type_list_unique<type_list<>, Type...> {
  44329. using type = type_list<Type...>;
  44330. };
  44331. } // namespace internal
  44332. /*! @endcond */
  44333. /**
  44334. * @brief Removes duplicates types from a type list.
  44335. * @tparam List Type list.
  44336. */
  44337. template<typename List>
  44338. struct type_list_unique {
  44339. /*! @brief A type list without duplicate types. */
  44340. using type = typename internal::type_list_unique<List>::type;
  44341. };
  44342. /**
  44343. * @brief Helper type.
  44344. * @tparam List Type list.
  44345. */
  44346. template<typename List>
  44347. using type_list_unique_t = typename type_list_unique<List>::type;
  44348. /**
  44349. * @brief Provides the member constant `value` to true if a type list contains a
  44350. * given type, false otherwise.
  44351. * @tparam List Type list.
  44352. * @tparam Type Type to look for.
  44353. */
  44354. template<typename List, typename Type>
  44355. struct type_list_contains;
  44356. /**
  44357. * @copybrief type_list_contains
  44358. * @tparam Type Types provided by the type list.
  44359. * @tparam Other Type to look for.
  44360. */
  44361. template<typename... Type, typename Other>
  44362. struct type_list_contains<type_list<Type...>, Other>
  44363. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  44364. /**
  44365. * @brief Helper variable template.
  44366. * @tparam List Type list.
  44367. * @tparam Type Type to look for.
  44368. */
  44369. template<typename List, typename Type>
  44370. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  44371. /*! @brief Primary template isn't defined on purpose. */
  44372. template<typename...>
  44373. struct type_list_diff;
  44374. /**
  44375. * @brief Computes the difference between two type lists.
  44376. * @tparam Type Types provided by the first type list.
  44377. * @tparam Other Types provided by the second type list.
  44378. */
  44379. template<typename... Type, typename... Other>
  44380. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  44381. /*! @brief A type list that is the difference between the two type lists. */
  44382. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  44383. };
  44384. /**
  44385. * @brief Helper type.
  44386. * @tparam List Type lists between which to compute the difference.
  44387. */
  44388. template<typename... List>
  44389. using type_list_diff_t = typename type_list_diff<List...>::type;
  44390. /*! @brief Primary template isn't defined on purpose. */
  44391. template<typename, template<typename...> class>
  44392. struct type_list_transform;
  44393. /**
  44394. * @brief Applies a given _function_ to a type list and generate a new list.
  44395. * @tparam Type Types provided by the type list.
  44396. * @tparam Op Unary operation as template class with a type member named `type`.
  44397. */
  44398. template<typename... Type, template<typename...> class Op>
  44399. struct type_list_transform<type_list<Type...>, Op> {
  44400. /*! @brief Resulting type list after applying the transform function. */
  44401. // NOLINTNEXTLINE(modernize-type-traits)
  44402. using type = type_list<typename Op<Type>::type...>;
  44403. };
  44404. /**
  44405. * @brief Helper type.
  44406. * @tparam List Type list.
  44407. * @tparam Op Unary operation as template class with a type member named `type`.
  44408. */
  44409. template<typename List, template<typename...> class Op>
  44410. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  44411. /**
  44412. * @brief A class to use to push around lists of constant values, nothing more.
  44413. * @tparam Value Values provided by the value list.
  44414. */
  44415. template<auto... Value>
  44416. struct value_list {
  44417. /*! @brief Value list type. */
  44418. using type = value_list;
  44419. /*! @brief Compile-time number of elements in the value list. */
  44420. static constexpr auto size = sizeof...(Value);
  44421. };
  44422. /*! @brief Primary template isn't defined on purpose. */
  44423. template<std::size_t, typename>
  44424. struct value_list_element;
  44425. /**
  44426. * @brief Provides compile-time indexed access to the values of a value list.
  44427. * @tparam Index Index of the value to return.
  44428. * @tparam Value First value provided by the value list.
  44429. * @tparam Other Other values provided by the value list.
  44430. */
  44431. template<std::size_t Index, auto Value, auto... Other>
  44432. struct value_list_element<Index, value_list<Value, Other...>>
  44433. : value_list_element<Index - 1u, value_list<Other...>> {};
  44434. /**
  44435. * @brief Provides compile-time indexed access to the types of a type list.
  44436. * @tparam Value First value provided by the value list.
  44437. * @tparam Other Other values provided by the value list.
  44438. */
  44439. template<auto Value, auto... Other>
  44440. struct value_list_element<0u, value_list<Value, Other...>> {
  44441. /*! @brief Searched type. */
  44442. using type = decltype(Value);
  44443. /*! @brief Searched value. */
  44444. static constexpr auto value = Value;
  44445. };
  44446. /**
  44447. * @brief Helper type.
  44448. * @tparam Index Index of the type to return.
  44449. * @tparam List Value list to search into.
  44450. */
  44451. template<std::size_t Index, typename List>
  44452. using value_list_element_t = typename value_list_element<Index, List>::type;
  44453. /**
  44454. * @brief Helper type.
  44455. * @tparam Index Index of the value to return.
  44456. * @tparam List Value list to search into.
  44457. */
  44458. template<std::size_t Index, typename List>
  44459. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  44460. /*! @brief Primary template isn't defined on purpose. */
  44461. template<auto, typename>
  44462. struct value_list_index;
  44463. /**
  44464. * @brief Provides compile-time type access to the values of a value list.
  44465. * @tparam Value Value to look for and for which to return the index.
  44466. * @tparam First First value provided by the value list.
  44467. * @tparam Other Other values provided by the value list.
  44468. */
  44469. template<auto Value, auto First, auto... Other>
  44470. struct value_list_index<Value, value_list<First, Other...>> {
  44471. /*! @brief Unsigned integer type. */
  44472. using value_type = std::size_t;
  44473. /*! @brief Compile-time position of the given value in the sublist. */
  44474. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  44475. };
  44476. /**
  44477. * @brief Provides compile-time type access to the values of a value list.
  44478. * @tparam Value Value to look for and for which to return the index.
  44479. * @tparam Other Other values provided by the value list.
  44480. */
  44481. template<auto Value, auto... Other>
  44482. struct value_list_index<Value, value_list<Value, Other...>> {
  44483. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  44484. /*! @brief Unsigned integer type. */
  44485. using value_type = std::size_t;
  44486. /*! @brief Compile-time position of the given value in the sublist. */
  44487. static constexpr value_type value = 0u;
  44488. };
  44489. /**
  44490. * @brief Provides compile-time type access to the values of a value list.
  44491. * @tparam Value Value to look for and for which to return the index.
  44492. */
  44493. template<auto Value>
  44494. struct value_list_index<Value, value_list<>> {
  44495. /*! @brief Unsigned integer type. */
  44496. using value_type = std::size_t;
  44497. /*! @brief Compile-time position of the given type in the sublist. */
  44498. static constexpr value_type value = 0u;
  44499. };
  44500. /**
  44501. * @brief Helper variable template.
  44502. * @tparam List Value list.
  44503. * @tparam Value Value to look for and for which to return the index.
  44504. */
  44505. template<auto Value, typename List>
  44506. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  44507. /**
  44508. * @brief Concatenates multiple value lists.
  44509. * @tparam Value Values provided by the first value list.
  44510. * @tparam Other Values provided by the second value list.
  44511. * @return A value list composed by the values of both the value lists.
  44512. */
  44513. template<auto... Value, auto... Other>
  44514. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  44515. return {};
  44516. }
  44517. /*! @brief Primary template isn't defined on purpose. */
  44518. template<typename...>
  44519. struct value_list_cat;
  44520. /*! @brief Concatenates multiple value lists. */
  44521. template<>
  44522. struct value_list_cat<> {
  44523. /*! @brief A value list composed by the values of all the value lists. */
  44524. using type = value_list<>;
  44525. };
  44526. /**
  44527. * @brief Concatenates multiple value lists.
  44528. * @tparam Value Values provided by the first value list.
  44529. * @tparam Other Values provided by the second value list.
  44530. * @tparam List Other value lists, if any.
  44531. */
  44532. template<auto... Value, auto... Other, typename... List>
  44533. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  44534. /*! @brief A value list composed by the values of all the value lists. */
  44535. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  44536. };
  44537. /**
  44538. * @brief Concatenates multiple value lists.
  44539. * @tparam Value Values provided by the value list.
  44540. */
  44541. template<auto... Value>
  44542. struct value_list_cat<value_list<Value...>> {
  44543. /*! @brief A value list composed by the values of all the value lists. */
  44544. using type = value_list<Value...>;
  44545. };
  44546. /**
  44547. * @brief Helper type.
  44548. * @tparam List Value lists to concatenate.
  44549. */
  44550. template<typename... List>
  44551. using value_list_cat_t = typename value_list_cat<List...>::type;
  44552. /*! @brief Primary template isn't defined on purpose. */
  44553. template<typename>
  44554. struct value_list_unique;
  44555. /**
  44556. * @brief Removes duplicates values from a value list.
  44557. * @tparam Value One of the values provided by the given value list.
  44558. * @tparam Other The other values provided by the given value list.
  44559. */
  44560. template<auto Value, auto... Other>
  44561. struct value_list_unique<value_list<Value, Other...>> {
  44562. /*! @brief A value list without duplicate types. */
  44563. using type = std::conditional_t<
  44564. ((Value == Other) || ...),
  44565. typename value_list_unique<value_list<Other...>>::type,
  44566. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  44567. };
  44568. /*! @brief Removes duplicates values from a value list. */
  44569. template<>
  44570. struct value_list_unique<value_list<>> {
  44571. /*! @brief A value list without duplicate types. */
  44572. using type = value_list<>;
  44573. };
  44574. /**
  44575. * @brief Helper type.
  44576. * @tparam Type A value list.
  44577. */
  44578. template<typename Type>
  44579. using value_list_unique_t = typename value_list_unique<Type>::type;
  44580. /**
  44581. * @brief Provides the member constant `value` to true if a value list contains
  44582. * a given value, false otherwise.
  44583. * @tparam List Value list.
  44584. * @tparam Value Value to look for.
  44585. */
  44586. template<typename List, auto Value>
  44587. struct value_list_contains;
  44588. /**
  44589. * @copybrief value_list_contains
  44590. * @tparam Value Values provided by the value list.
  44591. * @tparam Other Value to look for.
  44592. */
  44593. template<auto... Value, auto Other>
  44594. struct value_list_contains<value_list<Value...>, Other>
  44595. : std::bool_constant<((Value == Other) || ...)> {};
  44596. /**
  44597. * @brief Helper variable template.
  44598. * @tparam List Value list.
  44599. * @tparam Value Value to look for.
  44600. */
  44601. template<typename List, auto Value>
  44602. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  44603. /*! @brief Primary template isn't defined on purpose. */
  44604. template<typename...>
  44605. struct value_list_diff;
  44606. /**
  44607. * @brief Computes the difference between two value lists.
  44608. * @tparam Value Values provided by the first value list.
  44609. * @tparam Other Values provided by the second value list.
  44610. */
  44611. template<auto... Value, auto... Other>
  44612. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  44613. /*! @brief A value list that is the difference between the two value lists. */
  44614. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  44615. };
  44616. /**
  44617. * @brief Helper type.
  44618. * @tparam List Value lists between which to compute the difference.
  44619. */
  44620. template<typename... List>
  44621. using value_list_diff_t = typename value_list_diff<List...>::type;
  44622. /*! @brief Same as std::is_invocable, but with tuples. */
  44623. template<typename, typename>
  44624. struct is_applicable: std::false_type {};
  44625. /**
  44626. * @copybrief is_applicable
  44627. * @tparam Func A valid function type.
  44628. * @tparam Tuple Tuple-like type.
  44629. * @tparam Args The list of arguments to use to probe the function type.
  44630. */
  44631. template<typename Func, template<typename...> class Tuple, typename... Args>
  44632. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  44633. /**
  44634. * @copybrief is_applicable
  44635. * @tparam Func A valid function type.
  44636. * @tparam Tuple Tuple-like type.
  44637. * @tparam Args The list of arguments to use to probe the function type.
  44638. */
  44639. template<typename Func, template<typename...> class Tuple, typename... Args>
  44640. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  44641. /**
  44642. * @brief Helper variable template.
  44643. * @tparam Func A valid function type.
  44644. * @tparam Args The list of arguments to use to probe the function type.
  44645. */
  44646. template<typename Func, typename Args>
  44647. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  44648. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  44649. template<typename, typename, typename>
  44650. struct is_applicable_r: std::false_type {};
  44651. /**
  44652. * @copybrief is_applicable_r
  44653. * @tparam Ret The type to which the return type of the function should be
  44654. * convertible.
  44655. * @tparam Func A valid function type.
  44656. * @tparam Args The list of arguments to use to probe the function type.
  44657. */
  44658. template<typename Ret, typename Func, typename... Args>
  44659. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  44660. /**
  44661. * @brief Helper variable template.
  44662. * @tparam Ret The type to which the return type of the function should be
  44663. * convertible.
  44664. * @tparam Func A valid function type.
  44665. * @tparam Args The list of arguments to use to probe the function type.
  44666. */
  44667. template<typename Ret, typename Func, typename Args>
  44668. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  44669. /**
  44670. * @brief Provides the member constant `value` to true if a given type is
  44671. * complete, false otherwise.
  44672. * @tparam Type The type to test.
  44673. */
  44674. template<typename Type, typename = void>
  44675. struct is_complete: std::false_type {};
  44676. /*! @copydoc is_complete */
  44677. template<typename Type>
  44678. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  44679. /**
  44680. * @brief Helper variable template.
  44681. * @tparam Type The type to test.
  44682. */
  44683. template<typename Type>
  44684. inline constexpr bool is_complete_v = is_complete<Type>::value;
  44685. /**
  44686. * @brief Provides the member constant `value` to true if a given type is an
  44687. * iterator, false otherwise.
  44688. * @tparam Type The type to test.
  44689. */
  44690. template<typename Type, typename = void>
  44691. struct is_iterator: std::false_type {};
  44692. /*! @cond TURN_OFF_DOXYGEN */
  44693. namespace internal {
  44694. template<typename, typename = void>
  44695. struct has_iterator_category: std::false_type {};
  44696. template<typename Type>
  44697. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  44698. } // namespace internal
  44699. /*! @endcond */
  44700. /*! @copydoc is_iterator */
  44701. template<typename Type>
  44702. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  44703. : internal::has_iterator_category<Type> {};
  44704. /**
  44705. * @brief Helper variable template.
  44706. * @tparam Type The type to test.
  44707. */
  44708. template<typename Type>
  44709. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  44710. /**
  44711. * @brief Provides the member constant `value` to true if a given type is both
  44712. * an empty and non-final class, false otherwise.
  44713. * @tparam Type The type to test
  44714. */
  44715. template<typename Type>
  44716. struct is_ebco_eligible
  44717. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  44718. /**
  44719. * @brief Helper variable template.
  44720. * @tparam Type The type to test.
  44721. */
  44722. template<typename Type>
  44723. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  44724. /**
  44725. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  44726. * is valid and denotes a type, false otherwise.
  44727. * @tparam Type The type to test.
  44728. */
  44729. template<typename Type, typename = void>
  44730. struct is_transparent: std::false_type {};
  44731. /*! @copydoc is_transparent */
  44732. template<typename Type>
  44733. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  44734. /**
  44735. * @brief Helper variable template.
  44736. * @tparam Type The type to test.
  44737. */
  44738. template<typename Type>
  44739. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  44740. /*! @cond TURN_OFF_DOXYGEN */
  44741. namespace internal {
  44742. template<typename, typename = void>
  44743. struct has_tuple_size_value: std::false_type {};
  44744. template<typename Type>
  44745. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  44746. template<typename, typename = void>
  44747. struct has_value_type: std::false_type {};
  44748. template<typename Type>
  44749. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  44750. template<typename>
  44751. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  44752. template<typename Type, std::size_t... Index>
  44753. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  44754. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  44755. }
  44756. template<typename>
  44757. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  44758. return false;
  44759. }
  44760. template<typename Type>
  44761. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  44762. return true;
  44763. }
  44764. template<typename Type>
  44765. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  44766. // NOLINTBEGIN(modernize-use-transparent-functors)
  44767. if constexpr(std::is_array_v<Type>) {
  44768. return false;
  44769. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  44770. if constexpr(has_tuple_size_value<Type>::value) {
  44771. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  44772. } else {
  44773. return maybe_equality_comparable<Type>(0);
  44774. }
  44775. } else if constexpr(has_value_type<Type>::value) {
  44776. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  44777. return maybe_equality_comparable<Type>(0);
  44778. } else {
  44779. return false;
  44780. }
  44781. } else {
  44782. return maybe_equality_comparable<Type>(0);
  44783. }
  44784. // NOLINTEND(modernize-use-transparent-functors)
  44785. }
  44786. } // namespace internal
  44787. /*! @endcond */
  44788. /**
  44789. * @brief Provides the member constant `value` to true if a given type is
  44790. * equality comparable, false otherwise.
  44791. * @tparam Type The type to test.
  44792. */
  44793. template<typename Type>
  44794. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  44795. /*! @copydoc is_equality_comparable */
  44796. template<typename Type>
  44797. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  44798. /**
  44799. * @brief Helper variable template.
  44800. * @tparam Type The type to test.
  44801. */
  44802. template<typename Type>
  44803. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  44804. /**
  44805. * @brief Transcribes the constness of a type to another type.
  44806. * @tparam To The type to which to transcribe the constness.
  44807. * @tparam From The type from which to transcribe the constness.
  44808. */
  44809. template<typename To, typename From>
  44810. struct constness_as {
  44811. /*! @brief The type resulting from the transcription of the constness. */
  44812. using type = std::remove_const_t<To>;
  44813. };
  44814. /*! @copydoc constness_as */
  44815. template<typename To, typename From>
  44816. struct constness_as<To, const From> {
  44817. /*! @brief The type resulting from the transcription of the constness. */
  44818. using type = const To;
  44819. };
  44820. /**
  44821. * @brief Alias template to facilitate the transcription of the constness.
  44822. * @tparam To The type to which to transcribe the constness.
  44823. * @tparam From The type from which to transcribe the constness.
  44824. */
  44825. template<typename To, typename From>
  44826. using constness_as_t = typename constness_as<To, From>::type;
  44827. /**
  44828. * @brief Extracts the class of a non-static member object or function.
  44829. * @tparam Member A pointer to a non-static member object or function.
  44830. */
  44831. template<typename Member>
  44832. class member_class {
  44833. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  44834. template<typename Class, typename Ret, typename... Args>
  44835. static Class *clazz(Ret (Class::*)(Args...));
  44836. template<typename Class, typename Ret, typename... Args>
  44837. static Class *clazz(Ret (Class::*)(Args...) const);
  44838. template<typename Class, typename Type>
  44839. static Class *clazz(Type Class::*);
  44840. public:
  44841. /*! @brief The class of the given non-static member object or function. */
  44842. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  44843. };
  44844. /**
  44845. * @brief Helper type.
  44846. * @tparam Member A pointer to a non-static member object or function.
  44847. */
  44848. template<typename Member>
  44849. using member_class_t = typename member_class<Member>::type;
  44850. /**
  44851. * @brief Extracts the n-th argument of a _callable_ type.
  44852. * @tparam Index The index of the argument to extract.
  44853. * @tparam Candidate A valid _callable_ type.
  44854. */
  44855. template<std::size_t Index, typename Candidate>
  44856. class nth_argument {
  44857. template<typename Ret, typename... Args>
  44858. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  44859. template<typename Ret, typename Class, typename... Args>
  44860. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  44861. template<typename Ret, typename Class, typename... Args>
  44862. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  44863. template<typename Type, typename Class>
  44864. static constexpr type_list<Type> pick_up(Type Class ::*);
  44865. template<typename Type>
  44866. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  44867. public:
  44868. /*! @brief N-th argument of the _callable_ type. */
  44869. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  44870. };
  44871. /**
  44872. * @brief Helper type.
  44873. * @tparam Index The index of the argument to extract.
  44874. * @tparam Candidate A valid function, member function or data member type.
  44875. */
  44876. template<std::size_t Index, typename Candidate>
  44877. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  44878. } // namespace entt
  44879. template<typename... Type>
  44880. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  44881. template<std::size_t Index, typename... Type>
  44882. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  44883. template<auto... Value>
  44884. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  44885. template<std::size_t Index, auto... Value>
  44886. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  44887. #endif
  44888. namespace entt {
  44889. /*! @cond TURN_OFF_DOXYGEN */
  44890. namespace internal {
  44891. template<typename Type, std::size_t, typename = void>
  44892. struct compressed_pair_element {
  44893. using reference = Type &;
  44894. using const_reference = const Type &;
  44895. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  44896. // NOLINTNEXTLINE(modernize-use-equals-default)
  44897. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  44898. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  44899. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  44900. : value{std::forward<Arg>(arg)} {}
  44901. template<typename... Args, std::size_t... Index>
  44902. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  44903. : value{std::forward<Args>(std::get<Index>(args))...} {}
  44904. [[nodiscard]] constexpr reference get() noexcept {
  44905. return value;
  44906. }
  44907. [[nodiscard]] constexpr const_reference get() const noexcept {
  44908. return value;
  44909. }
  44910. private:
  44911. Type value{};
  44912. };
  44913. template<typename Type, std::size_t Tag>
  44914. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  44915. using reference = Type &;
  44916. using const_reference = const Type &;
  44917. using base_type = Type;
  44918. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  44919. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  44920. : base_type{} {}
  44921. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  44922. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  44923. : base_type{std::forward<Arg>(arg)} {}
  44924. template<typename... Args, std::size_t... Index>
  44925. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  44926. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  44927. [[nodiscard]] constexpr reference get() noexcept {
  44928. return *this;
  44929. }
  44930. [[nodiscard]] constexpr const_reference get() const noexcept {
  44931. return *this;
  44932. }
  44933. };
  44934. } // namespace internal
  44935. /*! @endcond */
  44936. /**
  44937. * @brief A compressed pair.
  44938. *
  44939. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  44940. * reduce its final size to a minimum.
  44941. *
  44942. * @tparam First The type of the first element that the pair stores.
  44943. * @tparam Second The type of the second element that the pair stores.
  44944. */
  44945. template<typename First, typename Second>
  44946. class compressed_pair final
  44947. : internal::compressed_pair_element<First, 0u>,
  44948. internal::compressed_pair_element<Second, 1u> {
  44949. using first_base = internal::compressed_pair_element<First, 0u>;
  44950. using second_base = internal::compressed_pair_element<Second, 1u>;
  44951. public:
  44952. /*! @brief The type of the first element that the pair stores. */
  44953. using first_type = First;
  44954. /*! @brief The type of the second element that the pair stores. */
  44955. using second_type = Second;
  44956. /**
  44957. * @brief Default constructor, conditionally enabled.
  44958. *
  44959. * This constructor is only available when the types that the pair stores
  44960. * are both at least default constructible.
  44961. *
  44962. * @tparam Dummy Dummy template parameter used for internal purposes.
  44963. */
  44964. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  44965. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  44966. : first_base{},
  44967. second_base{} {}
  44968. /**
  44969. * @brief Copy constructor.
  44970. * @param other The instance to copy from.
  44971. */
  44972. constexpr compressed_pair(const compressed_pair &other) = default;
  44973. /**
  44974. * @brief Move constructor.
  44975. * @param other The instance to move from.
  44976. */
  44977. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  44978. /**
  44979. * @brief Constructs a pair from its values.
  44980. * @tparam Arg Type of value to use to initialize the first element.
  44981. * @tparam Other Type of value to use to initialize the second element.
  44982. * @param arg Value to use to initialize the first element.
  44983. * @param other Value to use to initialize the second element.
  44984. */
  44985. template<typename Arg, typename Other>
  44986. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  44987. : first_base{std::forward<Arg>(arg)},
  44988. second_base{std::forward<Other>(other)} {}
  44989. /**
  44990. * @brief Constructs a pair by forwarding the arguments to its parts.
  44991. * @tparam Args Types of arguments to use to initialize the first element.
  44992. * @tparam Other Types of arguments to use to initialize the second element.
  44993. * @param args Arguments to use to initialize the first element.
  44994. * @param other Arguments to use to initialize the second element.
  44995. */
  44996. template<typename... Args, typename... Other>
  44997. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  44998. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  44999. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  45000. /*! @brief Default destructor. */
  45001. ~compressed_pair() = default;
  45002. /**
  45003. * @brief Copy assignment operator.
  45004. * @param other The instance to copy from.
  45005. * @return This compressed pair object.
  45006. */
  45007. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  45008. /**
  45009. * @brief Move assignment operator.
  45010. * @param other The instance to move from.
  45011. * @return This compressed pair object.
  45012. */
  45013. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  45014. /**
  45015. * @brief Returns the first element that a pair stores.
  45016. * @return The first element that a pair stores.
  45017. */
  45018. [[nodiscard]] constexpr first_type &first() noexcept {
  45019. return static_cast<first_base &>(*this).get();
  45020. }
  45021. /*! @copydoc first */
  45022. [[nodiscard]] constexpr const first_type &first() const noexcept {
  45023. return static_cast<const first_base &>(*this).get();
  45024. }
  45025. /**
  45026. * @brief Returns the second element that a pair stores.
  45027. * @return The second element that a pair stores.
  45028. */
  45029. [[nodiscard]] constexpr second_type &second() noexcept {
  45030. return static_cast<second_base &>(*this).get();
  45031. }
  45032. /*! @copydoc second */
  45033. [[nodiscard]] constexpr const second_type &second() const noexcept {
  45034. return static_cast<const second_base &>(*this).get();
  45035. }
  45036. /**
  45037. * @brief Swaps two compressed pair objects.
  45038. * @param other The compressed pair to swap with.
  45039. */
  45040. constexpr void swap(compressed_pair &other) noexcept {
  45041. using std::swap;
  45042. swap(first(), other.first());
  45043. swap(second(), other.second());
  45044. }
  45045. /**
  45046. * @brief Extracts an element from the compressed pair.
  45047. * @tparam Index An integer value that is either 0 or 1.
  45048. * @return Returns a reference to the first element if `Index` is 0 and a
  45049. * reference to the second element if `Index` is 1.
  45050. */
  45051. template<std::size_t Index>
  45052. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  45053. if constexpr(Index == 0u) {
  45054. return first();
  45055. } else {
  45056. static_assert(Index == 1u, "Index out of bounds");
  45057. return second();
  45058. }
  45059. }
  45060. /*! @copydoc get */
  45061. template<std::size_t Index>
  45062. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  45063. if constexpr(Index == 0u) {
  45064. return first();
  45065. } else {
  45066. static_assert(Index == 1u, "Index out of bounds");
  45067. return second();
  45068. }
  45069. }
  45070. };
  45071. /**
  45072. * @brief Deduction guide.
  45073. * @tparam Type Type of value to use to initialize the first element.
  45074. * @tparam Other Type of value to use to initialize the second element.
  45075. */
  45076. template<typename Type, typename Other>
  45077. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  45078. /**
  45079. * @brief Swaps two compressed pair objects.
  45080. * @tparam First The type of the first element that the pairs store.
  45081. * @tparam Second The type of the second element that the pairs store.
  45082. * @param lhs A valid compressed pair object.
  45083. * @param rhs A valid compressed pair object.
  45084. */
  45085. template<typename First, typename Second>
  45086. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  45087. lhs.swap(rhs);
  45088. }
  45089. } // namespace entt
  45090. namespace std {
  45091. /**
  45092. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  45093. * @tparam First The type of the first element that the pair stores.
  45094. * @tparam Second The type of the second element that the pair stores.
  45095. */
  45096. template<typename First, typename Second>
  45097. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  45098. /**
  45099. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  45100. * @tparam Index The index of the type to return.
  45101. * @tparam First The type of the first element that the pair stores.
  45102. * @tparam Second The type of the second element that the pair stores.
  45103. */
  45104. template<size_t Index, typename First, typename Second>
  45105. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  45106. static_assert(Index < 2u, "Index out of bounds");
  45107. };
  45108. } // namespace std
  45109. #endif
  45110. // #include "../core/fwd.hpp"
  45111. // #include "../core/iterator.hpp"
  45112. // #include "../core/utility.hpp"
  45113. #ifndef ENTT_CORE_UTILITY_HPP
  45114. #define ENTT_CORE_UTILITY_HPP
  45115. #include <type_traits>
  45116. #include <utility>
  45117. namespace entt {
  45118. /*! @brief Identity function object (waiting for C++20). */
  45119. struct identity {
  45120. /*! @brief Indicates that this is a transparent function object. */
  45121. using is_transparent = void;
  45122. /**
  45123. * @brief Returns its argument unchanged.
  45124. * @tparam Type Type of the argument.
  45125. * @param value The actual argument.
  45126. * @return The submitted value as-is.
  45127. */
  45128. template<typename Type>
  45129. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  45130. return std::forward<Type>(value);
  45131. }
  45132. };
  45133. /**
  45134. * @brief Constant utility to disambiguate overloaded members of a class.
  45135. * @tparam Type Type of the desired overload.
  45136. * @tparam Class Type of class to which the member belongs.
  45137. * @param member A valid pointer to a member.
  45138. * @return Pointer to the member.
  45139. */
  45140. template<typename Type, typename Class>
  45141. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  45142. return member;
  45143. }
  45144. /**
  45145. * @brief Constant utility to disambiguate overloaded functions.
  45146. * @tparam Func Function type of the desired overload.
  45147. * @param func A valid pointer to a function.
  45148. * @return Pointer to the function.
  45149. */
  45150. template<typename Func>
  45151. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  45152. return func;
  45153. }
  45154. /**
  45155. * @brief Helper type for visitors.
  45156. * @tparam Func Types of function objects.
  45157. */
  45158. template<typename... Func>
  45159. struct overloaded: Func... {
  45160. using Func::operator()...;
  45161. };
  45162. /**
  45163. * @brief Deduction guide.
  45164. * @tparam Func Types of function objects.
  45165. */
  45166. template<typename... Func>
  45167. overloaded(Func...) -> overloaded<Func...>;
  45168. /**
  45169. * @brief Basic implementation of a y-combinator.
  45170. * @tparam Func Type of a potentially recursive function.
  45171. */
  45172. template<typename Func>
  45173. struct y_combinator {
  45174. /**
  45175. * @brief Constructs a y-combinator from a given function.
  45176. * @param recursive A potentially recursive function.
  45177. */
  45178. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  45179. : func{std::move(recursive)} {}
  45180. /**
  45181. * @brief Invokes a y-combinator and therefore its underlying function.
  45182. * @tparam Args Types of arguments to use to invoke the underlying function.
  45183. * @param args Parameters to use to invoke the underlying function.
  45184. * @return Return value of the underlying function, if any.
  45185. */
  45186. template<typename... Args>
  45187. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  45188. return func(*this, std::forward<Args>(args)...);
  45189. }
  45190. /*! @copydoc operator()() */
  45191. template<typename... Args>
  45192. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  45193. return func(*this, std::forward<Args>(args)...);
  45194. }
  45195. private:
  45196. Func func;
  45197. };
  45198. } // namespace entt
  45199. #endif
  45200. // #include "adjacency_matrix.hpp"
  45201. #ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  45202. #define ENTT_GRAPH_ADJACENCY_MATRIX_HPP
  45203. #include <cstddef>
  45204. #include <iterator>
  45205. #include <memory>
  45206. #include <type_traits>
  45207. #include <utility>
  45208. #include <vector>
  45209. // #include "../config/config.h"
  45210. // #include "../core/iterator.hpp"
  45211. // #include "fwd.hpp"
  45212. namespace entt {
  45213. /*! @cond TURN_OFF_DOXYGEN */
  45214. namespace internal {
  45215. template<typename It>
  45216. class edge_iterator {
  45217. using size_type = std::size_t;
  45218. void find_next() noexcept {
  45219. for(; pos != last && !it[static_cast<typename It::difference_type>(pos)]; pos += offset) {}
  45220. }
  45221. public:
  45222. using value_type = std::pair<size_type, size_type>;
  45223. using pointer = input_iterator_pointer<value_type>;
  45224. using reference = value_type;
  45225. using difference_type = std::ptrdiff_t;
  45226. using iterator_category = std::input_iterator_tag;
  45227. using iterator_concept = std::forward_iterator_tag;
  45228. constexpr edge_iterator() noexcept = default;
  45229. // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
  45230. constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept
  45231. : it{std::move(base)},
  45232. vert{vertices},
  45233. pos{from},
  45234. last{to},
  45235. offset{step} {
  45236. find_next();
  45237. }
  45238. constexpr edge_iterator &operator++() noexcept {
  45239. pos += offset;
  45240. find_next();
  45241. return *this;
  45242. }
  45243. constexpr edge_iterator operator++(int) noexcept {
  45244. const edge_iterator orig = *this;
  45245. return ++(*this), orig;
  45246. }
  45247. [[nodiscard]] constexpr reference operator*() const noexcept {
  45248. return *operator->();
  45249. }
  45250. [[nodiscard]] constexpr pointer operator->() const noexcept {
  45251. return std::make_pair<size_type>(pos / vert, pos % vert);
  45252. }
  45253. template<typename Type>
  45254. friend constexpr bool operator==(const edge_iterator<Type> &, const edge_iterator<Type> &) noexcept;
  45255. private:
  45256. It it{};
  45257. size_type vert{};
  45258. size_type pos{};
  45259. size_type last{};
  45260. size_type offset{};
  45261. };
  45262. template<typename Container>
  45263. [[nodiscard]] constexpr bool operator==(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  45264. return lhs.pos == rhs.pos;
  45265. }
  45266. template<typename Container>
  45267. [[nodiscard]] constexpr bool operator!=(const edge_iterator<Container> &lhs, const edge_iterator<Container> &rhs) noexcept {
  45268. return !(lhs == rhs);
  45269. }
  45270. } // namespace internal
  45271. /*! @endcond */
  45272. /**
  45273. * @brief Basic implementation of a directed adjacency matrix.
  45274. * @tparam Category Either a directed or undirected category tag.
  45275. * @tparam Allocator Type of allocator used to manage memory and elements.
  45276. */
  45277. template<typename Category, typename Allocator>
  45278. class adjacency_matrix {
  45279. using alloc_traits = std::allocator_traits<Allocator>;
  45280. static_assert(std::is_base_of_v<directed_tag, Category>, "Invalid graph category");
  45281. static_assert(std::is_same_v<typename alloc_traits::value_type, std::size_t>, "Invalid value type");
  45282. using container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  45283. public:
  45284. /*! @brief Allocator type. */
  45285. using allocator_type = Allocator;
  45286. /*! @brief Unsigned integer type. */
  45287. using size_type = std::size_t;
  45288. /*! @brief Vertex type. */
  45289. using vertex_type = size_type;
  45290. /*! @brief Edge type. */
  45291. using edge_type = std::pair<vertex_type, vertex_type>;
  45292. /*! @brief Vertex iterator type. */
  45293. using vertex_iterator = iota_iterator<vertex_type>;
  45294. /*! @brief Edge iterator type. */
  45295. using edge_iterator = internal::edge_iterator<typename container_type::const_iterator>;
  45296. /*! @brief Out-edge iterator type. */
  45297. using out_edge_iterator = edge_iterator;
  45298. /*! @brief In-edge iterator type. */
  45299. using in_edge_iterator = edge_iterator;
  45300. /*! @brief Graph category tag. */
  45301. using graph_category = Category;
  45302. /*! @brief Default constructor. */
  45303. adjacency_matrix() noexcept(noexcept(allocator_type{}))
  45304. : adjacency_matrix{0u} {
  45305. }
  45306. /**
  45307. * @brief Constructs an empty container with a given allocator.
  45308. * @param allocator The allocator to use.
  45309. */
  45310. explicit adjacency_matrix(const allocator_type &allocator) noexcept
  45311. : adjacency_matrix{0u, allocator} {}
  45312. /**
  45313. * @brief Constructs an empty container with a given allocator and user
  45314. * supplied number of vertices.
  45315. * @param vertices Number of vertices.
  45316. * @param allocator The allocator to use.
  45317. */
  45318. adjacency_matrix(const size_type vertices, const allocator_type &allocator = allocator_type{})
  45319. : matrix{vertices * vertices, allocator},
  45320. vert{vertices} {}
  45321. /*! @brief Default copy constructor. */
  45322. adjacency_matrix(const adjacency_matrix &) = default;
  45323. /**
  45324. * @brief Allocator-extended copy constructor.
  45325. * @param other The instance to copy from.
  45326. * @param allocator The allocator to use.
  45327. */
  45328. adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator)
  45329. : matrix{other.matrix, allocator},
  45330. vert{other.vert} {}
  45331. /*! @brief Default move constructor. */
  45332. adjacency_matrix(adjacency_matrix &&) noexcept = default;
  45333. /**
  45334. * @brief Allocator-extended move constructor.
  45335. * @param other The instance to move from.
  45336. * @param allocator The allocator to use.
  45337. */
  45338. adjacency_matrix(adjacency_matrix &&other, const allocator_type &allocator)
  45339. : matrix{std::move(other.matrix), allocator},
  45340. vert{other.vert} {}
  45341. /*! @brief Default destructor. */
  45342. ~adjacency_matrix() = default;
  45343. /**
  45344. * @brief Default copy assignment operator.
  45345. * @return This container.
  45346. */
  45347. adjacency_matrix &operator=(const adjacency_matrix &) = default;
  45348. /**
  45349. * @brief Default move assignment operator.
  45350. * @return This container.
  45351. */
  45352. adjacency_matrix &operator=(adjacency_matrix &&) noexcept = default;
  45353. /**
  45354. * @brief Exchanges the contents with those of a given adjacency matrix.
  45355. * @param other Adjacency matrix to exchange the content with.
  45356. */
  45357. void swap(adjacency_matrix &other) noexcept {
  45358. using std::swap;
  45359. swap(matrix, other.matrix);
  45360. swap(vert, other.vert);
  45361. }
  45362. /**
  45363. * @brief Returns the associated allocator.
  45364. * @return The associated allocator.
  45365. */
  45366. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  45367. return matrix.get_allocator();
  45368. }
  45369. /*! @brief Clears the adjacency matrix. */
  45370. void clear() noexcept {
  45371. matrix.clear();
  45372. vert = {};
  45373. }
  45374. /**
  45375. * @brief Returns true if an adjacency matrix is empty, false otherwise.
  45376. *
  45377. * @warning
  45378. * Potentially expensive, try to avoid it on hot paths.
  45379. *
  45380. * @return True if the adjacency matrix is empty, false otherwise.
  45381. */
  45382. [[nodiscard]] bool empty() const noexcept {
  45383. const auto iterable = edges();
  45384. return (iterable.begin() == iterable.end());
  45385. }
  45386. /**
  45387. * @brief Returns the number of vertices.
  45388. * @return The number of vertices.
  45389. */
  45390. [[nodiscard]] size_type size() const noexcept {
  45391. return vert;
  45392. }
  45393. /**
  45394. * @brief Returns an iterable object to visit all vertices of a matrix.
  45395. * @return An iterable object to visit all vertices of a matrix.
  45396. */
  45397. [[nodiscard]] iterable_adaptor<vertex_iterator> vertices() const noexcept {
  45398. return {0u, vert};
  45399. }
  45400. /**
  45401. * @brief Returns an iterable object to visit all edges of a matrix.
  45402. * @return An iterable object to visit all edges of a matrix.
  45403. */
  45404. [[nodiscard]] iterable_adaptor<edge_iterator> edges() const noexcept {
  45405. const auto it = matrix.cbegin();
  45406. const auto sz = matrix.size();
  45407. return {{it, vert, 0u, sz, 1u}, {it, vert, sz, sz, 1u}};
  45408. }
  45409. /**
  45410. * @brief Returns an iterable object to visit all out-edges of a vertex.
  45411. * @param vertex The vertex of which to return all out-edges.
  45412. * @return An iterable object to visit all out-edges of a vertex.
  45413. */
  45414. [[nodiscard]] iterable_adaptor<out_edge_iterator> out_edges(const vertex_type vertex) const noexcept {
  45415. const auto it = matrix.cbegin();
  45416. const auto from = vertex * vert;
  45417. const auto to = from + vert;
  45418. return {{it, vert, from, to, 1u}, {it, vert, to, to, 1u}};
  45419. }
  45420. /**
  45421. * @brief Returns an iterable object to visit all in-edges of a vertex.
  45422. * @param vertex The vertex of which to return all in-edges.
  45423. * @return An iterable object to visit all in-edges of a vertex.
  45424. */
  45425. [[nodiscard]] iterable_adaptor<in_edge_iterator> in_edges(const vertex_type vertex) const noexcept {
  45426. const auto it = matrix.cbegin();
  45427. const auto from = vertex;
  45428. const auto to = vert * vert + from;
  45429. return {{it, vert, from, to, vert}, {it, vert, to, to, vert}};
  45430. }
  45431. /**
  45432. * @brief Resizes an adjacency matrix.
  45433. * @param vertices The new number of vertices.
  45434. */
  45435. void resize(const size_type vertices) {
  45436. adjacency_matrix other{vertices, get_allocator()};
  45437. for(auto [lhs, rhs]: edges()) {
  45438. other.insert(lhs, rhs);
  45439. }
  45440. other.swap(*this);
  45441. }
  45442. /**
  45443. * @brief Inserts an edge into the adjacency matrix, if it does not exist.
  45444. * @param lhs The left hand vertex of the edge.
  45445. * @param rhs The right hand vertex of the edge.
  45446. * @return A pair consisting of an iterator to the inserted element (or to
  45447. * the element that prevented the insertion) and a bool denoting whether the
  45448. * insertion took place.
  45449. */
  45450. std::pair<edge_iterator, bool> insert(const vertex_type lhs, const vertex_type rhs) {
  45451. const auto pos = lhs * vert + rhs;
  45452. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  45453. const auto rev = rhs * vert + lhs;
  45454. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  45455. matrix[rev] = 1u;
  45456. }
  45457. const auto inserted = !std::exchange(matrix[pos], 1u);
  45458. return {edge_iterator{matrix.cbegin(), vert, pos, matrix.size(), 1u}, inserted};
  45459. }
  45460. /**
  45461. * @brief Removes the edge associated with a pair of given vertices.
  45462. * @param lhs The left hand vertex of the edge.
  45463. * @param rhs The right hand vertex of the edge.
  45464. * @return Number of elements removed (either 0 or 1).
  45465. */
  45466. size_type erase(const vertex_type lhs, const vertex_type rhs) {
  45467. const auto pos = lhs * vert + rhs;
  45468. if constexpr(std::is_same_v<graph_category, undirected_tag>) {
  45469. const auto rev = rhs * vert + lhs;
  45470. ENTT_ASSERT(matrix[pos] == matrix[rev], "Something went really wrong");
  45471. matrix[rev] = 0u;
  45472. }
  45473. return std::exchange(matrix[pos], 0u);
  45474. }
  45475. /**
  45476. * @brief Checks if an adjacency matrix contains a given edge.
  45477. * @param lhs The left hand vertex of the edge.
  45478. * @param rhs The right hand vertex of the edge.
  45479. * @return True if there is such an edge, false otherwise.
  45480. */
  45481. [[nodiscard]] bool contains(const vertex_type lhs, const vertex_type rhs) const {
  45482. const auto pos = lhs * vert + rhs;
  45483. return pos < matrix.size() && matrix[pos];
  45484. }
  45485. private:
  45486. container_type matrix;
  45487. size_type vert;
  45488. };
  45489. } // namespace entt
  45490. #endif
  45491. // #include "fwd.hpp"
  45492. namespace entt {
  45493. /**
  45494. * @brief Utility class for creating task graphs.
  45495. * @tparam Allocator Type of allocator used to manage memory and elements.
  45496. */
  45497. template<typename Allocator>
  45498. class basic_flow {
  45499. using alloc_traits = std::allocator_traits<Allocator>;
  45500. static_assert(std::is_same_v<typename alloc_traits::value_type, id_type>, "Invalid value type");
  45501. using task_container_type = dense_set<id_type, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc<id_type>>;
  45502. using ro_rw_container_type = std::vector<std::pair<std::size_t, bool>, typename alloc_traits::template rebind_alloc<std::pair<std::size_t, bool>>>;
  45503. using deps_container_type = dense_map<id_type, ro_rw_container_type, identity, std::equal_to<>, typename alloc_traits::template rebind_alloc<std::pair<const id_type, ro_rw_container_type>>>;
  45504. using adjacency_matrix_type = adjacency_matrix<directed_tag, typename alloc_traits::template rebind_alloc<std::size_t>>;
  45505. void emplace(const id_type res, const bool is_rw) {
  45506. ENTT_ASSERT(index.first() < vertices.size(), "Invalid node");
  45507. if(!deps.contains(res) && sync_on != vertices.size()) {
  45508. deps[res].emplace_back(sync_on, true);
  45509. }
  45510. deps[res].emplace_back(index.first(), is_rw);
  45511. }
  45512. void setup_graph(adjacency_matrix_type &matrix) const {
  45513. for(const auto &elem: deps) {
  45514. const auto last = elem.second.cend();
  45515. auto it = elem.second.cbegin();
  45516. while(it != last) {
  45517. if(it->second) {
  45518. // rw item
  45519. if(auto curr = it++; it != last) {
  45520. if(it->second) {
  45521. matrix.insert(curr->first, it->first);
  45522. } else if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) {
  45523. for(; it != next; ++it) {
  45524. matrix.insert(curr->first, it->first);
  45525. matrix.insert(it->first, next->first);
  45526. }
  45527. } else {
  45528. for(; it != next; ++it) {
  45529. matrix.insert(curr->first, it->first);
  45530. }
  45531. }
  45532. }
  45533. } else {
  45534. // ro item (first iteration only)
  45535. if(const auto next = std::find_if(it, last, [](const auto &value) { return value.second; }); next != last) {
  45536. for(; it != next; ++it) {
  45537. matrix.insert(it->first, next->first);
  45538. }
  45539. } else {
  45540. it = last;
  45541. }
  45542. }
  45543. }
  45544. }
  45545. }
  45546. void transitive_closure(adjacency_matrix_type &matrix) const {
  45547. const auto length = matrix.size();
  45548. for(std::size_t vk{}; vk < length; ++vk) {
  45549. for(std::size_t vi{}; vi < length; ++vi) {
  45550. for(std::size_t vj{}; vj < length; ++vj) {
  45551. if(matrix.contains(vi, vk) && matrix.contains(vk, vj)) {
  45552. matrix.insert(vi, vj);
  45553. }
  45554. }
  45555. }
  45556. }
  45557. }
  45558. void transitive_reduction(adjacency_matrix_type &matrix) const {
  45559. const auto length = matrix.size();
  45560. for(std::size_t vert{}; vert < length; ++vert) {
  45561. matrix.erase(vert, vert);
  45562. }
  45563. for(std::size_t vj{}; vj < length; ++vj) {
  45564. for(std::size_t vi{}; vi < length; ++vi) {
  45565. if(matrix.contains(vi, vj)) {
  45566. for(std::size_t vk{}; vk < length; ++vk) {
  45567. if(matrix.contains(vj, vk)) {
  45568. matrix.erase(vi, vk);
  45569. }
  45570. }
  45571. }
  45572. }
  45573. }
  45574. }
  45575. public:
  45576. /*! @brief Allocator type. */
  45577. using allocator_type = Allocator;
  45578. /*! @brief Unsigned integer type. */
  45579. using size_type = std::size_t;
  45580. /*! @brief Iterable task list. */
  45581. using iterable = iterable_adaptor<typename task_container_type::const_iterator>;
  45582. /*! @brief Adjacency matrix type. */
  45583. using graph_type = adjacency_matrix_type;
  45584. /*! @brief Default constructor. */
  45585. basic_flow()
  45586. : basic_flow{allocator_type{}} {}
  45587. /**
  45588. * @brief Constructs a flow builder with a given allocator.
  45589. * @param allocator The allocator to use.
  45590. */
  45591. explicit basic_flow(const allocator_type &allocator)
  45592. : index{0u, allocator},
  45593. vertices{allocator},
  45594. deps{allocator} {}
  45595. /*! @brief Default copy constructor. */
  45596. basic_flow(const basic_flow &) = default;
  45597. /**
  45598. * @brief Allocator-extended copy constructor.
  45599. * @param other The instance to copy from.
  45600. * @param allocator The allocator to use.
  45601. */
  45602. basic_flow(const basic_flow &other, const allocator_type &allocator)
  45603. : index{other.index.first(), allocator},
  45604. vertices{other.vertices, allocator},
  45605. deps{other.deps, allocator},
  45606. sync_on{other.sync_on} {}
  45607. /*! @brief Default move constructor. */
  45608. basic_flow(basic_flow &&) noexcept = default;
  45609. /**
  45610. * @brief Allocator-extended move constructor.
  45611. * @param other The instance to move from.
  45612. * @param allocator The allocator to use.
  45613. */
  45614. basic_flow(basic_flow &&other, const allocator_type &allocator)
  45615. : index{other.index.first(), allocator},
  45616. vertices{std::move(other.vertices), allocator},
  45617. deps{std::move(other.deps), allocator},
  45618. sync_on{other.sync_on} {}
  45619. /*! @brief Default destructor. */
  45620. ~basic_flow() = default;
  45621. /**
  45622. * @brief Default copy assignment operator.
  45623. * @return This flow builder.
  45624. */
  45625. basic_flow &operator=(const basic_flow &) = default;
  45626. /**
  45627. * @brief Default move assignment operator.
  45628. * @return This flow builder.
  45629. */
  45630. basic_flow &operator=(basic_flow &&) noexcept = default;
  45631. /**
  45632. * @brief Exchanges the contents with those of a given flow builder.
  45633. * @param other Flow builder to exchange the content with.
  45634. */
  45635. void swap(basic_flow &other) noexcept {
  45636. using std::swap;
  45637. std::swap(index, other.index);
  45638. std::swap(vertices, other.vertices);
  45639. std::swap(deps, other.deps);
  45640. std::swap(sync_on, other.sync_on);
  45641. }
  45642. /**
  45643. * @brief Returns the associated allocator.
  45644. * @return The associated allocator.
  45645. */
  45646. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  45647. return allocator_type{index.second()};
  45648. }
  45649. /**
  45650. * @brief Returns the identifier at specified location.
  45651. * @param pos Position of the identifier to return.
  45652. * @return The requested identifier.
  45653. */
  45654. [[nodiscard]] id_type operator[](const size_type pos) const {
  45655. return vertices.cbegin()[static_cast<typename task_container_type::difference_type>(pos)];
  45656. }
  45657. /*! @brief Clears the flow builder. */
  45658. void clear() noexcept {
  45659. index.first() = {};
  45660. vertices.clear();
  45661. deps.clear();
  45662. sync_on = {};
  45663. }
  45664. /**
  45665. * @brief Returns true if a flow builder contains no tasks, false otherwise.
  45666. * @return True if the flow builder contains no tasks, false otherwise.
  45667. */
  45668. [[nodiscard]] bool empty() const noexcept {
  45669. return vertices.empty();
  45670. }
  45671. /**
  45672. * @brief Returns the number of tasks.
  45673. * @return The number of tasks.
  45674. */
  45675. [[nodiscard]] size_type size() const noexcept {
  45676. return vertices.size();
  45677. }
  45678. /**
  45679. * @brief Binds a task to a flow builder.
  45680. * @param value Task identifier.
  45681. * @return This flow builder.
  45682. */
  45683. basic_flow &bind(const id_type value) {
  45684. sync_on += (sync_on == vertices.size());
  45685. const auto it = vertices.emplace(value).first;
  45686. index.first() = size_type(it - vertices.begin());
  45687. return *this;
  45688. }
  45689. /**
  45690. * @brief Turns the current task into a sync point.
  45691. * @return This flow builder.
  45692. */
  45693. basic_flow &sync() {
  45694. ENTT_ASSERT(index.first() < vertices.size(), "Invalid node");
  45695. sync_on = index.first();
  45696. for(const auto &elem: deps) {
  45697. elem.second.emplace_back(sync_on, true);
  45698. }
  45699. return *this;
  45700. }
  45701. /**
  45702. * @brief Assigns a resource to the current task with a given access mode.
  45703. * @param res Resource identifier.
  45704. * @param is_rw Access mode.
  45705. * @return This flow builder.
  45706. */
  45707. basic_flow &set(const id_type res, bool is_rw = false) {
  45708. emplace(res, is_rw);
  45709. return *this;
  45710. }
  45711. /**
  45712. * @brief Assigns a read-only resource to the current task.
  45713. * @param res Resource identifier.
  45714. * @return This flow builder.
  45715. */
  45716. basic_flow &ro(const id_type res) {
  45717. emplace(res, false);
  45718. return *this;
  45719. }
  45720. /**
  45721. * @brief Assigns a range of read-only resources to the current task.
  45722. * @tparam It Type of input iterator.
  45723. * @param first An iterator to the first element of the range of elements.
  45724. * @param last An iterator past the last element of the range of elements.
  45725. * @return This flow builder.
  45726. */
  45727. template<typename It>
  45728. std::enable_if_t<std::is_same_v<std::remove_const_t<typename std::iterator_traits<It>::value_type>, id_type>, basic_flow &>
  45729. ro(It first, It last) {
  45730. for(; first != last; ++first) {
  45731. emplace(*first, false);
  45732. }
  45733. return *this;
  45734. }
  45735. /**
  45736. * @brief Assigns a writable resource to the current task.
  45737. * @param res Resource identifier.
  45738. * @return This flow builder.
  45739. */
  45740. basic_flow &rw(const id_type res) {
  45741. emplace(res, true);
  45742. return *this;
  45743. }
  45744. /**
  45745. * @brief Assigns a range of writable resources to the current task.
  45746. * @tparam It Type of input iterator.
  45747. * @param first An iterator to the first element of the range of elements.
  45748. * @param last An iterator past the last element of the range of elements.
  45749. * @return This flow builder.
  45750. */
  45751. template<typename It>
  45752. std::enable_if_t<std::is_same_v<std::remove_const_t<typename std::iterator_traits<It>::value_type>, id_type>, basic_flow &>
  45753. rw(It first, It last) {
  45754. for(; first != last; ++first) {
  45755. emplace(*first, true);
  45756. }
  45757. return *this;
  45758. }
  45759. /**
  45760. * @brief Generates a task graph for the current content.
  45761. * @return The adjacency matrix of the task graph.
  45762. */
  45763. [[nodiscard]] graph_type graph() const {
  45764. graph_type matrix{vertices.size(), get_allocator()};
  45765. setup_graph(matrix);
  45766. transitive_closure(matrix);
  45767. transitive_reduction(matrix);
  45768. return matrix;
  45769. }
  45770. private:
  45771. compressed_pair<size_type, allocator_type> index;
  45772. task_container_type vertices;
  45773. deps_container_type deps;
  45774. size_type sync_on{};
  45775. };
  45776. } // namespace entt
  45777. #endif
  45778. // #include "locator/locator.hpp"
  45779. #ifndef ENTT_LOCATOR_LOCATOR_HPP
  45780. #define ENTT_LOCATOR_LOCATOR_HPP
  45781. #include <memory>
  45782. #include <utility>
  45783. // #include "../config/config.h"
  45784. #ifndef ENTT_CONFIG_CONFIG_H
  45785. #define ENTT_CONFIG_CONFIG_H
  45786. // #include "version.h"
  45787. #ifndef ENTT_CONFIG_VERSION_H
  45788. #define ENTT_CONFIG_VERSION_H
  45789. // #include "macro.h"
  45790. #ifndef ENTT_CONFIG_MACRO_H
  45791. #define ENTT_CONFIG_MACRO_H
  45792. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  45793. #define ENTT_STR(arg) #arg
  45794. #define ENTT_XSTR(arg) ENTT_STR(arg)
  45795. // NOLINTEND(cppcoreguidelines-macro-usage)
  45796. #endif
  45797. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  45798. #define ENTT_VERSION_MAJOR 3
  45799. #define ENTT_VERSION_MINOR 16
  45800. #define ENTT_VERSION_PATCH 0
  45801. #define ENTT_VERSION \
  45802. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  45803. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  45804. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  45805. #endif
  45806. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  45807. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  45808. # define ENTT_CONSTEXPR
  45809. # define ENTT_THROW throw
  45810. # define ENTT_TRY try
  45811. # define ENTT_CATCH catch(...)
  45812. #else
  45813. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  45814. # define ENTT_THROW
  45815. # define ENTT_TRY if(true)
  45816. # define ENTT_CATCH if(false)
  45817. #endif
  45818. #if __has_include(<version>)
  45819. # include <version>
  45820. #
  45821. # if defined(__cpp_consteval)
  45822. # define ENTT_CONSTEVAL consteval
  45823. # endif
  45824. #endif
  45825. #ifndef ENTT_CONSTEVAL
  45826. # define ENTT_CONSTEVAL constexpr
  45827. #endif
  45828. #ifdef ENTT_USE_ATOMIC
  45829. # include <atomic>
  45830. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  45831. #else
  45832. # define ENTT_MAYBE_ATOMIC(Type) Type
  45833. #endif
  45834. #ifndef ENTT_ID_TYPE
  45835. # include <cstdint>
  45836. # define ENTT_ID_TYPE std::uint32_t
  45837. #else
  45838. # include <cstdint> // provides coverage for types in the std namespace
  45839. #endif
  45840. #ifndef ENTT_SPARSE_PAGE
  45841. # define ENTT_SPARSE_PAGE 4096
  45842. #endif
  45843. #ifndef ENTT_PACKED_PAGE
  45844. # define ENTT_PACKED_PAGE 1024
  45845. #endif
  45846. #ifdef ENTT_DISABLE_ASSERT
  45847. # undef ENTT_ASSERT
  45848. # define ENTT_ASSERT(condition, msg) (void(0))
  45849. #elif !defined ENTT_ASSERT
  45850. # include <cassert>
  45851. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  45852. #endif
  45853. #ifdef ENTT_DISABLE_ASSERT
  45854. # undef ENTT_ASSERT_CONSTEXPR
  45855. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  45856. #elif !defined ENTT_ASSERT_CONSTEXPR
  45857. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  45858. #endif
  45859. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  45860. #ifdef ENTT_NO_ETO
  45861. # define ENTT_ETO_TYPE(Type) void
  45862. #else
  45863. # define ENTT_ETO_TYPE(Type) Type
  45864. #endif
  45865. #ifdef ENTT_NO_MIXIN
  45866. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  45867. #else
  45868. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  45869. #endif
  45870. #ifdef ENTT_STANDARD_CPP
  45871. # define ENTT_NONSTD false
  45872. #else
  45873. # define ENTT_NONSTD true
  45874. # if defined __clang__ || defined __GNUC__
  45875. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  45876. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  45877. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  45878. # elif defined _MSC_VER
  45879. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  45880. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  45881. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  45882. # endif
  45883. #endif
  45884. #ifndef ENTT_EXPORT
  45885. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  45886. # define ENTT_EXPORT __declspec(dllexport)
  45887. # define ENTT_IMPORT __declspec(dllimport)
  45888. # define ENTT_HIDDEN
  45889. # elif defined __GNUC__ && __GNUC__ >= 4
  45890. # define ENTT_EXPORT __attribute__((visibility("default")))
  45891. # define ENTT_IMPORT __attribute__((visibility("default")))
  45892. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  45893. # else /* Unsupported compiler */
  45894. # define ENTT_EXPORT
  45895. # define ENTT_IMPORT
  45896. # define ENTT_HIDDEN
  45897. # endif
  45898. #endif
  45899. #ifndef ENTT_API
  45900. # if defined ENTT_API_EXPORT
  45901. # define ENTT_API ENTT_EXPORT
  45902. # elif defined ENTT_API_IMPORT
  45903. # define ENTT_API ENTT_IMPORT
  45904. # else /* No API */
  45905. # define ENTT_API
  45906. # endif
  45907. #endif
  45908. #if defined _MSC_VER
  45909. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  45910. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  45911. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  45912. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  45913. #endif
  45914. // NOLINTEND(cppcoreguidelines-macro-usage)
  45915. #endif
  45916. namespace entt {
  45917. /**
  45918. * @brief Service locator, nothing more.
  45919. *
  45920. * A service locator is used to do what it promises: locate services.<br/>
  45921. * Usually service locators are tightly bound to the services they expose and
  45922. * thus it's hard to define a general purpose class to do that. This tiny class
  45923. * tries to fill the gap and to get rid of the burden of defining a different
  45924. * specific locator for each application.
  45925. *
  45926. * @note
  45927. * Users shouldn't retain references to a service. The recommended way is to
  45928. * retrieve the service implementation currently set each and every time the
  45929. * need for it arises. The risk is to incur in unexpected behaviors otherwise.
  45930. *
  45931. * @tparam Service Service type.
  45932. */
  45933. template<typename Service>
  45934. class locator final {
  45935. class service_handle {
  45936. friend class locator<Service>;
  45937. std::shared_ptr<Service> value{};
  45938. };
  45939. public:
  45940. /*! @brief Service type. */
  45941. using type = Service;
  45942. /*! @brief Service node type. */
  45943. using node_type = service_handle;
  45944. /*! @brief Default constructor, deleted on purpose. */
  45945. locator() = delete;
  45946. /*! @brief Default copy constructor, deleted on purpose. */
  45947. locator(const locator &) = delete;
  45948. /*! @brief Default destructor, deleted on purpose. */
  45949. ~locator() = delete;
  45950. /**
  45951. * @brief Default copy assignment operator, deleted on purpose.
  45952. * @return This locator.
  45953. */
  45954. locator &operator=(const locator &) = delete;
  45955. /**
  45956. * @brief Checks whether a service locator contains a value.
  45957. * @return True if the service locator contains a value, false otherwise.
  45958. */
  45959. [[nodiscard]] static bool has_value() noexcept {
  45960. return (service != nullptr);
  45961. }
  45962. /**
  45963. * @brief Returns a reference to a valid service, if any.
  45964. *
  45965. * @warning
  45966. * Invoking this function can result in undefined behavior if the service
  45967. * hasn't been set yet.
  45968. *
  45969. * @return A reference to the service currently set, if any.
  45970. */
  45971. [[nodiscard]] static Service &value() noexcept {
  45972. ENTT_ASSERT(has_value(), "Service not available");
  45973. return *service;
  45974. }
  45975. /**
  45976. * @brief Returns a service if available or sets it from a fallback type.
  45977. *
  45978. * Arguments are used only if a service doesn't already exist. In all other
  45979. * cases, they are discarded.
  45980. *
  45981. * @tparam Args Types of arguments to use to construct the fallback service.
  45982. * @tparam Type Fallback service type.
  45983. * @param args Parameters to use to construct the fallback service.
  45984. * @return A reference to a valid service.
  45985. */
  45986. template<typename Type = Service, typename... Args>
  45987. [[nodiscard]] static Service &value_or(Args &&...args) {
  45988. return service ? *service : emplace<Type>(std::forward<Args>(args)...);
  45989. }
  45990. /**
  45991. * @brief Sets or replaces a service.
  45992. * @tparam Type Service type.
  45993. * @tparam Args Types of arguments to use to construct the service.
  45994. * @param args Parameters to use to construct the service.
  45995. * @return A reference to a valid service.
  45996. */
  45997. template<typename Type = Service, typename... Args>
  45998. static Service &emplace(Args &&...args) {
  45999. service = std::make_shared<Type>(std::forward<Args>(args)...);
  46000. return *service;
  46001. }
  46002. /**
  46003. * @brief Sets or replaces a service using a given allocator.
  46004. * @tparam Type Service type.
  46005. * @tparam Allocator Type of allocator used to manage memory and elements.
  46006. * @tparam Args Types of arguments to use to construct the service.
  46007. * @param alloc The allocator to use.
  46008. * @param args Parameters to use to construct the service.
  46009. * @return A reference to a valid service.
  46010. */
  46011. template<typename Type = Service, typename Allocator, typename... Args>
  46012. static Service &emplace(std::allocator_arg_t, Allocator alloc, Args &&...args) {
  46013. service = std::allocate_shared<Type>(alloc, std::forward<Args>(args)...);
  46014. return *service;
  46015. }
  46016. /**
  46017. * @brief Returns a handle to the underlying service.
  46018. * @return A handle to the underlying service.
  46019. */
  46020. static node_type handle() noexcept {
  46021. node_type node{};
  46022. node.value = service;
  46023. return node;
  46024. }
  46025. /**
  46026. * @brief Resets or replaces a service.
  46027. * @param other Optional handle with which to replace the service.
  46028. */
  46029. static void reset(const node_type &other = {}) noexcept {
  46030. service = other.value;
  46031. }
  46032. /**
  46033. * @brief Resets or replaces a service.
  46034. * @tparam Type Service type.
  46035. * @tparam Deleter Deleter type.
  46036. * @param elem A pointer to a service to manage.
  46037. * @param deleter A deleter to use to destroy the service.
  46038. */
  46039. template<typename Type, typename Deleter = std::default_delete<Type>>
  46040. static void reset(Type *elem, Deleter deleter = {}) {
  46041. service = std::shared_ptr<Service>{elem, std::move(deleter)};
  46042. }
  46043. private:
  46044. // std::shared_ptr because of its type erased allocator which is useful here
  46045. // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  46046. inline static std::shared_ptr<Service> service{};
  46047. };
  46048. } // namespace entt
  46049. #endif
  46050. // #include "meta/adl_pointer.hpp"
  46051. #ifndef ENTT_META_ADL_POINTER_HPP
  46052. #define ENTT_META_ADL_POINTER_HPP
  46053. namespace entt {
  46054. /**
  46055. * @brief ADL based lookup function for dereferencing meta pointer-like types.
  46056. * @tparam Type Element type.
  46057. * @param value A pointer-like object.
  46058. * @return The value returned from the dereferenced pointer.
  46059. */
  46060. template<typename Type>
  46061. decltype(auto) dereference_meta_pointer_like(const Type &value) {
  46062. return *value;
  46063. }
  46064. /**
  46065. * @brief Fake ADL based lookup function for meta pointer-like types.
  46066. * @tparam Type Element type.
  46067. */
  46068. template<typename Type>
  46069. struct adl_meta_pointer_like {
  46070. /**
  46071. * @brief Uses the default ADL based lookup method to resolve the call.
  46072. * @param value A pointer-like object.
  46073. * @return The value returned from the dereferenced pointer.
  46074. */
  46075. static decltype(auto) dereference(const Type &value) {
  46076. return dereference_meta_pointer_like(value);
  46077. }
  46078. };
  46079. } // namespace entt
  46080. #endif
  46081. // #include "meta/container.hpp"
  46082. // IWYU pragma: always_keep
  46083. #ifndef ENTT_META_CONTAINER_HPP
  46084. #define ENTT_META_CONTAINER_HPP
  46085. #include <array>
  46086. #include <cstddef>
  46087. #include <deque>
  46088. #include <iterator>
  46089. #include <list>
  46090. #include <map>
  46091. #include <set>
  46092. #include <type_traits>
  46093. #include <unordered_map>
  46094. #include <unordered_set>
  46095. #include <vector>
  46096. // #include "../container/dense_map.hpp"
  46097. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  46098. #define ENTT_CONTAINER_DENSE_MAP_HPP
  46099. #include <cmath>
  46100. #include <cstddef>
  46101. #include <functional>
  46102. #include <iterator>
  46103. #include <limits>
  46104. #include <memory>
  46105. #include <tuple>
  46106. #include <type_traits>
  46107. #include <utility>
  46108. #include <vector>
  46109. // #include "../config/config.h"
  46110. #ifndef ENTT_CONFIG_CONFIG_H
  46111. #define ENTT_CONFIG_CONFIG_H
  46112. // #include "version.h"
  46113. #ifndef ENTT_CONFIG_VERSION_H
  46114. #define ENTT_CONFIG_VERSION_H
  46115. // #include "macro.h"
  46116. #ifndef ENTT_CONFIG_MACRO_H
  46117. #define ENTT_CONFIG_MACRO_H
  46118. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  46119. #define ENTT_STR(arg) #arg
  46120. #define ENTT_XSTR(arg) ENTT_STR(arg)
  46121. // NOLINTEND(cppcoreguidelines-macro-usage)
  46122. #endif
  46123. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  46124. #define ENTT_VERSION_MAJOR 3
  46125. #define ENTT_VERSION_MINOR 16
  46126. #define ENTT_VERSION_PATCH 0
  46127. #define ENTT_VERSION \
  46128. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  46129. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  46130. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  46131. #endif
  46132. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  46133. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  46134. # define ENTT_CONSTEXPR
  46135. # define ENTT_THROW throw
  46136. # define ENTT_TRY try
  46137. # define ENTT_CATCH catch(...)
  46138. #else
  46139. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  46140. # define ENTT_THROW
  46141. # define ENTT_TRY if(true)
  46142. # define ENTT_CATCH if(false)
  46143. #endif
  46144. #if __has_include(<version>)
  46145. # include <version>
  46146. #
  46147. # if defined(__cpp_consteval)
  46148. # define ENTT_CONSTEVAL consteval
  46149. # endif
  46150. #endif
  46151. #ifndef ENTT_CONSTEVAL
  46152. # define ENTT_CONSTEVAL constexpr
  46153. #endif
  46154. #ifdef ENTT_USE_ATOMIC
  46155. # include <atomic>
  46156. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  46157. #else
  46158. # define ENTT_MAYBE_ATOMIC(Type) Type
  46159. #endif
  46160. #ifndef ENTT_ID_TYPE
  46161. # include <cstdint>
  46162. # define ENTT_ID_TYPE std::uint32_t
  46163. #else
  46164. # include <cstdint> // provides coverage for types in the std namespace
  46165. #endif
  46166. #ifndef ENTT_SPARSE_PAGE
  46167. # define ENTT_SPARSE_PAGE 4096
  46168. #endif
  46169. #ifndef ENTT_PACKED_PAGE
  46170. # define ENTT_PACKED_PAGE 1024
  46171. #endif
  46172. #ifdef ENTT_DISABLE_ASSERT
  46173. # undef ENTT_ASSERT
  46174. # define ENTT_ASSERT(condition, msg) (void(0))
  46175. #elif !defined ENTT_ASSERT
  46176. # include <cassert>
  46177. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  46178. #endif
  46179. #ifdef ENTT_DISABLE_ASSERT
  46180. # undef ENTT_ASSERT_CONSTEXPR
  46181. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  46182. #elif !defined ENTT_ASSERT_CONSTEXPR
  46183. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  46184. #endif
  46185. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  46186. #ifdef ENTT_NO_ETO
  46187. # define ENTT_ETO_TYPE(Type) void
  46188. #else
  46189. # define ENTT_ETO_TYPE(Type) Type
  46190. #endif
  46191. #ifdef ENTT_NO_MIXIN
  46192. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  46193. #else
  46194. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  46195. #endif
  46196. #ifdef ENTT_STANDARD_CPP
  46197. # define ENTT_NONSTD false
  46198. #else
  46199. # define ENTT_NONSTD true
  46200. # if defined __clang__ || defined __GNUC__
  46201. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  46202. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  46203. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  46204. # elif defined _MSC_VER
  46205. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  46206. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  46207. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  46208. # endif
  46209. #endif
  46210. #ifndef ENTT_EXPORT
  46211. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  46212. # define ENTT_EXPORT __declspec(dllexport)
  46213. # define ENTT_IMPORT __declspec(dllimport)
  46214. # define ENTT_HIDDEN
  46215. # elif defined __GNUC__ && __GNUC__ >= 4
  46216. # define ENTT_EXPORT __attribute__((visibility("default")))
  46217. # define ENTT_IMPORT __attribute__((visibility("default")))
  46218. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  46219. # else /* Unsupported compiler */
  46220. # define ENTT_EXPORT
  46221. # define ENTT_IMPORT
  46222. # define ENTT_HIDDEN
  46223. # endif
  46224. #endif
  46225. #ifndef ENTT_API
  46226. # if defined ENTT_API_EXPORT
  46227. # define ENTT_API ENTT_EXPORT
  46228. # elif defined ENTT_API_IMPORT
  46229. # define ENTT_API ENTT_IMPORT
  46230. # else /* No API */
  46231. # define ENTT_API
  46232. # endif
  46233. #endif
  46234. #if defined _MSC_VER
  46235. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  46236. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  46237. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  46238. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  46239. #endif
  46240. // NOLINTEND(cppcoreguidelines-macro-usage)
  46241. #endif
  46242. // #include "../core/bit.hpp"
  46243. #ifndef ENTT_CORE_BIT_HPP
  46244. #define ENTT_CORE_BIT_HPP
  46245. #include <cstddef>
  46246. #include <limits>
  46247. #include <type_traits>
  46248. // #include "../config/config.h"
  46249. #ifndef ENTT_CONFIG_CONFIG_H
  46250. #define ENTT_CONFIG_CONFIG_H
  46251. // #include "version.h"
  46252. #ifndef ENTT_CONFIG_VERSION_H
  46253. #define ENTT_CONFIG_VERSION_H
  46254. // #include "macro.h"
  46255. #ifndef ENTT_CONFIG_MACRO_H
  46256. #define ENTT_CONFIG_MACRO_H
  46257. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  46258. #define ENTT_STR(arg) #arg
  46259. #define ENTT_XSTR(arg) ENTT_STR(arg)
  46260. // NOLINTEND(cppcoreguidelines-macro-usage)
  46261. #endif
  46262. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  46263. #define ENTT_VERSION_MAJOR 3
  46264. #define ENTT_VERSION_MINOR 16
  46265. #define ENTT_VERSION_PATCH 0
  46266. #define ENTT_VERSION \
  46267. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  46268. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  46269. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  46270. #endif
  46271. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  46272. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  46273. # define ENTT_CONSTEXPR
  46274. # define ENTT_THROW throw
  46275. # define ENTT_TRY try
  46276. # define ENTT_CATCH catch(...)
  46277. #else
  46278. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  46279. # define ENTT_THROW
  46280. # define ENTT_TRY if(true)
  46281. # define ENTT_CATCH if(false)
  46282. #endif
  46283. #if __has_include(<version>)
  46284. # include <version>
  46285. #
  46286. # if defined(__cpp_consteval)
  46287. # define ENTT_CONSTEVAL consteval
  46288. # endif
  46289. #endif
  46290. #ifndef ENTT_CONSTEVAL
  46291. # define ENTT_CONSTEVAL constexpr
  46292. #endif
  46293. #ifdef ENTT_USE_ATOMIC
  46294. # include <atomic>
  46295. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  46296. #else
  46297. # define ENTT_MAYBE_ATOMIC(Type) Type
  46298. #endif
  46299. #ifndef ENTT_ID_TYPE
  46300. # include <cstdint>
  46301. # define ENTT_ID_TYPE std::uint32_t
  46302. #else
  46303. # include <cstdint> // provides coverage for types in the std namespace
  46304. #endif
  46305. #ifndef ENTT_SPARSE_PAGE
  46306. # define ENTT_SPARSE_PAGE 4096
  46307. #endif
  46308. #ifndef ENTT_PACKED_PAGE
  46309. # define ENTT_PACKED_PAGE 1024
  46310. #endif
  46311. #ifdef ENTT_DISABLE_ASSERT
  46312. # undef ENTT_ASSERT
  46313. # define ENTT_ASSERT(condition, msg) (void(0))
  46314. #elif !defined ENTT_ASSERT
  46315. # include <cassert>
  46316. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  46317. #endif
  46318. #ifdef ENTT_DISABLE_ASSERT
  46319. # undef ENTT_ASSERT_CONSTEXPR
  46320. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  46321. #elif !defined ENTT_ASSERT_CONSTEXPR
  46322. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  46323. #endif
  46324. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  46325. #ifdef ENTT_NO_ETO
  46326. # define ENTT_ETO_TYPE(Type) void
  46327. #else
  46328. # define ENTT_ETO_TYPE(Type) Type
  46329. #endif
  46330. #ifdef ENTT_NO_MIXIN
  46331. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  46332. #else
  46333. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  46334. #endif
  46335. #ifdef ENTT_STANDARD_CPP
  46336. # define ENTT_NONSTD false
  46337. #else
  46338. # define ENTT_NONSTD true
  46339. # if defined __clang__ || defined __GNUC__
  46340. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  46341. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  46342. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  46343. # elif defined _MSC_VER
  46344. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  46345. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  46346. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  46347. # endif
  46348. #endif
  46349. #ifndef ENTT_EXPORT
  46350. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  46351. # define ENTT_EXPORT __declspec(dllexport)
  46352. # define ENTT_IMPORT __declspec(dllimport)
  46353. # define ENTT_HIDDEN
  46354. # elif defined __GNUC__ && __GNUC__ >= 4
  46355. # define ENTT_EXPORT __attribute__((visibility("default")))
  46356. # define ENTT_IMPORT __attribute__((visibility("default")))
  46357. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  46358. # else /* Unsupported compiler */
  46359. # define ENTT_EXPORT
  46360. # define ENTT_IMPORT
  46361. # define ENTT_HIDDEN
  46362. # endif
  46363. #endif
  46364. #ifndef ENTT_API
  46365. # if defined ENTT_API_EXPORT
  46366. # define ENTT_API ENTT_EXPORT
  46367. # elif defined ENTT_API_IMPORT
  46368. # define ENTT_API ENTT_IMPORT
  46369. # else /* No API */
  46370. # define ENTT_API
  46371. # endif
  46372. #endif
  46373. #if defined _MSC_VER
  46374. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  46375. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  46376. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  46377. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  46378. #endif
  46379. // NOLINTEND(cppcoreguidelines-macro-usage)
  46380. #endif
  46381. namespace entt {
  46382. /**
  46383. * @brief Returns the number of set bits in a value (waiting for C++20 and
  46384. * `std::popcount`).
  46385. * @tparam Type Unsigned integer type.
  46386. * @param value A value of unsigned integer type.
  46387. * @return The number of set bits in the value.
  46388. */
  46389. template<typename Type>
  46390. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  46391. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  46392. }
  46393. /**
  46394. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  46395. * `std::has_single_bit`).
  46396. * @tparam Type Unsigned integer type.
  46397. * @param value A value of unsigned integer type.
  46398. * @return True if the value is a power of two, false otherwise.
  46399. */
  46400. template<typename Type>
  46401. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  46402. return value && ((value & (value - 1)) == 0);
  46403. }
  46404. /**
  46405. * @brief Computes the smallest power of two greater than or equal to a value
  46406. * (waiting for C++20 and `std::bit_ceil`).
  46407. * @tparam Type Unsigned integer type.
  46408. * @param value A value of unsigned integer type.
  46409. * @return The smallest power of two greater than or equal to the given value.
  46410. */
  46411. template<typename Type>
  46412. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  46413. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  46414. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  46415. Type curr = value - (value != 0u);
  46416. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  46417. curr |= (curr >> next);
  46418. }
  46419. return ++curr;
  46420. }
  46421. /**
  46422. * @brief Fast module utility function (powers of two only).
  46423. * @tparam Type Unsigned integer type.
  46424. * @param value A value of unsigned integer type.
  46425. * @param mod _Modulus_, it must be a power of two.
  46426. * @return The common remainder.
  46427. */
  46428. template<typename Type>
  46429. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  46430. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  46431. return static_cast<Type>(value & (mod - 1u));
  46432. }
  46433. } // namespace entt
  46434. #endif
  46435. // #include "../core/compressed_pair.hpp"
  46436. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  46437. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  46438. #include <cstddef>
  46439. #include <tuple>
  46440. #include <type_traits>
  46441. #include <utility>
  46442. // #include "fwd.hpp"
  46443. #ifndef ENTT_CORE_FWD_HPP
  46444. #define ENTT_CORE_FWD_HPP
  46445. #include <cstddef>
  46446. #include <cstdint>
  46447. // #include "../config/config.h"
  46448. namespace entt {
  46449. /*! @brief Possible modes of an any object. */
  46450. enum class any_policy : std::uint8_t {
  46451. /*! @brief Default mode, no element available. */
  46452. empty,
  46453. /*! @brief Owning mode, dynamically allocated element. */
  46454. dynamic,
  46455. /*! @brief Owning mode, embedded element. */
  46456. embedded,
  46457. /*! @brief Aliasing mode, non-const reference. */
  46458. ref,
  46459. /*! @brief Const aliasing mode, const reference. */
  46460. cref
  46461. };
  46462. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  46463. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  46464. class basic_any;
  46465. /*! @brief Alias declaration for type identifiers. */
  46466. using id_type = ENTT_ID_TYPE;
  46467. /*! @brief Alias declaration for the most common use case. */
  46468. using any = basic_any<>;
  46469. template<typename, typename>
  46470. class compressed_pair;
  46471. template<typename>
  46472. class basic_hashed_string;
  46473. /*! @brief Aliases for common character types. */
  46474. using hashed_string = basic_hashed_string<char>;
  46475. /*! @brief Aliases for common character types. */
  46476. using hashed_wstring = basic_hashed_string<wchar_t>;
  46477. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  46478. struct type_info;
  46479. } // namespace entt
  46480. #endif
  46481. // #include "type_traits.hpp"
  46482. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  46483. #define ENTT_CORE_TYPE_TRAITS_HPP
  46484. #include <cstddef>
  46485. #include <iterator>
  46486. #include <tuple>
  46487. #include <type_traits>
  46488. #include <utility>
  46489. // #include "../config/config.h"
  46490. // #include "fwd.hpp"
  46491. namespace entt {
  46492. /**
  46493. * @brief Utility class to disambiguate overloaded functions.
  46494. * @tparam N Number of choices available.
  46495. */
  46496. template<std::size_t N>
  46497. struct choice_t
  46498. // unfortunately, doxygen cannot parse such a construct
  46499. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  46500. {};
  46501. /*! @copybrief choice_t */
  46502. template<>
  46503. struct choice_t<0> {};
  46504. /**
  46505. * @brief Variable template for the choice trick.
  46506. * @tparam N Number of choices available.
  46507. */
  46508. template<std::size_t N>
  46509. inline constexpr choice_t<N> choice{};
  46510. /**
  46511. * @brief Identity type trait.
  46512. *
  46513. * Useful to establish non-deduced contexts in template argument deduction
  46514. * (waiting for C++20) or to provide types through function arguments.
  46515. *
  46516. * @tparam Type A type.
  46517. */
  46518. template<typename Type>
  46519. struct type_identity {
  46520. /*! @brief Identity type. */
  46521. using type = Type;
  46522. };
  46523. /**
  46524. * @brief Helper type.
  46525. * @tparam Type A type.
  46526. */
  46527. template<typename Type>
  46528. using type_identity_t = typename type_identity<Type>::type;
  46529. /**
  46530. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  46531. * @tparam Type The type of which to return the size.
  46532. */
  46533. template<typename Type, typename = void>
  46534. struct size_of: std::integral_constant<std::size_t, 0u> {};
  46535. /*! @copydoc size_of */
  46536. template<typename Type>
  46537. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  46538. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  46539. : std::integral_constant<std::size_t, sizeof(Type)> {};
  46540. /**
  46541. * @brief Helper variable template.
  46542. * @tparam Type The type of which to return the size.
  46543. */
  46544. template<typename Type>
  46545. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  46546. /**
  46547. * @brief Using declaration to be used to _repeat_ the same type a number of
  46548. * times equal to the size of a given parameter pack.
  46549. * @tparam Type A type to repeat.
  46550. */
  46551. template<typename Type, typename>
  46552. using unpack_as_type = Type;
  46553. /**
  46554. * @brief Helper variable template to be used to _repeat_ the same value a
  46555. * number of times equal to the size of a given parameter pack.
  46556. * @tparam Value A value to repeat.
  46557. */
  46558. template<auto Value, typename>
  46559. inline constexpr auto unpack_as_value = Value;
  46560. /**
  46561. * @brief Wraps a static constant.
  46562. * @tparam Value A static constant.
  46563. */
  46564. template<auto Value>
  46565. using integral_constant = std::integral_constant<decltype(Value), Value>;
  46566. /**
  46567. * @brief Alias template to facilitate the creation of named values.
  46568. * @tparam Value A constant value at least convertible to `id_type`.
  46569. */
  46570. template<id_type Value>
  46571. using tag = integral_constant<Value>;
  46572. /**
  46573. * @brief A class to use to push around lists of types, nothing more.
  46574. * @tparam Type Types provided by the type list.
  46575. */
  46576. template<typename... Type>
  46577. struct type_list {
  46578. /*! @brief Type list type. */
  46579. using type = type_list;
  46580. /*! @brief Compile-time number of elements in the type list. */
  46581. static constexpr auto size = sizeof...(Type);
  46582. };
  46583. /*! @brief Primary template isn't defined on purpose. */
  46584. template<std::size_t, typename>
  46585. struct type_list_element;
  46586. /**
  46587. * @brief Provides compile-time indexed access to the types of a type list.
  46588. * @tparam Index Index of the type to return.
  46589. * @tparam First First type provided by the type list.
  46590. * @tparam Other Other types provided by the type list.
  46591. */
  46592. template<std::size_t Index, typename First, typename... Other>
  46593. struct type_list_element<Index, type_list<First, Other...>>
  46594. : type_list_element<Index - 1u, type_list<Other...>> {};
  46595. /**
  46596. * @brief Provides compile-time indexed access to the types of a type list.
  46597. * @tparam First First type provided by the type list.
  46598. * @tparam Other Other types provided by the type list.
  46599. */
  46600. template<typename First, typename... Other>
  46601. struct type_list_element<0u, type_list<First, Other...>> {
  46602. /*! @brief Searched type. */
  46603. using type = First;
  46604. };
  46605. /**
  46606. * @brief Helper type.
  46607. * @tparam Index Index of the type to return.
  46608. * @tparam List Type list to search into.
  46609. */
  46610. template<std::size_t Index, typename List>
  46611. using type_list_element_t = typename type_list_element<Index, List>::type;
  46612. /*! @brief Primary template isn't defined on purpose. */
  46613. template<typename, typename>
  46614. struct type_list_index;
  46615. /**
  46616. * @brief Provides compile-time type access to the types of a type list.
  46617. * @tparam Type Type to look for and for which to return the index.
  46618. * @tparam First First type provided by the type list.
  46619. * @tparam Other Other types provided by the type list.
  46620. */
  46621. template<typename Type, typename First, typename... Other>
  46622. struct type_list_index<Type, type_list<First, Other...>> {
  46623. /*! @brief Unsigned integer type. */
  46624. using value_type = std::size_t;
  46625. /*! @brief Compile-time position of the given type in the sublist. */
  46626. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  46627. };
  46628. /**
  46629. * @brief Provides compile-time type access to the types of a type list.
  46630. * @tparam Type Type to look for and for which to return the index.
  46631. * @tparam Other Other types provided by the type list.
  46632. */
  46633. template<typename Type, typename... Other>
  46634. struct type_list_index<Type, type_list<Type, Other...>> {
  46635. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  46636. /*! @brief Unsigned integer type. */
  46637. using value_type = std::size_t;
  46638. /*! @brief Compile-time position of the given type in the sublist. */
  46639. static constexpr value_type value = 0u;
  46640. };
  46641. /**
  46642. * @brief Provides compile-time type access to the types of a type list.
  46643. * @tparam Type Type to look for and for which to return the index.
  46644. */
  46645. template<typename Type>
  46646. struct type_list_index<Type, type_list<>> {
  46647. /*! @brief Unsigned integer type. */
  46648. using value_type = std::size_t;
  46649. /*! @brief Compile-time position of the given type in the sublist. */
  46650. static constexpr value_type value = 0u;
  46651. };
  46652. /**
  46653. * @brief Helper variable template.
  46654. * @tparam List Type list.
  46655. * @tparam Type Type to look for and for which to return the index.
  46656. */
  46657. template<typename Type, typename List>
  46658. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  46659. /**
  46660. * @brief Concatenates multiple type lists.
  46661. * @tparam Type Types provided by the first type list.
  46662. * @tparam Other Types provided by the second type list.
  46663. * @return A type list composed by the types of both the type lists.
  46664. */
  46665. template<typename... Type, typename... Other>
  46666. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  46667. return {};
  46668. }
  46669. /*! @brief Primary template isn't defined on purpose. */
  46670. template<typename...>
  46671. struct type_list_cat;
  46672. /*! @brief Concatenates multiple type lists. */
  46673. template<>
  46674. struct type_list_cat<> {
  46675. /*! @brief A type list composed by the types of all the type lists. */
  46676. using type = type_list<>;
  46677. };
  46678. /**
  46679. * @brief Concatenates multiple type lists.
  46680. * @tparam Type Types provided by the first type list.
  46681. * @tparam Other Types provided by the second type list.
  46682. * @tparam List Other type lists, if any.
  46683. */
  46684. template<typename... Type, typename... Other, typename... List>
  46685. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  46686. /*! @brief A type list composed by the types of all the type lists. */
  46687. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  46688. };
  46689. /**
  46690. * @brief Concatenates multiple type lists.
  46691. * @tparam Type Types provided by the type list.
  46692. */
  46693. template<typename... Type>
  46694. struct type_list_cat<type_list<Type...>> {
  46695. /*! @brief A type list composed by the types of all the type lists. */
  46696. using type = type_list<Type...>;
  46697. };
  46698. /**
  46699. * @brief Helper type.
  46700. * @tparam List Type lists to concatenate.
  46701. */
  46702. template<typename... List>
  46703. using type_list_cat_t = typename type_list_cat<List...>::type;
  46704. /*! @cond TURN_OFF_DOXYGEN */
  46705. namespace internal {
  46706. template<typename...>
  46707. struct type_list_unique;
  46708. template<typename First, typename... Other, typename... Type>
  46709. struct type_list_unique<type_list<First, Other...>, Type...>
  46710. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  46711. template<typename... Type>
  46712. struct type_list_unique<type_list<>, Type...> {
  46713. using type = type_list<Type...>;
  46714. };
  46715. } // namespace internal
  46716. /*! @endcond */
  46717. /**
  46718. * @brief Removes duplicates types from a type list.
  46719. * @tparam List Type list.
  46720. */
  46721. template<typename List>
  46722. struct type_list_unique {
  46723. /*! @brief A type list without duplicate types. */
  46724. using type = typename internal::type_list_unique<List>::type;
  46725. };
  46726. /**
  46727. * @brief Helper type.
  46728. * @tparam List Type list.
  46729. */
  46730. template<typename List>
  46731. using type_list_unique_t = typename type_list_unique<List>::type;
  46732. /**
  46733. * @brief Provides the member constant `value` to true if a type list contains a
  46734. * given type, false otherwise.
  46735. * @tparam List Type list.
  46736. * @tparam Type Type to look for.
  46737. */
  46738. template<typename List, typename Type>
  46739. struct type_list_contains;
  46740. /**
  46741. * @copybrief type_list_contains
  46742. * @tparam Type Types provided by the type list.
  46743. * @tparam Other Type to look for.
  46744. */
  46745. template<typename... Type, typename Other>
  46746. struct type_list_contains<type_list<Type...>, Other>
  46747. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  46748. /**
  46749. * @brief Helper variable template.
  46750. * @tparam List Type list.
  46751. * @tparam Type Type to look for.
  46752. */
  46753. template<typename List, typename Type>
  46754. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  46755. /*! @brief Primary template isn't defined on purpose. */
  46756. template<typename...>
  46757. struct type_list_diff;
  46758. /**
  46759. * @brief Computes the difference between two type lists.
  46760. * @tparam Type Types provided by the first type list.
  46761. * @tparam Other Types provided by the second type list.
  46762. */
  46763. template<typename... Type, typename... Other>
  46764. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  46765. /*! @brief A type list that is the difference between the two type lists. */
  46766. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  46767. };
  46768. /**
  46769. * @brief Helper type.
  46770. * @tparam List Type lists between which to compute the difference.
  46771. */
  46772. template<typename... List>
  46773. using type_list_diff_t = typename type_list_diff<List...>::type;
  46774. /*! @brief Primary template isn't defined on purpose. */
  46775. template<typename, template<typename...> class>
  46776. struct type_list_transform;
  46777. /**
  46778. * @brief Applies a given _function_ to a type list and generate a new list.
  46779. * @tparam Type Types provided by the type list.
  46780. * @tparam Op Unary operation as template class with a type member named `type`.
  46781. */
  46782. template<typename... Type, template<typename...> class Op>
  46783. struct type_list_transform<type_list<Type...>, Op> {
  46784. /*! @brief Resulting type list after applying the transform function. */
  46785. // NOLINTNEXTLINE(modernize-type-traits)
  46786. using type = type_list<typename Op<Type>::type...>;
  46787. };
  46788. /**
  46789. * @brief Helper type.
  46790. * @tparam List Type list.
  46791. * @tparam Op Unary operation as template class with a type member named `type`.
  46792. */
  46793. template<typename List, template<typename...> class Op>
  46794. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  46795. /**
  46796. * @brief A class to use to push around lists of constant values, nothing more.
  46797. * @tparam Value Values provided by the value list.
  46798. */
  46799. template<auto... Value>
  46800. struct value_list {
  46801. /*! @brief Value list type. */
  46802. using type = value_list;
  46803. /*! @brief Compile-time number of elements in the value list. */
  46804. static constexpr auto size = sizeof...(Value);
  46805. };
  46806. /*! @brief Primary template isn't defined on purpose. */
  46807. template<std::size_t, typename>
  46808. struct value_list_element;
  46809. /**
  46810. * @brief Provides compile-time indexed access to the values of a value list.
  46811. * @tparam Index Index of the value to return.
  46812. * @tparam Value First value provided by the value list.
  46813. * @tparam Other Other values provided by the value list.
  46814. */
  46815. template<std::size_t Index, auto Value, auto... Other>
  46816. struct value_list_element<Index, value_list<Value, Other...>>
  46817. : value_list_element<Index - 1u, value_list<Other...>> {};
  46818. /**
  46819. * @brief Provides compile-time indexed access to the types of a type list.
  46820. * @tparam Value First value provided by the value list.
  46821. * @tparam Other Other values provided by the value list.
  46822. */
  46823. template<auto Value, auto... Other>
  46824. struct value_list_element<0u, value_list<Value, Other...>> {
  46825. /*! @brief Searched type. */
  46826. using type = decltype(Value);
  46827. /*! @brief Searched value. */
  46828. static constexpr auto value = Value;
  46829. };
  46830. /**
  46831. * @brief Helper type.
  46832. * @tparam Index Index of the type to return.
  46833. * @tparam List Value list to search into.
  46834. */
  46835. template<std::size_t Index, typename List>
  46836. using value_list_element_t = typename value_list_element<Index, List>::type;
  46837. /**
  46838. * @brief Helper type.
  46839. * @tparam Index Index of the value to return.
  46840. * @tparam List Value list to search into.
  46841. */
  46842. template<std::size_t Index, typename List>
  46843. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  46844. /*! @brief Primary template isn't defined on purpose. */
  46845. template<auto, typename>
  46846. struct value_list_index;
  46847. /**
  46848. * @brief Provides compile-time type access to the values of a value list.
  46849. * @tparam Value Value to look for and for which to return the index.
  46850. * @tparam First First value provided by the value list.
  46851. * @tparam Other Other values provided by the value list.
  46852. */
  46853. template<auto Value, auto First, auto... Other>
  46854. struct value_list_index<Value, value_list<First, Other...>> {
  46855. /*! @brief Unsigned integer type. */
  46856. using value_type = std::size_t;
  46857. /*! @brief Compile-time position of the given value in the sublist. */
  46858. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  46859. };
  46860. /**
  46861. * @brief Provides compile-time type access to the values of a value list.
  46862. * @tparam Value Value to look for and for which to return the index.
  46863. * @tparam Other Other values provided by the value list.
  46864. */
  46865. template<auto Value, auto... Other>
  46866. struct value_list_index<Value, value_list<Value, Other...>> {
  46867. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  46868. /*! @brief Unsigned integer type. */
  46869. using value_type = std::size_t;
  46870. /*! @brief Compile-time position of the given value in the sublist. */
  46871. static constexpr value_type value = 0u;
  46872. };
  46873. /**
  46874. * @brief Provides compile-time type access to the values of a value list.
  46875. * @tparam Value Value to look for and for which to return the index.
  46876. */
  46877. template<auto Value>
  46878. struct value_list_index<Value, value_list<>> {
  46879. /*! @brief Unsigned integer type. */
  46880. using value_type = std::size_t;
  46881. /*! @brief Compile-time position of the given type in the sublist. */
  46882. static constexpr value_type value = 0u;
  46883. };
  46884. /**
  46885. * @brief Helper variable template.
  46886. * @tparam List Value list.
  46887. * @tparam Value Value to look for and for which to return the index.
  46888. */
  46889. template<auto Value, typename List>
  46890. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  46891. /**
  46892. * @brief Concatenates multiple value lists.
  46893. * @tparam Value Values provided by the first value list.
  46894. * @tparam Other Values provided by the second value list.
  46895. * @return A value list composed by the values of both the value lists.
  46896. */
  46897. template<auto... Value, auto... Other>
  46898. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  46899. return {};
  46900. }
  46901. /*! @brief Primary template isn't defined on purpose. */
  46902. template<typename...>
  46903. struct value_list_cat;
  46904. /*! @brief Concatenates multiple value lists. */
  46905. template<>
  46906. struct value_list_cat<> {
  46907. /*! @brief A value list composed by the values of all the value lists. */
  46908. using type = value_list<>;
  46909. };
  46910. /**
  46911. * @brief Concatenates multiple value lists.
  46912. * @tparam Value Values provided by the first value list.
  46913. * @tparam Other Values provided by the second value list.
  46914. * @tparam List Other value lists, if any.
  46915. */
  46916. template<auto... Value, auto... Other, typename... List>
  46917. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  46918. /*! @brief A value list composed by the values of all the value lists. */
  46919. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  46920. };
  46921. /**
  46922. * @brief Concatenates multiple value lists.
  46923. * @tparam Value Values provided by the value list.
  46924. */
  46925. template<auto... Value>
  46926. struct value_list_cat<value_list<Value...>> {
  46927. /*! @brief A value list composed by the values of all the value lists. */
  46928. using type = value_list<Value...>;
  46929. };
  46930. /**
  46931. * @brief Helper type.
  46932. * @tparam List Value lists to concatenate.
  46933. */
  46934. template<typename... List>
  46935. using value_list_cat_t = typename value_list_cat<List...>::type;
  46936. /*! @brief Primary template isn't defined on purpose. */
  46937. template<typename>
  46938. struct value_list_unique;
  46939. /**
  46940. * @brief Removes duplicates values from a value list.
  46941. * @tparam Value One of the values provided by the given value list.
  46942. * @tparam Other The other values provided by the given value list.
  46943. */
  46944. template<auto Value, auto... Other>
  46945. struct value_list_unique<value_list<Value, Other...>> {
  46946. /*! @brief A value list without duplicate types. */
  46947. using type = std::conditional_t<
  46948. ((Value == Other) || ...),
  46949. typename value_list_unique<value_list<Other...>>::type,
  46950. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  46951. };
  46952. /*! @brief Removes duplicates values from a value list. */
  46953. template<>
  46954. struct value_list_unique<value_list<>> {
  46955. /*! @brief A value list without duplicate types. */
  46956. using type = value_list<>;
  46957. };
  46958. /**
  46959. * @brief Helper type.
  46960. * @tparam Type A value list.
  46961. */
  46962. template<typename Type>
  46963. using value_list_unique_t = typename value_list_unique<Type>::type;
  46964. /**
  46965. * @brief Provides the member constant `value` to true if a value list contains
  46966. * a given value, false otherwise.
  46967. * @tparam List Value list.
  46968. * @tparam Value Value to look for.
  46969. */
  46970. template<typename List, auto Value>
  46971. struct value_list_contains;
  46972. /**
  46973. * @copybrief value_list_contains
  46974. * @tparam Value Values provided by the value list.
  46975. * @tparam Other Value to look for.
  46976. */
  46977. template<auto... Value, auto Other>
  46978. struct value_list_contains<value_list<Value...>, Other>
  46979. : std::bool_constant<((Value == Other) || ...)> {};
  46980. /**
  46981. * @brief Helper variable template.
  46982. * @tparam List Value list.
  46983. * @tparam Value Value to look for.
  46984. */
  46985. template<typename List, auto Value>
  46986. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  46987. /*! @brief Primary template isn't defined on purpose. */
  46988. template<typename...>
  46989. struct value_list_diff;
  46990. /**
  46991. * @brief Computes the difference between two value lists.
  46992. * @tparam Value Values provided by the first value list.
  46993. * @tparam Other Values provided by the second value list.
  46994. */
  46995. template<auto... Value, auto... Other>
  46996. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  46997. /*! @brief A value list that is the difference between the two value lists. */
  46998. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  46999. };
  47000. /**
  47001. * @brief Helper type.
  47002. * @tparam List Value lists between which to compute the difference.
  47003. */
  47004. template<typename... List>
  47005. using value_list_diff_t = typename value_list_diff<List...>::type;
  47006. /*! @brief Same as std::is_invocable, but with tuples. */
  47007. template<typename, typename>
  47008. struct is_applicable: std::false_type {};
  47009. /**
  47010. * @copybrief is_applicable
  47011. * @tparam Func A valid function type.
  47012. * @tparam Tuple Tuple-like type.
  47013. * @tparam Args The list of arguments to use to probe the function type.
  47014. */
  47015. template<typename Func, template<typename...> class Tuple, typename... Args>
  47016. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  47017. /**
  47018. * @copybrief is_applicable
  47019. * @tparam Func A valid function type.
  47020. * @tparam Tuple Tuple-like type.
  47021. * @tparam Args The list of arguments to use to probe the function type.
  47022. */
  47023. template<typename Func, template<typename...> class Tuple, typename... Args>
  47024. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  47025. /**
  47026. * @brief Helper variable template.
  47027. * @tparam Func A valid function type.
  47028. * @tparam Args The list of arguments to use to probe the function type.
  47029. */
  47030. template<typename Func, typename Args>
  47031. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  47032. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  47033. template<typename, typename, typename>
  47034. struct is_applicable_r: std::false_type {};
  47035. /**
  47036. * @copybrief is_applicable_r
  47037. * @tparam Ret The type to which the return type of the function should be
  47038. * convertible.
  47039. * @tparam Func A valid function type.
  47040. * @tparam Args The list of arguments to use to probe the function type.
  47041. */
  47042. template<typename Ret, typename Func, typename... Args>
  47043. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  47044. /**
  47045. * @brief Helper variable template.
  47046. * @tparam Ret The type to which the return type of the function should be
  47047. * convertible.
  47048. * @tparam Func A valid function type.
  47049. * @tparam Args The list of arguments to use to probe the function type.
  47050. */
  47051. template<typename Ret, typename Func, typename Args>
  47052. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  47053. /**
  47054. * @brief Provides the member constant `value` to true if a given type is
  47055. * complete, false otherwise.
  47056. * @tparam Type The type to test.
  47057. */
  47058. template<typename Type, typename = void>
  47059. struct is_complete: std::false_type {};
  47060. /*! @copydoc is_complete */
  47061. template<typename Type>
  47062. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  47063. /**
  47064. * @brief Helper variable template.
  47065. * @tparam Type The type to test.
  47066. */
  47067. template<typename Type>
  47068. inline constexpr bool is_complete_v = is_complete<Type>::value;
  47069. /**
  47070. * @brief Provides the member constant `value` to true if a given type is an
  47071. * iterator, false otherwise.
  47072. * @tparam Type The type to test.
  47073. */
  47074. template<typename Type, typename = void>
  47075. struct is_iterator: std::false_type {};
  47076. /*! @cond TURN_OFF_DOXYGEN */
  47077. namespace internal {
  47078. template<typename, typename = void>
  47079. struct has_iterator_category: std::false_type {};
  47080. template<typename Type>
  47081. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  47082. } // namespace internal
  47083. /*! @endcond */
  47084. /*! @copydoc is_iterator */
  47085. template<typename Type>
  47086. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  47087. : internal::has_iterator_category<Type> {};
  47088. /**
  47089. * @brief Helper variable template.
  47090. * @tparam Type The type to test.
  47091. */
  47092. template<typename Type>
  47093. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  47094. /**
  47095. * @brief Provides the member constant `value` to true if a given type is both
  47096. * an empty and non-final class, false otherwise.
  47097. * @tparam Type The type to test
  47098. */
  47099. template<typename Type>
  47100. struct is_ebco_eligible
  47101. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  47102. /**
  47103. * @brief Helper variable template.
  47104. * @tparam Type The type to test.
  47105. */
  47106. template<typename Type>
  47107. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  47108. /**
  47109. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  47110. * is valid and denotes a type, false otherwise.
  47111. * @tparam Type The type to test.
  47112. */
  47113. template<typename Type, typename = void>
  47114. struct is_transparent: std::false_type {};
  47115. /*! @copydoc is_transparent */
  47116. template<typename Type>
  47117. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  47118. /**
  47119. * @brief Helper variable template.
  47120. * @tparam Type The type to test.
  47121. */
  47122. template<typename Type>
  47123. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  47124. /*! @cond TURN_OFF_DOXYGEN */
  47125. namespace internal {
  47126. template<typename, typename = void>
  47127. struct has_tuple_size_value: std::false_type {};
  47128. template<typename Type>
  47129. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  47130. template<typename, typename = void>
  47131. struct has_value_type: std::false_type {};
  47132. template<typename Type>
  47133. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  47134. template<typename>
  47135. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  47136. template<typename Type, std::size_t... Index>
  47137. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  47138. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  47139. }
  47140. template<typename>
  47141. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  47142. return false;
  47143. }
  47144. template<typename Type>
  47145. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  47146. return true;
  47147. }
  47148. template<typename Type>
  47149. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  47150. // NOLINTBEGIN(modernize-use-transparent-functors)
  47151. if constexpr(std::is_array_v<Type>) {
  47152. return false;
  47153. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  47154. if constexpr(has_tuple_size_value<Type>::value) {
  47155. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  47156. } else {
  47157. return maybe_equality_comparable<Type>(0);
  47158. }
  47159. } else if constexpr(has_value_type<Type>::value) {
  47160. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  47161. return maybe_equality_comparable<Type>(0);
  47162. } else {
  47163. return false;
  47164. }
  47165. } else {
  47166. return maybe_equality_comparable<Type>(0);
  47167. }
  47168. // NOLINTEND(modernize-use-transparent-functors)
  47169. }
  47170. } // namespace internal
  47171. /*! @endcond */
  47172. /**
  47173. * @brief Provides the member constant `value` to true if a given type is
  47174. * equality comparable, false otherwise.
  47175. * @tparam Type The type to test.
  47176. */
  47177. template<typename Type>
  47178. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  47179. /*! @copydoc is_equality_comparable */
  47180. template<typename Type>
  47181. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  47182. /**
  47183. * @brief Helper variable template.
  47184. * @tparam Type The type to test.
  47185. */
  47186. template<typename Type>
  47187. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  47188. /**
  47189. * @brief Transcribes the constness of a type to another type.
  47190. * @tparam To The type to which to transcribe the constness.
  47191. * @tparam From The type from which to transcribe the constness.
  47192. */
  47193. template<typename To, typename From>
  47194. struct constness_as {
  47195. /*! @brief The type resulting from the transcription of the constness. */
  47196. using type = std::remove_const_t<To>;
  47197. };
  47198. /*! @copydoc constness_as */
  47199. template<typename To, typename From>
  47200. struct constness_as<To, const From> {
  47201. /*! @brief The type resulting from the transcription of the constness. */
  47202. using type = const To;
  47203. };
  47204. /**
  47205. * @brief Alias template to facilitate the transcription of the constness.
  47206. * @tparam To The type to which to transcribe the constness.
  47207. * @tparam From The type from which to transcribe the constness.
  47208. */
  47209. template<typename To, typename From>
  47210. using constness_as_t = typename constness_as<To, From>::type;
  47211. /**
  47212. * @brief Extracts the class of a non-static member object or function.
  47213. * @tparam Member A pointer to a non-static member object or function.
  47214. */
  47215. template<typename Member>
  47216. class member_class {
  47217. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  47218. template<typename Class, typename Ret, typename... Args>
  47219. static Class *clazz(Ret (Class::*)(Args...));
  47220. template<typename Class, typename Ret, typename... Args>
  47221. static Class *clazz(Ret (Class::*)(Args...) const);
  47222. template<typename Class, typename Type>
  47223. static Class *clazz(Type Class::*);
  47224. public:
  47225. /*! @brief The class of the given non-static member object or function. */
  47226. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  47227. };
  47228. /**
  47229. * @brief Helper type.
  47230. * @tparam Member A pointer to a non-static member object or function.
  47231. */
  47232. template<typename Member>
  47233. using member_class_t = typename member_class<Member>::type;
  47234. /**
  47235. * @brief Extracts the n-th argument of a _callable_ type.
  47236. * @tparam Index The index of the argument to extract.
  47237. * @tparam Candidate A valid _callable_ type.
  47238. */
  47239. template<std::size_t Index, typename Candidate>
  47240. class nth_argument {
  47241. template<typename Ret, typename... Args>
  47242. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  47243. template<typename Ret, typename Class, typename... Args>
  47244. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  47245. template<typename Ret, typename Class, typename... Args>
  47246. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  47247. template<typename Type, typename Class>
  47248. static constexpr type_list<Type> pick_up(Type Class ::*);
  47249. template<typename Type>
  47250. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  47251. public:
  47252. /*! @brief N-th argument of the _callable_ type. */
  47253. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  47254. };
  47255. /**
  47256. * @brief Helper type.
  47257. * @tparam Index The index of the argument to extract.
  47258. * @tparam Candidate A valid function, member function or data member type.
  47259. */
  47260. template<std::size_t Index, typename Candidate>
  47261. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  47262. } // namespace entt
  47263. template<typename... Type>
  47264. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  47265. template<std::size_t Index, typename... Type>
  47266. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  47267. template<auto... Value>
  47268. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  47269. template<std::size_t Index, auto... Value>
  47270. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  47271. #endif
  47272. namespace entt {
  47273. /*! @cond TURN_OFF_DOXYGEN */
  47274. namespace internal {
  47275. template<typename Type, std::size_t, typename = void>
  47276. struct compressed_pair_element {
  47277. using reference = Type &;
  47278. using const_reference = const Type &;
  47279. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  47280. // NOLINTNEXTLINE(modernize-use-equals-default)
  47281. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  47282. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  47283. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  47284. : value{std::forward<Arg>(arg)} {}
  47285. template<typename... Args, std::size_t... Index>
  47286. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  47287. : value{std::forward<Args>(std::get<Index>(args))...} {}
  47288. [[nodiscard]] constexpr reference get() noexcept {
  47289. return value;
  47290. }
  47291. [[nodiscard]] constexpr const_reference get() const noexcept {
  47292. return value;
  47293. }
  47294. private:
  47295. Type value{};
  47296. };
  47297. template<typename Type, std::size_t Tag>
  47298. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  47299. using reference = Type &;
  47300. using const_reference = const Type &;
  47301. using base_type = Type;
  47302. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  47303. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  47304. : base_type{} {}
  47305. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  47306. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  47307. : base_type{std::forward<Arg>(arg)} {}
  47308. template<typename... Args, std::size_t... Index>
  47309. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  47310. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  47311. [[nodiscard]] constexpr reference get() noexcept {
  47312. return *this;
  47313. }
  47314. [[nodiscard]] constexpr const_reference get() const noexcept {
  47315. return *this;
  47316. }
  47317. };
  47318. } // namespace internal
  47319. /*! @endcond */
  47320. /**
  47321. * @brief A compressed pair.
  47322. *
  47323. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  47324. * reduce its final size to a minimum.
  47325. *
  47326. * @tparam First The type of the first element that the pair stores.
  47327. * @tparam Second The type of the second element that the pair stores.
  47328. */
  47329. template<typename First, typename Second>
  47330. class compressed_pair final
  47331. : internal::compressed_pair_element<First, 0u>,
  47332. internal::compressed_pair_element<Second, 1u> {
  47333. using first_base = internal::compressed_pair_element<First, 0u>;
  47334. using second_base = internal::compressed_pair_element<Second, 1u>;
  47335. public:
  47336. /*! @brief The type of the first element that the pair stores. */
  47337. using first_type = First;
  47338. /*! @brief The type of the second element that the pair stores. */
  47339. using second_type = Second;
  47340. /**
  47341. * @brief Default constructor, conditionally enabled.
  47342. *
  47343. * This constructor is only available when the types that the pair stores
  47344. * are both at least default constructible.
  47345. *
  47346. * @tparam Dummy Dummy template parameter used for internal purposes.
  47347. */
  47348. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  47349. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  47350. : first_base{},
  47351. second_base{} {}
  47352. /**
  47353. * @brief Copy constructor.
  47354. * @param other The instance to copy from.
  47355. */
  47356. constexpr compressed_pair(const compressed_pair &other) = default;
  47357. /**
  47358. * @brief Move constructor.
  47359. * @param other The instance to move from.
  47360. */
  47361. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  47362. /**
  47363. * @brief Constructs a pair from its values.
  47364. * @tparam Arg Type of value to use to initialize the first element.
  47365. * @tparam Other Type of value to use to initialize the second element.
  47366. * @param arg Value to use to initialize the first element.
  47367. * @param other Value to use to initialize the second element.
  47368. */
  47369. template<typename Arg, typename Other>
  47370. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  47371. : first_base{std::forward<Arg>(arg)},
  47372. second_base{std::forward<Other>(other)} {}
  47373. /**
  47374. * @brief Constructs a pair by forwarding the arguments to its parts.
  47375. * @tparam Args Types of arguments to use to initialize the first element.
  47376. * @tparam Other Types of arguments to use to initialize the second element.
  47377. * @param args Arguments to use to initialize the first element.
  47378. * @param other Arguments to use to initialize the second element.
  47379. */
  47380. template<typename... Args, typename... Other>
  47381. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  47382. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  47383. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  47384. /*! @brief Default destructor. */
  47385. ~compressed_pair() = default;
  47386. /**
  47387. * @brief Copy assignment operator.
  47388. * @param other The instance to copy from.
  47389. * @return This compressed pair object.
  47390. */
  47391. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  47392. /**
  47393. * @brief Move assignment operator.
  47394. * @param other The instance to move from.
  47395. * @return This compressed pair object.
  47396. */
  47397. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  47398. /**
  47399. * @brief Returns the first element that a pair stores.
  47400. * @return The first element that a pair stores.
  47401. */
  47402. [[nodiscard]] constexpr first_type &first() noexcept {
  47403. return static_cast<first_base &>(*this).get();
  47404. }
  47405. /*! @copydoc first */
  47406. [[nodiscard]] constexpr const first_type &first() const noexcept {
  47407. return static_cast<const first_base &>(*this).get();
  47408. }
  47409. /**
  47410. * @brief Returns the second element that a pair stores.
  47411. * @return The second element that a pair stores.
  47412. */
  47413. [[nodiscard]] constexpr second_type &second() noexcept {
  47414. return static_cast<second_base &>(*this).get();
  47415. }
  47416. /*! @copydoc second */
  47417. [[nodiscard]] constexpr const second_type &second() const noexcept {
  47418. return static_cast<const second_base &>(*this).get();
  47419. }
  47420. /**
  47421. * @brief Swaps two compressed pair objects.
  47422. * @param other The compressed pair to swap with.
  47423. */
  47424. constexpr void swap(compressed_pair &other) noexcept {
  47425. using std::swap;
  47426. swap(first(), other.first());
  47427. swap(second(), other.second());
  47428. }
  47429. /**
  47430. * @brief Extracts an element from the compressed pair.
  47431. * @tparam Index An integer value that is either 0 or 1.
  47432. * @return Returns a reference to the first element if `Index` is 0 and a
  47433. * reference to the second element if `Index` is 1.
  47434. */
  47435. template<std::size_t Index>
  47436. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  47437. if constexpr(Index == 0u) {
  47438. return first();
  47439. } else {
  47440. static_assert(Index == 1u, "Index out of bounds");
  47441. return second();
  47442. }
  47443. }
  47444. /*! @copydoc get */
  47445. template<std::size_t Index>
  47446. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  47447. if constexpr(Index == 0u) {
  47448. return first();
  47449. } else {
  47450. static_assert(Index == 1u, "Index out of bounds");
  47451. return second();
  47452. }
  47453. }
  47454. };
  47455. /**
  47456. * @brief Deduction guide.
  47457. * @tparam Type Type of value to use to initialize the first element.
  47458. * @tparam Other Type of value to use to initialize the second element.
  47459. */
  47460. template<typename Type, typename Other>
  47461. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  47462. /**
  47463. * @brief Swaps two compressed pair objects.
  47464. * @tparam First The type of the first element that the pairs store.
  47465. * @tparam Second The type of the second element that the pairs store.
  47466. * @param lhs A valid compressed pair object.
  47467. * @param rhs A valid compressed pair object.
  47468. */
  47469. template<typename First, typename Second>
  47470. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  47471. lhs.swap(rhs);
  47472. }
  47473. } // namespace entt
  47474. namespace std {
  47475. /**
  47476. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  47477. * @tparam First The type of the first element that the pair stores.
  47478. * @tparam Second The type of the second element that the pair stores.
  47479. */
  47480. template<typename First, typename Second>
  47481. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  47482. /**
  47483. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  47484. * @tparam Index The index of the type to return.
  47485. * @tparam First The type of the first element that the pair stores.
  47486. * @tparam Second The type of the second element that the pair stores.
  47487. */
  47488. template<size_t Index, typename First, typename Second>
  47489. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  47490. static_assert(Index < 2u, "Index out of bounds");
  47491. };
  47492. } // namespace std
  47493. #endif
  47494. // #include "../core/iterator.hpp"
  47495. #ifndef ENTT_CORE_ITERATOR_HPP
  47496. #define ENTT_CORE_ITERATOR_HPP
  47497. #include <iterator>
  47498. #include <memory>
  47499. #include <type_traits>
  47500. #include <utility>
  47501. namespace entt {
  47502. /**
  47503. * @brief Helper type to use as pointer with input iterators.
  47504. * @tparam Type of wrapped value.
  47505. */
  47506. template<typename Type>
  47507. struct input_iterator_pointer final {
  47508. /*! @brief Value type. */
  47509. using value_type = Type;
  47510. /*! @brief Pointer type. */
  47511. using pointer = Type *;
  47512. /*! @brief Reference type. */
  47513. using reference = Type &;
  47514. /**
  47515. * @brief Constructs a proxy object by move.
  47516. * @param val Value to use to initialize the proxy object.
  47517. */
  47518. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  47519. : value{std::move(val)} {}
  47520. /**
  47521. * @brief Access operator for accessing wrapped values.
  47522. * @return A pointer to the wrapped value.
  47523. */
  47524. [[nodiscard]] constexpr pointer operator->() noexcept {
  47525. return std::addressof(value);
  47526. }
  47527. /**
  47528. * @brief Dereference operator for accessing wrapped values.
  47529. * @return A reference to the wrapped value.
  47530. */
  47531. [[nodiscard]] constexpr reference operator*() noexcept {
  47532. return value;
  47533. }
  47534. private:
  47535. Type value;
  47536. };
  47537. /**
  47538. * @brief Plain iota iterator (waiting for C++20).
  47539. * @tparam Type Value type.
  47540. */
  47541. template<typename Type>
  47542. class iota_iterator final {
  47543. static_assert(std::is_integral_v<Type>, "Not an integral type");
  47544. public:
  47545. /*! @brief Value type, likely an integral one. */
  47546. using value_type = Type;
  47547. /*! @brief Invalid pointer type. */
  47548. using pointer = void;
  47549. /*! @brief Non-reference type, same as value type. */
  47550. using reference = value_type;
  47551. /*! @brief Difference type. */
  47552. using difference_type = std::ptrdiff_t;
  47553. /*! @brief Iterator category. */
  47554. using iterator_category = std::input_iterator_tag;
  47555. /*! @brief Default constructor. */
  47556. constexpr iota_iterator() noexcept
  47557. : current{} {}
  47558. /**
  47559. * @brief Constructs an iota iterator from a given value.
  47560. * @param init The initial value assigned to the iota iterator.
  47561. */
  47562. constexpr iota_iterator(const value_type init) noexcept
  47563. : current{init} {}
  47564. /**
  47565. * @brief Pre-increment operator.
  47566. * @return This iota iterator.
  47567. */
  47568. constexpr iota_iterator &operator++() noexcept {
  47569. return ++current, *this;
  47570. }
  47571. /**
  47572. * @brief Post-increment operator.
  47573. * @return This iota iterator.
  47574. */
  47575. constexpr iota_iterator operator++(int) noexcept {
  47576. const iota_iterator orig = *this;
  47577. return ++(*this), orig;
  47578. }
  47579. /**
  47580. * @brief Dereference operator.
  47581. * @return The underlying value.
  47582. */
  47583. [[nodiscard]] constexpr reference operator*() const noexcept {
  47584. return current;
  47585. }
  47586. private:
  47587. value_type current;
  47588. };
  47589. /**
  47590. * @brief Comparison operator.
  47591. * @tparam Type Value type of the iota iterator.
  47592. * @param lhs A properly initialized iota iterator.
  47593. * @param rhs A properly initialized iota iterator.
  47594. * @return True if the two iterators are identical, false otherwise.
  47595. */
  47596. template<typename Type>
  47597. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  47598. return *lhs == *rhs;
  47599. }
  47600. /**
  47601. * @brief Comparison operator.
  47602. * @tparam Type Value type of the iota iterator.
  47603. * @param lhs A properly initialized iota iterator.
  47604. * @param rhs A properly initialized iota iterator.
  47605. * @return True if the two iterators differ, false otherwise.
  47606. */
  47607. template<typename Type>
  47608. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  47609. return !(lhs == rhs);
  47610. }
  47611. /**
  47612. * @brief Utility class to create an iterable object from a pair of iterators.
  47613. * @tparam It Type of iterator.
  47614. * @tparam Sentinel Type of sentinel.
  47615. */
  47616. template<typename It, typename Sentinel = It>
  47617. struct iterable_adaptor final {
  47618. /*! @brief Value type. */
  47619. using value_type = typename std::iterator_traits<It>::value_type;
  47620. /*! @brief Iterator type. */
  47621. using iterator = It;
  47622. /*! @brief Sentinel type. */
  47623. using sentinel = Sentinel;
  47624. /*! @brief Default constructor. */
  47625. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  47626. : first{},
  47627. last{} {}
  47628. /**
  47629. * @brief Creates an iterable object from a pair of iterators.
  47630. * @param from Begin iterator.
  47631. * @param to End iterator.
  47632. */
  47633. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  47634. : first{std::move(from)},
  47635. last{std::move(to)} {}
  47636. /**
  47637. * @brief Returns an iterator to the beginning.
  47638. * @return An iterator to the first element of the range.
  47639. */
  47640. [[nodiscard]] constexpr iterator begin() const noexcept {
  47641. return first;
  47642. }
  47643. /**
  47644. * @brief Returns an iterator to the end.
  47645. * @return An iterator to the element following the last element of the
  47646. * range.
  47647. */
  47648. [[nodiscard]] constexpr sentinel end() const noexcept {
  47649. return last;
  47650. }
  47651. /*! @copydoc begin */
  47652. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  47653. return begin();
  47654. }
  47655. /*! @copydoc end */
  47656. [[nodiscard]] constexpr sentinel cend() const noexcept {
  47657. return end();
  47658. }
  47659. private:
  47660. It first;
  47661. Sentinel last;
  47662. };
  47663. } // namespace entt
  47664. #endif
  47665. // #include "../core/memory.hpp"
  47666. #ifndef ENTT_CORE_MEMORY_HPP
  47667. #define ENTT_CORE_MEMORY_HPP
  47668. #include <cstddef>
  47669. #include <memory>
  47670. #include <tuple>
  47671. #include <type_traits>
  47672. #include <utility>
  47673. // #include "../config/config.h"
  47674. namespace entt {
  47675. /**
  47676. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  47677. * @tparam Type Pointer type.
  47678. * @param ptr Fancy or raw pointer.
  47679. * @return A raw pointer that represents the address of the original pointer.
  47680. */
  47681. template<typename Type>
  47682. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  47683. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  47684. return ptr;
  47685. } else {
  47686. return to_address(std::forward<Type>(ptr).operator->());
  47687. }
  47688. }
  47689. /**
  47690. * @brief Utility function to design allocation-aware containers.
  47691. * @tparam Allocator Type of allocator.
  47692. * @param lhs A valid allocator.
  47693. * @param rhs Another valid allocator.
  47694. */
  47695. template<typename Allocator>
  47696. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  47697. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  47698. lhs = rhs;
  47699. }
  47700. }
  47701. /**
  47702. * @brief Utility function to design allocation-aware containers.
  47703. * @tparam Allocator Type of allocator.
  47704. * @param lhs A valid allocator.
  47705. * @param rhs Another valid allocator.
  47706. */
  47707. template<typename Allocator>
  47708. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  47709. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  47710. lhs = std::move(rhs);
  47711. }
  47712. }
  47713. /**
  47714. * @brief Utility function to design allocation-aware containers.
  47715. * @tparam Allocator Type of allocator.
  47716. * @param lhs A valid allocator.
  47717. * @param rhs Another valid allocator.
  47718. */
  47719. template<typename Allocator>
  47720. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  47721. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  47722. using std::swap;
  47723. swap(lhs, rhs);
  47724. } else {
  47725. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  47726. }
  47727. }
  47728. /**
  47729. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  47730. * @tparam Allocator Type of allocator used to manage memory and elements.
  47731. */
  47732. template<typename Allocator>
  47733. struct allocation_deleter: private Allocator {
  47734. /*! @brief Allocator type. */
  47735. using allocator_type = Allocator;
  47736. /*! @brief Pointer type. */
  47737. using pointer = typename std::allocator_traits<Allocator>::pointer;
  47738. /**
  47739. * @brief Inherited constructors.
  47740. * @param alloc The allocator to use.
  47741. */
  47742. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  47743. : Allocator{alloc} {}
  47744. /**
  47745. * @brief Destroys the pointed object and deallocates its memory.
  47746. * @param ptr A valid pointer to an object of the given type.
  47747. */
  47748. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  47749. using alloc_traits = std::allocator_traits<Allocator>;
  47750. alloc_traits::destroy(*this, to_address(ptr));
  47751. alloc_traits::deallocate(*this, ptr, 1u);
  47752. }
  47753. };
  47754. /**
  47755. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  47756. * @tparam Type Type of object to allocate for and to construct.
  47757. * @tparam Allocator Type of allocator used to manage memory and elements.
  47758. * @tparam Args Types of arguments to use to construct the object.
  47759. * @param allocator The allocator to use.
  47760. * @param args Parameters to use to construct the object.
  47761. * @return A properly initialized unique pointer with a custom deleter.
  47762. */
  47763. template<typename Type, typename Allocator, typename... Args>
  47764. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  47765. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  47766. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  47767. using allocator_type = typename alloc_traits::allocator_type;
  47768. allocator_type alloc{allocator};
  47769. auto ptr = alloc_traits::allocate(alloc, 1u);
  47770. ENTT_TRY {
  47771. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  47772. }
  47773. ENTT_CATCH {
  47774. alloc_traits::deallocate(alloc, ptr, 1u);
  47775. ENTT_THROW;
  47776. }
  47777. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  47778. }
  47779. /*! @cond TURN_OFF_DOXYGEN */
  47780. namespace internal {
  47781. template<typename Type>
  47782. struct uses_allocator_construction {
  47783. template<typename Allocator, typename... Params>
  47784. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  47785. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  47786. return std::forward_as_tuple(std::forward<Params>(params)...);
  47787. } else {
  47788. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  47789. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  47790. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  47791. } else {
  47792. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  47793. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  47794. }
  47795. }
  47796. }
  47797. };
  47798. template<typename Type, typename Other>
  47799. struct uses_allocator_construction<std::pair<Type, Other>> {
  47800. using type = std::pair<Type, Other>;
  47801. template<typename Allocator, typename First, typename Second>
  47802. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  47803. return std::make_tuple(
  47804. std::piecewise_construct,
  47805. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  47806. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  47807. }
  47808. template<typename Allocator>
  47809. static constexpr auto args(const Allocator &allocator) noexcept {
  47810. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  47811. }
  47812. template<typename Allocator, typename First, typename Second>
  47813. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  47814. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  47815. }
  47816. template<typename Allocator, typename First, typename Second>
  47817. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  47818. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  47819. }
  47820. template<typename Allocator, typename First, typename Second>
  47821. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  47822. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  47823. }
  47824. };
  47825. } // namespace internal
  47826. /*! @endcond */
  47827. /**
  47828. * @brief Uses-allocator construction utility (waiting for C++20).
  47829. *
  47830. * Primarily intended for internal use. Prepares the argument list needed to
  47831. * create an object of a given type by means of uses-allocator construction.
  47832. *
  47833. * @tparam Type Type to return arguments for.
  47834. * @tparam Allocator Type of allocator used to manage memory and elements.
  47835. * @tparam Args Types of arguments to use to construct the object.
  47836. * @param allocator The allocator to use.
  47837. * @param args Parameters to use to construct the object.
  47838. * @return The arguments needed to create an object of the given type.
  47839. */
  47840. template<typename Type, typename Allocator, typename... Args>
  47841. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  47842. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  47843. }
  47844. /**
  47845. * @brief Uses-allocator construction utility (waiting for C++20).
  47846. *
  47847. * Primarily intended for internal use. Creates an object of a given type by
  47848. * means of uses-allocator construction.
  47849. *
  47850. * @tparam Type Type of object to create.
  47851. * @tparam Allocator Type of allocator used to manage memory and elements.
  47852. * @tparam Args Types of arguments to use to construct the object.
  47853. * @param allocator The allocator to use.
  47854. * @param args Parameters to use to construct the object.
  47855. * @return A newly created object of the given type.
  47856. */
  47857. template<typename Type, typename Allocator, typename... Args>
  47858. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  47859. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  47860. }
  47861. /**
  47862. * @brief Uses-allocator construction utility (waiting for C++20).
  47863. *
  47864. * Primarily intended for internal use. Creates an object of a given type by
  47865. * means of uses-allocator construction at an uninitialized memory location.
  47866. *
  47867. * @tparam Type Type of object to create.
  47868. * @tparam Allocator Type of allocator used to manage memory and elements.
  47869. * @tparam Args Types of arguments to use to construct the object.
  47870. * @param value Memory location in which to place the object.
  47871. * @param allocator The allocator to use.
  47872. * @param args Parameters to use to construct the object.
  47873. * @return A pointer to the newly created object of the given type.
  47874. */
  47875. template<typename Type, typename Allocator, typename... Args>
  47876. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  47877. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  47878. }
  47879. } // namespace entt
  47880. #endif
  47881. // #include "../core/type_traits.hpp"
  47882. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  47883. #define ENTT_CORE_TYPE_TRAITS_HPP
  47884. #include <cstddef>
  47885. #include <iterator>
  47886. #include <tuple>
  47887. #include <type_traits>
  47888. #include <utility>
  47889. // #include "../config/config.h"
  47890. // #include "fwd.hpp"
  47891. namespace entt {
  47892. /**
  47893. * @brief Utility class to disambiguate overloaded functions.
  47894. * @tparam N Number of choices available.
  47895. */
  47896. template<std::size_t N>
  47897. struct choice_t
  47898. // unfortunately, doxygen cannot parse such a construct
  47899. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  47900. {};
  47901. /*! @copybrief choice_t */
  47902. template<>
  47903. struct choice_t<0> {};
  47904. /**
  47905. * @brief Variable template for the choice trick.
  47906. * @tparam N Number of choices available.
  47907. */
  47908. template<std::size_t N>
  47909. inline constexpr choice_t<N> choice{};
  47910. /**
  47911. * @brief Identity type trait.
  47912. *
  47913. * Useful to establish non-deduced contexts in template argument deduction
  47914. * (waiting for C++20) or to provide types through function arguments.
  47915. *
  47916. * @tparam Type A type.
  47917. */
  47918. template<typename Type>
  47919. struct type_identity {
  47920. /*! @brief Identity type. */
  47921. using type = Type;
  47922. };
  47923. /**
  47924. * @brief Helper type.
  47925. * @tparam Type A type.
  47926. */
  47927. template<typename Type>
  47928. using type_identity_t = typename type_identity<Type>::type;
  47929. /**
  47930. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  47931. * @tparam Type The type of which to return the size.
  47932. */
  47933. template<typename Type, typename = void>
  47934. struct size_of: std::integral_constant<std::size_t, 0u> {};
  47935. /*! @copydoc size_of */
  47936. template<typename Type>
  47937. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  47938. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  47939. : std::integral_constant<std::size_t, sizeof(Type)> {};
  47940. /**
  47941. * @brief Helper variable template.
  47942. * @tparam Type The type of which to return the size.
  47943. */
  47944. template<typename Type>
  47945. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  47946. /**
  47947. * @brief Using declaration to be used to _repeat_ the same type a number of
  47948. * times equal to the size of a given parameter pack.
  47949. * @tparam Type A type to repeat.
  47950. */
  47951. template<typename Type, typename>
  47952. using unpack_as_type = Type;
  47953. /**
  47954. * @brief Helper variable template to be used to _repeat_ the same value a
  47955. * number of times equal to the size of a given parameter pack.
  47956. * @tparam Value A value to repeat.
  47957. */
  47958. template<auto Value, typename>
  47959. inline constexpr auto unpack_as_value = Value;
  47960. /**
  47961. * @brief Wraps a static constant.
  47962. * @tparam Value A static constant.
  47963. */
  47964. template<auto Value>
  47965. using integral_constant = std::integral_constant<decltype(Value), Value>;
  47966. /**
  47967. * @brief Alias template to facilitate the creation of named values.
  47968. * @tparam Value A constant value at least convertible to `id_type`.
  47969. */
  47970. template<id_type Value>
  47971. using tag = integral_constant<Value>;
  47972. /**
  47973. * @brief A class to use to push around lists of types, nothing more.
  47974. * @tparam Type Types provided by the type list.
  47975. */
  47976. template<typename... Type>
  47977. struct type_list {
  47978. /*! @brief Type list type. */
  47979. using type = type_list;
  47980. /*! @brief Compile-time number of elements in the type list. */
  47981. static constexpr auto size = sizeof...(Type);
  47982. };
  47983. /*! @brief Primary template isn't defined on purpose. */
  47984. template<std::size_t, typename>
  47985. struct type_list_element;
  47986. /**
  47987. * @brief Provides compile-time indexed access to the types of a type list.
  47988. * @tparam Index Index of the type to return.
  47989. * @tparam First First type provided by the type list.
  47990. * @tparam Other Other types provided by the type list.
  47991. */
  47992. template<std::size_t Index, typename First, typename... Other>
  47993. struct type_list_element<Index, type_list<First, Other...>>
  47994. : type_list_element<Index - 1u, type_list<Other...>> {};
  47995. /**
  47996. * @brief Provides compile-time indexed access to the types of a type list.
  47997. * @tparam First First type provided by the type list.
  47998. * @tparam Other Other types provided by the type list.
  47999. */
  48000. template<typename First, typename... Other>
  48001. struct type_list_element<0u, type_list<First, Other...>> {
  48002. /*! @brief Searched type. */
  48003. using type = First;
  48004. };
  48005. /**
  48006. * @brief Helper type.
  48007. * @tparam Index Index of the type to return.
  48008. * @tparam List Type list to search into.
  48009. */
  48010. template<std::size_t Index, typename List>
  48011. using type_list_element_t = typename type_list_element<Index, List>::type;
  48012. /*! @brief Primary template isn't defined on purpose. */
  48013. template<typename, typename>
  48014. struct type_list_index;
  48015. /**
  48016. * @brief Provides compile-time type access to the types of a type list.
  48017. * @tparam Type Type to look for and for which to return the index.
  48018. * @tparam First First type provided by the type list.
  48019. * @tparam Other Other types provided by the type list.
  48020. */
  48021. template<typename Type, typename First, typename... Other>
  48022. struct type_list_index<Type, type_list<First, Other...>> {
  48023. /*! @brief Unsigned integer type. */
  48024. using value_type = std::size_t;
  48025. /*! @brief Compile-time position of the given type in the sublist. */
  48026. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  48027. };
  48028. /**
  48029. * @brief Provides compile-time type access to the types of a type list.
  48030. * @tparam Type Type to look for and for which to return the index.
  48031. * @tparam Other Other types provided by the type list.
  48032. */
  48033. template<typename Type, typename... Other>
  48034. struct type_list_index<Type, type_list<Type, Other...>> {
  48035. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  48036. /*! @brief Unsigned integer type. */
  48037. using value_type = std::size_t;
  48038. /*! @brief Compile-time position of the given type in the sublist. */
  48039. static constexpr value_type value = 0u;
  48040. };
  48041. /**
  48042. * @brief Provides compile-time type access to the types of a type list.
  48043. * @tparam Type Type to look for and for which to return the index.
  48044. */
  48045. template<typename Type>
  48046. struct type_list_index<Type, type_list<>> {
  48047. /*! @brief Unsigned integer type. */
  48048. using value_type = std::size_t;
  48049. /*! @brief Compile-time position of the given type in the sublist. */
  48050. static constexpr value_type value = 0u;
  48051. };
  48052. /**
  48053. * @brief Helper variable template.
  48054. * @tparam List Type list.
  48055. * @tparam Type Type to look for and for which to return the index.
  48056. */
  48057. template<typename Type, typename List>
  48058. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  48059. /**
  48060. * @brief Concatenates multiple type lists.
  48061. * @tparam Type Types provided by the first type list.
  48062. * @tparam Other Types provided by the second type list.
  48063. * @return A type list composed by the types of both the type lists.
  48064. */
  48065. template<typename... Type, typename... Other>
  48066. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  48067. return {};
  48068. }
  48069. /*! @brief Primary template isn't defined on purpose. */
  48070. template<typename...>
  48071. struct type_list_cat;
  48072. /*! @brief Concatenates multiple type lists. */
  48073. template<>
  48074. struct type_list_cat<> {
  48075. /*! @brief A type list composed by the types of all the type lists. */
  48076. using type = type_list<>;
  48077. };
  48078. /**
  48079. * @brief Concatenates multiple type lists.
  48080. * @tparam Type Types provided by the first type list.
  48081. * @tparam Other Types provided by the second type list.
  48082. * @tparam List Other type lists, if any.
  48083. */
  48084. template<typename... Type, typename... Other, typename... List>
  48085. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  48086. /*! @brief A type list composed by the types of all the type lists. */
  48087. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  48088. };
  48089. /**
  48090. * @brief Concatenates multiple type lists.
  48091. * @tparam Type Types provided by the type list.
  48092. */
  48093. template<typename... Type>
  48094. struct type_list_cat<type_list<Type...>> {
  48095. /*! @brief A type list composed by the types of all the type lists. */
  48096. using type = type_list<Type...>;
  48097. };
  48098. /**
  48099. * @brief Helper type.
  48100. * @tparam List Type lists to concatenate.
  48101. */
  48102. template<typename... List>
  48103. using type_list_cat_t = typename type_list_cat<List...>::type;
  48104. /*! @cond TURN_OFF_DOXYGEN */
  48105. namespace internal {
  48106. template<typename...>
  48107. struct type_list_unique;
  48108. template<typename First, typename... Other, typename... Type>
  48109. struct type_list_unique<type_list<First, Other...>, Type...>
  48110. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  48111. template<typename... Type>
  48112. struct type_list_unique<type_list<>, Type...> {
  48113. using type = type_list<Type...>;
  48114. };
  48115. } // namespace internal
  48116. /*! @endcond */
  48117. /**
  48118. * @brief Removes duplicates types from a type list.
  48119. * @tparam List Type list.
  48120. */
  48121. template<typename List>
  48122. struct type_list_unique {
  48123. /*! @brief A type list without duplicate types. */
  48124. using type = typename internal::type_list_unique<List>::type;
  48125. };
  48126. /**
  48127. * @brief Helper type.
  48128. * @tparam List Type list.
  48129. */
  48130. template<typename List>
  48131. using type_list_unique_t = typename type_list_unique<List>::type;
  48132. /**
  48133. * @brief Provides the member constant `value` to true if a type list contains a
  48134. * given type, false otherwise.
  48135. * @tparam List Type list.
  48136. * @tparam Type Type to look for.
  48137. */
  48138. template<typename List, typename Type>
  48139. struct type_list_contains;
  48140. /**
  48141. * @copybrief type_list_contains
  48142. * @tparam Type Types provided by the type list.
  48143. * @tparam Other Type to look for.
  48144. */
  48145. template<typename... Type, typename Other>
  48146. struct type_list_contains<type_list<Type...>, Other>
  48147. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  48148. /**
  48149. * @brief Helper variable template.
  48150. * @tparam List Type list.
  48151. * @tparam Type Type to look for.
  48152. */
  48153. template<typename List, typename Type>
  48154. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  48155. /*! @brief Primary template isn't defined on purpose. */
  48156. template<typename...>
  48157. struct type_list_diff;
  48158. /**
  48159. * @brief Computes the difference between two type lists.
  48160. * @tparam Type Types provided by the first type list.
  48161. * @tparam Other Types provided by the second type list.
  48162. */
  48163. template<typename... Type, typename... Other>
  48164. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  48165. /*! @brief A type list that is the difference between the two type lists. */
  48166. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  48167. };
  48168. /**
  48169. * @brief Helper type.
  48170. * @tparam List Type lists between which to compute the difference.
  48171. */
  48172. template<typename... List>
  48173. using type_list_diff_t = typename type_list_diff<List...>::type;
  48174. /*! @brief Primary template isn't defined on purpose. */
  48175. template<typename, template<typename...> class>
  48176. struct type_list_transform;
  48177. /**
  48178. * @brief Applies a given _function_ to a type list and generate a new list.
  48179. * @tparam Type Types provided by the type list.
  48180. * @tparam Op Unary operation as template class with a type member named `type`.
  48181. */
  48182. template<typename... Type, template<typename...> class Op>
  48183. struct type_list_transform<type_list<Type...>, Op> {
  48184. /*! @brief Resulting type list after applying the transform function. */
  48185. // NOLINTNEXTLINE(modernize-type-traits)
  48186. using type = type_list<typename Op<Type>::type...>;
  48187. };
  48188. /**
  48189. * @brief Helper type.
  48190. * @tparam List Type list.
  48191. * @tparam Op Unary operation as template class with a type member named `type`.
  48192. */
  48193. template<typename List, template<typename...> class Op>
  48194. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  48195. /**
  48196. * @brief A class to use to push around lists of constant values, nothing more.
  48197. * @tparam Value Values provided by the value list.
  48198. */
  48199. template<auto... Value>
  48200. struct value_list {
  48201. /*! @brief Value list type. */
  48202. using type = value_list;
  48203. /*! @brief Compile-time number of elements in the value list. */
  48204. static constexpr auto size = sizeof...(Value);
  48205. };
  48206. /*! @brief Primary template isn't defined on purpose. */
  48207. template<std::size_t, typename>
  48208. struct value_list_element;
  48209. /**
  48210. * @brief Provides compile-time indexed access to the values of a value list.
  48211. * @tparam Index Index of the value to return.
  48212. * @tparam Value First value provided by the value list.
  48213. * @tparam Other Other values provided by the value list.
  48214. */
  48215. template<std::size_t Index, auto Value, auto... Other>
  48216. struct value_list_element<Index, value_list<Value, Other...>>
  48217. : value_list_element<Index - 1u, value_list<Other...>> {};
  48218. /**
  48219. * @brief Provides compile-time indexed access to the types of a type list.
  48220. * @tparam Value First value provided by the value list.
  48221. * @tparam Other Other values provided by the value list.
  48222. */
  48223. template<auto Value, auto... Other>
  48224. struct value_list_element<0u, value_list<Value, Other...>> {
  48225. /*! @brief Searched type. */
  48226. using type = decltype(Value);
  48227. /*! @brief Searched value. */
  48228. static constexpr auto value = Value;
  48229. };
  48230. /**
  48231. * @brief Helper type.
  48232. * @tparam Index Index of the type to return.
  48233. * @tparam List Value list to search into.
  48234. */
  48235. template<std::size_t Index, typename List>
  48236. using value_list_element_t = typename value_list_element<Index, List>::type;
  48237. /**
  48238. * @brief Helper type.
  48239. * @tparam Index Index of the value to return.
  48240. * @tparam List Value list to search into.
  48241. */
  48242. template<std::size_t Index, typename List>
  48243. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  48244. /*! @brief Primary template isn't defined on purpose. */
  48245. template<auto, typename>
  48246. struct value_list_index;
  48247. /**
  48248. * @brief Provides compile-time type access to the values of a value list.
  48249. * @tparam Value Value to look for and for which to return the index.
  48250. * @tparam First First value provided by the value list.
  48251. * @tparam Other Other values provided by the value list.
  48252. */
  48253. template<auto Value, auto First, auto... Other>
  48254. struct value_list_index<Value, value_list<First, Other...>> {
  48255. /*! @brief Unsigned integer type. */
  48256. using value_type = std::size_t;
  48257. /*! @brief Compile-time position of the given value in the sublist. */
  48258. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  48259. };
  48260. /**
  48261. * @brief Provides compile-time type access to the values of a value list.
  48262. * @tparam Value Value to look for and for which to return the index.
  48263. * @tparam Other Other values provided by the value list.
  48264. */
  48265. template<auto Value, auto... Other>
  48266. struct value_list_index<Value, value_list<Value, Other...>> {
  48267. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  48268. /*! @brief Unsigned integer type. */
  48269. using value_type = std::size_t;
  48270. /*! @brief Compile-time position of the given value in the sublist. */
  48271. static constexpr value_type value = 0u;
  48272. };
  48273. /**
  48274. * @brief Provides compile-time type access to the values of a value list.
  48275. * @tparam Value Value to look for and for which to return the index.
  48276. */
  48277. template<auto Value>
  48278. struct value_list_index<Value, value_list<>> {
  48279. /*! @brief Unsigned integer type. */
  48280. using value_type = std::size_t;
  48281. /*! @brief Compile-time position of the given type in the sublist. */
  48282. static constexpr value_type value = 0u;
  48283. };
  48284. /**
  48285. * @brief Helper variable template.
  48286. * @tparam List Value list.
  48287. * @tparam Value Value to look for and for which to return the index.
  48288. */
  48289. template<auto Value, typename List>
  48290. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  48291. /**
  48292. * @brief Concatenates multiple value lists.
  48293. * @tparam Value Values provided by the first value list.
  48294. * @tparam Other Values provided by the second value list.
  48295. * @return A value list composed by the values of both the value lists.
  48296. */
  48297. template<auto... Value, auto... Other>
  48298. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  48299. return {};
  48300. }
  48301. /*! @brief Primary template isn't defined on purpose. */
  48302. template<typename...>
  48303. struct value_list_cat;
  48304. /*! @brief Concatenates multiple value lists. */
  48305. template<>
  48306. struct value_list_cat<> {
  48307. /*! @brief A value list composed by the values of all the value lists. */
  48308. using type = value_list<>;
  48309. };
  48310. /**
  48311. * @brief Concatenates multiple value lists.
  48312. * @tparam Value Values provided by the first value list.
  48313. * @tparam Other Values provided by the second value list.
  48314. * @tparam List Other value lists, if any.
  48315. */
  48316. template<auto... Value, auto... Other, typename... List>
  48317. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  48318. /*! @brief A value list composed by the values of all the value lists. */
  48319. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  48320. };
  48321. /**
  48322. * @brief Concatenates multiple value lists.
  48323. * @tparam Value Values provided by the value list.
  48324. */
  48325. template<auto... Value>
  48326. struct value_list_cat<value_list<Value...>> {
  48327. /*! @brief A value list composed by the values of all the value lists. */
  48328. using type = value_list<Value...>;
  48329. };
  48330. /**
  48331. * @brief Helper type.
  48332. * @tparam List Value lists to concatenate.
  48333. */
  48334. template<typename... List>
  48335. using value_list_cat_t = typename value_list_cat<List...>::type;
  48336. /*! @brief Primary template isn't defined on purpose. */
  48337. template<typename>
  48338. struct value_list_unique;
  48339. /**
  48340. * @brief Removes duplicates values from a value list.
  48341. * @tparam Value One of the values provided by the given value list.
  48342. * @tparam Other The other values provided by the given value list.
  48343. */
  48344. template<auto Value, auto... Other>
  48345. struct value_list_unique<value_list<Value, Other...>> {
  48346. /*! @brief A value list without duplicate types. */
  48347. using type = std::conditional_t<
  48348. ((Value == Other) || ...),
  48349. typename value_list_unique<value_list<Other...>>::type,
  48350. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  48351. };
  48352. /*! @brief Removes duplicates values from a value list. */
  48353. template<>
  48354. struct value_list_unique<value_list<>> {
  48355. /*! @brief A value list without duplicate types. */
  48356. using type = value_list<>;
  48357. };
  48358. /**
  48359. * @brief Helper type.
  48360. * @tparam Type A value list.
  48361. */
  48362. template<typename Type>
  48363. using value_list_unique_t = typename value_list_unique<Type>::type;
  48364. /**
  48365. * @brief Provides the member constant `value` to true if a value list contains
  48366. * a given value, false otherwise.
  48367. * @tparam List Value list.
  48368. * @tparam Value Value to look for.
  48369. */
  48370. template<typename List, auto Value>
  48371. struct value_list_contains;
  48372. /**
  48373. * @copybrief value_list_contains
  48374. * @tparam Value Values provided by the value list.
  48375. * @tparam Other Value to look for.
  48376. */
  48377. template<auto... Value, auto Other>
  48378. struct value_list_contains<value_list<Value...>, Other>
  48379. : std::bool_constant<((Value == Other) || ...)> {};
  48380. /**
  48381. * @brief Helper variable template.
  48382. * @tparam List Value list.
  48383. * @tparam Value Value to look for.
  48384. */
  48385. template<typename List, auto Value>
  48386. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  48387. /*! @brief Primary template isn't defined on purpose. */
  48388. template<typename...>
  48389. struct value_list_diff;
  48390. /**
  48391. * @brief Computes the difference between two value lists.
  48392. * @tparam Value Values provided by the first value list.
  48393. * @tparam Other Values provided by the second value list.
  48394. */
  48395. template<auto... Value, auto... Other>
  48396. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  48397. /*! @brief A value list that is the difference between the two value lists. */
  48398. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  48399. };
  48400. /**
  48401. * @brief Helper type.
  48402. * @tparam List Value lists between which to compute the difference.
  48403. */
  48404. template<typename... List>
  48405. using value_list_diff_t = typename value_list_diff<List...>::type;
  48406. /*! @brief Same as std::is_invocable, but with tuples. */
  48407. template<typename, typename>
  48408. struct is_applicable: std::false_type {};
  48409. /**
  48410. * @copybrief is_applicable
  48411. * @tparam Func A valid function type.
  48412. * @tparam Tuple Tuple-like type.
  48413. * @tparam Args The list of arguments to use to probe the function type.
  48414. */
  48415. template<typename Func, template<typename...> class Tuple, typename... Args>
  48416. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  48417. /**
  48418. * @copybrief is_applicable
  48419. * @tparam Func A valid function type.
  48420. * @tparam Tuple Tuple-like type.
  48421. * @tparam Args The list of arguments to use to probe the function type.
  48422. */
  48423. template<typename Func, template<typename...> class Tuple, typename... Args>
  48424. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  48425. /**
  48426. * @brief Helper variable template.
  48427. * @tparam Func A valid function type.
  48428. * @tparam Args The list of arguments to use to probe the function type.
  48429. */
  48430. template<typename Func, typename Args>
  48431. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  48432. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  48433. template<typename, typename, typename>
  48434. struct is_applicable_r: std::false_type {};
  48435. /**
  48436. * @copybrief is_applicable_r
  48437. * @tparam Ret The type to which the return type of the function should be
  48438. * convertible.
  48439. * @tparam Func A valid function type.
  48440. * @tparam Args The list of arguments to use to probe the function type.
  48441. */
  48442. template<typename Ret, typename Func, typename... Args>
  48443. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  48444. /**
  48445. * @brief Helper variable template.
  48446. * @tparam Ret The type to which the return type of the function should be
  48447. * convertible.
  48448. * @tparam Func A valid function type.
  48449. * @tparam Args The list of arguments to use to probe the function type.
  48450. */
  48451. template<typename Ret, typename Func, typename Args>
  48452. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  48453. /**
  48454. * @brief Provides the member constant `value` to true if a given type is
  48455. * complete, false otherwise.
  48456. * @tparam Type The type to test.
  48457. */
  48458. template<typename Type, typename = void>
  48459. struct is_complete: std::false_type {};
  48460. /*! @copydoc is_complete */
  48461. template<typename Type>
  48462. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  48463. /**
  48464. * @brief Helper variable template.
  48465. * @tparam Type The type to test.
  48466. */
  48467. template<typename Type>
  48468. inline constexpr bool is_complete_v = is_complete<Type>::value;
  48469. /**
  48470. * @brief Provides the member constant `value` to true if a given type is an
  48471. * iterator, false otherwise.
  48472. * @tparam Type The type to test.
  48473. */
  48474. template<typename Type, typename = void>
  48475. struct is_iterator: std::false_type {};
  48476. /*! @cond TURN_OFF_DOXYGEN */
  48477. namespace internal {
  48478. template<typename, typename = void>
  48479. struct has_iterator_category: std::false_type {};
  48480. template<typename Type>
  48481. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  48482. } // namespace internal
  48483. /*! @endcond */
  48484. /*! @copydoc is_iterator */
  48485. template<typename Type>
  48486. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  48487. : internal::has_iterator_category<Type> {};
  48488. /**
  48489. * @brief Helper variable template.
  48490. * @tparam Type The type to test.
  48491. */
  48492. template<typename Type>
  48493. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  48494. /**
  48495. * @brief Provides the member constant `value` to true if a given type is both
  48496. * an empty and non-final class, false otherwise.
  48497. * @tparam Type The type to test
  48498. */
  48499. template<typename Type>
  48500. struct is_ebco_eligible
  48501. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  48502. /**
  48503. * @brief Helper variable template.
  48504. * @tparam Type The type to test.
  48505. */
  48506. template<typename Type>
  48507. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  48508. /**
  48509. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  48510. * is valid and denotes a type, false otherwise.
  48511. * @tparam Type The type to test.
  48512. */
  48513. template<typename Type, typename = void>
  48514. struct is_transparent: std::false_type {};
  48515. /*! @copydoc is_transparent */
  48516. template<typename Type>
  48517. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  48518. /**
  48519. * @brief Helper variable template.
  48520. * @tparam Type The type to test.
  48521. */
  48522. template<typename Type>
  48523. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  48524. /*! @cond TURN_OFF_DOXYGEN */
  48525. namespace internal {
  48526. template<typename, typename = void>
  48527. struct has_tuple_size_value: std::false_type {};
  48528. template<typename Type>
  48529. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  48530. template<typename, typename = void>
  48531. struct has_value_type: std::false_type {};
  48532. template<typename Type>
  48533. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  48534. template<typename>
  48535. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  48536. template<typename Type, std::size_t... Index>
  48537. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  48538. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  48539. }
  48540. template<typename>
  48541. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  48542. return false;
  48543. }
  48544. template<typename Type>
  48545. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  48546. return true;
  48547. }
  48548. template<typename Type>
  48549. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  48550. // NOLINTBEGIN(modernize-use-transparent-functors)
  48551. if constexpr(std::is_array_v<Type>) {
  48552. return false;
  48553. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  48554. if constexpr(has_tuple_size_value<Type>::value) {
  48555. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  48556. } else {
  48557. return maybe_equality_comparable<Type>(0);
  48558. }
  48559. } else if constexpr(has_value_type<Type>::value) {
  48560. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  48561. return maybe_equality_comparable<Type>(0);
  48562. } else {
  48563. return false;
  48564. }
  48565. } else {
  48566. return maybe_equality_comparable<Type>(0);
  48567. }
  48568. // NOLINTEND(modernize-use-transparent-functors)
  48569. }
  48570. } // namespace internal
  48571. /*! @endcond */
  48572. /**
  48573. * @brief Provides the member constant `value` to true if a given type is
  48574. * equality comparable, false otherwise.
  48575. * @tparam Type The type to test.
  48576. */
  48577. template<typename Type>
  48578. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  48579. /*! @copydoc is_equality_comparable */
  48580. template<typename Type>
  48581. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  48582. /**
  48583. * @brief Helper variable template.
  48584. * @tparam Type The type to test.
  48585. */
  48586. template<typename Type>
  48587. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  48588. /**
  48589. * @brief Transcribes the constness of a type to another type.
  48590. * @tparam To The type to which to transcribe the constness.
  48591. * @tparam From The type from which to transcribe the constness.
  48592. */
  48593. template<typename To, typename From>
  48594. struct constness_as {
  48595. /*! @brief The type resulting from the transcription of the constness. */
  48596. using type = std::remove_const_t<To>;
  48597. };
  48598. /*! @copydoc constness_as */
  48599. template<typename To, typename From>
  48600. struct constness_as<To, const From> {
  48601. /*! @brief The type resulting from the transcription of the constness. */
  48602. using type = const To;
  48603. };
  48604. /**
  48605. * @brief Alias template to facilitate the transcription of the constness.
  48606. * @tparam To The type to which to transcribe the constness.
  48607. * @tparam From The type from which to transcribe the constness.
  48608. */
  48609. template<typename To, typename From>
  48610. using constness_as_t = typename constness_as<To, From>::type;
  48611. /**
  48612. * @brief Extracts the class of a non-static member object or function.
  48613. * @tparam Member A pointer to a non-static member object or function.
  48614. */
  48615. template<typename Member>
  48616. class member_class {
  48617. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  48618. template<typename Class, typename Ret, typename... Args>
  48619. static Class *clazz(Ret (Class::*)(Args...));
  48620. template<typename Class, typename Ret, typename... Args>
  48621. static Class *clazz(Ret (Class::*)(Args...) const);
  48622. template<typename Class, typename Type>
  48623. static Class *clazz(Type Class::*);
  48624. public:
  48625. /*! @brief The class of the given non-static member object or function. */
  48626. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  48627. };
  48628. /**
  48629. * @brief Helper type.
  48630. * @tparam Member A pointer to a non-static member object or function.
  48631. */
  48632. template<typename Member>
  48633. using member_class_t = typename member_class<Member>::type;
  48634. /**
  48635. * @brief Extracts the n-th argument of a _callable_ type.
  48636. * @tparam Index The index of the argument to extract.
  48637. * @tparam Candidate A valid _callable_ type.
  48638. */
  48639. template<std::size_t Index, typename Candidate>
  48640. class nth_argument {
  48641. template<typename Ret, typename... Args>
  48642. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  48643. template<typename Ret, typename Class, typename... Args>
  48644. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  48645. template<typename Ret, typename Class, typename... Args>
  48646. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  48647. template<typename Type, typename Class>
  48648. static constexpr type_list<Type> pick_up(Type Class ::*);
  48649. template<typename Type>
  48650. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  48651. public:
  48652. /*! @brief N-th argument of the _callable_ type. */
  48653. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  48654. };
  48655. /**
  48656. * @brief Helper type.
  48657. * @tparam Index The index of the argument to extract.
  48658. * @tparam Candidate A valid function, member function or data member type.
  48659. */
  48660. template<std::size_t Index, typename Candidate>
  48661. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  48662. } // namespace entt
  48663. template<typename... Type>
  48664. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  48665. template<std::size_t Index, typename... Type>
  48666. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  48667. template<auto... Value>
  48668. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  48669. template<std::size_t Index, auto... Value>
  48670. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  48671. #endif
  48672. // #include "fwd.hpp"
  48673. #ifndef ENTT_CONTAINER_FWD_HPP
  48674. #define ENTT_CONTAINER_FWD_HPP
  48675. #include <functional>
  48676. #include <memory>
  48677. #include <utility>
  48678. #include <vector>
  48679. namespace entt {
  48680. template<
  48681. typename Key,
  48682. typename Type,
  48683. typename = std::hash<Key>,
  48684. typename = std::equal_to<>,
  48685. typename = std::allocator<std::pair<const Key, Type>>>
  48686. class dense_map;
  48687. template<
  48688. typename Type,
  48689. typename = std::hash<Type>,
  48690. typename = std::equal_to<>,
  48691. typename = std::allocator<Type>>
  48692. class dense_set;
  48693. template<typename...>
  48694. class basic_table;
  48695. /**
  48696. * @brief Alias declaration for the most common use case.
  48697. * @tparam Type Element types.
  48698. */
  48699. template<typename... Type>
  48700. using table = basic_table<std::vector<Type>...>;
  48701. } // namespace entt
  48702. #endif
  48703. namespace entt {
  48704. /*! @cond TURN_OFF_DOXYGEN */
  48705. namespace internal {
  48706. static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  48707. template<typename Key, typename Type>
  48708. struct dense_map_node final {
  48709. using value_type = std::pair<Key, Type>;
  48710. template<typename... Args>
  48711. dense_map_node(const std::size_t pos, Args &&...args)
  48712. : next{pos},
  48713. element{std::forward<Args>(args)...} {}
  48714. template<typename Allocator, typename... Args>
  48715. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  48716. : next{pos},
  48717. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  48718. template<typename Allocator>
  48719. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  48720. : next{other.next},
  48721. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  48722. template<typename Allocator>
  48723. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  48724. : next{other.next},
  48725. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  48726. std::size_t next;
  48727. value_type element;
  48728. };
  48729. template<typename It>
  48730. class dense_map_iterator final {
  48731. template<typename>
  48732. friend class dense_map_iterator;
  48733. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  48734. using second_type = decltype((std::declval<It>()->element.second));
  48735. public:
  48736. using value_type = std::pair<first_type, second_type>;
  48737. using pointer = input_iterator_pointer<value_type>;
  48738. using reference = value_type;
  48739. using difference_type = std::ptrdiff_t;
  48740. using iterator_category = std::input_iterator_tag;
  48741. using iterator_concept = std::random_access_iterator_tag;
  48742. constexpr dense_map_iterator() noexcept
  48743. : it{} {}
  48744. constexpr dense_map_iterator(const It iter) noexcept
  48745. : it{iter} {}
  48746. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  48747. constexpr dense_map_iterator(const dense_map_iterator<Other> &other) noexcept
  48748. : it{other.it} {}
  48749. constexpr dense_map_iterator &operator++() noexcept {
  48750. return ++it, *this;
  48751. }
  48752. constexpr dense_map_iterator operator++(int) noexcept {
  48753. const dense_map_iterator orig = *this;
  48754. return ++(*this), orig;
  48755. }
  48756. constexpr dense_map_iterator &operator--() noexcept {
  48757. return --it, *this;
  48758. }
  48759. constexpr dense_map_iterator operator--(int) noexcept {
  48760. const dense_map_iterator orig = *this;
  48761. return operator--(), orig;
  48762. }
  48763. constexpr dense_map_iterator &operator+=(const difference_type value) noexcept {
  48764. it += value;
  48765. return *this;
  48766. }
  48767. constexpr dense_map_iterator operator+(const difference_type value) const noexcept {
  48768. dense_map_iterator copy = *this;
  48769. return (copy += value);
  48770. }
  48771. constexpr dense_map_iterator &operator-=(const difference_type value) noexcept {
  48772. return (*this += -value);
  48773. }
  48774. constexpr dense_map_iterator operator-(const difference_type value) const noexcept {
  48775. return (*this + -value);
  48776. }
  48777. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  48778. return {it[value].element.first, it[value].element.second};
  48779. }
  48780. [[nodiscard]] constexpr pointer operator->() const noexcept {
  48781. return operator*();
  48782. }
  48783. [[nodiscard]] constexpr reference operator*() const noexcept {
  48784. return operator[](0);
  48785. }
  48786. template<typename Lhs, typename Rhs>
  48787. friend constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  48788. template<typename Lhs, typename Rhs>
  48789. friend constexpr bool operator==(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  48790. template<typename Lhs, typename Rhs>
  48791. friend constexpr bool operator<(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  48792. private:
  48793. It it;
  48794. };
  48795. template<typename Lhs, typename Rhs>
  48796. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  48797. return lhs.it - rhs.it;
  48798. }
  48799. template<typename Lhs, typename Rhs>
  48800. [[nodiscard]] constexpr bool operator==(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  48801. return lhs.it == rhs.it;
  48802. }
  48803. template<typename Lhs, typename Rhs>
  48804. [[nodiscard]] constexpr bool operator!=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  48805. return !(lhs == rhs);
  48806. }
  48807. template<typename Lhs, typename Rhs>
  48808. [[nodiscard]] constexpr bool operator<(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  48809. return lhs.it < rhs.it;
  48810. }
  48811. template<typename Lhs, typename Rhs>
  48812. [[nodiscard]] constexpr bool operator>(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  48813. return rhs < lhs;
  48814. }
  48815. template<typename Lhs, typename Rhs>
  48816. [[nodiscard]] constexpr bool operator<=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  48817. return !(lhs > rhs);
  48818. }
  48819. template<typename Lhs, typename Rhs>
  48820. [[nodiscard]] constexpr bool operator>=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  48821. return !(lhs < rhs);
  48822. }
  48823. template<typename It>
  48824. class dense_map_local_iterator final {
  48825. template<typename>
  48826. friend class dense_map_local_iterator;
  48827. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  48828. using second_type = decltype((std::declval<It>()->element.second));
  48829. public:
  48830. using value_type = std::pair<first_type, second_type>;
  48831. using pointer = input_iterator_pointer<value_type>;
  48832. using reference = value_type;
  48833. using difference_type = std::ptrdiff_t;
  48834. using iterator_category = std::input_iterator_tag;
  48835. using iterator_concept = std::forward_iterator_tag;
  48836. constexpr dense_map_local_iterator() noexcept = default;
  48837. constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept
  48838. : it{iter},
  48839. offset{pos} {}
  48840. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  48841. constexpr dense_map_local_iterator(const dense_map_local_iterator<Other> &other) noexcept
  48842. : it{other.it},
  48843. offset{other.offset} {}
  48844. constexpr dense_map_local_iterator &operator++() noexcept {
  48845. return (offset = it[static_cast<typename It::difference_type>(offset)].next), *this;
  48846. }
  48847. constexpr dense_map_local_iterator operator++(int) noexcept {
  48848. const dense_map_local_iterator orig = *this;
  48849. return ++(*this), orig;
  48850. }
  48851. [[nodiscard]] constexpr pointer operator->() const noexcept {
  48852. return operator*();
  48853. }
  48854. [[nodiscard]] constexpr reference operator*() const noexcept {
  48855. const auto idx = static_cast<typename It::difference_type>(offset);
  48856. return {it[idx].element.first, it[idx].element.second};
  48857. }
  48858. [[nodiscard]] constexpr std::size_t index() const noexcept {
  48859. return offset;
  48860. }
  48861. private:
  48862. It it{};
  48863. std::size_t offset{dense_map_placeholder_position};
  48864. };
  48865. template<typename Lhs, typename Rhs>
  48866. [[nodiscard]] constexpr bool operator==(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  48867. return lhs.index() == rhs.index();
  48868. }
  48869. template<typename Lhs, typename Rhs>
  48870. [[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  48871. return !(lhs == rhs);
  48872. }
  48873. } // namespace internal
  48874. /*! @endcond */
  48875. /**
  48876. * @brief Associative container for key-value pairs with unique keys.
  48877. *
  48878. * Internally, elements are organized into buckets. Which bucket an element is
  48879. * placed into depends entirely on the hash of its key. Keys with the same hash
  48880. * code appear in the same bucket.
  48881. *
  48882. * @tparam Key Key type of the associative container.
  48883. * @tparam Type Mapped type of the associative container.
  48884. * @tparam Hash Type of function to use to hash the keys.
  48885. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  48886. * @tparam Allocator Type of allocator used to manage memory and elements.
  48887. */
  48888. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  48889. class dense_map {
  48890. static constexpr float default_threshold = 0.875f;
  48891. static constexpr std::size_t minimum_capacity = 8u;
  48892. static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position;
  48893. using node_type = internal::dense_map_node<Key, Type>;
  48894. using alloc_traits = std::allocator_traits<Allocator>;
  48895. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  48896. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  48897. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  48898. template<typename Other>
  48899. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept {
  48900. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  48901. return fast_mod(static_cast<size_type>(sparse.second()(key)), bucket_count());
  48902. }
  48903. template<typename Other>
  48904. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) {
  48905. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  48906. if(packed.second()(packed.first()[offset].element.first, key)) {
  48907. return begin() + static_cast<typename iterator::difference_type>(offset);
  48908. }
  48909. }
  48910. return end();
  48911. }
  48912. template<typename Other>
  48913. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const {
  48914. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  48915. if(packed.second()(packed.first()[offset].element.first, key)) {
  48916. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  48917. }
  48918. }
  48919. return cend();
  48920. }
  48921. template<typename Other, typename... Args>
  48922. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  48923. const auto index = key_to_bucket(key);
  48924. if(auto it = constrained_find(key, index); it != end()) {
  48925. return std::make_pair(it, false);
  48926. }
  48927. packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward<Other>(key)), std::forward_as_tuple(std::forward<Args>(args)...));
  48928. sparse.first()[index] = packed.first().size() - 1u;
  48929. rehash_if_required();
  48930. return std::make_pair(--end(), true);
  48931. }
  48932. template<typename Other, typename Arg>
  48933. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  48934. const auto index = key_to_bucket(key);
  48935. if(auto it = constrained_find(key, index); it != end()) {
  48936. it->second = std::forward<Arg>(value);
  48937. return std::make_pair(it, false);
  48938. }
  48939. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  48940. sparse.first()[index] = packed.first().size() - 1u;
  48941. rehash_if_required();
  48942. return std::make_pair(--end(), true);
  48943. }
  48944. void move_and_pop(const std::size_t pos) {
  48945. if(const auto last = size() - 1u; pos != last) {
  48946. size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)];
  48947. packed.first()[pos] = std::move(packed.first().back());
  48948. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  48949. *curr = pos;
  48950. }
  48951. packed.first().pop_back();
  48952. }
  48953. void rehash_if_required() {
  48954. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  48955. rehash(bc * 2u);
  48956. }
  48957. }
  48958. public:
  48959. /*! @brief Allocator type. */
  48960. using allocator_type = Allocator;
  48961. /*! @brief Key type of the container. */
  48962. using key_type = Key;
  48963. /*! @brief Mapped type of the container. */
  48964. using mapped_type = Type;
  48965. /*! @brief Key-value type of the container. */
  48966. using value_type = std::pair<const Key, Type>;
  48967. /*! @brief Unsigned integer type. */
  48968. using size_type = std::size_t;
  48969. /*! @brief Signed integer type. */
  48970. using difference_type = std::ptrdiff_t;
  48971. /*! @brief Type of function to use to hash the keys. */
  48972. using hasher = Hash;
  48973. /*! @brief Type of function to use to compare the keys for equality. */
  48974. using key_equal = KeyEqual;
  48975. /*! @brief Input iterator type. */
  48976. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  48977. /*! @brief Constant input iterator type. */
  48978. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  48979. /*! @brief Input iterator type. */
  48980. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  48981. /*! @brief Constant input iterator type. */
  48982. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  48983. /*! @brief Default constructor. */
  48984. dense_map()
  48985. : dense_map{minimum_capacity} {}
  48986. /**
  48987. * @brief Constructs an empty container with a given allocator.
  48988. * @param allocator The allocator to use.
  48989. */
  48990. explicit dense_map(const allocator_type &allocator)
  48991. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  48992. /**
  48993. * @brief Constructs an empty container with a given allocator and user
  48994. * supplied minimal number of buckets.
  48995. * @param cnt Minimal number of buckets.
  48996. * @param allocator The allocator to use.
  48997. */
  48998. dense_map(const size_type cnt, const allocator_type &allocator)
  48999. : dense_map{cnt, hasher{}, key_equal{}, allocator} {}
  49000. /**
  49001. * @brief Constructs an empty container with a given allocator, hash
  49002. * function and user supplied minimal number of buckets.
  49003. * @param cnt Minimal number of buckets.
  49004. * @param hash Hash function to use.
  49005. * @param allocator The allocator to use.
  49006. */
  49007. dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  49008. : dense_map{cnt, hash, key_equal{}, allocator} {}
  49009. /**
  49010. * @brief Constructs an empty container with a given allocator, hash
  49011. * function, compare function and user supplied minimal number of buckets.
  49012. * @param cnt Minimal number of buckets.
  49013. * @param hash Hash function to use.
  49014. * @param equal Compare function to use.
  49015. * @param allocator The allocator to use.
  49016. */
  49017. explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  49018. : sparse{allocator, hash},
  49019. packed{allocator, equal} {
  49020. rehash(cnt);
  49021. }
  49022. /*! @brief Default copy constructor. */
  49023. dense_map(const dense_map &) = default;
  49024. /**
  49025. * @brief Allocator-extended copy constructor.
  49026. * @param other The instance to copy from.
  49027. * @param allocator The allocator to use.
  49028. */
  49029. dense_map(const dense_map &other, const allocator_type &allocator)
  49030. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  49031. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  49032. threshold{other.threshold} {}
  49033. /*! @brief Default move constructor. */
  49034. dense_map(dense_map &&) noexcept = default;
  49035. /**
  49036. * @brief Allocator-extended move constructor.
  49037. * @param other The instance to move from.
  49038. * @param allocator The allocator to use.
  49039. */
  49040. dense_map(dense_map &&other, const allocator_type &allocator)
  49041. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  49042. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  49043. threshold{other.threshold} {}
  49044. /*! @brief Default destructor. */
  49045. ~dense_map() = default;
  49046. /**
  49047. * @brief Default copy assignment operator.
  49048. * @return This container.
  49049. */
  49050. dense_map &operator=(const dense_map &) = default;
  49051. /**
  49052. * @brief Default move assignment operator.
  49053. * @return This container.
  49054. */
  49055. dense_map &operator=(dense_map &&) noexcept = default;
  49056. /**
  49057. * @brief Exchanges the contents with those of a given container.
  49058. * @param other Container to exchange the content with.
  49059. */
  49060. void swap(dense_map &other) noexcept {
  49061. using std::swap;
  49062. swap(sparse, other.sparse);
  49063. swap(packed, other.packed);
  49064. swap(threshold, other.threshold);
  49065. }
  49066. /**
  49067. * @brief Returns the associated allocator.
  49068. * @return The associated allocator.
  49069. */
  49070. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  49071. return sparse.first().get_allocator();
  49072. }
  49073. /**
  49074. * @brief Returns an iterator to the beginning.
  49075. *
  49076. * If the array is empty, the returned iterator will be equal to `end()`.
  49077. *
  49078. * @return An iterator to the first instance of the internal array.
  49079. */
  49080. [[nodiscard]] const_iterator cbegin() const noexcept {
  49081. return packed.first().begin();
  49082. }
  49083. /*! @copydoc cbegin */
  49084. [[nodiscard]] const_iterator begin() const noexcept {
  49085. return cbegin();
  49086. }
  49087. /*! @copydoc begin */
  49088. [[nodiscard]] iterator begin() noexcept {
  49089. return packed.first().begin();
  49090. }
  49091. /**
  49092. * @brief Returns an iterator to the end.
  49093. * @return An iterator to the element following the last instance of the
  49094. * internal array.
  49095. */
  49096. [[nodiscard]] const_iterator cend() const noexcept {
  49097. return packed.first().end();
  49098. }
  49099. /*! @copydoc cend */
  49100. [[nodiscard]] const_iterator end() const noexcept {
  49101. return cend();
  49102. }
  49103. /*! @copydoc end */
  49104. [[nodiscard]] iterator end() noexcept {
  49105. return packed.first().end();
  49106. }
  49107. /**
  49108. * @brief Checks whether a container is empty.
  49109. * @return True if the container is empty, false otherwise.
  49110. */
  49111. [[nodiscard]] bool empty() const noexcept {
  49112. return packed.first().empty();
  49113. }
  49114. /**
  49115. * @brief Returns the number of elements in a container.
  49116. * @return Number of elements in a container.
  49117. */
  49118. [[nodiscard]] size_type size() const noexcept {
  49119. return packed.first().size();
  49120. }
  49121. /**
  49122. * @brief Returns the maximum possible number of elements.
  49123. * @return Maximum possible number of elements.
  49124. */
  49125. [[nodiscard]] size_type max_size() const noexcept {
  49126. return packed.first().max_size();
  49127. }
  49128. /*! @brief Clears the container. */
  49129. void clear() noexcept {
  49130. sparse.first().clear();
  49131. packed.first().clear();
  49132. rehash(0u);
  49133. }
  49134. /**
  49135. * @brief Inserts an element into the container, if the key does not exist.
  49136. * @param value A key-value pair eventually convertible to the value type.
  49137. * @return A pair consisting of an iterator to the inserted element (or to
  49138. * the element that prevented the insertion) and a bool denoting whether the
  49139. * insertion took place.
  49140. */
  49141. std::pair<iterator, bool> insert(const value_type &value) {
  49142. return insert_or_do_nothing(value.first, value.second);
  49143. }
  49144. /*! @copydoc insert */
  49145. std::pair<iterator, bool> insert(value_type &&value) {
  49146. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  49147. }
  49148. /**
  49149. * @copydoc insert
  49150. * @tparam Arg Type of the key-value pair to insert into the container.
  49151. */
  49152. template<typename Arg>
  49153. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  49154. insert(Arg &&value) {
  49155. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  49156. }
  49157. /**
  49158. * @brief Inserts elements into the container, if their keys do not exist.
  49159. * @tparam It Type of input iterator.
  49160. * @param first An iterator to the first element of the range of elements.
  49161. * @param last An iterator past the last element of the range of elements.
  49162. */
  49163. template<typename It>
  49164. void insert(It first, It last) {
  49165. for(; first != last; ++first) {
  49166. insert(*first);
  49167. }
  49168. }
  49169. /**
  49170. * @brief Inserts an element into the container or assigns to the current
  49171. * element if the key already exists.
  49172. * @tparam Arg Type of the value to insert or assign.
  49173. * @param key A key used both to look up and to insert if not found.
  49174. * @param value A value to insert or assign.
  49175. * @return A pair consisting of an iterator to the element and a bool
  49176. * denoting whether the insertion took place.
  49177. */
  49178. template<typename Arg>
  49179. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  49180. return insert_or_overwrite(key, std::forward<Arg>(value));
  49181. }
  49182. /*! @copydoc insert_or_assign */
  49183. template<typename Arg>
  49184. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  49185. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  49186. }
  49187. /**
  49188. * @brief Constructs an element in-place, if the key does not exist.
  49189. *
  49190. * The element is also constructed when the container already has the key,
  49191. * in which case the newly constructed object is destroyed immediately.
  49192. *
  49193. * @tparam Args Types of arguments to forward to the constructor of the
  49194. * element.
  49195. * @param args Arguments to forward to the constructor of the element.
  49196. * @return A pair consisting of an iterator to the inserted element (or to
  49197. * the element that prevented the insertion) and a bool denoting whether the
  49198. * insertion took place.
  49199. */
  49200. template<typename... Args>
  49201. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  49202. if constexpr(sizeof...(Args) == 0u) {
  49203. return insert_or_do_nothing(key_type{});
  49204. } else if constexpr(sizeof...(Args) == 1u) {
  49205. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  49206. } else if constexpr(sizeof...(Args) == 2u) {
  49207. return insert_or_do_nothing(std::forward<Args>(args)...);
  49208. } else {
  49209. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  49210. const auto index = key_to_bucket(node.element.first);
  49211. if(auto it = constrained_find(node.element.first, index); it != end()) {
  49212. packed.first().pop_back();
  49213. return std::make_pair(it, false);
  49214. }
  49215. std::swap(node.next, sparse.first()[index]);
  49216. rehash_if_required();
  49217. return std::make_pair(--end(), true);
  49218. }
  49219. }
  49220. /**
  49221. * @brief Inserts in-place if the key does not exist, does nothing if the
  49222. * key exists.
  49223. * @tparam Args Types of arguments to forward to the constructor of the
  49224. * element.
  49225. * @param key A key used both to look up and to insert if not found.
  49226. * @param args Arguments to forward to the constructor of the element.
  49227. * @return A pair consisting of an iterator to the inserted element (or to
  49228. * the element that prevented the insertion) and a bool denoting whether the
  49229. * insertion took place.
  49230. */
  49231. template<typename... Args>
  49232. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  49233. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  49234. }
  49235. /*! @copydoc try_emplace */
  49236. template<typename... Args>
  49237. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  49238. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  49239. }
  49240. /**
  49241. * @brief Removes an element from a given position.
  49242. * @param pos An iterator to the element to remove.
  49243. * @return An iterator following the removed element.
  49244. */
  49245. iterator erase(const_iterator pos) {
  49246. const auto diff = pos - cbegin();
  49247. erase(pos->first);
  49248. return begin() + diff;
  49249. }
  49250. /**
  49251. * @brief Removes the given elements from a container.
  49252. * @param first An iterator to the first element of the range of elements.
  49253. * @param last An iterator past the last element of the range of elements.
  49254. * @return An iterator following the last removed element.
  49255. */
  49256. iterator erase(const_iterator first, const_iterator last) {
  49257. const auto dist = first - cbegin();
  49258. for(auto from = last - cbegin(); from != dist; --from) {
  49259. erase(packed.first()[static_cast<size_type>(from) - 1u].element.first);
  49260. }
  49261. return (begin() + dist);
  49262. }
  49263. /**
  49264. * @brief Removes the element associated with a given key.
  49265. * @param key A key value of an element to remove.
  49266. * @return Number of elements removed (either 0 or 1).
  49267. */
  49268. size_type erase(const key_type &key) {
  49269. for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) {
  49270. if(packed.second()(packed.first()[*curr].element.first, key)) {
  49271. const auto index = *curr;
  49272. *curr = packed.first()[*curr].next;
  49273. move_and_pop(index);
  49274. return 1u;
  49275. }
  49276. }
  49277. return 0u;
  49278. }
  49279. /**
  49280. * @brief Accesses a given element with bounds checking.
  49281. * @param key A key of an element to find.
  49282. * @return A reference to the mapped value of the requested element.
  49283. */
  49284. [[nodiscard]] mapped_type &at(const key_type &key) {
  49285. auto it = find(key);
  49286. ENTT_ASSERT(it != end(), "Invalid key");
  49287. return it->second;
  49288. }
  49289. /*! @copydoc at */
  49290. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  49291. auto it = find(key);
  49292. ENTT_ASSERT(it != cend(), "Invalid key");
  49293. return it->second;
  49294. }
  49295. /**
  49296. * @brief Accesses a given element with bounds checking.
  49297. * @tparam Other Type of the key of an element to find.
  49298. * @param key A key of an element to find.
  49299. * @return A reference to the mapped value of the requested element.
  49300. */
  49301. template<typename Other>
  49302. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type const &>>
  49303. at(const Other &key) const {
  49304. auto it = find(key);
  49305. ENTT_ASSERT(it != cend(), "Invalid key");
  49306. return it->second;
  49307. }
  49308. /*! @copydoc at */
  49309. template<typename Other>
  49310. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type &>>
  49311. at(const Other &key) {
  49312. auto it = find(key);
  49313. ENTT_ASSERT(it != end(), "Invalid key");
  49314. return it->second;
  49315. }
  49316. /**
  49317. * @brief Accesses or inserts a given element.
  49318. * @param key A key of an element to find or insert.
  49319. * @return A reference to the mapped value of the requested element.
  49320. */
  49321. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  49322. return insert_or_do_nothing(key).first->second;
  49323. }
  49324. /**
  49325. * @brief Accesses or inserts a given element.
  49326. * @param key A key of an element to find or insert.
  49327. * @return A reference to the mapped value of the requested element.
  49328. */
  49329. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  49330. return insert_or_do_nothing(std::move(key)).first->second;
  49331. }
  49332. /**
  49333. * @brief Returns the number of elements matching a key (either 1 or 0).
  49334. * @param key Key value of an element to search for.
  49335. * @return Number of elements matching the key (either 1 or 0).
  49336. */
  49337. [[nodiscard]] size_type count(const key_type &key) const {
  49338. return find(key) != end();
  49339. }
  49340. /**
  49341. * @brief Returns the number of elements matching a key (either 1 or 0).
  49342. * @tparam Other Type of the key value of an element to search for.
  49343. * @param key Key value of an element to search for.
  49344. * @return Number of elements matching the key (either 1 or 0).
  49345. */
  49346. template<typename Other>
  49347. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  49348. count(const Other &key) const {
  49349. return find(key) != end();
  49350. }
  49351. /**
  49352. * @brief Finds an element with a given key.
  49353. * @param key Key value of an element to search for.
  49354. * @return An iterator to an element with the given key. If no such element
  49355. * is found, a past-the-end iterator is returned.
  49356. */
  49357. [[nodiscard]] iterator find(const key_type &key) {
  49358. return constrained_find(key, key_to_bucket(key));
  49359. }
  49360. /*! @copydoc find */
  49361. [[nodiscard]] const_iterator find(const key_type &key) const {
  49362. return constrained_find(key, key_to_bucket(key));
  49363. }
  49364. /**
  49365. * @brief Finds an element with a key that compares _equivalent_ to a given
  49366. * key.
  49367. * @tparam Other Type of the key value of an element to search for.
  49368. * @param key Key value of an element to search for.
  49369. * @return An iterator to an element with the given key. If no such element
  49370. * is found, a past-the-end iterator is returned.
  49371. */
  49372. template<typename Other>
  49373. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  49374. find(const Other &key) {
  49375. return constrained_find(key, key_to_bucket(key));
  49376. }
  49377. /*! @copydoc find */
  49378. template<typename Other>
  49379. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  49380. find(const Other &key) const {
  49381. return constrained_find(key, key_to_bucket(key));
  49382. }
  49383. /**
  49384. * @brief Returns a range containing all elements with a given key.
  49385. * @param key Key value of an element to search for.
  49386. * @return A pair of iterators pointing to the first element and past the
  49387. * last element of the range.
  49388. */
  49389. [[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
  49390. const auto it = find(key);
  49391. return {it, it + !(it == end())};
  49392. }
  49393. /*! @copydoc equal_range */
  49394. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
  49395. const auto it = find(key);
  49396. return {it, it + !(it == cend())};
  49397. }
  49398. /**
  49399. * @brief Returns a range containing all elements that compare _equivalent_
  49400. * to a given key.
  49401. * @tparam Other Type of an element to search for.
  49402. * @param key Key value of an element to search for.
  49403. * @return A pair of iterators pointing to the first element and past the
  49404. * last element of the range.
  49405. */
  49406. template<typename Other>
  49407. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  49408. equal_range(const Other &key) {
  49409. const auto it = find(key);
  49410. return {it, it + !(it == end())};
  49411. }
  49412. /*! @copydoc equal_range */
  49413. template<typename Other>
  49414. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  49415. equal_range(const Other &key) const {
  49416. const auto it = find(key);
  49417. return {it, it + !(it == cend())};
  49418. }
  49419. /**
  49420. * @brief Checks if the container contains an element with a given key.
  49421. * @param key Key value of an element to search for.
  49422. * @return True if there is such an element, false otherwise.
  49423. */
  49424. [[nodiscard]] bool contains(const key_type &key) const {
  49425. return (find(key) != cend());
  49426. }
  49427. /**
  49428. * @brief Checks if the container contains an element with a key that
  49429. * compares _equivalent_ to a given value.
  49430. * @tparam Other Type of the key value of an element to search for.
  49431. * @param key Key value of an element to search for.
  49432. * @return True if there is such an element, false otherwise.
  49433. */
  49434. template<typename Other>
  49435. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  49436. contains(const Other &key) const {
  49437. return (find(key) != cend());
  49438. }
  49439. /**
  49440. * @brief Returns an iterator to the beginning of a given bucket.
  49441. * @param index An index of a bucket to access.
  49442. * @return An iterator to the beginning of the given bucket.
  49443. */
  49444. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  49445. return {packed.first().begin(), sparse.first()[index]};
  49446. }
  49447. /**
  49448. * @brief Returns an iterator to the beginning of a given bucket.
  49449. * @param index An index of a bucket to access.
  49450. * @return An iterator to the beginning of the given bucket.
  49451. */
  49452. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  49453. return cbegin(index);
  49454. }
  49455. /**
  49456. * @brief Returns an iterator to the beginning of a given bucket.
  49457. * @param index An index of a bucket to access.
  49458. * @return An iterator to the beginning of the given bucket.
  49459. */
  49460. [[nodiscard]] local_iterator begin(const size_type index) {
  49461. return {packed.first().begin(), sparse.first()[index]};
  49462. }
  49463. /**
  49464. * @brief Returns an iterator to the end of a given bucket.
  49465. * @param index An index of a bucket to access.
  49466. * @return An iterator to the end of the given bucket.
  49467. */
  49468. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  49469. return {};
  49470. }
  49471. /**
  49472. * @brief Returns an iterator to the end of a given bucket.
  49473. * @param index An index of a bucket to access.
  49474. * @return An iterator to the end of the given bucket.
  49475. */
  49476. [[nodiscard]] const_local_iterator end(const size_type index) const {
  49477. return cend(index);
  49478. }
  49479. /**
  49480. * @brief Returns an iterator to the end of a given bucket.
  49481. * @param index An index of a bucket to access.
  49482. * @return An iterator to the end of the given bucket.
  49483. */
  49484. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  49485. return {};
  49486. }
  49487. /**
  49488. * @brief Returns the number of buckets.
  49489. * @return The number of buckets.
  49490. */
  49491. [[nodiscard]] size_type bucket_count() const {
  49492. return sparse.first().size();
  49493. }
  49494. /**
  49495. * @brief Returns the maximum number of buckets.
  49496. * @return The maximum number of buckets.
  49497. */
  49498. [[nodiscard]] size_type max_bucket_count() const {
  49499. return sparse.first().max_size();
  49500. }
  49501. /**
  49502. * @brief Returns the number of elements in a given bucket.
  49503. * @param index The index of the bucket to examine.
  49504. * @return The number of elements in the given bucket.
  49505. */
  49506. [[nodiscard]] size_type bucket_size(const size_type index) const {
  49507. return static_cast<size_type>(std::distance(begin(index), end(index)));
  49508. }
  49509. /**
  49510. * @brief Returns the bucket for a given key.
  49511. * @param key The value of the key to examine.
  49512. * @return The bucket for the given key.
  49513. */
  49514. [[nodiscard]] size_type bucket(const key_type &key) const {
  49515. return key_to_bucket(key);
  49516. }
  49517. /**
  49518. * @brief Returns the average number of elements per bucket.
  49519. * @return The average number of elements per bucket.
  49520. */
  49521. [[nodiscard]] float load_factor() const {
  49522. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  49523. }
  49524. /**
  49525. * @brief Returns the maximum average number of elements per bucket.
  49526. * @return The maximum average number of elements per bucket.
  49527. */
  49528. [[nodiscard]] float max_load_factor() const {
  49529. return threshold;
  49530. }
  49531. /**
  49532. * @brief Sets the desired maximum average number of elements per bucket.
  49533. * @param value A desired maximum average number of elements per bucket.
  49534. */
  49535. void max_load_factor(const float value) {
  49536. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  49537. threshold = value;
  49538. rehash(0u);
  49539. }
  49540. /**
  49541. * @brief Reserves at least the specified number of buckets and regenerates
  49542. * the hash table.
  49543. * @param cnt New number of buckets.
  49544. */
  49545. void rehash(const size_type cnt) {
  49546. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  49547. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  49548. value = value > cap ? value : cap;
  49549. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  49550. sparse.first().resize(sz);
  49551. for(auto &&elem: sparse.first()) {
  49552. elem = placeholder_position;
  49553. }
  49554. for(size_type pos{}, last = size(); pos < last; ++pos) {
  49555. const auto index = key_to_bucket(packed.first()[pos].element.first);
  49556. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  49557. }
  49558. }
  49559. }
  49560. /**
  49561. * @brief Reserves space for at least the specified number of elements and
  49562. * regenerates the hash table.
  49563. * @param cnt New number of elements.
  49564. */
  49565. void reserve(const size_type cnt) {
  49566. packed.first().reserve(cnt);
  49567. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  49568. }
  49569. /**
  49570. * @brief Returns the function used to hash the keys.
  49571. * @return The function used to hash the keys.
  49572. */
  49573. [[nodiscard]] hasher hash_function() const {
  49574. return sparse.second();
  49575. }
  49576. /**
  49577. * @brief Returns the function used to compare keys for equality.
  49578. * @return The function used to compare keys for equality.
  49579. */
  49580. [[nodiscard]] key_equal key_eq() const {
  49581. return packed.second();
  49582. }
  49583. private:
  49584. compressed_pair<sparse_container_type, hasher> sparse;
  49585. compressed_pair<packed_container_type, key_equal> packed;
  49586. float threshold{default_threshold};
  49587. };
  49588. } // namespace entt
  49589. /*! @cond TURN_OFF_DOXYGEN */
  49590. namespace std {
  49591. template<typename Key, typename Value, typename Allocator>
  49592. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  49593. : std::true_type {};
  49594. } // namespace std
  49595. /*! @endcond */
  49596. #endif
  49597. // #include "../container/dense_set.hpp"
  49598. #ifndef ENTT_CONTAINER_DENSE_SET_HPP
  49599. #define ENTT_CONTAINER_DENSE_SET_HPP
  49600. #include <cmath>
  49601. #include <cstddef>
  49602. #include <functional>
  49603. #include <iterator>
  49604. #include <limits>
  49605. #include <memory>
  49606. #include <tuple>
  49607. #include <type_traits>
  49608. #include <utility>
  49609. #include <vector>
  49610. // #include "../config/config.h"
  49611. // #include "../core/bit.hpp"
  49612. // #include "../core/compressed_pair.hpp"
  49613. // #include "../core/type_traits.hpp"
  49614. // #include "fwd.hpp"
  49615. namespace entt {
  49616. /*! @cond TURN_OFF_DOXYGEN */
  49617. namespace internal {
  49618. static constexpr std::size_t dense_set_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  49619. template<typename It>
  49620. class dense_set_iterator final {
  49621. template<typename>
  49622. friend class dense_set_iterator;
  49623. public:
  49624. using value_type = typename It::value_type::second_type;
  49625. using pointer = const value_type *;
  49626. using reference = const value_type &;
  49627. using difference_type = std::ptrdiff_t;
  49628. using iterator_category = std::random_access_iterator_tag;
  49629. constexpr dense_set_iterator() noexcept
  49630. : it{} {}
  49631. constexpr dense_set_iterator(const It iter) noexcept
  49632. : it{iter} {}
  49633. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  49634. constexpr dense_set_iterator(const dense_set_iterator<Other> &other) noexcept
  49635. : it{other.it} {}
  49636. constexpr dense_set_iterator &operator++() noexcept {
  49637. return ++it, *this;
  49638. }
  49639. constexpr dense_set_iterator operator++(int) noexcept {
  49640. const dense_set_iterator orig = *this;
  49641. return ++(*this), orig;
  49642. }
  49643. constexpr dense_set_iterator &operator--() noexcept {
  49644. return --it, *this;
  49645. }
  49646. constexpr dense_set_iterator operator--(int) noexcept {
  49647. const dense_set_iterator orig = *this;
  49648. return operator--(), orig;
  49649. }
  49650. constexpr dense_set_iterator &operator+=(const difference_type value) noexcept {
  49651. it += value;
  49652. return *this;
  49653. }
  49654. constexpr dense_set_iterator operator+(const difference_type value) const noexcept {
  49655. dense_set_iterator copy = *this;
  49656. return (copy += value);
  49657. }
  49658. constexpr dense_set_iterator &operator-=(const difference_type value) noexcept {
  49659. return (*this += -value);
  49660. }
  49661. constexpr dense_set_iterator operator-(const difference_type value) const noexcept {
  49662. return (*this + -value);
  49663. }
  49664. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  49665. return it[value].second;
  49666. }
  49667. [[nodiscard]] constexpr pointer operator->() const noexcept {
  49668. return std::addressof(operator[](0));
  49669. }
  49670. [[nodiscard]] constexpr reference operator*() const noexcept {
  49671. return operator[](0);
  49672. }
  49673. template<typename Lhs, typename Rhs>
  49674. friend constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  49675. template<typename Lhs, typename Rhs>
  49676. friend constexpr bool operator==(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  49677. template<typename Lhs, typename Rhs>
  49678. friend constexpr bool operator<(const dense_set_iterator<Lhs> &, const dense_set_iterator<Rhs> &) noexcept;
  49679. private:
  49680. It it;
  49681. };
  49682. template<typename Lhs, typename Rhs>
  49683. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  49684. return lhs.it - rhs.it;
  49685. }
  49686. template<typename Lhs, typename Rhs>
  49687. [[nodiscard]] constexpr bool operator==(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  49688. return lhs.it == rhs.it;
  49689. }
  49690. template<typename Lhs, typename Rhs>
  49691. [[nodiscard]] constexpr bool operator!=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  49692. return !(lhs == rhs);
  49693. }
  49694. template<typename Lhs, typename Rhs>
  49695. [[nodiscard]] constexpr bool operator<(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  49696. return lhs.it < rhs.it;
  49697. }
  49698. template<typename Lhs, typename Rhs>
  49699. [[nodiscard]] constexpr bool operator>(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  49700. return rhs < lhs;
  49701. }
  49702. template<typename Lhs, typename Rhs>
  49703. [[nodiscard]] constexpr bool operator<=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  49704. return !(lhs > rhs);
  49705. }
  49706. template<typename Lhs, typename Rhs>
  49707. [[nodiscard]] constexpr bool operator>=(const dense_set_iterator<Lhs> &lhs, const dense_set_iterator<Rhs> &rhs) noexcept {
  49708. return !(lhs < rhs);
  49709. }
  49710. template<typename It>
  49711. class dense_set_local_iterator final {
  49712. template<typename>
  49713. friend class dense_set_local_iterator;
  49714. public:
  49715. using value_type = typename It::value_type::second_type;
  49716. using pointer = const value_type *;
  49717. using reference = const value_type &;
  49718. using difference_type = std::ptrdiff_t;
  49719. using iterator_category = std::forward_iterator_tag;
  49720. constexpr dense_set_local_iterator() noexcept = default;
  49721. constexpr dense_set_local_iterator(It iter, const std::size_t pos) noexcept
  49722. : it{iter},
  49723. offset{pos} {}
  49724. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  49725. constexpr dense_set_local_iterator(const dense_set_local_iterator<Other> &other) noexcept
  49726. : it{other.it},
  49727. offset{other.offset} {}
  49728. constexpr dense_set_local_iterator &operator++() noexcept {
  49729. return offset = it[static_cast<typename It::difference_type>(offset)].first, *this;
  49730. }
  49731. constexpr dense_set_local_iterator operator++(int) noexcept {
  49732. const dense_set_local_iterator orig = *this;
  49733. return ++(*this), orig;
  49734. }
  49735. [[nodiscard]] constexpr pointer operator->() const noexcept {
  49736. return std::addressof(it[static_cast<typename It::difference_type>(offset)].second);
  49737. }
  49738. [[nodiscard]] constexpr reference operator*() const noexcept {
  49739. return *operator->();
  49740. }
  49741. [[nodiscard]] constexpr std::size_t index() const noexcept {
  49742. return offset;
  49743. }
  49744. private:
  49745. It it{};
  49746. std::size_t offset{dense_set_placeholder_position};
  49747. };
  49748. template<typename Lhs, typename Rhs>
  49749. [[nodiscard]] constexpr bool operator==(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  49750. return lhs.index() == rhs.index();
  49751. }
  49752. template<typename Lhs, typename Rhs>
  49753. [[nodiscard]] constexpr bool operator!=(const dense_set_local_iterator<Lhs> &lhs, const dense_set_local_iterator<Rhs> &rhs) noexcept {
  49754. return !(lhs == rhs);
  49755. }
  49756. } // namespace internal
  49757. /*! @endcond */
  49758. /**
  49759. * @brief Associative container for unique objects of a given type.
  49760. *
  49761. * Internally, elements are organized into buckets. Which bucket an element is
  49762. * placed into depends entirely on its hash. Elements with the same hash code
  49763. * appear in the same bucket.
  49764. *
  49765. * @tparam Type Value type of the associative container.
  49766. * @tparam Hash Type of function to use to hash the values.
  49767. * @tparam KeyEqual Type of function to use to compare the values for equality.
  49768. * @tparam Allocator Type of allocator used to manage memory and elements.
  49769. */
  49770. template<typename Type, typename Hash, typename KeyEqual, typename Allocator>
  49771. class dense_set {
  49772. static constexpr float default_threshold = 0.875f;
  49773. static constexpr std::size_t minimum_capacity = 8u;
  49774. static constexpr std::size_t placeholder_position = internal::dense_set_placeholder_position;
  49775. using node_type = std::pair<std::size_t, Type>;
  49776. using alloc_traits = std::allocator_traits<Allocator>;
  49777. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  49778. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  49779. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  49780. template<typename Other>
  49781. [[nodiscard]] std::size_t value_to_bucket(const Other &value) const noexcept {
  49782. return fast_mod(static_cast<size_type>(sparse.second()(value)), bucket_count());
  49783. }
  49784. template<typename Other>
  49785. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) {
  49786. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  49787. if(packed.second()(packed.first()[offset].second, value)) {
  49788. return begin() + static_cast<typename iterator::difference_type>(offset);
  49789. }
  49790. }
  49791. return end();
  49792. }
  49793. template<typename Other>
  49794. [[nodiscard]] auto constrained_find(const Other &value, const std::size_t bucket) const {
  49795. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].first) {
  49796. if(packed.second()(packed.first()[offset].second, value)) {
  49797. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  49798. }
  49799. }
  49800. return cend();
  49801. }
  49802. template<typename Other>
  49803. [[nodiscard]] auto insert_or_do_nothing(Other &&value) {
  49804. const auto index = value_to_bucket(value);
  49805. if(auto it = constrained_find(value, index); it != end()) {
  49806. return std::make_pair(it, false);
  49807. }
  49808. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(value));
  49809. sparse.first()[index] = packed.first().size() - 1u;
  49810. rehash_if_required();
  49811. return std::make_pair(--end(), true);
  49812. }
  49813. void move_and_pop(const std::size_t pos) {
  49814. if(const auto last = size() - 1u; pos != last) {
  49815. size_type *curr = &sparse.first()[value_to_bucket(packed.first().back().second)];
  49816. packed.first()[pos] = std::move(packed.first().back());
  49817. for(; *curr != last; curr = &packed.first()[*curr].first) {}
  49818. *curr = pos;
  49819. }
  49820. packed.first().pop_back();
  49821. }
  49822. void rehash_if_required() {
  49823. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  49824. rehash(bc * 2u);
  49825. }
  49826. }
  49827. public:
  49828. /*! @brief Allocator type. */
  49829. using allocator_type = Allocator;
  49830. /*! @brief Key type of the container. */
  49831. using key_type = Type;
  49832. /*! @brief Value type of the container. */
  49833. using value_type = Type;
  49834. /*! @brief Unsigned integer type. */
  49835. using size_type = std::size_t;
  49836. /*! @brief Signed integer type. */
  49837. using difference_type = std::ptrdiff_t;
  49838. /*! @brief Type of function to use to hash the elements. */
  49839. using hasher = Hash;
  49840. /*! @brief Type of function to use to compare the elements for equality. */
  49841. using key_equal = KeyEqual;
  49842. /*! @brief Random access iterator type. */
  49843. using iterator = internal::dense_set_iterator<typename packed_container_type::iterator>;
  49844. /*! @brief Constant random access iterator type. */
  49845. using const_iterator = internal::dense_set_iterator<typename packed_container_type::const_iterator>;
  49846. /*! @brief Reverse iterator type. */
  49847. using reverse_iterator = std::reverse_iterator<iterator>;
  49848. /*! @brief Constant reverse iterator type. */
  49849. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  49850. /*! @brief Forward iterator type. */
  49851. using local_iterator = internal::dense_set_local_iterator<typename packed_container_type::iterator>;
  49852. /*! @brief Constant forward iterator type. */
  49853. using const_local_iterator = internal::dense_set_local_iterator<typename packed_container_type::const_iterator>;
  49854. /*! @brief Default constructor. */
  49855. dense_set()
  49856. : dense_set{minimum_capacity} {}
  49857. /**
  49858. * @brief Constructs an empty container with a given allocator.
  49859. * @param allocator The allocator to use.
  49860. */
  49861. explicit dense_set(const allocator_type &allocator)
  49862. : dense_set{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  49863. /**
  49864. * @brief Constructs an empty container with a given allocator and user
  49865. * supplied minimal number of buckets.
  49866. * @param cnt Minimal number of buckets.
  49867. * @param allocator The allocator to use.
  49868. */
  49869. dense_set(const size_type cnt, const allocator_type &allocator)
  49870. : dense_set{cnt, hasher{}, key_equal{}, allocator} {}
  49871. /**
  49872. * @brief Constructs an empty container with a given allocator, hash
  49873. * function and user supplied minimal number of buckets.
  49874. * @param cnt Minimal number of buckets.
  49875. * @param hash Hash function to use.
  49876. * @param allocator The allocator to use.
  49877. */
  49878. dense_set(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  49879. : dense_set{cnt, hash, key_equal{}, allocator} {}
  49880. /**
  49881. * @brief Constructs an empty container with a given allocator, hash
  49882. * function, compare function and user supplied minimal number of buckets.
  49883. * @param cnt Minimal number of buckets.
  49884. * @param hash Hash function to use.
  49885. * @param equal Compare function to use.
  49886. * @param allocator The allocator to use.
  49887. */
  49888. explicit dense_set(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  49889. : sparse{allocator, hash},
  49890. packed{allocator, equal} {
  49891. rehash(cnt);
  49892. }
  49893. /*! @brief Default copy constructor. */
  49894. dense_set(const dense_set &) = default;
  49895. /**
  49896. * @brief Allocator-extended copy constructor.
  49897. * @param other The instance to copy from.
  49898. * @param allocator The allocator to use.
  49899. */
  49900. dense_set(const dense_set &other, const allocator_type &allocator)
  49901. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  49902. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  49903. threshold{other.threshold} {}
  49904. /*! @brief Default move constructor. */
  49905. dense_set(dense_set &&) noexcept = default;
  49906. /**
  49907. * @brief Allocator-extended move constructor.
  49908. * @param other The instance to move from.
  49909. * @param allocator The allocator to use.
  49910. */
  49911. dense_set(dense_set &&other, const allocator_type &allocator)
  49912. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  49913. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  49914. threshold{other.threshold} {}
  49915. /*! @brief Default destructor. */
  49916. ~dense_set() = default;
  49917. /**
  49918. * @brief Default copy assignment operator.
  49919. * @return This container.
  49920. */
  49921. dense_set &operator=(const dense_set &) = default;
  49922. /**
  49923. * @brief Default move assignment operator.
  49924. * @return This container.
  49925. */
  49926. dense_set &operator=(dense_set &&) noexcept = default;
  49927. /**
  49928. * @brief Exchanges the contents with those of a given container.
  49929. * @param other Container to exchange the content with.
  49930. */
  49931. void swap(dense_set &other) noexcept {
  49932. using std::swap;
  49933. swap(sparse, other.sparse);
  49934. swap(packed, other.packed);
  49935. swap(threshold, other.threshold);
  49936. }
  49937. /**
  49938. * @brief Returns the associated allocator.
  49939. * @return The associated allocator.
  49940. */
  49941. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  49942. return sparse.first().get_allocator();
  49943. }
  49944. /**
  49945. * @brief Returns an iterator to the beginning.
  49946. *
  49947. * If the array is empty, the returned iterator will be equal to `end()`.
  49948. *
  49949. * @return An iterator to the first instance of the internal array.
  49950. */
  49951. [[nodiscard]] const_iterator cbegin() const noexcept {
  49952. return packed.first().begin();
  49953. }
  49954. /*! @copydoc cbegin */
  49955. [[nodiscard]] const_iterator begin() const noexcept {
  49956. return cbegin();
  49957. }
  49958. /*! @copydoc begin */
  49959. [[nodiscard]] iterator begin() noexcept {
  49960. return packed.first().begin();
  49961. }
  49962. /**
  49963. * @brief Returns an iterator to the end.
  49964. * @return An iterator to the element following the last instance of the
  49965. * internal array.
  49966. */
  49967. [[nodiscard]] const_iterator cend() const noexcept {
  49968. return packed.first().end();
  49969. }
  49970. /*! @copydoc cend */
  49971. [[nodiscard]] const_iterator end() const noexcept {
  49972. return cend();
  49973. }
  49974. /*! @copydoc end */
  49975. [[nodiscard]] iterator end() noexcept {
  49976. return packed.first().end();
  49977. }
  49978. /**
  49979. * @brief Returns a reverse iterator to the beginning.
  49980. *
  49981. * If the array is empty, the returned iterator will be equal to `rend()`.
  49982. *
  49983. * @return An iterator to the first instance of the reversed internal array.
  49984. */
  49985. [[nodiscard]] const_reverse_iterator crbegin() const noexcept {
  49986. return std::make_reverse_iterator(cend());
  49987. }
  49988. /*! @copydoc crbegin */
  49989. [[nodiscard]] const_reverse_iterator rbegin() const noexcept {
  49990. return crbegin();
  49991. }
  49992. /*! @copydoc rbegin */
  49993. [[nodiscard]] reverse_iterator rbegin() noexcept {
  49994. return std::make_reverse_iterator(end());
  49995. }
  49996. /**
  49997. * @brief Returns a reverse iterator to the end.
  49998. * @return An iterator to the element following the last instance of the
  49999. * reversed internal array.
  50000. */
  50001. [[nodiscard]] const_reverse_iterator crend() const noexcept {
  50002. return std::make_reverse_iterator(cbegin());
  50003. }
  50004. /*! @copydoc crend */
  50005. [[nodiscard]] const_reverse_iterator rend() const noexcept {
  50006. return crend();
  50007. }
  50008. /*! @copydoc rend */
  50009. [[nodiscard]] reverse_iterator rend() noexcept {
  50010. return std::make_reverse_iterator(begin());
  50011. }
  50012. /**
  50013. * @brief Checks whether a container is empty.
  50014. * @return True if the container is empty, false otherwise.
  50015. */
  50016. [[nodiscard]] bool empty() const noexcept {
  50017. return packed.first().empty();
  50018. }
  50019. /**
  50020. * @brief Returns the number of elements in a container.
  50021. * @return Number of elements in a container.
  50022. */
  50023. [[nodiscard]] size_type size() const noexcept {
  50024. return packed.first().size();
  50025. }
  50026. /**
  50027. * @brief Returns the maximum possible number of elements.
  50028. * @return Maximum possible number of elements.
  50029. */
  50030. [[nodiscard]] size_type max_size() const noexcept {
  50031. return packed.first().max_size();
  50032. }
  50033. /*! @brief Clears the container. */
  50034. void clear() noexcept {
  50035. sparse.first().clear();
  50036. packed.first().clear();
  50037. rehash(0u);
  50038. }
  50039. /**
  50040. * @brief Inserts an element into the container, if it does not exist.
  50041. * @param value An element to insert into the container.
  50042. * @return A pair consisting of an iterator to the inserted element (or to
  50043. * the element that prevented the insertion) and a bool denoting whether the
  50044. * insertion took place.
  50045. */
  50046. std::pair<iterator, bool> insert(const value_type &value) {
  50047. return insert_or_do_nothing(value);
  50048. }
  50049. /*! @copydoc insert */
  50050. std::pair<iterator, bool> insert(value_type &&value) {
  50051. return insert_or_do_nothing(std::move(value));
  50052. }
  50053. /**
  50054. * @brief Inserts elements into the container, if they do not exist.
  50055. * @tparam It Type of input iterator.
  50056. * @param first An iterator to the first element of the range of elements.
  50057. * @param last An iterator past the last element of the range of elements.
  50058. */
  50059. template<typename It>
  50060. void insert(It first, It last) {
  50061. for(; first != last; ++first) {
  50062. insert(*first);
  50063. }
  50064. }
  50065. /**
  50066. * @brief Constructs an element in-place, if it does not exist.
  50067. *
  50068. * The element is also constructed when the container already has the key,
  50069. * in which case the newly constructed object is destroyed immediately.
  50070. *
  50071. * @tparam Args Types of arguments to forward to the constructor of the
  50072. * element.
  50073. * @param args Arguments to forward to the constructor of the element.
  50074. * @return A pair consisting of an iterator to the inserted element (or to
  50075. * the element that prevented the insertion) and a bool denoting whether the
  50076. * insertion took place.
  50077. */
  50078. template<typename... Args>
  50079. std::pair<iterator, bool> emplace(Args &&...args) {
  50080. if constexpr(((sizeof...(Args) == 1u) && ... && std::is_same_v<std::decay_t<Args>, value_type>)) {
  50081. return insert_or_do_nothing(std::forward<Args>(args)...);
  50082. } else {
  50083. auto &node = packed.first().emplace_back(std::piecewise_construct, std::make_tuple(packed.first().size()), std::forward_as_tuple(std::forward<Args>(args)...));
  50084. const auto index = value_to_bucket(node.second);
  50085. if(auto it = constrained_find(node.second, index); it != end()) {
  50086. packed.first().pop_back();
  50087. return std::make_pair(it, false);
  50088. }
  50089. std::swap(node.first, sparse.first()[index]);
  50090. rehash_if_required();
  50091. return std::make_pair(--end(), true);
  50092. }
  50093. }
  50094. /**
  50095. * @brief Removes an element from a given position.
  50096. * @param pos An iterator to the element to remove.
  50097. * @return An iterator following the removed element.
  50098. */
  50099. iterator erase(const_iterator pos) {
  50100. const auto diff = pos - cbegin();
  50101. erase(*pos);
  50102. return begin() + diff;
  50103. }
  50104. /**
  50105. * @brief Removes the given elements from a container.
  50106. * @param first An iterator to the first element of the range of elements.
  50107. * @param last An iterator past the last element of the range of elements.
  50108. * @return An iterator following the last removed element.
  50109. */
  50110. iterator erase(const_iterator first, const_iterator last) {
  50111. const auto dist = first - cbegin();
  50112. for(auto from = last - cbegin(); from != dist; --from) {
  50113. erase(packed.first()[static_cast<size_type>(from) - 1u].second);
  50114. }
  50115. return (begin() + dist);
  50116. }
  50117. /**
  50118. * @brief Removes the element associated with a given value.
  50119. * @param value Value of an element to remove.
  50120. * @return Number of elements removed (either 0 or 1).
  50121. */
  50122. size_type erase(const value_type &value) {
  50123. for(size_type *curr = &sparse.first()[value_to_bucket(value)]; *curr != placeholder_position; curr = &packed.first()[*curr].first) {
  50124. if(packed.second()(packed.first()[*curr].second, value)) {
  50125. const auto index = *curr;
  50126. *curr = packed.first()[*curr].first;
  50127. move_and_pop(index);
  50128. return 1u;
  50129. }
  50130. }
  50131. return 0u;
  50132. }
  50133. /**
  50134. * @brief Returns the number of elements matching a value (either 1 or 0).
  50135. * @param key Key value of an element to search for.
  50136. * @return Number of elements matching the key (either 1 or 0).
  50137. */
  50138. [[nodiscard]] size_type count(const value_type &key) const {
  50139. return find(key) != end();
  50140. }
  50141. /**
  50142. * @brief Returns the number of elements matching a key (either 1 or 0).
  50143. * @tparam Other Type of the key value of an element to search for.
  50144. * @param key Key value of an element to search for.
  50145. * @return Number of elements matching the key (either 1 or 0).
  50146. */
  50147. template<typename Other>
  50148. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  50149. count(const Other &key) const {
  50150. return find(key) != end();
  50151. }
  50152. /**
  50153. * @brief Finds an element with a given value.
  50154. * @param value Value of an element to search for.
  50155. * @return An iterator to an element with the given value. If no such
  50156. * element is found, a past-the-end iterator is returned.
  50157. */
  50158. [[nodiscard]] iterator find(const value_type &value) {
  50159. return constrained_find(value, value_to_bucket(value));
  50160. }
  50161. /*! @copydoc find */
  50162. [[nodiscard]] const_iterator find(const value_type &value) const {
  50163. return constrained_find(value, value_to_bucket(value));
  50164. }
  50165. /**
  50166. * @brief Finds an element that compares _equivalent_ to a given value.
  50167. * @tparam Other Type of an element to search for.
  50168. * @param value Value of an element to search for.
  50169. * @return An iterator to an element with the given value. If no such
  50170. * element is found, a past-the-end iterator is returned.
  50171. */
  50172. template<typename Other>
  50173. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  50174. find(const Other &value) {
  50175. return constrained_find(value, value_to_bucket(value));
  50176. }
  50177. /*! @copydoc find */
  50178. template<typename Other>
  50179. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  50180. find(const Other &value) const {
  50181. return constrained_find(value, value_to_bucket(value));
  50182. }
  50183. /**
  50184. * @brief Returns a range containing all elements with a given value.
  50185. * @param value Value of an element to search for.
  50186. * @return A pair of iterators pointing to the first element and past the
  50187. * last element of the range.
  50188. */
  50189. [[nodiscard]] std::pair<iterator, iterator> equal_range(const value_type &value) {
  50190. const auto it = find(value);
  50191. return {it, it + !(it == end())};
  50192. }
  50193. /*! @copydoc equal_range */
  50194. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const value_type &value) const {
  50195. const auto it = find(value);
  50196. return {it, it + !(it == cend())};
  50197. }
  50198. /**
  50199. * @brief Returns a range containing all elements that compare _equivalent_
  50200. * to a given value.
  50201. * @tparam Other Type of an element to search for.
  50202. * @param value Value of an element to search for.
  50203. * @return A pair of iterators pointing to the first element and past the
  50204. * last element of the range.
  50205. */
  50206. template<typename Other>
  50207. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  50208. equal_range(const Other &value) {
  50209. const auto it = find(value);
  50210. return {it, it + !(it == end())};
  50211. }
  50212. /*! @copydoc equal_range */
  50213. template<typename Other>
  50214. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  50215. equal_range(const Other &value) const {
  50216. const auto it = find(value);
  50217. return {it, it + !(it == cend())};
  50218. }
  50219. /**
  50220. * @brief Checks if the container contains an element with a given value.
  50221. * @param value Value of an element to search for.
  50222. * @return True if there is such an element, false otherwise.
  50223. */
  50224. [[nodiscard]] bool contains(const value_type &value) const {
  50225. return (find(value) != cend());
  50226. }
  50227. /**
  50228. * @brief Checks if the container contains an element that compares
  50229. * _equivalent_ to a given value.
  50230. * @tparam Other Type of an element to search for.
  50231. * @param value Value of an element to search for.
  50232. * @return True if there is such an element, false otherwise.
  50233. */
  50234. template<typename Other>
  50235. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  50236. contains(const Other &value) const {
  50237. return (find(value) != cend());
  50238. }
  50239. /**
  50240. * @brief Returns an iterator to the beginning of a given bucket.
  50241. * @param index An index of a bucket to access.
  50242. * @return An iterator to the beginning of the given bucket.
  50243. */
  50244. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  50245. return {packed.first().begin(), sparse.first()[index]};
  50246. }
  50247. /**
  50248. * @brief Returns an iterator to the beginning of a given bucket.
  50249. * @param index An index of a bucket to access.
  50250. * @return An iterator to the beginning of the given bucket.
  50251. */
  50252. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  50253. return cbegin(index);
  50254. }
  50255. /**
  50256. * @brief Returns an iterator to the beginning of a given bucket.
  50257. * @param index An index of a bucket to access.
  50258. * @return An iterator to the beginning of the given bucket.
  50259. */
  50260. [[nodiscard]] local_iterator begin(const size_type index) {
  50261. return {packed.first().begin(), sparse.first()[index]};
  50262. }
  50263. /**
  50264. * @brief Returns an iterator to the end of a given bucket.
  50265. * @param index An index of a bucket to access.
  50266. * @return An iterator to the end of the given bucket.
  50267. */
  50268. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  50269. return {};
  50270. }
  50271. /**
  50272. * @brief Returns an iterator to the end of a given bucket.
  50273. * @param index An index of a bucket to access.
  50274. * @return An iterator to the end of the given bucket.
  50275. */
  50276. [[nodiscard]] const_local_iterator end(const size_type index) const {
  50277. return cend(index);
  50278. }
  50279. /**
  50280. * @brief Returns an iterator to the end of a given bucket.
  50281. * @param index An index of a bucket to access.
  50282. * @return An iterator to the end of the given bucket.
  50283. */
  50284. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  50285. return {};
  50286. }
  50287. /**
  50288. * @brief Returns the number of buckets.
  50289. * @return The number of buckets.
  50290. */
  50291. [[nodiscard]] size_type bucket_count() const {
  50292. return sparse.first().size();
  50293. }
  50294. /**
  50295. * @brief Returns the maximum number of buckets.
  50296. * @return The maximum number of buckets.
  50297. */
  50298. [[nodiscard]] size_type max_bucket_count() const {
  50299. return sparse.first().max_size();
  50300. }
  50301. /**
  50302. * @brief Returns the number of elements in a given bucket.
  50303. * @param index The index of the bucket to examine.
  50304. * @return The number of elements in the given bucket.
  50305. */
  50306. [[nodiscard]] size_type bucket_size(const size_type index) const {
  50307. return static_cast<size_type>(std::distance(begin(index), end(index)));
  50308. }
  50309. /**
  50310. * @brief Returns the bucket for a given element.
  50311. * @param value The value of the element to examine.
  50312. * @return The bucket for the given element.
  50313. */
  50314. [[nodiscard]] size_type bucket(const value_type &value) const {
  50315. return value_to_bucket(value);
  50316. }
  50317. /**
  50318. * @brief Returns the average number of elements per bucket.
  50319. * @return The average number of elements per bucket.
  50320. */
  50321. [[nodiscard]] float load_factor() const {
  50322. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  50323. }
  50324. /**
  50325. * @brief Returns the maximum average number of elements per bucket.
  50326. * @return The maximum average number of elements per bucket.
  50327. */
  50328. [[nodiscard]] float max_load_factor() const {
  50329. return threshold;
  50330. }
  50331. /**
  50332. * @brief Sets the desired maximum average number of elements per bucket.
  50333. * @param value A desired maximum average number of elements per bucket.
  50334. */
  50335. void max_load_factor(const float value) {
  50336. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  50337. threshold = value;
  50338. rehash(0u);
  50339. }
  50340. /**
  50341. * @brief Reserves at least the specified number of buckets and regenerates
  50342. * the hash table.
  50343. * @param cnt New number of buckets.
  50344. */
  50345. void rehash(const size_type cnt) {
  50346. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  50347. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  50348. value = value > cap ? value : cap;
  50349. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  50350. sparse.first().resize(sz);
  50351. for(auto &&elem: sparse.first()) {
  50352. elem = placeholder_position;
  50353. }
  50354. for(size_type pos{}, last = size(); pos < last; ++pos) {
  50355. const auto index = value_to_bucket(packed.first()[pos].second);
  50356. packed.first()[pos].first = std::exchange(sparse.first()[index], pos);
  50357. }
  50358. }
  50359. }
  50360. /**
  50361. * @brief Reserves space for at least the specified number of elements and
  50362. * regenerates the hash table.
  50363. * @param cnt New number of elements.
  50364. */
  50365. void reserve(const size_type cnt) {
  50366. packed.first().reserve(cnt);
  50367. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  50368. }
  50369. /**
  50370. * @brief Returns the function used to hash the elements.
  50371. * @return The function used to hash the elements.
  50372. */
  50373. [[nodiscard]] hasher hash_function() const {
  50374. return sparse.second();
  50375. }
  50376. /**
  50377. * @brief Returns the function used to compare elements for equality.
  50378. * @return The function used to compare elements for equality.
  50379. */
  50380. [[nodiscard]] key_equal key_eq() const {
  50381. return packed.second();
  50382. }
  50383. private:
  50384. compressed_pair<sparse_container_type, hasher> sparse;
  50385. compressed_pair<packed_container_type, key_equal> packed;
  50386. float threshold{default_threshold};
  50387. };
  50388. } // namespace entt
  50389. #endif
  50390. // #include "../core/type_traits.hpp"
  50391. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  50392. #define ENTT_CORE_TYPE_TRAITS_HPP
  50393. #include <cstddef>
  50394. #include <iterator>
  50395. #include <tuple>
  50396. #include <type_traits>
  50397. #include <utility>
  50398. // #include "../config/config.h"
  50399. #ifndef ENTT_CONFIG_CONFIG_H
  50400. #define ENTT_CONFIG_CONFIG_H
  50401. // #include "version.h"
  50402. #ifndef ENTT_CONFIG_VERSION_H
  50403. #define ENTT_CONFIG_VERSION_H
  50404. // #include "macro.h"
  50405. #ifndef ENTT_CONFIG_MACRO_H
  50406. #define ENTT_CONFIG_MACRO_H
  50407. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  50408. #define ENTT_STR(arg) #arg
  50409. #define ENTT_XSTR(arg) ENTT_STR(arg)
  50410. // NOLINTEND(cppcoreguidelines-macro-usage)
  50411. #endif
  50412. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  50413. #define ENTT_VERSION_MAJOR 3
  50414. #define ENTT_VERSION_MINOR 16
  50415. #define ENTT_VERSION_PATCH 0
  50416. #define ENTT_VERSION \
  50417. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  50418. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  50419. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  50420. #endif
  50421. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  50422. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  50423. # define ENTT_CONSTEXPR
  50424. # define ENTT_THROW throw
  50425. # define ENTT_TRY try
  50426. # define ENTT_CATCH catch(...)
  50427. #else
  50428. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  50429. # define ENTT_THROW
  50430. # define ENTT_TRY if(true)
  50431. # define ENTT_CATCH if(false)
  50432. #endif
  50433. #if __has_include(<version>)
  50434. # include <version>
  50435. #
  50436. # if defined(__cpp_consteval)
  50437. # define ENTT_CONSTEVAL consteval
  50438. # endif
  50439. #endif
  50440. #ifndef ENTT_CONSTEVAL
  50441. # define ENTT_CONSTEVAL constexpr
  50442. #endif
  50443. #ifdef ENTT_USE_ATOMIC
  50444. # include <atomic>
  50445. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  50446. #else
  50447. # define ENTT_MAYBE_ATOMIC(Type) Type
  50448. #endif
  50449. #ifndef ENTT_ID_TYPE
  50450. # include <cstdint>
  50451. # define ENTT_ID_TYPE std::uint32_t
  50452. #else
  50453. # include <cstdint> // provides coverage for types in the std namespace
  50454. #endif
  50455. #ifndef ENTT_SPARSE_PAGE
  50456. # define ENTT_SPARSE_PAGE 4096
  50457. #endif
  50458. #ifndef ENTT_PACKED_PAGE
  50459. # define ENTT_PACKED_PAGE 1024
  50460. #endif
  50461. #ifdef ENTT_DISABLE_ASSERT
  50462. # undef ENTT_ASSERT
  50463. # define ENTT_ASSERT(condition, msg) (void(0))
  50464. #elif !defined ENTT_ASSERT
  50465. # include <cassert>
  50466. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  50467. #endif
  50468. #ifdef ENTT_DISABLE_ASSERT
  50469. # undef ENTT_ASSERT_CONSTEXPR
  50470. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  50471. #elif !defined ENTT_ASSERT_CONSTEXPR
  50472. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  50473. #endif
  50474. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  50475. #ifdef ENTT_NO_ETO
  50476. # define ENTT_ETO_TYPE(Type) void
  50477. #else
  50478. # define ENTT_ETO_TYPE(Type) Type
  50479. #endif
  50480. #ifdef ENTT_NO_MIXIN
  50481. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  50482. #else
  50483. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  50484. #endif
  50485. #ifdef ENTT_STANDARD_CPP
  50486. # define ENTT_NONSTD false
  50487. #else
  50488. # define ENTT_NONSTD true
  50489. # if defined __clang__ || defined __GNUC__
  50490. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  50491. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  50492. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  50493. # elif defined _MSC_VER
  50494. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  50495. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  50496. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  50497. # endif
  50498. #endif
  50499. #ifndef ENTT_EXPORT
  50500. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  50501. # define ENTT_EXPORT __declspec(dllexport)
  50502. # define ENTT_IMPORT __declspec(dllimport)
  50503. # define ENTT_HIDDEN
  50504. # elif defined __GNUC__ && __GNUC__ >= 4
  50505. # define ENTT_EXPORT __attribute__((visibility("default")))
  50506. # define ENTT_IMPORT __attribute__((visibility("default")))
  50507. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  50508. # else /* Unsupported compiler */
  50509. # define ENTT_EXPORT
  50510. # define ENTT_IMPORT
  50511. # define ENTT_HIDDEN
  50512. # endif
  50513. #endif
  50514. #ifndef ENTT_API
  50515. # if defined ENTT_API_EXPORT
  50516. # define ENTT_API ENTT_EXPORT
  50517. # elif defined ENTT_API_IMPORT
  50518. # define ENTT_API ENTT_IMPORT
  50519. # else /* No API */
  50520. # define ENTT_API
  50521. # endif
  50522. #endif
  50523. #if defined _MSC_VER
  50524. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  50525. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  50526. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  50527. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  50528. #endif
  50529. // NOLINTEND(cppcoreguidelines-macro-usage)
  50530. #endif
  50531. // #include "fwd.hpp"
  50532. #ifndef ENTT_CORE_FWD_HPP
  50533. #define ENTT_CORE_FWD_HPP
  50534. #include <cstddef>
  50535. #include <cstdint>
  50536. // #include "../config/config.h"
  50537. namespace entt {
  50538. /*! @brief Possible modes of an any object. */
  50539. enum class any_policy : std::uint8_t {
  50540. /*! @brief Default mode, no element available. */
  50541. empty,
  50542. /*! @brief Owning mode, dynamically allocated element. */
  50543. dynamic,
  50544. /*! @brief Owning mode, embedded element. */
  50545. embedded,
  50546. /*! @brief Aliasing mode, non-const reference. */
  50547. ref,
  50548. /*! @brief Const aliasing mode, const reference. */
  50549. cref
  50550. };
  50551. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  50552. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  50553. class basic_any;
  50554. /*! @brief Alias declaration for type identifiers. */
  50555. using id_type = ENTT_ID_TYPE;
  50556. /*! @brief Alias declaration for the most common use case. */
  50557. using any = basic_any<>;
  50558. template<typename, typename>
  50559. class compressed_pair;
  50560. template<typename>
  50561. class basic_hashed_string;
  50562. /*! @brief Aliases for common character types. */
  50563. using hashed_string = basic_hashed_string<char>;
  50564. /*! @brief Aliases for common character types. */
  50565. using hashed_wstring = basic_hashed_string<wchar_t>;
  50566. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  50567. struct type_info;
  50568. } // namespace entt
  50569. #endif
  50570. namespace entt {
  50571. /**
  50572. * @brief Utility class to disambiguate overloaded functions.
  50573. * @tparam N Number of choices available.
  50574. */
  50575. template<std::size_t N>
  50576. struct choice_t
  50577. // unfortunately, doxygen cannot parse such a construct
  50578. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  50579. {};
  50580. /*! @copybrief choice_t */
  50581. template<>
  50582. struct choice_t<0> {};
  50583. /**
  50584. * @brief Variable template for the choice trick.
  50585. * @tparam N Number of choices available.
  50586. */
  50587. template<std::size_t N>
  50588. inline constexpr choice_t<N> choice{};
  50589. /**
  50590. * @brief Identity type trait.
  50591. *
  50592. * Useful to establish non-deduced contexts in template argument deduction
  50593. * (waiting for C++20) or to provide types through function arguments.
  50594. *
  50595. * @tparam Type A type.
  50596. */
  50597. template<typename Type>
  50598. struct type_identity {
  50599. /*! @brief Identity type. */
  50600. using type = Type;
  50601. };
  50602. /**
  50603. * @brief Helper type.
  50604. * @tparam Type A type.
  50605. */
  50606. template<typename Type>
  50607. using type_identity_t = typename type_identity<Type>::type;
  50608. /**
  50609. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  50610. * @tparam Type The type of which to return the size.
  50611. */
  50612. template<typename Type, typename = void>
  50613. struct size_of: std::integral_constant<std::size_t, 0u> {};
  50614. /*! @copydoc size_of */
  50615. template<typename Type>
  50616. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  50617. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  50618. : std::integral_constant<std::size_t, sizeof(Type)> {};
  50619. /**
  50620. * @brief Helper variable template.
  50621. * @tparam Type The type of which to return the size.
  50622. */
  50623. template<typename Type>
  50624. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  50625. /**
  50626. * @brief Using declaration to be used to _repeat_ the same type a number of
  50627. * times equal to the size of a given parameter pack.
  50628. * @tparam Type A type to repeat.
  50629. */
  50630. template<typename Type, typename>
  50631. using unpack_as_type = Type;
  50632. /**
  50633. * @brief Helper variable template to be used to _repeat_ the same value a
  50634. * number of times equal to the size of a given parameter pack.
  50635. * @tparam Value A value to repeat.
  50636. */
  50637. template<auto Value, typename>
  50638. inline constexpr auto unpack_as_value = Value;
  50639. /**
  50640. * @brief Wraps a static constant.
  50641. * @tparam Value A static constant.
  50642. */
  50643. template<auto Value>
  50644. using integral_constant = std::integral_constant<decltype(Value), Value>;
  50645. /**
  50646. * @brief Alias template to facilitate the creation of named values.
  50647. * @tparam Value A constant value at least convertible to `id_type`.
  50648. */
  50649. template<id_type Value>
  50650. using tag = integral_constant<Value>;
  50651. /**
  50652. * @brief A class to use to push around lists of types, nothing more.
  50653. * @tparam Type Types provided by the type list.
  50654. */
  50655. template<typename... Type>
  50656. struct type_list {
  50657. /*! @brief Type list type. */
  50658. using type = type_list;
  50659. /*! @brief Compile-time number of elements in the type list. */
  50660. static constexpr auto size = sizeof...(Type);
  50661. };
  50662. /*! @brief Primary template isn't defined on purpose. */
  50663. template<std::size_t, typename>
  50664. struct type_list_element;
  50665. /**
  50666. * @brief Provides compile-time indexed access to the types of a type list.
  50667. * @tparam Index Index of the type to return.
  50668. * @tparam First First type provided by the type list.
  50669. * @tparam Other Other types provided by the type list.
  50670. */
  50671. template<std::size_t Index, typename First, typename... Other>
  50672. struct type_list_element<Index, type_list<First, Other...>>
  50673. : type_list_element<Index - 1u, type_list<Other...>> {};
  50674. /**
  50675. * @brief Provides compile-time indexed access to the types of a type list.
  50676. * @tparam First First type provided by the type list.
  50677. * @tparam Other Other types provided by the type list.
  50678. */
  50679. template<typename First, typename... Other>
  50680. struct type_list_element<0u, type_list<First, Other...>> {
  50681. /*! @brief Searched type. */
  50682. using type = First;
  50683. };
  50684. /**
  50685. * @brief Helper type.
  50686. * @tparam Index Index of the type to return.
  50687. * @tparam List Type list to search into.
  50688. */
  50689. template<std::size_t Index, typename List>
  50690. using type_list_element_t = typename type_list_element<Index, List>::type;
  50691. /*! @brief Primary template isn't defined on purpose. */
  50692. template<typename, typename>
  50693. struct type_list_index;
  50694. /**
  50695. * @brief Provides compile-time type access to the types of a type list.
  50696. * @tparam Type Type to look for and for which to return the index.
  50697. * @tparam First First type provided by the type list.
  50698. * @tparam Other Other types provided by the type list.
  50699. */
  50700. template<typename Type, typename First, typename... Other>
  50701. struct type_list_index<Type, type_list<First, Other...>> {
  50702. /*! @brief Unsigned integer type. */
  50703. using value_type = std::size_t;
  50704. /*! @brief Compile-time position of the given type in the sublist. */
  50705. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  50706. };
  50707. /**
  50708. * @brief Provides compile-time type access to the types of a type list.
  50709. * @tparam Type Type to look for and for which to return the index.
  50710. * @tparam Other Other types provided by the type list.
  50711. */
  50712. template<typename Type, typename... Other>
  50713. struct type_list_index<Type, type_list<Type, Other...>> {
  50714. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  50715. /*! @brief Unsigned integer type. */
  50716. using value_type = std::size_t;
  50717. /*! @brief Compile-time position of the given type in the sublist. */
  50718. static constexpr value_type value = 0u;
  50719. };
  50720. /**
  50721. * @brief Provides compile-time type access to the types of a type list.
  50722. * @tparam Type Type to look for and for which to return the index.
  50723. */
  50724. template<typename Type>
  50725. struct type_list_index<Type, type_list<>> {
  50726. /*! @brief Unsigned integer type. */
  50727. using value_type = std::size_t;
  50728. /*! @brief Compile-time position of the given type in the sublist. */
  50729. static constexpr value_type value = 0u;
  50730. };
  50731. /**
  50732. * @brief Helper variable template.
  50733. * @tparam List Type list.
  50734. * @tparam Type Type to look for and for which to return the index.
  50735. */
  50736. template<typename Type, typename List>
  50737. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  50738. /**
  50739. * @brief Concatenates multiple type lists.
  50740. * @tparam Type Types provided by the first type list.
  50741. * @tparam Other Types provided by the second type list.
  50742. * @return A type list composed by the types of both the type lists.
  50743. */
  50744. template<typename... Type, typename... Other>
  50745. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  50746. return {};
  50747. }
  50748. /*! @brief Primary template isn't defined on purpose. */
  50749. template<typename...>
  50750. struct type_list_cat;
  50751. /*! @brief Concatenates multiple type lists. */
  50752. template<>
  50753. struct type_list_cat<> {
  50754. /*! @brief A type list composed by the types of all the type lists. */
  50755. using type = type_list<>;
  50756. };
  50757. /**
  50758. * @brief Concatenates multiple type lists.
  50759. * @tparam Type Types provided by the first type list.
  50760. * @tparam Other Types provided by the second type list.
  50761. * @tparam List Other type lists, if any.
  50762. */
  50763. template<typename... Type, typename... Other, typename... List>
  50764. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  50765. /*! @brief A type list composed by the types of all the type lists. */
  50766. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  50767. };
  50768. /**
  50769. * @brief Concatenates multiple type lists.
  50770. * @tparam Type Types provided by the type list.
  50771. */
  50772. template<typename... Type>
  50773. struct type_list_cat<type_list<Type...>> {
  50774. /*! @brief A type list composed by the types of all the type lists. */
  50775. using type = type_list<Type...>;
  50776. };
  50777. /**
  50778. * @brief Helper type.
  50779. * @tparam List Type lists to concatenate.
  50780. */
  50781. template<typename... List>
  50782. using type_list_cat_t = typename type_list_cat<List...>::type;
  50783. /*! @cond TURN_OFF_DOXYGEN */
  50784. namespace internal {
  50785. template<typename...>
  50786. struct type_list_unique;
  50787. template<typename First, typename... Other, typename... Type>
  50788. struct type_list_unique<type_list<First, Other...>, Type...>
  50789. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  50790. template<typename... Type>
  50791. struct type_list_unique<type_list<>, Type...> {
  50792. using type = type_list<Type...>;
  50793. };
  50794. } // namespace internal
  50795. /*! @endcond */
  50796. /**
  50797. * @brief Removes duplicates types from a type list.
  50798. * @tparam List Type list.
  50799. */
  50800. template<typename List>
  50801. struct type_list_unique {
  50802. /*! @brief A type list without duplicate types. */
  50803. using type = typename internal::type_list_unique<List>::type;
  50804. };
  50805. /**
  50806. * @brief Helper type.
  50807. * @tparam List Type list.
  50808. */
  50809. template<typename List>
  50810. using type_list_unique_t = typename type_list_unique<List>::type;
  50811. /**
  50812. * @brief Provides the member constant `value` to true if a type list contains a
  50813. * given type, false otherwise.
  50814. * @tparam List Type list.
  50815. * @tparam Type Type to look for.
  50816. */
  50817. template<typename List, typename Type>
  50818. struct type_list_contains;
  50819. /**
  50820. * @copybrief type_list_contains
  50821. * @tparam Type Types provided by the type list.
  50822. * @tparam Other Type to look for.
  50823. */
  50824. template<typename... Type, typename Other>
  50825. struct type_list_contains<type_list<Type...>, Other>
  50826. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  50827. /**
  50828. * @brief Helper variable template.
  50829. * @tparam List Type list.
  50830. * @tparam Type Type to look for.
  50831. */
  50832. template<typename List, typename Type>
  50833. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  50834. /*! @brief Primary template isn't defined on purpose. */
  50835. template<typename...>
  50836. struct type_list_diff;
  50837. /**
  50838. * @brief Computes the difference between two type lists.
  50839. * @tparam Type Types provided by the first type list.
  50840. * @tparam Other Types provided by the second type list.
  50841. */
  50842. template<typename... Type, typename... Other>
  50843. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  50844. /*! @brief A type list that is the difference between the two type lists. */
  50845. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  50846. };
  50847. /**
  50848. * @brief Helper type.
  50849. * @tparam List Type lists between which to compute the difference.
  50850. */
  50851. template<typename... List>
  50852. using type_list_diff_t = typename type_list_diff<List...>::type;
  50853. /*! @brief Primary template isn't defined on purpose. */
  50854. template<typename, template<typename...> class>
  50855. struct type_list_transform;
  50856. /**
  50857. * @brief Applies a given _function_ to a type list and generate a new list.
  50858. * @tparam Type Types provided by the type list.
  50859. * @tparam Op Unary operation as template class with a type member named `type`.
  50860. */
  50861. template<typename... Type, template<typename...> class Op>
  50862. struct type_list_transform<type_list<Type...>, Op> {
  50863. /*! @brief Resulting type list after applying the transform function. */
  50864. // NOLINTNEXTLINE(modernize-type-traits)
  50865. using type = type_list<typename Op<Type>::type...>;
  50866. };
  50867. /**
  50868. * @brief Helper type.
  50869. * @tparam List Type list.
  50870. * @tparam Op Unary operation as template class with a type member named `type`.
  50871. */
  50872. template<typename List, template<typename...> class Op>
  50873. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  50874. /**
  50875. * @brief A class to use to push around lists of constant values, nothing more.
  50876. * @tparam Value Values provided by the value list.
  50877. */
  50878. template<auto... Value>
  50879. struct value_list {
  50880. /*! @brief Value list type. */
  50881. using type = value_list;
  50882. /*! @brief Compile-time number of elements in the value list. */
  50883. static constexpr auto size = sizeof...(Value);
  50884. };
  50885. /*! @brief Primary template isn't defined on purpose. */
  50886. template<std::size_t, typename>
  50887. struct value_list_element;
  50888. /**
  50889. * @brief Provides compile-time indexed access to the values of a value list.
  50890. * @tparam Index Index of the value to return.
  50891. * @tparam Value First value provided by the value list.
  50892. * @tparam Other Other values provided by the value list.
  50893. */
  50894. template<std::size_t Index, auto Value, auto... Other>
  50895. struct value_list_element<Index, value_list<Value, Other...>>
  50896. : value_list_element<Index - 1u, value_list<Other...>> {};
  50897. /**
  50898. * @brief Provides compile-time indexed access to the types of a type list.
  50899. * @tparam Value First value provided by the value list.
  50900. * @tparam Other Other values provided by the value list.
  50901. */
  50902. template<auto Value, auto... Other>
  50903. struct value_list_element<0u, value_list<Value, Other...>> {
  50904. /*! @brief Searched type. */
  50905. using type = decltype(Value);
  50906. /*! @brief Searched value. */
  50907. static constexpr auto value = Value;
  50908. };
  50909. /**
  50910. * @brief Helper type.
  50911. * @tparam Index Index of the type to return.
  50912. * @tparam List Value list to search into.
  50913. */
  50914. template<std::size_t Index, typename List>
  50915. using value_list_element_t = typename value_list_element<Index, List>::type;
  50916. /**
  50917. * @brief Helper type.
  50918. * @tparam Index Index of the value to return.
  50919. * @tparam List Value list to search into.
  50920. */
  50921. template<std::size_t Index, typename List>
  50922. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  50923. /*! @brief Primary template isn't defined on purpose. */
  50924. template<auto, typename>
  50925. struct value_list_index;
  50926. /**
  50927. * @brief Provides compile-time type access to the values of a value list.
  50928. * @tparam Value Value to look for and for which to return the index.
  50929. * @tparam First First value provided by the value list.
  50930. * @tparam Other Other values provided by the value list.
  50931. */
  50932. template<auto Value, auto First, auto... Other>
  50933. struct value_list_index<Value, value_list<First, Other...>> {
  50934. /*! @brief Unsigned integer type. */
  50935. using value_type = std::size_t;
  50936. /*! @brief Compile-time position of the given value in the sublist. */
  50937. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  50938. };
  50939. /**
  50940. * @brief Provides compile-time type access to the values of a value list.
  50941. * @tparam Value Value to look for and for which to return the index.
  50942. * @tparam Other Other values provided by the value list.
  50943. */
  50944. template<auto Value, auto... Other>
  50945. struct value_list_index<Value, value_list<Value, Other...>> {
  50946. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  50947. /*! @brief Unsigned integer type. */
  50948. using value_type = std::size_t;
  50949. /*! @brief Compile-time position of the given value in the sublist. */
  50950. static constexpr value_type value = 0u;
  50951. };
  50952. /**
  50953. * @brief Provides compile-time type access to the values of a value list.
  50954. * @tparam Value Value to look for and for which to return the index.
  50955. */
  50956. template<auto Value>
  50957. struct value_list_index<Value, value_list<>> {
  50958. /*! @brief Unsigned integer type. */
  50959. using value_type = std::size_t;
  50960. /*! @brief Compile-time position of the given type in the sublist. */
  50961. static constexpr value_type value = 0u;
  50962. };
  50963. /**
  50964. * @brief Helper variable template.
  50965. * @tparam List Value list.
  50966. * @tparam Value Value to look for and for which to return the index.
  50967. */
  50968. template<auto Value, typename List>
  50969. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  50970. /**
  50971. * @brief Concatenates multiple value lists.
  50972. * @tparam Value Values provided by the first value list.
  50973. * @tparam Other Values provided by the second value list.
  50974. * @return A value list composed by the values of both the value lists.
  50975. */
  50976. template<auto... Value, auto... Other>
  50977. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  50978. return {};
  50979. }
  50980. /*! @brief Primary template isn't defined on purpose. */
  50981. template<typename...>
  50982. struct value_list_cat;
  50983. /*! @brief Concatenates multiple value lists. */
  50984. template<>
  50985. struct value_list_cat<> {
  50986. /*! @brief A value list composed by the values of all the value lists. */
  50987. using type = value_list<>;
  50988. };
  50989. /**
  50990. * @brief Concatenates multiple value lists.
  50991. * @tparam Value Values provided by the first value list.
  50992. * @tparam Other Values provided by the second value list.
  50993. * @tparam List Other value lists, if any.
  50994. */
  50995. template<auto... Value, auto... Other, typename... List>
  50996. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  50997. /*! @brief A value list composed by the values of all the value lists. */
  50998. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  50999. };
  51000. /**
  51001. * @brief Concatenates multiple value lists.
  51002. * @tparam Value Values provided by the value list.
  51003. */
  51004. template<auto... Value>
  51005. struct value_list_cat<value_list<Value...>> {
  51006. /*! @brief A value list composed by the values of all the value lists. */
  51007. using type = value_list<Value...>;
  51008. };
  51009. /**
  51010. * @brief Helper type.
  51011. * @tparam List Value lists to concatenate.
  51012. */
  51013. template<typename... List>
  51014. using value_list_cat_t = typename value_list_cat<List...>::type;
  51015. /*! @brief Primary template isn't defined on purpose. */
  51016. template<typename>
  51017. struct value_list_unique;
  51018. /**
  51019. * @brief Removes duplicates values from a value list.
  51020. * @tparam Value One of the values provided by the given value list.
  51021. * @tparam Other The other values provided by the given value list.
  51022. */
  51023. template<auto Value, auto... Other>
  51024. struct value_list_unique<value_list<Value, Other...>> {
  51025. /*! @brief A value list without duplicate types. */
  51026. using type = std::conditional_t<
  51027. ((Value == Other) || ...),
  51028. typename value_list_unique<value_list<Other...>>::type,
  51029. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  51030. };
  51031. /*! @brief Removes duplicates values from a value list. */
  51032. template<>
  51033. struct value_list_unique<value_list<>> {
  51034. /*! @brief A value list without duplicate types. */
  51035. using type = value_list<>;
  51036. };
  51037. /**
  51038. * @brief Helper type.
  51039. * @tparam Type A value list.
  51040. */
  51041. template<typename Type>
  51042. using value_list_unique_t = typename value_list_unique<Type>::type;
  51043. /**
  51044. * @brief Provides the member constant `value` to true if a value list contains
  51045. * a given value, false otherwise.
  51046. * @tparam List Value list.
  51047. * @tparam Value Value to look for.
  51048. */
  51049. template<typename List, auto Value>
  51050. struct value_list_contains;
  51051. /**
  51052. * @copybrief value_list_contains
  51053. * @tparam Value Values provided by the value list.
  51054. * @tparam Other Value to look for.
  51055. */
  51056. template<auto... Value, auto Other>
  51057. struct value_list_contains<value_list<Value...>, Other>
  51058. : std::bool_constant<((Value == Other) || ...)> {};
  51059. /**
  51060. * @brief Helper variable template.
  51061. * @tparam List Value list.
  51062. * @tparam Value Value to look for.
  51063. */
  51064. template<typename List, auto Value>
  51065. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  51066. /*! @brief Primary template isn't defined on purpose. */
  51067. template<typename...>
  51068. struct value_list_diff;
  51069. /**
  51070. * @brief Computes the difference between two value lists.
  51071. * @tparam Value Values provided by the first value list.
  51072. * @tparam Other Values provided by the second value list.
  51073. */
  51074. template<auto... Value, auto... Other>
  51075. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  51076. /*! @brief A value list that is the difference between the two value lists. */
  51077. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  51078. };
  51079. /**
  51080. * @brief Helper type.
  51081. * @tparam List Value lists between which to compute the difference.
  51082. */
  51083. template<typename... List>
  51084. using value_list_diff_t = typename value_list_diff<List...>::type;
  51085. /*! @brief Same as std::is_invocable, but with tuples. */
  51086. template<typename, typename>
  51087. struct is_applicable: std::false_type {};
  51088. /**
  51089. * @copybrief is_applicable
  51090. * @tparam Func A valid function type.
  51091. * @tparam Tuple Tuple-like type.
  51092. * @tparam Args The list of arguments to use to probe the function type.
  51093. */
  51094. template<typename Func, template<typename...> class Tuple, typename... Args>
  51095. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  51096. /**
  51097. * @copybrief is_applicable
  51098. * @tparam Func A valid function type.
  51099. * @tparam Tuple Tuple-like type.
  51100. * @tparam Args The list of arguments to use to probe the function type.
  51101. */
  51102. template<typename Func, template<typename...> class Tuple, typename... Args>
  51103. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  51104. /**
  51105. * @brief Helper variable template.
  51106. * @tparam Func A valid function type.
  51107. * @tparam Args The list of arguments to use to probe the function type.
  51108. */
  51109. template<typename Func, typename Args>
  51110. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  51111. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  51112. template<typename, typename, typename>
  51113. struct is_applicable_r: std::false_type {};
  51114. /**
  51115. * @copybrief is_applicable_r
  51116. * @tparam Ret The type to which the return type of the function should be
  51117. * convertible.
  51118. * @tparam Func A valid function type.
  51119. * @tparam Args The list of arguments to use to probe the function type.
  51120. */
  51121. template<typename Ret, typename Func, typename... Args>
  51122. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  51123. /**
  51124. * @brief Helper variable template.
  51125. * @tparam Ret The type to which the return type of the function should be
  51126. * convertible.
  51127. * @tparam Func A valid function type.
  51128. * @tparam Args The list of arguments to use to probe the function type.
  51129. */
  51130. template<typename Ret, typename Func, typename Args>
  51131. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  51132. /**
  51133. * @brief Provides the member constant `value` to true if a given type is
  51134. * complete, false otherwise.
  51135. * @tparam Type The type to test.
  51136. */
  51137. template<typename Type, typename = void>
  51138. struct is_complete: std::false_type {};
  51139. /*! @copydoc is_complete */
  51140. template<typename Type>
  51141. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  51142. /**
  51143. * @brief Helper variable template.
  51144. * @tparam Type The type to test.
  51145. */
  51146. template<typename Type>
  51147. inline constexpr bool is_complete_v = is_complete<Type>::value;
  51148. /**
  51149. * @brief Provides the member constant `value` to true if a given type is an
  51150. * iterator, false otherwise.
  51151. * @tparam Type The type to test.
  51152. */
  51153. template<typename Type, typename = void>
  51154. struct is_iterator: std::false_type {};
  51155. /*! @cond TURN_OFF_DOXYGEN */
  51156. namespace internal {
  51157. template<typename, typename = void>
  51158. struct has_iterator_category: std::false_type {};
  51159. template<typename Type>
  51160. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  51161. } // namespace internal
  51162. /*! @endcond */
  51163. /*! @copydoc is_iterator */
  51164. template<typename Type>
  51165. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  51166. : internal::has_iterator_category<Type> {};
  51167. /**
  51168. * @brief Helper variable template.
  51169. * @tparam Type The type to test.
  51170. */
  51171. template<typename Type>
  51172. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  51173. /**
  51174. * @brief Provides the member constant `value` to true if a given type is both
  51175. * an empty and non-final class, false otherwise.
  51176. * @tparam Type The type to test
  51177. */
  51178. template<typename Type>
  51179. struct is_ebco_eligible
  51180. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  51181. /**
  51182. * @brief Helper variable template.
  51183. * @tparam Type The type to test.
  51184. */
  51185. template<typename Type>
  51186. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  51187. /**
  51188. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  51189. * is valid and denotes a type, false otherwise.
  51190. * @tparam Type The type to test.
  51191. */
  51192. template<typename Type, typename = void>
  51193. struct is_transparent: std::false_type {};
  51194. /*! @copydoc is_transparent */
  51195. template<typename Type>
  51196. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  51197. /**
  51198. * @brief Helper variable template.
  51199. * @tparam Type The type to test.
  51200. */
  51201. template<typename Type>
  51202. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  51203. /*! @cond TURN_OFF_DOXYGEN */
  51204. namespace internal {
  51205. template<typename, typename = void>
  51206. struct has_tuple_size_value: std::false_type {};
  51207. template<typename Type>
  51208. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  51209. template<typename, typename = void>
  51210. struct has_value_type: std::false_type {};
  51211. template<typename Type>
  51212. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  51213. template<typename>
  51214. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  51215. template<typename Type, std::size_t... Index>
  51216. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  51217. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  51218. }
  51219. template<typename>
  51220. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  51221. return false;
  51222. }
  51223. template<typename Type>
  51224. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  51225. return true;
  51226. }
  51227. template<typename Type>
  51228. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  51229. // NOLINTBEGIN(modernize-use-transparent-functors)
  51230. if constexpr(std::is_array_v<Type>) {
  51231. return false;
  51232. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  51233. if constexpr(has_tuple_size_value<Type>::value) {
  51234. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  51235. } else {
  51236. return maybe_equality_comparable<Type>(0);
  51237. }
  51238. } else if constexpr(has_value_type<Type>::value) {
  51239. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  51240. return maybe_equality_comparable<Type>(0);
  51241. } else {
  51242. return false;
  51243. }
  51244. } else {
  51245. return maybe_equality_comparable<Type>(0);
  51246. }
  51247. // NOLINTEND(modernize-use-transparent-functors)
  51248. }
  51249. } // namespace internal
  51250. /*! @endcond */
  51251. /**
  51252. * @brief Provides the member constant `value` to true if a given type is
  51253. * equality comparable, false otherwise.
  51254. * @tparam Type The type to test.
  51255. */
  51256. template<typename Type>
  51257. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  51258. /*! @copydoc is_equality_comparable */
  51259. template<typename Type>
  51260. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  51261. /**
  51262. * @brief Helper variable template.
  51263. * @tparam Type The type to test.
  51264. */
  51265. template<typename Type>
  51266. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  51267. /**
  51268. * @brief Transcribes the constness of a type to another type.
  51269. * @tparam To The type to which to transcribe the constness.
  51270. * @tparam From The type from which to transcribe the constness.
  51271. */
  51272. template<typename To, typename From>
  51273. struct constness_as {
  51274. /*! @brief The type resulting from the transcription of the constness. */
  51275. using type = std::remove_const_t<To>;
  51276. };
  51277. /*! @copydoc constness_as */
  51278. template<typename To, typename From>
  51279. struct constness_as<To, const From> {
  51280. /*! @brief The type resulting from the transcription of the constness. */
  51281. using type = const To;
  51282. };
  51283. /**
  51284. * @brief Alias template to facilitate the transcription of the constness.
  51285. * @tparam To The type to which to transcribe the constness.
  51286. * @tparam From The type from which to transcribe the constness.
  51287. */
  51288. template<typename To, typename From>
  51289. using constness_as_t = typename constness_as<To, From>::type;
  51290. /**
  51291. * @brief Extracts the class of a non-static member object or function.
  51292. * @tparam Member A pointer to a non-static member object or function.
  51293. */
  51294. template<typename Member>
  51295. class member_class {
  51296. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  51297. template<typename Class, typename Ret, typename... Args>
  51298. static Class *clazz(Ret (Class::*)(Args...));
  51299. template<typename Class, typename Ret, typename... Args>
  51300. static Class *clazz(Ret (Class::*)(Args...) const);
  51301. template<typename Class, typename Type>
  51302. static Class *clazz(Type Class::*);
  51303. public:
  51304. /*! @brief The class of the given non-static member object or function. */
  51305. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  51306. };
  51307. /**
  51308. * @brief Helper type.
  51309. * @tparam Member A pointer to a non-static member object or function.
  51310. */
  51311. template<typename Member>
  51312. using member_class_t = typename member_class<Member>::type;
  51313. /**
  51314. * @brief Extracts the n-th argument of a _callable_ type.
  51315. * @tparam Index The index of the argument to extract.
  51316. * @tparam Candidate A valid _callable_ type.
  51317. */
  51318. template<std::size_t Index, typename Candidate>
  51319. class nth_argument {
  51320. template<typename Ret, typename... Args>
  51321. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  51322. template<typename Ret, typename Class, typename... Args>
  51323. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  51324. template<typename Ret, typename Class, typename... Args>
  51325. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  51326. template<typename Type, typename Class>
  51327. static constexpr type_list<Type> pick_up(Type Class ::*);
  51328. template<typename Type>
  51329. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  51330. public:
  51331. /*! @brief N-th argument of the _callable_ type. */
  51332. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  51333. };
  51334. /**
  51335. * @brief Helper type.
  51336. * @tparam Index The index of the argument to extract.
  51337. * @tparam Candidate A valid function, member function or data member type.
  51338. */
  51339. template<std::size_t Index, typename Candidate>
  51340. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  51341. } // namespace entt
  51342. template<typename... Type>
  51343. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  51344. template<std::size_t Index, typename... Type>
  51345. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  51346. template<auto... Value>
  51347. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  51348. template<std::size_t Index, auto... Value>
  51349. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  51350. #endif
  51351. // #include "context.hpp"
  51352. #ifndef ENTT_META_CTX_HPP
  51353. #define ENTT_META_CTX_HPP
  51354. #include <memory>
  51355. // #include "../container/dense_map.hpp"
  51356. // #include "../core/fwd.hpp"
  51357. #ifndef ENTT_CORE_FWD_HPP
  51358. #define ENTT_CORE_FWD_HPP
  51359. #include <cstddef>
  51360. #include <cstdint>
  51361. // #include "../config/config.h"
  51362. namespace entt {
  51363. /*! @brief Possible modes of an any object. */
  51364. enum class any_policy : std::uint8_t {
  51365. /*! @brief Default mode, no element available. */
  51366. empty,
  51367. /*! @brief Owning mode, dynamically allocated element. */
  51368. dynamic,
  51369. /*! @brief Owning mode, embedded element. */
  51370. embedded,
  51371. /*! @brief Aliasing mode, non-const reference. */
  51372. ref,
  51373. /*! @brief Const aliasing mode, const reference. */
  51374. cref
  51375. };
  51376. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  51377. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  51378. class basic_any;
  51379. /*! @brief Alias declaration for type identifiers. */
  51380. using id_type = ENTT_ID_TYPE;
  51381. /*! @brief Alias declaration for the most common use case. */
  51382. using any = basic_any<>;
  51383. template<typename, typename>
  51384. class compressed_pair;
  51385. template<typename>
  51386. class basic_hashed_string;
  51387. /*! @brief Aliases for common character types. */
  51388. using hashed_string = basic_hashed_string<char>;
  51389. /*! @brief Aliases for common character types. */
  51390. using hashed_wstring = basic_hashed_string<wchar_t>;
  51391. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  51392. struct type_info;
  51393. } // namespace entt
  51394. #endif
  51395. // #include "../core/utility.hpp"
  51396. #ifndef ENTT_CORE_UTILITY_HPP
  51397. #define ENTT_CORE_UTILITY_HPP
  51398. #include <type_traits>
  51399. #include <utility>
  51400. namespace entt {
  51401. /*! @brief Identity function object (waiting for C++20). */
  51402. struct identity {
  51403. /*! @brief Indicates that this is a transparent function object. */
  51404. using is_transparent = void;
  51405. /**
  51406. * @brief Returns its argument unchanged.
  51407. * @tparam Type Type of the argument.
  51408. * @param value The actual argument.
  51409. * @return The submitted value as-is.
  51410. */
  51411. template<typename Type>
  51412. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  51413. return std::forward<Type>(value);
  51414. }
  51415. };
  51416. /**
  51417. * @brief Constant utility to disambiguate overloaded members of a class.
  51418. * @tparam Type Type of the desired overload.
  51419. * @tparam Class Type of class to which the member belongs.
  51420. * @param member A valid pointer to a member.
  51421. * @return Pointer to the member.
  51422. */
  51423. template<typename Type, typename Class>
  51424. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  51425. return member;
  51426. }
  51427. /**
  51428. * @brief Constant utility to disambiguate overloaded functions.
  51429. * @tparam Func Function type of the desired overload.
  51430. * @param func A valid pointer to a function.
  51431. * @return Pointer to the function.
  51432. */
  51433. template<typename Func>
  51434. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  51435. return func;
  51436. }
  51437. /**
  51438. * @brief Helper type for visitors.
  51439. * @tparam Func Types of function objects.
  51440. */
  51441. template<typename... Func>
  51442. struct overloaded: Func... {
  51443. using Func::operator()...;
  51444. };
  51445. /**
  51446. * @brief Deduction guide.
  51447. * @tparam Func Types of function objects.
  51448. */
  51449. template<typename... Func>
  51450. overloaded(Func...) -> overloaded<Func...>;
  51451. /**
  51452. * @brief Basic implementation of a y-combinator.
  51453. * @tparam Func Type of a potentially recursive function.
  51454. */
  51455. template<typename Func>
  51456. struct y_combinator {
  51457. /**
  51458. * @brief Constructs a y-combinator from a given function.
  51459. * @param recursive A potentially recursive function.
  51460. */
  51461. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  51462. : func{std::move(recursive)} {}
  51463. /**
  51464. * @brief Invokes a y-combinator and therefore its underlying function.
  51465. * @tparam Args Types of arguments to use to invoke the underlying function.
  51466. * @param args Parameters to use to invoke the underlying function.
  51467. * @return Return value of the underlying function, if any.
  51468. */
  51469. template<typename... Args>
  51470. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  51471. return func(*this, std::forward<Args>(args)...);
  51472. }
  51473. /*! @copydoc operator()() */
  51474. template<typename... Args>
  51475. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  51476. return func(*this, std::forward<Args>(args)...);
  51477. }
  51478. private:
  51479. Func func;
  51480. };
  51481. } // namespace entt
  51482. #endif
  51483. // #include "fwd.hpp"
  51484. #ifndef ENTT_META_FWD_HPP
  51485. #define ENTT_META_FWD_HPP
  51486. #include <cstddef>
  51487. #include <limits>
  51488. namespace entt {
  51489. class meta_ctx;
  51490. class meta_sequence_container;
  51491. class meta_associative_container;
  51492. class meta_any;
  51493. class meta_handle;
  51494. struct meta_custom;
  51495. class meta_data;
  51496. class meta_func;
  51497. class meta_type;
  51498. template<typename>
  51499. class meta_factory;
  51500. /*! @brief Used to identicate that a sequence container has not a fixed size. */
  51501. inline constexpr std::size_t meta_dynamic_extent = (std::numeric_limits<std::size_t>::max)();
  51502. } // namespace entt
  51503. #endif
  51504. namespace entt {
  51505. /*! @cond TURN_OFF_DOXYGEN */
  51506. namespace internal {
  51507. struct meta_type_node;
  51508. struct meta_context {
  51509. dense_map<id_type, std::unique_ptr<meta_type_node>, identity> value;
  51510. [[nodiscard]] inline static meta_context &from(meta_ctx &);
  51511. [[nodiscard]] inline static const meta_context &from(const meta_ctx &);
  51512. };
  51513. } // namespace internal
  51514. /*! @endcond */
  51515. /*! @brief Disambiguation tag for constructors and the like. */
  51516. class meta_ctx_arg_t final {};
  51517. /*! @brief Constant of type meta_context_arg_t used to disambiguate calls. */
  51518. inline constexpr meta_ctx_arg_t meta_ctx_arg{};
  51519. /*! @brief Opaque meta context type. */
  51520. class meta_ctx: private internal::meta_context {
  51521. // attorney idiom like model to access the base class
  51522. friend struct internal::meta_context;
  51523. };
  51524. /*! @cond TURN_OFF_DOXYGEN */
  51525. [[nodiscard]] inline internal::meta_context &internal::meta_context::from(meta_ctx &ctx) {
  51526. return ctx;
  51527. }
  51528. [[nodiscard]] inline const internal::meta_context &internal::meta_context::from(const meta_ctx &ctx) {
  51529. return ctx;
  51530. }
  51531. /*! @endcond */
  51532. } // namespace entt
  51533. #endif
  51534. // #include "fwd.hpp"
  51535. // #include "meta.hpp"
  51536. #ifndef ENTT_META_META_HPP
  51537. #define ENTT_META_META_HPP
  51538. #include <array>
  51539. #include <cstddef>
  51540. #include <iterator>
  51541. #include <memory>
  51542. #include <type_traits>
  51543. #include <utility>
  51544. // #include "../config/config.h"
  51545. #ifndef ENTT_CONFIG_CONFIG_H
  51546. #define ENTT_CONFIG_CONFIG_H
  51547. // #include "version.h"
  51548. #ifndef ENTT_CONFIG_VERSION_H
  51549. #define ENTT_CONFIG_VERSION_H
  51550. // #include "macro.h"
  51551. #ifndef ENTT_CONFIG_MACRO_H
  51552. #define ENTT_CONFIG_MACRO_H
  51553. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  51554. #define ENTT_STR(arg) #arg
  51555. #define ENTT_XSTR(arg) ENTT_STR(arg)
  51556. // NOLINTEND(cppcoreguidelines-macro-usage)
  51557. #endif
  51558. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  51559. #define ENTT_VERSION_MAJOR 3
  51560. #define ENTT_VERSION_MINOR 16
  51561. #define ENTT_VERSION_PATCH 0
  51562. #define ENTT_VERSION \
  51563. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  51564. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  51565. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  51566. #endif
  51567. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  51568. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  51569. # define ENTT_CONSTEXPR
  51570. # define ENTT_THROW throw
  51571. # define ENTT_TRY try
  51572. # define ENTT_CATCH catch(...)
  51573. #else
  51574. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  51575. # define ENTT_THROW
  51576. # define ENTT_TRY if(true)
  51577. # define ENTT_CATCH if(false)
  51578. #endif
  51579. #if __has_include(<version>)
  51580. # include <version>
  51581. #
  51582. # if defined(__cpp_consteval)
  51583. # define ENTT_CONSTEVAL consteval
  51584. # endif
  51585. #endif
  51586. #ifndef ENTT_CONSTEVAL
  51587. # define ENTT_CONSTEVAL constexpr
  51588. #endif
  51589. #ifdef ENTT_USE_ATOMIC
  51590. # include <atomic>
  51591. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  51592. #else
  51593. # define ENTT_MAYBE_ATOMIC(Type) Type
  51594. #endif
  51595. #ifndef ENTT_ID_TYPE
  51596. # include <cstdint>
  51597. # define ENTT_ID_TYPE std::uint32_t
  51598. #else
  51599. # include <cstdint> // provides coverage for types in the std namespace
  51600. #endif
  51601. #ifndef ENTT_SPARSE_PAGE
  51602. # define ENTT_SPARSE_PAGE 4096
  51603. #endif
  51604. #ifndef ENTT_PACKED_PAGE
  51605. # define ENTT_PACKED_PAGE 1024
  51606. #endif
  51607. #ifdef ENTT_DISABLE_ASSERT
  51608. # undef ENTT_ASSERT
  51609. # define ENTT_ASSERT(condition, msg) (void(0))
  51610. #elif !defined ENTT_ASSERT
  51611. # include <cassert>
  51612. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  51613. #endif
  51614. #ifdef ENTT_DISABLE_ASSERT
  51615. # undef ENTT_ASSERT_CONSTEXPR
  51616. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  51617. #elif !defined ENTT_ASSERT_CONSTEXPR
  51618. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  51619. #endif
  51620. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  51621. #ifdef ENTT_NO_ETO
  51622. # define ENTT_ETO_TYPE(Type) void
  51623. #else
  51624. # define ENTT_ETO_TYPE(Type) Type
  51625. #endif
  51626. #ifdef ENTT_NO_MIXIN
  51627. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  51628. #else
  51629. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  51630. #endif
  51631. #ifdef ENTT_STANDARD_CPP
  51632. # define ENTT_NONSTD false
  51633. #else
  51634. # define ENTT_NONSTD true
  51635. # if defined __clang__ || defined __GNUC__
  51636. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  51637. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  51638. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  51639. # elif defined _MSC_VER
  51640. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  51641. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  51642. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  51643. # endif
  51644. #endif
  51645. #ifndef ENTT_EXPORT
  51646. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  51647. # define ENTT_EXPORT __declspec(dllexport)
  51648. # define ENTT_IMPORT __declspec(dllimport)
  51649. # define ENTT_HIDDEN
  51650. # elif defined __GNUC__ && __GNUC__ >= 4
  51651. # define ENTT_EXPORT __attribute__((visibility("default")))
  51652. # define ENTT_IMPORT __attribute__((visibility("default")))
  51653. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  51654. # else /* Unsupported compiler */
  51655. # define ENTT_EXPORT
  51656. # define ENTT_IMPORT
  51657. # define ENTT_HIDDEN
  51658. # endif
  51659. #endif
  51660. #ifndef ENTT_API
  51661. # if defined ENTT_API_EXPORT
  51662. # define ENTT_API ENTT_EXPORT
  51663. # elif defined ENTT_API_IMPORT
  51664. # define ENTT_API ENTT_IMPORT
  51665. # else /* No API */
  51666. # define ENTT_API
  51667. # endif
  51668. #endif
  51669. #if defined _MSC_VER
  51670. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  51671. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  51672. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  51673. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  51674. #endif
  51675. // NOLINTEND(cppcoreguidelines-macro-usage)
  51676. #endif
  51677. // #include "../core/any.hpp"
  51678. #ifndef ENTT_CORE_ANY_HPP
  51679. #define ENTT_CORE_ANY_HPP
  51680. #include <cstddef>
  51681. #include <memory>
  51682. #include <type_traits>
  51683. #include <utility>
  51684. // #include "../config/config.h"
  51685. // #include "fwd.hpp"
  51686. // #include "type_info.hpp"
  51687. #ifndef ENTT_CORE_TYPE_INFO_HPP
  51688. #define ENTT_CORE_TYPE_INFO_HPP
  51689. #include <string_view>
  51690. #include <type_traits>
  51691. #include <utility>
  51692. // #include "../config/config.h"
  51693. // #include "fwd.hpp"
  51694. // #include "hashed_string.hpp"
  51695. #ifndef ENTT_CORE_HASHED_STRING_HPP
  51696. #define ENTT_CORE_HASHED_STRING_HPP
  51697. #include <cstddef>
  51698. #include <cstdint>
  51699. // #include "fwd.hpp"
  51700. namespace entt {
  51701. /*! @cond TURN_OFF_DOXYGEN */
  51702. namespace internal {
  51703. template<typename = id_type>
  51704. struct fnv_1a_params;
  51705. template<>
  51706. struct fnv_1a_params<std::uint32_t> {
  51707. static constexpr auto offset = 2166136261;
  51708. static constexpr auto prime = 16777619;
  51709. };
  51710. template<>
  51711. struct fnv_1a_params<std::uint64_t> {
  51712. static constexpr auto offset = 14695981039346656037ull;
  51713. static constexpr auto prime = 1099511628211ull;
  51714. };
  51715. template<typename Char>
  51716. struct basic_hashed_string {
  51717. using value_type = Char;
  51718. using size_type = std::size_t;
  51719. using hash_type = id_type;
  51720. const value_type *repr{};
  51721. hash_type hash{fnv_1a_params<>::offset};
  51722. size_type length{};
  51723. };
  51724. } // namespace internal
  51725. /*! @endcond */
  51726. /**
  51727. * @brief Zero overhead unique identifier.
  51728. *
  51729. * A hashed string is a compile-time tool that allows users to use
  51730. * human-readable identifiers in the codebase while using their numeric
  51731. * counterparts at runtime.<br/>
  51732. * Because of that, a hashed string can also be used in constant expressions if
  51733. * required.
  51734. *
  51735. * @warning
  51736. * This class doesn't take ownership of user-supplied strings nor does it make a
  51737. * copy of them.
  51738. *
  51739. * @tparam Char Character type.
  51740. */
  51741. template<typename Char>
  51742. class basic_hashed_string: internal::basic_hashed_string<Char> {
  51743. using base_type = internal::basic_hashed_string<Char>;
  51744. using params = internal::fnv_1a_params<>;
  51745. struct const_wrapper {
  51746. // non-explicit constructor on purpose
  51747. constexpr const_wrapper(const typename base_type::value_type *str) noexcept
  51748. : repr{str} {}
  51749. const typename base_type::value_type *repr;
  51750. };
  51751. public:
  51752. /*! @brief Character type. */
  51753. using value_type = typename base_type::value_type;
  51754. /*! @brief Unsigned integer type. */
  51755. using size_type = typename base_type::size_type;
  51756. /*! @brief Unsigned integer type. */
  51757. using hash_type = typename base_type::hash_type;
  51758. /**
  51759. * @brief Returns directly the numeric representation of a string view.
  51760. * @param str Human-readable identifier.
  51761. * @param len Length of the string to hash.
  51762. * @return The numeric representation of the string.
  51763. */
  51764. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
  51765. return basic_hashed_string{str, len};
  51766. }
  51767. /**
  51768. * @brief Returns directly the numeric representation of a string.
  51769. * @tparam N Number of characters of the identifier.
  51770. * @param str Human-readable identifier.
  51771. * @return The numeric representation of the string.
  51772. */
  51773. template<std::size_t N>
  51774. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  51775. [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept {
  51776. return basic_hashed_string{str};
  51777. }
  51778. /**
  51779. * @brief Returns directly the numeric representation of a string.
  51780. * @param wrapper Helps achieving the purpose by relying on overloading.
  51781. * @return The numeric representation of the string.
  51782. */
  51783. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
  51784. return basic_hashed_string{wrapper};
  51785. }
  51786. /*! @brief Constructs an empty hashed string. */
  51787. constexpr basic_hashed_string() noexcept
  51788. : basic_hashed_string{nullptr, 0u} {}
  51789. /**
  51790. * @brief Constructs a hashed string from a string view.
  51791. * @param str Human-readable identifier.
  51792. * @param len Length of the string to hash.
  51793. */
  51794. constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
  51795. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  51796. : base_type{str} {
  51797. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  51798. for(; base_type::length < len; ++base_type::length) {
  51799. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  51800. }
  51801. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  51802. }
  51803. /**
  51804. * @brief Constructs a hashed string from an array of const characters.
  51805. * @tparam N Number of characters of the identifier.
  51806. * @param str Human-readable identifier.
  51807. */
  51808. template<std::size_t N>
  51809. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  51810. ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept
  51811. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  51812. : base_type{str} {
  51813. for(; str[base_type::length]; ++base_type::length) {
  51814. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  51815. }
  51816. }
  51817. /**
  51818. * @brief Explicit constructor on purpose to avoid constructing a hashed
  51819. * string directly from a `const value_type *`.
  51820. *
  51821. * @warning
  51822. * The lifetime of the string is not extended nor is it copied.
  51823. *
  51824. * @param wrapper Helps achieving the purpose by relying on overloading.
  51825. */
  51826. explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
  51827. : base_type{wrapper.repr} {
  51828. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  51829. for(; wrapper.repr[base_type::length]; ++base_type::length) {
  51830. base_type::hash = (base_type::hash ^ static_cast<id_type>(wrapper.repr[base_type::length])) * params::prime;
  51831. }
  51832. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  51833. }
  51834. /**
  51835. * @brief Returns the size of a hashed string.
  51836. * @return The size of the hashed string.
  51837. */
  51838. [[nodiscard]] constexpr size_type size() const noexcept {
  51839. return base_type::length;
  51840. }
  51841. /**
  51842. * @brief Returns the human-readable representation of a hashed string.
  51843. * @return The string used to initialize the hashed string.
  51844. */
  51845. [[nodiscard]] constexpr const value_type *data() const noexcept {
  51846. return base_type::repr;
  51847. }
  51848. /**
  51849. * @brief Returns the numeric representation of a hashed string.
  51850. * @return The numeric representation of the hashed string.
  51851. */
  51852. [[nodiscard]] constexpr hash_type value() const noexcept {
  51853. return base_type::hash;
  51854. }
  51855. /*! @copydoc data */
  51856. [[nodiscard]] explicit constexpr operator const value_type *() const noexcept {
  51857. return data();
  51858. }
  51859. /**
  51860. * @brief Returns the numeric representation of a hashed string.
  51861. * @return The numeric representation of the hashed string.
  51862. */
  51863. [[nodiscard]] constexpr operator hash_type() const noexcept {
  51864. return value();
  51865. }
  51866. };
  51867. /**
  51868. * @brief Deduction guide.
  51869. * @tparam Char Character type.
  51870. * @param str Human-readable identifier.
  51871. * @param len Length of the string to hash.
  51872. */
  51873. template<typename Char>
  51874. basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string<Char>;
  51875. /**
  51876. * @brief Deduction guide.
  51877. * @tparam Char Character type.
  51878. * @tparam N Number of characters of the identifier.
  51879. * @param str Human-readable identifier.
  51880. */
  51881. template<typename Char, std::size_t N>
  51882. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  51883. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  51884. /**
  51885. * @brief Compares two hashed strings.
  51886. * @tparam Char Character type.
  51887. * @param lhs A valid hashed string.
  51888. * @param rhs A valid hashed string.
  51889. * @return True if the two hashed strings are identical, false otherwise.
  51890. */
  51891. template<typename Char>
  51892. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  51893. return lhs.value() == rhs.value();
  51894. }
  51895. /**
  51896. * @brief Compares two hashed strings.
  51897. * @tparam Char Character type.
  51898. * @param lhs A valid hashed string.
  51899. * @param rhs A valid hashed string.
  51900. * @return True if the two hashed strings differ, false otherwise.
  51901. */
  51902. template<typename Char>
  51903. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  51904. return !(lhs == rhs);
  51905. }
  51906. /**
  51907. * @brief Compares two hashed strings.
  51908. * @tparam Char Character type.
  51909. * @param lhs A valid hashed string.
  51910. * @param rhs A valid hashed string.
  51911. * @return True if the first element is less than the second, false otherwise.
  51912. */
  51913. template<typename Char>
  51914. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  51915. return lhs.value() < rhs.value();
  51916. }
  51917. /**
  51918. * @brief Compares two hashed strings.
  51919. * @tparam Char Character type.
  51920. * @param lhs A valid hashed string.
  51921. * @param rhs A valid hashed string.
  51922. * @return True if the first element is less than or equal to the second, false
  51923. * otherwise.
  51924. */
  51925. template<typename Char>
  51926. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  51927. return !(rhs < lhs);
  51928. }
  51929. /**
  51930. * @brief Compares two hashed strings.
  51931. * @tparam Char Character type.
  51932. * @param lhs A valid hashed string.
  51933. * @param rhs A valid hashed string.
  51934. * @return True if the first element is greater than the second, false
  51935. * otherwise.
  51936. */
  51937. template<typename Char>
  51938. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  51939. return rhs < lhs;
  51940. }
  51941. /**
  51942. * @brief Compares two hashed strings.
  51943. * @tparam Char Character type.
  51944. * @param lhs A valid hashed string.
  51945. * @param rhs A valid hashed string.
  51946. * @return True if the first element is greater than or equal to the second,
  51947. * false otherwise.
  51948. */
  51949. template<typename Char>
  51950. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  51951. return !(lhs < rhs);
  51952. }
  51953. inline namespace literals {
  51954. /**
  51955. * @brief User defined literal for hashed strings.
  51956. * @param str The literal without its suffix.
  51957. * @return A properly initialized hashed string.
  51958. */
  51959. [[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept {
  51960. return hashed_string{str};
  51961. }
  51962. /**
  51963. * @brief User defined literal for hashed wstrings.
  51964. * @param str The literal without its suffix.
  51965. * @return A properly initialized hashed wstring.
  51966. */
  51967. [[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept {
  51968. return hashed_wstring{str};
  51969. }
  51970. } // namespace literals
  51971. } // namespace entt
  51972. #endif
  51973. namespace entt {
  51974. /*! @cond TURN_OFF_DOXYGEN */
  51975. namespace internal {
  51976. struct ENTT_API type_index final {
  51977. [[nodiscard]] static id_type next() noexcept {
  51978. static ENTT_MAYBE_ATOMIC(id_type) value{};
  51979. return value++;
  51980. }
  51981. };
  51982. template<typename Type>
  51983. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  51984. #if defined ENTT_PRETTY_FUNCTION
  51985. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  51986. #else
  51987. return "";
  51988. #endif
  51989. }
  51990. template<typename Type>
  51991. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  51992. #if defined ENTT_PRETTY_FUNCTION
  51993. const std::string_view full_name{pretty_function<Type>()};
  51994. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  51995. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  51996. return value;
  51997. #else
  51998. return std::string_view{};
  51999. #endif
  52000. }
  52001. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  52002. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  52003. constexpr auto value = stripped_type_name<Type>();
  52004. return value;
  52005. }
  52006. template<typename Type>
  52007. [[nodiscard]] std::string_view type_name(char) noexcept {
  52008. static const auto value = stripped_type_name<Type>();
  52009. return value;
  52010. }
  52011. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  52012. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  52013. constexpr auto stripped = stripped_type_name<Type>();
  52014. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  52015. return value;
  52016. }
  52017. template<typename Type>
  52018. [[nodiscard]] id_type type_hash(char) noexcept {
  52019. static const auto value = [](const auto stripped) {
  52020. return hashed_string::value(stripped.data(), stripped.size());
  52021. }(stripped_type_name<Type>());
  52022. return value;
  52023. }
  52024. } // namespace internal
  52025. /*! @endcond */
  52026. /**
  52027. * @brief Type sequential identifier.
  52028. * @tparam Type Type for which to generate a sequential identifier.
  52029. */
  52030. template<typename Type, typename = void>
  52031. struct ENTT_API type_index final {
  52032. /**
  52033. * @brief Returns the sequential identifier of a given type.
  52034. * @return The sequential identifier of a given type.
  52035. */
  52036. [[nodiscard]] static id_type value() noexcept {
  52037. static const id_type value = internal::type_index::next();
  52038. return value;
  52039. }
  52040. /*! @copydoc value */
  52041. [[nodiscard]] constexpr operator id_type() const noexcept {
  52042. return value();
  52043. }
  52044. };
  52045. /**
  52046. * @brief Type hash.
  52047. * @tparam Type Type for which to generate a hash value.
  52048. */
  52049. template<typename Type, typename = void>
  52050. struct type_hash final {
  52051. /**
  52052. * @brief Returns the numeric representation of a given type.
  52053. * @return The numeric representation of the given type.
  52054. */
  52055. #if defined ENTT_PRETTY_FUNCTION
  52056. [[nodiscard]] static constexpr id_type value() noexcept {
  52057. return internal::type_hash<Type>(0);
  52058. #else
  52059. [[nodiscard]] static constexpr id_type value() noexcept {
  52060. return type_index<Type>::value();
  52061. #endif
  52062. }
  52063. /*! @copydoc value */
  52064. [[nodiscard]] constexpr operator id_type() const noexcept {
  52065. return value();
  52066. }
  52067. };
  52068. /**
  52069. * @brief Type name.
  52070. * @tparam Type Type for which to generate a name.
  52071. */
  52072. template<typename Type, typename = void>
  52073. struct type_name final {
  52074. /**
  52075. * @brief Returns the name of a given type.
  52076. * @return The name of the given type.
  52077. */
  52078. [[nodiscard]] static constexpr std::string_view value() noexcept {
  52079. return internal::type_name<Type>(0);
  52080. }
  52081. /*! @copydoc value */
  52082. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  52083. return value();
  52084. }
  52085. };
  52086. /*! @brief Implementation specific information about a type. */
  52087. struct type_info final {
  52088. /**
  52089. * @brief Constructs a type info object for a given type.
  52090. * @tparam Type Type for which to construct a type info object.
  52091. */
  52092. template<typename Type>
  52093. // NOLINTBEGIN(modernize-use-transparent-functors)
  52094. constexpr type_info(std::in_place_type_t<Type>) noexcept
  52095. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  52096. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  52097. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  52098. // NOLINTEND(modernize-use-transparent-functors)
  52099. /**
  52100. * @brief Type index.
  52101. * @return Type index.
  52102. */
  52103. [[nodiscard]] constexpr id_type index() const noexcept {
  52104. return seq;
  52105. }
  52106. /**
  52107. * @brief Type hash.
  52108. * @return Type hash.
  52109. */
  52110. [[nodiscard]] constexpr id_type hash() const noexcept {
  52111. return identifier;
  52112. }
  52113. /**
  52114. * @brief Type name.
  52115. * @return Type name.
  52116. */
  52117. [[nodiscard]] constexpr std::string_view name() const noexcept {
  52118. return alias;
  52119. }
  52120. private:
  52121. id_type seq;
  52122. id_type identifier;
  52123. std::string_view alias;
  52124. };
  52125. /**
  52126. * @brief Compares the contents of two type info objects.
  52127. * @param lhs A type info object.
  52128. * @param rhs A type info object.
  52129. * @return True if the two type info objects are identical, false otherwise.
  52130. */
  52131. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  52132. return lhs.hash() == rhs.hash();
  52133. }
  52134. /**
  52135. * @brief Compares the contents of two type info objects.
  52136. * @param lhs A type info object.
  52137. * @param rhs A type info object.
  52138. * @return True if the two type info objects differ, false otherwise.
  52139. */
  52140. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  52141. return !(lhs == rhs);
  52142. }
  52143. /**
  52144. * @brief Compares two type info objects.
  52145. * @param lhs A valid type info object.
  52146. * @param rhs A valid type info object.
  52147. * @return True if the first element is less than the second, false otherwise.
  52148. */
  52149. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  52150. return lhs.index() < rhs.index();
  52151. }
  52152. /**
  52153. * @brief Compares two type info objects.
  52154. * @param lhs A valid type info object.
  52155. * @param rhs A valid type info object.
  52156. * @return True if the first element is less than or equal to the second, false
  52157. * otherwise.
  52158. */
  52159. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  52160. return !(rhs < lhs);
  52161. }
  52162. /**
  52163. * @brief Compares two type info objects.
  52164. * @param lhs A valid type info object.
  52165. * @param rhs A valid type info object.
  52166. * @return True if the first element is greater than the second, false
  52167. * otherwise.
  52168. */
  52169. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  52170. return rhs < lhs;
  52171. }
  52172. /**
  52173. * @brief Compares two type info objects.
  52174. * @param lhs A valid type info object.
  52175. * @param rhs A valid type info object.
  52176. * @return True if the first element is greater than or equal to the second,
  52177. * false otherwise.
  52178. */
  52179. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  52180. return !(lhs < rhs);
  52181. }
  52182. /**
  52183. * @brief Returns the type info object associated to a given type.
  52184. *
  52185. * The returned element refers to an object with static storage duration.<br/>
  52186. * The type doesn't need to be a complete type. If the type is a reference, the
  52187. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  52188. * are ignored.
  52189. *
  52190. * @tparam Type Type for which to generate a type info object.
  52191. * @return A reference to a properly initialized type info object.
  52192. */
  52193. template<typename Type>
  52194. [[nodiscard]] const type_info &type_id() noexcept {
  52195. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  52196. static const type_info instance{std::in_place_type<Type>};
  52197. return instance;
  52198. } else {
  52199. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  52200. }
  52201. }
  52202. /*! @copydoc type_id */
  52203. template<typename Type>
  52204. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  52205. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  52206. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  52207. }
  52208. } // namespace entt
  52209. #endif
  52210. // #include "type_traits.hpp"
  52211. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  52212. #define ENTT_CORE_TYPE_TRAITS_HPP
  52213. #include <cstddef>
  52214. #include <iterator>
  52215. #include <tuple>
  52216. #include <type_traits>
  52217. #include <utility>
  52218. // #include "../config/config.h"
  52219. // #include "fwd.hpp"
  52220. namespace entt {
  52221. /**
  52222. * @brief Utility class to disambiguate overloaded functions.
  52223. * @tparam N Number of choices available.
  52224. */
  52225. template<std::size_t N>
  52226. struct choice_t
  52227. // unfortunately, doxygen cannot parse such a construct
  52228. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  52229. {};
  52230. /*! @copybrief choice_t */
  52231. template<>
  52232. struct choice_t<0> {};
  52233. /**
  52234. * @brief Variable template for the choice trick.
  52235. * @tparam N Number of choices available.
  52236. */
  52237. template<std::size_t N>
  52238. inline constexpr choice_t<N> choice{};
  52239. /**
  52240. * @brief Identity type trait.
  52241. *
  52242. * Useful to establish non-deduced contexts in template argument deduction
  52243. * (waiting for C++20) or to provide types through function arguments.
  52244. *
  52245. * @tparam Type A type.
  52246. */
  52247. template<typename Type>
  52248. struct type_identity {
  52249. /*! @brief Identity type. */
  52250. using type = Type;
  52251. };
  52252. /**
  52253. * @brief Helper type.
  52254. * @tparam Type A type.
  52255. */
  52256. template<typename Type>
  52257. using type_identity_t = typename type_identity<Type>::type;
  52258. /**
  52259. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  52260. * @tparam Type The type of which to return the size.
  52261. */
  52262. template<typename Type, typename = void>
  52263. struct size_of: std::integral_constant<std::size_t, 0u> {};
  52264. /*! @copydoc size_of */
  52265. template<typename Type>
  52266. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  52267. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  52268. : std::integral_constant<std::size_t, sizeof(Type)> {};
  52269. /**
  52270. * @brief Helper variable template.
  52271. * @tparam Type The type of which to return the size.
  52272. */
  52273. template<typename Type>
  52274. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  52275. /**
  52276. * @brief Using declaration to be used to _repeat_ the same type a number of
  52277. * times equal to the size of a given parameter pack.
  52278. * @tparam Type A type to repeat.
  52279. */
  52280. template<typename Type, typename>
  52281. using unpack_as_type = Type;
  52282. /**
  52283. * @brief Helper variable template to be used to _repeat_ the same value a
  52284. * number of times equal to the size of a given parameter pack.
  52285. * @tparam Value A value to repeat.
  52286. */
  52287. template<auto Value, typename>
  52288. inline constexpr auto unpack_as_value = Value;
  52289. /**
  52290. * @brief Wraps a static constant.
  52291. * @tparam Value A static constant.
  52292. */
  52293. template<auto Value>
  52294. using integral_constant = std::integral_constant<decltype(Value), Value>;
  52295. /**
  52296. * @brief Alias template to facilitate the creation of named values.
  52297. * @tparam Value A constant value at least convertible to `id_type`.
  52298. */
  52299. template<id_type Value>
  52300. using tag = integral_constant<Value>;
  52301. /**
  52302. * @brief A class to use to push around lists of types, nothing more.
  52303. * @tparam Type Types provided by the type list.
  52304. */
  52305. template<typename... Type>
  52306. struct type_list {
  52307. /*! @brief Type list type. */
  52308. using type = type_list;
  52309. /*! @brief Compile-time number of elements in the type list. */
  52310. static constexpr auto size = sizeof...(Type);
  52311. };
  52312. /*! @brief Primary template isn't defined on purpose. */
  52313. template<std::size_t, typename>
  52314. struct type_list_element;
  52315. /**
  52316. * @brief Provides compile-time indexed access to the types of a type list.
  52317. * @tparam Index Index of the type to return.
  52318. * @tparam First First type provided by the type list.
  52319. * @tparam Other Other types provided by the type list.
  52320. */
  52321. template<std::size_t Index, typename First, typename... Other>
  52322. struct type_list_element<Index, type_list<First, Other...>>
  52323. : type_list_element<Index - 1u, type_list<Other...>> {};
  52324. /**
  52325. * @brief Provides compile-time indexed access to the types of a type list.
  52326. * @tparam First First type provided by the type list.
  52327. * @tparam Other Other types provided by the type list.
  52328. */
  52329. template<typename First, typename... Other>
  52330. struct type_list_element<0u, type_list<First, Other...>> {
  52331. /*! @brief Searched type. */
  52332. using type = First;
  52333. };
  52334. /**
  52335. * @brief Helper type.
  52336. * @tparam Index Index of the type to return.
  52337. * @tparam List Type list to search into.
  52338. */
  52339. template<std::size_t Index, typename List>
  52340. using type_list_element_t = typename type_list_element<Index, List>::type;
  52341. /*! @brief Primary template isn't defined on purpose. */
  52342. template<typename, typename>
  52343. struct type_list_index;
  52344. /**
  52345. * @brief Provides compile-time type access to the types of a type list.
  52346. * @tparam Type Type to look for and for which to return the index.
  52347. * @tparam First First type provided by the type list.
  52348. * @tparam Other Other types provided by the type list.
  52349. */
  52350. template<typename Type, typename First, typename... Other>
  52351. struct type_list_index<Type, type_list<First, Other...>> {
  52352. /*! @brief Unsigned integer type. */
  52353. using value_type = std::size_t;
  52354. /*! @brief Compile-time position of the given type in the sublist. */
  52355. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  52356. };
  52357. /**
  52358. * @brief Provides compile-time type access to the types of a type list.
  52359. * @tparam Type Type to look for and for which to return the index.
  52360. * @tparam Other Other types provided by the type list.
  52361. */
  52362. template<typename Type, typename... Other>
  52363. struct type_list_index<Type, type_list<Type, Other...>> {
  52364. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  52365. /*! @brief Unsigned integer type. */
  52366. using value_type = std::size_t;
  52367. /*! @brief Compile-time position of the given type in the sublist. */
  52368. static constexpr value_type value = 0u;
  52369. };
  52370. /**
  52371. * @brief Provides compile-time type access to the types of a type list.
  52372. * @tparam Type Type to look for and for which to return the index.
  52373. */
  52374. template<typename Type>
  52375. struct type_list_index<Type, type_list<>> {
  52376. /*! @brief Unsigned integer type. */
  52377. using value_type = std::size_t;
  52378. /*! @brief Compile-time position of the given type in the sublist. */
  52379. static constexpr value_type value = 0u;
  52380. };
  52381. /**
  52382. * @brief Helper variable template.
  52383. * @tparam List Type list.
  52384. * @tparam Type Type to look for and for which to return the index.
  52385. */
  52386. template<typename Type, typename List>
  52387. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  52388. /**
  52389. * @brief Concatenates multiple type lists.
  52390. * @tparam Type Types provided by the first type list.
  52391. * @tparam Other Types provided by the second type list.
  52392. * @return A type list composed by the types of both the type lists.
  52393. */
  52394. template<typename... Type, typename... Other>
  52395. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  52396. return {};
  52397. }
  52398. /*! @brief Primary template isn't defined on purpose. */
  52399. template<typename...>
  52400. struct type_list_cat;
  52401. /*! @brief Concatenates multiple type lists. */
  52402. template<>
  52403. struct type_list_cat<> {
  52404. /*! @brief A type list composed by the types of all the type lists. */
  52405. using type = type_list<>;
  52406. };
  52407. /**
  52408. * @brief Concatenates multiple type lists.
  52409. * @tparam Type Types provided by the first type list.
  52410. * @tparam Other Types provided by the second type list.
  52411. * @tparam List Other type lists, if any.
  52412. */
  52413. template<typename... Type, typename... Other, typename... List>
  52414. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  52415. /*! @brief A type list composed by the types of all the type lists. */
  52416. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  52417. };
  52418. /**
  52419. * @brief Concatenates multiple type lists.
  52420. * @tparam Type Types provided by the type list.
  52421. */
  52422. template<typename... Type>
  52423. struct type_list_cat<type_list<Type...>> {
  52424. /*! @brief A type list composed by the types of all the type lists. */
  52425. using type = type_list<Type...>;
  52426. };
  52427. /**
  52428. * @brief Helper type.
  52429. * @tparam List Type lists to concatenate.
  52430. */
  52431. template<typename... List>
  52432. using type_list_cat_t = typename type_list_cat<List...>::type;
  52433. /*! @cond TURN_OFF_DOXYGEN */
  52434. namespace internal {
  52435. template<typename...>
  52436. struct type_list_unique;
  52437. template<typename First, typename... Other, typename... Type>
  52438. struct type_list_unique<type_list<First, Other...>, Type...>
  52439. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  52440. template<typename... Type>
  52441. struct type_list_unique<type_list<>, Type...> {
  52442. using type = type_list<Type...>;
  52443. };
  52444. } // namespace internal
  52445. /*! @endcond */
  52446. /**
  52447. * @brief Removes duplicates types from a type list.
  52448. * @tparam List Type list.
  52449. */
  52450. template<typename List>
  52451. struct type_list_unique {
  52452. /*! @brief A type list without duplicate types. */
  52453. using type = typename internal::type_list_unique<List>::type;
  52454. };
  52455. /**
  52456. * @brief Helper type.
  52457. * @tparam List Type list.
  52458. */
  52459. template<typename List>
  52460. using type_list_unique_t = typename type_list_unique<List>::type;
  52461. /**
  52462. * @brief Provides the member constant `value` to true if a type list contains a
  52463. * given type, false otherwise.
  52464. * @tparam List Type list.
  52465. * @tparam Type Type to look for.
  52466. */
  52467. template<typename List, typename Type>
  52468. struct type_list_contains;
  52469. /**
  52470. * @copybrief type_list_contains
  52471. * @tparam Type Types provided by the type list.
  52472. * @tparam Other Type to look for.
  52473. */
  52474. template<typename... Type, typename Other>
  52475. struct type_list_contains<type_list<Type...>, Other>
  52476. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  52477. /**
  52478. * @brief Helper variable template.
  52479. * @tparam List Type list.
  52480. * @tparam Type Type to look for.
  52481. */
  52482. template<typename List, typename Type>
  52483. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  52484. /*! @brief Primary template isn't defined on purpose. */
  52485. template<typename...>
  52486. struct type_list_diff;
  52487. /**
  52488. * @brief Computes the difference between two type lists.
  52489. * @tparam Type Types provided by the first type list.
  52490. * @tparam Other Types provided by the second type list.
  52491. */
  52492. template<typename... Type, typename... Other>
  52493. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  52494. /*! @brief A type list that is the difference between the two type lists. */
  52495. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  52496. };
  52497. /**
  52498. * @brief Helper type.
  52499. * @tparam List Type lists between which to compute the difference.
  52500. */
  52501. template<typename... List>
  52502. using type_list_diff_t = typename type_list_diff<List...>::type;
  52503. /*! @brief Primary template isn't defined on purpose. */
  52504. template<typename, template<typename...> class>
  52505. struct type_list_transform;
  52506. /**
  52507. * @brief Applies a given _function_ to a type list and generate a new list.
  52508. * @tparam Type Types provided by the type list.
  52509. * @tparam Op Unary operation as template class with a type member named `type`.
  52510. */
  52511. template<typename... Type, template<typename...> class Op>
  52512. struct type_list_transform<type_list<Type...>, Op> {
  52513. /*! @brief Resulting type list after applying the transform function. */
  52514. // NOLINTNEXTLINE(modernize-type-traits)
  52515. using type = type_list<typename Op<Type>::type...>;
  52516. };
  52517. /**
  52518. * @brief Helper type.
  52519. * @tparam List Type list.
  52520. * @tparam Op Unary operation as template class with a type member named `type`.
  52521. */
  52522. template<typename List, template<typename...> class Op>
  52523. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  52524. /**
  52525. * @brief A class to use to push around lists of constant values, nothing more.
  52526. * @tparam Value Values provided by the value list.
  52527. */
  52528. template<auto... Value>
  52529. struct value_list {
  52530. /*! @brief Value list type. */
  52531. using type = value_list;
  52532. /*! @brief Compile-time number of elements in the value list. */
  52533. static constexpr auto size = sizeof...(Value);
  52534. };
  52535. /*! @brief Primary template isn't defined on purpose. */
  52536. template<std::size_t, typename>
  52537. struct value_list_element;
  52538. /**
  52539. * @brief Provides compile-time indexed access to the values of a value list.
  52540. * @tparam Index Index of the value to return.
  52541. * @tparam Value First value provided by the value list.
  52542. * @tparam Other Other values provided by the value list.
  52543. */
  52544. template<std::size_t Index, auto Value, auto... Other>
  52545. struct value_list_element<Index, value_list<Value, Other...>>
  52546. : value_list_element<Index - 1u, value_list<Other...>> {};
  52547. /**
  52548. * @brief Provides compile-time indexed access to the types of a type list.
  52549. * @tparam Value First value provided by the value list.
  52550. * @tparam Other Other values provided by the value list.
  52551. */
  52552. template<auto Value, auto... Other>
  52553. struct value_list_element<0u, value_list<Value, Other...>> {
  52554. /*! @brief Searched type. */
  52555. using type = decltype(Value);
  52556. /*! @brief Searched value. */
  52557. static constexpr auto value = Value;
  52558. };
  52559. /**
  52560. * @brief Helper type.
  52561. * @tparam Index Index of the type to return.
  52562. * @tparam List Value list to search into.
  52563. */
  52564. template<std::size_t Index, typename List>
  52565. using value_list_element_t = typename value_list_element<Index, List>::type;
  52566. /**
  52567. * @brief Helper type.
  52568. * @tparam Index Index of the value to return.
  52569. * @tparam List Value list to search into.
  52570. */
  52571. template<std::size_t Index, typename List>
  52572. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  52573. /*! @brief Primary template isn't defined on purpose. */
  52574. template<auto, typename>
  52575. struct value_list_index;
  52576. /**
  52577. * @brief Provides compile-time type access to the values of a value list.
  52578. * @tparam Value Value to look for and for which to return the index.
  52579. * @tparam First First value provided by the value list.
  52580. * @tparam Other Other values provided by the value list.
  52581. */
  52582. template<auto Value, auto First, auto... Other>
  52583. struct value_list_index<Value, value_list<First, Other...>> {
  52584. /*! @brief Unsigned integer type. */
  52585. using value_type = std::size_t;
  52586. /*! @brief Compile-time position of the given value in the sublist. */
  52587. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  52588. };
  52589. /**
  52590. * @brief Provides compile-time type access to the values of a value list.
  52591. * @tparam Value Value to look for and for which to return the index.
  52592. * @tparam Other Other values provided by the value list.
  52593. */
  52594. template<auto Value, auto... Other>
  52595. struct value_list_index<Value, value_list<Value, Other...>> {
  52596. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  52597. /*! @brief Unsigned integer type. */
  52598. using value_type = std::size_t;
  52599. /*! @brief Compile-time position of the given value in the sublist. */
  52600. static constexpr value_type value = 0u;
  52601. };
  52602. /**
  52603. * @brief Provides compile-time type access to the values of a value list.
  52604. * @tparam Value Value to look for and for which to return the index.
  52605. */
  52606. template<auto Value>
  52607. struct value_list_index<Value, value_list<>> {
  52608. /*! @brief Unsigned integer type. */
  52609. using value_type = std::size_t;
  52610. /*! @brief Compile-time position of the given type in the sublist. */
  52611. static constexpr value_type value = 0u;
  52612. };
  52613. /**
  52614. * @brief Helper variable template.
  52615. * @tparam List Value list.
  52616. * @tparam Value Value to look for and for which to return the index.
  52617. */
  52618. template<auto Value, typename List>
  52619. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  52620. /**
  52621. * @brief Concatenates multiple value lists.
  52622. * @tparam Value Values provided by the first value list.
  52623. * @tparam Other Values provided by the second value list.
  52624. * @return A value list composed by the values of both the value lists.
  52625. */
  52626. template<auto... Value, auto... Other>
  52627. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  52628. return {};
  52629. }
  52630. /*! @brief Primary template isn't defined on purpose. */
  52631. template<typename...>
  52632. struct value_list_cat;
  52633. /*! @brief Concatenates multiple value lists. */
  52634. template<>
  52635. struct value_list_cat<> {
  52636. /*! @brief A value list composed by the values of all the value lists. */
  52637. using type = value_list<>;
  52638. };
  52639. /**
  52640. * @brief Concatenates multiple value lists.
  52641. * @tparam Value Values provided by the first value list.
  52642. * @tparam Other Values provided by the second value list.
  52643. * @tparam List Other value lists, if any.
  52644. */
  52645. template<auto... Value, auto... Other, typename... List>
  52646. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  52647. /*! @brief A value list composed by the values of all the value lists. */
  52648. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  52649. };
  52650. /**
  52651. * @brief Concatenates multiple value lists.
  52652. * @tparam Value Values provided by the value list.
  52653. */
  52654. template<auto... Value>
  52655. struct value_list_cat<value_list<Value...>> {
  52656. /*! @brief A value list composed by the values of all the value lists. */
  52657. using type = value_list<Value...>;
  52658. };
  52659. /**
  52660. * @brief Helper type.
  52661. * @tparam List Value lists to concatenate.
  52662. */
  52663. template<typename... List>
  52664. using value_list_cat_t = typename value_list_cat<List...>::type;
  52665. /*! @brief Primary template isn't defined on purpose. */
  52666. template<typename>
  52667. struct value_list_unique;
  52668. /**
  52669. * @brief Removes duplicates values from a value list.
  52670. * @tparam Value One of the values provided by the given value list.
  52671. * @tparam Other The other values provided by the given value list.
  52672. */
  52673. template<auto Value, auto... Other>
  52674. struct value_list_unique<value_list<Value, Other...>> {
  52675. /*! @brief A value list without duplicate types. */
  52676. using type = std::conditional_t<
  52677. ((Value == Other) || ...),
  52678. typename value_list_unique<value_list<Other...>>::type,
  52679. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  52680. };
  52681. /*! @brief Removes duplicates values from a value list. */
  52682. template<>
  52683. struct value_list_unique<value_list<>> {
  52684. /*! @brief A value list without duplicate types. */
  52685. using type = value_list<>;
  52686. };
  52687. /**
  52688. * @brief Helper type.
  52689. * @tparam Type A value list.
  52690. */
  52691. template<typename Type>
  52692. using value_list_unique_t = typename value_list_unique<Type>::type;
  52693. /**
  52694. * @brief Provides the member constant `value` to true if a value list contains
  52695. * a given value, false otherwise.
  52696. * @tparam List Value list.
  52697. * @tparam Value Value to look for.
  52698. */
  52699. template<typename List, auto Value>
  52700. struct value_list_contains;
  52701. /**
  52702. * @copybrief value_list_contains
  52703. * @tparam Value Values provided by the value list.
  52704. * @tparam Other Value to look for.
  52705. */
  52706. template<auto... Value, auto Other>
  52707. struct value_list_contains<value_list<Value...>, Other>
  52708. : std::bool_constant<((Value == Other) || ...)> {};
  52709. /**
  52710. * @brief Helper variable template.
  52711. * @tparam List Value list.
  52712. * @tparam Value Value to look for.
  52713. */
  52714. template<typename List, auto Value>
  52715. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  52716. /*! @brief Primary template isn't defined on purpose. */
  52717. template<typename...>
  52718. struct value_list_diff;
  52719. /**
  52720. * @brief Computes the difference between two value lists.
  52721. * @tparam Value Values provided by the first value list.
  52722. * @tparam Other Values provided by the second value list.
  52723. */
  52724. template<auto... Value, auto... Other>
  52725. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  52726. /*! @brief A value list that is the difference between the two value lists. */
  52727. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  52728. };
  52729. /**
  52730. * @brief Helper type.
  52731. * @tparam List Value lists between which to compute the difference.
  52732. */
  52733. template<typename... List>
  52734. using value_list_diff_t = typename value_list_diff<List...>::type;
  52735. /*! @brief Same as std::is_invocable, but with tuples. */
  52736. template<typename, typename>
  52737. struct is_applicable: std::false_type {};
  52738. /**
  52739. * @copybrief is_applicable
  52740. * @tparam Func A valid function type.
  52741. * @tparam Tuple Tuple-like type.
  52742. * @tparam Args The list of arguments to use to probe the function type.
  52743. */
  52744. template<typename Func, template<typename...> class Tuple, typename... Args>
  52745. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  52746. /**
  52747. * @copybrief is_applicable
  52748. * @tparam Func A valid function type.
  52749. * @tparam Tuple Tuple-like type.
  52750. * @tparam Args The list of arguments to use to probe the function type.
  52751. */
  52752. template<typename Func, template<typename...> class Tuple, typename... Args>
  52753. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  52754. /**
  52755. * @brief Helper variable template.
  52756. * @tparam Func A valid function type.
  52757. * @tparam Args The list of arguments to use to probe the function type.
  52758. */
  52759. template<typename Func, typename Args>
  52760. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  52761. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  52762. template<typename, typename, typename>
  52763. struct is_applicable_r: std::false_type {};
  52764. /**
  52765. * @copybrief is_applicable_r
  52766. * @tparam Ret The type to which the return type of the function should be
  52767. * convertible.
  52768. * @tparam Func A valid function type.
  52769. * @tparam Args The list of arguments to use to probe the function type.
  52770. */
  52771. template<typename Ret, typename Func, typename... Args>
  52772. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  52773. /**
  52774. * @brief Helper variable template.
  52775. * @tparam Ret The type to which the return type of the function should be
  52776. * convertible.
  52777. * @tparam Func A valid function type.
  52778. * @tparam Args The list of arguments to use to probe the function type.
  52779. */
  52780. template<typename Ret, typename Func, typename Args>
  52781. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  52782. /**
  52783. * @brief Provides the member constant `value` to true if a given type is
  52784. * complete, false otherwise.
  52785. * @tparam Type The type to test.
  52786. */
  52787. template<typename Type, typename = void>
  52788. struct is_complete: std::false_type {};
  52789. /*! @copydoc is_complete */
  52790. template<typename Type>
  52791. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  52792. /**
  52793. * @brief Helper variable template.
  52794. * @tparam Type The type to test.
  52795. */
  52796. template<typename Type>
  52797. inline constexpr bool is_complete_v = is_complete<Type>::value;
  52798. /**
  52799. * @brief Provides the member constant `value` to true if a given type is an
  52800. * iterator, false otherwise.
  52801. * @tparam Type The type to test.
  52802. */
  52803. template<typename Type, typename = void>
  52804. struct is_iterator: std::false_type {};
  52805. /*! @cond TURN_OFF_DOXYGEN */
  52806. namespace internal {
  52807. template<typename, typename = void>
  52808. struct has_iterator_category: std::false_type {};
  52809. template<typename Type>
  52810. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  52811. } // namespace internal
  52812. /*! @endcond */
  52813. /*! @copydoc is_iterator */
  52814. template<typename Type>
  52815. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  52816. : internal::has_iterator_category<Type> {};
  52817. /**
  52818. * @brief Helper variable template.
  52819. * @tparam Type The type to test.
  52820. */
  52821. template<typename Type>
  52822. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  52823. /**
  52824. * @brief Provides the member constant `value` to true if a given type is both
  52825. * an empty and non-final class, false otherwise.
  52826. * @tparam Type The type to test
  52827. */
  52828. template<typename Type>
  52829. struct is_ebco_eligible
  52830. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  52831. /**
  52832. * @brief Helper variable template.
  52833. * @tparam Type The type to test.
  52834. */
  52835. template<typename Type>
  52836. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  52837. /**
  52838. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  52839. * is valid and denotes a type, false otherwise.
  52840. * @tparam Type The type to test.
  52841. */
  52842. template<typename Type, typename = void>
  52843. struct is_transparent: std::false_type {};
  52844. /*! @copydoc is_transparent */
  52845. template<typename Type>
  52846. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  52847. /**
  52848. * @brief Helper variable template.
  52849. * @tparam Type The type to test.
  52850. */
  52851. template<typename Type>
  52852. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  52853. /*! @cond TURN_OFF_DOXYGEN */
  52854. namespace internal {
  52855. template<typename, typename = void>
  52856. struct has_tuple_size_value: std::false_type {};
  52857. template<typename Type>
  52858. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  52859. template<typename, typename = void>
  52860. struct has_value_type: std::false_type {};
  52861. template<typename Type>
  52862. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  52863. template<typename>
  52864. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  52865. template<typename Type, std::size_t... Index>
  52866. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  52867. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  52868. }
  52869. template<typename>
  52870. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  52871. return false;
  52872. }
  52873. template<typename Type>
  52874. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  52875. return true;
  52876. }
  52877. template<typename Type>
  52878. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  52879. // NOLINTBEGIN(modernize-use-transparent-functors)
  52880. if constexpr(std::is_array_v<Type>) {
  52881. return false;
  52882. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  52883. if constexpr(has_tuple_size_value<Type>::value) {
  52884. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  52885. } else {
  52886. return maybe_equality_comparable<Type>(0);
  52887. }
  52888. } else if constexpr(has_value_type<Type>::value) {
  52889. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  52890. return maybe_equality_comparable<Type>(0);
  52891. } else {
  52892. return false;
  52893. }
  52894. } else {
  52895. return maybe_equality_comparable<Type>(0);
  52896. }
  52897. // NOLINTEND(modernize-use-transparent-functors)
  52898. }
  52899. } // namespace internal
  52900. /*! @endcond */
  52901. /**
  52902. * @brief Provides the member constant `value` to true if a given type is
  52903. * equality comparable, false otherwise.
  52904. * @tparam Type The type to test.
  52905. */
  52906. template<typename Type>
  52907. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  52908. /*! @copydoc is_equality_comparable */
  52909. template<typename Type>
  52910. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  52911. /**
  52912. * @brief Helper variable template.
  52913. * @tparam Type The type to test.
  52914. */
  52915. template<typename Type>
  52916. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  52917. /**
  52918. * @brief Transcribes the constness of a type to another type.
  52919. * @tparam To The type to which to transcribe the constness.
  52920. * @tparam From The type from which to transcribe the constness.
  52921. */
  52922. template<typename To, typename From>
  52923. struct constness_as {
  52924. /*! @brief The type resulting from the transcription of the constness. */
  52925. using type = std::remove_const_t<To>;
  52926. };
  52927. /*! @copydoc constness_as */
  52928. template<typename To, typename From>
  52929. struct constness_as<To, const From> {
  52930. /*! @brief The type resulting from the transcription of the constness. */
  52931. using type = const To;
  52932. };
  52933. /**
  52934. * @brief Alias template to facilitate the transcription of the constness.
  52935. * @tparam To The type to which to transcribe the constness.
  52936. * @tparam From The type from which to transcribe the constness.
  52937. */
  52938. template<typename To, typename From>
  52939. using constness_as_t = typename constness_as<To, From>::type;
  52940. /**
  52941. * @brief Extracts the class of a non-static member object or function.
  52942. * @tparam Member A pointer to a non-static member object or function.
  52943. */
  52944. template<typename Member>
  52945. class member_class {
  52946. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  52947. template<typename Class, typename Ret, typename... Args>
  52948. static Class *clazz(Ret (Class::*)(Args...));
  52949. template<typename Class, typename Ret, typename... Args>
  52950. static Class *clazz(Ret (Class::*)(Args...) const);
  52951. template<typename Class, typename Type>
  52952. static Class *clazz(Type Class::*);
  52953. public:
  52954. /*! @brief The class of the given non-static member object or function. */
  52955. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  52956. };
  52957. /**
  52958. * @brief Helper type.
  52959. * @tparam Member A pointer to a non-static member object or function.
  52960. */
  52961. template<typename Member>
  52962. using member_class_t = typename member_class<Member>::type;
  52963. /**
  52964. * @brief Extracts the n-th argument of a _callable_ type.
  52965. * @tparam Index The index of the argument to extract.
  52966. * @tparam Candidate A valid _callable_ type.
  52967. */
  52968. template<std::size_t Index, typename Candidate>
  52969. class nth_argument {
  52970. template<typename Ret, typename... Args>
  52971. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  52972. template<typename Ret, typename Class, typename... Args>
  52973. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  52974. template<typename Ret, typename Class, typename... Args>
  52975. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  52976. template<typename Type, typename Class>
  52977. static constexpr type_list<Type> pick_up(Type Class ::*);
  52978. template<typename Type>
  52979. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  52980. public:
  52981. /*! @brief N-th argument of the _callable_ type. */
  52982. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  52983. };
  52984. /**
  52985. * @brief Helper type.
  52986. * @tparam Index The index of the argument to extract.
  52987. * @tparam Candidate A valid function, member function or data member type.
  52988. */
  52989. template<std::size_t Index, typename Candidate>
  52990. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  52991. } // namespace entt
  52992. template<typename... Type>
  52993. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  52994. template<std::size_t Index, typename... Type>
  52995. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  52996. template<auto... Value>
  52997. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  52998. template<std::size_t Index, auto... Value>
  52999. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  53000. #endif
  53001. // #include "utility.hpp"
  53002. #ifndef ENTT_CORE_UTILITY_HPP
  53003. #define ENTT_CORE_UTILITY_HPP
  53004. #include <type_traits>
  53005. #include <utility>
  53006. namespace entt {
  53007. /*! @brief Identity function object (waiting for C++20). */
  53008. struct identity {
  53009. /*! @brief Indicates that this is a transparent function object. */
  53010. using is_transparent = void;
  53011. /**
  53012. * @brief Returns its argument unchanged.
  53013. * @tparam Type Type of the argument.
  53014. * @param value The actual argument.
  53015. * @return The submitted value as-is.
  53016. */
  53017. template<typename Type>
  53018. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  53019. return std::forward<Type>(value);
  53020. }
  53021. };
  53022. /**
  53023. * @brief Constant utility to disambiguate overloaded members of a class.
  53024. * @tparam Type Type of the desired overload.
  53025. * @tparam Class Type of class to which the member belongs.
  53026. * @param member A valid pointer to a member.
  53027. * @return Pointer to the member.
  53028. */
  53029. template<typename Type, typename Class>
  53030. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  53031. return member;
  53032. }
  53033. /**
  53034. * @brief Constant utility to disambiguate overloaded functions.
  53035. * @tparam Func Function type of the desired overload.
  53036. * @param func A valid pointer to a function.
  53037. * @return Pointer to the function.
  53038. */
  53039. template<typename Func>
  53040. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  53041. return func;
  53042. }
  53043. /**
  53044. * @brief Helper type for visitors.
  53045. * @tparam Func Types of function objects.
  53046. */
  53047. template<typename... Func>
  53048. struct overloaded: Func... {
  53049. using Func::operator()...;
  53050. };
  53051. /**
  53052. * @brief Deduction guide.
  53053. * @tparam Func Types of function objects.
  53054. */
  53055. template<typename... Func>
  53056. overloaded(Func...) -> overloaded<Func...>;
  53057. /**
  53058. * @brief Basic implementation of a y-combinator.
  53059. * @tparam Func Type of a potentially recursive function.
  53060. */
  53061. template<typename Func>
  53062. struct y_combinator {
  53063. /**
  53064. * @brief Constructs a y-combinator from a given function.
  53065. * @param recursive A potentially recursive function.
  53066. */
  53067. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  53068. : func{std::move(recursive)} {}
  53069. /**
  53070. * @brief Invokes a y-combinator and therefore its underlying function.
  53071. * @tparam Args Types of arguments to use to invoke the underlying function.
  53072. * @param args Parameters to use to invoke the underlying function.
  53073. * @return Return value of the underlying function, if any.
  53074. */
  53075. template<typename... Args>
  53076. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  53077. return func(*this, std::forward<Args>(args)...);
  53078. }
  53079. /*! @copydoc operator()() */
  53080. template<typename... Args>
  53081. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  53082. return func(*this, std::forward<Args>(args)...);
  53083. }
  53084. private:
  53085. Func func;
  53086. };
  53087. } // namespace entt
  53088. #endif
  53089. namespace entt {
  53090. /*! @cond TURN_OFF_DOXYGEN */
  53091. namespace internal {
  53092. enum class any_request : std::uint8_t {
  53093. info,
  53094. transfer,
  53095. assign,
  53096. compare,
  53097. copy,
  53098. move
  53099. };
  53100. template<std::size_t Len, std::size_t Align>
  53101. struct basic_any_storage {
  53102. static constexpr bool has_buffer = true;
  53103. union {
  53104. const void *instance{};
  53105. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  53106. alignas(Align) std::byte buffer[Len];
  53107. };
  53108. };
  53109. template<std::size_t Align>
  53110. struct basic_any_storage<0u, Align> {
  53111. static constexpr bool has_buffer = false;
  53112. const void *instance{};
  53113. };
  53114. template<typename Type, std::size_t Len, std::size_t Align>
  53115. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  53116. struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v<Type>> {};
  53117. template<std::size_t Len, std::size_t Align>
  53118. struct in_situ<void, Len, Align>: std::false_type {};
  53119. } // namespace internal
  53120. /*! @endcond */
  53121. /**
  53122. * @brief A SBO friendly, type-safe container for single values of any type.
  53123. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  53124. * @tparam Align Optional alignment requirement.
  53125. */
  53126. template<std::size_t Len, std::size_t Align>
  53127. class basic_any: private internal::basic_any_storage<Len, Align> {
  53128. using request = internal::any_request;
  53129. using base_type = internal::basic_any_storage<Len, Align>;
  53130. using vtable_type = const void *(const request, const basic_any &, const void *);
  53131. using deleter_type = void(const basic_any &);
  53132. template<typename Type>
  53133. static constexpr bool in_situ_v = internal::in_situ<Type, Len, Align>::value;
  53134. template<typename Type>
  53135. static const void *basic_vtable(const request req, const basic_any &value, const void *other) {
  53136. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  53137. switch(const auto *elem = static_cast<const Type *>(value.data()); req) {
  53138. case request::info:
  53139. return &type_id<Type>();
  53140. case request::transfer:
  53141. if constexpr(std::is_move_assignable_v<Type>) {
  53142. // NOLINTNEXTLINE(bugprone-casting-through-void)
  53143. *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  53144. return other;
  53145. }
  53146. [[fallthrough]];
  53147. case request::assign:
  53148. if constexpr(std::is_copy_assignable_v<Type>) {
  53149. *const_cast<Type *>(elem) = *static_cast<const Type *>(other);
  53150. return other;
  53151. }
  53152. break;
  53153. case request::compare:
  53154. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  53155. return (*elem == *static_cast<const Type *>(other)) ? other : nullptr;
  53156. } else {
  53157. return (elem == other) ? other : nullptr;
  53158. }
  53159. case request::copy:
  53160. if constexpr(std::is_copy_constructible_v<Type>) {
  53161. // NOLINTNEXTLINE(bugprone-casting-through-void)
  53162. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*elem);
  53163. }
  53164. break;
  53165. case request::move:
  53166. ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
  53167. if constexpr(in_situ_v<Type>) {
  53168. // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion)
  53169. return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->buffer) Type{std::move(*const_cast<Type *>(elem))};
  53170. }
  53171. }
  53172. return nullptr;
  53173. }
  53174. template<typename Type>
  53175. static void basic_deleter(const basic_any &value) {
  53176. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  53177. ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v<Type>), "Unexpected policy");
  53178. const auto *elem = static_cast<const Type *>(value.data());
  53179. if constexpr(in_situ_v<Type>) {
  53180. (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem);
  53181. } else if constexpr(std::is_array_v<Type>) {
  53182. delete[] elem;
  53183. } else {
  53184. delete elem;
  53185. }
  53186. }
  53187. template<typename Type, typename... Args>
  53188. void initialize([[maybe_unused]] Args &&...args) {
  53189. using plain_type = std::remove_const_t<std::remove_reference_t<Type>>;
  53190. vtable = basic_vtable<plain_type>;
  53191. underlying_type = type_hash<plain_type>::value();
  53192. if constexpr(std::is_void_v<Type>) {
  53193. deleter = nullptr;
  53194. mode = any_policy::empty;
  53195. this->instance = nullptr;
  53196. } else if constexpr(std::is_lvalue_reference_v<Type>) {
  53197. deleter = nullptr;
  53198. mode = std::is_const_v<std::remove_reference_t<Type>> ? any_policy::cref : any_policy::ref;
  53199. static_assert((std::is_lvalue_reference_v<Args> && ...) && (sizeof...(Args) == 1u), "Invalid arguments");
  53200. // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
  53201. this->instance = (std::addressof(args), ...);
  53202. } else if constexpr(in_situ_v<plain_type>) {
  53203. if constexpr(std::is_trivially_destructible_v<plain_type>) {
  53204. deleter = nullptr;
  53205. } else {
  53206. deleter = &basic_deleter<plain_type>;
  53207. }
  53208. mode = any_policy::embedded;
  53209. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  53210. ::new(&this->buffer) plain_type{std::forward<Args>(args)...};
  53211. } else {
  53212. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  53213. ::new(&this->buffer) plain_type(std::forward<Args>(args)...);
  53214. }
  53215. } else {
  53216. deleter = &basic_deleter<plain_type>;
  53217. mode = any_policy::dynamic;
  53218. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  53219. this->instance = new plain_type{std::forward<Args>(args)...};
  53220. } else if constexpr(std::is_array_v<plain_type>) {
  53221. static_assert(sizeof...(Args) == 0u, "Invalid arguments");
  53222. this->instance = new plain_type[std::extent_v<plain_type>]();
  53223. } else {
  53224. this->instance = new plain_type(std::forward<Args>(args)...);
  53225. }
  53226. }
  53227. }
  53228. void invoke_deleter_if_exists() {
  53229. if(deleter != nullptr) {
  53230. deleter(*this);
  53231. }
  53232. }
  53233. public:
  53234. /*! @brief Size of the internal buffer. */
  53235. static constexpr auto length = Len;
  53236. /*! @brief Alignment requirement. */
  53237. static constexpr auto alignment = Align;
  53238. /*! @brief Default constructor. */
  53239. constexpr basic_any() noexcept
  53240. : basic_any{std::in_place_type<void>} {}
  53241. /**
  53242. * @brief Constructs a wrapper by directly initializing the new object.
  53243. * @tparam Type Type of object to use to initialize the wrapper.
  53244. * @tparam Args Types of arguments to use to construct the new instance.
  53245. * @param args Parameters to use to construct the instance.
  53246. */
  53247. template<typename Type, typename... Args>
  53248. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  53249. : base_type{} {
  53250. initialize<Type>(std::forward<Args>(args)...);
  53251. }
  53252. /**
  53253. * @brief Constructs a wrapper taking ownership of the passed object.
  53254. * @tparam Type Type of object to use to initialize the wrapper.
  53255. * @param value A pointer to an object to take ownership of.
  53256. */
  53257. template<typename Type>
  53258. explicit basic_any(std::in_place_t, Type *value)
  53259. : base_type{} {
  53260. static_assert(!std::is_const_v<Type> && !std::is_void_v<Type>, "Non-const non-void pointer required");
  53261. if(value == nullptr) {
  53262. initialize<void>();
  53263. } else {
  53264. initialize<Type &>(*value);
  53265. deleter = &basic_deleter<Type>;
  53266. mode = any_policy::dynamic;
  53267. }
  53268. }
  53269. /**
  53270. * @brief Constructs a wrapper from a given value.
  53271. * @tparam Type Type of object to use to initialize the wrapper.
  53272. * @param value An instance of an object to use to initialize the wrapper.
  53273. */
  53274. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  53275. basic_any(Type &&value)
  53276. : basic_any{std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
  53277. /**
  53278. * @brief Copy constructor.
  53279. * @param other The instance to copy from.
  53280. */
  53281. basic_any(const basic_any &other)
  53282. : basic_any{} {
  53283. other.vtable(request::copy, other, this);
  53284. }
  53285. /**
  53286. * @brief Move constructor.
  53287. * @param other The instance to move from.
  53288. */
  53289. basic_any(basic_any &&other) noexcept
  53290. : base_type{},
  53291. vtable{other.vtable},
  53292. deleter{other.deleter},
  53293. underlying_type{other.underlying_type},
  53294. mode{other.mode} {
  53295. if(other.mode == any_policy::embedded) {
  53296. other.vtable(request::move, other, this);
  53297. } else if(other.mode != any_policy::empty) {
  53298. this->instance = std::exchange(other.instance, nullptr);
  53299. }
  53300. }
  53301. /*! @brief Frees the internal buffer, whatever it means. */
  53302. ~basic_any() {
  53303. invoke_deleter_if_exists();
  53304. }
  53305. /**
  53306. * @brief Copy assignment operator.
  53307. * @param other The instance to copy from.
  53308. * @return This any object.
  53309. */
  53310. basic_any &operator=(const basic_any &other) {
  53311. if(this != &other) {
  53312. invoke_deleter_if_exists();
  53313. if(other) {
  53314. other.vtable(request::copy, other, this);
  53315. } else {
  53316. initialize<void>();
  53317. }
  53318. }
  53319. return *this;
  53320. }
  53321. /**
  53322. * @brief Move assignment operator.
  53323. * @param other The instance to move from.
  53324. * @return This any object.
  53325. */
  53326. basic_any &operator=(basic_any &&other) noexcept {
  53327. if(this != &other) {
  53328. invoke_deleter_if_exists();
  53329. if(other.mode == any_policy::embedded) {
  53330. other.vtable(request::move, other, this);
  53331. } else if(other.mode != any_policy::empty) {
  53332. this->instance = std::exchange(other.instance, nullptr);
  53333. }
  53334. vtable = other.vtable;
  53335. deleter = other.deleter;
  53336. underlying_type = other.underlying_type;
  53337. mode = other.mode;
  53338. }
  53339. return *this;
  53340. }
  53341. /**
  53342. * @brief Value assignment operator.
  53343. * @tparam Type Type of object to use to initialize the wrapper.
  53344. * @param value An instance of an object to use to initialize the wrapper.
  53345. * @return This any object.
  53346. */
  53347. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  53348. basic_any &operator=(Type &&value) {
  53349. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  53350. return *this;
  53351. }
  53352. /**
  53353. * @brief Returns false if a wrapper is empty, true otherwise.
  53354. * @return False if the wrapper is empty, true otherwise.
  53355. */
  53356. [[nodiscard]] bool has_value() const noexcept {
  53357. return (mode != any_policy::empty);
  53358. }
  53359. /**
  53360. * @brief Returns false if the wrapper does not contain the expected type,
  53361. * true otherwise.
  53362. * @param req Expected type.
  53363. * @return False if the wrapper does not contain the expected type, true
  53364. * otherwise.
  53365. */
  53366. [[nodiscard]] bool has_value(const type_info &req) const noexcept {
  53367. return (underlying_type == req.hash());
  53368. }
  53369. /**
  53370. * @brief Returns false if the wrapper does not contain the expected type,
  53371. * true otherwise.
  53372. * @tparam Type Expected type.
  53373. * @return False if the wrapper does not contain the expected type, true
  53374. * otherwise.
  53375. */
  53376. template<typename Type>
  53377. [[nodiscard]] bool has_value() const noexcept {
  53378. static_assert(std::is_same_v<std::remove_const_t<Type>, Type>, "Invalid type");
  53379. return (underlying_type == type_hash<Type>::value());
  53380. }
  53381. /**
  53382. * @brief Returns the object type info if any, `type_id<void>()` otherwise.
  53383. * @return The object type info if any, `type_id<void>()` otherwise.
  53384. */
  53385. [[nodiscard]] const type_info &info() const noexcept {
  53386. return *static_cast<const type_info *>(vtable(request::info, *this, nullptr));
  53387. }
  53388. /*! @copydoc info */
  53389. [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept {
  53390. return info();
  53391. }
  53392. /**
  53393. * @brief Returns an opaque pointer to the contained instance.
  53394. * @return An opaque pointer the contained instance, if any.
  53395. */
  53396. [[nodiscard]] const void *data() const noexcept {
  53397. if constexpr(base_type::has_buffer) {
  53398. return (mode == any_policy::embedded) ? &this->buffer : this->instance;
  53399. } else {
  53400. return this->instance;
  53401. }
  53402. }
  53403. /**
  53404. * @brief Returns an opaque pointer to the contained instance.
  53405. * @param req Expected type.
  53406. * @return An opaque pointer the contained instance, if any.
  53407. */
  53408. [[nodiscard]] const void *data(const type_info &req) const noexcept {
  53409. return has_value(req) ? data() : nullptr;
  53410. }
  53411. /**
  53412. * @brief Returns an opaque pointer to the contained instance.
  53413. * @tparam Type Expected type.
  53414. * @return An opaque pointer the contained instance, if any.
  53415. */
  53416. template<typename Type>
  53417. [[nodiscard]] const Type *data() const noexcept {
  53418. return has_value<std::remove_const_t<Type>>() ? static_cast<const Type *>(data()) : nullptr;
  53419. }
  53420. /**
  53421. * @brief Returns an opaque pointer to the contained instance.
  53422. * @return An opaque pointer the contained instance, if any.
  53423. */
  53424. [[nodiscard]] void *data() noexcept {
  53425. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data());
  53426. }
  53427. /**
  53428. * @brief Returns an opaque pointer to the contained instance.
  53429. * @param req Expected type.
  53430. * @return An opaque pointer the contained instance, if any.
  53431. */
  53432. [[nodiscard]] void *data(const type_info &req) noexcept {
  53433. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data(req));
  53434. }
  53435. /**
  53436. * @brief Returns an opaque pointer to the contained instance.
  53437. * @tparam Type Expected type.
  53438. * @return An opaque pointer the contained instance, if any.
  53439. */
  53440. template<typename Type>
  53441. [[nodiscard]] Type *data() noexcept {
  53442. if constexpr(std::is_const_v<Type>) {
  53443. return std::as_const(*this).template data<std::remove_const_t<Type>>();
  53444. } else {
  53445. return (mode == any_policy::cref) ? nullptr : const_cast<Type *>(std::as_const(*this).template data<std::remove_const_t<Type>>());
  53446. }
  53447. }
  53448. /**
  53449. * @brief Replaces the contained object by creating a new instance directly.
  53450. * @tparam Type Type of object to use to initialize the wrapper.
  53451. * @tparam Args Types of arguments to use to construct the new instance.
  53452. * @param args Parameters to use to construct the instance.
  53453. */
  53454. template<typename Type, typename... Args>
  53455. void emplace(Args &&...args) {
  53456. invoke_deleter_if_exists();
  53457. initialize<Type>(std::forward<Args>(args)...);
  53458. }
  53459. /**
  53460. * @brief Assigns a value to the contained object without replacing it.
  53461. * @param other The value to assign to the contained object.
  53462. * @return True in case of success, false otherwise.
  53463. */
  53464. bool assign(const basic_any &other) {
  53465. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  53466. return (vtable(request::assign, *this, other.data()) != nullptr);
  53467. }
  53468. return false;
  53469. }
  53470. /*! @copydoc assign */
  53471. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  53472. bool assign(basic_any &&other) {
  53473. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  53474. return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr);
  53475. }
  53476. return false;
  53477. }
  53478. /*! @brief Destroys contained object */
  53479. void reset() {
  53480. invoke_deleter_if_exists();
  53481. initialize<void>();
  53482. }
  53483. /**
  53484. * @brief Returns false if a wrapper is empty, true otherwise.
  53485. * @return False if the wrapper is empty, true otherwise.
  53486. */
  53487. [[nodiscard]] explicit operator bool() const noexcept {
  53488. return has_value();
  53489. }
  53490. /**
  53491. * @brief Checks if two wrappers differ in their content.
  53492. * @param other Wrapper with which to compare.
  53493. * @return False if the two objects differ in their content, true otherwise.
  53494. */
  53495. [[nodiscard]] bool operator==(const basic_any &other) const noexcept {
  53496. if(other && (underlying_type == other.underlying_type)) {
  53497. return (vtable(request::compare, *this, other.data()) != nullptr);
  53498. }
  53499. return (!*this && !other);
  53500. }
  53501. /**
  53502. * @brief Checks if two wrappers differ in their content.
  53503. * @param other Wrapper with which to compare.
  53504. * @return True if the two objects differ in their content, false otherwise.
  53505. */
  53506. [[nodiscard]] bool operator!=(const basic_any &other) const noexcept {
  53507. return !(*this == other);
  53508. }
  53509. /**
  53510. * @brief Aliasing constructor.
  53511. * @return A wrapper that shares a reference to an unmanaged object.
  53512. */
  53513. [[nodiscard]] basic_any as_ref() noexcept {
  53514. basic_any other = std::as_const(*this).as_ref();
  53515. other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref);
  53516. return other;
  53517. }
  53518. /*! @copydoc as_ref */
  53519. [[nodiscard]] basic_any as_ref() const noexcept {
  53520. basic_any other{};
  53521. other.instance = data();
  53522. other.vtable = vtable;
  53523. other.underlying_type = underlying_type;
  53524. other.mode = any_policy::cref;
  53525. return other;
  53526. }
  53527. /**
  53528. * @brief Returns true if a wrapper owns its object, false otherwise.
  53529. * @return True if the wrapper owns its object, false otherwise.
  53530. */
  53531. [[nodiscard]] bool owner() const noexcept {
  53532. return (mode == any_policy::dynamic || mode == any_policy::embedded);
  53533. }
  53534. /**
  53535. * @brief Returns the current mode of an any object.
  53536. * @return The current mode of the any object.
  53537. */
  53538. [[nodiscard]] any_policy policy() const noexcept {
  53539. return mode;
  53540. }
  53541. private:
  53542. vtable_type *vtable{};
  53543. deleter_type *deleter{};
  53544. id_type underlying_type{};
  53545. any_policy mode{};
  53546. };
  53547. /**
  53548. * @brief Performs type-safe access to the contained object.
  53549. * @tparam Type Type to which conversion is required.
  53550. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  53551. * @tparam Align Alignment requirement.
  53552. * @param data Target any object.
  53553. * @return The element converted to the requested type.
  53554. */
  53555. template<typename Type, std::size_t Len, std::size_t Align>
  53556. [[nodiscard]] std::remove_const_t<Type> any_cast(const basic_any<Len, Align> &data) noexcept {
  53557. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  53558. ENTT_ASSERT(instance, "Invalid instance");
  53559. return static_cast<Type>(*instance);
  53560. }
  53561. /*! @copydoc any_cast */
  53562. template<typename Type, std::size_t Len, std::size_t Align>
  53563. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &data) noexcept {
  53564. // forces const on non-reference types to make them work also with wrappers for const references
  53565. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  53566. ENTT_ASSERT(instance, "Invalid instance");
  53567. return static_cast<Type>(*instance);
  53568. }
  53569. /*! @copydoc any_cast */
  53570. template<typename Type, std::size_t Len, std::size_t Align>
  53571. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  53572. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &&data) noexcept {
  53573. if constexpr(std::is_copy_constructible_v<std::remove_const_t<std::remove_reference_t<Type>>>) {
  53574. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  53575. return static_cast<Type>(std::move(*instance));
  53576. }
  53577. return any_cast<Type>(data);
  53578. } else {
  53579. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  53580. ENTT_ASSERT(instance, "Invalid instance");
  53581. return static_cast<Type>(std::move(*instance));
  53582. }
  53583. }
  53584. /*! @copydoc any_cast */
  53585. template<typename Type, std::size_t Len, std::size_t Align>
  53586. [[nodiscard]] const Type *any_cast(const basic_any<Len, Align> *data) noexcept {
  53587. return data->template data<std::remove_const_t<Type>>();
  53588. }
  53589. /*! @copydoc any_cast */
  53590. template<typename Type, std::size_t Len, std::size_t Align>
  53591. [[nodiscard]] Type *any_cast(basic_any<Len, Align> *data) noexcept {
  53592. if constexpr(std::is_const_v<Type>) {
  53593. // last attempt to make wrappers for const references return their values
  53594. return any_cast<Type>(&std::as_const(*data));
  53595. } else {
  53596. return data->template data<Type>();
  53597. }
  53598. }
  53599. /**
  53600. * @brief Constructs a wrapper from a given type, passing it all arguments.
  53601. * @tparam Type Type of object to use to initialize the wrapper.
  53602. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  53603. * @tparam Align Optional alignment requirement.
  53604. * @tparam Args Types of arguments to use to construct the new instance.
  53605. * @param args Parameters to use to construct the instance.
  53606. * @return A properly initialized wrapper for an object of the given type.
  53607. */
  53608. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  53609. [[nodiscard]] basic_any<Len, Align> make_any(Args &&...args) {
  53610. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  53611. }
  53612. /**
  53613. * @brief Forwards its argument and avoids copies for lvalue references.
  53614. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  53615. * @tparam Align Optional alignment requirement.
  53616. * @tparam Type Type of argument to use to construct the new instance.
  53617. * @param value Parameter to use to construct the instance.
  53618. * @return A properly initialized and not necessarily owning wrapper.
  53619. */
  53620. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  53621. [[nodiscard]] basic_any<Len, Align> forward_as_any(Type &&value) {
  53622. return basic_any<Len, Align>{std::in_place_type<Type &&>, std::forward<Type>(value)};
  53623. }
  53624. } // namespace entt
  53625. #endif
  53626. // #include "../core/fwd.hpp"
  53627. // #include "../core/iterator.hpp"
  53628. #ifndef ENTT_CORE_ITERATOR_HPP
  53629. #define ENTT_CORE_ITERATOR_HPP
  53630. #include <iterator>
  53631. #include <memory>
  53632. #include <type_traits>
  53633. #include <utility>
  53634. namespace entt {
  53635. /**
  53636. * @brief Helper type to use as pointer with input iterators.
  53637. * @tparam Type of wrapped value.
  53638. */
  53639. template<typename Type>
  53640. struct input_iterator_pointer final {
  53641. /*! @brief Value type. */
  53642. using value_type = Type;
  53643. /*! @brief Pointer type. */
  53644. using pointer = Type *;
  53645. /*! @brief Reference type. */
  53646. using reference = Type &;
  53647. /**
  53648. * @brief Constructs a proxy object by move.
  53649. * @param val Value to use to initialize the proxy object.
  53650. */
  53651. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  53652. : value{std::move(val)} {}
  53653. /**
  53654. * @brief Access operator for accessing wrapped values.
  53655. * @return A pointer to the wrapped value.
  53656. */
  53657. [[nodiscard]] constexpr pointer operator->() noexcept {
  53658. return std::addressof(value);
  53659. }
  53660. /**
  53661. * @brief Dereference operator for accessing wrapped values.
  53662. * @return A reference to the wrapped value.
  53663. */
  53664. [[nodiscard]] constexpr reference operator*() noexcept {
  53665. return value;
  53666. }
  53667. private:
  53668. Type value;
  53669. };
  53670. /**
  53671. * @brief Plain iota iterator (waiting for C++20).
  53672. * @tparam Type Value type.
  53673. */
  53674. template<typename Type>
  53675. class iota_iterator final {
  53676. static_assert(std::is_integral_v<Type>, "Not an integral type");
  53677. public:
  53678. /*! @brief Value type, likely an integral one. */
  53679. using value_type = Type;
  53680. /*! @brief Invalid pointer type. */
  53681. using pointer = void;
  53682. /*! @brief Non-reference type, same as value type. */
  53683. using reference = value_type;
  53684. /*! @brief Difference type. */
  53685. using difference_type = std::ptrdiff_t;
  53686. /*! @brief Iterator category. */
  53687. using iterator_category = std::input_iterator_tag;
  53688. /*! @brief Default constructor. */
  53689. constexpr iota_iterator() noexcept
  53690. : current{} {}
  53691. /**
  53692. * @brief Constructs an iota iterator from a given value.
  53693. * @param init The initial value assigned to the iota iterator.
  53694. */
  53695. constexpr iota_iterator(const value_type init) noexcept
  53696. : current{init} {}
  53697. /**
  53698. * @brief Pre-increment operator.
  53699. * @return This iota iterator.
  53700. */
  53701. constexpr iota_iterator &operator++() noexcept {
  53702. return ++current, *this;
  53703. }
  53704. /**
  53705. * @brief Post-increment operator.
  53706. * @return This iota iterator.
  53707. */
  53708. constexpr iota_iterator operator++(int) noexcept {
  53709. const iota_iterator orig = *this;
  53710. return ++(*this), orig;
  53711. }
  53712. /**
  53713. * @brief Dereference operator.
  53714. * @return The underlying value.
  53715. */
  53716. [[nodiscard]] constexpr reference operator*() const noexcept {
  53717. return current;
  53718. }
  53719. private:
  53720. value_type current;
  53721. };
  53722. /**
  53723. * @brief Comparison operator.
  53724. * @tparam Type Value type of the iota iterator.
  53725. * @param lhs A properly initialized iota iterator.
  53726. * @param rhs A properly initialized iota iterator.
  53727. * @return True if the two iterators are identical, false otherwise.
  53728. */
  53729. template<typename Type>
  53730. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  53731. return *lhs == *rhs;
  53732. }
  53733. /**
  53734. * @brief Comparison operator.
  53735. * @tparam Type Value type of the iota iterator.
  53736. * @param lhs A properly initialized iota iterator.
  53737. * @param rhs A properly initialized iota iterator.
  53738. * @return True if the two iterators differ, false otherwise.
  53739. */
  53740. template<typename Type>
  53741. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  53742. return !(lhs == rhs);
  53743. }
  53744. /**
  53745. * @brief Utility class to create an iterable object from a pair of iterators.
  53746. * @tparam It Type of iterator.
  53747. * @tparam Sentinel Type of sentinel.
  53748. */
  53749. template<typename It, typename Sentinel = It>
  53750. struct iterable_adaptor final {
  53751. /*! @brief Value type. */
  53752. using value_type = typename std::iterator_traits<It>::value_type;
  53753. /*! @brief Iterator type. */
  53754. using iterator = It;
  53755. /*! @brief Sentinel type. */
  53756. using sentinel = Sentinel;
  53757. /*! @brief Default constructor. */
  53758. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  53759. : first{},
  53760. last{} {}
  53761. /**
  53762. * @brief Creates an iterable object from a pair of iterators.
  53763. * @param from Begin iterator.
  53764. * @param to End iterator.
  53765. */
  53766. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  53767. : first{std::move(from)},
  53768. last{std::move(to)} {}
  53769. /**
  53770. * @brief Returns an iterator to the beginning.
  53771. * @return An iterator to the first element of the range.
  53772. */
  53773. [[nodiscard]] constexpr iterator begin() const noexcept {
  53774. return first;
  53775. }
  53776. /**
  53777. * @brief Returns an iterator to the end.
  53778. * @return An iterator to the element following the last element of the
  53779. * range.
  53780. */
  53781. [[nodiscard]] constexpr sentinel end() const noexcept {
  53782. return last;
  53783. }
  53784. /*! @copydoc begin */
  53785. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  53786. return begin();
  53787. }
  53788. /*! @copydoc end */
  53789. [[nodiscard]] constexpr sentinel cend() const noexcept {
  53790. return end();
  53791. }
  53792. private:
  53793. It first;
  53794. Sentinel last;
  53795. };
  53796. } // namespace entt
  53797. #endif
  53798. // #include "../core/type_info.hpp"
  53799. #ifndef ENTT_CORE_TYPE_INFO_HPP
  53800. #define ENTT_CORE_TYPE_INFO_HPP
  53801. #include <string_view>
  53802. #include <type_traits>
  53803. #include <utility>
  53804. // #include "../config/config.h"
  53805. // #include "fwd.hpp"
  53806. // #include "hashed_string.hpp"
  53807. namespace entt {
  53808. /*! @cond TURN_OFF_DOXYGEN */
  53809. namespace internal {
  53810. struct ENTT_API type_index final {
  53811. [[nodiscard]] static id_type next() noexcept {
  53812. static ENTT_MAYBE_ATOMIC(id_type) value{};
  53813. return value++;
  53814. }
  53815. };
  53816. template<typename Type>
  53817. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  53818. #if defined ENTT_PRETTY_FUNCTION
  53819. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  53820. #else
  53821. return "";
  53822. #endif
  53823. }
  53824. template<typename Type>
  53825. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  53826. #if defined ENTT_PRETTY_FUNCTION
  53827. const std::string_view full_name{pretty_function<Type>()};
  53828. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  53829. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  53830. return value;
  53831. #else
  53832. return std::string_view{};
  53833. #endif
  53834. }
  53835. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  53836. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  53837. constexpr auto value = stripped_type_name<Type>();
  53838. return value;
  53839. }
  53840. template<typename Type>
  53841. [[nodiscard]] std::string_view type_name(char) noexcept {
  53842. static const auto value = stripped_type_name<Type>();
  53843. return value;
  53844. }
  53845. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  53846. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  53847. constexpr auto stripped = stripped_type_name<Type>();
  53848. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  53849. return value;
  53850. }
  53851. template<typename Type>
  53852. [[nodiscard]] id_type type_hash(char) noexcept {
  53853. static const auto value = [](const auto stripped) {
  53854. return hashed_string::value(stripped.data(), stripped.size());
  53855. }(stripped_type_name<Type>());
  53856. return value;
  53857. }
  53858. } // namespace internal
  53859. /*! @endcond */
  53860. /**
  53861. * @brief Type sequential identifier.
  53862. * @tparam Type Type for which to generate a sequential identifier.
  53863. */
  53864. template<typename Type, typename = void>
  53865. struct ENTT_API type_index final {
  53866. /**
  53867. * @brief Returns the sequential identifier of a given type.
  53868. * @return The sequential identifier of a given type.
  53869. */
  53870. [[nodiscard]] static id_type value() noexcept {
  53871. static const id_type value = internal::type_index::next();
  53872. return value;
  53873. }
  53874. /*! @copydoc value */
  53875. [[nodiscard]] constexpr operator id_type() const noexcept {
  53876. return value();
  53877. }
  53878. };
  53879. /**
  53880. * @brief Type hash.
  53881. * @tparam Type Type for which to generate a hash value.
  53882. */
  53883. template<typename Type, typename = void>
  53884. struct type_hash final {
  53885. /**
  53886. * @brief Returns the numeric representation of a given type.
  53887. * @return The numeric representation of the given type.
  53888. */
  53889. #if defined ENTT_PRETTY_FUNCTION
  53890. [[nodiscard]] static constexpr id_type value() noexcept {
  53891. return internal::type_hash<Type>(0);
  53892. #else
  53893. [[nodiscard]] static constexpr id_type value() noexcept {
  53894. return type_index<Type>::value();
  53895. #endif
  53896. }
  53897. /*! @copydoc value */
  53898. [[nodiscard]] constexpr operator id_type() const noexcept {
  53899. return value();
  53900. }
  53901. };
  53902. /**
  53903. * @brief Type name.
  53904. * @tparam Type Type for which to generate a name.
  53905. */
  53906. template<typename Type, typename = void>
  53907. struct type_name final {
  53908. /**
  53909. * @brief Returns the name of a given type.
  53910. * @return The name of the given type.
  53911. */
  53912. [[nodiscard]] static constexpr std::string_view value() noexcept {
  53913. return internal::type_name<Type>(0);
  53914. }
  53915. /*! @copydoc value */
  53916. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  53917. return value();
  53918. }
  53919. };
  53920. /*! @brief Implementation specific information about a type. */
  53921. struct type_info final {
  53922. /**
  53923. * @brief Constructs a type info object for a given type.
  53924. * @tparam Type Type for which to construct a type info object.
  53925. */
  53926. template<typename Type>
  53927. // NOLINTBEGIN(modernize-use-transparent-functors)
  53928. constexpr type_info(std::in_place_type_t<Type>) noexcept
  53929. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  53930. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  53931. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  53932. // NOLINTEND(modernize-use-transparent-functors)
  53933. /**
  53934. * @brief Type index.
  53935. * @return Type index.
  53936. */
  53937. [[nodiscard]] constexpr id_type index() const noexcept {
  53938. return seq;
  53939. }
  53940. /**
  53941. * @brief Type hash.
  53942. * @return Type hash.
  53943. */
  53944. [[nodiscard]] constexpr id_type hash() const noexcept {
  53945. return identifier;
  53946. }
  53947. /**
  53948. * @brief Type name.
  53949. * @return Type name.
  53950. */
  53951. [[nodiscard]] constexpr std::string_view name() const noexcept {
  53952. return alias;
  53953. }
  53954. private:
  53955. id_type seq;
  53956. id_type identifier;
  53957. std::string_view alias;
  53958. };
  53959. /**
  53960. * @brief Compares the contents of two type info objects.
  53961. * @param lhs A type info object.
  53962. * @param rhs A type info object.
  53963. * @return True if the two type info objects are identical, false otherwise.
  53964. */
  53965. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  53966. return lhs.hash() == rhs.hash();
  53967. }
  53968. /**
  53969. * @brief Compares the contents of two type info objects.
  53970. * @param lhs A type info object.
  53971. * @param rhs A type info object.
  53972. * @return True if the two type info objects differ, false otherwise.
  53973. */
  53974. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  53975. return !(lhs == rhs);
  53976. }
  53977. /**
  53978. * @brief Compares two type info objects.
  53979. * @param lhs A valid type info object.
  53980. * @param rhs A valid type info object.
  53981. * @return True if the first element is less than the second, false otherwise.
  53982. */
  53983. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  53984. return lhs.index() < rhs.index();
  53985. }
  53986. /**
  53987. * @brief Compares two type info objects.
  53988. * @param lhs A valid type info object.
  53989. * @param rhs A valid type info object.
  53990. * @return True if the first element is less than or equal to the second, false
  53991. * otherwise.
  53992. */
  53993. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  53994. return !(rhs < lhs);
  53995. }
  53996. /**
  53997. * @brief Compares two type info objects.
  53998. * @param lhs A valid type info object.
  53999. * @param rhs A valid type info object.
  54000. * @return True if the first element is greater than the second, false
  54001. * otherwise.
  54002. */
  54003. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  54004. return rhs < lhs;
  54005. }
  54006. /**
  54007. * @brief Compares two type info objects.
  54008. * @param lhs A valid type info object.
  54009. * @param rhs A valid type info object.
  54010. * @return True if the first element is greater than or equal to the second,
  54011. * false otherwise.
  54012. */
  54013. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  54014. return !(lhs < rhs);
  54015. }
  54016. /**
  54017. * @brief Returns the type info object associated to a given type.
  54018. *
  54019. * The returned element refers to an object with static storage duration.<br/>
  54020. * The type doesn't need to be a complete type. If the type is a reference, the
  54021. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  54022. * are ignored.
  54023. *
  54024. * @tparam Type Type for which to generate a type info object.
  54025. * @return A reference to a properly initialized type info object.
  54026. */
  54027. template<typename Type>
  54028. [[nodiscard]] const type_info &type_id() noexcept {
  54029. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  54030. static const type_info instance{std::in_place_type<Type>};
  54031. return instance;
  54032. } else {
  54033. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  54034. }
  54035. }
  54036. /*! @copydoc type_id */
  54037. template<typename Type>
  54038. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  54039. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  54040. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  54041. }
  54042. } // namespace entt
  54043. #endif
  54044. // #include "../core/type_traits.hpp"
  54045. // #include "../core/utility.hpp"
  54046. // #include "../locator/locator.hpp"
  54047. #ifndef ENTT_LOCATOR_LOCATOR_HPP
  54048. #define ENTT_LOCATOR_LOCATOR_HPP
  54049. #include <memory>
  54050. #include <utility>
  54051. // #include "../config/config.h"
  54052. #ifndef ENTT_CONFIG_CONFIG_H
  54053. #define ENTT_CONFIG_CONFIG_H
  54054. // #include "version.h"
  54055. #ifndef ENTT_CONFIG_VERSION_H
  54056. #define ENTT_CONFIG_VERSION_H
  54057. // #include "macro.h"
  54058. #ifndef ENTT_CONFIG_MACRO_H
  54059. #define ENTT_CONFIG_MACRO_H
  54060. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  54061. #define ENTT_STR(arg) #arg
  54062. #define ENTT_XSTR(arg) ENTT_STR(arg)
  54063. // NOLINTEND(cppcoreguidelines-macro-usage)
  54064. #endif
  54065. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  54066. #define ENTT_VERSION_MAJOR 3
  54067. #define ENTT_VERSION_MINOR 16
  54068. #define ENTT_VERSION_PATCH 0
  54069. #define ENTT_VERSION \
  54070. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  54071. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  54072. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  54073. #endif
  54074. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  54075. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  54076. # define ENTT_CONSTEXPR
  54077. # define ENTT_THROW throw
  54078. # define ENTT_TRY try
  54079. # define ENTT_CATCH catch(...)
  54080. #else
  54081. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  54082. # define ENTT_THROW
  54083. # define ENTT_TRY if(true)
  54084. # define ENTT_CATCH if(false)
  54085. #endif
  54086. #if __has_include(<version>)
  54087. # include <version>
  54088. #
  54089. # if defined(__cpp_consteval)
  54090. # define ENTT_CONSTEVAL consteval
  54091. # endif
  54092. #endif
  54093. #ifndef ENTT_CONSTEVAL
  54094. # define ENTT_CONSTEVAL constexpr
  54095. #endif
  54096. #ifdef ENTT_USE_ATOMIC
  54097. # include <atomic>
  54098. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  54099. #else
  54100. # define ENTT_MAYBE_ATOMIC(Type) Type
  54101. #endif
  54102. #ifndef ENTT_ID_TYPE
  54103. # include <cstdint>
  54104. # define ENTT_ID_TYPE std::uint32_t
  54105. #else
  54106. # include <cstdint> // provides coverage for types in the std namespace
  54107. #endif
  54108. #ifndef ENTT_SPARSE_PAGE
  54109. # define ENTT_SPARSE_PAGE 4096
  54110. #endif
  54111. #ifndef ENTT_PACKED_PAGE
  54112. # define ENTT_PACKED_PAGE 1024
  54113. #endif
  54114. #ifdef ENTT_DISABLE_ASSERT
  54115. # undef ENTT_ASSERT
  54116. # define ENTT_ASSERT(condition, msg) (void(0))
  54117. #elif !defined ENTT_ASSERT
  54118. # include <cassert>
  54119. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  54120. #endif
  54121. #ifdef ENTT_DISABLE_ASSERT
  54122. # undef ENTT_ASSERT_CONSTEXPR
  54123. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  54124. #elif !defined ENTT_ASSERT_CONSTEXPR
  54125. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  54126. #endif
  54127. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  54128. #ifdef ENTT_NO_ETO
  54129. # define ENTT_ETO_TYPE(Type) void
  54130. #else
  54131. # define ENTT_ETO_TYPE(Type) Type
  54132. #endif
  54133. #ifdef ENTT_NO_MIXIN
  54134. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  54135. #else
  54136. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  54137. #endif
  54138. #ifdef ENTT_STANDARD_CPP
  54139. # define ENTT_NONSTD false
  54140. #else
  54141. # define ENTT_NONSTD true
  54142. # if defined __clang__ || defined __GNUC__
  54143. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  54144. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  54145. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  54146. # elif defined _MSC_VER
  54147. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  54148. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  54149. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  54150. # endif
  54151. #endif
  54152. #ifndef ENTT_EXPORT
  54153. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  54154. # define ENTT_EXPORT __declspec(dllexport)
  54155. # define ENTT_IMPORT __declspec(dllimport)
  54156. # define ENTT_HIDDEN
  54157. # elif defined __GNUC__ && __GNUC__ >= 4
  54158. # define ENTT_EXPORT __attribute__((visibility("default")))
  54159. # define ENTT_IMPORT __attribute__((visibility("default")))
  54160. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  54161. # else /* Unsupported compiler */
  54162. # define ENTT_EXPORT
  54163. # define ENTT_IMPORT
  54164. # define ENTT_HIDDEN
  54165. # endif
  54166. #endif
  54167. #ifndef ENTT_API
  54168. # if defined ENTT_API_EXPORT
  54169. # define ENTT_API ENTT_EXPORT
  54170. # elif defined ENTT_API_IMPORT
  54171. # define ENTT_API ENTT_IMPORT
  54172. # else /* No API */
  54173. # define ENTT_API
  54174. # endif
  54175. #endif
  54176. #if defined _MSC_VER
  54177. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  54178. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  54179. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  54180. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  54181. #endif
  54182. // NOLINTEND(cppcoreguidelines-macro-usage)
  54183. #endif
  54184. namespace entt {
  54185. /**
  54186. * @brief Service locator, nothing more.
  54187. *
  54188. * A service locator is used to do what it promises: locate services.<br/>
  54189. * Usually service locators are tightly bound to the services they expose and
  54190. * thus it's hard to define a general purpose class to do that. This tiny class
  54191. * tries to fill the gap and to get rid of the burden of defining a different
  54192. * specific locator for each application.
  54193. *
  54194. * @note
  54195. * Users shouldn't retain references to a service. The recommended way is to
  54196. * retrieve the service implementation currently set each and every time the
  54197. * need for it arises. The risk is to incur in unexpected behaviors otherwise.
  54198. *
  54199. * @tparam Service Service type.
  54200. */
  54201. template<typename Service>
  54202. class locator final {
  54203. class service_handle {
  54204. friend class locator<Service>;
  54205. std::shared_ptr<Service> value{};
  54206. };
  54207. public:
  54208. /*! @brief Service type. */
  54209. using type = Service;
  54210. /*! @brief Service node type. */
  54211. using node_type = service_handle;
  54212. /*! @brief Default constructor, deleted on purpose. */
  54213. locator() = delete;
  54214. /*! @brief Default copy constructor, deleted on purpose. */
  54215. locator(const locator &) = delete;
  54216. /*! @brief Default destructor, deleted on purpose. */
  54217. ~locator() = delete;
  54218. /**
  54219. * @brief Default copy assignment operator, deleted on purpose.
  54220. * @return This locator.
  54221. */
  54222. locator &operator=(const locator &) = delete;
  54223. /**
  54224. * @brief Checks whether a service locator contains a value.
  54225. * @return True if the service locator contains a value, false otherwise.
  54226. */
  54227. [[nodiscard]] static bool has_value() noexcept {
  54228. return (service != nullptr);
  54229. }
  54230. /**
  54231. * @brief Returns a reference to a valid service, if any.
  54232. *
  54233. * @warning
  54234. * Invoking this function can result in undefined behavior if the service
  54235. * hasn't been set yet.
  54236. *
  54237. * @return A reference to the service currently set, if any.
  54238. */
  54239. [[nodiscard]] static Service &value() noexcept {
  54240. ENTT_ASSERT(has_value(), "Service not available");
  54241. return *service;
  54242. }
  54243. /**
  54244. * @brief Returns a service if available or sets it from a fallback type.
  54245. *
  54246. * Arguments are used only if a service doesn't already exist. In all other
  54247. * cases, they are discarded.
  54248. *
  54249. * @tparam Args Types of arguments to use to construct the fallback service.
  54250. * @tparam Type Fallback service type.
  54251. * @param args Parameters to use to construct the fallback service.
  54252. * @return A reference to a valid service.
  54253. */
  54254. template<typename Type = Service, typename... Args>
  54255. [[nodiscard]] static Service &value_or(Args &&...args) {
  54256. return service ? *service : emplace<Type>(std::forward<Args>(args)...);
  54257. }
  54258. /**
  54259. * @brief Sets or replaces a service.
  54260. * @tparam Type Service type.
  54261. * @tparam Args Types of arguments to use to construct the service.
  54262. * @param args Parameters to use to construct the service.
  54263. * @return A reference to a valid service.
  54264. */
  54265. template<typename Type = Service, typename... Args>
  54266. static Service &emplace(Args &&...args) {
  54267. service = std::make_shared<Type>(std::forward<Args>(args)...);
  54268. return *service;
  54269. }
  54270. /**
  54271. * @brief Sets or replaces a service using a given allocator.
  54272. * @tparam Type Service type.
  54273. * @tparam Allocator Type of allocator used to manage memory and elements.
  54274. * @tparam Args Types of arguments to use to construct the service.
  54275. * @param alloc The allocator to use.
  54276. * @param args Parameters to use to construct the service.
  54277. * @return A reference to a valid service.
  54278. */
  54279. template<typename Type = Service, typename Allocator, typename... Args>
  54280. static Service &emplace(std::allocator_arg_t, Allocator alloc, Args &&...args) {
  54281. service = std::allocate_shared<Type>(alloc, std::forward<Args>(args)...);
  54282. return *service;
  54283. }
  54284. /**
  54285. * @brief Returns a handle to the underlying service.
  54286. * @return A handle to the underlying service.
  54287. */
  54288. static node_type handle() noexcept {
  54289. node_type node{};
  54290. node.value = service;
  54291. return node;
  54292. }
  54293. /**
  54294. * @brief Resets or replaces a service.
  54295. * @param other Optional handle with which to replace the service.
  54296. */
  54297. static void reset(const node_type &other = {}) noexcept {
  54298. service = other.value;
  54299. }
  54300. /**
  54301. * @brief Resets or replaces a service.
  54302. * @tparam Type Service type.
  54303. * @tparam Deleter Deleter type.
  54304. * @param elem A pointer to a service to manage.
  54305. * @param deleter A deleter to use to destroy the service.
  54306. */
  54307. template<typename Type, typename Deleter = std::default_delete<Type>>
  54308. static void reset(Type *elem, Deleter deleter = {}) {
  54309. service = std::shared_ptr<Service>{elem, std::move(deleter)};
  54310. }
  54311. private:
  54312. // std::shared_ptr because of its type erased allocator which is useful here
  54313. // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
  54314. inline static std::shared_ptr<Service> service{};
  54315. };
  54316. } // namespace entt
  54317. #endif
  54318. // #include "adl_pointer.hpp"
  54319. #ifndef ENTT_META_ADL_POINTER_HPP
  54320. #define ENTT_META_ADL_POINTER_HPP
  54321. namespace entt {
  54322. /**
  54323. * @brief ADL based lookup function for dereferencing meta pointer-like types.
  54324. * @tparam Type Element type.
  54325. * @param value A pointer-like object.
  54326. * @return The value returned from the dereferenced pointer.
  54327. */
  54328. template<typename Type>
  54329. decltype(auto) dereference_meta_pointer_like(const Type &value) {
  54330. return *value;
  54331. }
  54332. /**
  54333. * @brief Fake ADL based lookup function for meta pointer-like types.
  54334. * @tparam Type Element type.
  54335. */
  54336. template<typename Type>
  54337. struct adl_meta_pointer_like {
  54338. /**
  54339. * @brief Uses the default ADL based lookup method to resolve the call.
  54340. * @param value A pointer-like object.
  54341. * @return The value returned from the dereferenced pointer.
  54342. */
  54343. static decltype(auto) dereference(const Type &value) {
  54344. return dereference_meta_pointer_like(value);
  54345. }
  54346. };
  54347. } // namespace entt
  54348. #endif
  54349. // #include "context.hpp"
  54350. // #include "fwd.hpp"
  54351. // #include "node.hpp"
  54352. #ifndef ENTT_META_NODE_HPP
  54353. #define ENTT_META_NODE_HPP
  54354. #include <array>
  54355. #include <cstddef>
  54356. #include <memory>
  54357. #include <type_traits>
  54358. #include <utility>
  54359. #include <vector>
  54360. // #include "../config/config.h"
  54361. // #include "../core/bit.hpp"
  54362. #ifndef ENTT_CORE_BIT_HPP
  54363. #define ENTT_CORE_BIT_HPP
  54364. #include <cstddef>
  54365. #include <limits>
  54366. #include <type_traits>
  54367. // #include "../config/config.h"
  54368. namespace entt {
  54369. /**
  54370. * @brief Returns the number of set bits in a value (waiting for C++20 and
  54371. * `std::popcount`).
  54372. * @tparam Type Unsigned integer type.
  54373. * @param value A value of unsigned integer type.
  54374. * @return The number of set bits in the value.
  54375. */
  54376. template<typename Type>
  54377. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  54378. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  54379. }
  54380. /**
  54381. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  54382. * `std::has_single_bit`).
  54383. * @tparam Type Unsigned integer type.
  54384. * @param value A value of unsigned integer type.
  54385. * @return True if the value is a power of two, false otherwise.
  54386. */
  54387. template<typename Type>
  54388. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  54389. return value && ((value & (value - 1)) == 0);
  54390. }
  54391. /**
  54392. * @brief Computes the smallest power of two greater than or equal to a value
  54393. * (waiting for C++20 and `std::bit_ceil`).
  54394. * @tparam Type Unsigned integer type.
  54395. * @param value A value of unsigned integer type.
  54396. * @return The smallest power of two greater than or equal to the given value.
  54397. */
  54398. template<typename Type>
  54399. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  54400. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  54401. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  54402. Type curr = value - (value != 0u);
  54403. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  54404. curr |= (curr >> next);
  54405. }
  54406. return ++curr;
  54407. }
  54408. /**
  54409. * @brief Fast module utility function (powers of two only).
  54410. * @tparam Type Unsigned integer type.
  54411. * @param value A value of unsigned integer type.
  54412. * @param mod _Modulus_, it must be a power of two.
  54413. * @return The common remainder.
  54414. */
  54415. template<typename Type>
  54416. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  54417. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  54418. return static_cast<Type>(value & (mod - 1u));
  54419. }
  54420. } // namespace entt
  54421. #endif
  54422. // #include "../core/enum.hpp"
  54423. #ifndef ENTT_CORE_ENUM_HPP
  54424. #define ENTT_CORE_ENUM_HPP
  54425. #include <type_traits>
  54426. namespace entt {
  54427. /**
  54428. * @brief Enable bitmask support for enum classes.
  54429. * @tparam Type The enum type for which to enable bitmask support.
  54430. */
  54431. template<typename Type, typename = void>
  54432. struct enum_as_bitmask: std::false_type {};
  54433. /*! @copydoc enum_as_bitmask */
  54434. template<typename Type>
  54435. struct enum_as_bitmask<Type, std::void_t<decltype(Type::_entt_enum_as_bitmask)>>: std::is_enum<Type> {};
  54436. /**
  54437. * @brief Helper variable template.
  54438. * @tparam Type The enum class type for which to enable bitmask support.
  54439. */
  54440. template<typename Type>
  54441. inline constexpr bool enum_as_bitmask_v = enum_as_bitmask<Type>::value;
  54442. } // namespace entt
  54443. /**
  54444. * @brief Operator available for enums for which bitmask support is enabled.
  54445. * @tparam Type Enum class type.
  54446. * @param lhs The first value to use.
  54447. * @param rhs The second value to use.
  54448. * @return The result of invoking the operator on the underlying types of the
  54449. * two values provided.
  54450. */
  54451. template<typename Type>
  54452. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  54453. operator|(const Type lhs, const Type rhs) noexcept {
  54454. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) | static_cast<std::underlying_type_t<Type>>(rhs));
  54455. }
  54456. /*! @copydoc operator| */
  54457. template<typename Type>
  54458. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  54459. operator&(const Type lhs, const Type rhs) noexcept {
  54460. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) & static_cast<std::underlying_type_t<Type>>(rhs));
  54461. }
  54462. /*! @copydoc operator| */
  54463. template<typename Type>
  54464. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  54465. operator^(const Type lhs, const Type rhs) noexcept {
  54466. return static_cast<Type>(static_cast<std::underlying_type_t<Type>>(lhs) ^ static_cast<std::underlying_type_t<Type>>(rhs));
  54467. }
  54468. /**
  54469. * @brief Operator available for enums for which bitmask support is enabled.
  54470. * @tparam Type Enum class type.
  54471. * @param value The value to use.
  54472. * @return The result of invoking the operator on the underlying types of the
  54473. * value provided.
  54474. */
  54475. template<typename Type>
  54476. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type>
  54477. operator~(const Type value) noexcept {
  54478. return static_cast<Type>(~static_cast<std::underlying_type_t<Type>>(value));
  54479. }
  54480. /*! @copydoc operator~ */
  54481. template<typename Type>
  54482. [[nodiscard]] constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, bool>
  54483. operator!(const Type value) noexcept {
  54484. return !static_cast<std::underlying_type_t<Type>>(value);
  54485. }
  54486. /*! @copydoc operator| */
  54487. template<typename Type>
  54488. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  54489. operator|=(Type &lhs, const Type rhs) noexcept {
  54490. return (lhs = (lhs | rhs));
  54491. }
  54492. /*! @copydoc operator| */
  54493. template<typename Type>
  54494. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  54495. operator&=(Type &lhs, const Type rhs) noexcept {
  54496. return (lhs = (lhs & rhs));
  54497. }
  54498. /*! @copydoc operator| */
  54499. template<typename Type>
  54500. constexpr std::enable_if_t<entt::enum_as_bitmask_v<Type>, Type &>
  54501. operator^=(Type &lhs, const Type rhs) noexcept {
  54502. return (lhs = (lhs ^ rhs));
  54503. }
  54504. #endif
  54505. // #include "../core/fwd.hpp"
  54506. // #include "../core/type_info.hpp"
  54507. // #include "../core/type_traits.hpp"
  54508. // #include "../core/utility.hpp"
  54509. // #include "context.hpp"
  54510. // #include "type_traits.hpp"
  54511. #ifndef ENTT_META_TYPE_TRAITS_HPP
  54512. #define ENTT_META_TYPE_TRAITS_HPP
  54513. #include <type_traits>
  54514. #include <utility>
  54515. namespace entt {
  54516. /**
  54517. * @brief Traits class template to be specialized to enable support for meta
  54518. * template information.
  54519. */
  54520. template<typename>
  54521. struct meta_template_traits;
  54522. /**
  54523. * @brief Traits class template to be specialized to enable support for meta
  54524. * sequence containers.
  54525. */
  54526. template<typename>
  54527. struct meta_sequence_container_traits;
  54528. /**
  54529. * @brief Traits class template to be specialized to enable support for meta
  54530. * associative containers.
  54531. */
  54532. template<typename>
  54533. struct meta_associative_container_traits;
  54534. /**
  54535. * @brief Provides the member constant `value` to true if a given type is a
  54536. * pointer-like type from the point of view of the meta system, false otherwise.
  54537. */
  54538. template<typename, typename = void>
  54539. struct is_meta_pointer_like: std::false_type {};
  54540. /**
  54541. * @brief Partial specialization to ensure that const pointer-like types are
  54542. * also accepted.
  54543. * @tparam Type Potentially pointer-like type.
  54544. */
  54545. template<typename Type>
  54546. struct is_meta_pointer_like<const Type>: is_meta_pointer_like<Type> {};
  54547. /**
  54548. * @brief Helper variable template.
  54549. * @tparam Type Potentially pointer-like type.
  54550. */
  54551. template<typename Type>
  54552. inline constexpr auto is_meta_pointer_like_v = is_meta_pointer_like<Type>::value;
  54553. } // namespace entt
  54554. #endif
  54555. namespace entt {
  54556. class meta_any;
  54557. class meta_type;
  54558. class meta_handle;
  54559. /*! @cond TURN_OFF_DOXYGEN */
  54560. namespace internal {
  54561. enum class meta_traits : std::uint32_t {
  54562. is_none = 0x0000,
  54563. is_const = 0x0001,
  54564. is_static = 0x0002,
  54565. is_arithmetic = 0x0004,
  54566. is_integral = 0x0008,
  54567. is_signed = 0x0010,
  54568. is_array = 0x0020,
  54569. is_enum = 0x0040,
  54570. is_class = 0x0080,
  54571. is_pointer = 0x0100,
  54572. is_pointer_like = 0x0200,
  54573. is_sequence_container = 0x0400,
  54574. is_associative_container = 0x0800,
  54575. _user_defined_traits = 0xFFFF,
  54576. _entt_enum_as_bitmask = 0xFFFF
  54577. };
  54578. template<typename Type>
  54579. [[nodiscard]] auto meta_to_user_traits(const meta_traits traits) noexcept {
  54580. static_assert(std::is_enum_v<Type>, "Invalid enum type");
  54581. constexpr auto shift = popcount(static_cast<std::underlying_type_t<meta_traits>>(meta_traits::_user_defined_traits));
  54582. return Type{static_cast<std::underlying_type_t<Type>>(static_cast<std::underlying_type_t<meta_traits>>(traits) >> shift)};
  54583. }
  54584. template<typename Type>
  54585. [[nodiscard]] auto user_to_meta_traits(const Type value) noexcept {
  54586. static_assert(std::is_enum_v<Type>, "Invalid enum type");
  54587. constexpr auto shift = popcount(static_cast<std::underlying_type_t<meta_traits>>(meta_traits::_user_defined_traits));
  54588. const auto traits = static_cast<std::underlying_type_t<internal::meta_traits>>(static_cast<std::underlying_type_t<Type>>(value));
  54589. ENTT_ASSERT(traits < ((~static_cast<std::underlying_type_t<meta_traits>>(meta_traits::_user_defined_traits)) >> shift), "Invalid traits");
  54590. return meta_traits{traits << shift};
  54591. }
  54592. struct meta_type_node;
  54593. struct meta_custom_node {
  54594. id_type type{};
  54595. std::shared_ptr<void> value{};
  54596. };
  54597. struct meta_base_node {
  54598. id_type type{};
  54599. const meta_type_node &(*resolve)(const meta_context &) noexcept {};
  54600. const void *(*cast)(const void *) noexcept {};
  54601. };
  54602. struct meta_conv_node {
  54603. id_type type{};
  54604. meta_any (*conv)(const meta_ctx &, const void *){};
  54605. };
  54606. struct meta_ctor_node {
  54607. using size_type = std::size_t;
  54608. id_type id{};
  54609. size_type arity{0u};
  54610. meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
  54611. meta_any (*invoke)(const meta_ctx &, meta_any *const){};
  54612. };
  54613. struct meta_data_node {
  54614. using size_type = std::size_t;
  54615. id_type id{};
  54616. const char *name{};
  54617. meta_traits traits{meta_traits::is_none};
  54618. size_type arity{0u};
  54619. const meta_type_node &(*type)(const meta_context &) noexcept {};
  54620. meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
  54621. bool (*set)(meta_handle, meta_any){};
  54622. meta_any (*get)(meta_handle){};
  54623. meta_custom_node custom{};
  54624. };
  54625. struct meta_func_node {
  54626. using size_type = std::size_t;
  54627. id_type id{};
  54628. const char *name{};
  54629. meta_traits traits{meta_traits::is_none};
  54630. size_type arity{0u};
  54631. const meta_type_node &(*ret)(const meta_context &) noexcept {};
  54632. meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
  54633. meta_any (*invoke)(meta_handle, meta_any *const){};
  54634. std::unique_ptr<meta_func_node> next;
  54635. meta_custom_node custom{};
  54636. };
  54637. struct meta_template_node {
  54638. using size_type = std::size_t;
  54639. size_type arity{0u};
  54640. const meta_type_node &(*resolve)(const meta_context &) noexcept {};
  54641. const meta_type_node &(*arg)(const meta_context &, const size_type) noexcept {};
  54642. };
  54643. struct meta_type_descriptor {
  54644. std::vector<meta_ctor_node> ctor{};
  54645. std::vector<meta_base_node> base{};
  54646. std::vector<meta_conv_node> conv{};
  54647. std::vector<meta_data_node> data{};
  54648. std::vector<meta_func_node> func{};
  54649. };
  54650. struct meta_type_node {
  54651. using size_type = std::size_t;
  54652. const type_info *info{};
  54653. id_type id{};
  54654. const char *name{};
  54655. meta_traits traits{meta_traits::is_none};
  54656. size_type size_of{0u};
  54657. const meta_type_node &(*remove_pointer)(const meta_context &) noexcept {};
  54658. meta_any (*default_constructor)(const meta_ctx &){};
  54659. double (*conversion_helper)(void *, const void *){};
  54660. meta_any (*from_void)(const meta_ctx &, void *, const void *){};
  54661. meta_template_node templ{};
  54662. meta_custom_node custom{};
  54663. std::unique_ptr<meta_type_descriptor> details{};
  54664. };
  54665. template<auto Member, typename Type, typename Value>
  54666. [[nodiscard]] auto *find_member(Type &from, const Value value) {
  54667. for(auto &&elem: from) {
  54668. if((elem.*Member) == value) {
  54669. return &elem;
  54670. }
  54671. }
  54672. return static_cast<typename Type::value_type *>(nullptr);
  54673. }
  54674. [[nodiscard]] inline auto *find_overload(meta_func_node *curr, std::remove_pointer_t<decltype(meta_func_node::invoke)> *const ref) {
  54675. while((curr != nullptr) && (curr->invoke != ref)) { curr = curr->next.get(); }
  54676. return curr;
  54677. }
  54678. template<auto Member>
  54679. [[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id, bool recursive) {
  54680. using value_type = typename std::remove_reference_t<decltype((node.details.get()->*Member))>::value_type;
  54681. if(node.details) {
  54682. if(auto *member = find_member<&value_type::id>((node.details.get()->*Member), id); member != nullptr) {
  54683. return member;
  54684. }
  54685. if(recursive) {
  54686. for(auto &&curr: node.details->base) {
  54687. if(auto *elem = look_for<Member>(context, curr.resolve(context), id, recursive); elem) {
  54688. return elem;
  54689. }
  54690. }
  54691. }
  54692. }
  54693. return static_cast<value_type *>(nullptr);
  54694. }
  54695. template<typename Type>
  54696. const meta_type_node &resolve(const meta_context &) noexcept;
  54697. template<typename... Args>
  54698. [[nodiscard]] const meta_type_node &meta_arg_node(const meta_context &context, type_list<Args...>, const std::size_t index) noexcept {
  54699. using resolve_type = const meta_type_node &(*)(const meta_context &) noexcept;
  54700. constexpr std::array<resolve_type, sizeof...(Args)> list{&resolve<std::remove_const_t<std::remove_reference_t<Args>>>...};
  54701. ENTT_ASSERT(index < sizeof...(Args), "Out of bounds");
  54702. return list[index](context);
  54703. }
  54704. [[nodiscard]] inline const void *try_cast(const meta_context &context, const meta_type_node &from, const id_type to, const void *instance) noexcept {
  54705. if(from.details) {
  54706. for(auto &&curr: from.details->base) {
  54707. if(const void *other = curr.cast(instance); curr.type == to) {
  54708. return other;
  54709. } else if(const void *elem = try_cast(context, curr.resolve(context), to, other); elem) {
  54710. return elem;
  54711. }
  54712. }
  54713. }
  54714. return nullptr;
  54715. }
  54716. template<typename Type>
  54717. auto setup_node_for() noexcept {
  54718. meta_type_node node{
  54719. &type_id<Type>(),
  54720. type_id<Type>().hash(),
  54721. nullptr,
  54722. (std::is_arithmetic_v<Type> ? meta_traits::is_arithmetic : meta_traits::is_none)
  54723. | (std::is_integral_v<Type> ? meta_traits::is_integral : meta_traits::is_none)
  54724. | (std::is_signed_v<Type> ? meta_traits::is_signed : meta_traits::is_none)
  54725. | (std::is_array_v<Type> ? meta_traits::is_array : meta_traits::is_none)
  54726. | (std::is_enum_v<Type> ? meta_traits::is_enum : meta_traits::is_none)
  54727. | (std::is_class_v<Type> ? meta_traits::is_class : meta_traits::is_none)
  54728. | (std::is_pointer_v<Type> ? meta_traits::is_pointer : meta_traits::is_none)
  54729. | (is_meta_pointer_like_v<Type> ? meta_traits::is_pointer_like : meta_traits::is_none)
  54730. | (is_complete_v<meta_sequence_container_traits<Type>> ? meta_traits::is_sequence_container : meta_traits::is_none)
  54731. | (is_complete_v<meta_associative_container_traits<Type>> ? meta_traits::is_associative_container : meta_traits::is_none),
  54732. size_of_v<Type>,
  54733. &resolve<std::remove_const_t<std::remove_pointer_t<Type>>>};
  54734. if constexpr(std::is_default_constructible_v<Type>) {
  54735. node.default_constructor = +[](const meta_ctx &ctx) {
  54736. return meta_any{ctx, std::in_place_type<Type>};
  54737. };
  54738. }
  54739. if constexpr(std::is_arithmetic_v<Type>) {
  54740. node.conversion_helper = +[](void *lhs, const void *rhs) {
  54741. return lhs ? static_cast<double>(*static_cast<Type *>(lhs) = static_cast<Type>(*static_cast<const double *>(rhs))) : static_cast<double>(*static_cast<const Type *>(rhs));
  54742. };
  54743. } else if constexpr(std::is_enum_v<Type>) {
  54744. node.conversion_helper = +[](void *lhs, const void *rhs) {
  54745. return lhs ? static_cast<double>(*static_cast<Type *>(lhs) = static_cast<Type>(static_cast<std::underlying_type_t<Type>>(*static_cast<const double *>(rhs)))) : static_cast<double>(*static_cast<const Type *>(rhs));
  54746. };
  54747. }
  54748. if constexpr(!std::is_void_v<Type> && !std::is_function_v<Type>) {
  54749. node.from_void = +[](const meta_ctx &ctx, void *elem, const void *celem) {
  54750. if(elem && celem) { // ownership construction request
  54751. return meta_any{ctx, std::in_place, static_cast<std::decay_t<Type> *>(elem)};
  54752. }
  54753. if(elem) { // non-const reference construction request
  54754. return meta_any{ctx, std::in_place_type<std::decay_t<Type> &>, *static_cast<std::decay_t<Type> *>(elem)};
  54755. }
  54756. // const reference construction request
  54757. return meta_any{ctx, std::in_place_type<const std::decay_t<Type> &>, *static_cast<const std::decay_t<Type> *>(celem)};
  54758. };
  54759. }
  54760. if constexpr(is_complete_v<meta_template_traits<Type>>) {
  54761. node.templ = meta_template_node{
  54762. meta_template_traits<Type>::args_type::size,
  54763. &resolve<typename meta_template_traits<Type>::class_type>,
  54764. +[](const meta_context &area, const std::size_t index) noexcept -> decltype(auto) { return meta_arg_node(area, typename meta_template_traits<Type>::args_type{}, index); }};
  54765. }
  54766. return node;
  54767. }
  54768. [[nodiscard]] inline const meta_type_node *try_resolve(const meta_context &context, const type_info &info) noexcept {
  54769. const auto it = context.value.find(info.hash());
  54770. return (it != context.value.end()) ? it->second.get() : nullptr;
  54771. }
  54772. template<typename Type>
  54773. [[nodiscard]] const meta_type_node &resolve(const meta_context &context) noexcept {
  54774. static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Invalid type");
  54775. static const meta_type_node node = setup_node_for<Type>();
  54776. const auto *elem = try_resolve(context, *node.info);
  54777. return (elem == nullptr) ? node : *elem;
  54778. }
  54779. } // namespace internal
  54780. /*! @endcond */
  54781. } // namespace entt
  54782. #endif
  54783. // #include "range.hpp"
  54784. #ifndef ENTT_META_RANGE_HPP
  54785. #define ENTT_META_RANGE_HPP
  54786. #include <cstddef>
  54787. #include <iterator>
  54788. #include <utility>
  54789. // #include "../core/fwd.hpp"
  54790. // #include "../core/iterator.hpp"
  54791. // #include "context.hpp"
  54792. namespace entt {
  54793. /*! @cond TURN_OFF_DOXYGEN */
  54794. namespace internal {
  54795. struct meta_base_node;
  54796. template<typename Type, typename It>
  54797. struct meta_range_iterator final {
  54798. using value_type = std::pair<id_type, Type>;
  54799. using pointer = input_iterator_pointer<value_type>;
  54800. using reference = value_type;
  54801. using difference_type = std::ptrdiff_t;
  54802. using iterator_category = std::input_iterator_tag;
  54803. using iterator_concept = std::random_access_iterator_tag;
  54804. constexpr meta_range_iterator() noexcept
  54805. : it{},
  54806. ctx{} {}
  54807. constexpr meta_range_iterator(const meta_ctx &area, const It iter) noexcept
  54808. : it{iter},
  54809. ctx{&area} {}
  54810. constexpr meta_range_iterator &operator++() noexcept {
  54811. return ++it, *this;
  54812. }
  54813. constexpr meta_range_iterator operator++(int) noexcept {
  54814. const meta_range_iterator orig = *this;
  54815. return ++(*this), orig;
  54816. }
  54817. constexpr meta_range_iterator &operator--() noexcept {
  54818. return --it, *this;
  54819. }
  54820. constexpr meta_range_iterator operator--(int) noexcept {
  54821. const meta_range_iterator orig = *this;
  54822. return operator--(), orig;
  54823. }
  54824. constexpr meta_range_iterator &operator+=(const difference_type value) noexcept {
  54825. it += value;
  54826. return *this;
  54827. }
  54828. constexpr meta_range_iterator operator+(const difference_type value) const noexcept {
  54829. meta_range_iterator copy = *this;
  54830. return (copy += value);
  54831. }
  54832. constexpr meta_range_iterator &operator-=(const difference_type value) noexcept {
  54833. return (*this += -value);
  54834. }
  54835. constexpr meta_range_iterator operator-(const difference_type value) const noexcept {
  54836. return (*this + -value);
  54837. }
  54838. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  54839. if constexpr(std::is_same_v<It, typename decltype(meta_context::value)::const_iterator>) {
  54840. return {it[value].first, Type{*ctx, *it[value].second}};
  54841. } else if constexpr(std::is_same_v<typename std::iterator_traits<It>::value_type, meta_base_node>) {
  54842. return {it[value].type, Type{*ctx, it[value]}};
  54843. } else {
  54844. return {it[value].id, Type{*ctx, it[value]}};
  54845. }
  54846. }
  54847. [[nodiscard]] constexpr pointer operator->() const noexcept {
  54848. return operator*();
  54849. }
  54850. [[nodiscard]] constexpr reference operator*() const noexcept {
  54851. return operator[](0);
  54852. }
  54853. template<typename... Args>
  54854. friend constexpr std::ptrdiff_t operator-(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  54855. template<typename... Args>
  54856. friend constexpr bool operator==(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  54857. template<typename... Args>
  54858. friend constexpr bool operator<(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  54859. private:
  54860. It it;
  54861. const meta_ctx *ctx;
  54862. };
  54863. template<typename... Args>
  54864. [[nodiscard]] constexpr std::ptrdiff_t operator-(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  54865. return lhs.it - rhs.it;
  54866. }
  54867. template<typename... Args>
  54868. [[nodiscard]] constexpr bool operator==(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  54869. return lhs.it == rhs.it;
  54870. }
  54871. template<typename... Args>
  54872. [[nodiscard]] constexpr bool operator!=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  54873. return !(lhs == rhs);
  54874. }
  54875. template<typename... Args>
  54876. [[nodiscard]] constexpr bool operator<(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  54877. return lhs.it < rhs.it;
  54878. }
  54879. template<typename... Args>
  54880. [[nodiscard]] constexpr bool operator>(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  54881. return rhs < lhs;
  54882. }
  54883. template<typename... Args>
  54884. [[nodiscard]] constexpr bool operator<=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  54885. return !(lhs > rhs);
  54886. }
  54887. template<typename... Args>
  54888. [[nodiscard]] constexpr bool operator>=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  54889. return !(lhs < rhs);
  54890. }
  54891. } // namespace internal
  54892. /*! @endcond */
  54893. /**
  54894. * @brief Iterable range to use to iterate all types of meta objects.
  54895. * @tparam Type Type of meta objects returned.
  54896. * @tparam It Type of forward iterator.
  54897. */
  54898. template<typename Type, typename It>
  54899. using meta_range = iterable_adaptor<internal::meta_range_iterator<Type, It>>;
  54900. } // namespace entt
  54901. #endif
  54902. // #include "type_traits.hpp"
  54903. namespace entt {
  54904. class meta_any;
  54905. class meta_type;
  54906. /*! @brief Proxy object for sequence containers. */
  54907. class meta_sequence_container {
  54908. class meta_iterator;
  54909. public:
  54910. /*! @brief Unsigned integer type. */
  54911. using size_type = std::size_t;
  54912. /*! @brief Meta iterator type. */
  54913. using iterator = meta_iterator;
  54914. /*! @brief Default constructor. */
  54915. meta_sequence_container() = default;
  54916. /**
  54917. * @brief Context aware constructor.
  54918. * @tparam Type Type of container to wrap.
  54919. * @param area The context from which to search for meta types.
  54920. * @param instance The container to wrap.
  54921. */
  54922. template<typename Type>
  54923. meta_sequence_container(const meta_ctx &area, Type &instance) noexcept
  54924. : ctx{&area},
  54925. data{&instance},
  54926. value_type_node{&internal::resolve<typename Type::value_type>},
  54927. const_reference_node{&internal::resolve<std::remove_const_t<std::remove_reference_t<typename Type::const_reference>>>},
  54928. size_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::size},
  54929. clear_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::clear},
  54930. reserve_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::reserve},
  54931. resize_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::resize},
  54932. begin_end_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::iter},
  54933. insert_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::insert},
  54934. erase_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::erase},
  54935. const_only{std::is_const_v<Type>} {}
  54936. [[nodiscard]] inline meta_type value_type() const noexcept;
  54937. [[nodiscard]] inline size_type size() const noexcept;
  54938. inline bool resize(size_type);
  54939. inline bool clear();
  54940. inline bool reserve(size_type);
  54941. [[nodiscard]] inline iterator begin();
  54942. [[nodiscard]] inline iterator end();
  54943. inline iterator insert(const iterator &, meta_any);
  54944. inline iterator erase(const iterator &);
  54945. [[nodiscard]] inline meta_any operator[](size_type);
  54946. [[nodiscard]] inline explicit operator bool() const noexcept;
  54947. private:
  54948. const meta_ctx *ctx{};
  54949. const void *data{};
  54950. const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){};
  54951. const internal::meta_type_node &(*const_reference_node)(const internal::meta_context &){};
  54952. size_type (*size_fn)(const void *){};
  54953. bool (*clear_fn)(void *){};
  54954. bool (*reserve_fn)(void *, const size_type){};
  54955. bool (*resize_fn)(void *, const size_type){};
  54956. iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){};
  54957. iterator (*insert_fn)(const meta_ctx &, void *, const void *, const void *, const iterator &){};
  54958. iterator (*erase_fn)(const meta_ctx &, void *, const iterator &){};
  54959. bool const_only{};
  54960. };
  54961. /*! @brief Proxy object for associative containers. */
  54962. class meta_associative_container {
  54963. class meta_iterator;
  54964. public:
  54965. /*! @brief Unsigned integer type. */
  54966. using size_type = std::size_t;
  54967. /*! @brief Meta iterator type. */
  54968. using iterator = meta_iterator;
  54969. /*! @brief Default constructor. */
  54970. meta_associative_container() = default;
  54971. /**
  54972. * @brief Context aware constructor.
  54973. * @tparam Type Type of container to wrap.
  54974. * @param area The context from which to search for meta types.
  54975. * @param instance The container to wrap.
  54976. */
  54977. template<typename Type>
  54978. meta_associative_container(const meta_ctx &area, Type &instance) noexcept
  54979. : ctx{&area},
  54980. data{&instance},
  54981. key_type_node{&internal::resolve<typename Type::key_type>},
  54982. value_type_node{&internal::resolve<typename Type::value_type>},
  54983. size_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::size},
  54984. clear_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::clear},
  54985. reserve_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::reserve},
  54986. begin_end_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::iter},
  54987. insert_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::insert},
  54988. erase_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::erase},
  54989. find_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::find},
  54990. const_only{std::is_const_v<Type>} {
  54991. if constexpr(!meta_associative_container_traits<std::remove_const_t<Type>>::key_only) {
  54992. mapped_type_node = &internal::resolve<typename Type::mapped_type>;
  54993. }
  54994. }
  54995. [[nodiscard]] inline meta_type key_type() const noexcept;
  54996. [[nodiscard]] inline meta_type mapped_type() const noexcept;
  54997. [[nodiscard]] inline meta_type value_type() const noexcept;
  54998. [[nodiscard]] inline size_type size() const noexcept;
  54999. inline bool clear();
  55000. inline bool reserve(size_type);
  55001. [[nodiscard]] inline iterator begin();
  55002. [[nodiscard]] inline iterator end();
  55003. inline bool insert(meta_any, meta_any);
  55004. inline size_type erase(meta_any);
  55005. [[nodiscard]] inline iterator find(meta_any);
  55006. [[nodiscard]] inline explicit operator bool() const noexcept;
  55007. private:
  55008. const meta_ctx *ctx{};
  55009. const void *data{};
  55010. const internal::meta_type_node &(*key_type_node)(const internal::meta_context &){};
  55011. const internal::meta_type_node &(*mapped_type_node)(const internal::meta_context &){};
  55012. const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){};
  55013. size_type (*size_fn)(const void *){};
  55014. bool (*clear_fn)(void *){};
  55015. bool (*reserve_fn)(void *, const size_type){};
  55016. iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){};
  55017. bool (*insert_fn)(void *, const void *, const void *){};
  55018. size_type (*erase_fn)(void *, const void *){};
  55019. iterator (*find_fn)(const meta_ctx &, void *, const void *, const void *){};
  55020. bool const_only{};
  55021. };
  55022. /*! @brief Opaque wrapper for values of any type. */
  55023. class meta_any {
  55024. using vtable_type = void(const internal::meta_traits, const meta_any &, const void *);
  55025. template<typename Type>
  55026. static void basic_vtable(const internal::meta_traits req, const meta_any &value, [[maybe_unused]] const void *other) {
  55027. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  55028. if(req == internal::meta_traits::is_none) {
  55029. value.node = &internal::resolve<Type>(internal::meta_context::from(*value.ctx));
  55030. }
  55031. if constexpr(is_meta_pointer_like_v<Type>) {
  55032. if(req == internal::meta_traits::is_pointer_like) {
  55033. if constexpr(std::is_function_v<typename std::pointer_traits<Type>::element_type>) {
  55034. const_cast<meta_any &>(value).emplace<Type>(*static_cast<const Type *>(other));
  55035. } else if constexpr(!std::is_void_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
  55036. using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(std::declval<const Type &>()));
  55037. if constexpr(std::is_constructible_v<bool, Type>) {
  55038. if(const auto &pointer_like = *static_cast<const Type *>(other); pointer_like) {
  55039. const_cast<meta_any &>(value).emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(pointer_like));
  55040. }
  55041. } else {
  55042. const_cast<meta_any &>(value).emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(*static_cast<const Type *>(other)));
  55043. }
  55044. }
  55045. }
  55046. }
  55047. if constexpr(is_complete_v<meta_sequence_container_traits<Type>> || is_complete_v<meta_associative_container_traits<Type>>) {
  55048. if(constexpr auto flag = (is_complete_v<meta_sequence_container_traits<Type>> ? internal::meta_traits::is_sequence_container : internal::meta_traits::is_associative_container); !!(req & flag)) {
  55049. using container_type = std::conditional_t<is_complete_v<meta_sequence_container_traits<Type>>, meta_sequence_container, meta_associative_container>;
  55050. if(!!(req & internal::meta_traits::is_const) || (value.storage.policy() == any_policy::cref)) {
  55051. // NOLINTNEXTLINE(bugprone-casting-through-void)
  55052. *static_cast<container_type *>(const_cast<void *>(other)) = container_type{*value.ctx, any_cast<const Type &>(value.storage)};
  55053. } else {
  55054. // NOLINTNEXTLINE(bugprone-casting-through-void)
  55055. *static_cast<container_type *>(const_cast<void *>(other)) = container_type{*value.ctx, any_cast<Type &>(const_cast<meta_any &>(value).storage)};
  55056. }
  55057. }
  55058. }
  55059. }
  55060. [[nodiscard]] const auto &fetch_node() const {
  55061. if(node == nullptr) {
  55062. ENTT_ASSERT(*this, "Invalid vtable function");
  55063. vtable(internal::meta_traits::is_none, *this, nullptr);
  55064. }
  55065. ENTT_ASSERT(node != nullptr, "Invalid pointer to node");
  55066. return *node;
  55067. }
  55068. meta_any(const meta_any &other, any elem)
  55069. : storage{std::move(elem)},
  55070. ctx{other.ctx},
  55071. node{other.node},
  55072. vtable{other.vtable} {}
  55073. public:
  55074. /*! Default constructor. */
  55075. meta_any() = default;
  55076. /**
  55077. * @brief Context aware constructor.
  55078. * @param area The context from which to search for meta types.
  55079. */
  55080. meta_any(meta_ctx_arg_t, const meta_ctx &area)
  55081. : ctx{&area} {}
  55082. /**
  55083. * @brief Constructs a wrapper by directly initializing the new object.
  55084. * @tparam Type Type of object to use to initialize the wrapper.
  55085. * @tparam Args Types of arguments to use to construct the new instance.
  55086. * @param args Parameters to use to construct the instance.
  55087. */
  55088. template<typename Type, typename... Args>
  55089. explicit meta_any(std::in_place_type_t<Type>, Args &&...args)
  55090. : meta_any{locator<meta_ctx>::value_or(), std::in_place_type<Type>, std::forward<Args>(args)...} {}
  55091. /**
  55092. * @brief Constructs a wrapper by directly initializing the new object.
  55093. * @tparam Type Type of object to use to initialize the wrapper.
  55094. * @tparam Args Types of arguments to use to construct the new instance.
  55095. * @param area The context from which to search for meta types.
  55096. * @param args Parameters to use to construct the instance.
  55097. */
  55098. template<typename Type, typename... Args>
  55099. explicit meta_any(const meta_ctx &area, std::in_place_type_t<Type>, Args &&...args)
  55100. : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
  55101. ctx{&area},
  55102. vtable{&basic_vtable<std::remove_const_t<std::remove_reference_t<Type>>>} {}
  55103. /**
  55104. * @brief Constructs a wrapper taking ownership of the passed object.
  55105. * @tparam Type Type of object to use to initialize the wrapper.
  55106. * @param value A pointer to an object to take ownership of.
  55107. */
  55108. template<typename Type>
  55109. explicit meta_any(std::in_place_t, Type *value)
  55110. : meta_any{locator<meta_ctx>::value_or(), std::in_place, value} {}
  55111. /**
  55112. * @brief Constructs a wrapper taking ownership of the passed object.
  55113. * @tparam Type Type of object to use to initialize the wrapper.
  55114. * @param area The context from which to search for meta types.
  55115. * @param value A pointer to an object to take ownership of.
  55116. */
  55117. template<typename Type>
  55118. explicit meta_any(const meta_ctx &area, std::in_place_t, Type *value)
  55119. : storage{std::in_place, value},
  55120. ctx{&area},
  55121. vtable{storage ? &basic_vtable<Type> : nullptr} {
  55122. }
  55123. /**
  55124. * @brief Constructs a wrapper from a given value.
  55125. * @tparam Type Type of object to use to initialize the wrapper.
  55126. * @param value An instance of an object to use to initialize the wrapper.
  55127. */
  55128. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  55129. meta_any(Type &&value)
  55130. : meta_any{locator<meta_ctx>::value_or(), std::forward<Type>(value)} {}
  55131. /**
  55132. * @brief Constructs a wrapper from a given value.
  55133. * @tparam Type Type of object to use to initialize the wrapper.
  55134. * @param area The context from which to search for meta types.
  55135. * @param value An instance of an object to use to initialize the wrapper.
  55136. */
  55137. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  55138. meta_any(const meta_ctx &area, Type &&value)
  55139. : meta_any{area, std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
  55140. /**
  55141. * @brief Context aware copy constructor.
  55142. * @param area The context from which to search for meta types.
  55143. * @param other The instance to copy from.
  55144. */
  55145. meta_any(const meta_ctx &area, const meta_any &other)
  55146. : storage{other.storage},
  55147. ctx{&area},
  55148. node{(ctx == other.ctx) ? other.node : nullptr},
  55149. vtable{other.vtable} {}
  55150. /**
  55151. * @brief Context aware move constructor.
  55152. * @param area The context from which to search for meta types.
  55153. * @param other The instance to move from.
  55154. */
  55155. meta_any(const meta_ctx &area, meta_any &&other)
  55156. : storage{std::move(other.storage)},
  55157. ctx{&area},
  55158. node{(ctx == other.ctx) ? std::exchange(other.node, nullptr) : nullptr},
  55159. vtable{std::exchange(other.vtable, nullptr)} {}
  55160. /**
  55161. * @brief Copy constructor.
  55162. * @param other The instance to copy from.
  55163. */
  55164. meta_any(const meta_any &other) = default;
  55165. /**
  55166. * @brief Move constructor.
  55167. * @param other The instance to move from.
  55168. */
  55169. meta_any(meta_any &&other) noexcept
  55170. : storage{std::move(other.storage)},
  55171. ctx{other.ctx},
  55172. node{std::exchange(other.node, nullptr)},
  55173. vtable{std::exchange(other.vtable, nullptr)} {}
  55174. /*! @brief Default destructor. */
  55175. ~meta_any() = default;
  55176. /**
  55177. * @brief Copy assignment operator.
  55178. * @param other The instance to copy from.
  55179. * @return This meta any object.
  55180. */
  55181. meta_any &operator=(const meta_any &other) {
  55182. if(this != &other) {
  55183. storage = other.storage;
  55184. ctx = other.ctx;
  55185. node = other.node;
  55186. vtable = other.vtable;
  55187. }
  55188. return *this;
  55189. }
  55190. /**
  55191. * @brief Move assignment operator.
  55192. * @param other The instance to move from.
  55193. * @return This meta any object.
  55194. */
  55195. meta_any &operator=(meta_any &&other) noexcept {
  55196. storage = std::move(other.storage);
  55197. ctx = other.ctx;
  55198. node = std::exchange(other.node, nullptr);
  55199. vtable = std::exchange(other.vtable, nullptr);
  55200. return *this;
  55201. }
  55202. /**
  55203. * @brief Value assignment operator.
  55204. * @tparam Type Type of object to use to initialize the wrapper.
  55205. * @param value An instance of an object to use to initialize the wrapper.
  55206. * @return This meta any object.
  55207. */
  55208. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  55209. meta_any &operator=(Type &&value) {
  55210. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  55211. return *this;
  55212. }
  55213. /*! @copydoc any::info */
  55214. [[nodiscard]] inline meta_type type() const noexcept;
  55215. /**
  55216. * @brief Invokes the underlying function, if possible.
  55217. * @tparam Args Types of arguments to use to invoke the function.
  55218. * @param id Unique identifier.
  55219. * @param args Parameters to use to invoke the function.
  55220. * @return A wrapper containing the returned value, if any.
  55221. */
  55222. template<typename... Args>
  55223. meta_any invoke(id_type id, Args &&...args) const;
  55224. /*! @copydoc invoke */
  55225. template<typename... Args>
  55226. meta_any invoke(id_type id, Args &&...args);
  55227. /**
  55228. * @brief Sets the value of a given variable.
  55229. * @tparam Type Type of value to assign.
  55230. * @param id Unique identifier.
  55231. * @param value Parameter to use to set the underlying variable.
  55232. * @return True in case of success, false otherwise.
  55233. */
  55234. template<typename Type>
  55235. bool set(id_type id, Type &&value);
  55236. /**
  55237. * @brief Gets the value of a given variable.
  55238. * @param id Unique identifier.
  55239. * @return A wrapper containing the value of the underlying variable.
  55240. */
  55241. [[nodiscard]] meta_any get(id_type id) const;
  55242. /*! @copydoc get */
  55243. [[nodiscard]] meta_any get(id_type id);
  55244. /**
  55245. * @brief Tries to cast an instance to a given type.
  55246. * @tparam Type Type to which to cast the instance.
  55247. * @return A (possibly null) pointer to the contained instance.
  55248. */
  55249. template<typename Type>
  55250. [[nodiscard]] const Type *try_cast() const {
  55251. const auto *elem = any_cast<const Type>(&storage);
  55252. return ((elem != nullptr) || !*this) ? elem : static_cast<const Type *>(internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), type_hash<std::remove_const_t<Type>>::value(), storage.data()));
  55253. }
  55254. /*! @copydoc try_cast */
  55255. template<typename Type>
  55256. [[nodiscard]] Type *try_cast() {
  55257. return ((storage.policy() == any_policy::cref) && !std::is_const_v<Type>) ? nullptr : const_cast<Type *>(std::as_const(*this).try_cast<std::remove_const_t<Type>>());
  55258. }
  55259. /**
  55260. * @brief Tries to cast an instance to a given type.
  55261. * @tparam Type Type to which to cast the instance.
  55262. * @return A reference to the contained instance.
  55263. */
  55264. template<typename Type>
  55265. [[nodiscard]] std::remove_const_t<Type> cast() const {
  55266. auto *const instance = try_cast<std::remove_reference_t<Type>>();
  55267. ENTT_ASSERT(instance, "Invalid instance");
  55268. return static_cast<Type>(*instance);
  55269. }
  55270. /*! @copydoc cast */
  55271. template<typename Type>
  55272. [[nodiscard]] std::remove_const_t<Type> cast() {
  55273. // forces const on non-reference types to make them work also with wrappers for const references
  55274. auto *const instance = try_cast<std::remove_reference_t<const Type>>();
  55275. ENTT_ASSERT(instance, "Invalid instance");
  55276. return static_cast<Type>(*instance);
  55277. }
  55278. /**
  55279. * @brief Converts an object in such a way that a given cast becomes viable.
  55280. * @param type Meta type to which the cast is requested.
  55281. * @return A valid meta object if convertible, an invalid one otherwise.
  55282. */
  55283. [[nodiscard]] meta_any allow_cast(const meta_type &type) const;
  55284. /**
  55285. * @brief Converts an object in such a way that a given cast becomes viable.
  55286. * @param type Meta type to which the cast is requested.
  55287. * @return True if convertible, false otherwise.
  55288. */
  55289. [[nodiscard]] bool allow_cast(const meta_type &type);
  55290. /**
  55291. * @brief Converts an object in such a way that a given cast becomes viable.
  55292. * @tparam Type Type to which the cast is requested.
  55293. * @return A valid meta object if convertible, an invalid one otherwise.
  55294. */
  55295. template<typename Type>
  55296. [[nodiscard]] meta_any allow_cast() const {
  55297. if constexpr(!std::is_reference_v<Type> || std::is_const_v<std::remove_reference_t<Type>>) {
  55298. if(storage.has_value<std::remove_const_t<std::remove_reference_t<Type>>>()) {
  55299. return as_ref();
  55300. } else if(*this) {
  55301. if constexpr(std::is_arithmetic_v<std::remove_const_t<std::remove_reference_t<Type>>> || std::is_enum_v<std::remove_const_t<std::remove_reference_t<Type>>>) {
  55302. if(const auto &from = fetch_node(); from.conversion_helper) {
  55303. return meta_any{*ctx, static_cast<Type>(from.conversion_helper(nullptr, storage.data()))};
  55304. }
  55305. }
  55306. if(const auto &from = fetch_node(); from.details != nullptr) {
  55307. if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, entt::type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()); elem != nullptr) {
  55308. return elem->conv(*ctx, storage.data());
  55309. }
  55310. for(auto &&curr: from.details->base) {
  55311. if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == entt::type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()) {
  55312. return other;
  55313. } else if(auto from_base = std::as_const(other).template allow_cast<Type>(); from_base) {
  55314. return from_base;
  55315. }
  55316. }
  55317. }
  55318. }
  55319. }
  55320. return meta_any{meta_ctx_arg, *ctx};
  55321. }
  55322. /**
  55323. * @brief Converts an object in such a way that a given cast becomes viable.
  55324. * @tparam Type Type to which the cast is requested.
  55325. * @return True if convertible, false otherwise.
  55326. */
  55327. template<typename Type>
  55328. [[nodiscard]] bool allow_cast() {
  55329. if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
  55330. return allow_cast<const std::remove_reference_t<Type> &>() && (storage.policy() != any_policy::cref);
  55331. } else {
  55332. if(storage.has_value<std::remove_const_t<std::remove_reference_t<Type>>>()) {
  55333. return true;
  55334. } else if(auto other = std::as_const(*this).allow_cast<std::remove_const_t<std::remove_reference_t<Type>>>(); other) {
  55335. if(other.storage.owner()) {
  55336. std::swap(*this, other);
  55337. }
  55338. return true;
  55339. }
  55340. return false;
  55341. }
  55342. }
  55343. /*! @copydoc any::emplace */
  55344. template<typename Type, typename... Args>
  55345. void emplace(Args &&...args) {
  55346. storage.emplace<Type>(std::forward<Args>(args)...);
  55347. auto *prev = std::exchange(vtable, &basic_vtable<std::remove_const_t<std::remove_reference_t<Type>>>);
  55348. node = (prev == vtable) ? node : nullptr;
  55349. }
  55350. /*! @copydoc any::assign */
  55351. bool assign(const meta_any &other);
  55352. /*! @copydoc any::assign */
  55353. bool assign(meta_any &&other);
  55354. /*! @copydoc any::reset */
  55355. void reset() {
  55356. storage.reset();
  55357. node = nullptr;
  55358. vtable = nullptr;
  55359. }
  55360. /**
  55361. * @brief Returns a sequence container proxy.
  55362. * @return A sequence container proxy for the underlying object.
  55363. */
  55364. [[nodiscard]] meta_sequence_container as_sequence_container() noexcept {
  55365. meta_sequence_container proxy{};
  55366. if(*this) { vtable(internal::meta_traits::is_sequence_container, *this, &proxy); }
  55367. return proxy;
  55368. }
  55369. /*! @copydoc as_sequence_container */
  55370. [[nodiscard]] meta_sequence_container as_sequence_container() const noexcept {
  55371. meta_sequence_container proxy{};
  55372. if(*this) { vtable(internal::meta_traits::is_sequence_container | internal::meta_traits::is_const, *this, &proxy); }
  55373. return proxy;
  55374. }
  55375. /**
  55376. * @brief Returns an associative container proxy.
  55377. * @return An associative container proxy for the underlying object.
  55378. */
  55379. [[nodiscard]] meta_associative_container as_associative_container() noexcept {
  55380. meta_associative_container proxy{};
  55381. if(*this) { vtable(internal::meta_traits::is_associative_container, *this, &proxy); }
  55382. return proxy;
  55383. }
  55384. /*! @copydoc as_associative_container */
  55385. [[nodiscard]] meta_associative_container as_associative_container() const noexcept {
  55386. meta_associative_container proxy{};
  55387. if(*this) { vtable(internal::meta_traits::is_associative_container | internal::meta_traits::is_const, *this, &proxy); }
  55388. return proxy;
  55389. }
  55390. /**
  55391. * @brief Indirection operator for dereferencing opaque objects.
  55392. * @return A wrapper that shares a reference to an unmanaged object if the
  55393. * wrapped element is dereferenceable, an invalid meta any otherwise.
  55394. */
  55395. [[nodiscard]] meta_any operator*() const noexcept {
  55396. meta_any ret{meta_ctx_arg, *ctx};
  55397. if(*this) { vtable(internal::meta_traits::is_pointer_like, ret, storage.data()); }
  55398. return ret;
  55399. }
  55400. /*! @copydoc any::operator bool */
  55401. [[nodiscard]] explicit operator bool() const noexcept {
  55402. return !(vtable == nullptr);
  55403. }
  55404. /*! @copydoc any::operator== */
  55405. [[nodiscard]] bool operator==(const meta_any &other) const noexcept {
  55406. return (ctx == other.ctx) && (!*this == !other) && (storage == other.storage);
  55407. }
  55408. /*! @copydoc any::operator!= */
  55409. [[nodiscard]] bool operator!=(const meta_any &other) const noexcept {
  55410. return !(*this == other);
  55411. }
  55412. /*! @copydoc any::as_ref */
  55413. [[nodiscard]] meta_any as_ref() noexcept {
  55414. return meta_any{*this, storage.as_ref()};
  55415. }
  55416. /*! @copydoc any::as_ref */
  55417. [[nodiscard]] meta_any as_ref() const noexcept {
  55418. return meta_any{*this, storage.as_ref()};
  55419. }
  55420. /**
  55421. * @brief Returns the underlying storage.
  55422. * @return The underlyig storage.
  55423. */
  55424. [[nodiscard]] const any &base() const noexcept {
  55425. return storage;
  55426. }
  55427. /**
  55428. * @brief Returns the underlying meta context.
  55429. * @return The underlying meta context.
  55430. */
  55431. [[nodiscard]] const meta_ctx &context() const noexcept {
  55432. return *ctx;
  55433. }
  55434. private:
  55435. any storage{};
  55436. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  55437. mutable const internal::meta_type_node *node{};
  55438. vtable_type *vtable{};
  55439. };
  55440. /**
  55441. * @brief Forwards its argument and avoids copies for lvalue references.
  55442. * @tparam Type Type of argument to use to construct the new instance.
  55443. * @param value Parameter to use to construct the instance.
  55444. * @param ctx The context from which to search for meta types.
  55445. * @return A properly initialized and not necessarily owning wrapper.
  55446. */
  55447. template<typename Type>
  55448. [[nodiscard]] meta_any forward_as_meta(const meta_ctx &ctx, Type &&value) {
  55449. return meta_any{ctx, std::in_place_type<Type &&>, std::forward<Type>(value)};
  55450. }
  55451. /**
  55452. * @brief Forwards its argument and avoids copies for lvalue references.
  55453. * @tparam Type Type of argument to use to construct the new instance.
  55454. * @param value Parameter to use to construct the instance.
  55455. * @return A properly initialized and not necessarily owning wrapper.
  55456. */
  55457. template<typename Type>
  55458. [[nodiscard]] meta_any forward_as_meta(Type &&value) {
  55459. return forward_as_meta(locator<meta_ctx>::value_or(), std::forward<Type>(value));
  55460. }
  55461. /*! @brief Opaque pointers to instances of any type. */
  55462. class meta_handle {
  55463. template<typename Type, typename... Args, typename = std::enable_if_t<std::is_same_v<std::decay_t<Type>, meta_any>>>
  55464. meta_handle(int, Type &value, Args &&...args)
  55465. : any{std::forward<Args>(args)..., value.as_ref()} {}
  55466. template<typename Type, typename... Args>
  55467. meta_handle(char, Type &value, Args &&...args)
  55468. : any{std::forward<Args>(args)..., std::in_place_type<Type &>, value} {}
  55469. public:
  55470. /*! Default constructor. */
  55471. meta_handle() = default;
  55472. /**
  55473. * @brief Creates a handle that points to an unmanaged object.
  55474. * @tparam Type Type of object to use to initialize the handle.
  55475. * @param ctx The context from which to search for meta types.
  55476. * @param value An instance of an object to use to initialize the handle.
  55477. */
  55478. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
  55479. meta_handle(const meta_ctx &ctx, Type &value)
  55480. : meta_handle{0, value, ctx} {}
  55481. /**
  55482. * @brief Creates a handle that points to an unmanaged object.
  55483. * @tparam Type Type of object to use to initialize the handle.
  55484. * @param value An instance of an object to use to initialize the handle.
  55485. */
  55486. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
  55487. meta_handle(Type &value)
  55488. : meta_handle{0, value} {}
  55489. /**
  55490. * @brief Context aware move constructor.
  55491. * @param area The context from which to search for meta types.
  55492. * @param other The instance to move from.
  55493. */
  55494. meta_handle(const meta_ctx &area, meta_handle &&other)
  55495. : any{area, std::move(other.any)} {}
  55496. /*! @brief Default copy constructor, deleted on purpose. */
  55497. meta_handle(const meta_handle &) = delete;
  55498. /*! @brief Default move constructor. */
  55499. meta_handle(meta_handle &&) = default;
  55500. /*! @brief Default destructor. */
  55501. ~meta_handle() = default;
  55502. /**
  55503. * @brief Default copy assignment operator, deleted on purpose.
  55504. * @return This meta handle.
  55505. */
  55506. meta_handle &operator=(const meta_handle &) = delete;
  55507. /**
  55508. * @brief Default move assignment operator.
  55509. * @return This meta handle.
  55510. */
  55511. meta_handle &operator=(meta_handle &&) = default;
  55512. /**
  55513. * @brief Returns false if a handle is invalid, true otherwise.
  55514. * @return False if the handle is invalid, true otherwise.
  55515. */
  55516. [[nodiscard]] explicit operator bool() const noexcept {
  55517. return static_cast<bool>(any);
  55518. }
  55519. /**
  55520. * @brief Access operator for accessing the contained opaque object.
  55521. * @return A wrapper that shares a reference to an unmanaged object.
  55522. */
  55523. [[nodiscard]] meta_any *operator->() {
  55524. return &any;
  55525. }
  55526. /*! @copydoc operator-> */
  55527. [[deprecated("do not use const handles")]] [[nodiscard]] const meta_any *operator->() const {
  55528. return &any;
  55529. }
  55530. private:
  55531. meta_any any{};
  55532. };
  55533. /*! @brief Opaque wrapper for user defined data of any type. */
  55534. struct meta_custom {
  55535. /*! @brief Default constructor. */
  55536. meta_custom() noexcept = default;
  55537. /**
  55538. * @brief Basic constructor for meta objects.
  55539. * @param curr The underlying node with which to construct the instance.
  55540. */
  55541. meta_custom(const internal::meta_custom_node &curr) noexcept
  55542. : node{&curr} {}
  55543. /**
  55544. * @brief Generic conversion operator.
  55545. * @tparam Type Type to which conversion is requested.
  55546. */
  55547. template<typename Type>
  55548. [[nodiscard]] operator Type *() const noexcept {
  55549. return ((node != nullptr) && (type_hash<std::remove_const_t<Type>>::value() == node->type)) ? static_cast<Type *>(node->value.get()) : nullptr;
  55550. }
  55551. /**
  55552. * @brief Generic conversion operator.
  55553. * @tparam Type Type to which conversion is requested.
  55554. */
  55555. template<typename Type>
  55556. [[nodiscard]] operator Type &() const noexcept {
  55557. ENTT_ASSERT(static_cast<Type *>(*this) != nullptr, "Invalid type");
  55558. return *static_cast<Type *>(node->value.get());
  55559. }
  55560. private:
  55561. const internal::meta_custom_node *node{};
  55562. };
  55563. /*! @brief Opaque wrapper for data members. */
  55564. class meta_data {
  55565. [[nodiscard]] auto &node_or_assert() const noexcept {
  55566. ENTT_ASSERT(node != nullptr, "Invalid pointer to node");
  55567. return *node;
  55568. }
  55569. public:
  55570. /*! @brief Unsigned integer type. */
  55571. using size_type = typename internal::meta_data_node::size_type;
  55572. /*! @brief Default constructor. */
  55573. meta_data() noexcept = default;
  55574. /**
  55575. * @brief Context aware constructor for meta objects.
  55576. * @param area The context from which to search for meta types.
  55577. * @param curr The underlying node with which to construct the instance.
  55578. */
  55579. meta_data(const meta_ctx &area, const internal::meta_data_node &curr) noexcept
  55580. : node{&curr},
  55581. ctx{&area} {}
  55582. /**
  55583. * @brief Returns the name assigned to a data member, if any.
  55584. * @return The name assigned to the data member, if any.
  55585. */
  55586. [[nodiscard]] const char *name() const noexcept {
  55587. return node_or_assert().name;
  55588. }
  55589. /**
  55590. * @brief Returns the number of setters available.
  55591. * @return The number of setters available.
  55592. */
  55593. [[nodiscard]] size_type arity() const noexcept {
  55594. return node_or_assert().arity;
  55595. }
  55596. /**
  55597. * @brief Indicates whether a data member is constant or not.
  55598. * @return True if the data member is constant, false otherwise.
  55599. */
  55600. [[nodiscard]] bool is_const() const noexcept {
  55601. return !!(node_or_assert().traits & internal::meta_traits::is_const);
  55602. }
  55603. /**
  55604. * @brief Indicates whether a data member is static or not.
  55605. * @return True if the data member is static, false otherwise.
  55606. */
  55607. [[nodiscard]] bool is_static() const noexcept {
  55608. return !!(node_or_assert().traits & internal::meta_traits::is_static);
  55609. }
  55610. /*! @copydoc meta_any::type */
  55611. [[nodiscard]] inline meta_type type() const noexcept;
  55612. /**
  55613. * @brief Sets the value of a given variable.
  55614. * @tparam Instance Type of instance to operate on.
  55615. * @tparam Type Type of value to assign.
  55616. * @param instance An instance that fits the underlying type.
  55617. * @param value Parameter to use to set the underlying variable.
  55618. * @return True in case of success, false otherwise.
  55619. */
  55620. template<typename Instance = meta_handle, typename Type>
  55621. // NOLINTNEXTLINE(modernize-use-nodiscard)
  55622. bool set(Instance &&instance, Type &&value) const {
  55623. return node_or_assert().set(meta_handle{*ctx, std::forward<Instance>(instance)}, meta_any{*ctx, std::forward<Type>(value)});
  55624. }
  55625. /**
  55626. * @brief Gets the value of a given variable.
  55627. * @tparam Instance Type of instance to operate on.
  55628. * @param instance An instance that fits the underlying type.
  55629. * @return A wrapper containing the value of the underlying variable.
  55630. */
  55631. template<typename Instance = meta_handle>
  55632. [[nodiscard]] meta_any get(Instance &&instance) const {
  55633. return node_or_assert().get(meta_handle{*ctx, std::forward<Instance>(instance)});
  55634. }
  55635. /**
  55636. * @brief Returns the type accepted by the i-th setter.
  55637. * @param index Index of the setter of which to return the accepted type.
  55638. * @return The type accepted by the i-th setter.
  55639. */
  55640. [[nodiscard]] inline meta_type arg(size_type index) const noexcept;
  55641. /**
  55642. * @brief Returns all meta traits for a given meta object.
  55643. * @tparam Type The type to convert the meta traits to.
  55644. * @return The registered meta traits, if any.
  55645. */
  55646. template<typename Type>
  55647. [[nodiscard]] Type traits() const noexcept {
  55648. return internal::meta_to_user_traits<Type>(node_or_assert().traits);
  55649. }
  55650. /**
  55651. * @brief Returns user defined data for a given meta object.
  55652. * @return User defined arbitrary data.
  55653. */
  55654. [[nodiscard]] meta_custom custom() const noexcept {
  55655. return {node_or_assert().custom};
  55656. }
  55657. /**
  55658. * @brief Returns true if an object is valid, false otherwise.
  55659. * @return True if the object is valid, false otherwise.
  55660. */
  55661. [[nodiscard]] explicit operator bool() const noexcept {
  55662. return (node != nullptr);
  55663. }
  55664. /**
  55665. * @brief Checks if two objects refer to the same type.
  55666. * @param other The object with which to compare.
  55667. * @return True if the objects refer to the same type, false otherwise.
  55668. */
  55669. [[nodiscard]] bool operator==(const meta_data &other) const noexcept {
  55670. return (ctx == other.ctx) && (node == other.node);
  55671. }
  55672. private:
  55673. const internal::meta_data_node *node{};
  55674. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  55675. };
  55676. /**
  55677. * @brief Checks if two objects refer to the same type.
  55678. * @param lhs An object, either valid or not.
  55679. * @param rhs An object, either valid or not.
  55680. * @return False if the objects refer to the same node, true otherwise.
  55681. */
  55682. [[nodiscard]] inline bool operator!=(const meta_data &lhs, const meta_data &rhs) noexcept {
  55683. return !(lhs == rhs);
  55684. }
  55685. /*! @brief Opaque wrapper for member functions. */
  55686. class meta_func {
  55687. [[nodiscard]] auto &node_or_assert() const noexcept {
  55688. ENTT_ASSERT(node != nullptr, "Invalid pointer to node");
  55689. return *node;
  55690. }
  55691. public:
  55692. /*! @brief Unsigned integer type. */
  55693. using size_type = typename internal::meta_func_node::size_type;
  55694. /*! @brief Default constructor. */
  55695. meta_func() noexcept = default;
  55696. /**
  55697. * @brief Context aware constructor for meta objects.
  55698. * @param area The context from which to search for meta types.
  55699. * @param curr The underlying node with which to construct the instance.
  55700. */
  55701. meta_func(const meta_ctx &area, const internal::meta_func_node &curr) noexcept
  55702. : node{&curr},
  55703. ctx{&area} {}
  55704. /**
  55705. * @brief Returns the name assigned to a member function, if any.
  55706. * @return The name assigned to the member function, if any.
  55707. */
  55708. [[nodiscard]] const char *name() const noexcept {
  55709. return node_or_assert().name;
  55710. }
  55711. /**
  55712. * @brief Returns the number of arguments accepted by a member function.
  55713. * @return The number of arguments accepted by the member function.
  55714. */
  55715. [[nodiscard]] size_type arity() const noexcept {
  55716. return node_or_assert().arity;
  55717. }
  55718. /**
  55719. * @brief Indicates whether a member function is constant or not.
  55720. * @return True if the member function is constant, false otherwise.
  55721. */
  55722. [[nodiscard]] bool is_const() const noexcept {
  55723. return !!(node_or_assert().traits & internal::meta_traits::is_const);
  55724. }
  55725. /**
  55726. * @brief Indicates whether a member function is static or not.
  55727. * @return True if the member function is static, false otherwise.
  55728. */
  55729. [[nodiscard]] bool is_static() const noexcept {
  55730. return !!(node_or_assert().traits & internal::meta_traits::is_static);
  55731. }
  55732. /**
  55733. * @brief Returns the return type of a member function.
  55734. * @return The return type of the member function.
  55735. */
  55736. [[nodiscard]] inline meta_type ret() const noexcept;
  55737. /**
  55738. * @brief Returns the type of the i-th argument of a member function.
  55739. * @param index Index of the argument of which to return the type.
  55740. * @return The type of the i-th argument of a member function.
  55741. */
  55742. [[nodiscard]] inline meta_type arg(size_type index) const noexcept;
  55743. /**
  55744. * @brief Invokes the underlying function, if possible.
  55745. * @tparam Instance Type of instance to operate on.
  55746. * @param instance An instance that fits the underlying type.
  55747. * @param args Parameters to use to invoke the function.
  55748. * @param sz Number of parameters to use to invoke the function.
  55749. * @return A wrapper containing the returned value, if any.
  55750. */
  55751. template<typename Instance = meta_handle>
  55752. meta_any invoke(Instance &&instance, meta_any *const args, const size_type sz) const {
  55753. return (sz == arity()) ? node_or_assert().invoke(meta_handle{*ctx, std::forward<Instance>(instance)}, args) : meta_any{meta_ctx_arg, *ctx};
  55754. }
  55755. /**
  55756. * @copybrief invoke
  55757. * @tparam Instance Type of instance to operate on.
  55758. * @tparam Args Types of arguments to use to invoke the function.
  55759. * @param instance An instance that fits the underlying type.
  55760. * @param args Parameters to use to invoke the function.
  55761. * @return A wrapper containing the returned value, if any.
  55762. */
  55763. template<typename Instance = meta_handle, typename... Args>
  55764. // NOLINTNEXTLINE(modernize-use-nodiscard)
  55765. meta_any invoke(Instance &&instance, Args &&...args) const {
  55766. return invoke(std::forward<Instance>(instance), std::array<meta_any, sizeof...(Args)>{meta_any{*ctx, std::forward<Args>(args)}...}.data(), sizeof...(Args));
  55767. }
  55768. /*! @copydoc meta_data::traits */
  55769. template<typename Type>
  55770. [[nodiscard]] Type traits() const noexcept {
  55771. return internal::meta_to_user_traits<Type>(node_or_assert().traits);
  55772. }
  55773. /*! @copydoc meta_data::custom */
  55774. [[nodiscard]] meta_custom custom() const noexcept {
  55775. return {node_or_assert().custom};
  55776. }
  55777. /**
  55778. * @brief Returns the next overload of a given function, if any.
  55779. * @return The next overload of the given function, if any.
  55780. */
  55781. [[nodiscard]] meta_func next() const {
  55782. return (node_or_assert().next != nullptr) ? meta_func{*ctx, *node_or_assert().next} : meta_func{};
  55783. }
  55784. /*! @copydoc meta_data::operator bool */
  55785. [[nodiscard]] explicit operator bool() const noexcept {
  55786. return (node != nullptr);
  55787. }
  55788. /*! @copydoc meta_data::operator== */
  55789. [[nodiscard]] bool operator==(const meta_func &other) const noexcept {
  55790. return (ctx == other.ctx) && (node == other.node);
  55791. }
  55792. private:
  55793. const internal::meta_func_node *node{};
  55794. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  55795. };
  55796. /*! @copydoc operator!=(const meta_data &, const meta_data &) */
  55797. [[nodiscard]] inline bool operator!=(const meta_func &lhs, const meta_func &rhs) noexcept {
  55798. return !(lhs == rhs);
  55799. }
  55800. /*! @brief Opaque wrapper for types. */
  55801. class meta_type {
  55802. [[nodiscard]] const auto &fetch_node() const {
  55803. return (node == nullptr) ? internal::resolve<void>(internal::meta_context::from(*ctx)) : *node;
  55804. }
  55805. template<typename Func>
  55806. [[nodiscard]] auto lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, [[maybe_unused]] bool constness, Func next) const {
  55807. decltype(next()) candidate = nullptr;
  55808. size_type same{};
  55809. bool ambiguous{};
  55810. for(auto curr = next(); curr; curr = next()) {
  55811. if constexpr(std::is_same_v<std::decay_t<decltype(*curr)>, internal::meta_func_node>) {
  55812. if(constness && !(curr->traits & internal::meta_traits::is_const)) {
  55813. continue;
  55814. }
  55815. }
  55816. if(curr->arity == sz) {
  55817. size_type match{};
  55818. size_type pos{};
  55819. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  55820. for(; pos < sz && args[pos]; ++pos) {
  55821. const auto other = curr->arg(*ctx, pos);
  55822. const auto type = args[pos].type();
  55823. if(const auto &info = other.info(); info == type.info()) {
  55824. ++match;
  55825. } else if(!(type.fetch_node().conversion_helper && other.fetch_node().conversion_helper) && !(type.fetch_node().details && (internal::find_member<&internal::meta_base_node::type>(type.fetch_node().details->base, info.hash()) || internal::find_member<&internal::meta_conv_node::type>(type.fetch_node().details->conv, info.hash())))) {
  55826. break;
  55827. }
  55828. }
  55829. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  55830. if(pos == sz) {
  55831. if(!candidate || match > same) {
  55832. candidate = curr;
  55833. same = match;
  55834. ambiguous = false;
  55835. } else if(match == same) {
  55836. if constexpr(std::is_same_v<std::decay_t<decltype(*curr)>, internal::meta_func_node>) {
  55837. if(!!(curr->traits & internal::meta_traits::is_const) != !!(candidate->traits & internal::meta_traits::is_const)) {
  55838. candidate = !!(candidate->traits & internal::meta_traits::is_const) ? curr : candidate;
  55839. ambiguous = false;
  55840. continue;
  55841. }
  55842. }
  55843. ambiguous = true;
  55844. }
  55845. }
  55846. }
  55847. }
  55848. return ambiguous ? nullptr : candidate;
  55849. }
  55850. public:
  55851. /*! @brief Unsigned integer type. */
  55852. using size_type = typename internal::meta_type_node::size_type;
  55853. /*! @brief Default constructor. */
  55854. meta_type() noexcept = default;
  55855. /**
  55856. * @brief Context aware constructor for meta objects.
  55857. * @param area The context from which to search for meta types.
  55858. * @param curr The underlying node with which to construct the instance.
  55859. */
  55860. meta_type(const meta_ctx &area, const internal::meta_type_node &curr) noexcept
  55861. : node{&curr},
  55862. ctx{&area} {}
  55863. /**
  55864. * @brief Context aware constructor for meta objects.
  55865. * @param area The context from which to search for meta types.
  55866. * @param curr The underlying node with which to construct the instance.
  55867. */
  55868. meta_type(const meta_ctx &area, const internal::meta_base_node &curr) noexcept
  55869. : meta_type{area, curr.resolve(internal::meta_context::from(area))} {}
  55870. /**
  55871. * @brief Returns the type info object of the underlying type.
  55872. * @return The type info object of the underlying type.
  55873. */
  55874. [[nodiscard]] const type_info &info() const noexcept {
  55875. return *fetch_node().info;
  55876. }
  55877. /**
  55878. * @brief Returns the identifier assigned to a type.
  55879. * @return The identifier assigned to the type.
  55880. */
  55881. [[nodiscard]] id_type id() const noexcept {
  55882. return fetch_node().id;
  55883. }
  55884. /**
  55885. * @brief Returns the name assigned to a type, if any.
  55886. * @return The name assigned to the type, if any.
  55887. */
  55888. [[nodiscard]] const char *name() const noexcept {
  55889. return fetch_node().name;
  55890. }
  55891. /**
  55892. * @brief Returns the size of the underlying type if known.
  55893. * @return The size of the underlying type if known, 0 otherwise.
  55894. */
  55895. [[nodiscard]] size_type size_of() const noexcept {
  55896. return fetch_node().size_of;
  55897. }
  55898. /**
  55899. * @brief Checks whether a type refers to an arithmetic type or not.
  55900. * @return True if the underlying type is an arithmetic type, false
  55901. * otherwise.
  55902. */
  55903. [[nodiscard]] bool is_arithmetic() const noexcept {
  55904. return !!(fetch_node().traits & internal::meta_traits::is_arithmetic);
  55905. }
  55906. /**
  55907. * @brief Checks whether a type refers to an integral type or not.
  55908. * @return True if the underlying type is an integral type, false otherwise.
  55909. */
  55910. [[nodiscard]] bool is_integral() const noexcept {
  55911. return !!(fetch_node().traits & internal::meta_traits::is_integral);
  55912. }
  55913. /**
  55914. * @brief Checks whether a type refers to a signed type or not.
  55915. * @return True if the underlying type is a signed type, false otherwise.
  55916. */
  55917. [[nodiscard]] bool is_signed() const noexcept {
  55918. return !!(fetch_node().traits & internal::meta_traits::is_signed);
  55919. }
  55920. /**
  55921. * @brief Checks whether a type refers to an array type or not.
  55922. * @return True if the underlying type is an array type, false otherwise.
  55923. */
  55924. [[nodiscard]] bool is_array() const noexcept {
  55925. return !!(fetch_node().traits & internal::meta_traits::is_array);
  55926. }
  55927. /**
  55928. * @brief Checks whether a type refers to an enum or not.
  55929. * @return True if the underlying type is an enum, false otherwise.
  55930. */
  55931. [[nodiscard]] bool is_enum() const noexcept {
  55932. return !!(fetch_node().traits & internal::meta_traits::is_enum);
  55933. }
  55934. /**
  55935. * @brief Checks whether a type refers to a class or not.
  55936. * @return True if the underlying type is a class, false otherwise.
  55937. */
  55938. [[nodiscard]] bool is_class() const noexcept {
  55939. return !!(fetch_node().traits & internal::meta_traits::is_class);
  55940. }
  55941. /**
  55942. * @brief Checks whether a type refers to a pointer or not.
  55943. * @return True if the underlying type is a pointer, false otherwise.
  55944. */
  55945. [[nodiscard]] bool is_pointer() const noexcept {
  55946. return !!(fetch_node().traits & internal::meta_traits::is_pointer);
  55947. }
  55948. /**
  55949. * @brief Provides the type for which the pointer is defined.
  55950. * @return The type for which the pointer is defined or this type if it
  55951. * doesn't refer to a pointer type.
  55952. */
  55953. [[nodiscard]] meta_type remove_pointer() const noexcept {
  55954. return meta_type{*ctx, fetch_node().remove_pointer(internal::meta_context::from(*ctx))};
  55955. }
  55956. /**
  55957. * @brief Checks whether a type is a pointer-like type or not.
  55958. * @return True if the underlying type is pointer-like, false otherwise.
  55959. */
  55960. [[nodiscard]] bool is_pointer_like() const noexcept {
  55961. return !!(fetch_node().traits & internal::meta_traits::is_pointer_like);
  55962. }
  55963. /**
  55964. * @brief Checks whether a type refers to a sequence container or not.
  55965. * @return True if the type is a sequence container, false otherwise.
  55966. */
  55967. [[nodiscard]] bool is_sequence_container() const noexcept {
  55968. return !!(fetch_node().traits & internal::meta_traits::is_sequence_container);
  55969. }
  55970. /**
  55971. * @brief Checks whether a type refers to an associative container or not.
  55972. * @return True if the type is an associative container, false otherwise.
  55973. */
  55974. [[nodiscard]] bool is_associative_container() const noexcept {
  55975. return !!(fetch_node().traits & internal::meta_traits::is_associative_container);
  55976. }
  55977. /**
  55978. * @brief Checks whether a type refers to a template specialization or not.
  55979. * @return True if the type is a template specialization, false otherwise.
  55980. */
  55981. [[nodiscard]] bool is_template_specialization() const noexcept {
  55982. return (fetch_node().templ.arity != 0u);
  55983. }
  55984. /**
  55985. * @brief Returns the number of template arguments.
  55986. * @return The number of template arguments.
  55987. */
  55988. [[nodiscard]] size_type template_arity() const noexcept {
  55989. return fetch_node().templ.arity;
  55990. }
  55991. /**
  55992. * @brief Returns a tag for the class template of the underlying type.
  55993. * @return The tag for the class template of the underlying type.
  55994. */
  55995. [[nodiscard]] meta_type template_type() const noexcept {
  55996. return (fetch_node().templ.resolve != nullptr) ? meta_type{*ctx, fetch_node().templ.resolve(internal::meta_context::from(*ctx))} : meta_type{};
  55997. }
  55998. /**
  55999. * @brief Returns the type of the i-th template argument of a type.
  56000. * @param index Index of the template argument of which to return the type.
  56001. * @return The type of the i-th template argument of a type.
  56002. */
  56003. [[nodiscard]] meta_type template_arg(const size_type index) const noexcept {
  56004. return index < template_arity() ? meta_type{*ctx, fetch_node().templ.arg(internal::meta_context::from(*ctx), index)} : meta_type{};
  56005. }
  56006. /**
  56007. * @brief Checks if a type supports direct casting to another type.
  56008. * @param other The meta type to test for.
  56009. * @return True if direct casting is allowed, false otherwise.
  56010. */
  56011. [[nodiscard]] bool can_cast(const meta_type &other) const noexcept {
  56012. // casting this is UB in all cases but we aren't going to use the resulting pointer, so...
  56013. return other && ((*this == other) || (internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), other.fetch_node().info->hash(), this) != nullptr));
  56014. }
  56015. /**
  56016. * @brief Checks whether a type supports conversion to another type.
  56017. * @param other The meta type to test for.
  56018. * @return True if the conversion is allowed, false otherwise.
  56019. */
  56020. [[nodiscard]] bool can_convert(const meta_type &other) const noexcept {
  56021. if(const auto &to = other.info().hash(); (info().hash() == to) || ((fetch_node().conversion_helper != nullptr) && (other.is_arithmetic() || other.is_enum()))) {
  56022. return true;
  56023. } else if(const auto &from = fetch_node(); from.details) {
  56024. if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, to); elem != nullptr) {
  56025. return true;
  56026. }
  56027. for(auto &&curr: from.details->base) {
  56028. if(curr.type == to || meta_type{*ctx, curr.resolve(internal::meta_context::from(*ctx))}.can_convert(other)) {
  56029. return true;
  56030. }
  56031. }
  56032. }
  56033. return false;
  56034. }
  56035. /**
  56036. * @brief Returns a range to visit registered top-level base meta types.
  56037. * @return An iterable range to visit registered top-level base meta types.
  56038. */
  56039. [[nodiscard]] meta_range<meta_type, typename decltype(internal::meta_type_descriptor::base)::const_iterator> base() const noexcept {
  56040. using range_type = meta_range<meta_type, typename decltype(internal::meta_type_descriptor::base)::const_iterator>;
  56041. return fetch_node().details ? range_type{{*ctx, fetch_node().details->base.cbegin()}, {*ctx, fetch_node().details->base.cend()}} : range_type{};
  56042. }
  56043. /**
  56044. * @brief Returns a range to visit registered top-level meta data.
  56045. * @return An iterable range to visit registered top-level meta data.
  56046. */
  56047. [[nodiscard]] meta_range<meta_data, typename decltype(internal::meta_type_descriptor::data)::const_iterator> data() const noexcept {
  56048. using range_type = meta_range<meta_data, typename decltype(internal::meta_type_descriptor::data)::const_iterator>;
  56049. return fetch_node().details ? range_type{{*ctx, fetch_node().details->data.cbegin()}, {*ctx, fetch_node().details->data.cend()}} : range_type{};
  56050. }
  56051. /**
  56052. * @brief Lookup utility for meta data (bases are also visited).
  56053. * @param id Unique identifier.
  56054. * @param recursive True for a search in the base classes, false otherwise.
  56055. * @return The registered meta data for the given identifier, if any.
  56056. */
  56057. [[nodiscard]] meta_data data(const id_type id, const bool recursive = true) const {
  56058. const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
  56059. return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{};
  56060. }
  56061. /**
  56062. * @brief Returns a range to visit registered top-level functions.
  56063. * @return An iterable range to visit registered top-level functions.
  56064. */
  56065. [[nodiscard]] meta_range<meta_func, typename decltype(internal::meta_type_descriptor::func)::const_iterator> func() const noexcept {
  56066. using return_type = meta_range<meta_func, typename decltype(internal::meta_type_descriptor::func)::const_iterator>;
  56067. return fetch_node().details ? return_type{{*ctx, fetch_node().details->func.cbegin()}, {*ctx, fetch_node().details->func.cend()}} : return_type{};
  56068. }
  56069. /**
  56070. * @brief Lookup utility for meta functions (bases are also visited).
  56071. * @param id Unique identifier.
  56072. * @param recursive True for a search in the base classes, false otherwise.
  56073. * @return The registered meta function for the given identifier, if any.
  56074. */
  56075. [[nodiscard]] meta_func func(const id_type id, const bool recursive = true) const {
  56076. const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
  56077. return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{};
  56078. }
  56079. /**
  56080. * @brief Creates an instance of the underlying type, if possible.
  56081. * @param args Parameters to use to construct the instance.
  56082. * @param sz Number of parameters to use to construct the instance.
  56083. * @return A wrapper containing the new instance, if any.
  56084. */
  56085. [[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const {
  56086. if(const auto &ref = fetch_node(); ref.details) {
  56087. if(const auto *candidate = lookup(args, sz, false, [first = ref.details->ctor.cbegin(), last = ref.details->ctor.cend()]() mutable { return first == last ? nullptr : &*(first++); }); candidate) {
  56088. return candidate->invoke(*ctx, args);
  56089. }
  56090. }
  56091. if(const auto &ref = fetch_node(); (sz == 0u) && (ref.default_constructor != nullptr)) {
  56092. return ref.default_constructor(*ctx);
  56093. }
  56094. return meta_any{meta_ctx_arg, *ctx};
  56095. }
  56096. /**
  56097. * @copybrief construct
  56098. * @tparam Args Types of arguments to use to construct the instance.
  56099. * @param args Parameters to use to construct the instance.
  56100. * @return A wrapper containing the new instance, if any.
  56101. */
  56102. template<typename... Args>
  56103. [[nodiscard]] meta_any construct(Args &&...args) const {
  56104. return construct(std::array<meta_any, sizeof...(Args)>{meta_any{*ctx, std::forward<Args>(args)}...}.data(), sizeof...(Args));
  56105. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  56106. }
  56107. /**
  56108. * @brief Wraps an opaque element of the underlying type.
  56109. * @param elem A valid pointer to an element of the underlying type.
  56110. * @param transfer_ownership True to transfer ownership, false otherwise.
  56111. * @return A wrapper that references the given instance.
  56112. */
  56113. [[nodiscard]] meta_any from_void(void *elem, bool transfer_ownership = false) const {
  56114. return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, elem, transfer_ownership ? elem : nullptr) : meta_any{meta_ctx_arg, *ctx};
  56115. }
  56116. /**
  56117. * @brief Wraps an opaque element of the underlying type.
  56118. * @param elem A valid pointer to an element of the underlying type.
  56119. * @return A wrapper that references the given instance.
  56120. */
  56121. [[nodiscard]] meta_any from_void(const void *elem) const {
  56122. return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, nullptr, elem) : meta_any{meta_ctx_arg, *ctx};
  56123. }
  56124. /**
  56125. * @brief Invokes a function given an identifier, if possible.
  56126. * @tparam Instance Type of instance to operate on.
  56127. * @param id Unique identifier.
  56128. * @param instance An instance that fits the underlying type.
  56129. * @param args Parameters to use to invoke the function.
  56130. * @param sz Number of parameters to use to invoke the function.
  56131. * @return A wrapper containing the returned value, if any.
  56132. */
  56133. template<typename Instance = meta_handle>
  56134. // NOLINTNEXTLINE(modernize-use-nodiscard)
  56135. meta_any invoke(const id_type id, Instance &&instance, meta_any *const args, const size_type sz) const {
  56136. meta_handle wrapped{*ctx, std::forward<Instance>(instance)};
  56137. if(const auto &ref = fetch_node(); ref.details) {
  56138. if(auto *elem = internal::find_member<&internal::meta_func_node::id>(ref.details->func, id); elem != nullptr) {
  56139. if(const auto *candidate = lookup(args, sz, (wrapped->base().policy() == any_policy::cref), [curr = elem]() mutable { return (curr != nullptr) ? std::exchange(curr, curr->next.get()) : nullptr; }); candidate) {
  56140. return candidate->invoke(std::move(wrapped), args);
  56141. }
  56142. }
  56143. }
  56144. for(auto &&curr: base()) {
  56145. if(auto elem = curr.second.invoke(id, *wrapped.operator->(), args, sz); elem) {
  56146. return elem;
  56147. }
  56148. }
  56149. return meta_any{meta_ctx_arg, *ctx};
  56150. }
  56151. /**
  56152. * @copybrief invoke
  56153. * @param id Unique identifier.
  56154. * @tparam Instance Type of instance to operate on.
  56155. * @tparam Args Types of arguments to use to invoke the function.
  56156. * @param instance An instance that fits the underlying type.
  56157. * @param args Parameters to use to invoke the function.
  56158. * @return A wrapper containing the returned value, if any.
  56159. */
  56160. template<typename Instance = meta_handle, typename... Args>
  56161. // NOLINTNEXTLINE(modernize-use-nodiscard)
  56162. meta_any invoke(const id_type id, Instance &&instance, Args &&...args) const {
  56163. return invoke(id, std::forward<Instance>(instance), std::array<meta_any, sizeof...(Args)>{meta_any{*ctx, std::forward<Args>(args)}...}.data(), sizeof...(Args));
  56164. }
  56165. /**
  56166. * @brief Sets the value of a given variable.
  56167. * @tparam Instance Type of instance to operate on.
  56168. * @tparam Type Type of value to assign.
  56169. * @param id Unique identifier.
  56170. * @param instance An instance that fits the underlying type.
  56171. * @param value Parameter to use to set the underlying variable.
  56172. * @return True in case of success, false otherwise.
  56173. */
  56174. template<typename Instance = meta_handle, typename Type>
  56175. // NOLINTNEXTLINE(modernize-use-nodiscard)
  56176. bool set(const id_type id, Instance &&instance, Type &&value) const {
  56177. const auto candidate = data(id);
  56178. return candidate && candidate.set(std::forward<Instance>(instance), std::forward<Type>(value));
  56179. }
  56180. /**
  56181. * @brief Gets the value of a given variable.
  56182. * @tparam Instance Type of instance to operate on.
  56183. * @param id Unique identifier.
  56184. * @param instance An instance that fits the underlying type.
  56185. * @return A wrapper containing the value of the underlying variable.
  56186. */
  56187. template<typename Instance = meta_handle>
  56188. [[nodiscard]] meta_any get(const id_type id, Instance &&instance) const {
  56189. const auto candidate = data(id);
  56190. return candidate ? candidate.get(std::forward<Instance>(instance)) : meta_any{meta_ctx_arg, *ctx};
  56191. }
  56192. /*! @copydoc meta_data::traits */
  56193. template<typename Type>
  56194. [[nodiscard]] Type traits() const noexcept {
  56195. return internal::meta_to_user_traits<Type>(fetch_node().traits);
  56196. }
  56197. /*! @copydoc meta_data::custom */
  56198. [[nodiscard]] meta_custom custom() const noexcept {
  56199. return fetch_node().custom;
  56200. }
  56201. /*! @copydoc meta_data::operator bool */
  56202. [[nodiscard]] explicit operator bool() const noexcept {
  56203. return (node != nullptr);
  56204. }
  56205. /*! @copydoc meta_data::operator== */
  56206. [[nodiscard]] bool operator==(const meta_type &other) const noexcept {
  56207. return (ctx == other.ctx) && (fetch_node().id == other.fetch_node().id);
  56208. }
  56209. private:
  56210. mutable const internal::meta_type_node *node{};
  56211. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  56212. };
  56213. /*! @copydoc operator!=(const meta_data &, const meta_data &) */
  56214. [[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) noexcept {
  56215. return !(lhs == rhs);
  56216. }
  56217. [[nodiscard]] inline meta_type meta_any::type() const noexcept {
  56218. return *this ? meta_type{*ctx, fetch_node()} : meta_type{};
  56219. }
  56220. template<typename... Args>
  56221. // NOLINTNEXTLINE(modernize-use-nodiscard)
  56222. meta_any meta_any::invoke(const id_type id, Args &&...args) const {
  56223. return type().invoke(id, *this, std::forward<Args>(args)...);
  56224. }
  56225. template<typename... Args>
  56226. meta_any meta_any::invoke(const id_type id, Args &&...args) {
  56227. return type().invoke(id, *this, std::forward<Args>(args)...);
  56228. }
  56229. template<typename Type>
  56230. bool meta_any::set(const id_type id, Type &&value) {
  56231. return type().set(id, *this, std::forward<Type>(value));
  56232. }
  56233. [[nodiscard]] inline meta_any meta_any::get(const id_type id) const {
  56234. return type().get(id, *this);
  56235. }
  56236. [[nodiscard]] inline meta_any meta_any::get(const id_type id) {
  56237. return type().get(id, *this);
  56238. }
  56239. [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
  56240. if(storage.has_value(type.info())) {
  56241. return as_ref();
  56242. } else if(*this) {
  56243. if(const auto &from = fetch_node(); (from.conversion_helper != nullptr) && (type.is_arithmetic() || type.is_enum())) {
  56244. auto other = type.construct();
  56245. const auto value = from.conversion_helper(nullptr, storage.data());
  56246. other.fetch_node().conversion_helper(other.storage.data(), &value);
  56247. return other;
  56248. }
  56249. if(const auto &from = fetch_node(); from.details) {
  56250. if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, type.info().hash()); elem != nullptr) {
  56251. return elem->conv(*ctx, storage.data());
  56252. }
  56253. for(auto &&curr: from.details->base) {
  56254. if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == type.info().hash()) {
  56255. return other;
  56256. } else if(auto from_base = std::as_const(other).allow_cast(type); from_base) {
  56257. return from_base;
  56258. }
  56259. }
  56260. }
  56261. }
  56262. return meta_any{meta_ctx_arg, *ctx};
  56263. }
  56264. [[nodiscard]] inline bool meta_any::allow_cast(const meta_type &type) {
  56265. if(storage.has_value(type.info())) {
  56266. return true;
  56267. } else if(auto other = std::as_const(*this).allow_cast(type); other) {
  56268. if(other.storage.owner()) {
  56269. std::swap(*this, other);
  56270. }
  56271. return true;
  56272. }
  56273. return false;
  56274. }
  56275. inline bool meta_any::assign(const meta_any &other) {
  56276. if(!storage.assign(other.storage)) {
  56277. auto value = other.allow_cast(type());
  56278. return storage.assign(value.storage);
  56279. }
  56280. return true;
  56281. }
  56282. inline bool meta_any::assign(meta_any &&other) {
  56283. return storage.assign(std::move(other.storage)) || storage.assign(std::as_const(other).allow_cast(type()).storage);
  56284. }
  56285. [[nodiscard]] inline meta_type meta_data::type() const noexcept {
  56286. return meta_type{*ctx, node_or_assert().type(internal::meta_context::from(*ctx))};
  56287. }
  56288. [[nodiscard]] inline meta_type meta_data::arg(const size_type index) const noexcept {
  56289. return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{};
  56290. }
  56291. [[nodiscard]] inline meta_type meta_func::ret() const noexcept {
  56292. return meta_type{*ctx, node_or_assert().ret(internal::meta_context::from(*ctx))};
  56293. }
  56294. [[nodiscard]] inline meta_type meta_func::arg(const size_type index) const noexcept {
  56295. return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{};
  56296. }
  56297. /*! @cond TURN_OFF_DOXYGEN */
  56298. class meta_sequence_container::meta_iterator final {
  56299. using vtable_type = void(const void *, const std::ptrdiff_t, meta_any *);
  56300. template<typename It>
  56301. static void basic_vtable(const void *value, const std::ptrdiff_t offset, meta_any *other) {
  56302. const auto &it = *static_cast<const It *>(value);
  56303. other ? other->emplace<decltype(*it)>(*it) : std::advance(const_cast<It &>(it), offset);
  56304. }
  56305. public:
  56306. using value_type = meta_any;
  56307. using pointer = input_iterator_pointer<value_type>;
  56308. using reference = value_type;
  56309. using difference_type = std::ptrdiff_t;
  56310. using iterator_category = std::input_iterator_tag;
  56311. using iterator_concept = std::bidirectional_iterator_tag;
  56312. meta_iterator() = default;
  56313. template<typename It>
  56314. meta_iterator(const meta_ctx &area, It iter) noexcept
  56315. : ctx{&area},
  56316. vtable{&basic_vtable<It>},
  56317. handle{iter} {}
  56318. meta_iterator &operator++() noexcept {
  56319. return vtable(handle.data(), 1, nullptr), *this;
  56320. }
  56321. meta_iterator operator++(int value) noexcept {
  56322. meta_iterator orig = *this;
  56323. vtable(handle.data(), ++value, nullptr);
  56324. return orig;
  56325. }
  56326. meta_iterator &operator--() noexcept {
  56327. return vtable(handle.data(), -1, nullptr), *this;
  56328. }
  56329. meta_iterator operator--(int value) noexcept {
  56330. meta_iterator orig = *this;
  56331. vtable(handle.data(), --value, nullptr);
  56332. return orig;
  56333. }
  56334. [[nodiscard]] reference operator*() const {
  56335. reference other{meta_ctx_arg, *ctx};
  56336. vtable(handle.data(), 0, &other);
  56337. return other;
  56338. }
  56339. [[nodiscard]] pointer operator->() const {
  56340. return operator*();
  56341. }
  56342. [[nodiscard]] explicit operator bool() const noexcept {
  56343. return (vtable != nullptr);
  56344. }
  56345. [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept {
  56346. return handle == other.handle;
  56347. }
  56348. [[nodiscard]] const any &base() const noexcept {
  56349. return handle;
  56350. }
  56351. private:
  56352. const meta_ctx *ctx{};
  56353. vtable_type *vtable{};
  56354. any handle{};
  56355. };
  56356. [[nodiscard]] inline bool operator!=(const meta_sequence_container::iterator &lhs, const meta_sequence_container::iterator &rhs) noexcept {
  56357. return !(lhs == rhs);
  56358. }
  56359. class meta_associative_container::meta_iterator final {
  56360. using vtable_type = void(const void *, std::pair<meta_any, meta_any> *);
  56361. template<bool KeyOnly, typename It>
  56362. static void basic_vtable(const void *value, std::pair<meta_any, meta_any> *other) {
  56363. if(const auto &it = *static_cast<const It *>(value); other) {
  56364. if constexpr(KeyOnly) {
  56365. other->first.emplace<decltype(*it)>(*it);
  56366. } else {
  56367. other->first.emplace<decltype((it->first))>(it->first);
  56368. other->second.emplace<decltype((it->second))>(it->second);
  56369. }
  56370. } else {
  56371. ++const_cast<It &>(it);
  56372. }
  56373. }
  56374. public:
  56375. using value_type = std::pair<meta_any, meta_any>;
  56376. using pointer = input_iterator_pointer<value_type>;
  56377. using reference = value_type;
  56378. using difference_type = std::ptrdiff_t;
  56379. using iterator_category = std::input_iterator_tag;
  56380. using iterator_concept = std::forward_iterator_tag;
  56381. meta_iterator() = default;
  56382. template<bool KeyOnly, typename It>
  56383. meta_iterator(const meta_ctx &area, std::bool_constant<KeyOnly>, It iter) noexcept
  56384. : ctx{&area},
  56385. vtable{&basic_vtable<KeyOnly, It>},
  56386. handle{iter} {}
  56387. meta_iterator &operator++() noexcept {
  56388. return vtable(handle.data(), nullptr), *this;
  56389. }
  56390. meta_iterator operator++(int) noexcept {
  56391. meta_iterator orig = *this;
  56392. vtable(handle.data(), nullptr);
  56393. return orig;
  56394. }
  56395. [[nodiscard]] reference operator*() const {
  56396. reference other{{meta_ctx_arg, *ctx}, {meta_ctx_arg, *ctx}};
  56397. vtable(handle.data(), &other);
  56398. return other;
  56399. }
  56400. [[nodiscard]] pointer operator->() const {
  56401. return operator*();
  56402. }
  56403. [[nodiscard]] explicit operator bool() const noexcept {
  56404. return (vtable != nullptr);
  56405. }
  56406. [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept {
  56407. return handle == other.handle;
  56408. }
  56409. private:
  56410. const meta_ctx *ctx{};
  56411. vtable_type *vtable{};
  56412. any handle{};
  56413. };
  56414. [[nodiscard]] inline bool operator!=(const meta_associative_container::iterator &lhs, const meta_associative_container::iterator &rhs) noexcept {
  56415. return !(lhs == rhs);
  56416. }
  56417. /*! @endcond */
  56418. /**
  56419. * @brief Returns the meta value type of a container.
  56420. * @return The meta value type of the container.
  56421. */
  56422. [[nodiscard]] inline meta_type meta_sequence_container::value_type() const noexcept {
  56423. return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  56424. }
  56425. /**
  56426. * @brief Returns the size of a container.
  56427. * @return The size of the container.
  56428. */
  56429. [[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const noexcept {
  56430. return size_fn(data);
  56431. }
  56432. /**
  56433. * @brief Resizes a container to contain a given number of elements.
  56434. * @param sz The new size of the container.
  56435. * @return True in case of success, false otherwise.
  56436. */
  56437. inline bool meta_sequence_container::resize(const size_type sz) {
  56438. return !const_only && resize_fn(const_cast<void *>(data), sz);
  56439. }
  56440. /**
  56441. * @brief Clears the content of a container.
  56442. * @return True in case of success, false otherwise.
  56443. */
  56444. inline bool meta_sequence_container::clear() {
  56445. return !const_only && clear_fn(const_cast<void *>(data));
  56446. }
  56447. /**
  56448. * @brief Reserves storage for at least the given number of elements.
  56449. * @param sz The new capacity of the container.
  56450. * @return True in case of success, false otherwise.
  56451. */
  56452. inline bool meta_sequence_container::reserve(const size_type sz) {
  56453. return !const_only && reserve_fn(const_cast<void *>(data), sz);
  56454. }
  56455. /**
  56456. * @brief Returns an iterator to the first element of a container.
  56457. * @return An iterator to the first element of the container.
  56458. */
  56459. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
  56460. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, false);
  56461. }
  56462. /**
  56463. * @brief Returns an iterator that is past the last element of a container.
  56464. * @return An iterator that is past the last element of the container.
  56465. */
  56466. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
  56467. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, true);
  56468. }
  56469. /**
  56470. * @brief Inserts an element at a specified location of a container.
  56471. * @param it Iterator before which the element will be inserted.
  56472. * @param value Element value to insert.
  56473. * @return A possibly invalid iterator to the inserted element.
  56474. */
  56475. inline meta_sequence_container::iterator meta_sequence_container::insert(const iterator &it, meta_any value) {
  56476. // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
  56477. if(const auto &vtype = value_type_node(internal::meta_context::from(*ctx)); !const_only && (value.allow_cast({*ctx, vtype}) || value.allow_cast({*ctx, const_reference_node(internal::meta_context::from(*ctx))}))) {
  56478. const bool is_value_type = (value.type().info() == *vtype.info);
  56479. return insert_fn(*ctx, const_cast<void *>(data), is_value_type ? value.base().data() : nullptr, is_value_type ? nullptr : value.base().data(), it);
  56480. }
  56481. return iterator{};
  56482. }
  56483. /**
  56484. * @brief Removes a given element from a container.
  56485. * @param it Iterator to the element to remove.
  56486. * @return A possibly invalid iterator following the last removed element.
  56487. */
  56488. inline meta_sequence_container::iterator meta_sequence_container::erase(const iterator &it) {
  56489. return const_only ? iterator{} : erase_fn(*ctx, const_cast<void *>(data), it);
  56490. }
  56491. /**
  56492. * @brief Returns a reference to the element at a given location of a container.
  56493. * @param pos The position of the element to return.
  56494. * @return A reference to the requested element properly wrapped.
  56495. */
  56496. [[nodiscard]] inline meta_any meta_sequence_container::operator[](const size_type pos) {
  56497. auto it = begin();
  56498. it.operator++(static_cast<int>(pos) - 1);
  56499. return *it;
  56500. }
  56501. /**
  56502. * @brief Returns false if a proxy is invalid, true otherwise.
  56503. * @return False if the proxy is invalid, true otherwise.
  56504. */
  56505. [[nodiscard]] inline meta_sequence_container::operator bool() const noexcept {
  56506. return (data != nullptr);
  56507. }
  56508. /**
  56509. * @brief Returns the meta key type of a container.
  56510. * @return The meta key type of the a container.
  56511. */
  56512. [[nodiscard]] inline meta_type meta_associative_container::key_type() const noexcept {
  56513. return (key_type_node != nullptr) ? meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  56514. }
  56515. /**
  56516. * @brief Returns the meta mapped type of a container.
  56517. * @return The meta mapped type of the a container.
  56518. */
  56519. [[nodiscard]] inline meta_type meta_associative_container::mapped_type() const noexcept {
  56520. return (mapped_type_node != nullptr) ? meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  56521. }
  56522. /*! @copydoc meta_sequence_container::value_type */
  56523. [[nodiscard]] inline meta_type meta_associative_container::value_type() const noexcept {
  56524. return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  56525. }
  56526. /*! @copydoc meta_sequence_container::size */
  56527. [[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const noexcept {
  56528. return size_fn(data);
  56529. }
  56530. /*! @copydoc meta_sequence_container::clear */
  56531. inline bool meta_associative_container::clear() {
  56532. return !const_only && clear_fn(const_cast<void *>(data));
  56533. }
  56534. /*! @copydoc meta_sequence_container::reserve */
  56535. inline bool meta_associative_container::reserve(const size_type sz) {
  56536. return !const_only && reserve_fn(const_cast<void *>(data), sz);
  56537. }
  56538. /*! @copydoc meta_sequence_container::begin */
  56539. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
  56540. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, false);
  56541. }
  56542. /*! @copydoc meta_sequence_container::end */
  56543. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
  56544. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, true);
  56545. }
  56546. /**
  56547. * @brief Inserts a key-only or key/value element into a container.
  56548. * @param key The key of the element to insert.
  56549. * @param value The value of the element to insert, if needed.
  56550. * @return A bool denoting whether the insertion took place.
  56551. */
  56552. inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
  56553. return !const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})
  56554. && ((mapped_type_node == nullptr) || value.allow_cast(meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))}))
  56555. && insert_fn(const_cast<void *>(data), key.base().data(), value.base().data());
  56556. }
  56557. /**
  56558. * @brief Removes the specified element from a container.
  56559. * @param key The key of the element to remove.
  56560. * @return A bool denoting whether the removal took place.
  56561. */
  56562. inline meta_associative_container::size_type meta_associative_container::erase(meta_any key) {
  56563. return (!const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})) ? erase_fn(const_cast<void *>(data), key.base().data()) : 0u;
  56564. }
  56565. /**
  56566. * @brief Returns an iterator to the element with a given key, if any.
  56567. * @param key The key of the element to search.
  56568. * @return An iterator to the element with the given key, if any.
  56569. */
  56570. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
  56571. return key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) ? find_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, key.base().data()) : iterator{};
  56572. }
  56573. /**
  56574. * @brief Returns false if a proxy is invalid, true otherwise.
  56575. * @return False if the proxy is invalid, true otherwise.
  56576. */
  56577. [[nodiscard]] inline meta_associative_container::operator bool() const noexcept {
  56578. return (data != nullptr);
  56579. }
  56580. } // namespace entt
  56581. #endif
  56582. // #include "type_traits.hpp"
  56583. namespace entt {
  56584. /*! @cond TURN_OFF_DOXYGEN */
  56585. namespace internal {
  56586. template<typename Type, typename = void>
  56587. struct sequence_container_extent: integral_constant<meta_dynamic_extent> {};
  56588. template<typename Type>
  56589. struct sequence_container_extent<Type, std::enable_if_t<is_complete_v<std::tuple_size<Type>>>>: integral_constant<std::tuple_size_v<Type>> {};
  56590. template<typename Type>
  56591. inline constexpr std::size_t sequence_container_extent_v = sequence_container_extent<Type>::value;
  56592. template<typename, typename = void>
  56593. struct key_only_associative_container: std::true_type {};
  56594. template<typename Type>
  56595. struct key_only_associative_container<Type, std::void_t<typename Type::mapped_type>>: std::false_type {};
  56596. template<typename Type>
  56597. inline constexpr bool key_only_associative_container_v = key_only_associative_container<Type>::value;
  56598. template<typename, typename = void>
  56599. struct reserve_aware_container: std::false_type {};
  56600. template<typename Type>
  56601. struct reserve_aware_container<Type, std::void_t<decltype(&Type::reserve)>>: std::true_type {};
  56602. template<typename Type>
  56603. inline constexpr bool reserve_aware_container_v = reserve_aware_container<Type>::value;
  56604. } // namespace internal
  56605. /*! @endcond */
  56606. /**
  56607. * @brief General purpose implementation of meta sequence container traits.
  56608. * @tparam Type Type of underlying sequence container.
  56609. */
  56610. template<typename Type>
  56611. struct basic_meta_sequence_container_traits {
  56612. static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Unexpected type");
  56613. /*! @brief Unsigned integer type. */
  56614. using size_type = typename meta_sequence_container::size_type;
  56615. /*! @brief Meta iterator type. */
  56616. using iterator = typename meta_sequence_container::iterator;
  56617. /*! @brief Number of elements, or `meta_dynamic_extent` if dynamic. */
  56618. static constexpr std::size_t extent = internal::sequence_container_extent_v<Type>;
  56619. /*! @brief True in case of fixed size containers, false otherwise. */
  56620. [[deprecated("use ::extent instead")]] static constexpr bool fixed_size = (extent != meta_dynamic_extent);
  56621. /**
  56622. * @brief Returns the number of elements in a container.
  56623. * @param container Opaque pointer to a container of the given type.
  56624. * @return Number of elements.
  56625. */
  56626. [[nodiscard]] static size_type size(const void *container) {
  56627. return static_cast<const Type *>(container)->size();
  56628. }
  56629. /**
  56630. * @brief Clears a container.
  56631. * @param container Opaque pointer to a container of the given type.
  56632. * @return True in case of success, false otherwise.
  56633. */
  56634. [[nodiscard]] static bool clear([[maybe_unused]] void *container) {
  56635. if constexpr(extent == meta_dynamic_extent) {
  56636. static_cast<Type *>(container)->clear();
  56637. return true;
  56638. } else {
  56639. return false;
  56640. }
  56641. }
  56642. /**
  56643. * @brief Increases the capacity of a container.
  56644. * @param container Opaque pointer to a container of the given type.
  56645. * @param sz Desired capacity.
  56646. * @return True in case of success, false otherwise.
  56647. */
  56648. [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
  56649. if constexpr(internal::reserve_aware_container_v<Type>) {
  56650. static_cast<Type *>(container)->reserve(sz);
  56651. return true;
  56652. } else {
  56653. return false;
  56654. }
  56655. }
  56656. /**
  56657. * @brief Resizes a container.
  56658. * @param container Opaque pointer to a container of the given type.
  56659. * @param sz The new number of elements.
  56660. * @return True in case of success, false otherwise.
  56661. */
  56662. [[nodiscard]] static bool resize([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
  56663. if constexpr((extent == meta_dynamic_extent) && std::is_default_constructible_v<typename Type::value_type>) {
  56664. static_cast<Type *>(container)->resize(sz);
  56665. return true;
  56666. } else {
  56667. return false;
  56668. }
  56669. }
  56670. /**
  56671. * @brief Returns a possibly const iterator to the beginning or the end.
  56672. * @param area The context to pass to the newly created iterator.
  56673. * @param container Opaque pointer to a container of the given type.
  56674. * @param as_const Const opaque pointer fallback.
  56675. * @param end False to get a pointer that is past the last element.
  56676. * @return An iterator to the first or past the last element of the
  56677. * container.
  56678. */
  56679. static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) {
  56680. return (container == nullptr)
  56681. ? iterator{area, end ? static_cast<const Type *>(as_const)->cend() : static_cast<const Type *>(as_const)->cbegin()}
  56682. : iterator{area, end ? static_cast<Type *>(container)->end() : static_cast<Type *>(container)->begin()};
  56683. }
  56684. /**
  56685. * @brief Assigns one element to a container and constructs its object from
  56686. * a given opaque instance.
  56687. * @param area The context to pass to the newly created iterator.
  56688. * @param container Opaque pointer to a container of the given type.
  56689. * @param value Optional opaque instance of the object to construct (as
  56690. * value type).
  56691. * @param cref Optional opaque instance of the object to construct (as
  56692. * decayed const reference type).
  56693. * @param it Iterator before which the element will be inserted.
  56694. * @return A possibly invalid iterator to the inserted element.
  56695. */
  56696. [[nodiscard]] static iterator insert([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] const iterator &it) {
  56697. if constexpr(extent == meta_dynamic_extent) {
  56698. auto *const non_const = any_cast<typename Type::iterator>(&it.base());
  56699. return {area, static_cast<Type *>(container)->insert(
  56700. non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
  56701. (value != nullptr) ? *static_cast<const typename Type::value_type *>(value) : *static_cast<const std::remove_reference_t<typename Type::const_reference> *>(cref))};
  56702. } else {
  56703. return iterator{};
  56704. }
  56705. }
  56706. /**
  56707. * @brief Erases an element from a container.
  56708. * @param area The context to pass to the newly created iterator.
  56709. * @param container Opaque pointer to a container of the given type.
  56710. * @param it An opaque iterator to the element to erase.
  56711. * @return A possibly invalid iterator following the last removed element.
  56712. */
  56713. [[nodiscard]] static iterator erase([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) {
  56714. if constexpr(extent == meta_dynamic_extent) {
  56715. auto *const non_const = any_cast<typename Type::iterator>(&it.base());
  56716. return {area, static_cast<Type *>(container)->erase(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()))};
  56717. } else {
  56718. return iterator{};
  56719. }
  56720. }
  56721. };
  56722. /**
  56723. * @brief General purpose implementation of meta associative container traits.
  56724. * @tparam Type Type of underlying associative container.
  56725. */
  56726. template<typename Type>
  56727. struct basic_meta_associative_container_traits {
  56728. static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Unexpected type");
  56729. /*! @brief Unsigned integer type. */
  56730. using size_type = typename meta_associative_container::size_type;
  56731. /*! @brief Meta iterator type. */
  56732. using iterator = typename meta_associative_container::iterator;
  56733. /*! @brief True in case of key-only containers, false otherwise. */
  56734. static constexpr bool key_only = internal::key_only_associative_container_v<Type>;
  56735. /**
  56736. * @brief Returns the number of elements in a container.
  56737. * @param container Opaque pointer to a container of the given type.
  56738. * @return Number of elements.
  56739. */
  56740. [[nodiscard]] static size_type size(const void *container) {
  56741. return static_cast<const Type *>(container)->size();
  56742. }
  56743. /**
  56744. * @brief Clears a container.
  56745. * @param container Opaque pointer to a container of the given type.
  56746. * @return True in case of success, false otherwise.
  56747. */
  56748. [[nodiscard]] static bool clear(void *container) {
  56749. static_cast<Type *>(container)->clear();
  56750. return true;
  56751. }
  56752. /**
  56753. * @brief Increases the capacity of a container.
  56754. * @param container Opaque pointer to a container of the given type.
  56755. * @param sz Desired capacity.
  56756. * @return True in case of success, false otherwise.
  56757. */
  56758. [[nodiscard]] static bool reserve([[maybe_unused]] void *container, [[maybe_unused]] const size_type sz) {
  56759. if constexpr(internal::reserve_aware_container_v<Type>) {
  56760. static_cast<Type *>(container)->reserve(sz);
  56761. return true;
  56762. } else {
  56763. return false;
  56764. }
  56765. }
  56766. /**
  56767. * @brief Returns a possibly const iterator to the beginning or the end.
  56768. * @param area The context to pass to the newly created iterator.
  56769. * @param container Opaque pointer to a container of the given type.
  56770. * @param as_const Const opaque pointer fallback.
  56771. * @param end False to get a pointer that is past the last element.
  56772. * @return An iterator to the first or past the last element of the
  56773. * container.
  56774. */
  56775. static iterator iter(const meta_ctx &area, void *container, const void *as_const, const bool end) {
  56776. return (container == nullptr)
  56777. ? iterator{area, std::bool_constant<key_only>{}, end ? static_cast<const Type *>(as_const)->cend() : static_cast<const Type *>(as_const)->cbegin()}
  56778. : iterator{area, std::bool_constant<key_only>{}, end ? static_cast<Type *>(container)->end() : static_cast<Type *>(container)->begin()};
  56779. }
  56780. /**
  56781. * @brief Inserts an element into a container, if the key does not exist.
  56782. * @param container Opaque pointer to a container of the given type.
  56783. * @param key An opaque key value of an element to insert.
  56784. * @param value Optional opaque value to insert (key-value containers).
  56785. * @return True if the insertion took place, false otherwise.
  56786. */
  56787. [[nodiscard]] static bool insert(void *container, const void *key, [[maybe_unused]] const void *value) {
  56788. if constexpr(key_only) {
  56789. return static_cast<Type *>(container)->insert(*static_cast<const typename Type::key_type *>(key)).second;
  56790. } else {
  56791. return static_cast<Type *>(container)->emplace(*static_cast<const typename Type::key_type *>(key), *static_cast<const typename Type::mapped_type *>(value)).second;
  56792. }
  56793. }
  56794. /**
  56795. * @brief Removes an element from a container.
  56796. * @param container Opaque pointer to a container of the given type.
  56797. * @param key An opaque key value of an element to remove.
  56798. * @return Number of elements removed (either 0 or 1).
  56799. */
  56800. [[nodiscard]] static size_type erase(void *container, const void *key) {
  56801. return static_cast<Type *>(container)->erase(*static_cast<const typename Type::key_type *>(key));
  56802. }
  56803. /**
  56804. * @brief Finds an element with a given key.
  56805. * @param area The context to pass to the newly created iterator.
  56806. * @param container Opaque pointer to a container of the given type.
  56807. * @param as_const Const opaque pointer fallback.
  56808. * @param key Opaque key value of an element to search for.
  56809. * @return An iterator to the element with the given key, if any.
  56810. */
  56811. static iterator find(const meta_ctx &area, void *container, const void *as_const, const void *key) {
  56812. return (container != nullptr) ? iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(container)->find(*static_cast<const typename Type::key_type *>(key))}
  56813. : iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(as_const)->find(*static_cast<const typename Type::key_type *>(key))};
  56814. }
  56815. };
  56816. /**
  56817. * @brief Meta sequence container traits for `std::vector`s of any type.
  56818. * @tparam Args Template arguments for the container.
  56819. */
  56820. template<typename... Args>
  56821. struct meta_sequence_container_traits<std::vector<Args...>>
  56822. : basic_meta_sequence_container_traits<std::vector<Args...>> {};
  56823. /**
  56824. * @brief Meta sequence container traits for `std::array`s of any type.
  56825. * @tparam Type Template arguments for the container.
  56826. * @tparam N Template arguments for the container.
  56827. */
  56828. template<typename Type, auto N>
  56829. struct meta_sequence_container_traits<std::array<Type, N>>
  56830. : basic_meta_sequence_container_traits<std::array<Type, N>> {};
  56831. /**
  56832. * @brief Meta sequence container traits for `std::list`s of any type.
  56833. * @tparam Args Template arguments for the container.
  56834. */
  56835. template<typename... Args>
  56836. struct meta_sequence_container_traits<std::list<Args...>>
  56837. : basic_meta_sequence_container_traits<std::list<Args...>> {};
  56838. /**
  56839. * @brief Meta sequence container traits for `std::deque`s of any type.
  56840. * @tparam Args Template arguments for the container.
  56841. */
  56842. template<typename... Args>
  56843. struct meta_sequence_container_traits<std::deque<Args...>>
  56844. : basic_meta_sequence_container_traits<std::deque<Args...>> {};
  56845. /**
  56846. * @brief Meta associative container traits for `std::map`s of any type.
  56847. * @tparam Args Template arguments for the container.
  56848. */
  56849. template<typename... Args>
  56850. struct meta_associative_container_traits<std::map<Args...>>
  56851. : basic_meta_associative_container_traits<std::map<Args...>> {};
  56852. /**
  56853. * @brief Meta associative container traits for `std::unordered_map`s of any
  56854. * type.
  56855. * @tparam Args Template arguments for the container.
  56856. */
  56857. template<typename... Args>
  56858. struct meta_associative_container_traits<std::unordered_map<Args...>>
  56859. : basic_meta_associative_container_traits<std::unordered_map<Args...>> {};
  56860. /**
  56861. * @brief Meta associative container traits for `std::set`s of any type.
  56862. * @tparam Args Template arguments for the container.
  56863. */
  56864. template<typename... Args>
  56865. struct meta_associative_container_traits<std::set<Args...>>
  56866. : basic_meta_associative_container_traits<std::set<Args...>> {};
  56867. /**
  56868. * @brief Meta associative container traits for `std::unordered_set`s of any
  56869. * type.
  56870. * @tparam Args Template arguments for the container.
  56871. */
  56872. template<typename... Args>
  56873. struct meta_associative_container_traits<std::unordered_set<Args...>>
  56874. : basic_meta_associative_container_traits<std::unordered_set<Args...>> {};
  56875. /**
  56876. * @brief Meta associative container traits for `dense_map`s of any type.
  56877. * @tparam Args Template arguments for the container.
  56878. */
  56879. template<typename... Args>
  56880. struct meta_associative_container_traits<dense_map<Args...>>
  56881. : basic_meta_associative_container_traits<dense_map<Args...>> {};
  56882. /**
  56883. * @brief Meta associative container traits for `dense_set`s of any type.
  56884. * @tparam Args Template arguments for the container.
  56885. */
  56886. template<typename... Args>
  56887. struct meta_associative_container_traits<dense_set<Args...>>
  56888. : basic_meta_associative_container_traits<dense_set<Args...>> {};
  56889. } // namespace entt
  56890. #endif
  56891. // #include "meta/context.hpp"
  56892. #ifndef ENTT_META_CTX_HPP
  56893. #define ENTT_META_CTX_HPP
  56894. #include <memory>
  56895. // #include "../container/dense_map.hpp"
  56896. // #include "../core/fwd.hpp"
  56897. // #include "../core/utility.hpp"
  56898. // #include "fwd.hpp"
  56899. namespace entt {
  56900. /*! @cond TURN_OFF_DOXYGEN */
  56901. namespace internal {
  56902. struct meta_type_node;
  56903. struct meta_context {
  56904. dense_map<id_type, std::unique_ptr<meta_type_node>, identity> value;
  56905. [[nodiscard]] inline static meta_context &from(meta_ctx &);
  56906. [[nodiscard]] inline static const meta_context &from(const meta_ctx &);
  56907. };
  56908. } // namespace internal
  56909. /*! @endcond */
  56910. /*! @brief Disambiguation tag for constructors and the like. */
  56911. class meta_ctx_arg_t final {};
  56912. /*! @brief Constant of type meta_context_arg_t used to disambiguate calls. */
  56913. inline constexpr meta_ctx_arg_t meta_ctx_arg{};
  56914. /*! @brief Opaque meta context type. */
  56915. class meta_ctx: private internal::meta_context {
  56916. // attorney idiom like model to access the base class
  56917. friend struct internal::meta_context;
  56918. };
  56919. /*! @cond TURN_OFF_DOXYGEN */
  56920. [[nodiscard]] inline internal::meta_context &internal::meta_context::from(meta_ctx &ctx) {
  56921. return ctx;
  56922. }
  56923. [[nodiscard]] inline const internal::meta_context &internal::meta_context::from(const meta_ctx &ctx) {
  56924. return ctx;
  56925. }
  56926. /*! @endcond */
  56927. } // namespace entt
  56928. #endif
  56929. // #include "meta/factory.hpp"
  56930. #ifndef ENTT_META_FACTORY_HPP
  56931. #define ENTT_META_FACTORY_HPP
  56932. #include <cstddef>
  56933. #include <cstdint>
  56934. #include <functional>
  56935. #include <memory>
  56936. #include <tuple>
  56937. #include <type_traits>
  56938. #include <utility>
  56939. // #include "../config/config.h"
  56940. // #include "../core/bit.hpp"
  56941. // #include "../core/fwd.hpp"
  56942. // #include "../core/hashed_string.hpp"
  56943. #ifndef ENTT_CORE_HASHED_STRING_HPP
  56944. #define ENTT_CORE_HASHED_STRING_HPP
  56945. #include <cstddef>
  56946. #include <cstdint>
  56947. // #include "fwd.hpp"
  56948. namespace entt {
  56949. /*! @cond TURN_OFF_DOXYGEN */
  56950. namespace internal {
  56951. template<typename = id_type>
  56952. struct fnv_1a_params;
  56953. template<>
  56954. struct fnv_1a_params<std::uint32_t> {
  56955. static constexpr auto offset = 2166136261;
  56956. static constexpr auto prime = 16777619;
  56957. };
  56958. template<>
  56959. struct fnv_1a_params<std::uint64_t> {
  56960. static constexpr auto offset = 14695981039346656037ull;
  56961. static constexpr auto prime = 1099511628211ull;
  56962. };
  56963. template<typename Char>
  56964. struct basic_hashed_string {
  56965. using value_type = Char;
  56966. using size_type = std::size_t;
  56967. using hash_type = id_type;
  56968. const value_type *repr{};
  56969. hash_type hash{fnv_1a_params<>::offset};
  56970. size_type length{};
  56971. };
  56972. } // namespace internal
  56973. /*! @endcond */
  56974. /**
  56975. * @brief Zero overhead unique identifier.
  56976. *
  56977. * A hashed string is a compile-time tool that allows users to use
  56978. * human-readable identifiers in the codebase while using their numeric
  56979. * counterparts at runtime.<br/>
  56980. * Because of that, a hashed string can also be used in constant expressions if
  56981. * required.
  56982. *
  56983. * @warning
  56984. * This class doesn't take ownership of user-supplied strings nor does it make a
  56985. * copy of them.
  56986. *
  56987. * @tparam Char Character type.
  56988. */
  56989. template<typename Char>
  56990. class basic_hashed_string: internal::basic_hashed_string<Char> {
  56991. using base_type = internal::basic_hashed_string<Char>;
  56992. using params = internal::fnv_1a_params<>;
  56993. struct const_wrapper {
  56994. // non-explicit constructor on purpose
  56995. constexpr const_wrapper(const typename base_type::value_type *str) noexcept
  56996. : repr{str} {}
  56997. const typename base_type::value_type *repr;
  56998. };
  56999. public:
  57000. /*! @brief Character type. */
  57001. using value_type = typename base_type::value_type;
  57002. /*! @brief Unsigned integer type. */
  57003. using size_type = typename base_type::size_type;
  57004. /*! @brief Unsigned integer type. */
  57005. using hash_type = typename base_type::hash_type;
  57006. /**
  57007. * @brief Returns directly the numeric representation of a string view.
  57008. * @param str Human-readable identifier.
  57009. * @param len Length of the string to hash.
  57010. * @return The numeric representation of the string.
  57011. */
  57012. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
  57013. return basic_hashed_string{str, len};
  57014. }
  57015. /**
  57016. * @brief Returns directly the numeric representation of a string.
  57017. * @tparam N Number of characters of the identifier.
  57018. * @param str Human-readable identifier.
  57019. * @return The numeric representation of the string.
  57020. */
  57021. template<std::size_t N>
  57022. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  57023. [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept {
  57024. return basic_hashed_string{str};
  57025. }
  57026. /**
  57027. * @brief Returns directly the numeric representation of a string.
  57028. * @param wrapper Helps achieving the purpose by relying on overloading.
  57029. * @return The numeric representation of the string.
  57030. */
  57031. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
  57032. return basic_hashed_string{wrapper};
  57033. }
  57034. /*! @brief Constructs an empty hashed string. */
  57035. constexpr basic_hashed_string() noexcept
  57036. : basic_hashed_string{nullptr, 0u} {}
  57037. /**
  57038. * @brief Constructs a hashed string from a string view.
  57039. * @param str Human-readable identifier.
  57040. * @param len Length of the string to hash.
  57041. */
  57042. constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
  57043. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  57044. : base_type{str} {
  57045. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  57046. for(; base_type::length < len; ++base_type::length) {
  57047. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  57048. }
  57049. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  57050. }
  57051. /**
  57052. * @brief Constructs a hashed string from an array of const characters.
  57053. * @tparam N Number of characters of the identifier.
  57054. * @param str Human-readable identifier.
  57055. */
  57056. template<std::size_t N>
  57057. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  57058. ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept
  57059. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  57060. : base_type{str} {
  57061. for(; str[base_type::length]; ++base_type::length) {
  57062. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  57063. }
  57064. }
  57065. /**
  57066. * @brief Explicit constructor on purpose to avoid constructing a hashed
  57067. * string directly from a `const value_type *`.
  57068. *
  57069. * @warning
  57070. * The lifetime of the string is not extended nor is it copied.
  57071. *
  57072. * @param wrapper Helps achieving the purpose by relying on overloading.
  57073. */
  57074. explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
  57075. : base_type{wrapper.repr} {
  57076. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  57077. for(; wrapper.repr[base_type::length]; ++base_type::length) {
  57078. base_type::hash = (base_type::hash ^ static_cast<id_type>(wrapper.repr[base_type::length])) * params::prime;
  57079. }
  57080. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  57081. }
  57082. /**
  57083. * @brief Returns the size of a hashed string.
  57084. * @return The size of the hashed string.
  57085. */
  57086. [[nodiscard]] constexpr size_type size() const noexcept {
  57087. return base_type::length;
  57088. }
  57089. /**
  57090. * @brief Returns the human-readable representation of a hashed string.
  57091. * @return The string used to initialize the hashed string.
  57092. */
  57093. [[nodiscard]] constexpr const value_type *data() const noexcept {
  57094. return base_type::repr;
  57095. }
  57096. /**
  57097. * @brief Returns the numeric representation of a hashed string.
  57098. * @return The numeric representation of the hashed string.
  57099. */
  57100. [[nodiscard]] constexpr hash_type value() const noexcept {
  57101. return base_type::hash;
  57102. }
  57103. /*! @copydoc data */
  57104. [[nodiscard]] explicit constexpr operator const value_type *() const noexcept {
  57105. return data();
  57106. }
  57107. /**
  57108. * @brief Returns the numeric representation of a hashed string.
  57109. * @return The numeric representation of the hashed string.
  57110. */
  57111. [[nodiscard]] constexpr operator hash_type() const noexcept {
  57112. return value();
  57113. }
  57114. };
  57115. /**
  57116. * @brief Deduction guide.
  57117. * @tparam Char Character type.
  57118. * @param str Human-readable identifier.
  57119. * @param len Length of the string to hash.
  57120. */
  57121. template<typename Char>
  57122. basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string<Char>;
  57123. /**
  57124. * @brief Deduction guide.
  57125. * @tparam Char Character type.
  57126. * @tparam N Number of characters of the identifier.
  57127. * @param str Human-readable identifier.
  57128. */
  57129. template<typename Char, std::size_t N>
  57130. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  57131. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  57132. /**
  57133. * @brief Compares two hashed strings.
  57134. * @tparam Char Character type.
  57135. * @param lhs A valid hashed string.
  57136. * @param rhs A valid hashed string.
  57137. * @return True if the two hashed strings are identical, false otherwise.
  57138. */
  57139. template<typename Char>
  57140. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  57141. return lhs.value() == rhs.value();
  57142. }
  57143. /**
  57144. * @brief Compares two hashed strings.
  57145. * @tparam Char Character type.
  57146. * @param lhs A valid hashed string.
  57147. * @param rhs A valid hashed string.
  57148. * @return True if the two hashed strings differ, false otherwise.
  57149. */
  57150. template<typename Char>
  57151. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  57152. return !(lhs == rhs);
  57153. }
  57154. /**
  57155. * @brief Compares two hashed strings.
  57156. * @tparam Char Character type.
  57157. * @param lhs A valid hashed string.
  57158. * @param rhs A valid hashed string.
  57159. * @return True if the first element is less than the second, false otherwise.
  57160. */
  57161. template<typename Char>
  57162. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  57163. return lhs.value() < rhs.value();
  57164. }
  57165. /**
  57166. * @brief Compares two hashed strings.
  57167. * @tparam Char Character type.
  57168. * @param lhs A valid hashed string.
  57169. * @param rhs A valid hashed string.
  57170. * @return True if the first element is less than or equal to the second, false
  57171. * otherwise.
  57172. */
  57173. template<typename Char>
  57174. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  57175. return !(rhs < lhs);
  57176. }
  57177. /**
  57178. * @brief Compares two hashed strings.
  57179. * @tparam Char Character type.
  57180. * @param lhs A valid hashed string.
  57181. * @param rhs A valid hashed string.
  57182. * @return True if the first element is greater than the second, false
  57183. * otherwise.
  57184. */
  57185. template<typename Char>
  57186. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  57187. return rhs < lhs;
  57188. }
  57189. /**
  57190. * @brief Compares two hashed strings.
  57191. * @tparam Char Character type.
  57192. * @param lhs A valid hashed string.
  57193. * @param rhs A valid hashed string.
  57194. * @return True if the first element is greater than or equal to the second,
  57195. * false otherwise.
  57196. */
  57197. template<typename Char>
  57198. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  57199. return !(lhs < rhs);
  57200. }
  57201. inline namespace literals {
  57202. /**
  57203. * @brief User defined literal for hashed strings.
  57204. * @param str The literal without its suffix.
  57205. * @return A properly initialized hashed string.
  57206. */
  57207. [[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept {
  57208. return hashed_string{str};
  57209. }
  57210. /**
  57211. * @brief User defined literal for hashed wstrings.
  57212. * @param str The literal without its suffix.
  57213. * @return A properly initialized hashed wstring.
  57214. */
  57215. [[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept {
  57216. return hashed_wstring{str};
  57217. }
  57218. } // namespace literals
  57219. } // namespace entt
  57220. #endif
  57221. // #include "../core/type_info.hpp"
  57222. // #include "../core/type_traits.hpp"
  57223. // #include "../locator/locator.hpp"
  57224. // #include "context.hpp"
  57225. // #include "fwd.hpp"
  57226. // #include "meta.hpp"
  57227. // #include "node.hpp"
  57228. // #include "policy.hpp"
  57229. #ifndef ENTT_META_POLICY_HPP
  57230. #define ENTT_META_POLICY_HPP
  57231. #include <type_traits>
  57232. namespace entt {
  57233. /*! @cond TURN_OFF_DOXYGEN */
  57234. namespace internal {
  57235. struct meta_policy {};
  57236. } // namespace internal
  57237. /*! @endcond */
  57238. /*! @brief Empty class type used to request the _as-is_ policy. */
  57239. struct as_value_t final: private internal::meta_policy {
  57240. /*! @cond TURN_OFF_DOXYGEN */
  57241. template<typename>
  57242. static constexpr bool value = true;
  57243. /*! @endcond */
  57244. };
  57245. /*! @brief Empty class type used to request the _as void_ policy. */
  57246. struct as_void_t final: private internal::meta_policy {
  57247. /*! @cond TURN_OFF_DOXYGEN */
  57248. template<typename>
  57249. static constexpr bool value = true;
  57250. /*! @endcond */
  57251. };
  57252. /*! @brief Empty class type used to request the _as ref_ policy. */
  57253. struct as_ref_t final: private internal::meta_policy {
  57254. /*! @cond TURN_OFF_DOXYGEN */
  57255. template<typename Type>
  57256. static constexpr bool value = std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>;
  57257. /*! @endcond */
  57258. };
  57259. /*! @brief Empty class type used to request the _as cref_ policy. */
  57260. struct as_cref_t final: private internal::meta_policy {
  57261. /*! @cond TURN_OFF_DOXYGEN */
  57262. template<typename Type>
  57263. static constexpr bool value = std::is_reference_v<Type>;
  57264. /*! @endcond */
  57265. };
  57266. /*! @brief Empty class type used to request the _as auto_ policy. */
  57267. struct as_is_t final: private internal::meta_policy {
  57268. /*! @cond TURN_OFF_DOXYGEN */
  57269. template<typename>
  57270. static constexpr bool value = true;
  57271. /*! @endcond */
  57272. };
  57273. /**
  57274. * @brief Provides the member constant `value` to true if a type also is a meta
  57275. * policy, false otherwise.
  57276. * @tparam Type Type to check.
  57277. */
  57278. template<typename Type>
  57279. struct is_meta_policy
  57280. : std::bool_constant<std::is_base_of_v<internal::meta_policy, Type>> {};
  57281. /**
  57282. * @brief Helper variable template.
  57283. * @tparam Type Type to check.
  57284. */
  57285. template<typename Type>
  57286. inline constexpr bool is_meta_policy_v = is_meta_policy<Type>::value;
  57287. } // namespace entt
  57288. #endif
  57289. // #include "range.hpp"
  57290. // #include "resolve.hpp"
  57291. #ifndef ENTT_META_RESOLVE_HPP
  57292. #define ENTT_META_RESOLVE_HPP
  57293. #include <type_traits>
  57294. // #include "../core/type_info.hpp"
  57295. // #include "../locator/locator.hpp"
  57296. // #include "context.hpp"
  57297. // #include "meta.hpp"
  57298. // #include "node.hpp"
  57299. // #include "range.hpp"
  57300. namespace entt {
  57301. /**
  57302. * @brief Returns the meta type associated with a given type.
  57303. * @tparam Type Type to use to search for a meta type.
  57304. * @param ctx The context from which to search for meta types.
  57305. * @return The meta type associated with the given type, if any.
  57306. */
  57307. template<typename Type>
  57308. [[nodiscard]] meta_type resolve(const meta_ctx &ctx) noexcept {
  57309. const auto &context = internal::meta_context::from(ctx);
  57310. return {ctx, internal::resolve<std::remove_const_t<std::remove_reference_t<Type>>>(context)};
  57311. }
  57312. /**
  57313. * @brief Returns the meta type associated with a given type.
  57314. * @tparam Type Type to use to search for a meta type.
  57315. * @return The meta type associated with the given type, if any.
  57316. */
  57317. template<typename Type>
  57318. [[nodiscard]] meta_type resolve() noexcept {
  57319. return resolve<Type>(locator<meta_ctx>::value_or());
  57320. }
  57321. /**
  57322. * @brief Returns a range to use to visit all meta types.
  57323. * @param ctx The context from which to search for meta types.
  57324. * @return An iterable range to use to visit all meta types.
  57325. */
  57326. [[nodiscard]] inline meta_range<meta_type, typename decltype(internal::meta_context::value)::const_iterator> resolve(const meta_ctx &ctx) noexcept {
  57327. const auto &context = internal::meta_context::from(ctx);
  57328. return {{ctx, context.value.cbegin()}, {ctx, context.value.cend()}};
  57329. }
  57330. /**
  57331. * @brief Returns a range to use to visit all meta types.
  57332. * @return An iterable range to use to visit all meta types.
  57333. */
  57334. [[nodiscard]] inline meta_range<meta_type, typename decltype(internal::meta_context::value)::const_iterator> resolve() noexcept {
  57335. return resolve(locator<meta_ctx>::value_or());
  57336. }
  57337. /**
  57338. * @brief Returns the meta type associated with a given identifier, if any.
  57339. * @param ctx The context from which to search for meta types.
  57340. * @param id Unique identifier.
  57341. * @return The meta type associated with the given identifier, if any.
  57342. */
  57343. [[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const id_type id) noexcept {
  57344. for(auto &&curr: resolve(ctx)) {
  57345. if(curr.second.id() == id) {
  57346. return curr.second;
  57347. }
  57348. }
  57349. return meta_type{};
  57350. }
  57351. /**
  57352. * @brief Returns the meta type associated with a given identifier, if any.
  57353. * @param id Unique identifier.
  57354. * @return The meta type associated with the given identifier, if any.
  57355. */
  57356. [[nodiscard]] inline meta_type resolve(const id_type id) noexcept {
  57357. return resolve(locator<meta_ctx>::value_or(), id);
  57358. }
  57359. /**
  57360. * @brief Returns the meta type associated with a given type info object.
  57361. * @param ctx The context from which to search for meta types.
  57362. * @param info The type info object of the requested type.
  57363. * @return The meta type associated with the given type info object, if any.
  57364. */
  57365. [[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const type_info &info) noexcept {
  57366. const auto &context = internal::meta_context::from(ctx);
  57367. const auto *elem = internal::try_resolve(context, info);
  57368. return (elem != nullptr) ? meta_type{ctx, *elem} : meta_type{};
  57369. }
  57370. /**
  57371. * @brief Returns the meta type associated with a given type info object.
  57372. * @param info The type info object of the requested type.
  57373. * @return The meta type associated with the given type info object, if any.
  57374. */
  57375. [[nodiscard]] inline meta_type resolve(const type_info &info) noexcept {
  57376. return resolve(locator<meta_ctx>::value_or(), info);
  57377. }
  57378. } // namespace entt
  57379. #endif
  57380. // #include "utility.hpp"
  57381. #ifndef ENTT_META_UTILITY_HPP
  57382. #define ENTT_META_UTILITY_HPP
  57383. #include <cstddef>
  57384. #include <functional>
  57385. #include <type_traits>
  57386. #include <utility>
  57387. // #include "../core/type_traits.hpp"
  57388. // #include "../locator/locator.hpp"
  57389. // #include "meta.hpp"
  57390. // #include "node.hpp"
  57391. // #include "policy.hpp"
  57392. namespace entt {
  57393. /**
  57394. * @brief Meta function descriptor traits.
  57395. * @tparam Ret Function return type.
  57396. * @tparam Args Function arguments.
  57397. * @tparam Static Function staticness.
  57398. * @tparam Const Function constness.
  57399. */
  57400. template<typename Ret, typename Args, bool Static, bool Const>
  57401. struct meta_function_descriptor_traits {
  57402. /*! @brief Meta function return type. */
  57403. using return_type = Ret;
  57404. /*! @brief Meta function arguments. */
  57405. using args_type = Args;
  57406. /*! @brief True if the meta function is static, false otherwise. */
  57407. static constexpr bool is_static = Static;
  57408. /*! @brief True if the meta function is const, false otherwise. */
  57409. static constexpr bool is_const = Const;
  57410. };
  57411. /*! @brief Primary template isn't defined on purpose. */
  57412. template<typename, typename>
  57413. struct meta_function_descriptor;
  57414. /**
  57415. * @brief Meta function descriptor.
  57416. * @tparam Type Reflected type to which the meta function is associated.
  57417. * @tparam Ret Function return type.
  57418. * @tparam Class Actual owner of the member function.
  57419. * @tparam Args Function arguments.
  57420. */
  57421. template<typename Type, typename Ret, typename Class, typename... Args>
  57422. struct meta_function_descriptor<Type, Ret (Class::*)(Args...) const>
  57423. : meta_function_descriptor_traits<
  57424. Ret,
  57425. std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<const Class &, Args...>>,
  57426. !std::is_base_of_v<Class, Type>,
  57427. true> {};
  57428. /**
  57429. * @brief Meta function descriptor.
  57430. * @tparam Type Reflected type to which the meta function is associated.
  57431. * @tparam Ret Function return type.
  57432. * @tparam Class Actual owner of the member function.
  57433. * @tparam Args Function arguments.
  57434. */
  57435. template<typename Type, typename Ret, typename Class, typename... Args>
  57436. struct meta_function_descriptor<Type, Ret (Class::*)(Args...)>
  57437. : meta_function_descriptor_traits<
  57438. Ret,
  57439. std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<Class &, Args...>>,
  57440. !std::is_base_of_v<Class, Type>,
  57441. false> {};
  57442. /**
  57443. * @brief Meta function descriptor.
  57444. * @tparam Type Reflected type to which the meta data is associated.
  57445. * @tparam Class Actual owner of the data member.
  57446. * @tparam Ret Data member type.
  57447. */
  57448. template<typename Type, typename Ret, typename Class>
  57449. struct meta_function_descriptor<Type, Ret Class::*>
  57450. : meta_function_descriptor_traits<
  57451. Ret &,
  57452. std::conditional_t<std::is_base_of_v<Class, Type>, type_list<>, type_list<Class &>>,
  57453. !std::is_base_of_v<Class, Type>,
  57454. false> {};
  57455. /**
  57456. * @brief Meta function descriptor.
  57457. * @tparam Type Reflected type to which the meta function is associated.
  57458. * @tparam Ret Function return type.
  57459. * @tparam MaybeType First function argument.
  57460. * @tparam Args Other function arguments.
  57461. */
  57462. template<typename Type, typename Ret, typename MaybeType, typename... Args>
  57463. struct meta_function_descriptor<Type, Ret (*)(MaybeType, Args...)>
  57464. : meta_function_descriptor_traits<
  57465. Ret,
  57466. std::conditional_t<
  57467. std::is_same_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>,
  57468. type_list<Args...>,
  57469. type_list<MaybeType, Args...>>,
  57470. !(std::is_same_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>),
  57471. std::is_const_v<std::remove_reference_t<MaybeType>> && (std::is_same_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>)> {};
  57472. /**
  57473. * @brief Meta function descriptor.
  57474. * @tparam Type Reflected type to which the meta function is associated.
  57475. * @tparam Ret Function return type.
  57476. */
  57477. template<typename Type, typename Ret>
  57478. struct meta_function_descriptor<Type, Ret (*)()>
  57479. : meta_function_descriptor_traits<
  57480. Ret,
  57481. type_list<>,
  57482. true,
  57483. false> {};
  57484. /**
  57485. * @brief Meta function helper.
  57486. *
  57487. * Converts a function type to be associated with a reflected type into its meta
  57488. * function descriptor.
  57489. *
  57490. * @tparam Type Reflected type to which the meta function is associated.
  57491. * @tparam Candidate The actual function to associate with the reflected type.
  57492. */
  57493. template<typename Type, typename Candidate>
  57494. class meta_function_helper {
  57495. template<typename Ret, typename... Args, typename Class>
  57496. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...) const> get_rid_of_noexcept(Ret (Class::*)(Args...) const);
  57497. template<typename Ret, typename... Args, typename Class>
  57498. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...)> get_rid_of_noexcept(Ret (Class::*)(Args...));
  57499. template<typename Ret, typename Class, typename = std::enable_if_t<std::is_member_object_pointer_v<Ret Class::*>>>
  57500. static constexpr meta_function_descriptor<Type, Ret Class::*> get_rid_of_noexcept(Ret Class::*);
  57501. template<typename Ret, typename... Args>
  57502. static constexpr meta_function_descriptor<Type, Ret (*)(Args...)> get_rid_of_noexcept(Ret (*)(Args...));
  57503. template<typename Class>
  57504. static constexpr meta_function_descriptor<Class, decltype(&Class::operator())> get_rid_of_noexcept(Class);
  57505. public:
  57506. /*! @brief The meta function descriptor of the given function. */
  57507. using type = decltype(get_rid_of_noexcept(std::declval<Candidate>()));
  57508. };
  57509. /**
  57510. * @brief Helper type.
  57511. * @tparam Type Reflected type to which the meta function is associated.
  57512. * @tparam Candidate The actual function to associate with the reflected type.
  57513. */
  57514. template<typename Type, typename Candidate>
  57515. using meta_function_helper_t = typename meta_function_helper<Type, Candidate>::type;
  57516. /**
  57517. * @brief Wraps a value depending on the given policy.
  57518. *
  57519. * This function always returns a wrapped value in the requested context.<br/>
  57520. * Therefore, if the passed value is itself a wrapped object with a different
  57521. * context, it undergoes a rebinding to the requested context.
  57522. *
  57523. * @tparam Policy Optional policy (no policy set by default).
  57524. * @tparam Type Type of value to wrap.
  57525. * @param ctx The context from which to search for meta types.
  57526. * @param value Value to wrap.
  57527. * @return A meta any containing the returned value, if any.
  57528. */
  57529. template<typename Policy = as_value_t, typename Type>
  57530. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_dispatch(const meta_ctx &ctx, [[maybe_unused]] Type &&value) {
  57531. if constexpr(std::is_same_v<Policy, as_cref_t>) {
  57532. static_assert(std::is_lvalue_reference_v<Type>, "Invalid type");
  57533. return meta_any{ctx, std::in_place_type<const std::remove_reference_t<Type> &>, std::as_const(value)};
  57534. } else if constexpr(std::is_same_v<Policy, as_ref_t> || (std::is_same_v<Policy, as_is_t> && std::is_lvalue_reference_v<Type>)) {
  57535. return meta_any{ctx, std::in_place_type<Type>, value};
  57536. } else if constexpr(std::is_same_v<Policy, as_void_t>) {
  57537. return meta_any{ctx, std::in_place_type<void>};
  57538. } else {
  57539. return meta_any{ctx, std::forward<Type>(value)};
  57540. }
  57541. }
  57542. /**
  57543. * @brief Wraps a value depending on the given policy.
  57544. * @tparam Policy Optional policy (no policy set by default).
  57545. * @tparam Type Type of value to wrap.
  57546. * @param value Value to wrap.
  57547. * @return A meta any containing the returned value, if any.
  57548. */
  57549. template<typename Policy = as_value_t, typename Type>
  57550. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_dispatch(Type &&value) {
  57551. return meta_dispatch<Policy, Type>(locator<meta_ctx>::value_or(), std::forward<Type>(value));
  57552. }
  57553. /*! @cond TURN_OFF_DOXYGEN */
  57554. namespace internal {
  57555. template<typename Policy, typename Candidate, typename... Args>
  57556. [[nodiscard]] meta_any meta_invoke_with_args(const meta_ctx &ctx, Candidate &&candidate, Args &&...args) {
  57557. if constexpr(std::is_void_v<decltype(std::invoke(std::forward<Candidate>(candidate), args...))>) {
  57558. std::invoke(std::forward<Candidate>(candidate), args...);
  57559. return meta_any{ctx, std::in_place_type<void>};
  57560. } else {
  57561. return meta_dispatch<Policy>(ctx, std::invoke(std::forward<Candidate>(candidate), args...));
  57562. }
  57563. }
  57564. template<typename Type, typename Policy, typename Candidate, std::size_t... Index>
  57565. [[nodiscard]] meta_any meta_invoke(meta_any &instance, Candidate &&candidate, [[maybe_unused]] meta_any *const args, std::index_sequence<Index...>) {
  57566. using descriptor = meta_function_helper_t<Type, std::remove_reference_t<Candidate>>;
  57567. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  57568. if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, const Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  57569. if(const auto *const clazz = instance.try_cast<const Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  57570. return meta_invoke_with_args<Policy>(instance.context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  57571. }
  57572. } else if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  57573. if(auto *const clazz = instance.try_cast<Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  57574. return meta_invoke_with_args<Policy>(instance.context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  57575. }
  57576. } else {
  57577. if(((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  57578. return meta_invoke_with_args<Policy>(instance.context(), std::forward<Candidate>(candidate), (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  57579. }
  57580. }
  57581. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  57582. return meta_any{meta_ctx_arg, instance.context()};
  57583. }
  57584. template<typename Type, typename... Args, std::size_t... Index>
  57585. [[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args, std::index_sequence<Index...>) {
  57586. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  57587. if(((args + Index)->allow_cast<Args>() && ...)) {
  57588. return meta_any{ctx, std::in_place_type<Type>, (args + Index)->cast<Args>()...};
  57589. }
  57590. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  57591. return meta_any{meta_ctx_arg, ctx};
  57592. }
  57593. } // namespace internal
  57594. /*! @endcond */
  57595. /**
  57596. * @brief Returns the meta type of the i-th element of a list of arguments.
  57597. * @tparam Type Type list of the actual types of arguments.
  57598. * @param ctx The context from which to search for meta types.
  57599. * @param index The index of the element for which to return the meta type.
  57600. * @return The meta type of the i-th element of the list of arguments.
  57601. */
  57602. template<typename Type>
  57603. [[nodiscard]] meta_type meta_arg(const meta_ctx &ctx, const std::size_t index) noexcept {
  57604. const auto &context = internal::meta_context::from(ctx);
  57605. return {ctx, internal::meta_arg_node(context, Type{}, index)};
  57606. }
  57607. /**
  57608. * @brief Returns the meta type of the i-th element of a list of arguments.
  57609. * @tparam Type Type list of the actual types of arguments.
  57610. * @param index The index of the element for which to return the meta type.
  57611. * @return The meta type of the i-th element of the list of arguments.
  57612. */
  57613. template<typename Type>
  57614. [[nodiscard]] meta_type meta_arg(const std::size_t index) noexcept {
  57615. return meta_arg<Type>(locator<meta_ctx>::value_or(), index);
  57616. }
  57617. /**
  57618. * @brief Sets the value of a given variable.
  57619. * @tparam Type Reflected type to which the variable is associated.
  57620. * @tparam Data The actual variable to set.
  57621. * @param instance An opaque instance of the underlying type, if required.
  57622. * @param value Parameter to use to set the variable.
  57623. * @return True in case of success, false otherwise.
  57624. */
  57625. template<typename Type, auto Data>
  57626. [[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) {
  57627. if constexpr(std::is_member_function_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  57628. using descriptor = meta_function_helper_t<Type, decltype(Data)>;
  57629. using data_type = type_list_element_t<descriptor::is_static, typename descriptor::args_type>;
  57630. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  57631. std::invoke(Data, *clazz, value.cast<data_type>());
  57632. return true;
  57633. }
  57634. } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
  57635. using data_type = std::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
  57636. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  57637. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  57638. std::invoke(Data, *clazz) = value.cast<data_type>();
  57639. return true;
  57640. }
  57641. }
  57642. } else if constexpr(std::is_pointer_v<decltype(Data)>) {
  57643. using data_type = std::remove_reference_t<decltype(*Data)>;
  57644. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  57645. if(value.allow_cast<data_type>()) {
  57646. *Data = value.cast<data_type>();
  57647. return true;
  57648. }
  57649. }
  57650. }
  57651. return false;
  57652. }
  57653. /**
  57654. * @brief Gets the value of a given variable.
  57655. * @tparam Type Reflected type to which the variable is associated.
  57656. * @tparam Data The actual variable to get.
  57657. * @tparam Policy Optional policy (no policy set by default).
  57658. * @param instance An opaque instance of the underlying type, if required.
  57659. * @return A meta any containing the value of the underlying variable.
  57660. */
  57661. template<typename Type, auto Data, typename Policy = as_value_t>
  57662. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_getter(meta_handle instance) {
  57663. if constexpr(std::is_member_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  57664. if constexpr(!std::is_array_v<std::remove_const_t<std::remove_reference_t<std::invoke_result_t<decltype(Data), Type &>>>>) {
  57665. if constexpr(std::is_invocable_v<decltype(Data), Type &>) {
  57666. if(auto *clazz = instance->try_cast<Type>(); clazz) {
  57667. return meta_dispatch<Policy>(instance->context(), std::invoke(Data, *clazz));
  57668. }
  57669. }
  57670. if constexpr(std::is_invocable_v<decltype(Data), const Type &>) {
  57671. if(auto *fallback = instance->try_cast<const Type>(); fallback) {
  57672. return meta_dispatch<Policy>(instance->context(), std::invoke(Data, *fallback));
  57673. }
  57674. }
  57675. }
  57676. return meta_any{meta_ctx_arg, instance->context()};
  57677. } else if constexpr(std::is_pointer_v<decltype(Data)>) {
  57678. if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
  57679. return meta_any{meta_ctx_arg, instance->context()};
  57680. } else {
  57681. return meta_dispatch<Policy>(instance->context(), *Data);
  57682. }
  57683. } else {
  57684. return meta_dispatch<Policy>(instance->context(), Data);
  57685. }
  57686. }
  57687. /**
  57688. * @brief Tries to _invoke_ an object given a list of erased parameters.
  57689. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  57690. * @tparam Policy Optional policy (no policy set by default).
  57691. * @tparam Candidate The type of the actual object to _invoke_.
  57692. * @param instance An opaque instance of the underlying type, if required.
  57693. * @param candidate The actual object to _invoke_.
  57694. * @param args Parameters to use to _invoke_ the object.
  57695. * @return A meta any containing the returned value, if any.
  57696. */
  57697. template<typename Type, typename Policy = as_value_t, typename Candidate>
  57698. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_invoke(meta_handle instance, Candidate &&candidate, meta_any *const args) {
  57699. return internal::meta_invoke<Type, Policy>(*instance.operator->(), std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  57700. }
  57701. /**
  57702. * @brief Tries to invoke a function given a list of erased parameters.
  57703. * @tparam Type Reflected type to which the function is associated.
  57704. * @tparam Candidate The actual function to invoke.
  57705. * @tparam Policy Optional policy (no policy set by default).
  57706. * @param instance An opaque instance of the underlying type, if required.
  57707. * @param args Parameters to use to invoke the function.
  57708. * @return A meta any containing the returned value, if any.
  57709. */
  57710. template<typename Type, auto Candidate, typename Policy = as_value_t>
  57711. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_invoke(meta_handle instance, meta_any *const args) {
  57712. return internal::meta_invoke<Type, Policy>(*instance.operator->(), Candidate, args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<decltype(Candidate)>>::args_type::size>{});
  57713. }
  57714. /**
  57715. * @brief Tries to construct an instance given a list of erased parameters.
  57716. *
  57717. * @warning
  57718. * The context provided is used only for the return type.<br/>
  57719. * It's up to the caller to bind the arguments to the right context(s).
  57720. *
  57721. * @tparam Type Actual type of the instance to construct.
  57722. * @tparam Args Types of arguments expected.
  57723. * @param ctx The context from which to search for meta types.
  57724. * @param args Parameters to use to construct the instance.
  57725. * @return A meta any containing the new instance, if any.
  57726. */
  57727. template<typename Type, typename... Args>
  57728. [[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args) {
  57729. return internal::meta_construct<Type, Args...>(ctx, args, std::index_sequence_for<Args...>{});
  57730. }
  57731. /**
  57732. * @brief Tries to construct an instance given a list of erased parameters.
  57733. * @tparam Type Actual type of the instance to construct.
  57734. * @tparam Args Types of arguments expected.
  57735. * @param args Parameters to use to construct the instance.
  57736. * @return A meta any containing the new instance, if any.
  57737. */
  57738. template<typename Type, typename... Args>
  57739. [[nodiscard]] meta_any meta_construct(meta_any *const args) {
  57740. return meta_construct<Type, Args...>(locator<meta_ctx>::value_or(), args);
  57741. }
  57742. /**
  57743. * @brief Tries to construct an instance given a list of erased parameters.
  57744. *
  57745. * @warning
  57746. * The context provided is used only for the return type.<br/>
  57747. * It's up to the caller to bind the arguments to the right context(s).
  57748. *
  57749. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  57750. * @tparam Policy Optional policy (no policy set by default).
  57751. * @tparam Candidate The type of the actual object to _invoke_.
  57752. * @param ctx The context from which to search for meta types.
  57753. * @param candidate The actual object to _invoke_.
  57754. * @param args Parameters to use to _invoke_ the object.
  57755. * @return A meta any containing the returned value, if any.
  57756. */
  57757. template<typename Type, typename Policy = as_value_t, typename Candidate>
  57758. [[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, Candidate &&candidate, meta_any *const args) {
  57759. if constexpr(meta_function_helper_t<Type, Candidate>::is_static || std::is_class_v<std::remove_const_t<std::remove_reference_t<Candidate>>>) {
  57760. meta_any placeholder{meta_ctx_arg, ctx};
  57761. return internal::meta_invoke<Type, Policy>(placeholder, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  57762. } else {
  57763. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  57764. return internal::meta_invoke<Type, Policy>(*args, std::forward<Candidate>(candidate), args + 1u, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  57765. }
  57766. }
  57767. /**
  57768. * @brief Tries to construct an instance given a list of erased parameters.
  57769. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  57770. * @tparam Policy Optional policy (no policy set by default).
  57771. * @tparam Candidate The type of the actual object to _invoke_.
  57772. * @param candidate The actual object to _invoke_.
  57773. * @param args Parameters to use to _invoke_ the object.
  57774. * @return A meta any containing the returned value, if any.
  57775. */
  57776. template<typename Type, typename Policy = as_value_t, typename Candidate>
  57777. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(Candidate &&candidate, meta_any *const args) {
  57778. return meta_construct<Type, Policy>(locator<meta_ctx>::value_or(), std::forward<Candidate>(candidate), args);
  57779. }
  57780. /**
  57781. * @brief Tries to construct an instance given a list of erased parameters.
  57782. *
  57783. * @warning
  57784. * The context provided is used only for the return type.<br/>
  57785. * It's up to the caller to bind the arguments to the right context(s).
  57786. *
  57787. * @tparam Type Reflected type to which the function is associated.
  57788. * @tparam Candidate The actual function to invoke.
  57789. * @tparam Policy Optional policy (no policy set by default).
  57790. * @param ctx The context from which to search for meta types.
  57791. * @param args Parameters to use to invoke the function.
  57792. * @return A meta any containing the returned value, if any.
  57793. */
  57794. template<typename Type, auto Candidate, typename Policy = as_value_t>
  57795. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(const meta_ctx &ctx, meta_any *const args) {
  57796. return meta_construct<Type, Policy>(ctx, Candidate, args);
  57797. }
  57798. /**
  57799. * @brief Tries to construct an instance given a list of erased parameters.
  57800. * @tparam Type Reflected type to which the function is associated.
  57801. * @tparam Candidate The actual function to invoke.
  57802. * @tparam Policy Optional policy (no policy set by default).
  57803. * @param args Parameters to use to invoke the function.
  57804. * @return A meta any containing the returned value, if any.
  57805. */
  57806. template<typename Type, auto Candidate, typename Policy = as_value_t>
  57807. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(meta_any *const args) {
  57808. return meta_construct<Type, Candidate, Policy>(locator<meta_ctx>::value_or(), args);
  57809. }
  57810. } // namespace entt
  57811. #endif
  57812. namespace entt {
  57813. /*! @cond TURN_OFF_DOXYGEN */
  57814. namespace internal {
  57815. class basic_meta_factory {
  57816. using invoke_type = std::remove_pointer_t<decltype(meta_func_node::invoke)>;
  57817. [[nodiscard]] auto &fetch_node() noexcept {
  57818. return *meta_context::from(*ctx).value[parent];
  57819. }
  57820. [[nodiscard]] auto *find_member_or_assert() {
  57821. auto *member = find_member<&meta_data_node::id>(fetch_node().details->data, bucket);
  57822. ENTT_ASSERT(member != nullptr, "Cannot find member");
  57823. return member;
  57824. }
  57825. [[nodiscard]] auto *find_overload_or_assert() {
  57826. auto *overload = find_overload(find_member<&meta_func_node::id>(fetch_node().details->func, bucket), invoke);
  57827. ENTT_ASSERT(overload != nullptr, "Cannot find overload");
  57828. return overload;
  57829. }
  57830. void reset_bucket(const id_type id, invoke_type *const ref = nullptr) {
  57831. invoke = ref;
  57832. bucket = id;
  57833. }
  57834. protected:
  57835. void type(const id_type id, const char *name) noexcept {
  57836. reset_bucket(parent);
  57837. auto &elem = fetch_node();
  57838. ENTT_ASSERT(elem.id == id || !resolve(*ctx, id), "Duplicate identifier");
  57839. elem.name = name;
  57840. elem.id = id;
  57841. }
  57842. template<typename Type>
  57843. void insert_or_assign(Type node) {
  57844. auto &elem = fetch_node();
  57845. reset_bucket(parent);
  57846. if constexpr(std::is_same_v<Type, meta_base_node>) {
  57847. auto *member = find_member<&meta_base_node::type>(elem.details->base, node.type);
  57848. member ? (*member = node) : elem.details->base.emplace_back(node);
  57849. } else if constexpr(std::is_same_v<Type, meta_conv_node>) {
  57850. auto *member = find_member<&meta_conv_node::type>(elem.details->conv, node.type);
  57851. member ? (*member = node) : elem.details->conv.emplace_back(node);
  57852. } else {
  57853. static_assert(std::is_same_v<Type, meta_ctor_node>, "Unexpected type");
  57854. auto *member = find_member<&meta_ctor_node::id>(elem.details->ctor, node.id);
  57855. member ? (*member = node) : elem.details->ctor.emplace_back(node);
  57856. }
  57857. }
  57858. void data(meta_data_node node) {
  57859. auto &elem = fetch_node();
  57860. reset_bucket(node.id);
  57861. if(auto *member = find_member<&meta_data_node::id>(elem.details->data, node.id); member == nullptr) {
  57862. elem.details->data.emplace_back(std::move(node));
  57863. } else if(member->set != node.set || member->get != node.get) {
  57864. *member = std::move(node);
  57865. }
  57866. }
  57867. void func(meta_func_node node) {
  57868. auto &elem = fetch_node();
  57869. reset_bucket(node.id, node.invoke);
  57870. if(auto *member = find_member<&meta_func_node::id>(elem.details->func, node.id); member == nullptr) {
  57871. elem.details->func.emplace_back(std::move(node));
  57872. } else if(auto *overload = find_overload(member, node.invoke); overload == nullptr) {
  57873. while(member->next != nullptr) { member = member->next.get(); }
  57874. member->next = std::make_unique<meta_func_node>(std::move(node));
  57875. }
  57876. }
  57877. void traits(const meta_traits value, const bool unset) {
  57878. auto set_or_unset_on = [=](auto &node) {
  57879. node.traits = (unset ? (node.traits & ~value) : (node.traits | value));
  57880. };
  57881. if(bucket == parent) {
  57882. set_or_unset_on(fetch_node());
  57883. } else if(invoke == nullptr) {
  57884. set_or_unset_on(*find_member_or_assert());
  57885. } else {
  57886. set_or_unset_on(*find_overload_or_assert());
  57887. }
  57888. }
  57889. void custom(meta_custom_node node) {
  57890. if(bucket == parent) {
  57891. fetch_node().custom = std::move(node);
  57892. } else if(invoke == nullptr) {
  57893. find_member_or_assert()->custom = std::move(node);
  57894. } else {
  57895. find_overload_or_assert()->custom = std::move(node);
  57896. }
  57897. }
  57898. public:
  57899. basic_meta_factory(meta_ctx &area, meta_type_node node)
  57900. : ctx{&area},
  57901. parent{node.info->hash()},
  57902. bucket{parent} {
  57903. if(auto *curr = meta_context::from(*ctx).value.try_emplace(parent, std::make_unique<meta_type_node>(std::move(node))).first->second.get(); curr->details == nullptr) {
  57904. curr->details = std::make_unique<meta_type_descriptor>();
  57905. }
  57906. }
  57907. private:
  57908. meta_ctx *ctx{};
  57909. id_type parent{};
  57910. id_type bucket{};
  57911. invoke_type *invoke{};
  57912. };
  57913. } // namespace internal
  57914. /*! @endcond */
  57915. /**
  57916. * @brief Meta factory to be used for reflection purposes.
  57917. * @tparam Type Type for which the factory was created.
  57918. */
  57919. template<typename Type>
  57920. class meta_factory: private internal::basic_meta_factory {
  57921. using base_type = internal::basic_meta_factory;
  57922. public:
  57923. /*! @brief Type of object for which this factory builds a meta type. */
  57924. using element_type = Type;
  57925. /*! @brief Default constructor. */
  57926. meta_factory() noexcept
  57927. : meta_factory{locator<meta_ctx>::value_or()} {}
  57928. /**
  57929. * @brief Context aware constructor.
  57930. * @param area The context into which to construct meta types.
  57931. */
  57932. meta_factory(meta_ctx &area) noexcept
  57933. : internal::basic_meta_factory{area, internal::setup_node_for<Type>()} {}
  57934. /**
  57935. * @brief Assigns a custom unique identifier to a meta type.
  57936. * @param name A custom unique identifier as a **string literal**.
  57937. * @return A meta factory for the given type.
  57938. */
  57939. meta_factory type(const char *name) noexcept {
  57940. return type(hashed_string::value(name), name);
  57941. }
  57942. /**
  57943. * @brief Assigns a custom unique identifier to a meta type.
  57944. * @param id A custom unique identifier.
  57945. * @param name An optional name for the type as a **string literal**.
  57946. * @return A meta factory for the given type.
  57947. */
  57948. meta_factory type(const id_type id, const char *name = nullptr) noexcept {
  57949. base_type::type(id, name);
  57950. return *this;
  57951. }
  57952. /**
  57953. * @brief Assigns a meta base to a meta type.
  57954. *
  57955. * A reflected base class must be a real base class of the reflected type.
  57956. *
  57957. * @tparam Base Type of the base class to assign to the meta type.
  57958. * @return A meta factory for the parent type.
  57959. */
  57960. template<typename Base>
  57961. meta_factory base() noexcept {
  57962. static_assert(!std::is_same_v<Type, Base> && std::is_base_of_v<Base, Type>, "Invalid base type");
  57963. auto *const op = +[](const void *instance) noexcept { return static_cast<const void *>(static_cast<const Base *>(static_cast<const Type *>(instance))); };
  57964. base_type::insert_or_assign(internal::meta_base_node{type_id<Base>().hash(), &internal::resolve<Base>, op});
  57965. return *this;
  57966. }
  57967. /**
  57968. * @brief Assigns a meta conversion function to a meta type.
  57969. *
  57970. * Conversion functions can be either free functions or member
  57971. * functions.<br/>
  57972. * In case of free functions, they must accept a const reference to an
  57973. * instance of the parent type as an argument. In case of member functions,
  57974. * they should have no arguments at all.
  57975. *
  57976. * @tparam Candidate The actual function to use for the conversion.
  57977. * @return A meta factory for the parent type.
  57978. */
  57979. template<auto Candidate>
  57980. auto conv() noexcept {
  57981. using conv_type = std::remove_const_t<std::remove_reference_t<std::invoke_result_t<decltype(Candidate), Type &>>>;
  57982. auto *const op = +[](const meta_ctx &area, const void *instance) { return forward_as_meta(area, std::invoke(Candidate, *static_cast<const Type *>(instance))); };
  57983. base_type::insert_or_assign(internal::meta_conv_node{type_id<conv_type>().hash(), op});
  57984. return *this;
  57985. }
  57986. /**
  57987. * @brief Assigns a meta conversion function to a meta type.
  57988. *
  57989. * The given type must be such that an instance of the reflected type can be
  57990. * converted to it.
  57991. *
  57992. * @tparam To Type of the conversion function to assign to the meta type.
  57993. * @return A meta factory for the parent type.
  57994. */
  57995. template<typename To>
  57996. meta_factory conv() noexcept {
  57997. using conv_type = std::remove_const_t<std::remove_reference_t<To>>;
  57998. auto *const op = +[](const meta_ctx &area, const void *instance) { return forward_as_meta(area, static_cast<To>(*static_cast<const Type *>(instance))); };
  57999. base_type::insert_or_assign(internal::meta_conv_node{type_id<conv_type>().hash(), op});
  58000. return *this;
  58001. }
  58002. /**
  58003. * @brief Assigns a meta constructor to a meta type.
  58004. *
  58005. * Both member functions and free function can be assigned to meta types in
  58006. * the role of constructors. All that is required is that they return an
  58007. * instance of the underlying type.<br/>
  58008. * From a client's point of view, nothing changes if a constructor of a meta
  58009. * type is a built-in one or not.
  58010. *
  58011. * @tparam Candidate The actual function to use as a constructor.
  58012. * @tparam Policy Optional policy (no policy set by default).
  58013. * @return A meta factory for the parent type.
  58014. */
  58015. template<auto Candidate, typename Policy = as_value_t>
  58016. meta_factory ctor() noexcept {
  58017. using descriptor = meta_function_helper_t<Type, decltype(Candidate)>;
  58018. static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
  58019. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<typename descriptor::return_type>>, Type>, "The function doesn't return an object of the required type");
  58020. base_type::insert_or_assign(internal::meta_ctor_node{type_id<typename descriptor::args_type>().hash(), descriptor::args_type::size, &meta_arg<typename descriptor::args_type>, &meta_construct<Type, Candidate, Policy>});
  58021. return *this;
  58022. }
  58023. /**
  58024. * @brief Assigns a meta constructor to a meta type.
  58025. *
  58026. * A meta constructor is uniquely identified by the types of its arguments
  58027. * and is such that there exists an actual constructor of the underlying
  58028. * type that can be invoked with parameters whose types are those given.
  58029. *
  58030. * @tparam Args Types of arguments to use to construct an instance.
  58031. * @return A meta factory for the parent type.
  58032. */
  58033. template<typename... Args>
  58034. meta_factory ctor() noexcept {
  58035. // default constructor is already implicitly generated, no need for redundancy
  58036. if constexpr(sizeof...(Args) != 0u) {
  58037. using descriptor = meta_function_helper_t<Type, Type (*)(Args...)>;
  58038. base_type::insert_or_assign(internal::meta_ctor_node{type_id<typename descriptor::args_type>().hash(), descriptor::args_type::size, &meta_arg<typename descriptor::args_type>, &meta_construct<Type, Args...>});
  58039. }
  58040. return *this;
  58041. }
  58042. /**
  58043. * @brief Assigns a meta data to a meta type.
  58044. * @tparam Data The actual variable to attach to the meta type.
  58045. * @tparam Policy Optional policy (no policy set by default).
  58046. * @param name A custom unique identifier as a **string literal**.
  58047. * @return A meta factory for the given type.
  58048. */
  58049. template<auto Data, typename Policy = as_value_t>
  58050. meta_factory data(const char *name) noexcept {
  58051. return data<Data, Policy>(hashed_string::value(name), name);
  58052. }
  58053. /**
  58054. * @brief Assigns a meta data to a meta type.
  58055. *
  58056. * Both data members and static and global variables, as well as constants
  58057. * of any kind, can be assigned to a meta type.<br/>
  58058. * From a client's point of view, all the variables associated with the
  58059. * reflected object will appear as if they were part of the type itself.
  58060. *
  58061. * @tparam Data The actual variable to attach to the meta type.
  58062. * @tparam Policy Optional policy (no policy set by default).
  58063. * @param id Unique identifier.
  58064. * @param name An optional name for the meta data as a **string literal**.
  58065. * @return A meta factory for the parent type.
  58066. */
  58067. template<auto Data, typename Policy = as_value_t>
  58068. meta_factory data(const id_type id, const char *name = nullptr) noexcept {
  58069. if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
  58070. using data_type = std::invoke_result_t<decltype(Data), Type &>;
  58071. static_assert(Policy::template value<data_type>, "Invalid return type for the given policy");
  58072. base_type::data(
  58073. internal::meta_data_node{
  58074. id,
  58075. name,
  58076. /* this is never static */
  58077. std::is_const_v<std::remove_reference_t<data_type>> ? internal::meta_traits::is_const : internal::meta_traits::is_none,
  58078. 1u,
  58079. &internal::resolve<std::remove_const_t<std::remove_reference_t<data_type>>>,
  58080. &meta_arg<type_list<std::remove_const_t<std::remove_reference_t<data_type>>>>,
  58081. &meta_setter<Type, Data>,
  58082. &meta_getter<Type, Data, Policy>});
  58083. } else {
  58084. using data_type = std::remove_pointer_t<decltype(Data)>;
  58085. if constexpr(std::is_pointer_v<decltype(Data)>) {
  58086. static_assert(Policy::template value<decltype(*Data)>, "Invalid return type for the given policy");
  58087. } else {
  58088. static_assert(Policy::template value<data_type>, "Invalid return type for the given policy");
  58089. }
  58090. base_type::data(
  58091. internal::meta_data_node{
  58092. id,
  58093. name,
  58094. ((!std::is_pointer_v<decltype(Data)> || std::is_const_v<data_type>) ? internal::meta_traits::is_const : internal::meta_traits::is_none) | internal::meta_traits::is_static,
  58095. 1u,
  58096. &internal::resolve<std::remove_const_t<std::remove_reference_t<data_type>>>,
  58097. &meta_arg<type_list<std::remove_const_t<std::remove_reference_t<data_type>>>>,
  58098. &meta_setter<Type, Data>,
  58099. &meta_getter<Type, Data, Policy>});
  58100. }
  58101. return *this;
  58102. }
  58103. /**
  58104. * @brief Assigns a meta data to a meta type by means of its setter and
  58105. * getter.
  58106. * @tparam Setter The actual function to use as a setter.
  58107. * @tparam Getter The actual function to use as a getter.
  58108. * @tparam Policy Optional policy (no policy set by default).
  58109. * @param name A custom unique identifier as a **string literal**.
  58110. * @return A meta factory for the given type.
  58111. */
  58112. template<auto Setter, auto Getter, typename Policy = as_value_t>
  58113. meta_factory data(const char *name) noexcept {
  58114. return data<Setter, Getter, Policy>(hashed_string::value(name), name);
  58115. }
  58116. /**
  58117. * @brief Assigns a meta data to a meta type by means of its setter and
  58118. * getter.
  58119. *
  58120. * Setters and getters can be either free functions, member functions or a
  58121. * mix of them.<br/>
  58122. * In case of free functions, setters and getters must accept a reference to
  58123. * an instance of the parent type as their first argument. A setter has then
  58124. * an extra argument of a type convertible to that of the parameter to
  58125. * set.<br/>
  58126. * In case of member functions, getters have no arguments at all, while
  58127. * setters has an argument of a type convertible to that of the parameter to
  58128. * set.
  58129. *
  58130. * @tparam Setter The actual function to use as a setter.
  58131. * @tparam Getter The actual function to use as a getter.
  58132. * @tparam Policy Optional policy (no policy set by default).
  58133. * @param id Unique identifier.
  58134. * @param name An optional name for the meta data as a **string literal**.
  58135. * @return A meta factory for the parent type.
  58136. */
  58137. template<auto Setter, auto Getter, typename Policy = as_value_t>
  58138. meta_factory data(const id_type id, const char *name = nullptr) noexcept {
  58139. using descriptor = meta_function_helper_t<Type, decltype(Getter)>;
  58140. static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
  58141. if constexpr(std::is_same_v<decltype(Setter), std::nullptr_t>) {
  58142. base_type::data(
  58143. internal::meta_data_node{
  58144. id,
  58145. name,
  58146. /* this is never static */
  58147. internal::meta_traits::is_const,
  58148. 0u,
  58149. &internal::resolve<std::remove_const_t<std::remove_reference_t<typename descriptor::return_type>>>,
  58150. &meta_arg<type_list<>>,
  58151. &meta_setter<Type, Setter>,
  58152. &meta_getter<Type, Getter, Policy>});
  58153. } else {
  58154. using args_type = typename meta_function_helper_t<Type, decltype(Setter)>::args_type;
  58155. base_type::data(
  58156. internal::meta_data_node{
  58157. id,
  58158. name,
  58159. /* this is never static nor const */
  58160. internal::meta_traits::is_none,
  58161. 1u,
  58162. &internal::resolve<std::remove_const_t<std::remove_reference_t<typename descriptor::return_type>>>,
  58163. &meta_arg<type_list<type_list_element_t<static_cast<std::size_t>(args_type::size != 1u), args_type>>>,
  58164. &meta_setter<Type, Setter>,
  58165. &meta_getter<Type, Getter, Policy>});
  58166. }
  58167. return *this;
  58168. }
  58169. /**
  58170. * @brief Assigns a meta function to a meta type.
  58171. * @tparam Candidate The actual function to attach to the meta function.
  58172. * @tparam Policy Optional policy (no policy set by default).
  58173. * @param name A custom unique identifier as a **string literal**.
  58174. * @return A meta factory for the given type.
  58175. */
  58176. template<auto Candidate, typename Policy = as_value_t>
  58177. meta_factory func(const char *name) noexcept {
  58178. return func<Candidate, Policy>(hashed_string::value(name), name);
  58179. }
  58180. /**
  58181. * @brief Assigns a meta function to a meta type.
  58182. *
  58183. * Both member functions and free functions can be assigned to a meta
  58184. * type.<br/>
  58185. * From a client's point of view, all the functions associated with the
  58186. * reflected object will appear as if they were part of the type itself.
  58187. *
  58188. * @tparam Candidate The actual function to attach to the meta type.
  58189. * @tparam Policy Optional policy (no policy set by default).
  58190. * @param id Unique identifier.
  58191. * @param name An optional name for the function as a **string literal**.
  58192. * @return A meta factory for the parent type.
  58193. */
  58194. template<auto Candidate, typename Policy = as_value_t>
  58195. meta_factory func(const id_type id, const char *name = nullptr) noexcept {
  58196. using descriptor = meta_function_helper_t<Type, decltype(Candidate)>;
  58197. static_assert(Policy::template value<typename descriptor::return_type>, "Invalid return type for the given policy");
  58198. base_type::func(
  58199. internal::meta_func_node{
  58200. id,
  58201. name,
  58202. (descriptor::is_const ? internal::meta_traits::is_const : internal::meta_traits::is_none) | (descriptor::is_static ? internal::meta_traits::is_static : internal::meta_traits::is_none),
  58203. descriptor::args_type::size,
  58204. &internal::resolve<std::conditional_t<std::is_same_v<Policy, as_void_t>, void, std::remove_const_t<std::remove_reference_t<typename descriptor::return_type>>>>,
  58205. &meta_arg<typename descriptor::args_type>,
  58206. &meta_invoke<Type, Candidate, Policy>});
  58207. return *this;
  58208. }
  58209. /**
  58210. * @brief Sets traits on the last created meta object.
  58211. *
  58212. * The assigned value must be an enum and intended as a bitmask.
  58213. *
  58214. * @tparam Value Type of the traits value.
  58215. * @param value Traits value.
  58216. * @param unset True to unset the given traits, false otherwise.
  58217. * @return A meta factory for the parent type.
  58218. */
  58219. template<typename Value>
  58220. meta_factory traits(const Value value, const bool unset = false) {
  58221. static_assert(std::is_enum_v<Value>, "Invalid enum type");
  58222. base_type::traits(internal::user_to_meta_traits(value), unset);
  58223. return *this;
  58224. }
  58225. /**
  58226. * @brief Sets user defined data that will never be used by the library.
  58227. * @tparam Value Type of user defined data to store.
  58228. * @tparam Args Types of arguments to use to construct the user data.
  58229. * @param args Parameters to use to initialize the user data.
  58230. * @return A meta factory for the parent type.
  58231. */
  58232. template<typename Value, typename... Args>
  58233. meta_factory custom(Args &&...args) {
  58234. base_type::custom(internal::meta_custom_node{type_id<Value>().hash(), std::make_shared<Value>(std::forward<Args>(args)...)});
  58235. return *this;
  58236. }
  58237. };
  58238. /**
  58239. * @brief Resets a type and all its parts.
  58240. *
  58241. * Resets a type and all its data members, member functions and properties, as
  58242. * well as its constructors, destructors and conversion functions if any.<br/>
  58243. * Base classes aren't reset but the link between the two types is removed.
  58244. *
  58245. * The type is also removed from the set of searchable types.
  58246. *
  58247. * @param id Unique identifier.
  58248. * @param ctx The context from which to reset meta types.
  58249. */
  58250. inline void meta_reset(meta_ctx &ctx, const id_type id) noexcept {
  58251. auto &context = internal::meta_context::from(ctx);
  58252. for(auto it = context.value.begin(); it != context.value.end();) {
  58253. if(it->second->id == id) {
  58254. it = context.value.erase(it);
  58255. } else {
  58256. ++it;
  58257. }
  58258. }
  58259. }
  58260. /**
  58261. * @brief Resets a type and all its parts.
  58262. *
  58263. * Resets a type and all its data members, member functions and properties, as
  58264. * well as its constructors, destructors and conversion functions if any.<br/>
  58265. * Base classes aren't reset but the link between the two types is removed.
  58266. *
  58267. * The type is also removed from the set of searchable types.
  58268. *
  58269. * @param id Unique identifier.
  58270. */
  58271. inline void meta_reset(const id_type id) noexcept {
  58272. meta_reset(locator<meta_ctx>::value_or(), id);
  58273. }
  58274. /**
  58275. * @brief Resets a type and all its parts.
  58276. *
  58277. * @sa meta_reset
  58278. *
  58279. * @tparam Type Type to reset.
  58280. * @param ctx The context from which to reset meta types.
  58281. */
  58282. template<typename Type>
  58283. void meta_reset(meta_ctx &ctx) noexcept {
  58284. internal::meta_context::from(ctx).value.erase(type_id<Type>().hash());
  58285. }
  58286. /**
  58287. * @brief Resets a type and all its parts.
  58288. *
  58289. * @sa meta_reset
  58290. *
  58291. * @tparam Type Type to reset.
  58292. */
  58293. template<typename Type>
  58294. void meta_reset() noexcept {
  58295. meta_reset<Type>(locator<meta_ctx>::value_or());
  58296. }
  58297. /**
  58298. * @brief Resets all meta types.
  58299. *
  58300. * @sa meta_reset
  58301. *
  58302. * @param ctx The context from which to reset meta types.
  58303. */
  58304. inline void meta_reset(meta_ctx &ctx) noexcept {
  58305. internal::meta_context::from(ctx).value.clear();
  58306. }
  58307. /**
  58308. * @brief Resets all meta types.
  58309. *
  58310. * @sa meta_reset
  58311. */
  58312. inline void meta_reset() noexcept {
  58313. meta_reset(locator<meta_ctx>::value_or());
  58314. }
  58315. } // namespace entt
  58316. #endif
  58317. // #include "meta/meta.hpp"
  58318. #ifndef ENTT_META_META_HPP
  58319. #define ENTT_META_META_HPP
  58320. #include <array>
  58321. #include <cstddef>
  58322. #include <iterator>
  58323. #include <memory>
  58324. #include <type_traits>
  58325. #include <utility>
  58326. // #include "../config/config.h"
  58327. // #include "../core/any.hpp"
  58328. // #include "../core/fwd.hpp"
  58329. // #include "../core/iterator.hpp"
  58330. // #include "../core/type_info.hpp"
  58331. // #include "../core/type_traits.hpp"
  58332. // #include "../core/utility.hpp"
  58333. // #include "../locator/locator.hpp"
  58334. // #include "adl_pointer.hpp"
  58335. // #include "context.hpp"
  58336. // #include "fwd.hpp"
  58337. // #include "node.hpp"
  58338. // #include "range.hpp"
  58339. // #include "type_traits.hpp"
  58340. namespace entt {
  58341. class meta_any;
  58342. class meta_type;
  58343. /*! @brief Proxy object for sequence containers. */
  58344. class meta_sequence_container {
  58345. class meta_iterator;
  58346. public:
  58347. /*! @brief Unsigned integer type. */
  58348. using size_type = std::size_t;
  58349. /*! @brief Meta iterator type. */
  58350. using iterator = meta_iterator;
  58351. /*! @brief Default constructor. */
  58352. meta_sequence_container() = default;
  58353. /**
  58354. * @brief Context aware constructor.
  58355. * @tparam Type Type of container to wrap.
  58356. * @param area The context from which to search for meta types.
  58357. * @param instance The container to wrap.
  58358. */
  58359. template<typename Type>
  58360. meta_sequence_container(const meta_ctx &area, Type &instance) noexcept
  58361. : ctx{&area},
  58362. data{&instance},
  58363. value_type_node{&internal::resolve<typename Type::value_type>},
  58364. const_reference_node{&internal::resolve<std::remove_const_t<std::remove_reference_t<typename Type::const_reference>>>},
  58365. size_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::size},
  58366. clear_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::clear},
  58367. reserve_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::reserve},
  58368. resize_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::resize},
  58369. begin_end_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::iter},
  58370. insert_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::insert},
  58371. erase_fn{meta_sequence_container_traits<std::remove_const_t<Type>>::erase},
  58372. const_only{std::is_const_v<Type>} {}
  58373. [[nodiscard]] inline meta_type value_type() const noexcept;
  58374. [[nodiscard]] inline size_type size() const noexcept;
  58375. inline bool resize(size_type);
  58376. inline bool clear();
  58377. inline bool reserve(size_type);
  58378. [[nodiscard]] inline iterator begin();
  58379. [[nodiscard]] inline iterator end();
  58380. inline iterator insert(const iterator &, meta_any);
  58381. inline iterator erase(const iterator &);
  58382. [[nodiscard]] inline meta_any operator[](size_type);
  58383. [[nodiscard]] inline explicit operator bool() const noexcept;
  58384. private:
  58385. const meta_ctx *ctx{};
  58386. const void *data{};
  58387. const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){};
  58388. const internal::meta_type_node &(*const_reference_node)(const internal::meta_context &){};
  58389. size_type (*size_fn)(const void *){};
  58390. bool (*clear_fn)(void *){};
  58391. bool (*reserve_fn)(void *, const size_type){};
  58392. bool (*resize_fn)(void *, const size_type){};
  58393. iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){};
  58394. iterator (*insert_fn)(const meta_ctx &, void *, const void *, const void *, const iterator &){};
  58395. iterator (*erase_fn)(const meta_ctx &, void *, const iterator &){};
  58396. bool const_only{};
  58397. };
  58398. /*! @brief Proxy object for associative containers. */
  58399. class meta_associative_container {
  58400. class meta_iterator;
  58401. public:
  58402. /*! @brief Unsigned integer type. */
  58403. using size_type = std::size_t;
  58404. /*! @brief Meta iterator type. */
  58405. using iterator = meta_iterator;
  58406. /*! @brief Default constructor. */
  58407. meta_associative_container() = default;
  58408. /**
  58409. * @brief Context aware constructor.
  58410. * @tparam Type Type of container to wrap.
  58411. * @param area The context from which to search for meta types.
  58412. * @param instance The container to wrap.
  58413. */
  58414. template<typename Type>
  58415. meta_associative_container(const meta_ctx &area, Type &instance) noexcept
  58416. : ctx{&area},
  58417. data{&instance},
  58418. key_type_node{&internal::resolve<typename Type::key_type>},
  58419. value_type_node{&internal::resolve<typename Type::value_type>},
  58420. size_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::size},
  58421. clear_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::clear},
  58422. reserve_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::reserve},
  58423. begin_end_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::iter},
  58424. insert_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::insert},
  58425. erase_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::erase},
  58426. find_fn{&meta_associative_container_traits<std::remove_const_t<Type>>::find},
  58427. const_only{std::is_const_v<Type>} {
  58428. if constexpr(!meta_associative_container_traits<std::remove_const_t<Type>>::key_only) {
  58429. mapped_type_node = &internal::resolve<typename Type::mapped_type>;
  58430. }
  58431. }
  58432. [[nodiscard]] inline meta_type key_type() const noexcept;
  58433. [[nodiscard]] inline meta_type mapped_type() const noexcept;
  58434. [[nodiscard]] inline meta_type value_type() const noexcept;
  58435. [[nodiscard]] inline size_type size() const noexcept;
  58436. inline bool clear();
  58437. inline bool reserve(size_type);
  58438. [[nodiscard]] inline iterator begin();
  58439. [[nodiscard]] inline iterator end();
  58440. inline bool insert(meta_any, meta_any);
  58441. inline size_type erase(meta_any);
  58442. [[nodiscard]] inline iterator find(meta_any);
  58443. [[nodiscard]] inline explicit operator bool() const noexcept;
  58444. private:
  58445. const meta_ctx *ctx{};
  58446. const void *data{};
  58447. const internal::meta_type_node &(*key_type_node)(const internal::meta_context &){};
  58448. const internal::meta_type_node &(*mapped_type_node)(const internal::meta_context &){};
  58449. const internal::meta_type_node &(*value_type_node)(const internal::meta_context &){};
  58450. size_type (*size_fn)(const void *){};
  58451. bool (*clear_fn)(void *){};
  58452. bool (*reserve_fn)(void *, const size_type){};
  58453. iterator (*begin_end_fn)(const meta_ctx &, void *, const void *, const bool){};
  58454. bool (*insert_fn)(void *, const void *, const void *){};
  58455. size_type (*erase_fn)(void *, const void *){};
  58456. iterator (*find_fn)(const meta_ctx &, void *, const void *, const void *){};
  58457. bool const_only{};
  58458. };
  58459. /*! @brief Opaque wrapper for values of any type. */
  58460. class meta_any {
  58461. using vtable_type = void(const internal::meta_traits, const meta_any &, const void *);
  58462. template<typename Type>
  58463. static void basic_vtable(const internal::meta_traits req, const meta_any &value, [[maybe_unused]] const void *other) {
  58464. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  58465. if(req == internal::meta_traits::is_none) {
  58466. value.node = &internal::resolve<Type>(internal::meta_context::from(*value.ctx));
  58467. }
  58468. if constexpr(is_meta_pointer_like_v<Type>) {
  58469. if(req == internal::meta_traits::is_pointer_like) {
  58470. if constexpr(std::is_function_v<typename std::pointer_traits<Type>::element_type>) {
  58471. const_cast<meta_any &>(value).emplace<Type>(*static_cast<const Type *>(other));
  58472. } else if constexpr(!std::is_void_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
  58473. using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(std::declval<const Type &>()));
  58474. if constexpr(std::is_constructible_v<bool, Type>) {
  58475. if(const auto &pointer_like = *static_cast<const Type *>(other); pointer_like) {
  58476. const_cast<meta_any &>(value).emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(pointer_like));
  58477. }
  58478. } else {
  58479. const_cast<meta_any &>(value).emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(*static_cast<const Type *>(other)));
  58480. }
  58481. }
  58482. }
  58483. }
  58484. if constexpr(is_complete_v<meta_sequence_container_traits<Type>> || is_complete_v<meta_associative_container_traits<Type>>) {
  58485. if(constexpr auto flag = (is_complete_v<meta_sequence_container_traits<Type>> ? internal::meta_traits::is_sequence_container : internal::meta_traits::is_associative_container); !!(req & flag)) {
  58486. using container_type = std::conditional_t<is_complete_v<meta_sequence_container_traits<Type>>, meta_sequence_container, meta_associative_container>;
  58487. if(!!(req & internal::meta_traits::is_const) || (value.storage.policy() == any_policy::cref)) {
  58488. // NOLINTNEXTLINE(bugprone-casting-through-void)
  58489. *static_cast<container_type *>(const_cast<void *>(other)) = container_type{*value.ctx, any_cast<const Type &>(value.storage)};
  58490. } else {
  58491. // NOLINTNEXTLINE(bugprone-casting-through-void)
  58492. *static_cast<container_type *>(const_cast<void *>(other)) = container_type{*value.ctx, any_cast<Type &>(const_cast<meta_any &>(value).storage)};
  58493. }
  58494. }
  58495. }
  58496. }
  58497. [[nodiscard]] const auto &fetch_node() const {
  58498. if(node == nullptr) {
  58499. ENTT_ASSERT(*this, "Invalid vtable function");
  58500. vtable(internal::meta_traits::is_none, *this, nullptr);
  58501. }
  58502. ENTT_ASSERT(node != nullptr, "Invalid pointer to node");
  58503. return *node;
  58504. }
  58505. meta_any(const meta_any &other, any elem)
  58506. : storage{std::move(elem)},
  58507. ctx{other.ctx},
  58508. node{other.node},
  58509. vtable{other.vtable} {}
  58510. public:
  58511. /*! Default constructor. */
  58512. meta_any() = default;
  58513. /**
  58514. * @brief Context aware constructor.
  58515. * @param area The context from which to search for meta types.
  58516. */
  58517. meta_any(meta_ctx_arg_t, const meta_ctx &area)
  58518. : ctx{&area} {}
  58519. /**
  58520. * @brief Constructs a wrapper by directly initializing the new object.
  58521. * @tparam Type Type of object to use to initialize the wrapper.
  58522. * @tparam Args Types of arguments to use to construct the new instance.
  58523. * @param args Parameters to use to construct the instance.
  58524. */
  58525. template<typename Type, typename... Args>
  58526. explicit meta_any(std::in_place_type_t<Type>, Args &&...args)
  58527. : meta_any{locator<meta_ctx>::value_or(), std::in_place_type<Type>, std::forward<Args>(args)...} {}
  58528. /**
  58529. * @brief Constructs a wrapper by directly initializing the new object.
  58530. * @tparam Type Type of object to use to initialize the wrapper.
  58531. * @tparam Args Types of arguments to use to construct the new instance.
  58532. * @param area The context from which to search for meta types.
  58533. * @param args Parameters to use to construct the instance.
  58534. */
  58535. template<typename Type, typename... Args>
  58536. explicit meta_any(const meta_ctx &area, std::in_place_type_t<Type>, Args &&...args)
  58537. : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
  58538. ctx{&area},
  58539. vtable{&basic_vtable<std::remove_const_t<std::remove_reference_t<Type>>>} {}
  58540. /**
  58541. * @brief Constructs a wrapper taking ownership of the passed object.
  58542. * @tparam Type Type of object to use to initialize the wrapper.
  58543. * @param value A pointer to an object to take ownership of.
  58544. */
  58545. template<typename Type>
  58546. explicit meta_any(std::in_place_t, Type *value)
  58547. : meta_any{locator<meta_ctx>::value_or(), std::in_place, value} {}
  58548. /**
  58549. * @brief Constructs a wrapper taking ownership of the passed object.
  58550. * @tparam Type Type of object to use to initialize the wrapper.
  58551. * @param area The context from which to search for meta types.
  58552. * @param value A pointer to an object to take ownership of.
  58553. */
  58554. template<typename Type>
  58555. explicit meta_any(const meta_ctx &area, std::in_place_t, Type *value)
  58556. : storage{std::in_place, value},
  58557. ctx{&area},
  58558. vtable{storage ? &basic_vtable<Type> : nullptr} {
  58559. }
  58560. /**
  58561. * @brief Constructs a wrapper from a given value.
  58562. * @tparam Type Type of object to use to initialize the wrapper.
  58563. * @param value An instance of an object to use to initialize the wrapper.
  58564. */
  58565. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  58566. meta_any(Type &&value)
  58567. : meta_any{locator<meta_ctx>::value_or(), std::forward<Type>(value)} {}
  58568. /**
  58569. * @brief Constructs a wrapper from a given value.
  58570. * @tparam Type Type of object to use to initialize the wrapper.
  58571. * @param area The context from which to search for meta types.
  58572. * @param value An instance of an object to use to initialize the wrapper.
  58573. */
  58574. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  58575. meta_any(const meta_ctx &area, Type &&value)
  58576. : meta_any{area, std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
  58577. /**
  58578. * @brief Context aware copy constructor.
  58579. * @param area The context from which to search for meta types.
  58580. * @param other The instance to copy from.
  58581. */
  58582. meta_any(const meta_ctx &area, const meta_any &other)
  58583. : storage{other.storage},
  58584. ctx{&area},
  58585. node{(ctx == other.ctx) ? other.node : nullptr},
  58586. vtable{other.vtable} {}
  58587. /**
  58588. * @brief Context aware move constructor.
  58589. * @param area The context from which to search for meta types.
  58590. * @param other The instance to move from.
  58591. */
  58592. meta_any(const meta_ctx &area, meta_any &&other)
  58593. : storage{std::move(other.storage)},
  58594. ctx{&area},
  58595. node{(ctx == other.ctx) ? std::exchange(other.node, nullptr) : nullptr},
  58596. vtable{std::exchange(other.vtable, nullptr)} {}
  58597. /**
  58598. * @brief Copy constructor.
  58599. * @param other The instance to copy from.
  58600. */
  58601. meta_any(const meta_any &other) = default;
  58602. /**
  58603. * @brief Move constructor.
  58604. * @param other The instance to move from.
  58605. */
  58606. meta_any(meta_any &&other) noexcept
  58607. : storage{std::move(other.storage)},
  58608. ctx{other.ctx},
  58609. node{std::exchange(other.node, nullptr)},
  58610. vtable{std::exchange(other.vtable, nullptr)} {}
  58611. /*! @brief Default destructor. */
  58612. ~meta_any() = default;
  58613. /**
  58614. * @brief Copy assignment operator.
  58615. * @param other The instance to copy from.
  58616. * @return This meta any object.
  58617. */
  58618. meta_any &operator=(const meta_any &other) {
  58619. if(this != &other) {
  58620. storage = other.storage;
  58621. ctx = other.ctx;
  58622. node = other.node;
  58623. vtable = other.vtable;
  58624. }
  58625. return *this;
  58626. }
  58627. /**
  58628. * @brief Move assignment operator.
  58629. * @param other The instance to move from.
  58630. * @return This meta any object.
  58631. */
  58632. meta_any &operator=(meta_any &&other) noexcept {
  58633. storage = std::move(other.storage);
  58634. ctx = other.ctx;
  58635. node = std::exchange(other.node, nullptr);
  58636. vtable = std::exchange(other.vtable, nullptr);
  58637. return *this;
  58638. }
  58639. /**
  58640. * @brief Value assignment operator.
  58641. * @tparam Type Type of object to use to initialize the wrapper.
  58642. * @param value An instance of an object to use to initialize the wrapper.
  58643. * @return This meta any object.
  58644. */
  58645. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_any>>>
  58646. meta_any &operator=(Type &&value) {
  58647. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  58648. return *this;
  58649. }
  58650. /*! @copydoc any::info */
  58651. [[nodiscard]] inline meta_type type() const noexcept;
  58652. /**
  58653. * @brief Invokes the underlying function, if possible.
  58654. * @tparam Args Types of arguments to use to invoke the function.
  58655. * @param id Unique identifier.
  58656. * @param args Parameters to use to invoke the function.
  58657. * @return A wrapper containing the returned value, if any.
  58658. */
  58659. template<typename... Args>
  58660. meta_any invoke(id_type id, Args &&...args) const;
  58661. /*! @copydoc invoke */
  58662. template<typename... Args>
  58663. meta_any invoke(id_type id, Args &&...args);
  58664. /**
  58665. * @brief Sets the value of a given variable.
  58666. * @tparam Type Type of value to assign.
  58667. * @param id Unique identifier.
  58668. * @param value Parameter to use to set the underlying variable.
  58669. * @return True in case of success, false otherwise.
  58670. */
  58671. template<typename Type>
  58672. bool set(id_type id, Type &&value);
  58673. /**
  58674. * @brief Gets the value of a given variable.
  58675. * @param id Unique identifier.
  58676. * @return A wrapper containing the value of the underlying variable.
  58677. */
  58678. [[nodiscard]] meta_any get(id_type id) const;
  58679. /*! @copydoc get */
  58680. [[nodiscard]] meta_any get(id_type id);
  58681. /**
  58682. * @brief Tries to cast an instance to a given type.
  58683. * @tparam Type Type to which to cast the instance.
  58684. * @return A (possibly null) pointer to the contained instance.
  58685. */
  58686. template<typename Type>
  58687. [[nodiscard]] const Type *try_cast() const {
  58688. const auto *elem = any_cast<const Type>(&storage);
  58689. return ((elem != nullptr) || !*this) ? elem : static_cast<const Type *>(internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), type_hash<std::remove_const_t<Type>>::value(), storage.data()));
  58690. }
  58691. /*! @copydoc try_cast */
  58692. template<typename Type>
  58693. [[nodiscard]] Type *try_cast() {
  58694. return ((storage.policy() == any_policy::cref) && !std::is_const_v<Type>) ? nullptr : const_cast<Type *>(std::as_const(*this).try_cast<std::remove_const_t<Type>>());
  58695. }
  58696. /**
  58697. * @brief Tries to cast an instance to a given type.
  58698. * @tparam Type Type to which to cast the instance.
  58699. * @return A reference to the contained instance.
  58700. */
  58701. template<typename Type>
  58702. [[nodiscard]] std::remove_const_t<Type> cast() const {
  58703. auto *const instance = try_cast<std::remove_reference_t<Type>>();
  58704. ENTT_ASSERT(instance, "Invalid instance");
  58705. return static_cast<Type>(*instance);
  58706. }
  58707. /*! @copydoc cast */
  58708. template<typename Type>
  58709. [[nodiscard]] std::remove_const_t<Type> cast() {
  58710. // forces const on non-reference types to make them work also with wrappers for const references
  58711. auto *const instance = try_cast<std::remove_reference_t<const Type>>();
  58712. ENTT_ASSERT(instance, "Invalid instance");
  58713. return static_cast<Type>(*instance);
  58714. }
  58715. /**
  58716. * @brief Converts an object in such a way that a given cast becomes viable.
  58717. * @param type Meta type to which the cast is requested.
  58718. * @return A valid meta object if convertible, an invalid one otherwise.
  58719. */
  58720. [[nodiscard]] meta_any allow_cast(const meta_type &type) const;
  58721. /**
  58722. * @brief Converts an object in such a way that a given cast becomes viable.
  58723. * @param type Meta type to which the cast is requested.
  58724. * @return True if convertible, false otherwise.
  58725. */
  58726. [[nodiscard]] bool allow_cast(const meta_type &type);
  58727. /**
  58728. * @brief Converts an object in such a way that a given cast becomes viable.
  58729. * @tparam Type Type to which the cast is requested.
  58730. * @return A valid meta object if convertible, an invalid one otherwise.
  58731. */
  58732. template<typename Type>
  58733. [[nodiscard]] meta_any allow_cast() const {
  58734. if constexpr(!std::is_reference_v<Type> || std::is_const_v<std::remove_reference_t<Type>>) {
  58735. if(storage.has_value<std::remove_const_t<std::remove_reference_t<Type>>>()) {
  58736. return as_ref();
  58737. } else if(*this) {
  58738. if constexpr(std::is_arithmetic_v<std::remove_const_t<std::remove_reference_t<Type>>> || std::is_enum_v<std::remove_const_t<std::remove_reference_t<Type>>>) {
  58739. if(const auto &from = fetch_node(); from.conversion_helper) {
  58740. return meta_any{*ctx, static_cast<Type>(from.conversion_helper(nullptr, storage.data()))};
  58741. }
  58742. }
  58743. if(const auto &from = fetch_node(); from.details != nullptr) {
  58744. if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, entt::type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()); elem != nullptr) {
  58745. return elem->conv(*ctx, storage.data());
  58746. }
  58747. for(auto &&curr: from.details->base) {
  58748. if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == entt::type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()) {
  58749. return other;
  58750. } else if(auto from_base = std::as_const(other).template allow_cast<Type>(); from_base) {
  58751. return from_base;
  58752. }
  58753. }
  58754. }
  58755. }
  58756. }
  58757. return meta_any{meta_ctx_arg, *ctx};
  58758. }
  58759. /**
  58760. * @brief Converts an object in such a way that a given cast becomes viable.
  58761. * @tparam Type Type to which the cast is requested.
  58762. * @return True if convertible, false otherwise.
  58763. */
  58764. template<typename Type>
  58765. [[nodiscard]] bool allow_cast() {
  58766. if constexpr(std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>) {
  58767. return allow_cast<const std::remove_reference_t<Type> &>() && (storage.policy() != any_policy::cref);
  58768. } else {
  58769. if(storage.has_value<std::remove_const_t<std::remove_reference_t<Type>>>()) {
  58770. return true;
  58771. } else if(auto other = std::as_const(*this).allow_cast<std::remove_const_t<std::remove_reference_t<Type>>>(); other) {
  58772. if(other.storage.owner()) {
  58773. std::swap(*this, other);
  58774. }
  58775. return true;
  58776. }
  58777. return false;
  58778. }
  58779. }
  58780. /*! @copydoc any::emplace */
  58781. template<typename Type, typename... Args>
  58782. void emplace(Args &&...args) {
  58783. storage.emplace<Type>(std::forward<Args>(args)...);
  58784. auto *prev = std::exchange(vtable, &basic_vtable<std::remove_const_t<std::remove_reference_t<Type>>>);
  58785. node = (prev == vtable) ? node : nullptr;
  58786. }
  58787. /*! @copydoc any::assign */
  58788. bool assign(const meta_any &other);
  58789. /*! @copydoc any::assign */
  58790. bool assign(meta_any &&other);
  58791. /*! @copydoc any::reset */
  58792. void reset() {
  58793. storage.reset();
  58794. node = nullptr;
  58795. vtable = nullptr;
  58796. }
  58797. /**
  58798. * @brief Returns a sequence container proxy.
  58799. * @return A sequence container proxy for the underlying object.
  58800. */
  58801. [[nodiscard]] meta_sequence_container as_sequence_container() noexcept {
  58802. meta_sequence_container proxy{};
  58803. if(*this) { vtable(internal::meta_traits::is_sequence_container, *this, &proxy); }
  58804. return proxy;
  58805. }
  58806. /*! @copydoc as_sequence_container */
  58807. [[nodiscard]] meta_sequence_container as_sequence_container() const noexcept {
  58808. meta_sequence_container proxy{};
  58809. if(*this) { vtable(internal::meta_traits::is_sequence_container | internal::meta_traits::is_const, *this, &proxy); }
  58810. return proxy;
  58811. }
  58812. /**
  58813. * @brief Returns an associative container proxy.
  58814. * @return An associative container proxy for the underlying object.
  58815. */
  58816. [[nodiscard]] meta_associative_container as_associative_container() noexcept {
  58817. meta_associative_container proxy{};
  58818. if(*this) { vtable(internal::meta_traits::is_associative_container, *this, &proxy); }
  58819. return proxy;
  58820. }
  58821. /*! @copydoc as_associative_container */
  58822. [[nodiscard]] meta_associative_container as_associative_container() const noexcept {
  58823. meta_associative_container proxy{};
  58824. if(*this) { vtable(internal::meta_traits::is_associative_container | internal::meta_traits::is_const, *this, &proxy); }
  58825. return proxy;
  58826. }
  58827. /**
  58828. * @brief Indirection operator for dereferencing opaque objects.
  58829. * @return A wrapper that shares a reference to an unmanaged object if the
  58830. * wrapped element is dereferenceable, an invalid meta any otherwise.
  58831. */
  58832. [[nodiscard]] meta_any operator*() const noexcept {
  58833. meta_any ret{meta_ctx_arg, *ctx};
  58834. if(*this) { vtable(internal::meta_traits::is_pointer_like, ret, storage.data()); }
  58835. return ret;
  58836. }
  58837. /*! @copydoc any::operator bool */
  58838. [[nodiscard]] explicit operator bool() const noexcept {
  58839. return !(vtable == nullptr);
  58840. }
  58841. /*! @copydoc any::operator== */
  58842. [[nodiscard]] bool operator==(const meta_any &other) const noexcept {
  58843. return (ctx == other.ctx) && (!*this == !other) && (storage == other.storage);
  58844. }
  58845. /*! @copydoc any::operator!= */
  58846. [[nodiscard]] bool operator!=(const meta_any &other) const noexcept {
  58847. return !(*this == other);
  58848. }
  58849. /*! @copydoc any::as_ref */
  58850. [[nodiscard]] meta_any as_ref() noexcept {
  58851. return meta_any{*this, storage.as_ref()};
  58852. }
  58853. /*! @copydoc any::as_ref */
  58854. [[nodiscard]] meta_any as_ref() const noexcept {
  58855. return meta_any{*this, storage.as_ref()};
  58856. }
  58857. /**
  58858. * @brief Returns the underlying storage.
  58859. * @return The underlyig storage.
  58860. */
  58861. [[nodiscard]] const any &base() const noexcept {
  58862. return storage;
  58863. }
  58864. /**
  58865. * @brief Returns the underlying meta context.
  58866. * @return The underlying meta context.
  58867. */
  58868. [[nodiscard]] const meta_ctx &context() const noexcept {
  58869. return *ctx;
  58870. }
  58871. private:
  58872. any storage{};
  58873. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  58874. mutable const internal::meta_type_node *node{};
  58875. vtable_type *vtable{};
  58876. };
  58877. /**
  58878. * @brief Forwards its argument and avoids copies for lvalue references.
  58879. * @tparam Type Type of argument to use to construct the new instance.
  58880. * @param value Parameter to use to construct the instance.
  58881. * @param ctx The context from which to search for meta types.
  58882. * @return A properly initialized and not necessarily owning wrapper.
  58883. */
  58884. template<typename Type>
  58885. [[nodiscard]] meta_any forward_as_meta(const meta_ctx &ctx, Type &&value) {
  58886. return meta_any{ctx, std::in_place_type<Type &&>, std::forward<Type>(value)};
  58887. }
  58888. /**
  58889. * @brief Forwards its argument and avoids copies for lvalue references.
  58890. * @tparam Type Type of argument to use to construct the new instance.
  58891. * @param value Parameter to use to construct the instance.
  58892. * @return A properly initialized and not necessarily owning wrapper.
  58893. */
  58894. template<typename Type>
  58895. [[nodiscard]] meta_any forward_as_meta(Type &&value) {
  58896. return forward_as_meta(locator<meta_ctx>::value_or(), std::forward<Type>(value));
  58897. }
  58898. /*! @brief Opaque pointers to instances of any type. */
  58899. class meta_handle {
  58900. template<typename Type, typename... Args, typename = std::enable_if_t<std::is_same_v<std::decay_t<Type>, meta_any>>>
  58901. meta_handle(int, Type &value, Args &&...args)
  58902. : any{std::forward<Args>(args)..., value.as_ref()} {}
  58903. template<typename Type, typename... Args>
  58904. meta_handle(char, Type &value, Args &&...args)
  58905. : any{std::forward<Args>(args)..., std::in_place_type<Type &>, value} {}
  58906. public:
  58907. /*! Default constructor. */
  58908. meta_handle() = default;
  58909. /**
  58910. * @brief Creates a handle that points to an unmanaged object.
  58911. * @tparam Type Type of object to use to initialize the handle.
  58912. * @param ctx The context from which to search for meta types.
  58913. * @param value An instance of an object to use to initialize the handle.
  58914. */
  58915. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
  58916. meta_handle(const meta_ctx &ctx, Type &value)
  58917. : meta_handle{0, value, ctx} {}
  58918. /**
  58919. * @brief Creates a handle that points to an unmanaged object.
  58920. * @tparam Type Type of object to use to initialize the handle.
  58921. * @param value An instance of an object to use to initialize the handle.
  58922. */
  58923. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, meta_handle>>>
  58924. meta_handle(Type &value)
  58925. : meta_handle{0, value} {}
  58926. /**
  58927. * @brief Context aware move constructor.
  58928. * @param area The context from which to search for meta types.
  58929. * @param other The instance to move from.
  58930. */
  58931. meta_handle(const meta_ctx &area, meta_handle &&other)
  58932. : any{area, std::move(other.any)} {}
  58933. /*! @brief Default copy constructor, deleted on purpose. */
  58934. meta_handle(const meta_handle &) = delete;
  58935. /*! @brief Default move constructor. */
  58936. meta_handle(meta_handle &&) = default;
  58937. /*! @brief Default destructor. */
  58938. ~meta_handle() = default;
  58939. /**
  58940. * @brief Default copy assignment operator, deleted on purpose.
  58941. * @return This meta handle.
  58942. */
  58943. meta_handle &operator=(const meta_handle &) = delete;
  58944. /**
  58945. * @brief Default move assignment operator.
  58946. * @return This meta handle.
  58947. */
  58948. meta_handle &operator=(meta_handle &&) = default;
  58949. /**
  58950. * @brief Returns false if a handle is invalid, true otherwise.
  58951. * @return False if the handle is invalid, true otherwise.
  58952. */
  58953. [[nodiscard]] explicit operator bool() const noexcept {
  58954. return static_cast<bool>(any);
  58955. }
  58956. /**
  58957. * @brief Access operator for accessing the contained opaque object.
  58958. * @return A wrapper that shares a reference to an unmanaged object.
  58959. */
  58960. [[nodiscard]] meta_any *operator->() {
  58961. return &any;
  58962. }
  58963. /*! @copydoc operator-> */
  58964. [[deprecated("do not use const handles")]] [[nodiscard]] const meta_any *operator->() const {
  58965. return &any;
  58966. }
  58967. private:
  58968. meta_any any{};
  58969. };
  58970. /*! @brief Opaque wrapper for user defined data of any type. */
  58971. struct meta_custom {
  58972. /*! @brief Default constructor. */
  58973. meta_custom() noexcept = default;
  58974. /**
  58975. * @brief Basic constructor for meta objects.
  58976. * @param curr The underlying node with which to construct the instance.
  58977. */
  58978. meta_custom(const internal::meta_custom_node &curr) noexcept
  58979. : node{&curr} {}
  58980. /**
  58981. * @brief Generic conversion operator.
  58982. * @tparam Type Type to which conversion is requested.
  58983. */
  58984. template<typename Type>
  58985. [[nodiscard]] operator Type *() const noexcept {
  58986. return ((node != nullptr) && (type_hash<std::remove_const_t<Type>>::value() == node->type)) ? static_cast<Type *>(node->value.get()) : nullptr;
  58987. }
  58988. /**
  58989. * @brief Generic conversion operator.
  58990. * @tparam Type Type to which conversion is requested.
  58991. */
  58992. template<typename Type>
  58993. [[nodiscard]] operator Type &() const noexcept {
  58994. ENTT_ASSERT(static_cast<Type *>(*this) != nullptr, "Invalid type");
  58995. return *static_cast<Type *>(node->value.get());
  58996. }
  58997. private:
  58998. const internal::meta_custom_node *node{};
  58999. };
  59000. /*! @brief Opaque wrapper for data members. */
  59001. class meta_data {
  59002. [[nodiscard]] auto &node_or_assert() const noexcept {
  59003. ENTT_ASSERT(node != nullptr, "Invalid pointer to node");
  59004. return *node;
  59005. }
  59006. public:
  59007. /*! @brief Unsigned integer type. */
  59008. using size_type = typename internal::meta_data_node::size_type;
  59009. /*! @brief Default constructor. */
  59010. meta_data() noexcept = default;
  59011. /**
  59012. * @brief Context aware constructor for meta objects.
  59013. * @param area The context from which to search for meta types.
  59014. * @param curr The underlying node with which to construct the instance.
  59015. */
  59016. meta_data(const meta_ctx &area, const internal::meta_data_node &curr) noexcept
  59017. : node{&curr},
  59018. ctx{&area} {}
  59019. /**
  59020. * @brief Returns the name assigned to a data member, if any.
  59021. * @return The name assigned to the data member, if any.
  59022. */
  59023. [[nodiscard]] const char *name() const noexcept {
  59024. return node_or_assert().name;
  59025. }
  59026. /**
  59027. * @brief Returns the number of setters available.
  59028. * @return The number of setters available.
  59029. */
  59030. [[nodiscard]] size_type arity() const noexcept {
  59031. return node_or_assert().arity;
  59032. }
  59033. /**
  59034. * @brief Indicates whether a data member is constant or not.
  59035. * @return True if the data member is constant, false otherwise.
  59036. */
  59037. [[nodiscard]] bool is_const() const noexcept {
  59038. return !!(node_or_assert().traits & internal::meta_traits::is_const);
  59039. }
  59040. /**
  59041. * @brief Indicates whether a data member is static or not.
  59042. * @return True if the data member is static, false otherwise.
  59043. */
  59044. [[nodiscard]] bool is_static() const noexcept {
  59045. return !!(node_or_assert().traits & internal::meta_traits::is_static);
  59046. }
  59047. /*! @copydoc meta_any::type */
  59048. [[nodiscard]] inline meta_type type() const noexcept;
  59049. /**
  59050. * @brief Sets the value of a given variable.
  59051. * @tparam Instance Type of instance to operate on.
  59052. * @tparam Type Type of value to assign.
  59053. * @param instance An instance that fits the underlying type.
  59054. * @param value Parameter to use to set the underlying variable.
  59055. * @return True in case of success, false otherwise.
  59056. */
  59057. template<typename Instance = meta_handle, typename Type>
  59058. // NOLINTNEXTLINE(modernize-use-nodiscard)
  59059. bool set(Instance &&instance, Type &&value) const {
  59060. return node_or_assert().set(meta_handle{*ctx, std::forward<Instance>(instance)}, meta_any{*ctx, std::forward<Type>(value)});
  59061. }
  59062. /**
  59063. * @brief Gets the value of a given variable.
  59064. * @tparam Instance Type of instance to operate on.
  59065. * @param instance An instance that fits the underlying type.
  59066. * @return A wrapper containing the value of the underlying variable.
  59067. */
  59068. template<typename Instance = meta_handle>
  59069. [[nodiscard]] meta_any get(Instance &&instance) const {
  59070. return node_or_assert().get(meta_handle{*ctx, std::forward<Instance>(instance)});
  59071. }
  59072. /**
  59073. * @brief Returns the type accepted by the i-th setter.
  59074. * @param index Index of the setter of which to return the accepted type.
  59075. * @return The type accepted by the i-th setter.
  59076. */
  59077. [[nodiscard]] inline meta_type arg(size_type index) const noexcept;
  59078. /**
  59079. * @brief Returns all meta traits for a given meta object.
  59080. * @tparam Type The type to convert the meta traits to.
  59081. * @return The registered meta traits, if any.
  59082. */
  59083. template<typename Type>
  59084. [[nodiscard]] Type traits() const noexcept {
  59085. return internal::meta_to_user_traits<Type>(node_or_assert().traits);
  59086. }
  59087. /**
  59088. * @brief Returns user defined data for a given meta object.
  59089. * @return User defined arbitrary data.
  59090. */
  59091. [[nodiscard]] meta_custom custom() const noexcept {
  59092. return {node_or_assert().custom};
  59093. }
  59094. /**
  59095. * @brief Returns true if an object is valid, false otherwise.
  59096. * @return True if the object is valid, false otherwise.
  59097. */
  59098. [[nodiscard]] explicit operator bool() const noexcept {
  59099. return (node != nullptr);
  59100. }
  59101. /**
  59102. * @brief Checks if two objects refer to the same type.
  59103. * @param other The object with which to compare.
  59104. * @return True if the objects refer to the same type, false otherwise.
  59105. */
  59106. [[nodiscard]] bool operator==(const meta_data &other) const noexcept {
  59107. return (ctx == other.ctx) && (node == other.node);
  59108. }
  59109. private:
  59110. const internal::meta_data_node *node{};
  59111. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  59112. };
  59113. /**
  59114. * @brief Checks if two objects refer to the same type.
  59115. * @param lhs An object, either valid or not.
  59116. * @param rhs An object, either valid or not.
  59117. * @return False if the objects refer to the same node, true otherwise.
  59118. */
  59119. [[nodiscard]] inline bool operator!=(const meta_data &lhs, const meta_data &rhs) noexcept {
  59120. return !(lhs == rhs);
  59121. }
  59122. /*! @brief Opaque wrapper for member functions. */
  59123. class meta_func {
  59124. [[nodiscard]] auto &node_or_assert() const noexcept {
  59125. ENTT_ASSERT(node != nullptr, "Invalid pointer to node");
  59126. return *node;
  59127. }
  59128. public:
  59129. /*! @brief Unsigned integer type. */
  59130. using size_type = typename internal::meta_func_node::size_type;
  59131. /*! @brief Default constructor. */
  59132. meta_func() noexcept = default;
  59133. /**
  59134. * @brief Context aware constructor for meta objects.
  59135. * @param area The context from which to search for meta types.
  59136. * @param curr The underlying node with which to construct the instance.
  59137. */
  59138. meta_func(const meta_ctx &area, const internal::meta_func_node &curr) noexcept
  59139. : node{&curr},
  59140. ctx{&area} {}
  59141. /**
  59142. * @brief Returns the name assigned to a member function, if any.
  59143. * @return The name assigned to the member function, if any.
  59144. */
  59145. [[nodiscard]] const char *name() const noexcept {
  59146. return node_or_assert().name;
  59147. }
  59148. /**
  59149. * @brief Returns the number of arguments accepted by a member function.
  59150. * @return The number of arguments accepted by the member function.
  59151. */
  59152. [[nodiscard]] size_type arity() const noexcept {
  59153. return node_or_assert().arity;
  59154. }
  59155. /**
  59156. * @brief Indicates whether a member function is constant or not.
  59157. * @return True if the member function is constant, false otherwise.
  59158. */
  59159. [[nodiscard]] bool is_const() const noexcept {
  59160. return !!(node_or_assert().traits & internal::meta_traits::is_const);
  59161. }
  59162. /**
  59163. * @brief Indicates whether a member function is static or not.
  59164. * @return True if the member function is static, false otherwise.
  59165. */
  59166. [[nodiscard]] bool is_static() const noexcept {
  59167. return !!(node_or_assert().traits & internal::meta_traits::is_static);
  59168. }
  59169. /**
  59170. * @brief Returns the return type of a member function.
  59171. * @return The return type of the member function.
  59172. */
  59173. [[nodiscard]] inline meta_type ret() const noexcept;
  59174. /**
  59175. * @brief Returns the type of the i-th argument of a member function.
  59176. * @param index Index of the argument of which to return the type.
  59177. * @return The type of the i-th argument of a member function.
  59178. */
  59179. [[nodiscard]] inline meta_type arg(size_type index) const noexcept;
  59180. /**
  59181. * @brief Invokes the underlying function, if possible.
  59182. * @tparam Instance Type of instance to operate on.
  59183. * @param instance An instance that fits the underlying type.
  59184. * @param args Parameters to use to invoke the function.
  59185. * @param sz Number of parameters to use to invoke the function.
  59186. * @return A wrapper containing the returned value, if any.
  59187. */
  59188. template<typename Instance = meta_handle>
  59189. meta_any invoke(Instance &&instance, meta_any *const args, const size_type sz) const {
  59190. return (sz == arity()) ? node_or_assert().invoke(meta_handle{*ctx, std::forward<Instance>(instance)}, args) : meta_any{meta_ctx_arg, *ctx};
  59191. }
  59192. /**
  59193. * @copybrief invoke
  59194. * @tparam Instance Type of instance to operate on.
  59195. * @tparam Args Types of arguments to use to invoke the function.
  59196. * @param instance An instance that fits the underlying type.
  59197. * @param args Parameters to use to invoke the function.
  59198. * @return A wrapper containing the returned value, if any.
  59199. */
  59200. template<typename Instance = meta_handle, typename... Args>
  59201. // NOLINTNEXTLINE(modernize-use-nodiscard)
  59202. meta_any invoke(Instance &&instance, Args &&...args) const {
  59203. return invoke(std::forward<Instance>(instance), std::array<meta_any, sizeof...(Args)>{meta_any{*ctx, std::forward<Args>(args)}...}.data(), sizeof...(Args));
  59204. }
  59205. /*! @copydoc meta_data::traits */
  59206. template<typename Type>
  59207. [[nodiscard]] Type traits() const noexcept {
  59208. return internal::meta_to_user_traits<Type>(node_or_assert().traits);
  59209. }
  59210. /*! @copydoc meta_data::custom */
  59211. [[nodiscard]] meta_custom custom() const noexcept {
  59212. return {node_or_assert().custom};
  59213. }
  59214. /**
  59215. * @brief Returns the next overload of a given function, if any.
  59216. * @return The next overload of the given function, if any.
  59217. */
  59218. [[nodiscard]] meta_func next() const {
  59219. return (node_or_assert().next != nullptr) ? meta_func{*ctx, *node_or_assert().next} : meta_func{};
  59220. }
  59221. /*! @copydoc meta_data::operator bool */
  59222. [[nodiscard]] explicit operator bool() const noexcept {
  59223. return (node != nullptr);
  59224. }
  59225. /*! @copydoc meta_data::operator== */
  59226. [[nodiscard]] bool operator==(const meta_func &other) const noexcept {
  59227. return (ctx == other.ctx) && (node == other.node);
  59228. }
  59229. private:
  59230. const internal::meta_func_node *node{};
  59231. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  59232. };
  59233. /*! @copydoc operator!=(const meta_data &, const meta_data &) */
  59234. [[nodiscard]] inline bool operator!=(const meta_func &lhs, const meta_func &rhs) noexcept {
  59235. return !(lhs == rhs);
  59236. }
  59237. /*! @brief Opaque wrapper for types. */
  59238. class meta_type {
  59239. [[nodiscard]] const auto &fetch_node() const {
  59240. return (node == nullptr) ? internal::resolve<void>(internal::meta_context::from(*ctx)) : *node;
  59241. }
  59242. template<typename Func>
  59243. [[nodiscard]] auto lookup(meta_any *const args, const typename internal::meta_type_node::size_type sz, [[maybe_unused]] bool constness, Func next) const {
  59244. decltype(next()) candidate = nullptr;
  59245. size_type same{};
  59246. bool ambiguous{};
  59247. for(auto curr = next(); curr; curr = next()) {
  59248. if constexpr(std::is_same_v<std::decay_t<decltype(*curr)>, internal::meta_func_node>) {
  59249. if(constness && !(curr->traits & internal::meta_traits::is_const)) {
  59250. continue;
  59251. }
  59252. }
  59253. if(curr->arity == sz) {
  59254. size_type match{};
  59255. size_type pos{};
  59256. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  59257. for(; pos < sz && args[pos]; ++pos) {
  59258. const auto other = curr->arg(*ctx, pos);
  59259. const auto type = args[pos].type();
  59260. if(const auto &info = other.info(); info == type.info()) {
  59261. ++match;
  59262. } else if(!(type.fetch_node().conversion_helper && other.fetch_node().conversion_helper) && !(type.fetch_node().details && (internal::find_member<&internal::meta_base_node::type>(type.fetch_node().details->base, info.hash()) || internal::find_member<&internal::meta_conv_node::type>(type.fetch_node().details->conv, info.hash())))) {
  59263. break;
  59264. }
  59265. }
  59266. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  59267. if(pos == sz) {
  59268. if(!candidate || match > same) {
  59269. candidate = curr;
  59270. same = match;
  59271. ambiguous = false;
  59272. } else if(match == same) {
  59273. if constexpr(std::is_same_v<std::decay_t<decltype(*curr)>, internal::meta_func_node>) {
  59274. if(!!(curr->traits & internal::meta_traits::is_const) != !!(candidate->traits & internal::meta_traits::is_const)) {
  59275. candidate = !!(candidate->traits & internal::meta_traits::is_const) ? curr : candidate;
  59276. ambiguous = false;
  59277. continue;
  59278. }
  59279. }
  59280. ambiguous = true;
  59281. }
  59282. }
  59283. }
  59284. }
  59285. return ambiguous ? nullptr : candidate;
  59286. }
  59287. public:
  59288. /*! @brief Unsigned integer type. */
  59289. using size_type = typename internal::meta_type_node::size_type;
  59290. /*! @brief Default constructor. */
  59291. meta_type() noexcept = default;
  59292. /**
  59293. * @brief Context aware constructor for meta objects.
  59294. * @param area The context from which to search for meta types.
  59295. * @param curr The underlying node with which to construct the instance.
  59296. */
  59297. meta_type(const meta_ctx &area, const internal::meta_type_node &curr) noexcept
  59298. : node{&curr},
  59299. ctx{&area} {}
  59300. /**
  59301. * @brief Context aware constructor for meta objects.
  59302. * @param area The context from which to search for meta types.
  59303. * @param curr The underlying node with which to construct the instance.
  59304. */
  59305. meta_type(const meta_ctx &area, const internal::meta_base_node &curr) noexcept
  59306. : meta_type{area, curr.resolve(internal::meta_context::from(area))} {}
  59307. /**
  59308. * @brief Returns the type info object of the underlying type.
  59309. * @return The type info object of the underlying type.
  59310. */
  59311. [[nodiscard]] const type_info &info() const noexcept {
  59312. return *fetch_node().info;
  59313. }
  59314. /**
  59315. * @brief Returns the identifier assigned to a type.
  59316. * @return The identifier assigned to the type.
  59317. */
  59318. [[nodiscard]] id_type id() const noexcept {
  59319. return fetch_node().id;
  59320. }
  59321. /**
  59322. * @brief Returns the name assigned to a type, if any.
  59323. * @return The name assigned to the type, if any.
  59324. */
  59325. [[nodiscard]] const char *name() const noexcept {
  59326. return fetch_node().name;
  59327. }
  59328. /**
  59329. * @brief Returns the size of the underlying type if known.
  59330. * @return The size of the underlying type if known, 0 otherwise.
  59331. */
  59332. [[nodiscard]] size_type size_of() const noexcept {
  59333. return fetch_node().size_of;
  59334. }
  59335. /**
  59336. * @brief Checks whether a type refers to an arithmetic type or not.
  59337. * @return True if the underlying type is an arithmetic type, false
  59338. * otherwise.
  59339. */
  59340. [[nodiscard]] bool is_arithmetic() const noexcept {
  59341. return !!(fetch_node().traits & internal::meta_traits::is_arithmetic);
  59342. }
  59343. /**
  59344. * @brief Checks whether a type refers to an integral type or not.
  59345. * @return True if the underlying type is an integral type, false otherwise.
  59346. */
  59347. [[nodiscard]] bool is_integral() const noexcept {
  59348. return !!(fetch_node().traits & internal::meta_traits::is_integral);
  59349. }
  59350. /**
  59351. * @brief Checks whether a type refers to a signed type or not.
  59352. * @return True if the underlying type is a signed type, false otherwise.
  59353. */
  59354. [[nodiscard]] bool is_signed() const noexcept {
  59355. return !!(fetch_node().traits & internal::meta_traits::is_signed);
  59356. }
  59357. /**
  59358. * @brief Checks whether a type refers to an array type or not.
  59359. * @return True if the underlying type is an array type, false otherwise.
  59360. */
  59361. [[nodiscard]] bool is_array() const noexcept {
  59362. return !!(fetch_node().traits & internal::meta_traits::is_array);
  59363. }
  59364. /**
  59365. * @brief Checks whether a type refers to an enum or not.
  59366. * @return True if the underlying type is an enum, false otherwise.
  59367. */
  59368. [[nodiscard]] bool is_enum() const noexcept {
  59369. return !!(fetch_node().traits & internal::meta_traits::is_enum);
  59370. }
  59371. /**
  59372. * @brief Checks whether a type refers to a class or not.
  59373. * @return True if the underlying type is a class, false otherwise.
  59374. */
  59375. [[nodiscard]] bool is_class() const noexcept {
  59376. return !!(fetch_node().traits & internal::meta_traits::is_class);
  59377. }
  59378. /**
  59379. * @brief Checks whether a type refers to a pointer or not.
  59380. * @return True if the underlying type is a pointer, false otherwise.
  59381. */
  59382. [[nodiscard]] bool is_pointer() const noexcept {
  59383. return !!(fetch_node().traits & internal::meta_traits::is_pointer);
  59384. }
  59385. /**
  59386. * @brief Provides the type for which the pointer is defined.
  59387. * @return The type for which the pointer is defined or this type if it
  59388. * doesn't refer to a pointer type.
  59389. */
  59390. [[nodiscard]] meta_type remove_pointer() const noexcept {
  59391. return meta_type{*ctx, fetch_node().remove_pointer(internal::meta_context::from(*ctx))};
  59392. }
  59393. /**
  59394. * @brief Checks whether a type is a pointer-like type or not.
  59395. * @return True if the underlying type is pointer-like, false otherwise.
  59396. */
  59397. [[nodiscard]] bool is_pointer_like() const noexcept {
  59398. return !!(fetch_node().traits & internal::meta_traits::is_pointer_like);
  59399. }
  59400. /**
  59401. * @brief Checks whether a type refers to a sequence container or not.
  59402. * @return True if the type is a sequence container, false otherwise.
  59403. */
  59404. [[nodiscard]] bool is_sequence_container() const noexcept {
  59405. return !!(fetch_node().traits & internal::meta_traits::is_sequence_container);
  59406. }
  59407. /**
  59408. * @brief Checks whether a type refers to an associative container or not.
  59409. * @return True if the type is an associative container, false otherwise.
  59410. */
  59411. [[nodiscard]] bool is_associative_container() const noexcept {
  59412. return !!(fetch_node().traits & internal::meta_traits::is_associative_container);
  59413. }
  59414. /**
  59415. * @brief Checks whether a type refers to a template specialization or not.
  59416. * @return True if the type is a template specialization, false otherwise.
  59417. */
  59418. [[nodiscard]] bool is_template_specialization() const noexcept {
  59419. return (fetch_node().templ.arity != 0u);
  59420. }
  59421. /**
  59422. * @brief Returns the number of template arguments.
  59423. * @return The number of template arguments.
  59424. */
  59425. [[nodiscard]] size_type template_arity() const noexcept {
  59426. return fetch_node().templ.arity;
  59427. }
  59428. /**
  59429. * @brief Returns a tag for the class template of the underlying type.
  59430. * @return The tag for the class template of the underlying type.
  59431. */
  59432. [[nodiscard]] meta_type template_type() const noexcept {
  59433. return (fetch_node().templ.resolve != nullptr) ? meta_type{*ctx, fetch_node().templ.resolve(internal::meta_context::from(*ctx))} : meta_type{};
  59434. }
  59435. /**
  59436. * @brief Returns the type of the i-th template argument of a type.
  59437. * @param index Index of the template argument of which to return the type.
  59438. * @return The type of the i-th template argument of a type.
  59439. */
  59440. [[nodiscard]] meta_type template_arg(const size_type index) const noexcept {
  59441. return index < template_arity() ? meta_type{*ctx, fetch_node().templ.arg(internal::meta_context::from(*ctx), index)} : meta_type{};
  59442. }
  59443. /**
  59444. * @brief Checks if a type supports direct casting to another type.
  59445. * @param other The meta type to test for.
  59446. * @return True if direct casting is allowed, false otherwise.
  59447. */
  59448. [[nodiscard]] bool can_cast(const meta_type &other) const noexcept {
  59449. // casting this is UB in all cases but we aren't going to use the resulting pointer, so...
  59450. return other && ((*this == other) || (internal::try_cast(internal::meta_context::from(*ctx), fetch_node(), other.fetch_node().info->hash(), this) != nullptr));
  59451. }
  59452. /**
  59453. * @brief Checks whether a type supports conversion to another type.
  59454. * @param other The meta type to test for.
  59455. * @return True if the conversion is allowed, false otherwise.
  59456. */
  59457. [[nodiscard]] bool can_convert(const meta_type &other) const noexcept {
  59458. if(const auto &to = other.info().hash(); (info().hash() == to) || ((fetch_node().conversion_helper != nullptr) && (other.is_arithmetic() || other.is_enum()))) {
  59459. return true;
  59460. } else if(const auto &from = fetch_node(); from.details) {
  59461. if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, to); elem != nullptr) {
  59462. return true;
  59463. }
  59464. for(auto &&curr: from.details->base) {
  59465. if(curr.type == to || meta_type{*ctx, curr.resolve(internal::meta_context::from(*ctx))}.can_convert(other)) {
  59466. return true;
  59467. }
  59468. }
  59469. }
  59470. return false;
  59471. }
  59472. /**
  59473. * @brief Returns a range to visit registered top-level base meta types.
  59474. * @return An iterable range to visit registered top-level base meta types.
  59475. */
  59476. [[nodiscard]] meta_range<meta_type, typename decltype(internal::meta_type_descriptor::base)::const_iterator> base() const noexcept {
  59477. using range_type = meta_range<meta_type, typename decltype(internal::meta_type_descriptor::base)::const_iterator>;
  59478. return fetch_node().details ? range_type{{*ctx, fetch_node().details->base.cbegin()}, {*ctx, fetch_node().details->base.cend()}} : range_type{};
  59479. }
  59480. /**
  59481. * @brief Returns a range to visit registered top-level meta data.
  59482. * @return An iterable range to visit registered top-level meta data.
  59483. */
  59484. [[nodiscard]] meta_range<meta_data, typename decltype(internal::meta_type_descriptor::data)::const_iterator> data() const noexcept {
  59485. using range_type = meta_range<meta_data, typename decltype(internal::meta_type_descriptor::data)::const_iterator>;
  59486. return fetch_node().details ? range_type{{*ctx, fetch_node().details->data.cbegin()}, {*ctx, fetch_node().details->data.cend()}} : range_type{};
  59487. }
  59488. /**
  59489. * @brief Lookup utility for meta data (bases are also visited).
  59490. * @param id Unique identifier.
  59491. * @param recursive True for a search in the base classes, false otherwise.
  59492. * @return The registered meta data for the given identifier, if any.
  59493. */
  59494. [[nodiscard]] meta_data data(const id_type id, const bool recursive = true) const {
  59495. const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
  59496. return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{};
  59497. }
  59498. /**
  59499. * @brief Returns a range to visit registered top-level functions.
  59500. * @return An iterable range to visit registered top-level functions.
  59501. */
  59502. [[nodiscard]] meta_range<meta_func, typename decltype(internal::meta_type_descriptor::func)::const_iterator> func() const noexcept {
  59503. using return_type = meta_range<meta_func, typename decltype(internal::meta_type_descriptor::func)::const_iterator>;
  59504. return fetch_node().details ? return_type{{*ctx, fetch_node().details->func.cbegin()}, {*ctx, fetch_node().details->func.cend()}} : return_type{};
  59505. }
  59506. /**
  59507. * @brief Lookup utility for meta functions (bases are also visited).
  59508. * @param id Unique identifier.
  59509. * @param recursive True for a search in the base classes, false otherwise.
  59510. * @return The registered meta function for the given identifier, if any.
  59511. */
  59512. [[nodiscard]] meta_func func(const id_type id, const bool recursive = true) const {
  59513. const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
  59514. return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{};
  59515. }
  59516. /**
  59517. * @brief Creates an instance of the underlying type, if possible.
  59518. * @param args Parameters to use to construct the instance.
  59519. * @param sz Number of parameters to use to construct the instance.
  59520. * @return A wrapper containing the new instance, if any.
  59521. */
  59522. [[nodiscard]] meta_any construct(meta_any *const args, const size_type sz) const {
  59523. if(const auto &ref = fetch_node(); ref.details) {
  59524. if(const auto *candidate = lookup(args, sz, false, [first = ref.details->ctor.cbegin(), last = ref.details->ctor.cend()]() mutable { return first == last ? nullptr : &*(first++); }); candidate) {
  59525. return candidate->invoke(*ctx, args);
  59526. }
  59527. }
  59528. if(const auto &ref = fetch_node(); (sz == 0u) && (ref.default_constructor != nullptr)) {
  59529. return ref.default_constructor(*ctx);
  59530. }
  59531. return meta_any{meta_ctx_arg, *ctx};
  59532. }
  59533. /**
  59534. * @copybrief construct
  59535. * @tparam Args Types of arguments to use to construct the instance.
  59536. * @param args Parameters to use to construct the instance.
  59537. * @return A wrapper containing the new instance, if any.
  59538. */
  59539. template<typename... Args>
  59540. [[nodiscard]] meta_any construct(Args &&...args) const {
  59541. return construct(std::array<meta_any, sizeof...(Args)>{meta_any{*ctx, std::forward<Args>(args)}...}.data(), sizeof...(Args));
  59542. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
  59543. }
  59544. /**
  59545. * @brief Wraps an opaque element of the underlying type.
  59546. * @param elem A valid pointer to an element of the underlying type.
  59547. * @param transfer_ownership True to transfer ownership, false otherwise.
  59548. * @return A wrapper that references the given instance.
  59549. */
  59550. [[nodiscard]] meta_any from_void(void *elem, bool transfer_ownership = false) const {
  59551. return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, elem, transfer_ownership ? elem : nullptr) : meta_any{meta_ctx_arg, *ctx};
  59552. }
  59553. /**
  59554. * @brief Wraps an opaque element of the underlying type.
  59555. * @param elem A valid pointer to an element of the underlying type.
  59556. * @return A wrapper that references the given instance.
  59557. */
  59558. [[nodiscard]] meta_any from_void(const void *elem) const {
  59559. return ((elem != nullptr) && (fetch_node().from_void != nullptr)) ? fetch_node().from_void(*ctx, nullptr, elem) : meta_any{meta_ctx_arg, *ctx};
  59560. }
  59561. /**
  59562. * @brief Invokes a function given an identifier, if possible.
  59563. * @tparam Instance Type of instance to operate on.
  59564. * @param id Unique identifier.
  59565. * @param instance An instance that fits the underlying type.
  59566. * @param args Parameters to use to invoke the function.
  59567. * @param sz Number of parameters to use to invoke the function.
  59568. * @return A wrapper containing the returned value, if any.
  59569. */
  59570. template<typename Instance = meta_handle>
  59571. // NOLINTNEXTLINE(modernize-use-nodiscard)
  59572. meta_any invoke(const id_type id, Instance &&instance, meta_any *const args, const size_type sz) const {
  59573. meta_handle wrapped{*ctx, std::forward<Instance>(instance)};
  59574. if(const auto &ref = fetch_node(); ref.details) {
  59575. if(auto *elem = internal::find_member<&internal::meta_func_node::id>(ref.details->func, id); elem != nullptr) {
  59576. if(const auto *candidate = lookup(args, sz, (wrapped->base().policy() == any_policy::cref), [curr = elem]() mutable { return (curr != nullptr) ? std::exchange(curr, curr->next.get()) : nullptr; }); candidate) {
  59577. return candidate->invoke(std::move(wrapped), args);
  59578. }
  59579. }
  59580. }
  59581. for(auto &&curr: base()) {
  59582. if(auto elem = curr.second.invoke(id, *wrapped.operator->(), args, sz); elem) {
  59583. return elem;
  59584. }
  59585. }
  59586. return meta_any{meta_ctx_arg, *ctx};
  59587. }
  59588. /**
  59589. * @copybrief invoke
  59590. * @param id Unique identifier.
  59591. * @tparam Instance Type of instance to operate on.
  59592. * @tparam Args Types of arguments to use to invoke the function.
  59593. * @param instance An instance that fits the underlying type.
  59594. * @param args Parameters to use to invoke the function.
  59595. * @return A wrapper containing the returned value, if any.
  59596. */
  59597. template<typename Instance = meta_handle, typename... Args>
  59598. // NOLINTNEXTLINE(modernize-use-nodiscard)
  59599. meta_any invoke(const id_type id, Instance &&instance, Args &&...args) const {
  59600. return invoke(id, std::forward<Instance>(instance), std::array<meta_any, sizeof...(Args)>{meta_any{*ctx, std::forward<Args>(args)}...}.data(), sizeof...(Args));
  59601. }
  59602. /**
  59603. * @brief Sets the value of a given variable.
  59604. * @tparam Instance Type of instance to operate on.
  59605. * @tparam Type Type of value to assign.
  59606. * @param id Unique identifier.
  59607. * @param instance An instance that fits the underlying type.
  59608. * @param value Parameter to use to set the underlying variable.
  59609. * @return True in case of success, false otherwise.
  59610. */
  59611. template<typename Instance = meta_handle, typename Type>
  59612. // NOLINTNEXTLINE(modernize-use-nodiscard)
  59613. bool set(const id_type id, Instance &&instance, Type &&value) const {
  59614. const auto candidate = data(id);
  59615. return candidate && candidate.set(std::forward<Instance>(instance), std::forward<Type>(value));
  59616. }
  59617. /**
  59618. * @brief Gets the value of a given variable.
  59619. * @tparam Instance Type of instance to operate on.
  59620. * @param id Unique identifier.
  59621. * @param instance An instance that fits the underlying type.
  59622. * @return A wrapper containing the value of the underlying variable.
  59623. */
  59624. template<typename Instance = meta_handle>
  59625. [[nodiscard]] meta_any get(const id_type id, Instance &&instance) const {
  59626. const auto candidate = data(id);
  59627. return candidate ? candidate.get(std::forward<Instance>(instance)) : meta_any{meta_ctx_arg, *ctx};
  59628. }
  59629. /*! @copydoc meta_data::traits */
  59630. template<typename Type>
  59631. [[nodiscard]] Type traits() const noexcept {
  59632. return internal::meta_to_user_traits<Type>(fetch_node().traits);
  59633. }
  59634. /*! @copydoc meta_data::custom */
  59635. [[nodiscard]] meta_custom custom() const noexcept {
  59636. return fetch_node().custom;
  59637. }
  59638. /*! @copydoc meta_data::operator bool */
  59639. [[nodiscard]] explicit operator bool() const noexcept {
  59640. return (node != nullptr);
  59641. }
  59642. /*! @copydoc meta_data::operator== */
  59643. [[nodiscard]] bool operator==(const meta_type &other) const noexcept {
  59644. return (ctx == other.ctx) && (fetch_node().id == other.fetch_node().id);
  59645. }
  59646. private:
  59647. mutable const internal::meta_type_node *node{};
  59648. const meta_ctx *ctx{&locator<meta_ctx>::value_or()};
  59649. };
  59650. /*! @copydoc operator!=(const meta_data &, const meta_data &) */
  59651. [[nodiscard]] inline bool operator!=(const meta_type &lhs, const meta_type &rhs) noexcept {
  59652. return !(lhs == rhs);
  59653. }
  59654. [[nodiscard]] inline meta_type meta_any::type() const noexcept {
  59655. return *this ? meta_type{*ctx, fetch_node()} : meta_type{};
  59656. }
  59657. template<typename... Args>
  59658. // NOLINTNEXTLINE(modernize-use-nodiscard)
  59659. meta_any meta_any::invoke(const id_type id, Args &&...args) const {
  59660. return type().invoke(id, *this, std::forward<Args>(args)...);
  59661. }
  59662. template<typename... Args>
  59663. meta_any meta_any::invoke(const id_type id, Args &&...args) {
  59664. return type().invoke(id, *this, std::forward<Args>(args)...);
  59665. }
  59666. template<typename Type>
  59667. bool meta_any::set(const id_type id, Type &&value) {
  59668. return type().set(id, *this, std::forward<Type>(value));
  59669. }
  59670. [[nodiscard]] inline meta_any meta_any::get(const id_type id) const {
  59671. return type().get(id, *this);
  59672. }
  59673. [[nodiscard]] inline meta_any meta_any::get(const id_type id) {
  59674. return type().get(id, *this);
  59675. }
  59676. [[nodiscard]] inline meta_any meta_any::allow_cast(const meta_type &type) const {
  59677. if(storage.has_value(type.info())) {
  59678. return as_ref();
  59679. } else if(*this) {
  59680. if(const auto &from = fetch_node(); (from.conversion_helper != nullptr) && (type.is_arithmetic() || type.is_enum())) {
  59681. auto other = type.construct();
  59682. const auto value = from.conversion_helper(nullptr, storage.data());
  59683. other.fetch_node().conversion_helper(other.storage.data(), &value);
  59684. return other;
  59685. }
  59686. if(const auto &from = fetch_node(); from.details) {
  59687. if(const auto *elem = internal::find_member<&internal::meta_conv_node::type>(from.details->conv, type.info().hash()); elem != nullptr) {
  59688. return elem->conv(*ctx, storage.data());
  59689. }
  59690. for(auto &&curr: from.details->base) {
  59691. if(auto other = curr.resolve(internal::meta_context::from(*ctx)).from_void(*ctx, nullptr, curr.cast(storage.data())); curr.type == type.info().hash()) {
  59692. return other;
  59693. } else if(auto from_base = std::as_const(other).allow_cast(type); from_base) {
  59694. return from_base;
  59695. }
  59696. }
  59697. }
  59698. }
  59699. return meta_any{meta_ctx_arg, *ctx};
  59700. }
  59701. [[nodiscard]] inline bool meta_any::allow_cast(const meta_type &type) {
  59702. if(storage.has_value(type.info())) {
  59703. return true;
  59704. } else if(auto other = std::as_const(*this).allow_cast(type); other) {
  59705. if(other.storage.owner()) {
  59706. std::swap(*this, other);
  59707. }
  59708. return true;
  59709. }
  59710. return false;
  59711. }
  59712. inline bool meta_any::assign(const meta_any &other) {
  59713. if(!storage.assign(other.storage)) {
  59714. auto value = other.allow_cast(type());
  59715. return storage.assign(value.storage);
  59716. }
  59717. return true;
  59718. }
  59719. inline bool meta_any::assign(meta_any &&other) {
  59720. return storage.assign(std::move(other.storage)) || storage.assign(std::as_const(other).allow_cast(type()).storage);
  59721. }
  59722. [[nodiscard]] inline meta_type meta_data::type() const noexcept {
  59723. return meta_type{*ctx, node_or_assert().type(internal::meta_context::from(*ctx))};
  59724. }
  59725. [[nodiscard]] inline meta_type meta_data::arg(const size_type index) const noexcept {
  59726. return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{};
  59727. }
  59728. [[nodiscard]] inline meta_type meta_func::ret() const noexcept {
  59729. return meta_type{*ctx, node_or_assert().ret(internal::meta_context::from(*ctx))};
  59730. }
  59731. [[nodiscard]] inline meta_type meta_func::arg(const size_type index) const noexcept {
  59732. return index < arity() ? node_or_assert().arg(*ctx, index) : meta_type{};
  59733. }
  59734. /*! @cond TURN_OFF_DOXYGEN */
  59735. class meta_sequence_container::meta_iterator final {
  59736. using vtable_type = void(const void *, const std::ptrdiff_t, meta_any *);
  59737. template<typename It>
  59738. static void basic_vtable(const void *value, const std::ptrdiff_t offset, meta_any *other) {
  59739. const auto &it = *static_cast<const It *>(value);
  59740. other ? other->emplace<decltype(*it)>(*it) : std::advance(const_cast<It &>(it), offset);
  59741. }
  59742. public:
  59743. using value_type = meta_any;
  59744. using pointer = input_iterator_pointer<value_type>;
  59745. using reference = value_type;
  59746. using difference_type = std::ptrdiff_t;
  59747. using iterator_category = std::input_iterator_tag;
  59748. using iterator_concept = std::bidirectional_iterator_tag;
  59749. meta_iterator() = default;
  59750. template<typename It>
  59751. meta_iterator(const meta_ctx &area, It iter) noexcept
  59752. : ctx{&area},
  59753. vtable{&basic_vtable<It>},
  59754. handle{iter} {}
  59755. meta_iterator &operator++() noexcept {
  59756. return vtable(handle.data(), 1, nullptr), *this;
  59757. }
  59758. meta_iterator operator++(int value) noexcept {
  59759. meta_iterator orig = *this;
  59760. vtable(handle.data(), ++value, nullptr);
  59761. return orig;
  59762. }
  59763. meta_iterator &operator--() noexcept {
  59764. return vtable(handle.data(), -1, nullptr), *this;
  59765. }
  59766. meta_iterator operator--(int value) noexcept {
  59767. meta_iterator orig = *this;
  59768. vtable(handle.data(), --value, nullptr);
  59769. return orig;
  59770. }
  59771. [[nodiscard]] reference operator*() const {
  59772. reference other{meta_ctx_arg, *ctx};
  59773. vtable(handle.data(), 0, &other);
  59774. return other;
  59775. }
  59776. [[nodiscard]] pointer operator->() const {
  59777. return operator*();
  59778. }
  59779. [[nodiscard]] explicit operator bool() const noexcept {
  59780. return (vtable != nullptr);
  59781. }
  59782. [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept {
  59783. return handle == other.handle;
  59784. }
  59785. [[nodiscard]] const any &base() const noexcept {
  59786. return handle;
  59787. }
  59788. private:
  59789. const meta_ctx *ctx{};
  59790. vtable_type *vtable{};
  59791. any handle{};
  59792. };
  59793. [[nodiscard]] inline bool operator!=(const meta_sequence_container::iterator &lhs, const meta_sequence_container::iterator &rhs) noexcept {
  59794. return !(lhs == rhs);
  59795. }
  59796. class meta_associative_container::meta_iterator final {
  59797. using vtable_type = void(const void *, std::pair<meta_any, meta_any> *);
  59798. template<bool KeyOnly, typename It>
  59799. static void basic_vtable(const void *value, std::pair<meta_any, meta_any> *other) {
  59800. if(const auto &it = *static_cast<const It *>(value); other) {
  59801. if constexpr(KeyOnly) {
  59802. other->first.emplace<decltype(*it)>(*it);
  59803. } else {
  59804. other->first.emplace<decltype((it->first))>(it->first);
  59805. other->second.emplace<decltype((it->second))>(it->second);
  59806. }
  59807. } else {
  59808. ++const_cast<It &>(it);
  59809. }
  59810. }
  59811. public:
  59812. using value_type = std::pair<meta_any, meta_any>;
  59813. using pointer = input_iterator_pointer<value_type>;
  59814. using reference = value_type;
  59815. using difference_type = std::ptrdiff_t;
  59816. using iterator_category = std::input_iterator_tag;
  59817. using iterator_concept = std::forward_iterator_tag;
  59818. meta_iterator() = default;
  59819. template<bool KeyOnly, typename It>
  59820. meta_iterator(const meta_ctx &area, std::bool_constant<KeyOnly>, It iter) noexcept
  59821. : ctx{&area},
  59822. vtable{&basic_vtable<KeyOnly, It>},
  59823. handle{iter} {}
  59824. meta_iterator &operator++() noexcept {
  59825. return vtable(handle.data(), nullptr), *this;
  59826. }
  59827. meta_iterator operator++(int) noexcept {
  59828. meta_iterator orig = *this;
  59829. vtable(handle.data(), nullptr);
  59830. return orig;
  59831. }
  59832. [[nodiscard]] reference operator*() const {
  59833. reference other{{meta_ctx_arg, *ctx}, {meta_ctx_arg, *ctx}};
  59834. vtable(handle.data(), &other);
  59835. return other;
  59836. }
  59837. [[nodiscard]] pointer operator->() const {
  59838. return operator*();
  59839. }
  59840. [[nodiscard]] explicit operator bool() const noexcept {
  59841. return (vtable != nullptr);
  59842. }
  59843. [[nodiscard]] bool operator==(const meta_iterator &other) const noexcept {
  59844. return handle == other.handle;
  59845. }
  59846. private:
  59847. const meta_ctx *ctx{};
  59848. vtable_type *vtable{};
  59849. any handle{};
  59850. };
  59851. [[nodiscard]] inline bool operator!=(const meta_associative_container::iterator &lhs, const meta_associative_container::iterator &rhs) noexcept {
  59852. return !(lhs == rhs);
  59853. }
  59854. /*! @endcond */
  59855. /**
  59856. * @brief Returns the meta value type of a container.
  59857. * @return The meta value type of the container.
  59858. */
  59859. [[nodiscard]] inline meta_type meta_sequence_container::value_type() const noexcept {
  59860. return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  59861. }
  59862. /**
  59863. * @brief Returns the size of a container.
  59864. * @return The size of the container.
  59865. */
  59866. [[nodiscard]] inline meta_sequence_container::size_type meta_sequence_container::size() const noexcept {
  59867. return size_fn(data);
  59868. }
  59869. /**
  59870. * @brief Resizes a container to contain a given number of elements.
  59871. * @param sz The new size of the container.
  59872. * @return True in case of success, false otherwise.
  59873. */
  59874. inline bool meta_sequence_container::resize(const size_type sz) {
  59875. return !const_only && resize_fn(const_cast<void *>(data), sz);
  59876. }
  59877. /**
  59878. * @brief Clears the content of a container.
  59879. * @return True in case of success, false otherwise.
  59880. */
  59881. inline bool meta_sequence_container::clear() {
  59882. return !const_only && clear_fn(const_cast<void *>(data));
  59883. }
  59884. /**
  59885. * @brief Reserves storage for at least the given number of elements.
  59886. * @param sz The new capacity of the container.
  59887. * @return True in case of success, false otherwise.
  59888. */
  59889. inline bool meta_sequence_container::reserve(const size_type sz) {
  59890. return !const_only && reserve_fn(const_cast<void *>(data), sz);
  59891. }
  59892. /**
  59893. * @brief Returns an iterator to the first element of a container.
  59894. * @return An iterator to the first element of the container.
  59895. */
  59896. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
  59897. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, false);
  59898. }
  59899. /**
  59900. * @brief Returns an iterator that is past the last element of a container.
  59901. * @return An iterator that is past the last element of the container.
  59902. */
  59903. [[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
  59904. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, true);
  59905. }
  59906. /**
  59907. * @brief Inserts an element at a specified location of a container.
  59908. * @param it Iterator before which the element will be inserted.
  59909. * @param value Element value to insert.
  59910. * @return A possibly invalid iterator to the inserted element.
  59911. */
  59912. inline meta_sequence_container::iterator meta_sequence_container::insert(const iterator &it, meta_any value) {
  59913. // this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
  59914. if(const auto &vtype = value_type_node(internal::meta_context::from(*ctx)); !const_only && (value.allow_cast({*ctx, vtype}) || value.allow_cast({*ctx, const_reference_node(internal::meta_context::from(*ctx))}))) {
  59915. const bool is_value_type = (value.type().info() == *vtype.info);
  59916. return insert_fn(*ctx, const_cast<void *>(data), is_value_type ? value.base().data() : nullptr, is_value_type ? nullptr : value.base().data(), it);
  59917. }
  59918. return iterator{};
  59919. }
  59920. /**
  59921. * @brief Removes a given element from a container.
  59922. * @param it Iterator to the element to remove.
  59923. * @return A possibly invalid iterator following the last removed element.
  59924. */
  59925. inline meta_sequence_container::iterator meta_sequence_container::erase(const iterator &it) {
  59926. return const_only ? iterator{} : erase_fn(*ctx, const_cast<void *>(data), it);
  59927. }
  59928. /**
  59929. * @brief Returns a reference to the element at a given location of a container.
  59930. * @param pos The position of the element to return.
  59931. * @return A reference to the requested element properly wrapped.
  59932. */
  59933. [[nodiscard]] inline meta_any meta_sequence_container::operator[](const size_type pos) {
  59934. auto it = begin();
  59935. it.operator++(static_cast<int>(pos) - 1);
  59936. return *it;
  59937. }
  59938. /**
  59939. * @brief Returns false if a proxy is invalid, true otherwise.
  59940. * @return False if the proxy is invalid, true otherwise.
  59941. */
  59942. [[nodiscard]] inline meta_sequence_container::operator bool() const noexcept {
  59943. return (data != nullptr);
  59944. }
  59945. /**
  59946. * @brief Returns the meta key type of a container.
  59947. * @return The meta key type of the a container.
  59948. */
  59949. [[nodiscard]] inline meta_type meta_associative_container::key_type() const noexcept {
  59950. return (key_type_node != nullptr) ? meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  59951. }
  59952. /**
  59953. * @brief Returns the meta mapped type of a container.
  59954. * @return The meta mapped type of the a container.
  59955. */
  59956. [[nodiscard]] inline meta_type meta_associative_container::mapped_type() const noexcept {
  59957. return (mapped_type_node != nullptr) ? meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  59958. }
  59959. /*! @copydoc meta_sequence_container::value_type */
  59960. [[nodiscard]] inline meta_type meta_associative_container::value_type() const noexcept {
  59961. return (value_type_node != nullptr) ? meta_type{*ctx, value_type_node(internal::meta_context::from(*ctx))} : meta_type{};
  59962. }
  59963. /*! @copydoc meta_sequence_container::size */
  59964. [[nodiscard]] inline meta_associative_container::size_type meta_associative_container::size() const noexcept {
  59965. return size_fn(data);
  59966. }
  59967. /*! @copydoc meta_sequence_container::clear */
  59968. inline bool meta_associative_container::clear() {
  59969. return !const_only && clear_fn(const_cast<void *>(data));
  59970. }
  59971. /*! @copydoc meta_sequence_container::reserve */
  59972. inline bool meta_associative_container::reserve(const size_type sz) {
  59973. return !const_only && reserve_fn(const_cast<void *>(data), sz);
  59974. }
  59975. /*! @copydoc meta_sequence_container::begin */
  59976. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
  59977. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, false);
  59978. }
  59979. /*! @copydoc meta_sequence_container::end */
  59980. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
  59981. return begin_end_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, true);
  59982. }
  59983. /**
  59984. * @brief Inserts a key-only or key/value element into a container.
  59985. * @param key The key of the element to insert.
  59986. * @param value The value of the element to insert, if needed.
  59987. * @return A bool denoting whether the insertion took place.
  59988. */
  59989. inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
  59990. return !const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})
  59991. && ((mapped_type_node == nullptr) || value.allow_cast(meta_type{*ctx, mapped_type_node(internal::meta_context::from(*ctx))}))
  59992. && insert_fn(const_cast<void *>(data), key.base().data(), value.base().data());
  59993. }
  59994. /**
  59995. * @brief Removes the specified element from a container.
  59996. * @param key The key of the element to remove.
  59997. * @return A bool denoting whether the removal took place.
  59998. */
  59999. inline meta_associative_container::size_type meta_associative_container::erase(meta_any key) {
  60000. return (!const_only && key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})) ? erase_fn(const_cast<void *>(data), key.base().data()) : 0u;
  60001. }
  60002. /**
  60003. * @brief Returns an iterator to the element with a given key, if any.
  60004. * @param key The key of the element to search.
  60005. * @return An iterator to the element with the given key, if any.
  60006. */
  60007. [[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
  60008. return key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))}) ? find_fn(*ctx, const_only ? nullptr : const_cast<void *>(data), data, key.base().data()) : iterator{};
  60009. }
  60010. /**
  60011. * @brief Returns false if a proxy is invalid, true otherwise.
  60012. * @return False if the proxy is invalid, true otherwise.
  60013. */
  60014. [[nodiscard]] inline meta_associative_container::operator bool() const noexcept {
  60015. return (data != nullptr);
  60016. }
  60017. } // namespace entt
  60018. #endif
  60019. // #include "meta/node.hpp"
  60020. #ifndef ENTT_META_NODE_HPP
  60021. #define ENTT_META_NODE_HPP
  60022. #include <array>
  60023. #include <cstddef>
  60024. #include <memory>
  60025. #include <type_traits>
  60026. #include <utility>
  60027. #include <vector>
  60028. // #include "../config/config.h"
  60029. // #include "../core/bit.hpp"
  60030. // #include "../core/enum.hpp"
  60031. // #include "../core/fwd.hpp"
  60032. // #include "../core/type_info.hpp"
  60033. // #include "../core/type_traits.hpp"
  60034. // #include "../core/utility.hpp"
  60035. // #include "context.hpp"
  60036. // #include "type_traits.hpp"
  60037. namespace entt {
  60038. class meta_any;
  60039. class meta_type;
  60040. class meta_handle;
  60041. /*! @cond TURN_OFF_DOXYGEN */
  60042. namespace internal {
  60043. enum class meta_traits : std::uint32_t {
  60044. is_none = 0x0000,
  60045. is_const = 0x0001,
  60046. is_static = 0x0002,
  60047. is_arithmetic = 0x0004,
  60048. is_integral = 0x0008,
  60049. is_signed = 0x0010,
  60050. is_array = 0x0020,
  60051. is_enum = 0x0040,
  60052. is_class = 0x0080,
  60053. is_pointer = 0x0100,
  60054. is_pointer_like = 0x0200,
  60055. is_sequence_container = 0x0400,
  60056. is_associative_container = 0x0800,
  60057. _user_defined_traits = 0xFFFF,
  60058. _entt_enum_as_bitmask = 0xFFFF
  60059. };
  60060. template<typename Type>
  60061. [[nodiscard]] auto meta_to_user_traits(const meta_traits traits) noexcept {
  60062. static_assert(std::is_enum_v<Type>, "Invalid enum type");
  60063. constexpr auto shift = popcount(static_cast<std::underlying_type_t<meta_traits>>(meta_traits::_user_defined_traits));
  60064. return Type{static_cast<std::underlying_type_t<Type>>(static_cast<std::underlying_type_t<meta_traits>>(traits) >> shift)};
  60065. }
  60066. template<typename Type>
  60067. [[nodiscard]] auto user_to_meta_traits(const Type value) noexcept {
  60068. static_assert(std::is_enum_v<Type>, "Invalid enum type");
  60069. constexpr auto shift = popcount(static_cast<std::underlying_type_t<meta_traits>>(meta_traits::_user_defined_traits));
  60070. const auto traits = static_cast<std::underlying_type_t<internal::meta_traits>>(static_cast<std::underlying_type_t<Type>>(value));
  60071. ENTT_ASSERT(traits < ((~static_cast<std::underlying_type_t<meta_traits>>(meta_traits::_user_defined_traits)) >> shift), "Invalid traits");
  60072. return meta_traits{traits << shift};
  60073. }
  60074. struct meta_type_node;
  60075. struct meta_custom_node {
  60076. id_type type{};
  60077. std::shared_ptr<void> value{};
  60078. };
  60079. struct meta_base_node {
  60080. id_type type{};
  60081. const meta_type_node &(*resolve)(const meta_context &) noexcept {};
  60082. const void *(*cast)(const void *) noexcept {};
  60083. };
  60084. struct meta_conv_node {
  60085. id_type type{};
  60086. meta_any (*conv)(const meta_ctx &, const void *){};
  60087. };
  60088. struct meta_ctor_node {
  60089. using size_type = std::size_t;
  60090. id_type id{};
  60091. size_type arity{0u};
  60092. meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
  60093. meta_any (*invoke)(const meta_ctx &, meta_any *const){};
  60094. };
  60095. struct meta_data_node {
  60096. using size_type = std::size_t;
  60097. id_type id{};
  60098. const char *name{};
  60099. meta_traits traits{meta_traits::is_none};
  60100. size_type arity{0u};
  60101. const meta_type_node &(*type)(const meta_context &) noexcept {};
  60102. meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
  60103. bool (*set)(meta_handle, meta_any){};
  60104. meta_any (*get)(meta_handle){};
  60105. meta_custom_node custom{};
  60106. };
  60107. struct meta_func_node {
  60108. using size_type = std::size_t;
  60109. id_type id{};
  60110. const char *name{};
  60111. meta_traits traits{meta_traits::is_none};
  60112. size_type arity{0u};
  60113. const meta_type_node &(*ret)(const meta_context &) noexcept {};
  60114. meta_type (*arg)(const meta_ctx &, const size_type) noexcept {};
  60115. meta_any (*invoke)(meta_handle, meta_any *const){};
  60116. std::unique_ptr<meta_func_node> next;
  60117. meta_custom_node custom{};
  60118. };
  60119. struct meta_template_node {
  60120. using size_type = std::size_t;
  60121. size_type arity{0u};
  60122. const meta_type_node &(*resolve)(const meta_context &) noexcept {};
  60123. const meta_type_node &(*arg)(const meta_context &, const size_type) noexcept {};
  60124. };
  60125. struct meta_type_descriptor {
  60126. std::vector<meta_ctor_node> ctor{};
  60127. std::vector<meta_base_node> base{};
  60128. std::vector<meta_conv_node> conv{};
  60129. std::vector<meta_data_node> data{};
  60130. std::vector<meta_func_node> func{};
  60131. };
  60132. struct meta_type_node {
  60133. using size_type = std::size_t;
  60134. const type_info *info{};
  60135. id_type id{};
  60136. const char *name{};
  60137. meta_traits traits{meta_traits::is_none};
  60138. size_type size_of{0u};
  60139. const meta_type_node &(*remove_pointer)(const meta_context &) noexcept {};
  60140. meta_any (*default_constructor)(const meta_ctx &){};
  60141. double (*conversion_helper)(void *, const void *){};
  60142. meta_any (*from_void)(const meta_ctx &, void *, const void *){};
  60143. meta_template_node templ{};
  60144. meta_custom_node custom{};
  60145. std::unique_ptr<meta_type_descriptor> details{};
  60146. };
  60147. template<auto Member, typename Type, typename Value>
  60148. [[nodiscard]] auto *find_member(Type &from, const Value value) {
  60149. for(auto &&elem: from) {
  60150. if((elem.*Member) == value) {
  60151. return &elem;
  60152. }
  60153. }
  60154. return static_cast<typename Type::value_type *>(nullptr);
  60155. }
  60156. [[nodiscard]] inline auto *find_overload(meta_func_node *curr, std::remove_pointer_t<decltype(meta_func_node::invoke)> *const ref) {
  60157. while((curr != nullptr) && (curr->invoke != ref)) { curr = curr->next.get(); }
  60158. return curr;
  60159. }
  60160. template<auto Member>
  60161. [[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id, bool recursive) {
  60162. using value_type = typename std::remove_reference_t<decltype((node.details.get()->*Member))>::value_type;
  60163. if(node.details) {
  60164. if(auto *member = find_member<&value_type::id>((node.details.get()->*Member), id); member != nullptr) {
  60165. return member;
  60166. }
  60167. if(recursive) {
  60168. for(auto &&curr: node.details->base) {
  60169. if(auto *elem = look_for<Member>(context, curr.resolve(context), id, recursive); elem) {
  60170. return elem;
  60171. }
  60172. }
  60173. }
  60174. }
  60175. return static_cast<value_type *>(nullptr);
  60176. }
  60177. template<typename Type>
  60178. const meta_type_node &resolve(const meta_context &) noexcept;
  60179. template<typename... Args>
  60180. [[nodiscard]] const meta_type_node &meta_arg_node(const meta_context &context, type_list<Args...>, const std::size_t index) noexcept {
  60181. using resolve_type = const meta_type_node &(*)(const meta_context &) noexcept;
  60182. constexpr std::array<resolve_type, sizeof...(Args)> list{&resolve<std::remove_const_t<std::remove_reference_t<Args>>>...};
  60183. ENTT_ASSERT(index < sizeof...(Args), "Out of bounds");
  60184. return list[index](context);
  60185. }
  60186. [[nodiscard]] inline const void *try_cast(const meta_context &context, const meta_type_node &from, const id_type to, const void *instance) noexcept {
  60187. if(from.details) {
  60188. for(auto &&curr: from.details->base) {
  60189. if(const void *other = curr.cast(instance); curr.type == to) {
  60190. return other;
  60191. } else if(const void *elem = try_cast(context, curr.resolve(context), to, other); elem) {
  60192. return elem;
  60193. }
  60194. }
  60195. }
  60196. return nullptr;
  60197. }
  60198. template<typename Type>
  60199. auto setup_node_for() noexcept {
  60200. meta_type_node node{
  60201. &type_id<Type>(),
  60202. type_id<Type>().hash(),
  60203. nullptr,
  60204. (std::is_arithmetic_v<Type> ? meta_traits::is_arithmetic : meta_traits::is_none)
  60205. | (std::is_integral_v<Type> ? meta_traits::is_integral : meta_traits::is_none)
  60206. | (std::is_signed_v<Type> ? meta_traits::is_signed : meta_traits::is_none)
  60207. | (std::is_array_v<Type> ? meta_traits::is_array : meta_traits::is_none)
  60208. | (std::is_enum_v<Type> ? meta_traits::is_enum : meta_traits::is_none)
  60209. | (std::is_class_v<Type> ? meta_traits::is_class : meta_traits::is_none)
  60210. | (std::is_pointer_v<Type> ? meta_traits::is_pointer : meta_traits::is_none)
  60211. | (is_meta_pointer_like_v<Type> ? meta_traits::is_pointer_like : meta_traits::is_none)
  60212. | (is_complete_v<meta_sequence_container_traits<Type>> ? meta_traits::is_sequence_container : meta_traits::is_none)
  60213. | (is_complete_v<meta_associative_container_traits<Type>> ? meta_traits::is_associative_container : meta_traits::is_none),
  60214. size_of_v<Type>,
  60215. &resolve<std::remove_const_t<std::remove_pointer_t<Type>>>};
  60216. if constexpr(std::is_default_constructible_v<Type>) {
  60217. node.default_constructor = +[](const meta_ctx &ctx) {
  60218. return meta_any{ctx, std::in_place_type<Type>};
  60219. };
  60220. }
  60221. if constexpr(std::is_arithmetic_v<Type>) {
  60222. node.conversion_helper = +[](void *lhs, const void *rhs) {
  60223. return lhs ? static_cast<double>(*static_cast<Type *>(lhs) = static_cast<Type>(*static_cast<const double *>(rhs))) : static_cast<double>(*static_cast<const Type *>(rhs));
  60224. };
  60225. } else if constexpr(std::is_enum_v<Type>) {
  60226. node.conversion_helper = +[](void *lhs, const void *rhs) {
  60227. return lhs ? static_cast<double>(*static_cast<Type *>(lhs) = static_cast<Type>(static_cast<std::underlying_type_t<Type>>(*static_cast<const double *>(rhs)))) : static_cast<double>(*static_cast<const Type *>(rhs));
  60228. };
  60229. }
  60230. if constexpr(!std::is_void_v<Type> && !std::is_function_v<Type>) {
  60231. node.from_void = +[](const meta_ctx &ctx, void *elem, const void *celem) {
  60232. if(elem && celem) { // ownership construction request
  60233. return meta_any{ctx, std::in_place, static_cast<std::decay_t<Type> *>(elem)};
  60234. }
  60235. if(elem) { // non-const reference construction request
  60236. return meta_any{ctx, std::in_place_type<std::decay_t<Type> &>, *static_cast<std::decay_t<Type> *>(elem)};
  60237. }
  60238. // const reference construction request
  60239. return meta_any{ctx, std::in_place_type<const std::decay_t<Type> &>, *static_cast<const std::decay_t<Type> *>(celem)};
  60240. };
  60241. }
  60242. if constexpr(is_complete_v<meta_template_traits<Type>>) {
  60243. node.templ = meta_template_node{
  60244. meta_template_traits<Type>::args_type::size,
  60245. &resolve<typename meta_template_traits<Type>::class_type>,
  60246. +[](const meta_context &area, const std::size_t index) noexcept -> decltype(auto) { return meta_arg_node(area, typename meta_template_traits<Type>::args_type{}, index); }};
  60247. }
  60248. return node;
  60249. }
  60250. [[nodiscard]] inline const meta_type_node *try_resolve(const meta_context &context, const type_info &info) noexcept {
  60251. const auto it = context.value.find(info.hash());
  60252. return (it != context.value.end()) ? it->second.get() : nullptr;
  60253. }
  60254. template<typename Type>
  60255. [[nodiscard]] const meta_type_node &resolve(const meta_context &context) noexcept {
  60256. static_assert(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>, "Invalid type");
  60257. static const meta_type_node node = setup_node_for<Type>();
  60258. const auto *elem = try_resolve(context, *node.info);
  60259. return (elem == nullptr) ? node : *elem;
  60260. }
  60261. } // namespace internal
  60262. /*! @endcond */
  60263. } // namespace entt
  60264. #endif
  60265. // #include "meta/pointer.hpp"
  60266. // IWYU pragma: always_keep
  60267. #ifndef ENTT_META_POINTER_HPP
  60268. #define ENTT_META_POINTER_HPP
  60269. #include <memory>
  60270. #include <type_traits>
  60271. // #include "type_traits.hpp"
  60272. namespace entt {
  60273. /**
  60274. * @brief Makes plain pointers pointer-like types for the meta system.
  60275. * @tparam Type Element type.
  60276. */
  60277. template<typename Type>
  60278. struct is_meta_pointer_like<Type *>
  60279. : std::true_type {};
  60280. /**
  60281. * @brief Partial specialization used to reject pointers to arrays.
  60282. * @tparam Type Type of elements of the array.
  60283. * @tparam N Number of elements of the array.
  60284. */
  60285. template<typename Type, std::size_t N>
  60286. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  60287. struct is_meta_pointer_like<Type (*)[N]>
  60288. : std::false_type {};
  60289. /**
  60290. * @brief Makes `std::shared_ptr`s of any type pointer-like types for the meta
  60291. * system.
  60292. * @tparam Type Element type.
  60293. */
  60294. template<typename Type>
  60295. struct is_meta_pointer_like<std::shared_ptr<Type>>
  60296. : std::true_type {};
  60297. /**
  60298. * @brief Makes `std::unique_ptr`s of any type pointer-like types for the meta
  60299. * system.
  60300. * @tparam Type Element type.
  60301. * @tparam Args Other arguments.
  60302. */
  60303. template<typename Type, typename... Args>
  60304. struct is_meta_pointer_like<std::unique_ptr<Type, Args...>>
  60305. : std::true_type {};
  60306. /**
  60307. * @brief Specialization for self-proclaimed meta pointer like types.
  60308. * @tparam Type Element type.
  60309. */
  60310. template<typename Type>
  60311. struct is_meta_pointer_like<Type, std::void_t<typename Type::is_meta_pointer_like>>
  60312. : std::true_type {};
  60313. } // namespace entt
  60314. #endif
  60315. // #include "meta/policy.hpp"
  60316. #ifndef ENTT_META_POLICY_HPP
  60317. #define ENTT_META_POLICY_HPP
  60318. #include <type_traits>
  60319. namespace entt {
  60320. /*! @cond TURN_OFF_DOXYGEN */
  60321. namespace internal {
  60322. struct meta_policy {};
  60323. } // namespace internal
  60324. /*! @endcond */
  60325. /*! @brief Empty class type used to request the _as-is_ policy. */
  60326. struct as_value_t final: private internal::meta_policy {
  60327. /*! @cond TURN_OFF_DOXYGEN */
  60328. template<typename>
  60329. static constexpr bool value = true;
  60330. /*! @endcond */
  60331. };
  60332. /*! @brief Empty class type used to request the _as void_ policy. */
  60333. struct as_void_t final: private internal::meta_policy {
  60334. /*! @cond TURN_OFF_DOXYGEN */
  60335. template<typename>
  60336. static constexpr bool value = true;
  60337. /*! @endcond */
  60338. };
  60339. /*! @brief Empty class type used to request the _as ref_ policy. */
  60340. struct as_ref_t final: private internal::meta_policy {
  60341. /*! @cond TURN_OFF_DOXYGEN */
  60342. template<typename Type>
  60343. static constexpr bool value = std::is_reference_v<Type> && !std::is_const_v<std::remove_reference_t<Type>>;
  60344. /*! @endcond */
  60345. };
  60346. /*! @brief Empty class type used to request the _as cref_ policy. */
  60347. struct as_cref_t final: private internal::meta_policy {
  60348. /*! @cond TURN_OFF_DOXYGEN */
  60349. template<typename Type>
  60350. static constexpr bool value = std::is_reference_v<Type>;
  60351. /*! @endcond */
  60352. };
  60353. /*! @brief Empty class type used to request the _as auto_ policy. */
  60354. struct as_is_t final: private internal::meta_policy {
  60355. /*! @cond TURN_OFF_DOXYGEN */
  60356. template<typename>
  60357. static constexpr bool value = true;
  60358. /*! @endcond */
  60359. };
  60360. /**
  60361. * @brief Provides the member constant `value` to true if a type also is a meta
  60362. * policy, false otherwise.
  60363. * @tparam Type Type to check.
  60364. */
  60365. template<typename Type>
  60366. struct is_meta_policy
  60367. : std::bool_constant<std::is_base_of_v<internal::meta_policy, Type>> {};
  60368. /**
  60369. * @brief Helper variable template.
  60370. * @tparam Type Type to check.
  60371. */
  60372. template<typename Type>
  60373. inline constexpr bool is_meta_policy_v = is_meta_policy<Type>::value;
  60374. } // namespace entt
  60375. #endif
  60376. // #include "meta/range.hpp"
  60377. #ifndef ENTT_META_RANGE_HPP
  60378. #define ENTT_META_RANGE_HPP
  60379. #include <cstddef>
  60380. #include <iterator>
  60381. #include <utility>
  60382. // #include "../core/fwd.hpp"
  60383. // #include "../core/iterator.hpp"
  60384. // #include "context.hpp"
  60385. namespace entt {
  60386. /*! @cond TURN_OFF_DOXYGEN */
  60387. namespace internal {
  60388. struct meta_base_node;
  60389. template<typename Type, typename It>
  60390. struct meta_range_iterator final {
  60391. using value_type = std::pair<id_type, Type>;
  60392. using pointer = input_iterator_pointer<value_type>;
  60393. using reference = value_type;
  60394. using difference_type = std::ptrdiff_t;
  60395. using iterator_category = std::input_iterator_tag;
  60396. using iterator_concept = std::random_access_iterator_tag;
  60397. constexpr meta_range_iterator() noexcept
  60398. : it{},
  60399. ctx{} {}
  60400. constexpr meta_range_iterator(const meta_ctx &area, const It iter) noexcept
  60401. : it{iter},
  60402. ctx{&area} {}
  60403. constexpr meta_range_iterator &operator++() noexcept {
  60404. return ++it, *this;
  60405. }
  60406. constexpr meta_range_iterator operator++(int) noexcept {
  60407. const meta_range_iterator orig = *this;
  60408. return ++(*this), orig;
  60409. }
  60410. constexpr meta_range_iterator &operator--() noexcept {
  60411. return --it, *this;
  60412. }
  60413. constexpr meta_range_iterator operator--(int) noexcept {
  60414. const meta_range_iterator orig = *this;
  60415. return operator--(), orig;
  60416. }
  60417. constexpr meta_range_iterator &operator+=(const difference_type value) noexcept {
  60418. it += value;
  60419. return *this;
  60420. }
  60421. constexpr meta_range_iterator operator+(const difference_type value) const noexcept {
  60422. meta_range_iterator copy = *this;
  60423. return (copy += value);
  60424. }
  60425. constexpr meta_range_iterator &operator-=(const difference_type value) noexcept {
  60426. return (*this += -value);
  60427. }
  60428. constexpr meta_range_iterator operator-(const difference_type value) const noexcept {
  60429. return (*this + -value);
  60430. }
  60431. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  60432. if constexpr(std::is_same_v<It, typename decltype(meta_context::value)::const_iterator>) {
  60433. return {it[value].first, Type{*ctx, *it[value].second}};
  60434. } else if constexpr(std::is_same_v<typename std::iterator_traits<It>::value_type, meta_base_node>) {
  60435. return {it[value].type, Type{*ctx, it[value]}};
  60436. } else {
  60437. return {it[value].id, Type{*ctx, it[value]}};
  60438. }
  60439. }
  60440. [[nodiscard]] constexpr pointer operator->() const noexcept {
  60441. return operator*();
  60442. }
  60443. [[nodiscard]] constexpr reference operator*() const noexcept {
  60444. return operator[](0);
  60445. }
  60446. template<typename... Args>
  60447. friend constexpr std::ptrdiff_t operator-(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  60448. template<typename... Args>
  60449. friend constexpr bool operator==(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  60450. template<typename... Args>
  60451. friend constexpr bool operator<(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;
  60452. private:
  60453. It it;
  60454. const meta_ctx *ctx;
  60455. };
  60456. template<typename... Args>
  60457. [[nodiscard]] constexpr std::ptrdiff_t operator-(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  60458. return lhs.it - rhs.it;
  60459. }
  60460. template<typename... Args>
  60461. [[nodiscard]] constexpr bool operator==(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  60462. return lhs.it == rhs.it;
  60463. }
  60464. template<typename... Args>
  60465. [[nodiscard]] constexpr bool operator!=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  60466. return !(lhs == rhs);
  60467. }
  60468. template<typename... Args>
  60469. [[nodiscard]] constexpr bool operator<(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  60470. return lhs.it < rhs.it;
  60471. }
  60472. template<typename... Args>
  60473. [[nodiscard]] constexpr bool operator>(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  60474. return rhs < lhs;
  60475. }
  60476. template<typename... Args>
  60477. [[nodiscard]] constexpr bool operator<=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  60478. return !(lhs > rhs);
  60479. }
  60480. template<typename... Args>
  60481. [[nodiscard]] constexpr bool operator>=(const meta_range_iterator<Args...> &lhs, const meta_range_iterator<Args...> &rhs) noexcept {
  60482. return !(lhs < rhs);
  60483. }
  60484. } // namespace internal
  60485. /*! @endcond */
  60486. /**
  60487. * @brief Iterable range to use to iterate all types of meta objects.
  60488. * @tparam Type Type of meta objects returned.
  60489. * @tparam It Type of forward iterator.
  60490. */
  60491. template<typename Type, typename It>
  60492. using meta_range = iterable_adaptor<internal::meta_range_iterator<Type, It>>;
  60493. } // namespace entt
  60494. #endif
  60495. // #include "meta/resolve.hpp"
  60496. #ifndef ENTT_META_RESOLVE_HPP
  60497. #define ENTT_META_RESOLVE_HPP
  60498. #include <type_traits>
  60499. // #include "../core/type_info.hpp"
  60500. // #include "../locator/locator.hpp"
  60501. // #include "context.hpp"
  60502. // #include "meta.hpp"
  60503. // #include "node.hpp"
  60504. // #include "range.hpp"
  60505. namespace entt {
  60506. /**
  60507. * @brief Returns the meta type associated with a given type.
  60508. * @tparam Type Type to use to search for a meta type.
  60509. * @param ctx The context from which to search for meta types.
  60510. * @return The meta type associated with the given type, if any.
  60511. */
  60512. template<typename Type>
  60513. [[nodiscard]] meta_type resolve(const meta_ctx &ctx) noexcept {
  60514. const auto &context = internal::meta_context::from(ctx);
  60515. return {ctx, internal::resolve<std::remove_const_t<std::remove_reference_t<Type>>>(context)};
  60516. }
  60517. /**
  60518. * @brief Returns the meta type associated with a given type.
  60519. * @tparam Type Type to use to search for a meta type.
  60520. * @return The meta type associated with the given type, if any.
  60521. */
  60522. template<typename Type>
  60523. [[nodiscard]] meta_type resolve() noexcept {
  60524. return resolve<Type>(locator<meta_ctx>::value_or());
  60525. }
  60526. /**
  60527. * @brief Returns a range to use to visit all meta types.
  60528. * @param ctx The context from which to search for meta types.
  60529. * @return An iterable range to use to visit all meta types.
  60530. */
  60531. [[nodiscard]] inline meta_range<meta_type, typename decltype(internal::meta_context::value)::const_iterator> resolve(const meta_ctx &ctx) noexcept {
  60532. const auto &context = internal::meta_context::from(ctx);
  60533. return {{ctx, context.value.cbegin()}, {ctx, context.value.cend()}};
  60534. }
  60535. /**
  60536. * @brief Returns a range to use to visit all meta types.
  60537. * @return An iterable range to use to visit all meta types.
  60538. */
  60539. [[nodiscard]] inline meta_range<meta_type, typename decltype(internal::meta_context::value)::const_iterator> resolve() noexcept {
  60540. return resolve(locator<meta_ctx>::value_or());
  60541. }
  60542. /**
  60543. * @brief Returns the meta type associated with a given identifier, if any.
  60544. * @param ctx The context from which to search for meta types.
  60545. * @param id Unique identifier.
  60546. * @return The meta type associated with the given identifier, if any.
  60547. */
  60548. [[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const id_type id) noexcept {
  60549. for(auto &&curr: resolve(ctx)) {
  60550. if(curr.second.id() == id) {
  60551. return curr.second;
  60552. }
  60553. }
  60554. return meta_type{};
  60555. }
  60556. /**
  60557. * @brief Returns the meta type associated with a given identifier, if any.
  60558. * @param id Unique identifier.
  60559. * @return The meta type associated with the given identifier, if any.
  60560. */
  60561. [[nodiscard]] inline meta_type resolve(const id_type id) noexcept {
  60562. return resolve(locator<meta_ctx>::value_or(), id);
  60563. }
  60564. /**
  60565. * @brief Returns the meta type associated with a given type info object.
  60566. * @param ctx The context from which to search for meta types.
  60567. * @param info The type info object of the requested type.
  60568. * @return The meta type associated with the given type info object, if any.
  60569. */
  60570. [[nodiscard]] inline meta_type resolve(const meta_ctx &ctx, const type_info &info) noexcept {
  60571. const auto &context = internal::meta_context::from(ctx);
  60572. const auto *elem = internal::try_resolve(context, info);
  60573. return (elem != nullptr) ? meta_type{ctx, *elem} : meta_type{};
  60574. }
  60575. /**
  60576. * @brief Returns the meta type associated with a given type info object.
  60577. * @param info The type info object of the requested type.
  60578. * @return The meta type associated with the given type info object, if any.
  60579. */
  60580. [[nodiscard]] inline meta_type resolve(const type_info &info) noexcept {
  60581. return resolve(locator<meta_ctx>::value_or(), info);
  60582. }
  60583. } // namespace entt
  60584. #endif
  60585. // #include "meta/template.hpp"
  60586. // IWYU pragma: always_keep
  60587. #ifndef ENTT_META_TEMPLATE_HPP
  60588. #define ENTT_META_TEMPLATE_HPP
  60589. // #include "../core/type_traits.hpp"
  60590. namespace entt {
  60591. /*! @brief Utility class to disambiguate class templates. */
  60592. template<template<typename...> class>
  60593. struct meta_class_template_tag {};
  60594. /**
  60595. * @brief General purpose traits class for generating meta template information.
  60596. * @tparam Clazz Type of class template.
  60597. * @tparam Args Types of template arguments.
  60598. */
  60599. template<template<typename...> class Clazz, typename... Args>
  60600. struct meta_template_traits<Clazz<Args...>> {
  60601. /*! @brief Wrapped class template. */
  60602. using class_type = meta_class_template_tag<Clazz>;
  60603. /*! @brief List of template arguments. */
  60604. using args_type = type_list<Args...>;
  60605. };
  60606. } // namespace entt
  60607. #endif
  60608. // #include "meta/type_traits.hpp"
  60609. #ifndef ENTT_META_TYPE_TRAITS_HPP
  60610. #define ENTT_META_TYPE_TRAITS_HPP
  60611. #include <type_traits>
  60612. #include <utility>
  60613. namespace entt {
  60614. /**
  60615. * @brief Traits class template to be specialized to enable support for meta
  60616. * template information.
  60617. */
  60618. template<typename>
  60619. struct meta_template_traits;
  60620. /**
  60621. * @brief Traits class template to be specialized to enable support for meta
  60622. * sequence containers.
  60623. */
  60624. template<typename>
  60625. struct meta_sequence_container_traits;
  60626. /**
  60627. * @brief Traits class template to be specialized to enable support for meta
  60628. * associative containers.
  60629. */
  60630. template<typename>
  60631. struct meta_associative_container_traits;
  60632. /**
  60633. * @brief Provides the member constant `value` to true if a given type is a
  60634. * pointer-like type from the point of view of the meta system, false otherwise.
  60635. */
  60636. template<typename, typename = void>
  60637. struct is_meta_pointer_like: std::false_type {};
  60638. /**
  60639. * @brief Partial specialization to ensure that const pointer-like types are
  60640. * also accepted.
  60641. * @tparam Type Potentially pointer-like type.
  60642. */
  60643. template<typename Type>
  60644. struct is_meta_pointer_like<const Type>: is_meta_pointer_like<Type> {};
  60645. /**
  60646. * @brief Helper variable template.
  60647. * @tparam Type Potentially pointer-like type.
  60648. */
  60649. template<typename Type>
  60650. inline constexpr auto is_meta_pointer_like_v = is_meta_pointer_like<Type>::value;
  60651. } // namespace entt
  60652. #endif
  60653. // #include "meta/utility.hpp"
  60654. #ifndef ENTT_META_UTILITY_HPP
  60655. #define ENTT_META_UTILITY_HPP
  60656. #include <cstddef>
  60657. #include <functional>
  60658. #include <type_traits>
  60659. #include <utility>
  60660. // #include "../core/type_traits.hpp"
  60661. // #include "../locator/locator.hpp"
  60662. // #include "meta.hpp"
  60663. // #include "node.hpp"
  60664. // #include "policy.hpp"
  60665. namespace entt {
  60666. /**
  60667. * @brief Meta function descriptor traits.
  60668. * @tparam Ret Function return type.
  60669. * @tparam Args Function arguments.
  60670. * @tparam Static Function staticness.
  60671. * @tparam Const Function constness.
  60672. */
  60673. template<typename Ret, typename Args, bool Static, bool Const>
  60674. struct meta_function_descriptor_traits {
  60675. /*! @brief Meta function return type. */
  60676. using return_type = Ret;
  60677. /*! @brief Meta function arguments. */
  60678. using args_type = Args;
  60679. /*! @brief True if the meta function is static, false otherwise. */
  60680. static constexpr bool is_static = Static;
  60681. /*! @brief True if the meta function is const, false otherwise. */
  60682. static constexpr bool is_const = Const;
  60683. };
  60684. /*! @brief Primary template isn't defined on purpose. */
  60685. template<typename, typename>
  60686. struct meta_function_descriptor;
  60687. /**
  60688. * @brief Meta function descriptor.
  60689. * @tparam Type Reflected type to which the meta function is associated.
  60690. * @tparam Ret Function return type.
  60691. * @tparam Class Actual owner of the member function.
  60692. * @tparam Args Function arguments.
  60693. */
  60694. template<typename Type, typename Ret, typename Class, typename... Args>
  60695. struct meta_function_descriptor<Type, Ret (Class::*)(Args...) const>
  60696. : meta_function_descriptor_traits<
  60697. Ret,
  60698. std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<const Class &, Args...>>,
  60699. !std::is_base_of_v<Class, Type>,
  60700. true> {};
  60701. /**
  60702. * @brief Meta function descriptor.
  60703. * @tparam Type Reflected type to which the meta function is associated.
  60704. * @tparam Ret Function return type.
  60705. * @tparam Class Actual owner of the member function.
  60706. * @tparam Args Function arguments.
  60707. */
  60708. template<typename Type, typename Ret, typename Class, typename... Args>
  60709. struct meta_function_descriptor<Type, Ret (Class::*)(Args...)>
  60710. : meta_function_descriptor_traits<
  60711. Ret,
  60712. std::conditional_t<std::is_base_of_v<Class, Type>, type_list<Args...>, type_list<Class &, Args...>>,
  60713. !std::is_base_of_v<Class, Type>,
  60714. false> {};
  60715. /**
  60716. * @brief Meta function descriptor.
  60717. * @tparam Type Reflected type to which the meta data is associated.
  60718. * @tparam Class Actual owner of the data member.
  60719. * @tparam Ret Data member type.
  60720. */
  60721. template<typename Type, typename Ret, typename Class>
  60722. struct meta_function_descriptor<Type, Ret Class::*>
  60723. : meta_function_descriptor_traits<
  60724. Ret &,
  60725. std::conditional_t<std::is_base_of_v<Class, Type>, type_list<>, type_list<Class &>>,
  60726. !std::is_base_of_v<Class, Type>,
  60727. false> {};
  60728. /**
  60729. * @brief Meta function descriptor.
  60730. * @tparam Type Reflected type to which the meta function is associated.
  60731. * @tparam Ret Function return type.
  60732. * @tparam MaybeType First function argument.
  60733. * @tparam Args Other function arguments.
  60734. */
  60735. template<typename Type, typename Ret, typename MaybeType, typename... Args>
  60736. struct meta_function_descriptor<Type, Ret (*)(MaybeType, Args...)>
  60737. : meta_function_descriptor_traits<
  60738. Ret,
  60739. std::conditional_t<
  60740. std::is_same_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>,
  60741. type_list<Args...>,
  60742. type_list<MaybeType, Args...>>,
  60743. !(std::is_same_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>),
  60744. std::is_const_v<std::remove_reference_t<MaybeType>> && (std::is_same_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type> || std::is_base_of_v<std::remove_const_t<std::remove_reference_t<MaybeType>>, Type>)> {};
  60745. /**
  60746. * @brief Meta function descriptor.
  60747. * @tparam Type Reflected type to which the meta function is associated.
  60748. * @tparam Ret Function return type.
  60749. */
  60750. template<typename Type, typename Ret>
  60751. struct meta_function_descriptor<Type, Ret (*)()>
  60752. : meta_function_descriptor_traits<
  60753. Ret,
  60754. type_list<>,
  60755. true,
  60756. false> {};
  60757. /**
  60758. * @brief Meta function helper.
  60759. *
  60760. * Converts a function type to be associated with a reflected type into its meta
  60761. * function descriptor.
  60762. *
  60763. * @tparam Type Reflected type to which the meta function is associated.
  60764. * @tparam Candidate The actual function to associate with the reflected type.
  60765. */
  60766. template<typename Type, typename Candidate>
  60767. class meta_function_helper {
  60768. template<typename Ret, typename... Args, typename Class>
  60769. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...) const> get_rid_of_noexcept(Ret (Class::*)(Args...) const);
  60770. template<typename Ret, typename... Args, typename Class>
  60771. static constexpr meta_function_descriptor<Type, Ret (Class::*)(Args...)> get_rid_of_noexcept(Ret (Class::*)(Args...));
  60772. template<typename Ret, typename Class, typename = std::enable_if_t<std::is_member_object_pointer_v<Ret Class::*>>>
  60773. static constexpr meta_function_descriptor<Type, Ret Class::*> get_rid_of_noexcept(Ret Class::*);
  60774. template<typename Ret, typename... Args>
  60775. static constexpr meta_function_descriptor<Type, Ret (*)(Args...)> get_rid_of_noexcept(Ret (*)(Args...));
  60776. template<typename Class>
  60777. static constexpr meta_function_descriptor<Class, decltype(&Class::operator())> get_rid_of_noexcept(Class);
  60778. public:
  60779. /*! @brief The meta function descriptor of the given function. */
  60780. using type = decltype(get_rid_of_noexcept(std::declval<Candidate>()));
  60781. };
  60782. /**
  60783. * @brief Helper type.
  60784. * @tparam Type Reflected type to which the meta function is associated.
  60785. * @tparam Candidate The actual function to associate with the reflected type.
  60786. */
  60787. template<typename Type, typename Candidate>
  60788. using meta_function_helper_t = typename meta_function_helper<Type, Candidate>::type;
  60789. /**
  60790. * @brief Wraps a value depending on the given policy.
  60791. *
  60792. * This function always returns a wrapped value in the requested context.<br/>
  60793. * Therefore, if the passed value is itself a wrapped object with a different
  60794. * context, it undergoes a rebinding to the requested context.
  60795. *
  60796. * @tparam Policy Optional policy (no policy set by default).
  60797. * @tparam Type Type of value to wrap.
  60798. * @param ctx The context from which to search for meta types.
  60799. * @param value Value to wrap.
  60800. * @return A meta any containing the returned value, if any.
  60801. */
  60802. template<typename Policy = as_value_t, typename Type>
  60803. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_dispatch(const meta_ctx &ctx, [[maybe_unused]] Type &&value) {
  60804. if constexpr(std::is_same_v<Policy, as_cref_t>) {
  60805. static_assert(std::is_lvalue_reference_v<Type>, "Invalid type");
  60806. return meta_any{ctx, std::in_place_type<const std::remove_reference_t<Type> &>, std::as_const(value)};
  60807. } else if constexpr(std::is_same_v<Policy, as_ref_t> || (std::is_same_v<Policy, as_is_t> && std::is_lvalue_reference_v<Type>)) {
  60808. return meta_any{ctx, std::in_place_type<Type>, value};
  60809. } else if constexpr(std::is_same_v<Policy, as_void_t>) {
  60810. return meta_any{ctx, std::in_place_type<void>};
  60811. } else {
  60812. return meta_any{ctx, std::forward<Type>(value)};
  60813. }
  60814. }
  60815. /**
  60816. * @brief Wraps a value depending on the given policy.
  60817. * @tparam Policy Optional policy (no policy set by default).
  60818. * @tparam Type Type of value to wrap.
  60819. * @param value Value to wrap.
  60820. * @return A meta any containing the returned value, if any.
  60821. */
  60822. template<typename Policy = as_value_t, typename Type>
  60823. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_dispatch(Type &&value) {
  60824. return meta_dispatch<Policy, Type>(locator<meta_ctx>::value_or(), std::forward<Type>(value));
  60825. }
  60826. /*! @cond TURN_OFF_DOXYGEN */
  60827. namespace internal {
  60828. template<typename Policy, typename Candidate, typename... Args>
  60829. [[nodiscard]] meta_any meta_invoke_with_args(const meta_ctx &ctx, Candidate &&candidate, Args &&...args) {
  60830. if constexpr(std::is_void_v<decltype(std::invoke(std::forward<Candidate>(candidate), args...))>) {
  60831. std::invoke(std::forward<Candidate>(candidate), args...);
  60832. return meta_any{ctx, std::in_place_type<void>};
  60833. } else {
  60834. return meta_dispatch<Policy>(ctx, std::invoke(std::forward<Candidate>(candidate), args...));
  60835. }
  60836. }
  60837. template<typename Type, typename Policy, typename Candidate, std::size_t... Index>
  60838. [[nodiscard]] meta_any meta_invoke(meta_any &instance, Candidate &&candidate, [[maybe_unused]] meta_any *const args, std::index_sequence<Index...>) {
  60839. using descriptor = meta_function_helper_t<Type, std::remove_reference_t<Candidate>>;
  60840. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  60841. if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, const Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  60842. if(const auto *const clazz = instance.try_cast<const Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  60843. return meta_invoke_with_args<Policy>(instance.context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  60844. }
  60845. } else if constexpr(std::is_invocable_v<std::remove_reference_t<Candidate>, Type &, type_list_element_t<Index, typename descriptor::args_type>...>) {
  60846. if(auto *const clazz = instance.try_cast<Type>(); clazz && ((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  60847. return meta_invoke_with_args<Policy>(instance.context(), std::forward<Candidate>(candidate), *clazz, (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  60848. }
  60849. } else {
  60850. if(((args + Index)->allow_cast<type_list_element_t<Index, typename descriptor::args_type>>() && ...)) {
  60851. return meta_invoke_with_args<Policy>(instance.context(), std::forward<Candidate>(candidate), (args + Index)->cast<type_list_element_t<Index, typename descriptor::args_type>>()...);
  60852. }
  60853. }
  60854. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  60855. return meta_any{meta_ctx_arg, instance.context()};
  60856. }
  60857. template<typename Type, typename... Args, std::size_t... Index>
  60858. [[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args, std::index_sequence<Index...>) {
  60859. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  60860. if(((args + Index)->allow_cast<Args>() && ...)) {
  60861. return meta_any{ctx, std::in_place_type<Type>, (args + Index)->cast<Args>()...};
  60862. }
  60863. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  60864. return meta_any{meta_ctx_arg, ctx};
  60865. }
  60866. } // namespace internal
  60867. /*! @endcond */
  60868. /**
  60869. * @brief Returns the meta type of the i-th element of a list of arguments.
  60870. * @tparam Type Type list of the actual types of arguments.
  60871. * @param ctx The context from which to search for meta types.
  60872. * @param index The index of the element for which to return the meta type.
  60873. * @return The meta type of the i-th element of the list of arguments.
  60874. */
  60875. template<typename Type>
  60876. [[nodiscard]] meta_type meta_arg(const meta_ctx &ctx, const std::size_t index) noexcept {
  60877. const auto &context = internal::meta_context::from(ctx);
  60878. return {ctx, internal::meta_arg_node(context, Type{}, index)};
  60879. }
  60880. /**
  60881. * @brief Returns the meta type of the i-th element of a list of arguments.
  60882. * @tparam Type Type list of the actual types of arguments.
  60883. * @param index The index of the element for which to return the meta type.
  60884. * @return The meta type of the i-th element of the list of arguments.
  60885. */
  60886. template<typename Type>
  60887. [[nodiscard]] meta_type meta_arg(const std::size_t index) noexcept {
  60888. return meta_arg<Type>(locator<meta_ctx>::value_or(), index);
  60889. }
  60890. /**
  60891. * @brief Sets the value of a given variable.
  60892. * @tparam Type Reflected type to which the variable is associated.
  60893. * @tparam Data The actual variable to set.
  60894. * @param instance An opaque instance of the underlying type, if required.
  60895. * @param value Parameter to use to set the variable.
  60896. * @return True in case of success, false otherwise.
  60897. */
  60898. template<typename Type, auto Data>
  60899. [[nodiscard]] bool meta_setter([[maybe_unused]] meta_handle instance, [[maybe_unused]] meta_any value) {
  60900. if constexpr(std::is_member_function_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  60901. using descriptor = meta_function_helper_t<Type, decltype(Data)>;
  60902. using data_type = type_list_element_t<descriptor::is_static, typename descriptor::args_type>;
  60903. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  60904. std::invoke(Data, *clazz, value.cast<data_type>());
  60905. return true;
  60906. }
  60907. } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
  60908. using data_type = std::remove_reference_t<typename meta_function_helper_t<Type, decltype(Data)>::return_type>;
  60909. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  60910. if(auto *const clazz = instance->try_cast<Type>(); clazz && value.allow_cast<data_type>()) {
  60911. std::invoke(Data, *clazz) = value.cast<data_type>();
  60912. return true;
  60913. }
  60914. }
  60915. } else if constexpr(std::is_pointer_v<decltype(Data)>) {
  60916. using data_type = std::remove_reference_t<decltype(*Data)>;
  60917. if constexpr(!std::is_array_v<data_type> && !std::is_const_v<data_type>) {
  60918. if(value.allow_cast<data_type>()) {
  60919. *Data = value.cast<data_type>();
  60920. return true;
  60921. }
  60922. }
  60923. }
  60924. return false;
  60925. }
  60926. /**
  60927. * @brief Gets the value of a given variable.
  60928. * @tparam Type Reflected type to which the variable is associated.
  60929. * @tparam Data The actual variable to get.
  60930. * @tparam Policy Optional policy (no policy set by default).
  60931. * @param instance An opaque instance of the underlying type, if required.
  60932. * @return A meta any containing the value of the underlying variable.
  60933. */
  60934. template<typename Type, auto Data, typename Policy = as_value_t>
  60935. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_getter(meta_handle instance) {
  60936. if constexpr(std::is_member_pointer_v<decltype(Data)> || std::is_function_v<std::remove_reference_t<std::remove_pointer_t<decltype(Data)>>>) {
  60937. if constexpr(!std::is_array_v<std::remove_const_t<std::remove_reference_t<std::invoke_result_t<decltype(Data), Type &>>>>) {
  60938. if constexpr(std::is_invocable_v<decltype(Data), Type &>) {
  60939. if(auto *clazz = instance->try_cast<Type>(); clazz) {
  60940. return meta_dispatch<Policy>(instance->context(), std::invoke(Data, *clazz));
  60941. }
  60942. }
  60943. if constexpr(std::is_invocable_v<decltype(Data), const Type &>) {
  60944. if(auto *fallback = instance->try_cast<const Type>(); fallback) {
  60945. return meta_dispatch<Policy>(instance->context(), std::invoke(Data, *fallback));
  60946. }
  60947. }
  60948. }
  60949. return meta_any{meta_ctx_arg, instance->context()};
  60950. } else if constexpr(std::is_pointer_v<decltype(Data)>) {
  60951. if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
  60952. return meta_any{meta_ctx_arg, instance->context()};
  60953. } else {
  60954. return meta_dispatch<Policy>(instance->context(), *Data);
  60955. }
  60956. } else {
  60957. return meta_dispatch<Policy>(instance->context(), Data);
  60958. }
  60959. }
  60960. /**
  60961. * @brief Tries to _invoke_ an object given a list of erased parameters.
  60962. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  60963. * @tparam Policy Optional policy (no policy set by default).
  60964. * @tparam Candidate The type of the actual object to _invoke_.
  60965. * @param instance An opaque instance of the underlying type, if required.
  60966. * @param candidate The actual object to _invoke_.
  60967. * @param args Parameters to use to _invoke_ the object.
  60968. * @return A meta any containing the returned value, if any.
  60969. */
  60970. template<typename Type, typename Policy = as_value_t, typename Candidate>
  60971. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_invoke(meta_handle instance, Candidate &&candidate, meta_any *const args) {
  60972. return internal::meta_invoke<Type, Policy>(*instance.operator->(), std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  60973. }
  60974. /**
  60975. * @brief Tries to invoke a function given a list of erased parameters.
  60976. * @tparam Type Reflected type to which the function is associated.
  60977. * @tparam Candidate The actual function to invoke.
  60978. * @tparam Policy Optional policy (no policy set by default).
  60979. * @param instance An opaque instance of the underlying type, if required.
  60980. * @param args Parameters to use to invoke the function.
  60981. * @return A meta any containing the returned value, if any.
  60982. */
  60983. template<typename Type, auto Candidate, typename Policy = as_value_t>
  60984. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_invoke(meta_handle instance, meta_any *const args) {
  60985. return internal::meta_invoke<Type, Policy>(*instance.operator->(), Candidate, args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<decltype(Candidate)>>::args_type::size>{});
  60986. }
  60987. /**
  60988. * @brief Tries to construct an instance given a list of erased parameters.
  60989. *
  60990. * @warning
  60991. * The context provided is used only for the return type.<br/>
  60992. * It's up to the caller to bind the arguments to the right context(s).
  60993. *
  60994. * @tparam Type Actual type of the instance to construct.
  60995. * @tparam Args Types of arguments expected.
  60996. * @param ctx The context from which to search for meta types.
  60997. * @param args Parameters to use to construct the instance.
  60998. * @return A meta any containing the new instance, if any.
  60999. */
  61000. template<typename Type, typename... Args>
  61001. [[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, meta_any *const args) {
  61002. return internal::meta_construct<Type, Args...>(ctx, args, std::index_sequence_for<Args...>{});
  61003. }
  61004. /**
  61005. * @brief Tries to construct an instance given a list of erased parameters.
  61006. * @tparam Type Actual type of the instance to construct.
  61007. * @tparam Args Types of arguments expected.
  61008. * @param args Parameters to use to construct the instance.
  61009. * @return A meta any containing the new instance, if any.
  61010. */
  61011. template<typename Type, typename... Args>
  61012. [[nodiscard]] meta_any meta_construct(meta_any *const args) {
  61013. return meta_construct<Type, Args...>(locator<meta_ctx>::value_or(), args);
  61014. }
  61015. /**
  61016. * @brief Tries to construct an instance given a list of erased parameters.
  61017. *
  61018. * @warning
  61019. * The context provided is used only for the return type.<br/>
  61020. * It's up to the caller to bind the arguments to the right context(s).
  61021. *
  61022. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  61023. * @tparam Policy Optional policy (no policy set by default).
  61024. * @tparam Candidate The type of the actual object to _invoke_.
  61025. * @param ctx The context from which to search for meta types.
  61026. * @param candidate The actual object to _invoke_.
  61027. * @param args Parameters to use to _invoke_ the object.
  61028. * @return A meta any containing the returned value, if any.
  61029. */
  61030. template<typename Type, typename Policy = as_value_t, typename Candidate>
  61031. [[nodiscard]] meta_any meta_construct(const meta_ctx &ctx, Candidate &&candidate, meta_any *const args) {
  61032. if constexpr(meta_function_helper_t<Type, Candidate>::is_static || std::is_class_v<std::remove_const_t<std::remove_reference_t<Candidate>>>) {
  61033. meta_any placeholder{meta_ctx_arg, ctx};
  61034. return internal::meta_invoke<Type, Policy>(placeholder, std::forward<Candidate>(candidate), args, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  61035. } else {
  61036. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - waiting for C++20 (and std::span)
  61037. return internal::meta_invoke<Type, Policy>(*args, std::forward<Candidate>(candidate), args + 1u, std::make_index_sequence<meta_function_helper_t<Type, std::remove_reference_t<Candidate>>::args_type::size>{});
  61038. }
  61039. }
  61040. /**
  61041. * @brief Tries to construct an instance given a list of erased parameters.
  61042. * @tparam Type Reflected type to which the object to _invoke_ is associated.
  61043. * @tparam Policy Optional policy (no policy set by default).
  61044. * @tparam Candidate The type of the actual object to _invoke_.
  61045. * @param candidate The actual object to _invoke_.
  61046. * @param args Parameters to use to _invoke_ the object.
  61047. * @return A meta any containing the returned value, if any.
  61048. */
  61049. template<typename Type, typename Policy = as_value_t, typename Candidate>
  61050. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(Candidate &&candidate, meta_any *const args) {
  61051. return meta_construct<Type, Policy>(locator<meta_ctx>::value_or(), std::forward<Candidate>(candidate), args);
  61052. }
  61053. /**
  61054. * @brief Tries to construct an instance given a list of erased parameters.
  61055. *
  61056. * @warning
  61057. * The context provided is used only for the return type.<br/>
  61058. * It's up to the caller to bind the arguments to the right context(s).
  61059. *
  61060. * @tparam Type Reflected type to which the function is associated.
  61061. * @tparam Candidate The actual function to invoke.
  61062. * @tparam Policy Optional policy (no policy set by default).
  61063. * @param ctx The context from which to search for meta types.
  61064. * @param args Parameters to use to invoke the function.
  61065. * @return A meta any containing the returned value, if any.
  61066. */
  61067. template<typename Type, auto Candidate, typename Policy = as_value_t>
  61068. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(const meta_ctx &ctx, meta_any *const args) {
  61069. return meta_construct<Type, Policy>(ctx, Candidate, args);
  61070. }
  61071. /**
  61072. * @brief Tries to construct an instance given a list of erased parameters.
  61073. * @tparam Type Reflected type to which the function is associated.
  61074. * @tparam Candidate The actual function to invoke.
  61075. * @tparam Policy Optional policy (no policy set by default).
  61076. * @param args Parameters to use to invoke the function.
  61077. * @return A meta any containing the returned value, if any.
  61078. */
  61079. template<typename Type, auto Candidate, typename Policy = as_value_t>
  61080. [[nodiscard]] std::enable_if_t<is_meta_policy_v<Policy>, meta_any> meta_construct(meta_any *const args) {
  61081. return meta_construct<Type, Candidate, Policy>(locator<meta_ctx>::value_or(), args);
  61082. }
  61083. } // namespace entt
  61084. #endif
  61085. // #include "poly/poly.hpp"
  61086. #ifndef ENTT_POLY_POLY_HPP
  61087. #define ENTT_POLY_POLY_HPP
  61088. #include <cstddef>
  61089. #include <functional>
  61090. #include <tuple>
  61091. #include <type_traits>
  61092. #include <utility>
  61093. // #include "../core/any.hpp"
  61094. #ifndef ENTT_CORE_ANY_HPP
  61095. #define ENTT_CORE_ANY_HPP
  61096. #include <cstddef>
  61097. #include <memory>
  61098. #include <type_traits>
  61099. #include <utility>
  61100. // #include "../config/config.h"
  61101. #ifndef ENTT_CONFIG_CONFIG_H
  61102. #define ENTT_CONFIG_CONFIG_H
  61103. // #include "version.h"
  61104. #ifndef ENTT_CONFIG_VERSION_H
  61105. #define ENTT_CONFIG_VERSION_H
  61106. // #include "macro.h"
  61107. #ifndef ENTT_CONFIG_MACRO_H
  61108. #define ENTT_CONFIG_MACRO_H
  61109. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  61110. #define ENTT_STR(arg) #arg
  61111. #define ENTT_XSTR(arg) ENTT_STR(arg)
  61112. // NOLINTEND(cppcoreguidelines-macro-usage)
  61113. #endif
  61114. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  61115. #define ENTT_VERSION_MAJOR 3
  61116. #define ENTT_VERSION_MINOR 16
  61117. #define ENTT_VERSION_PATCH 0
  61118. #define ENTT_VERSION \
  61119. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  61120. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  61121. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  61122. #endif
  61123. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  61124. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  61125. # define ENTT_CONSTEXPR
  61126. # define ENTT_THROW throw
  61127. # define ENTT_TRY try
  61128. # define ENTT_CATCH catch(...)
  61129. #else
  61130. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  61131. # define ENTT_THROW
  61132. # define ENTT_TRY if(true)
  61133. # define ENTT_CATCH if(false)
  61134. #endif
  61135. #if __has_include(<version>)
  61136. # include <version>
  61137. #
  61138. # if defined(__cpp_consteval)
  61139. # define ENTT_CONSTEVAL consteval
  61140. # endif
  61141. #endif
  61142. #ifndef ENTT_CONSTEVAL
  61143. # define ENTT_CONSTEVAL constexpr
  61144. #endif
  61145. #ifdef ENTT_USE_ATOMIC
  61146. # include <atomic>
  61147. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  61148. #else
  61149. # define ENTT_MAYBE_ATOMIC(Type) Type
  61150. #endif
  61151. #ifndef ENTT_ID_TYPE
  61152. # include <cstdint>
  61153. # define ENTT_ID_TYPE std::uint32_t
  61154. #else
  61155. # include <cstdint> // provides coverage for types in the std namespace
  61156. #endif
  61157. #ifndef ENTT_SPARSE_PAGE
  61158. # define ENTT_SPARSE_PAGE 4096
  61159. #endif
  61160. #ifndef ENTT_PACKED_PAGE
  61161. # define ENTT_PACKED_PAGE 1024
  61162. #endif
  61163. #ifdef ENTT_DISABLE_ASSERT
  61164. # undef ENTT_ASSERT
  61165. # define ENTT_ASSERT(condition, msg) (void(0))
  61166. #elif !defined ENTT_ASSERT
  61167. # include <cassert>
  61168. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  61169. #endif
  61170. #ifdef ENTT_DISABLE_ASSERT
  61171. # undef ENTT_ASSERT_CONSTEXPR
  61172. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  61173. #elif !defined ENTT_ASSERT_CONSTEXPR
  61174. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  61175. #endif
  61176. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  61177. #ifdef ENTT_NO_ETO
  61178. # define ENTT_ETO_TYPE(Type) void
  61179. #else
  61180. # define ENTT_ETO_TYPE(Type) Type
  61181. #endif
  61182. #ifdef ENTT_NO_MIXIN
  61183. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  61184. #else
  61185. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  61186. #endif
  61187. #ifdef ENTT_STANDARD_CPP
  61188. # define ENTT_NONSTD false
  61189. #else
  61190. # define ENTT_NONSTD true
  61191. # if defined __clang__ || defined __GNUC__
  61192. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  61193. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  61194. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  61195. # elif defined _MSC_VER
  61196. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  61197. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  61198. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  61199. # endif
  61200. #endif
  61201. #ifndef ENTT_EXPORT
  61202. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  61203. # define ENTT_EXPORT __declspec(dllexport)
  61204. # define ENTT_IMPORT __declspec(dllimport)
  61205. # define ENTT_HIDDEN
  61206. # elif defined __GNUC__ && __GNUC__ >= 4
  61207. # define ENTT_EXPORT __attribute__((visibility("default")))
  61208. # define ENTT_IMPORT __attribute__((visibility("default")))
  61209. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  61210. # else /* Unsupported compiler */
  61211. # define ENTT_EXPORT
  61212. # define ENTT_IMPORT
  61213. # define ENTT_HIDDEN
  61214. # endif
  61215. #endif
  61216. #ifndef ENTT_API
  61217. # if defined ENTT_API_EXPORT
  61218. # define ENTT_API ENTT_EXPORT
  61219. # elif defined ENTT_API_IMPORT
  61220. # define ENTT_API ENTT_IMPORT
  61221. # else /* No API */
  61222. # define ENTT_API
  61223. # endif
  61224. #endif
  61225. #if defined _MSC_VER
  61226. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  61227. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  61228. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  61229. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  61230. #endif
  61231. // NOLINTEND(cppcoreguidelines-macro-usage)
  61232. #endif
  61233. // #include "fwd.hpp"
  61234. #ifndef ENTT_CORE_FWD_HPP
  61235. #define ENTT_CORE_FWD_HPP
  61236. #include <cstddef>
  61237. #include <cstdint>
  61238. // #include "../config/config.h"
  61239. namespace entt {
  61240. /*! @brief Possible modes of an any object. */
  61241. enum class any_policy : std::uint8_t {
  61242. /*! @brief Default mode, no element available. */
  61243. empty,
  61244. /*! @brief Owning mode, dynamically allocated element. */
  61245. dynamic,
  61246. /*! @brief Owning mode, embedded element. */
  61247. embedded,
  61248. /*! @brief Aliasing mode, non-const reference. */
  61249. ref,
  61250. /*! @brief Const aliasing mode, const reference. */
  61251. cref
  61252. };
  61253. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  61254. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  61255. class basic_any;
  61256. /*! @brief Alias declaration for type identifiers. */
  61257. using id_type = ENTT_ID_TYPE;
  61258. /*! @brief Alias declaration for the most common use case. */
  61259. using any = basic_any<>;
  61260. template<typename, typename>
  61261. class compressed_pair;
  61262. template<typename>
  61263. class basic_hashed_string;
  61264. /*! @brief Aliases for common character types. */
  61265. using hashed_string = basic_hashed_string<char>;
  61266. /*! @brief Aliases for common character types. */
  61267. using hashed_wstring = basic_hashed_string<wchar_t>;
  61268. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  61269. struct type_info;
  61270. } // namespace entt
  61271. #endif
  61272. // #include "type_info.hpp"
  61273. #ifndef ENTT_CORE_TYPE_INFO_HPP
  61274. #define ENTT_CORE_TYPE_INFO_HPP
  61275. #include <string_view>
  61276. #include <type_traits>
  61277. #include <utility>
  61278. // #include "../config/config.h"
  61279. // #include "fwd.hpp"
  61280. // #include "hashed_string.hpp"
  61281. #ifndef ENTT_CORE_HASHED_STRING_HPP
  61282. #define ENTT_CORE_HASHED_STRING_HPP
  61283. #include <cstddef>
  61284. #include <cstdint>
  61285. // #include "fwd.hpp"
  61286. namespace entt {
  61287. /*! @cond TURN_OFF_DOXYGEN */
  61288. namespace internal {
  61289. template<typename = id_type>
  61290. struct fnv_1a_params;
  61291. template<>
  61292. struct fnv_1a_params<std::uint32_t> {
  61293. static constexpr auto offset = 2166136261;
  61294. static constexpr auto prime = 16777619;
  61295. };
  61296. template<>
  61297. struct fnv_1a_params<std::uint64_t> {
  61298. static constexpr auto offset = 14695981039346656037ull;
  61299. static constexpr auto prime = 1099511628211ull;
  61300. };
  61301. template<typename Char>
  61302. struct basic_hashed_string {
  61303. using value_type = Char;
  61304. using size_type = std::size_t;
  61305. using hash_type = id_type;
  61306. const value_type *repr{};
  61307. hash_type hash{fnv_1a_params<>::offset};
  61308. size_type length{};
  61309. };
  61310. } // namespace internal
  61311. /*! @endcond */
  61312. /**
  61313. * @brief Zero overhead unique identifier.
  61314. *
  61315. * A hashed string is a compile-time tool that allows users to use
  61316. * human-readable identifiers in the codebase while using their numeric
  61317. * counterparts at runtime.<br/>
  61318. * Because of that, a hashed string can also be used in constant expressions if
  61319. * required.
  61320. *
  61321. * @warning
  61322. * This class doesn't take ownership of user-supplied strings nor does it make a
  61323. * copy of them.
  61324. *
  61325. * @tparam Char Character type.
  61326. */
  61327. template<typename Char>
  61328. class basic_hashed_string: internal::basic_hashed_string<Char> {
  61329. using base_type = internal::basic_hashed_string<Char>;
  61330. using params = internal::fnv_1a_params<>;
  61331. struct const_wrapper {
  61332. // non-explicit constructor on purpose
  61333. constexpr const_wrapper(const typename base_type::value_type *str) noexcept
  61334. : repr{str} {}
  61335. const typename base_type::value_type *repr;
  61336. };
  61337. public:
  61338. /*! @brief Character type. */
  61339. using value_type = typename base_type::value_type;
  61340. /*! @brief Unsigned integer type. */
  61341. using size_type = typename base_type::size_type;
  61342. /*! @brief Unsigned integer type. */
  61343. using hash_type = typename base_type::hash_type;
  61344. /**
  61345. * @brief Returns directly the numeric representation of a string view.
  61346. * @param str Human-readable identifier.
  61347. * @param len Length of the string to hash.
  61348. * @return The numeric representation of the string.
  61349. */
  61350. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
  61351. return basic_hashed_string{str, len};
  61352. }
  61353. /**
  61354. * @brief Returns directly the numeric representation of a string.
  61355. * @tparam N Number of characters of the identifier.
  61356. * @param str Human-readable identifier.
  61357. * @return The numeric representation of the string.
  61358. */
  61359. template<std::size_t N>
  61360. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  61361. [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept {
  61362. return basic_hashed_string{str};
  61363. }
  61364. /**
  61365. * @brief Returns directly the numeric representation of a string.
  61366. * @param wrapper Helps achieving the purpose by relying on overloading.
  61367. * @return The numeric representation of the string.
  61368. */
  61369. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
  61370. return basic_hashed_string{wrapper};
  61371. }
  61372. /*! @brief Constructs an empty hashed string. */
  61373. constexpr basic_hashed_string() noexcept
  61374. : basic_hashed_string{nullptr, 0u} {}
  61375. /**
  61376. * @brief Constructs a hashed string from a string view.
  61377. * @param str Human-readable identifier.
  61378. * @param len Length of the string to hash.
  61379. */
  61380. constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
  61381. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  61382. : base_type{str} {
  61383. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  61384. for(; base_type::length < len; ++base_type::length) {
  61385. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  61386. }
  61387. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  61388. }
  61389. /**
  61390. * @brief Constructs a hashed string from an array of const characters.
  61391. * @tparam N Number of characters of the identifier.
  61392. * @param str Human-readable identifier.
  61393. */
  61394. template<std::size_t N>
  61395. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  61396. ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept
  61397. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  61398. : base_type{str} {
  61399. for(; str[base_type::length]; ++base_type::length) {
  61400. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  61401. }
  61402. }
  61403. /**
  61404. * @brief Explicit constructor on purpose to avoid constructing a hashed
  61405. * string directly from a `const value_type *`.
  61406. *
  61407. * @warning
  61408. * The lifetime of the string is not extended nor is it copied.
  61409. *
  61410. * @param wrapper Helps achieving the purpose by relying on overloading.
  61411. */
  61412. explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
  61413. : base_type{wrapper.repr} {
  61414. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  61415. for(; wrapper.repr[base_type::length]; ++base_type::length) {
  61416. base_type::hash = (base_type::hash ^ static_cast<id_type>(wrapper.repr[base_type::length])) * params::prime;
  61417. }
  61418. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  61419. }
  61420. /**
  61421. * @brief Returns the size of a hashed string.
  61422. * @return The size of the hashed string.
  61423. */
  61424. [[nodiscard]] constexpr size_type size() const noexcept {
  61425. return base_type::length;
  61426. }
  61427. /**
  61428. * @brief Returns the human-readable representation of a hashed string.
  61429. * @return The string used to initialize the hashed string.
  61430. */
  61431. [[nodiscard]] constexpr const value_type *data() const noexcept {
  61432. return base_type::repr;
  61433. }
  61434. /**
  61435. * @brief Returns the numeric representation of a hashed string.
  61436. * @return The numeric representation of the hashed string.
  61437. */
  61438. [[nodiscard]] constexpr hash_type value() const noexcept {
  61439. return base_type::hash;
  61440. }
  61441. /*! @copydoc data */
  61442. [[nodiscard]] explicit constexpr operator const value_type *() const noexcept {
  61443. return data();
  61444. }
  61445. /**
  61446. * @brief Returns the numeric representation of a hashed string.
  61447. * @return The numeric representation of the hashed string.
  61448. */
  61449. [[nodiscard]] constexpr operator hash_type() const noexcept {
  61450. return value();
  61451. }
  61452. };
  61453. /**
  61454. * @brief Deduction guide.
  61455. * @tparam Char Character type.
  61456. * @param str Human-readable identifier.
  61457. * @param len Length of the string to hash.
  61458. */
  61459. template<typename Char>
  61460. basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string<Char>;
  61461. /**
  61462. * @brief Deduction guide.
  61463. * @tparam Char Character type.
  61464. * @tparam N Number of characters of the identifier.
  61465. * @param str Human-readable identifier.
  61466. */
  61467. template<typename Char, std::size_t N>
  61468. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  61469. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  61470. /**
  61471. * @brief Compares two hashed strings.
  61472. * @tparam Char Character type.
  61473. * @param lhs A valid hashed string.
  61474. * @param rhs A valid hashed string.
  61475. * @return True if the two hashed strings are identical, false otherwise.
  61476. */
  61477. template<typename Char>
  61478. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  61479. return lhs.value() == rhs.value();
  61480. }
  61481. /**
  61482. * @brief Compares two hashed strings.
  61483. * @tparam Char Character type.
  61484. * @param lhs A valid hashed string.
  61485. * @param rhs A valid hashed string.
  61486. * @return True if the two hashed strings differ, false otherwise.
  61487. */
  61488. template<typename Char>
  61489. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  61490. return !(lhs == rhs);
  61491. }
  61492. /**
  61493. * @brief Compares two hashed strings.
  61494. * @tparam Char Character type.
  61495. * @param lhs A valid hashed string.
  61496. * @param rhs A valid hashed string.
  61497. * @return True if the first element is less than the second, false otherwise.
  61498. */
  61499. template<typename Char>
  61500. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  61501. return lhs.value() < rhs.value();
  61502. }
  61503. /**
  61504. * @brief Compares two hashed strings.
  61505. * @tparam Char Character type.
  61506. * @param lhs A valid hashed string.
  61507. * @param rhs A valid hashed string.
  61508. * @return True if the first element is less than or equal to the second, false
  61509. * otherwise.
  61510. */
  61511. template<typename Char>
  61512. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  61513. return !(rhs < lhs);
  61514. }
  61515. /**
  61516. * @brief Compares two hashed strings.
  61517. * @tparam Char Character type.
  61518. * @param lhs A valid hashed string.
  61519. * @param rhs A valid hashed string.
  61520. * @return True if the first element is greater than the second, false
  61521. * otherwise.
  61522. */
  61523. template<typename Char>
  61524. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  61525. return rhs < lhs;
  61526. }
  61527. /**
  61528. * @brief Compares two hashed strings.
  61529. * @tparam Char Character type.
  61530. * @param lhs A valid hashed string.
  61531. * @param rhs A valid hashed string.
  61532. * @return True if the first element is greater than or equal to the second,
  61533. * false otherwise.
  61534. */
  61535. template<typename Char>
  61536. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  61537. return !(lhs < rhs);
  61538. }
  61539. inline namespace literals {
  61540. /**
  61541. * @brief User defined literal for hashed strings.
  61542. * @param str The literal without its suffix.
  61543. * @return A properly initialized hashed string.
  61544. */
  61545. [[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept {
  61546. return hashed_string{str};
  61547. }
  61548. /**
  61549. * @brief User defined literal for hashed wstrings.
  61550. * @param str The literal without its suffix.
  61551. * @return A properly initialized hashed wstring.
  61552. */
  61553. [[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept {
  61554. return hashed_wstring{str};
  61555. }
  61556. } // namespace literals
  61557. } // namespace entt
  61558. #endif
  61559. namespace entt {
  61560. /*! @cond TURN_OFF_DOXYGEN */
  61561. namespace internal {
  61562. struct ENTT_API type_index final {
  61563. [[nodiscard]] static id_type next() noexcept {
  61564. static ENTT_MAYBE_ATOMIC(id_type) value{};
  61565. return value++;
  61566. }
  61567. };
  61568. template<typename Type>
  61569. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  61570. #if defined ENTT_PRETTY_FUNCTION
  61571. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  61572. #else
  61573. return "";
  61574. #endif
  61575. }
  61576. template<typename Type>
  61577. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  61578. #if defined ENTT_PRETTY_FUNCTION
  61579. const std::string_view full_name{pretty_function<Type>()};
  61580. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  61581. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  61582. return value;
  61583. #else
  61584. return std::string_view{};
  61585. #endif
  61586. }
  61587. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  61588. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  61589. constexpr auto value = stripped_type_name<Type>();
  61590. return value;
  61591. }
  61592. template<typename Type>
  61593. [[nodiscard]] std::string_view type_name(char) noexcept {
  61594. static const auto value = stripped_type_name<Type>();
  61595. return value;
  61596. }
  61597. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  61598. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  61599. constexpr auto stripped = stripped_type_name<Type>();
  61600. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  61601. return value;
  61602. }
  61603. template<typename Type>
  61604. [[nodiscard]] id_type type_hash(char) noexcept {
  61605. static const auto value = [](const auto stripped) {
  61606. return hashed_string::value(stripped.data(), stripped.size());
  61607. }(stripped_type_name<Type>());
  61608. return value;
  61609. }
  61610. } // namespace internal
  61611. /*! @endcond */
  61612. /**
  61613. * @brief Type sequential identifier.
  61614. * @tparam Type Type for which to generate a sequential identifier.
  61615. */
  61616. template<typename Type, typename = void>
  61617. struct ENTT_API type_index final {
  61618. /**
  61619. * @brief Returns the sequential identifier of a given type.
  61620. * @return The sequential identifier of a given type.
  61621. */
  61622. [[nodiscard]] static id_type value() noexcept {
  61623. static const id_type value = internal::type_index::next();
  61624. return value;
  61625. }
  61626. /*! @copydoc value */
  61627. [[nodiscard]] constexpr operator id_type() const noexcept {
  61628. return value();
  61629. }
  61630. };
  61631. /**
  61632. * @brief Type hash.
  61633. * @tparam Type Type for which to generate a hash value.
  61634. */
  61635. template<typename Type, typename = void>
  61636. struct type_hash final {
  61637. /**
  61638. * @brief Returns the numeric representation of a given type.
  61639. * @return The numeric representation of the given type.
  61640. */
  61641. #if defined ENTT_PRETTY_FUNCTION
  61642. [[nodiscard]] static constexpr id_type value() noexcept {
  61643. return internal::type_hash<Type>(0);
  61644. #else
  61645. [[nodiscard]] static constexpr id_type value() noexcept {
  61646. return type_index<Type>::value();
  61647. #endif
  61648. }
  61649. /*! @copydoc value */
  61650. [[nodiscard]] constexpr operator id_type() const noexcept {
  61651. return value();
  61652. }
  61653. };
  61654. /**
  61655. * @brief Type name.
  61656. * @tparam Type Type for which to generate a name.
  61657. */
  61658. template<typename Type, typename = void>
  61659. struct type_name final {
  61660. /**
  61661. * @brief Returns the name of a given type.
  61662. * @return The name of the given type.
  61663. */
  61664. [[nodiscard]] static constexpr std::string_view value() noexcept {
  61665. return internal::type_name<Type>(0);
  61666. }
  61667. /*! @copydoc value */
  61668. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  61669. return value();
  61670. }
  61671. };
  61672. /*! @brief Implementation specific information about a type. */
  61673. struct type_info final {
  61674. /**
  61675. * @brief Constructs a type info object for a given type.
  61676. * @tparam Type Type for which to construct a type info object.
  61677. */
  61678. template<typename Type>
  61679. // NOLINTBEGIN(modernize-use-transparent-functors)
  61680. constexpr type_info(std::in_place_type_t<Type>) noexcept
  61681. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  61682. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  61683. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  61684. // NOLINTEND(modernize-use-transparent-functors)
  61685. /**
  61686. * @brief Type index.
  61687. * @return Type index.
  61688. */
  61689. [[nodiscard]] constexpr id_type index() const noexcept {
  61690. return seq;
  61691. }
  61692. /**
  61693. * @brief Type hash.
  61694. * @return Type hash.
  61695. */
  61696. [[nodiscard]] constexpr id_type hash() const noexcept {
  61697. return identifier;
  61698. }
  61699. /**
  61700. * @brief Type name.
  61701. * @return Type name.
  61702. */
  61703. [[nodiscard]] constexpr std::string_view name() const noexcept {
  61704. return alias;
  61705. }
  61706. private:
  61707. id_type seq;
  61708. id_type identifier;
  61709. std::string_view alias;
  61710. };
  61711. /**
  61712. * @brief Compares the contents of two type info objects.
  61713. * @param lhs A type info object.
  61714. * @param rhs A type info object.
  61715. * @return True if the two type info objects are identical, false otherwise.
  61716. */
  61717. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  61718. return lhs.hash() == rhs.hash();
  61719. }
  61720. /**
  61721. * @brief Compares the contents of two type info objects.
  61722. * @param lhs A type info object.
  61723. * @param rhs A type info object.
  61724. * @return True if the two type info objects differ, false otherwise.
  61725. */
  61726. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  61727. return !(lhs == rhs);
  61728. }
  61729. /**
  61730. * @brief Compares two type info objects.
  61731. * @param lhs A valid type info object.
  61732. * @param rhs A valid type info object.
  61733. * @return True if the first element is less than the second, false otherwise.
  61734. */
  61735. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  61736. return lhs.index() < rhs.index();
  61737. }
  61738. /**
  61739. * @brief Compares two type info objects.
  61740. * @param lhs A valid type info object.
  61741. * @param rhs A valid type info object.
  61742. * @return True if the first element is less than or equal to the second, false
  61743. * otherwise.
  61744. */
  61745. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  61746. return !(rhs < lhs);
  61747. }
  61748. /**
  61749. * @brief Compares two type info objects.
  61750. * @param lhs A valid type info object.
  61751. * @param rhs A valid type info object.
  61752. * @return True if the first element is greater than the second, false
  61753. * otherwise.
  61754. */
  61755. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  61756. return rhs < lhs;
  61757. }
  61758. /**
  61759. * @brief Compares two type info objects.
  61760. * @param lhs A valid type info object.
  61761. * @param rhs A valid type info object.
  61762. * @return True if the first element is greater than or equal to the second,
  61763. * false otherwise.
  61764. */
  61765. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  61766. return !(lhs < rhs);
  61767. }
  61768. /**
  61769. * @brief Returns the type info object associated to a given type.
  61770. *
  61771. * The returned element refers to an object with static storage duration.<br/>
  61772. * The type doesn't need to be a complete type. If the type is a reference, the
  61773. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  61774. * are ignored.
  61775. *
  61776. * @tparam Type Type for which to generate a type info object.
  61777. * @return A reference to a properly initialized type info object.
  61778. */
  61779. template<typename Type>
  61780. [[nodiscard]] const type_info &type_id() noexcept {
  61781. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  61782. static const type_info instance{std::in_place_type<Type>};
  61783. return instance;
  61784. } else {
  61785. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  61786. }
  61787. }
  61788. /*! @copydoc type_id */
  61789. template<typename Type>
  61790. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  61791. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  61792. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  61793. }
  61794. } // namespace entt
  61795. #endif
  61796. // #include "type_traits.hpp"
  61797. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  61798. #define ENTT_CORE_TYPE_TRAITS_HPP
  61799. #include <cstddef>
  61800. #include <iterator>
  61801. #include <tuple>
  61802. #include <type_traits>
  61803. #include <utility>
  61804. // #include "../config/config.h"
  61805. // #include "fwd.hpp"
  61806. namespace entt {
  61807. /**
  61808. * @brief Utility class to disambiguate overloaded functions.
  61809. * @tparam N Number of choices available.
  61810. */
  61811. template<std::size_t N>
  61812. struct choice_t
  61813. // unfortunately, doxygen cannot parse such a construct
  61814. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  61815. {};
  61816. /*! @copybrief choice_t */
  61817. template<>
  61818. struct choice_t<0> {};
  61819. /**
  61820. * @brief Variable template for the choice trick.
  61821. * @tparam N Number of choices available.
  61822. */
  61823. template<std::size_t N>
  61824. inline constexpr choice_t<N> choice{};
  61825. /**
  61826. * @brief Identity type trait.
  61827. *
  61828. * Useful to establish non-deduced contexts in template argument deduction
  61829. * (waiting for C++20) or to provide types through function arguments.
  61830. *
  61831. * @tparam Type A type.
  61832. */
  61833. template<typename Type>
  61834. struct type_identity {
  61835. /*! @brief Identity type. */
  61836. using type = Type;
  61837. };
  61838. /**
  61839. * @brief Helper type.
  61840. * @tparam Type A type.
  61841. */
  61842. template<typename Type>
  61843. using type_identity_t = typename type_identity<Type>::type;
  61844. /**
  61845. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  61846. * @tparam Type The type of which to return the size.
  61847. */
  61848. template<typename Type, typename = void>
  61849. struct size_of: std::integral_constant<std::size_t, 0u> {};
  61850. /*! @copydoc size_of */
  61851. template<typename Type>
  61852. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  61853. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  61854. : std::integral_constant<std::size_t, sizeof(Type)> {};
  61855. /**
  61856. * @brief Helper variable template.
  61857. * @tparam Type The type of which to return the size.
  61858. */
  61859. template<typename Type>
  61860. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  61861. /**
  61862. * @brief Using declaration to be used to _repeat_ the same type a number of
  61863. * times equal to the size of a given parameter pack.
  61864. * @tparam Type A type to repeat.
  61865. */
  61866. template<typename Type, typename>
  61867. using unpack_as_type = Type;
  61868. /**
  61869. * @brief Helper variable template to be used to _repeat_ the same value a
  61870. * number of times equal to the size of a given parameter pack.
  61871. * @tparam Value A value to repeat.
  61872. */
  61873. template<auto Value, typename>
  61874. inline constexpr auto unpack_as_value = Value;
  61875. /**
  61876. * @brief Wraps a static constant.
  61877. * @tparam Value A static constant.
  61878. */
  61879. template<auto Value>
  61880. using integral_constant = std::integral_constant<decltype(Value), Value>;
  61881. /**
  61882. * @brief Alias template to facilitate the creation of named values.
  61883. * @tparam Value A constant value at least convertible to `id_type`.
  61884. */
  61885. template<id_type Value>
  61886. using tag = integral_constant<Value>;
  61887. /**
  61888. * @brief A class to use to push around lists of types, nothing more.
  61889. * @tparam Type Types provided by the type list.
  61890. */
  61891. template<typename... Type>
  61892. struct type_list {
  61893. /*! @brief Type list type. */
  61894. using type = type_list;
  61895. /*! @brief Compile-time number of elements in the type list. */
  61896. static constexpr auto size = sizeof...(Type);
  61897. };
  61898. /*! @brief Primary template isn't defined on purpose. */
  61899. template<std::size_t, typename>
  61900. struct type_list_element;
  61901. /**
  61902. * @brief Provides compile-time indexed access to the types of a type list.
  61903. * @tparam Index Index of the type to return.
  61904. * @tparam First First type provided by the type list.
  61905. * @tparam Other Other types provided by the type list.
  61906. */
  61907. template<std::size_t Index, typename First, typename... Other>
  61908. struct type_list_element<Index, type_list<First, Other...>>
  61909. : type_list_element<Index - 1u, type_list<Other...>> {};
  61910. /**
  61911. * @brief Provides compile-time indexed access to the types of a type list.
  61912. * @tparam First First type provided by the type list.
  61913. * @tparam Other Other types provided by the type list.
  61914. */
  61915. template<typename First, typename... Other>
  61916. struct type_list_element<0u, type_list<First, Other...>> {
  61917. /*! @brief Searched type. */
  61918. using type = First;
  61919. };
  61920. /**
  61921. * @brief Helper type.
  61922. * @tparam Index Index of the type to return.
  61923. * @tparam List Type list to search into.
  61924. */
  61925. template<std::size_t Index, typename List>
  61926. using type_list_element_t = typename type_list_element<Index, List>::type;
  61927. /*! @brief Primary template isn't defined on purpose. */
  61928. template<typename, typename>
  61929. struct type_list_index;
  61930. /**
  61931. * @brief Provides compile-time type access to the types of a type list.
  61932. * @tparam Type Type to look for and for which to return the index.
  61933. * @tparam First First type provided by the type list.
  61934. * @tparam Other Other types provided by the type list.
  61935. */
  61936. template<typename Type, typename First, typename... Other>
  61937. struct type_list_index<Type, type_list<First, Other...>> {
  61938. /*! @brief Unsigned integer type. */
  61939. using value_type = std::size_t;
  61940. /*! @brief Compile-time position of the given type in the sublist. */
  61941. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  61942. };
  61943. /**
  61944. * @brief Provides compile-time type access to the types of a type list.
  61945. * @tparam Type Type to look for and for which to return the index.
  61946. * @tparam Other Other types provided by the type list.
  61947. */
  61948. template<typename Type, typename... Other>
  61949. struct type_list_index<Type, type_list<Type, Other...>> {
  61950. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  61951. /*! @brief Unsigned integer type. */
  61952. using value_type = std::size_t;
  61953. /*! @brief Compile-time position of the given type in the sublist. */
  61954. static constexpr value_type value = 0u;
  61955. };
  61956. /**
  61957. * @brief Provides compile-time type access to the types of a type list.
  61958. * @tparam Type Type to look for and for which to return the index.
  61959. */
  61960. template<typename Type>
  61961. struct type_list_index<Type, type_list<>> {
  61962. /*! @brief Unsigned integer type. */
  61963. using value_type = std::size_t;
  61964. /*! @brief Compile-time position of the given type in the sublist. */
  61965. static constexpr value_type value = 0u;
  61966. };
  61967. /**
  61968. * @brief Helper variable template.
  61969. * @tparam List Type list.
  61970. * @tparam Type Type to look for and for which to return the index.
  61971. */
  61972. template<typename Type, typename List>
  61973. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  61974. /**
  61975. * @brief Concatenates multiple type lists.
  61976. * @tparam Type Types provided by the first type list.
  61977. * @tparam Other Types provided by the second type list.
  61978. * @return A type list composed by the types of both the type lists.
  61979. */
  61980. template<typename... Type, typename... Other>
  61981. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  61982. return {};
  61983. }
  61984. /*! @brief Primary template isn't defined on purpose. */
  61985. template<typename...>
  61986. struct type_list_cat;
  61987. /*! @brief Concatenates multiple type lists. */
  61988. template<>
  61989. struct type_list_cat<> {
  61990. /*! @brief A type list composed by the types of all the type lists. */
  61991. using type = type_list<>;
  61992. };
  61993. /**
  61994. * @brief Concatenates multiple type lists.
  61995. * @tparam Type Types provided by the first type list.
  61996. * @tparam Other Types provided by the second type list.
  61997. * @tparam List Other type lists, if any.
  61998. */
  61999. template<typename... Type, typename... Other, typename... List>
  62000. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  62001. /*! @brief A type list composed by the types of all the type lists. */
  62002. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  62003. };
  62004. /**
  62005. * @brief Concatenates multiple type lists.
  62006. * @tparam Type Types provided by the type list.
  62007. */
  62008. template<typename... Type>
  62009. struct type_list_cat<type_list<Type...>> {
  62010. /*! @brief A type list composed by the types of all the type lists. */
  62011. using type = type_list<Type...>;
  62012. };
  62013. /**
  62014. * @brief Helper type.
  62015. * @tparam List Type lists to concatenate.
  62016. */
  62017. template<typename... List>
  62018. using type_list_cat_t = typename type_list_cat<List...>::type;
  62019. /*! @cond TURN_OFF_DOXYGEN */
  62020. namespace internal {
  62021. template<typename...>
  62022. struct type_list_unique;
  62023. template<typename First, typename... Other, typename... Type>
  62024. struct type_list_unique<type_list<First, Other...>, Type...>
  62025. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  62026. template<typename... Type>
  62027. struct type_list_unique<type_list<>, Type...> {
  62028. using type = type_list<Type...>;
  62029. };
  62030. } // namespace internal
  62031. /*! @endcond */
  62032. /**
  62033. * @brief Removes duplicates types from a type list.
  62034. * @tparam List Type list.
  62035. */
  62036. template<typename List>
  62037. struct type_list_unique {
  62038. /*! @brief A type list without duplicate types. */
  62039. using type = typename internal::type_list_unique<List>::type;
  62040. };
  62041. /**
  62042. * @brief Helper type.
  62043. * @tparam List Type list.
  62044. */
  62045. template<typename List>
  62046. using type_list_unique_t = typename type_list_unique<List>::type;
  62047. /**
  62048. * @brief Provides the member constant `value` to true if a type list contains a
  62049. * given type, false otherwise.
  62050. * @tparam List Type list.
  62051. * @tparam Type Type to look for.
  62052. */
  62053. template<typename List, typename Type>
  62054. struct type_list_contains;
  62055. /**
  62056. * @copybrief type_list_contains
  62057. * @tparam Type Types provided by the type list.
  62058. * @tparam Other Type to look for.
  62059. */
  62060. template<typename... Type, typename Other>
  62061. struct type_list_contains<type_list<Type...>, Other>
  62062. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  62063. /**
  62064. * @brief Helper variable template.
  62065. * @tparam List Type list.
  62066. * @tparam Type Type to look for.
  62067. */
  62068. template<typename List, typename Type>
  62069. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  62070. /*! @brief Primary template isn't defined on purpose. */
  62071. template<typename...>
  62072. struct type_list_diff;
  62073. /**
  62074. * @brief Computes the difference between two type lists.
  62075. * @tparam Type Types provided by the first type list.
  62076. * @tparam Other Types provided by the second type list.
  62077. */
  62078. template<typename... Type, typename... Other>
  62079. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  62080. /*! @brief A type list that is the difference between the two type lists. */
  62081. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  62082. };
  62083. /**
  62084. * @brief Helper type.
  62085. * @tparam List Type lists between which to compute the difference.
  62086. */
  62087. template<typename... List>
  62088. using type_list_diff_t = typename type_list_diff<List...>::type;
  62089. /*! @brief Primary template isn't defined on purpose. */
  62090. template<typename, template<typename...> class>
  62091. struct type_list_transform;
  62092. /**
  62093. * @brief Applies a given _function_ to a type list and generate a new list.
  62094. * @tparam Type Types provided by the type list.
  62095. * @tparam Op Unary operation as template class with a type member named `type`.
  62096. */
  62097. template<typename... Type, template<typename...> class Op>
  62098. struct type_list_transform<type_list<Type...>, Op> {
  62099. /*! @brief Resulting type list after applying the transform function. */
  62100. // NOLINTNEXTLINE(modernize-type-traits)
  62101. using type = type_list<typename Op<Type>::type...>;
  62102. };
  62103. /**
  62104. * @brief Helper type.
  62105. * @tparam List Type list.
  62106. * @tparam Op Unary operation as template class with a type member named `type`.
  62107. */
  62108. template<typename List, template<typename...> class Op>
  62109. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  62110. /**
  62111. * @brief A class to use to push around lists of constant values, nothing more.
  62112. * @tparam Value Values provided by the value list.
  62113. */
  62114. template<auto... Value>
  62115. struct value_list {
  62116. /*! @brief Value list type. */
  62117. using type = value_list;
  62118. /*! @brief Compile-time number of elements in the value list. */
  62119. static constexpr auto size = sizeof...(Value);
  62120. };
  62121. /*! @brief Primary template isn't defined on purpose. */
  62122. template<std::size_t, typename>
  62123. struct value_list_element;
  62124. /**
  62125. * @brief Provides compile-time indexed access to the values of a value list.
  62126. * @tparam Index Index of the value to return.
  62127. * @tparam Value First value provided by the value list.
  62128. * @tparam Other Other values provided by the value list.
  62129. */
  62130. template<std::size_t Index, auto Value, auto... Other>
  62131. struct value_list_element<Index, value_list<Value, Other...>>
  62132. : value_list_element<Index - 1u, value_list<Other...>> {};
  62133. /**
  62134. * @brief Provides compile-time indexed access to the types of a type list.
  62135. * @tparam Value First value provided by the value list.
  62136. * @tparam Other Other values provided by the value list.
  62137. */
  62138. template<auto Value, auto... Other>
  62139. struct value_list_element<0u, value_list<Value, Other...>> {
  62140. /*! @brief Searched type. */
  62141. using type = decltype(Value);
  62142. /*! @brief Searched value. */
  62143. static constexpr auto value = Value;
  62144. };
  62145. /**
  62146. * @brief Helper type.
  62147. * @tparam Index Index of the type to return.
  62148. * @tparam List Value list to search into.
  62149. */
  62150. template<std::size_t Index, typename List>
  62151. using value_list_element_t = typename value_list_element<Index, List>::type;
  62152. /**
  62153. * @brief Helper type.
  62154. * @tparam Index Index of the value to return.
  62155. * @tparam List Value list to search into.
  62156. */
  62157. template<std::size_t Index, typename List>
  62158. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  62159. /*! @brief Primary template isn't defined on purpose. */
  62160. template<auto, typename>
  62161. struct value_list_index;
  62162. /**
  62163. * @brief Provides compile-time type access to the values of a value list.
  62164. * @tparam Value Value to look for and for which to return the index.
  62165. * @tparam First First value provided by the value list.
  62166. * @tparam Other Other values provided by the value list.
  62167. */
  62168. template<auto Value, auto First, auto... Other>
  62169. struct value_list_index<Value, value_list<First, Other...>> {
  62170. /*! @brief Unsigned integer type. */
  62171. using value_type = std::size_t;
  62172. /*! @brief Compile-time position of the given value in the sublist. */
  62173. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  62174. };
  62175. /**
  62176. * @brief Provides compile-time type access to the values of a value list.
  62177. * @tparam Value Value to look for and for which to return the index.
  62178. * @tparam Other Other values provided by the value list.
  62179. */
  62180. template<auto Value, auto... Other>
  62181. struct value_list_index<Value, value_list<Value, Other...>> {
  62182. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  62183. /*! @brief Unsigned integer type. */
  62184. using value_type = std::size_t;
  62185. /*! @brief Compile-time position of the given value in the sublist. */
  62186. static constexpr value_type value = 0u;
  62187. };
  62188. /**
  62189. * @brief Provides compile-time type access to the values of a value list.
  62190. * @tparam Value Value to look for and for which to return the index.
  62191. */
  62192. template<auto Value>
  62193. struct value_list_index<Value, value_list<>> {
  62194. /*! @brief Unsigned integer type. */
  62195. using value_type = std::size_t;
  62196. /*! @brief Compile-time position of the given type in the sublist. */
  62197. static constexpr value_type value = 0u;
  62198. };
  62199. /**
  62200. * @brief Helper variable template.
  62201. * @tparam List Value list.
  62202. * @tparam Value Value to look for and for which to return the index.
  62203. */
  62204. template<auto Value, typename List>
  62205. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  62206. /**
  62207. * @brief Concatenates multiple value lists.
  62208. * @tparam Value Values provided by the first value list.
  62209. * @tparam Other Values provided by the second value list.
  62210. * @return A value list composed by the values of both the value lists.
  62211. */
  62212. template<auto... Value, auto... Other>
  62213. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  62214. return {};
  62215. }
  62216. /*! @brief Primary template isn't defined on purpose. */
  62217. template<typename...>
  62218. struct value_list_cat;
  62219. /*! @brief Concatenates multiple value lists. */
  62220. template<>
  62221. struct value_list_cat<> {
  62222. /*! @brief A value list composed by the values of all the value lists. */
  62223. using type = value_list<>;
  62224. };
  62225. /**
  62226. * @brief Concatenates multiple value lists.
  62227. * @tparam Value Values provided by the first value list.
  62228. * @tparam Other Values provided by the second value list.
  62229. * @tparam List Other value lists, if any.
  62230. */
  62231. template<auto... Value, auto... Other, typename... List>
  62232. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  62233. /*! @brief A value list composed by the values of all the value lists. */
  62234. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  62235. };
  62236. /**
  62237. * @brief Concatenates multiple value lists.
  62238. * @tparam Value Values provided by the value list.
  62239. */
  62240. template<auto... Value>
  62241. struct value_list_cat<value_list<Value...>> {
  62242. /*! @brief A value list composed by the values of all the value lists. */
  62243. using type = value_list<Value...>;
  62244. };
  62245. /**
  62246. * @brief Helper type.
  62247. * @tparam List Value lists to concatenate.
  62248. */
  62249. template<typename... List>
  62250. using value_list_cat_t = typename value_list_cat<List...>::type;
  62251. /*! @brief Primary template isn't defined on purpose. */
  62252. template<typename>
  62253. struct value_list_unique;
  62254. /**
  62255. * @brief Removes duplicates values from a value list.
  62256. * @tparam Value One of the values provided by the given value list.
  62257. * @tparam Other The other values provided by the given value list.
  62258. */
  62259. template<auto Value, auto... Other>
  62260. struct value_list_unique<value_list<Value, Other...>> {
  62261. /*! @brief A value list without duplicate types. */
  62262. using type = std::conditional_t<
  62263. ((Value == Other) || ...),
  62264. typename value_list_unique<value_list<Other...>>::type,
  62265. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  62266. };
  62267. /*! @brief Removes duplicates values from a value list. */
  62268. template<>
  62269. struct value_list_unique<value_list<>> {
  62270. /*! @brief A value list without duplicate types. */
  62271. using type = value_list<>;
  62272. };
  62273. /**
  62274. * @brief Helper type.
  62275. * @tparam Type A value list.
  62276. */
  62277. template<typename Type>
  62278. using value_list_unique_t = typename value_list_unique<Type>::type;
  62279. /**
  62280. * @brief Provides the member constant `value` to true if a value list contains
  62281. * a given value, false otherwise.
  62282. * @tparam List Value list.
  62283. * @tparam Value Value to look for.
  62284. */
  62285. template<typename List, auto Value>
  62286. struct value_list_contains;
  62287. /**
  62288. * @copybrief value_list_contains
  62289. * @tparam Value Values provided by the value list.
  62290. * @tparam Other Value to look for.
  62291. */
  62292. template<auto... Value, auto Other>
  62293. struct value_list_contains<value_list<Value...>, Other>
  62294. : std::bool_constant<((Value == Other) || ...)> {};
  62295. /**
  62296. * @brief Helper variable template.
  62297. * @tparam List Value list.
  62298. * @tparam Value Value to look for.
  62299. */
  62300. template<typename List, auto Value>
  62301. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  62302. /*! @brief Primary template isn't defined on purpose. */
  62303. template<typename...>
  62304. struct value_list_diff;
  62305. /**
  62306. * @brief Computes the difference between two value lists.
  62307. * @tparam Value Values provided by the first value list.
  62308. * @tparam Other Values provided by the second value list.
  62309. */
  62310. template<auto... Value, auto... Other>
  62311. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  62312. /*! @brief A value list that is the difference between the two value lists. */
  62313. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  62314. };
  62315. /**
  62316. * @brief Helper type.
  62317. * @tparam List Value lists between which to compute the difference.
  62318. */
  62319. template<typename... List>
  62320. using value_list_diff_t = typename value_list_diff<List...>::type;
  62321. /*! @brief Same as std::is_invocable, but with tuples. */
  62322. template<typename, typename>
  62323. struct is_applicable: std::false_type {};
  62324. /**
  62325. * @copybrief is_applicable
  62326. * @tparam Func A valid function type.
  62327. * @tparam Tuple Tuple-like type.
  62328. * @tparam Args The list of arguments to use to probe the function type.
  62329. */
  62330. template<typename Func, template<typename...> class Tuple, typename... Args>
  62331. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  62332. /**
  62333. * @copybrief is_applicable
  62334. * @tparam Func A valid function type.
  62335. * @tparam Tuple Tuple-like type.
  62336. * @tparam Args The list of arguments to use to probe the function type.
  62337. */
  62338. template<typename Func, template<typename...> class Tuple, typename... Args>
  62339. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  62340. /**
  62341. * @brief Helper variable template.
  62342. * @tparam Func A valid function type.
  62343. * @tparam Args The list of arguments to use to probe the function type.
  62344. */
  62345. template<typename Func, typename Args>
  62346. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  62347. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  62348. template<typename, typename, typename>
  62349. struct is_applicable_r: std::false_type {};
  62350. /**
  62351. * @copybrief is_applicable_r
  62352. * @tparam Ret The type to which the return type of the function should be
  62353. * convertible.
  62354. * @tparam Func A valid function type.
  62355. * @tparam Args The list of arguments to use to probe the function type.
  62356. */
  62357. template<typename Ret, typename Func, typename... Args>
  62358. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  62359. /**
  62360. * @brief Helper variable template.
  62361. * @tparam Ret The type to which the return type of the function should be
  62362. * convertible.
  62363. * @tparam Func A valid function type.
  62364. * @tparam Args The list of arguments to use to probe the function type.
  62365. */
  62366. template<typename Ret, typename Func, typename Args>
  62367. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  62368. /**
  62369. * @brief Provides the member constant `value` to true if a given type is
  62370. * complete, false otherwise.
  62371. * @tparam Type The type to test.
  62372. */
  62373. template<typename Type, typename = void>
  62374. struct is_complete: std::false_type {};
  62375. /*! @copydoc is_complete */
  62376. template<typename Type>
  62377. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  62378. /**
  62379. * @brief Helper variable template.
  62380. * @tparam Type The type to test.
  62381. */
  62382. template<typename Type>
  62383. inline constexpr bool is_complete_v = is_complete<Type>::value;
  62384. /**
  62385. * @brief Provides the member constant `value` to true if a given type is an
  62386. * iterator, false otherwise.
  62387. * @tparam Type The type to test.
  62388. */
  62389. template<typename Type, typename = void>
  62390. struct is_iterator: std::false_type {};
  62391. /*! @cond TURN_OFF_DOXYGEN */
  62392. namespace internal {
  62393. template<typename, typename = void>
  62394. struct has_iterator_category: std::false_type {};
  62395. template<typename Type>
  62396. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  62397. } // namespace internal
  62398. /*! @endcond */
  62399. /*! @copydoc is_iterator */
  62400. template<typename Type>
  62401. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  62402. : internal::has_iterator_category<Type> {};
  62403. /**
  62404. * @brief Helper variable template.
  62405. * @tparam Type The type to test.
  62406. */
  62407. template<typename Type>
  62408. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  62409. /**
  62410. * @brief Provides the member constant `value` to true if a given type is both
  62411. * an empty and non-final class, false otherwise.
  62412. * @tparam Type The type to test
  62413. */
  62414. template<typename Type>
  62415. struct is_ebco_eligible
  62416. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  62417. /**
  62418. * @brief Helper variable template.
  62419. * @tparam Type The type to test.
  62420. */
  62421. template<typename Type>
  62422. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  62423. /**
  62424. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  62425. * is valid and denotes a type, false otherwise.
  62426. * @tparam Type The type to test.
  62427. */
  62428. template<typename Type, typename = void>
  62429. struct is_transparent: std::false_type {};
  62430. /*! @copydoc is_transparent */
  62431. template<typename Type>
  62432. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  62433. /**
  62434. * @brief Helper variable template.
  62435. * @tparam Type The type to test.
  62436. */
  62437. template<typename Type>
  62438. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  62439. /*! @cond TURN_OFF_DOXYGEN */
  62440. namespace internal {
  62441. template<typename, typename = void>
  62442. struct has_tuple_size_value: std::false_type {};
  62443. template<typename Type>
  62444. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  62445. template<typename, typename = void>
  62446. struct has_value_type: std::false_type {};
  62447. template<typename Type>
  62448. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  62449. template<typename>
  62450. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  62451. template<typename Type, std::size_t... Index>
  62452. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  62453. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  62454. }
  62455. template<typename>
  62456. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  62457. return false;
  62458. }
  62459. template<typename Type>
  62460. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  62461. return true;
  62462. }
  62463. template<typename Type>
  62464. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  62465. // NOLINTBEGIN(modernize-use-transparent-functors)
  62466. if constexpr(std::is_array_v<Type>) {
  62467. return false;
  62468. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  62469. if constexpr(has_tuple_size_value<Type>::value) {
  62470. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  62471. } else {
  62472. return maybe_equality_comparable<Type>(0);
  62473. }
  62474. } else if constexpr(has_value_type<Type>::value) {
  62475. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  62476. return maybe_equality_comparable<Type>(0);
  62477. } else {
  62478. return false;
  62479. }
  62480. } else {
  62481. return maybe_equality_comparable<Type>(0);
  62482. }
  62483. // NOLINTEND(modernize-use-transparent-functors)
  62484. }
  62485. } // namespace internal
  62486. /*! @endcond */
  62487. /**
  62488. * @brief Provides the member constant `value` to true if a given type is
  62489. * equality comparable, false otherwise.
  62490. * @tparam Type The type to test.
  62491. */
  62492. template<typename Type>
  62493. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  62494. /*! @copydoc is_equality_comparable */
  62495. template<typename Type>
  62496. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  62497. /**
  62498. * @brief Helper variable template.
  62499. * @tparam Type The type to test.
  62500. */
  62501. template<typename Type>
  62502. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  62503. /**
  62504. * @brief Transcribes the constness of a type to another type.
  62505. * @tparam To The type to which to transcribe the constness.
  62506. * @tparam From The type from which to transcribe the constness.
  62507. */
  62508. template<typename To, typename From>
  62509. struct constness_as {
  62510. /*! @brief The type resulting from the transcription of the constness. */
  62511. using type = std::remove_const_t<To>;
  62512. };
  62513. /*! @copydoc constness_as */
  62514. template<typename To, typename From>
  62515. struct constness_as<To, const From> {
  62516. /*! @brief The type resulting from the transcription of the constness. */
  62517. using type = const To;
  62518. };
  62519. /**
  62520. * @brief Alias template to facilitate the transcription of the constness.
  62521. * @tparam To The type to which to transcribe the constness.
  62522. * @tparam From The type from which to transcribe the constness.
  62523. */
  62524. template<typename To, typename From>
  62525. using constness_as_t = typename constness_as<To, From>::type;
  62526. /**
  62527. * @brief Extracts the class of a non-static member object or function.
  62528. * @tparam Member A pointer to a non-static member object or function.
  62529. */
  62530. template<typename Member>
  62531. class member_class {
  62532. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  62533. template<typename Class, typename Ret, typename... Args>
  62534. static Class *clazz(Ret (Class::*)(Args...));
  62535. template<typename Class, typename Ret, typename... Args>
  62536. static Class *clazz(Ret (Class::*)(Args...) const);
  62537. template<typename Class, typename Type>
  62538. static Class *clazz(Type Class::*);
  62539. public:
  62540. /*! @brief The class of the given non-static member object or function. */
  62541. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  62542. };
  62543. /**
  62544. * @brief Helper type.
  62545. * @tparam Member A pointer to a non-static member object or function.
  62546. */
  62547. template<typename Member>
  62548. using member_class_t = typename member_class<Member>::type;
  62549. /**
  62550. * @brief Extracts the n-th argument of a _callable_ type.
  62551. * @tparam Index The index of the argument to extract.
  62552. * @tparam Candidate A valid _callable_ type.
  62553. */
  62554. template<std::size_t Index, typename Candidate>
  62555. class nth_argument {
  62556. template<typename Ret, typename... Args>
  62557. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  62558. template<typename Ret, typename Class, typename... Args>
  62559. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  62560. template<typename Ret, typename Class, typename... Args>
  62561. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  62562. template<typename Type, typename Class>
  62563. static constexpr type_list<Type> pick_up(Type Class ::*);
  62564. template<typename Type>
  62565. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  62566. public:
  62567. /*! @brief N-th argument of the _callable_ type. */
  62568. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  62569. };
  62570. /**
  62571. * @brief Helper type.
  62572. * @tparam Index The index of the argument to extract.
  62573. * @tparam Candidate A valid function, member function or data member type.
  62574. */
  62575. template<std::size_t Index, typename Candidate>
  62576. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  62577. } // namespace entt
  62578. template<typename... Type>
  62579. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  62580. template<std::size_t Index, typename... Type>
  62581. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  62582. template<auto... Value>
  62583. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  62584. template<std::size_t Index, auto... Value>
  62585. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  62586. #endif
  62587. // #include "utility.hpp"
  62588. #ifndef ENTT_CORE_UTILITY_HPP
  62589. #define ENTT_CORE_UTILITY_HPP
  62590. #include <type_traits>
  62591. #include <utility>
  62592. namespace entt {
  62593. /*! @brief Identity function object (waiting for C++20). */
  62594. struct identity {
  62595. /*! @brief Indicates that this is a transparent function object. */
  62596. using is_transparent = void;
  62597. /**
  62598. * @brief Returns its argument unchanged.
  62599. * @tparam Type Type of the argument.
  62600. * @param value The actual argument.
  62601. * @return The submitted value as-is.
  62602. */
  62603. template<typename Type>
  62604. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  62605. return std::forward<Type>(value);
  62606. }
  62607. };
  62608. /**
  62609. * @brief Constant utility to disambiguate overloaded members of a class.
  62610. * @tparam Type Type of the desired overload.
  62611. * @tparam Class Type of class to which the member belongs.
  62612. * @param member A valid pointer to a member.
  62613. * @return Pointer to the member.
  62614. */
  62615. template<typename Type, typename Class>
  62616. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  62617. return member;
  62618. }
  62619. /**
  62620. * @brief Constant utility to disambiguate overloaded functions.
  62621. * @tparam Func Function type of the desired overload.
  62622. * @param func A valid pointer to a function.
  62623. * @return Pointer to the function.
  62624. */
  62625. template<typename Func>
  62626. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  62627. return func;
  62628. }
  62629. /**
  62630. * @brief Helper type for visitors.
  62631. * @tparam Func Types of function objects.
  62632. */
  62633. template<typename... Func>
  62634. struct overloaded: Func... {
  62635. using Func::operator()...;
  62636. };
  62637. /**
  62638. * @brief Deduction guide.
  62639. * @tparam Func Types of function objects.
  62640. */
  62641. template<typename... Func>
  62642. overloaded(Func...) -> overloaded<Func...>;
  62643. /**
  62644. * @brief Basic implementation of a y-combinator.
  62645. * @tparam Func Type of a potentially recursive function.
  62646. */
  62647. template<typename Func>
  62648. struct y_combinator {
  62649. /**
  62650. * @brief Constructs a y-combinator from a given function.
  62651. * @param recursive A potentially recursive function.
  62652. */
  62653. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  62654. : func{std::move(recursive)} {}
  62655. /**
  62656. * @brief Invokes a y-combinator and therefore its underlying function.
  62657. * @tparam Args Types of arguments to use to invoke the underlying function.
  62658. * @param args Parameters to use to invoke the underlying function.
  62659. * @return Return value of the underlying function, if any.
  62660. */
  62661. template<typename... Args>
  62662. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  62663. return func(*this, std::forward<Args>(args)...);
  62664. }
  62665. /*! @copydoc operator()() */
  62666. template<typename... Args>
  62667. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  62668. return func(*this, std::forward<Args>(args)...);
  62669. }
  62670. private:
  62671. Func func;
  62672. };
  62673. } // namespace entt
  62674. #endif
  62675. namespace entt {
  62676. /*! @cond TURN_OFF_DOXYGEN */
  62677. namespace internal {
  62678. enum class any_request : std::uint8_t {
  62679. info,
  62680. transfer,
  62681. assign,
  62682. compare,
  62683. copy,
  62684. move
  62685. };
  62686. template<std::size_t Len, std::size_t Align>
  62687. struct basic_any_storage {
  62688. static constexpr bool has_buffer = true;
  62689. union {
  62690. const void *instance{};
  62691. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  62692. alignas(Align) std::byte buffer[Len];
  62693. };
  62694. };
  62695. template<std::size_t Align>
  62696. struct basic_any_storage<0u, Align> {
  62697. static constexpr bool has_buffer = false;
  62698. const void *instance{};
  62699. };
  62700. template<typename Type, std::size_t Len, std::size_t Align>
  62701. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  62702. struct in_situ: std::bool_constant<(Len != 0u) && alignof(Type) <= Align && sizeof(Type) <= Len && std::is_nothrow_move_constructible_v<Type>> {};
  62703. template<std::size_t Len, std::size_t Align>
  62704. struct in_situ<void, Len, Align>: std::false_type {};
  62705. } // namespace internal
  62706. /*! @endcond */
  62707. /**
  62708. * @brief A SBO friendly, type-safe container for single values of any type.
  62709. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  62710. * @tparam Align Optional alignment requirement.
  62711. */
  62712. template<std::size_t Len, std::size_t Align>
  62713. class basic_any: private internal::basic_any_storage<Len, Align> {
  62714. using request = internal::any_request;
  62715. using base_type = internal::basic_any_storage<Len, Align>;
  62716. using vtable_type = const void *(const request, const basic_any &, const void *);
  62717. using deleter_type = void(const basic_any &);
  62718. template<typename Type>
  62719. static constexpr bool in_situ_v = internal::in_situ<Type, Len, Align>::value;
  62720. template<typename Type>
  62721. static const void *basic_vtable(const request req, const basic_any &value, const void *other) {
  62722. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  62723. switch(const auto *elem = static_cast<const Type *>(value.data()); req) {
  62724. case request::info:
  62725. return &type_id<Type>();
  62726. case request::transfer:
  62727. if constexpr(std::is_move_assignable_v<Type>) {
  62728. // NOLINTNEXTLINE(bugprone-casting-through-void)
  62729. *const_cast<Type *>(elem) = std::move(*static_cast<Type *>(const_cast<void *>(other)));
  62730. return other;
  62731. }
  62732. [[fallthrough]];
  62733. case request::assign:
  62734. if constexpr(std::is_copy_assignable_v<Type>) {
  62735. *const_cast<Type *>(elem) = *static_cast<const Type *>(other);
  62736. return other;
  62737. }
  62738. break;
  62739. case request::compare:
  62740. if constexpr(!std::is_function_v<Type> && !std::is_array_v<Type> && is_equality_comparable_v<Type>) {
  62741. return (*elem == *static_cast<const Type *>(other)) ? other : nullptr;
  62742. } else {
  62743. return (elem == other) ? other : nullptr;
  62744. }
  62745. case request::copy:
  62746. if constexpr(std::is_copy_constructible_v<Type>) {
  62747. // NOLINTNEXTLINE(bugprone-casting-through-void)
  62748. static_cast<basic_any *>(const_cast<void *>(other))->initialize<Type>(*elem);
  62749. }
  62750. break;
  62751. case request::move:
  62752. ENTT_ASSERT(value.mode == any_policy::embedded, "Unexpected policy");
  62753. if constexpr(in_situ_v<Type>) {
  62754. // NOLINTNEXTLINE(bugprone-casting-through-void, bugprone-multi-level-implicit-pointer-conversion)
  62755. return ::new(&static_cast<basic_any *>(const_cast<void *>(other))->buffer) Type{std::move(*const_cast<Type *>(elem))};
  62756. }
  62757. }
  62758. return nullptr;
  62759. }
  62760. template<typename Type>
  62761. static void basic_deleter(const basic_any &value) {
  62762. static_assert(std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, Type>, "Invalid type");
  62763. ENTT_ASSERT((value.mode == any_policy::dynamic) || ((value.mode == any_policy::embedded) && !std::is_trivially_destructible_v<Type>), "Unexpected policy");
  62764. const auto *elem = static_cast<const Type *>(value.data());
  62765. if constexpr(in_situ_v<Type>) {
  62766. (value.mode == any_policy::embedded) ? elem->~Type() : (delete elem);
  62767. } else if constexpr(std::is_array_v<Type>) {
  62768. delete[] elem;
  62769. } else {
  62770. delete elem;
  62771. }
  62772. }
  62773. template<typename Type, typename... Args>
  62774. void initialize([[maybe_unused]] Args &&...args) {
  62775. using plain_type = std::remove_const_t<std::remove_reference_t<Type>>;
  62776. vtable = basic_vtable<plain_type>;
  62777. underlying_type = type_hash<plain_type>::value();
  62778. if constexpr(std::is_void_v<Type>) {
  62779. deleter = nullptr;
  62780. mode = any_policy::empty;
  62781. this->instance = nullptr;
  62782. } else if constexpr(std::is_lvalue_reference_v<Type>) {
  62783. deleter = nullptr;
  62784. mode = std::is_const_v<std::remove_reference_t<Type>> ? any_policy::cref : any_policy::ref;
  62785. static_assert((std::is_lvalue_reference_v<Args> && ...) && (sizeof...(Args) == 1u), "Invalid arguments");
  62786. // NOLINTNEXTLINE(bugprone-multi-level-implicit-pointer-conversion)
  62787. this->instance = (std::addressof(args), ...);
  62788. } else if constexpr(in_situ_v<plain_type>) {
  62789. if constexpr(std::is_trivially_destructible_v<plain_type>) {
  62790. deleter = nullptr;
  62791. } else {
  62792. deleter = &basic_deleter<plain_type>;
  62793. }
  62794. mode = any_policy::embedded;
  62795. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  62796. ::new(&this->buffer) plain_type{std::forward<Args>(args)...};
  62797. } else {
  62798. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  62799. ::new(&this->buffer) plain_type(std::forward<Args>(args)...);
  62800. }
  62801. } else {
  62802. deleter = &basic_deleter<plain_type>;
  62803. mode = any_policy::dynamic;
  62804. if constexpr(std::is_aggregate_v<plain_type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<plain_type>)) {
  62805. this->instance = new plain_type{std::forward<Args>(args)...};
  62806. } else if constexpr(std::is_array_v<plain_type>) {
  62807. static_assert(sizeof...(Args) == 0u, "Invalid arguments");
  62808. this->instance = new plain_type[std::extent_v<plain_type>]();
  62809. } else {
  62810. this->instance = new plain_type(std::forward<Args>(args)...);
  62811. }
  62812. }
  62813. }
  62814. void invoke_deleter_if_exists() {
  62815. if(deleter != nullptr) {
  62816. deleter(*this);
  62817. }
  62818. }
  62819. public:
  62820. /*! @brief Size of the internal buffer. */
  62821. static constexpr auto length = Len;
  62822. /*! @brief Alignment requirement. */
  62823. static constexpr auto alignment = Align;
  62824. /*! @brief Default constructor. */
  62825. constexpr basic_any() noexcept
  62826. : basic_any{std::in_place_type<void>} {}
  62827. /**
  62828. * @brief Constructs a wrapper by directly initializing the new object.
  62829. * @tparam Type Type of object to use to initialize the wrapper.
  62830. * @tparam Args Types of arguments to use to construct the new instance.
  62831. * @param args Parameters to use to construct the instance.
  62832. */
  62833. template<typename Type, typename... Args>
  62834. explicit basic_any(std::in_place_type_t<Type>, Args &&...args)
  62835. : base_type{} {
  62836. initialize<Type>(std::forward<Args>(args)...);
  62837. }
  62838. /**
  62839. * @brief Constructs a wrapper taking ownership of the passed object.
  62840. * @tparam Type Type of object to use to initialize the wrapper.
  62841. * @param value A pointer to an object to take ownership of.
  62842. */
  62843. template<typename Type>
  62844. explicit basic_any(std::in_place_t, Type *value)
  62845. : base_type{} {
  62846. static_assert(!std::is_const_v<Type> && !std::is_void_v<Type>, "Non-const non-void pointer required");
  62847. if(value == nullptr) {
  62848. initialize<void>();
  62849. } else {
  62850. initialize<Type &>(*value);
  62851. deleter = &basic_deleter<Type>;
  62852. mode = any_policy::dynamic;
  62853. }
  62854. }
  62855. /**
  62856. * @brief Constructs a wrapper from a given value.
  62857. * @tparam Type Type of object to use to initialize the wrapper.
  62858. * @param value An instance of an object to use to initialize the wrapper.
  62859. */
  62860. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  62861. basic_any(Type &&value)
  62862. : basic_any{std::in_place_type<std::decay_t<Type>>, std::forward<Type>(value)} {}
  62863. /**
  62864. * @brief Copy constructor.
  62865. * @param other The instance to copy from.
  62866. */
  62867. basic_any(const basic_any &other)
  62868. : basic_any{} {
  62869. other.vtable(request::copy, other, this);
  62870. }
  62871. /**
  62872. * @brief Move constructor.
  62873. * @param other The instance to move from.
  62874. */
  62875. basic_any(basic_any &&other) noexcept
  62876. : base_type{},
  62877. vtable{other.vtable},
  62878. deleter{other.deleter},
  62879. underlying_type{other.underlying_type},
  62880. mode{other.mode} {
  62881. if(other.mode == any_policy::embedded) {
  62882. other.vtable(request::move, other, this);
  62883. } else if(other.mode != any_policy::empty) {
  62884. this->instance = std::exchange(other.instance, nullptr);
  62885. }
  62886. }
  62887. /*! @brief Frees the internal buffer, whatever it means. */
  62888. ~basic_any() {
  62889. invoke_deleter_if_exists();
  62890. }
  62891. /**
  62892. * @brief Copy assignment operator.
  62893. * @param other The instance to copy from.
  62894. * @return This any object.
  62895. */
  62896. basic_any &operator=(const basic_any &other) {
  62897. if(this != &other) {
  62898. invoke_deleter_if_exists();
  62899. if(other) {
  62900. other.vtable(request::copy, other, this);
  62901. } else {
  62902. initialize<void>();
  62903. }
  62904. }
  62905. return *this;
  62906. }
  62907. /**
  62908. * @brief Move assignment operator.
  62909. * @param other The instance to move from.
  62910. * @return This any object.
  62911. */
  62912. basic_any &operator=(basic_any &&other) noexcept {
  62913. if(this != &other) {
  62914. invoke_deleter_if_exists();
  62915. if(other.mode == any_policy::embedded) {
  62916. other.vtable(request::move, other, this);
  62917. } else if(other.mode != any_policy::empty) {
  62918. this->instance = std::exchange(other.instance, nullptr);
  62919. }
  62920. vtable = other.vtable;
  62921. deleter = other.deleter;
  62922. underlying_type = other.underlying_type;
  62923. mode = other.mode;
  62924. }
  62925. return *this;
  62926. }
  62927. /**
  62928. * @brief Value assignment operator.
  62929. * @tparam Type Type of object to use to initialize the wrapper.
  62930. * @param value An instance of an object to use to initialize the wrapper.
  62931. * @return This any object.
  62932. */
  62933. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::decay_t<Type>, basic_any>>>
  62934. basic_any &operator=(Type &&value) {
  62935. emplace<std::decay_t<Type>>(std::forward<Type>(value));
  62936. return *this;
  62937. }
  62938. /**
  62939. * @brief Returns false if a wrapper is empty, true otherwise.
  62940. * @return False if the wrapper is empty, true otherwise.
  62941. */
  62942. [[nodiscard]] bool has_value() const noexcept {
  62943. return (mode != any_policy::empty);
  62944. }
  62945. /**
  62946. * @brief Returns false if the wrapper does not contain the expected type,
  62947. * true otherwise.
  62948. * @param req Expected type.
  62949. * @return False if the wrapper does not contain the expected type, true
  62950. * otherwise.
  62951. */
  62952. [[nodiscard]] bool has_value(const type_info &req) const noexcept {
  62953. return (underlying_type == req.hash());
  62954. }
  62955. /**
  62956. * @brief Returns false if the wrapper does not contain the expected type,
  62957. * true otherwise.
  62958. * @tparam Type Expected type.
  62959. * @return False if the wrapper does not contain the expected type, true
  62960. * otherwise.
  62961. */
  62962. template<typename Type>
  62963. [[nodiscard]] bool has_value() const noexcept {
  62964. static_assert(std::is_same_v<std::remove_const_t<Type>, Type>, "Invalid type");
  62965. return (underlying_type == type_hash<Type>::value());
  62966. }
  62967. /**
  62968. * @brief Returns the object type info if any, `type_id<void>()` otherwise.
  62969. * @return The object type info if any, `type_id<void>()` otherwise.
  62970. */
  62971. [[nodiscard]] const type_info &info() const noexcept {
  62972. return *static_cast<const type_info *>(vtable(request::info, *this, nullptr));
  62973. }
  62974. /*! @copydoc info */
  62975. [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept {
  62976. return info();
  62977. }
  62978. /**
  62979. * @brief Returns an opaque pointer to the contained instance.
  62980. * @return An opaque pointer the contained instance, if any.
  62981. */
  62982. [[nodiscard]] const void *data() const noexcept {
  62983. if constexpr(base_type::has_buffer) {
  62984. return (mode == any_policy::embedded) ? &this->buffer : this->instance;
  62985. } else {
  62986. return this->instance;
  62987. }
  62988. }
  62989. /**
  62990. * @brief Returns an opaque pointer to the contained instance.
  62991. * @param req Expected type.
  62992. * @return An opaque pointer the contained instance, if any.
  62993. */
  62994. [[nodiscard]] const void *data(const type_info &req) const noexcept {
  62995. return has_value(req) ? data() : nullptr;
  62996. }
  62997. /**
  62998. * @brief Returns an opaque pointer to the contained instance.
  62999. * @tparam Type Expected type.
  63000. * @return An opaque pointer the contained instance, if any.
  63001. */
  63002. template<typename Type>
  63003. [[nodiscard]] const Type *data() const noexcept {
  63004. return has_value<std::remove_const_t<Type>>() ? static_cast<const Type *>(data()) : nullptr;
  63005. }
  63006. /**
  63007. * @brief Returns an opaque pointer to the contained instance.
  63008. * @return An opaque pointer the contained instance, if any.
  63009. */
  63010. [[nodiscard]] void *data() noexcept {
  63011. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data());
  63012. }
  63013. /**
  63014. * @brief Returns an opaque pointer to the contained instance.
  63015. * @param req Expected type.
  63016. * @return An opaque pointer the contained instance, if any.
  63017. */
  63018. [[nodiscard]] void *data(const type_info &req) noexcept {
  63019. return (mode == any_policy::cref) ? nullptr : const_cast<void *>(std::as_const(*this).data(req));
  63020. }
  63021. /**
  63022. * @brief Returns an opaque pointer to the contained instance.
  63023. * @tparam Type Expected type.
  63024. * @return An opaque pointer the contained instance, if any.
  63025. */
  63026. template<typename Type>
  63027. [[nodiscard]] Type *data() noexcept {
  63028. if constexpr(std::is_const_v<Type>) {
  63029. return std::as_const(*this).template data<std::remove_const_t<Type>>();
  63030. } else {
  63031. return (mode == any_policy::cref) ? nullptr : const_cast<Type *>(std::as_const(*this).template data<std::remove_const_t<Type>>());
  63032. }
  63033. }
  63034. /**
  63035. * @brief Replaces the contained object by creating a new instance directly.
  63036. * @tparam Type Type of object to use to initialize the wrapper.
  63037. * @tparam Args Types of arguments to use to construct the new instance.
  63038. * @param args Parameters to use to construct the instance.
  63039. */
  63040. template<typename Type, typename... Args>
  63041. void emplace(Args &&...args) {
  63042. invoke_deleter_if_exists();
  63043. initialize<Type>(std::forward<Args>(args)...);
  63044. }
  63045. /**
  63046. * @brief Assigns a value to the contained object without replacing it.
  63047. * @param other The value to assign to the contained object.
  63048. * @return True in case of success, false otherwise.
  63049. */
  63050. bool assign(const basic_any &other) {
  63051. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  63052. return (vtable(request::assign, *this, other.data()) != nullptr);
  63053. }
  63054. return false;
  63055. }
  63056. /*! @copydoc assign */
  63057. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  63058. bool assign(basic_any &&other) {
  63059. if(other && (mode != any_policy::cref) && (underlying_type == other.underlying_type)) {
  63060. return (other.mode == any_policy::cref) ? (vtable(request::assign, *this, std::as_const(other).data()) != nullptr) : (vtable(request::transfer, *this, other.data()) != nullptr);
  63061. }
  63062. return false;
  63063. }
  63064. /*! @brief Destroys contained object */
  63065. void reset() {
  63066. invoke_deleter_if_exists();
  63067. initialize<void>();
  63068. }
  63069. /**
  63070. * @brief Returns false if a wrapper is empty, true otherwise.
  63071. * @return False if the wrapper is empty, true otherwise.
  63072. */
  63073. [[nodiscard]] explicit operator bool() const noexcept {
  63074. return has_value();
  63075. }
  63076. /**
  63077. * @brief Checks if two wrappers differ in their content.
  63078. * @param other Wrapper with which to compare.
  63079. * @return False if the two objects differ in their content, true otherwise.
  63080. */
  63081. [[nodiscard]] bool operator==(const basic_any &other) const noexcept {
  63082. if(other && (underlying_type == other.underlying_type)) {
  63083. return (vtable(request::compare, *this, other.data()) != nullptr);
  63084. }
  63085. return (!*this && !other);
  63086. }
  63087. /**
  63088. * @brief Checks if two wrappers differ in their content.
  63089. * @param other Wrapper with which to compare.
  63090. * @return True if the two objects differ in their content, false otherwise.
  63091. */
  63092. [[nodiscard]] bool operator!=(const basic_any &other) const noexcept {
  63093. return !(*this == other);
  63094. }
  63095. /**
  63096. * @brief Aliasing constructor.
  63097. * @return A wrapper that shares a reference to an unmanaged object.
  63098. */
  63099. [[nodiscard]] basic_any as_ref() noexcept {
  63100. basic_any other = std::as_const(*this).as_ref();
  63101. other.mode = (mode == any_policy::cref ? any_policy::cref : any_policy::ref);
  63102. return other;
  63103. }
  63104. /*! @copydoc as_ref */
  63105. [[nodiscard]] basic_any as_ref() const noexcept {
  63106. basic_any other{};
  63107. other.instance = data();
  63108. other.vtable = vtable;
  63109. other.underlying_type = underlying_type;
  63110. other.mode = any_policy::cref;
  63111. return other;
  63112. }
  63113. /**
  63114. * @brief Returns true if a wrapper owns its object, false otherwise.
  63115. * @return True if the wrapper owns its object, false otherwise.
  63116. */
  63117. [[nodiscard]] bool owner() const noexcept {
  63118. return (mode == any_policy::dynamic || mode == any_policy::embedded);
  63119. }
  63120. /**
  63121. * @brief Returns the current mode of an any object.
  63122. * @return The current mode of the any object.
  63123. */
  63124. [[nodiscard]] any_policy policy() const noexcept {
  63125. return mode;
  63126. }
  63127. private:
  63128. vtable_type *vtable{};
  63129. deleter_type *deleter{};
  63130. id_type underlying_type{};
  63131. any_policy mode{};
  63132. };
  63133. /**
  63134. * @brief Performs type-safe access to the contained object.
  63135. * @tparam Type Type to which conversion is required.
  63136. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  63137. * @tparam Align Alignment requirement.
  63138. * @param data Target any object.
  63139. * @return The element converted to the requested type.
  63140. */
  63141. template<typename Type, std::size_t Len, std::size_t Align>
  63142. [[nodiscard]] std::remove_const_t<Type> any_cast(const basic_any<Len, Align> &data) noexcept {
  63143. const auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  63144. ENTT_ASSERT(instance, "Invalid instance");
  63145. return static_cast<Type>(*instance);
  63146. }
  63147. /*! @copydoc any_cast */
  63148. template<typename Type, std::size_t Len, std::size_t Align>
  63149. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &data) noexcept {
  63150. // forces const on non-reference types to make them work also with wrappers for const references
  63151. auto *const instance = any_cast<std::remove_reference_t<const Type>>(&data);
  63152. ENTT_ASSERT(instance, "Invalid instance");
  63153. return static_cast<Type>(*instance);
  63154. }
  63155. /*! @copydoc any_cast */
  63156. template<typename Type, std::size_t Len, std::size_t Align>
  63157. // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved)
  63158. [[nodiscard]] std::remove_const_t<Type> any_cast(basic_any<Len, Align> &&data) noexcept {
  63159. if constexpr(std::is_copy_constructible_v<std::remove_const_t<std::remove_reference_t<Type>>>) {
  63160. if(auto *const instance = any_cast<std::remove_reference_t<Type>>(&data); instance) {
  63161. return static_cast<Type>(std::move(*instance));
  63162. }
  63163. return any_cast<Type>(data);
  63164. } else {
  63165. auto *const instance = any_cast<std::remove_reference_t<Type>>(&data);
  63166. ENTT_ASSERT(instance, "Invalid instance");
  63167. return static_cast<Type>(std::move(*instance));
  63168. }
  63169. }
  63170. /*! @copydoc any_cast */
  63171. template<typename Type, std::size_t Len, std::size_t Align>
  63172. [[nodiscard]] const Type *any_cast(const basic_any<Len, Align> *data) noexcept {
  63173. return data->template data<std::remove_const_t<Type>>();
  63174. }
  63175. /*! @copydoc any_cast */
  63176. template<typename Type, std::size_t Len, std::size_t Align>
  63177. [[nodiscard]] Type *any_cast(basic_any<Len, Align> *data) noexcept {
  63178. if constexpr(std::is_const_v<Type>) {
  63179. // last attempt to make wrappers for const references return their values
  63180. return any_cast<Type>(&std::as_const(*data));
  63181. } else {
  63182. return data->template data<Type>();
  63183. }
  63184. }
  63185. /**
  63186. * @brief Constructs a wrapper from a given type, passing it all arguments.
  63187. * @tparam Type Type of object to use to initialize the wrapper.
  63188. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  63189. * @tparam Align Optional alignment requirement.
  63190. * @tparam Args Types of arguments to use to construct the new instance.
  63191. * @param args Parameters to use to construct the instance.
  63192. * @return A properly initialized wrapper for an object of the given type.
  63193. */
  63194. template<typename Type, std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename... Args>
  63195. [[nodiscard]] basic_any<Len, Align> make_any(Args &&...args) {
  63196. return basic_any<Len, Align>{std::in_place_type<Type>, std::forward<Args>(args)...};
  63197. }
  63198. /**
  63199. * @brief Forwards its argument and avoids copies for lvalue references.
  63200. * @tparam Len Size of the buffer reserved for the small buffer optimization.
  63201. * @tparam Align Optional alignment requirement.
  63202. * @tparam Type Type of argument to use to construct the new instance.
  63203. * @param value Parameter to use to construct the instance.
  63204. * @return A properly initialized and not necessarily owning wrapper.
  63205. */
  63206. template<std::size_t Len = basic_any<>::length, std::size_t Align = basic_any<Len>::alignment, typename Type>
  63207. [[nodiscard]] basic_any<Len, Align> forward_as_any(Type &&value) {
  63208. return basic_any<Len, Align>{std::in_place_type<Type &&>, std::forward<Type>(value)};
  63209. }
  63210. } // namespace entt
  63211. #endif
  63212. // #include "../core/type_info.hpp"
  63213. #ifndef ENTT_CORE_TYPE_INFO_HPP
  63214. #define ENTT_CORE_TYPE_INFO_HPP
  63215. #include <string_view>
  63216. #include <type_traits>
  63217. #include <utility>
  63218. // #include "../config/config.h"
  63219. // #include "fwd.hpp"
  63220. // #include "hashed_string.hpp"
  63221. namespace entt {
  63222. /*! @cond TURN_OFF_DOXYGEN */
  63223. namespace internal {
  63224. struct ENTT_API type_index final {
  63225. [[nodiscard]] static id_type next() noexcept {
  63226. static ENTT_MAYBE_ATOMIC(id_type) value{};
  63227. return value++;
  63228. }
  63229. };
  63230. template<typename Type>
  63231. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  63232. #if defined ENTT_PRETTY_FUNCTION
  63233. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  63234. #else
  63235. return "";
  63236. #endif
  63237. }
  63238. template<typename Type>
  63239. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  63240. #if defined ENTT_PRETTY_FUNCTION
  63241. const std::string_view full_name{pretty_function<Type>()};
  63242. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  63243. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  63244. return value;
  63245. #else
  63246. return std::string_view{};
  63247. #endif
  63248. }
  63249. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  63250. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  63251. constexpr auto value = stripped_type_name<Type>();
  63252. return value;
  63253. }
  63254. template<typename Type>
  63255. [[nodiscard]] std::string_view type_name(char) noexcept {
  63256. static const auto value = stripped_type_name<Type>();
  63257. return value;
  63258. }
  63259. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  63260. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  63261. constexpr auto stripped = stripped_type_name<Type>();
  63262. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  63263. return value;
  63264. }
  63265. template<typename Type>
  63266. [[nodiscard]] id_type type_hash(char) noexcept {
  63267. static const auto value = [](const auto stripped) {
  63268. return hashed_string::value(stripped.data(), stripped.size());
  63269. }(stripped_type_name<Type>());
  63270. return value;
  63271. }
  63272. } // namespace internal
  63273. /*! @endcond */
  63274. /**
  63275. * @brief Type sequential identifier.
  63276. * @tparam Type Type for which to generate a sequential identifier.
  63277. */
  63278. template<typename Type, typename = void>
  63279. struct ENTT_API type_index final {
  63280. /**
  63281. * @brief Returns the sequential identifier of a given type.
  63282. * @return The sequential identifier of a given type.
  63283. */
  63284. [[nodiscard]] static id_type value() noexcept {
  63285. static const id_type value = internal::type_index::next();
  63286. return value;
  63287. }
  63288. /*! @copydoc value */
  63289. [[nodiscard]] constexpr operator id_type() const noexcept {
  63290. return value();
  63291. }
  63292. };
  63293. /**
  63294. * @brief Type hash.
  63295. * @tparam Type Type for which to generate a hash value.
  63296. */
  63297. template<typename Type, typename = void>
  63298. struct type_hash final {
  63299. /**
  63300. * @brief Returns the numeric representation of a given type.
  63301. * @return The numeric representation of the given type.
  63302. */
  63303. #if defined ENTT_PRETTY_FUNCTION
  63304. [[nodiscard]] static constexpr id_type value() noexcept {
  63305. return internal::type_hash<Type>(0);
  63306. #else
  63307. [[nodiscard]] static constexpr id_type value() noexcept {
  63308. return type_index<Type>::value();
  63309. #endif
  63310. }
  63311. /*! @copydoc value */
  63312. [[nodiscard]] constexpr operator id_type() const noexcept {
  63313. return value();
  63314. }
  63315. };
  63316. /**
  63317. * @brief Type name.
  63318. * @tparam Type Type for which to generate a name.
  63319. */
  63320. template<typename Type, typename = void>
  63321. struct type_name final {
  63322. /**
  63323. * @brief Returns the name of a given type.
  63324. * @return The name of the given type.
  63325. */
  63326. [[nodiscard]] static constexpr std::string_view value() noexcept {
  63327. return internal::type_name<Type>(0);
  63328. }
  63329. /*! @copydoc value */
  63330. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  63331. return value();
  63332. }
  63333. };
  63334. /*! @brief Implementation specific information about a type. */
  63335. struct type_info final {
  63336. /**
  63337. * @brief Constructs a type info object for a given type.
  63338. * @tparam Type Type for which to construct a type info object.
  63339. */
  63340. template<typename Type>
  63341. // NOLINTBEGIN(modernize-use-transparent-functors)
  63342. constexpr type_info(std::in_place_type_t<Type>) noexcept
  63343. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  63344. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  63345. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  63346. // NOLINTEND(modernize-use-transparent-functors)
  63347. /**
  63348. * @brief Type index.
  63349. * @return Type index.
  63350. */
  63351. [[nodiscard]] constexpr id_type index() const noexcept {
  63352. return seq;
  63353. }
  63354. /**
  63355. * @brief Type hash.
  63356. * @return Type hash.
  63357. */
  63358. [[nodiscard]] constexpr id_type hash() const noexcept {
  63359. return identifier;
  63360. }
  63361. /**
  63362. * @brief Type name.
  63363. * @return Type name.
  63364. */
  63365. [[nodiscard]] constexpr std::string_view name() const noexcept {
  63366. return alias;
  63367. }
  63368. private:
  63369. id_type seq;
  63370. id_type identifier;
  63371. std::string_view alias;
  63372. };
  63373. /**
  63374. * @brief Compares the contents of two type info objects.
  63375. * @param lhs A type info object.
  63376. * @param rhs A type info object.
  63377. * @return True if the two type info objects are identical, false otherwise.
  63378. */
  63379. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  63380. return lhs.hash() == rhs.hash();
  63381. }
  63382. /**
  63383. * @brief Compares the contents of two type info objects.
  63384. * @param lhs A type info object.
  63385. * @param rhs A type info object.
  63386. * @return True if the two type info objects differ, false otherwise.
  63387. */
  63388. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  63389. return !(lhs == rhs);
  63390. }
  63391. /**
  63392. * @brief Compares two type info objects.
  63393. * @param lhs A valid type info object.
  63394. * @param rhs A valid type info object.
  63395. * @return True if the first element is less than the second, false otherwise.
  63396. */
  63397. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  63398. return lhs.index() < rhs.index();
  63399. }
  63400. /**
  63401. * @brief Compares two type info objects.
  63402. * @param lhs A valid type info object.
  63403. * @param rhs A valid type info object.
  63404. * @return True if the first element is less than or equal to the second, false
  63405. * otherwise.
  63406. */
  63407. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  63408. return !(rhs < lhs);
  63409. }
  63410. /**
  63411. * @brief Compares two type info objects.
  63412. * @param lhs A valid type info object.
  63413. * @param rhs A valid type info object.
  63414. * @return True if the first element is greater than the second, false
  63415. * otherwise.
  63416. */
  63417. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  63418. return rhs < lhs;
  63419. }
  63420. /**
  63421. * @brief Compares two type info objects.
  63422. * @param lhs A valid type info object.
  63423. * @param rhs A valid type info object.
  63424. * @return True if the first element is greater than or equal to the second,
  63425. * false otherwise.
  63426. */
  63427. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  63428. return !(lhs < rhs);
  63429. }
  63430. /**
  63431. * @brief Returns the type info object associated to a given type.
  63432. *
  63433. * The returned element refers to an object with static storage duration.<br/>
  63434. * The type doesn't need to be a complete type. If the type is a reference, the
  63435. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  63436. * are ignored.
  63437. *
  63438. * @tparam Type Type for which to generate a type info object.
  63439. * @return A reference to a properly initialized type info object.
  63440. */
  63441. template<typename Type>
  63442. [[nodiscard]] const type_info &type_id() noexcept {
  63443. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  63444. static const type_info instance{std::in_place_type<Type>};
  63445. return instance;
  63446. } else {
  63447. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  63448. }
  63449. }
  63450. /*! @copydoc type_id */
  63451. template<typename Type>
  63452. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  63453. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  63454. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  63455. }
  63456. } // namespace entt
  63457. #endif
  63458. // #include "../core/type_traits.hpp"
  63459. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  63460. #define ENTT_CORE_TYPE_TRAITS_HPP
  63461. #include <cstddef>
  63462. #include <iterator>
  63463. #include <tuple>
  63464. #include <type_traits>
  63465. #include <utility>
  63466. // #include "../config/config.h"
  63467. // #include "fwd.hpp"
  63468. namespace entt {
  63469. /**
  63470. * @brief Utility class to disambiguate overloaded functions.
  63471. * @tparam N Number of choices available.
  63472. */
  63473. template<std::size_t N>
  63474. struct choice_t
  63475. // unfortunately, doxygen cannot parse such a construct
  63476. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  63477. {};
  63478. /*! @copybrief choice_t */
  63479. template<>
  63480. struct choice_t<0> {};
  63481. /**
  63482. * @brief Variable template for the choice trick.
  63483. * @tparam N Number of choices available.
  63484. */
  63485. template<std::size_t N>
  63486. inline constexpr choice_t<N> choice{};
  63487. /**
  63488. * @brief Identity type trait.
  63489. *
  63490. * Useful to establish non-deduced contexts in template argument deduction
  63491. * (waiting for C++20) or to provide types through function arguments.
  63492. *
  63493. * @tparam Type A type.
  63494. */
  63495. template<typename Type>
  63496. struct type_identity {
  63497. /*! @brief Identity type. */
  63498. using type = Type;
  63499. };
  63500. /**
  63501. * @brief Helper type.
  63502. * @tparam Type A type.
  63503. */
  63504. template<typename Type>
  63505. using type_identity_t = typename type_identity<Type>::type;
  63506. /**
  63507. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  63508. * @tparam Type The type of which to return the size.
  63509. */
  63510. template<typename Type, typename = void>
  63511. struct size_of: std::integral_constant<std::size_t, 0u> {};
  63512. /*! @copydoc size_of */
  63513. template<typename Type>
  63514. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  63515. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  63516. : std::integral_constant<std::size_t, sizeof(Type)> {};
  63517. /**
  63518. * @brief Helper variable template.
  63519. * @tparam Type The type of which to return the size.
  63520. */
  63521. template<typename Type>
  63522. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  63523. /**
  63524. * @brief Using declaration to be used to _repeat_ the same type a number of
  63525. * times equal to the size of a given parameter pack.
  63526. * @tparam Type A type to repeat.
  63527. */
  63528. template<typename Type, typename>
  63529. using unpack_as_type = Type;
  63530. /**
  63531. * @brief Helper variable template to be used to _repeat_ the same value a
  63532. * number of times equal to the size of a given parameter pack.
  63533. * @tparam Value A value to repeat.
  63534. */
  63535. template<auto Value, typename>
  63536. inline constexpr auto unpack_as_value = Value;
  63537. /**
  63538. * @brief Wraps a static constant.
  63539. * @tparam Value A static constant.
  63540. */
  63541. template<auto Value>
  63542. using integral_constant = std::integral_constant<decltype(Value), Value>;
  63543. /**
  63544. * @brief Alias template to facilitate the creation of named values.
  63545. * @tparam Value A constant value at least convertible to `id_type`.
  63546. */
  63547. template<id_type Value>
  63548. using tag = integral_constant<Value>;
  63549. /**
  63550. * @brief A class to use to push around lists of types, nothing more.
  63551. * @tparam Type Types provided by the type list.
  63552. */
  63553. template<typename... Type>
  63554. struct type_list {
  63555. /*! @brief Type list type. */
  63556. using type = type_list;
  63557. /*! @brief Compile-time number of elements in the type list. */
  63558. static constexpr auto size = sizeof...(Type);
  63559. };
  63560. /*! @brief Primary template isn't defined on purpose. */
  63561. template<std::size_t, typename>
  63562. struct type_list_element;
  63563. /**
  63564. * @brief Provides compile-time indexed access to the types of a type list.
  63565. * @tparam Index Index of the type to return.
  63566. * @tparam First First type provided by the type list.
  63567. * @tparam Other Other types provided by the type list.
  63568. */
  63569. template<std::size_t Index, typename First, typename... Other>
  63570. struct type_list_element<Index, type_list<First, Other...>>
  63571. : type_list_element<Index - 1u, type_list<Other...>> {};
  63572. /**
  63573. * @brief Provides compile-time indexed access to the types of a type list.
  63574. * @tparam First First type provided by the type list.
  63575. * @tparam Other Other types provided by the type list.
  63576. */
  63577. template<typename First, typename... Other>
  63578. struct type_list_element<0u, type_list<First, Other...>> {
  63579. /*! @brief Searched type. */
  63580. using type = First;
  63581. };
  63582. /**
  63583. * @brief Helper type.
  63584. * @tparam Index Index of the type to return.
  63585. * @tparam List Type list to search into.
  63586. */
  63587. template<std::size_t Index, typename List>
  63588. using type_list_element_t = typename type_list_element<Index, List>::type;
  63589. /*! @brief Primary template isn't defined on purpose. */
  63590. template<typename, typename>
  63591. struct type_list_index;
  63592. /**
  63593. * @brief Provides compile-time type access to the types of a type list.
  63594. * @tparam Type Type to look for and for which to return the index.
  63595. * @tparam First First type provided by the type list.
  63596. * @tparam Other Other types provided by the type list.
  63597. */
  63598. template<typename Type, typename First, typename... Other>
  63599. struct type_list_index<Type, type_list<First, Other...>> {
  63600. /*! @brief Unsigned integer type. */
  63601. using value_type = std::size_t;
  63602. /*! @brief Compile-time position of the given type in the sublist. */
  63603. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  63604. };
  63605. /**
  63606. * @brief Provides compile-time type access to the types of a type list.
  63607. * @tparam Type Type to look for and for which to return the index.
  63608. * @tparam Other Other types provided by the type list.
  63609. */
  63610. template<typename Type, typename... Other>
  63611. struct type_list_index<Type, type_list<Type, Other...>> {
  63612. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  63613. /*! @brief Unsigned integer type. */
  63614. using value_type = std::size_t;
  63615. /*! @brief Compile-time position of the given type in the sublist. */
  63616. static constexpr value_type value = 0u;
  63617. };
  63618. /**
  63619. * @brief Provides compile-time type access to the types of a type list.
  63620. * @tparam Type Type to look for and for which to return the index.
  63621. */
  63622. template<typename Type>
  63623. struct type_list_index<Type, type_list<>> {
  63624. /*! @brief Unsigned integer type. */
  63625. using value_type = std::size_t;
  63626. /*! @brief Compile-time position of the given type in the sublist. */
  63627. static constexpr value_type value = 0u;
  63628. };
  63629. /**
  63630. * @brief Helper variable template.
  63631. * @tparam List Type list.
  63632. * @tparam Type Type to look for and for which to return the index.
  63633. */
  63634. template<typename Type, typename List>
  63635. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  63636. /**
  63637. * @brief Concatenates multiple type lists.
  63638. * @tparam Type Types provided by the first type list.
  63639. * @tparam Other Types provided by the second type list.
  63640. * @return A type list composed by the types of both the type lists.
  63641. */
  63642. template<typename... Type, typename... Other>
  63643. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  63644. return {};
  63645. }
  63646. /*! @brief Primary template isn't defined on purpose. */
  63647. template<typename...>
  63648. struct type_list_cat;
  63649. /*! @brief Concatenates multiple type lists. */
  63650. template<>
  63651. struct type_list_cat<> {
  63652. /*! @brief A type list composed by the types of all the type lists. */
  63653. using type = type_list<>;
  63654. };
  63655. /**
  63656. * @brief Concatenates multiple type lists.
  63657. * @tparam Type Types provided by the first type list.
  63658. * @tparam Other Types provided by the second type list.
  63659. * @tparam List Other type lists, if any.
  63660. */
  63661. template<typename... Type, typename... Other, typename... List>
  63662. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  63663. /*! @brief A type list composed by the types of all the type lists. */
  63664. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  63665. };
  63666. /**
  63667. * @brief Concatenates multiple type lists.
  63668. * @tparam Type Types provided by the type list.
  63669. */
  63670. template<typename... Type>
  63671. struct type_list_cat<type_list<Type...>> {
  63672. /*! @brief A type list composed by the types of all the type lists. */
  63673. using type = type_list<Type...>;
  63674. };
  63675. /**
  63676. * @brief Helper type.
  63677. * @tparam List Type lists to concatenate.
  63678. */
  63679. template<typename... List>
  63680. using type_list_cat_t = typename type_list_cat<List...>::type;
  63681. /*! @cond TURN_OFF_DOXYGEN */
  63682. namespace internal {
  63683. template<typename...>
  63684. struct type_list_unique;
  63685. template<typename First, typename... Other, typename... Type>
  63686. struct type_list_unique<type_list<First, Other...>, Type...>
  63687. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  63688. template<typename... Type>
  63689. struct type_list_unique<type_list<>, Type...> {
  63690. using type = type_list<Type...>;
  63691. };
  63692. } // namespace internal
  63693. /*! @endcond */
  63694. /**
  63695. * @brief Removes duplicates types from a type list.
  63696. * @tparam List Type list.
  63697. */
  63698. template<typename List>
  63699. struct type_list_unique {
  63700. /*! @brief A type list without duplicate types. */
  63701. using type = typename internal::type_list_unique<List>::type;
  63702. };
  63703. /**
  63704. * @brief Helper type.
  63705. * @tparam List Type list.
  63706. */
  63707. template<typename List>
  63708. using type_list_unique_t = typename type_list_unique<List>::type;
  63709. /**
  63710. * @brief Provides the member constant `value` to true if a type list contains a
  63711. * given type, false otherwise.
  63712. * @tparam List Type list.
  63713. * @tparam Type Type to look for.
  63714. */
  63715. template<typename List, typename Type>
  63716. struct type_list_contains;
  63717. /**
  63718. * @copybrief type_list_contains
  63719. * @tparam Type Types provided by the type list.
  63720. * @tparam Other Type to look for.
  63721. */
  63722. template<typename... Type, typename Other>
  63723. struct type_list_contains<type_list<Type...>, Other>
  63724. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  63725. /**
  63726. * @brief Helper variable template.
  63727. * @tparam List Type list.
  63728. * @tparam Type Type to look for.
  63729. */
  63730. template<typename List, typename Type>
  63731. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  63732. /*! @brief Primary template isn't defined on purpose. */
  63733. template<typename...>
  63734. struct type_list_diff;
  63735. /**
  63736. * @brief Computes the difference between two type lists.
  63737. * @tparam Type Types provided by the first type list.
  63738. * @tparam Other Types provided by the second type list.
  63739. */
  63740. template<typename... Type, typename... Other>
  63741. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  63742. /*! @brief A type list that is the difference between the two type lists. */
  63743. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  63744. };
  63745. /**
  63746. * @brief Helper type.
  63747. * @tparam List Type lists between which to compute the difference.
  63748. */
  63749. template<typename... List>
  63750. using type_list_diff_t = typename type_list_diff<List...>::type;
  63751. /*! @brief Primary template isn't defined on purpose. */
  63752. template<typename, template<typename...> class>
  63753. struct type_list_transform;
  63754. /**
  63755. * @brief Applies a given _function_ to a type list and generate a new list.
  63756. * @tparam Type Types provided by the type list.
  63757. * @tparam Op Unary operation as template class with a type member named `type`.
  63758. */
  63759. template<typename... Type, template<typename...> class Op>
  63760. struct type_list_transform<type_list<Type...>, Op> {
  63761. /*! @brief Resulting type list after applying the transform function. */
  63762. // NOLINTNEXTLINE(modernize-type-traits)
  63763. using type = type_list<typename Op<Type>::type...>;
  63764. };
  63765. /**
  63766. * @brief Helper type.
  63767. * @tparam List Type list.
  63768. * @tparam Op Unary operation as template class with a type member named `type`.
  63769. */
  63770. template<typename List, template<typename...> class Op>
  63771. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  63772. /**
  63773. * @brief A class to use to push around lists of constant values, nothing more.
  63774. * @tparam Value Values provided by the value list.
  63775. */
  63776. template<auto... Value>
  63777. struct value_list {
  63778. /*! @brief Value list type. */
  63779. using type = value_list;
  63780. /*! @brief Compile-time number of elements in the value list. */
  63781. static constexpr auto size = sizeof...(Value);
  63782. };
  63783. /*! @brief Primary template isn't defined on purpose. */
  63784. template<std::size_t, typename>
  63785. struct value_list_element;
  63786. /**
  63787. * @brief Provides compile-time indexed access to the values of a value list.
  63788. * @tparam Index Index of the value to return.
  63789. * @tparam Value First value provided by the value list.
  63790. * @tparam Other Other values provided by the value list.
  63791. */
  63792. template<std::size_t Index, auto Value, auto... Other>
  63793. struct value_list_element<Index, value_list<Value, Other...>>
  63794. : value_list_element<Index - 1u, value_list<Other...>> {};
  63795. /**
  63796. * @brief Provides compile-time indexed access to the types of a type list.
  63797. * @tparam Value First value provided by the value list.
  63798. * @tparam Other Other values provided by the value list.
  63799. */
  63800. template<auto Value, auto... Other>
  63801. struct value_list_element<0u, value_list<Value, Other...>> {
  63802. /*! @brief Searched type. */
  63803. using type = decltype(Value);
  63804. /*! @brief Searched value. */
  63805. static constexpr auto value = Value;
  63806. };
  63807. /**
  63808. * @brief Helper type.
  63809. * @tparam Index Index of the type to return.
  63810. * @tparam List Value list to search into.
  63811. */
  63812. template<std::size_t Index, typename List>
  63813. using value_list_element_t = typename value_list_element<Index, List>::type;
  63814. /**
  63815. * @brief Helper type.
  63816. * @tparam Index Index of the value to return.
  63817. * @tparam List Value list to search into.
  63818. */
  63819. template<std::size_t Index, typename List>
  63820. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  63821. /*! @brief Primary template isn't defined on purpose. */
  63822. template<auto, typename>
  63823. struct value_list_index;
  63824. /**
  63825. * @brief Provides compile-time type access to the values of a value list.
  63826. * @tparam Value Value to look for and for which to return the index.
  63827. * @tparam First First value provided by the value list.
  63828. * @tparam Other Other values provided by the value list.
  63829. */
  63830. template<auto Value, auto First, auto... Other>
  63831. struct value_list_index<Value, value_list<First, Other...>> {
  63832. /*! @brief Unsigned integer type. */
  63833. using value_type = std::size_t;
  63834. /*! @brief Compile-time position of the given value in the sublist. */
  63835. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  63836. };
  63837. /**
  63838. * @brief Provides compile-time type access to the values of a value list.
  63839. * @tparam Value Value to look for and for which to return the index.
  63840. * @tparam Other Other values provided by the value list.
  63841. */
  63842. template<auto Value, auto... Other>
  63843. struct value_list_index<Value, value_list<Value, Other...>> {
  63844. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  63845. /*! @brief Unsigned integer type. */
  63846. using value_type = std::size_t;
  63847. /*! @brief Compile-time position of the given value in the sublist. */
  63848. static constexpr value_type value = 0u;
  63849. };
  63850. /**
  63851. * @brief Provides compile-time type access to the values of a value list.
  63852. * @tparam Value Value to look for and for which to return the index.
  63853. */
  63854. template<auto Value>
  63855. struct value_list_index<Value, value_list<>> {
  63856. /*! @brief Unsigned integer type. */
  63857. using value_type = std::size_t;
  63858. /*! @brief Compile-time position of the given type in the sublist. */
  63859. static constexpr value_type value = 0u;
  63860. };
  63861. /**
  63862. * @brief Helper variable template.
  63863. * @tparam List Value list.
  63864. * @tparam Value Value to look for and for which to return the index.
  63865. */
  63866. template<auto Value, typename List>
  63867. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  63868. /**
  63869. * @brief Concatenates multiple value lists.
  63870. * @tparam Value Values provided by the first value list.
  63871. * @tparam Other Values provided by the second value list.
  63872. * @return A value list composed by the values of both the value lists.
  63873. */
  63874. template<auto... Value, auto... Other>
  63875. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  63876. return {};
  63877. }
  63878. /*! @brief Primary template isn't defined on purpose. */
  63879. template<typename...>
  63880. struct value_list_cat;
  63881. /*! @brief Concatenates multiple value lists. */
  63882. template<>
  63883. struct value_list_cat<> {
  63884. /*! @brief A value list composed by the values of all the value lists. */
  63885. using type = value_list<>;
  63886. };
  63887. /**
  63888. * @brief Concatenates multiple value lists.
  63889. * @tparam Value Values provided by the first value list.
  63890. * @tparam Other Values provided by the second value list.
  63891. * @tparam List Other value lists, if any.
  63892. */
  63893. template<auto... Value, auto... Other, typename... List>
  63894. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  63895. /*! @brief A value list composed by the values of all the value lists. */
  63896. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  63897. };
  63898. /**
  63899. * @brief Concatenates multiple value lists.
  63900. * @tparam Value Values provided by the value list.
  63901. */
  63902. template<auto... Value>
  63903. struct value_list_cat<value_list<Value...>> {
  63904. /*! @brief A value list composed by the values of all the value lists. */
  63905. using type = value_list<Value...>;
  63906. };
  63907. /**
  63908. * @brief Helper type.
  63909. * @tparam List Value lists to concatenate.
  63910. */
  63911. template<typename... List>
  63912. using value_list_cat_t = typename value_list_cat<List...>::type;
  63913. /*! @brief Primary template isn't defined on purpose. */
  63914. template<typename>
  63915. struct value_list_unique;
  63916. /**
  63917. * @brief Removes duplicates values from a value list.
  63918. * @tparam Value One of the values provided by the given value list.
  63919. * @tparam Other The other values provided by the given value list.
  63920. */
  63921. template<auto Value, auto... Other>
  63922. struct value_list_unique<value_list<Value, Other...>> {
  63923. /*! @brief A value list without duplicate types. */
  63924. using type = std::conditional_t<
  63925. ((Value == Other) || ...),
  63926. typename value_list_unique<value_list<Other...>>::type,
  63927. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  63928. };
  63929. /*! @brief Removes duplicates values from a value list. */
  63930. template<>
  63931. struct value_list_unique<value_list<>> {
  63932. /*! @brief A value list without duplicate types. */
  63933. using type = value_list<>;
  63934. };
  63935. /**
  63936. * @brief Helper type.
  63937. * @tparam Type A value list.
  63938. */
  63939. template<typename Type>
  63940. using value_list_unique_t = typename value_list_unique<Type>::type;
  63941. /**
  63942. * @brief Provides the member constant `value` to true if a value list contains
  63943. * a given value, false otherwise.
  63944. * @tparam List Value list.
  63945. * @tparam Value Value to look for.
  63946. */
  63947. template<typename List, auto Value>
  63948. struct value_list_contains;
  63949. /**
  63950. * @copybrief value_list_contains
  63951. * @tparam Value Values provided by the value list.
  63952. * @tparam Other Value to look for.
  63953. */
  63954. template<auto... Value, auto Other>
  63955. struct value_list_contains<value_list<Value...>, Other>
  63956. : std::bool_constant<((Value == Other) || ...)> {};
  63957. /**
  63958. * @brief Helper variable template.
  63959. * @tparam List Value list.
  63960. * @tparam Value Value to look for.
  63961. */
  63962. template<typename List, auto Value>
  63963. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  63964. /*! @brief Primary template isn't defined on purpose. */
  63965. template<typename...>
  63966. struct value_list_diff;
  63967. /**
  63968. * @brief Computes the difference between two value lists.
  63969. * @tparam Value Values provided by the first value list.
  63970. * @tparam Other Values provided by the second value list.
  63971. */
  63972. template<auto... Value, auto... Other>
  63973. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  63974. /*! @brief A value list that is the difference between the two value lists. */
  63975. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  63976. };
  63977. /**
  63978. * @brief Helper type.
  63979. * @tparam List Value lists between which to compute the difference.
  63980. */
  63981. template<typename... List>
  63982. using value_list_diff_t = typename value_list_diff<List...>::type;
  63983. /*! @brief Same as std::is_invocable, but with tuples. */
  63984. template<typename, typename>
  63985. struct is_applicable: std::false_type {};
  63986. /**
  63987. * @copybrief is_applicable
  63988. * @tparam Func A valid function type.
  63989. * @tparam Tuple Tuple-like type.
  63990. * @tparam Args The list of arguments to use to probe the function type.
  63991. */
  63992. template<typename Func, template<typename...> class Tuple, typename... Args>
  63993. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  63994. /**
  63995. * @copybrief is_applicable
  63996. * @tparam Func A valid function type.
  63997. * @tparam Tuple Tuple-like type.
  63998. * @tparam Args The list of arguments to use to probe the function type.
  63999. */
  64000. template<typename Func, template<typename...> class Tuple, typename... Args>
  64001. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  64002. /**
  64003. * @brief Helper variable template.
  64004. * @tparam Func A valid function type.
  64005. * @tparam Args The list of arguments to use to probe the function type.
  64006. */
  64007. template<typename Func, typename Args>
  64008. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  64009. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  64010. template<typename, typename, typename>
  64011. struct is_applicable_r: std::false_type {};
  64012. /**
  64013. * @copybrief is_applicable_r
  64014. * @tparam Ret The type to which the return type of the function should be
  64015. * convertible.
  64016. * @tparam Func A valid function type.
  64017. * @tparam Args The list of arguments to use to probe the function type.
  64018. */
  64019. template<typename Ret, typename Func, typename... Args>
  64020. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  64021. /**
  64022. * @brief Helper variable template.
  64023. * @tparam Ret The type to which the return type of the function should be
  64024. * convertible.
  64025. * @tparam Func A valid function type.
  64026. * @tparam Args The list of arguments to use to probe the function type.
  64027. */
  64028. template<typename Ret, typename Func, typename Args>
  64029. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  64030. /**
  64031. * @brief Provides the member constant `value` to true if a given type is
  64032. * complete, false otherwise.
  64033. * @tparam Type The type to test.
  64034. */
  64035. template<typename Type, typename = void>
  64036. struct is_complete: std::false_type {};
  64037. /*! @copydoc is_complete */
  64038. template<typename Type>
  64039. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  64040. /**
  64041. * @brief Helper variable template.
  64042. * @tparam Type The type to test.
  64043. */
  64044. template<typename Type>
  64045. inline constexpr bool is_complete_v = is_complete<Type>::value;
  64046. /**
  64047. * @brief Provides the member constant `value` to true if a given type is an
  64048. * iterator, false otherwise.
  64049. * @tparam Type The type to test.
  64050. */
  64051. template<typename Type, typename = void>
  64052. struct is_iterator: std::false_type {};
  64053. /*! @cond TURN_OFF_DOXYGEN */
  64054. namespace internal {
  64055. template<typename, typename = void>
  64056. struct has_iterator_category: std::false_type {};
  64057. template<typename Type>
  64058. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  64059. } // namespace internal
  64060. /*! @endcond */
  64061. /*! @copydoc is_iterator */
  64062. template<typename Type>
  64063. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  64064. : internal::has_iterator_category<Type> {};
  64065. /**
  64066. * @brief Helper variable template.
  64067. * @tparam Type The type to test.
  64068. */
  64069. template<typename Type>
  64070. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  64071. /**
  64072. * @brief Provides the member constant `value` to true if a given type is both
  64073. * an empty and non-final class, false otherwise.
  64074. * @tparam Type The type to test
  64075. */
  64076. template<typename Type>
  64077. struct is_ebco_eligible
  64078. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  64079. /**
  64080. * @brief Helper variable template.
  64081. * @tparam Type The type to test.
  64082. */
  64083. template<typename Type>
  64084. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  64085. /**
  64086. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  64087. * is valid and denotes a type, false otherwise.
  64088. * @tparam Type The type to test.
  64089. */
  64090. template<typename Type, typename = void>
  64091. struct is_transparent: std::false_type {};
  64092. /*! @copydoc is_transparent */
  64093. template<typename Type>
  64094. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  64095. /**
  64096. * @brief Helper variable template.
  64097. * @tparam Type The type to test.
  64098. */
  64099. template<typename Type>
  64100. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  64101. /*! @cond TURN_OFF_DOXYGEN */
  64102. namespace internal {
  64103. template<typename, typename = void>
  64104. struct has_tuple_size_value: std::false_type {};
  64105. template<typename Type>
  64106. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  64107. template<typename, typename = void>
  64108. struct has_value_type: std::false_type {};
  64109. template<typename Type>
  64110. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  64111. template<typename>
  64112. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  64113. template<typename Type, std::size_t... Index>
  64114. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  64115. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  64116. }
  64117. template<typename>
  64118. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  64119. return false;
  64120. }
  64121. template<typename Type>
  64122. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  64123. return true;
  64124. }
  64125. template<typename Type>
  64126. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  64127. // NOLINTBEGIN(modernize-use-transparent-functors)
  64128. if constexpr(std::is_array_v<Type>) {
  64129. return false;
  64130. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  64131. if constexpr(has_tuple_size_value<Type>::value) {
  64132. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  64133. } else {
  64134. return maybe_equality_comparable<Type>(0);
  64135. }
  64136. } else if constexpr(has_value_type<Type>::value) {
  64137. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  64138. return maybe_equality_comparable<Type>(0);
  64139. } else {
  64140. return false;
  64141. }
  64142. } else {
  64143. return maybe_equality_comparable<Type>(0);
  64144. }
  64145. // NOLINTEND(modernize-use-transparent-functors)
  64146. }
  64147. } // namespace internal
  64148. /*! @endcond */
  64149. /**
  64150. * @brief Provides the member constant `value` to true if a given type is
  64151. * equality comparable, false otherwise.
  64152. * @tparam Type The type to test.
  64153. */
  64154. template<typename Type>
  64155. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  64156. /*! @copydoc is_equality_comparable */
  64157. template<typename Type>
  64158. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  64159. /**
  64160. * @brief Helper variable template.
  64161. * @tparam Type The type to test.
  64162. */
  64163. template<typename Type>
  64164. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  64165. /**
  64166. * @brief Transcribes the constness of a type to another type.
  64167. * @tparam To The type to which to transcribe the constness.
  64168. * @tparam From The type from which to transcribe the constness.
  64169. */
  64170. template<typename To, typename From>
  64171. struct constness_as {
  64172. /*! @brief The type resulting from the transcription of the constness. */
  64173. using type = std::remove_const_t<To>;
  64174. };
  64175. /*! @copydoc constness_as */
  64176. template<typename To, typename From>
  64177. struct constness_as<To, const From> {
  64178. /*! @brief The type resulting from the transcription of the constness. */
  64179. using type = const To;
  64180. };
  64181. /**
  64182. * @brief Alias template to facilitate the transcription of the constness.
  64183. * @tparam To The type to which to transcribe the constness.
  64184. * @tparam From The type from which to transcribe the constness.
  64185. */
  64186. template<typename To, typename From>
  64187. using constness_as_t = typename constness_as<To, From>::type;
  64188. /**
  64189. * @brief Extracts the class of a non-static member object or function.
  64190. * @tparam Member A pointer to a non-static member object or function.
  64191. */
  64192. template<typename Member>
  64193. class member_class {
  64194. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  64195. template<typename Class, typename Ret, typename... Args>
  64196. static Class *clazz(Ret (Class::*)(Args...));
  64197. template<typename Class, typename Ret, typename... Args>
  64198. static Class *clazz(Ret (Class::*)(Args...) const);
  64199. template<typename Class, typename Type>
  64200. static Class *clazz(Type Class::*);
  64201. public:
  64202. /*! @brief The class of the given non-static member object or function. */
  64203. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  64204. };
  64205. /**
  64206. * @brief Helper type.
  64207. * @tparam Member A pointer to a non-static member object or function.
  64208. */
  64209. template<typename Member>
  64210. using member_class_t = typename member_class<Member>::type;
  64211. /**
  64212. * @brief Extracts the n-th argument of a _callable_ type.
  64213. * @tparam Index The index of the argument to extract.
  64214. * @tparam Candidate A valid _callable_ type.
  64215. */
  64216. template<std::size_t Index, typename Candidate>
  64217. class nth_argument {
  64218. template<typename Ret, typename... Args>
  64219. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  64220. template<typename Ret, typename Class, typename... Args>
  64221. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  64222. template<typename Ret, typename Class, typename... Args>
  64223. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  64224. template<typename Type, typename Class>
  64225. static constexpr type_list<Type> pick_up(Type Class ::*);
  64226. template<typename Type>
  64227. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  64228. public:
  64229. /*! @brief N-th argument of the _callable_ type. */
  64230. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  64231. };
  64232. /**
  64233. * @brief Helper type.
  64234. * @tparam Index The index of the argument to extract.
  64235. * @tparam Candidate A valid function, member function or data member type.
  64236. */
  64237. template<std::size_t Index, typename Candidate>
  64238. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  64239. } // namespace entt
  64240. template<typename... Type>
  64241. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  64242. template<std::size_t Index, typename... Type>
  64243. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  64244. template<auto... Value>
  64245. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  64246. template<std::size_t Index, auto... Value>
  64247. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  64248. #endif
  64249. // #include "fwd.hpp"
  64250. #ifndef ENTT_POLY_FWD_HPP
  64251. #define ENTT_POLY_FWD_HPP
  64252. #include <cstddef>
  64253. namespace entt {
  64254. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  64255. template<typename, std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  64256. class basic_poly;
  64257. /**
  64258. * @brief Alias declaration for the most common use case.
  64259. * @tparam Concept Concept descriptor.
  64260. */
  64261. template<typename Concept>
  64262. using poly = basic_poly<Concept>;
  64263. } // namespace entt
  64264. #endif
  64265. namespace entt {
  64266. /*! @brief Inspector class used to infer the type of the virtual table. */
  64267. struct poly_inspector {
  64268. /**
  64269. * @brief Generic conversion operator (definition only).
  64270. * @tparam Type Type to which conversion is requested.
  64271. */
  64272. template<typename Type>
  64273. operator Type &&() const;
  64274. /**
  64275. * @brief Dummy invocation function (definition only).
  64276. * @tparam Member Index of the function to invoke.
  64277. * @tparam Args Types of arguments to pass to the function.
  64278. * @param args The arguments to pass to the function.
  64279. * @return A poly inspector convertible to any type.
  64280. */
  64281. template<std::size_t Member, typename... Args>
  64282. [[nodiscard]] poly_inspector invoke(Args &&...args) const;
  64283. /*! @copydoc invoke */
  64284. template<std::size_t Member, typename... Args>
  64285. [[nodiscard]] poly_inspector invoke(Args &&...args);
  64286. };
  64287. /**
  64288. * @brief Static virtual table factory.
  64289. * @tparam Concept Concept descriptor.
  64290. * @tparam Len Size of the storage reserved for the small buffer optimization.
  64291. * @tparam Align Alignment requirement.
  64292. */
  64293. template<typename Concept, std::size_t Len, std::size_t Align>
  64294. class poly_vtable {
  64295. using inspector = typename Concept::template type<poly_inspector>;
  64296. template<typename Ret, typename Clazz, typename... Args>
  64297. static auto vtable_entry(Ret (*)(Clazz &, Args...))
  64298. -> std::enable_if_t<std::is_base_of_v<std::remove_const_t<Clazz>, inspector>, Ret (*)(constness_as_t<basic_any<Len, Align>, Clazz> &, Args...)>;
  64299. template<typename Ret, typename... Args>
  64300. static auto vtable_entry(Ret (*)(Args...))
  64301. -> Ret (*)(const basic_any<Len, Align> &, Args...);
  64302. template<typename Ret, typename Clazz, typename... Args>
  64303. static auto vtable_entry(Ret (Clazz::*)(Args...))
  64304. -> std::enable_if_t<std::is_base_of_v<Clazz, inspector>, Ret (*)(basic_any<Len, Align> &, Args...)>;
  64305. template<typename Ret, typename Clazz, typename... Args>
  64306. static auto vtable_entry(Ret (Clazz::*)(Args...) const)
  64307. -> std::enable_if_t<std::is_base_of_v<Clazz, inspector>, Ret (*)(const basic_any<Len, Align> &, Args...)>;
  64308. template<auto... Candidate>
  64309. static auto make_vtable(value_list<Candidate...>) noexcept
  64310. -> decltype(std::make_tuple(vtable_entry(Candidate)...));
  64311. template<typename... Func>
  64312. [[nodiscard]] static constexpr auto make_vtable(type_list<Func...>) noexcept {
  64313. if constexpr(sizeof...(Func) == 0u) {
  64314. return decltype(make_vtable(typename Concept::template impl<inspector>{})){};
  64315. } else if constexpr((std::is_function_v<Func> && ...)) {
  64316. return decltype(std::make_tuple(vtable_entry(std::declval<Func inspector::*>())...)){};
  64317. }
  64318. }
  64319. template<typename Type, auto Candidate, typename Ret, typename Any, typename... Args>
  64320. static void fill_vtable_entry(Ret (*&entry)(Any &, Args...)) noexcept {
  64321. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  64322. entry = +[](Any &, Args... args) -> Ret {
  64323. return std::invoke(Candidate, std::forward<Args>(args)...);
  64324. };
  64325. } else {
  64326. entry = +[](Any &instance, Args... args) -> Ret {
  64327. return static_cast<Ret>(std::invoke(Candidate, any_cast<constness_as_t<Type, Any> &>(instance), std::forward<Args>(args)...));
  64328. };
  64329. }
  64330. }
  64331. template<typename Type, auto... Index>
  64332. [[nodiscard]] static auto fill_vtable(std::index_sequence<Index...>) noexcept {
  64333. vtable_type impl{};
  64334. (fill_vtable_entry<Type, value_list_element_v<Index, typename Concept::template impl<Type>>>(std::get<Index>(impl)), ...);
  64335. return impl;
  64336. }
  64337. using vtable_type = decltype(make_vtable(Concept{}));
  64338. static constexpr bool is_mono = std::tuple_size_v<vtable_type> == 1u;
  64339. public:
  64340. /*! @brief Virtual table type. */
  64341. using type = std::conditional_t<is_mono, std::tuple_element_t<0u, vtable_type>, const vtable_type *>;
  64342. /**
  64343. * @brief Returns a static virtual table for a specific concept and type.
  64344. * @tparam Type The type for which to generate the virtual table.
  64345. * @return A static virtual table for the given concept and type.
  64346. */
  64347. template<typename Type>
  64348. [[nodiscard]] static type instance() noexcept {
  64349. static_assert(std::is_same_v<Type, std::decay_t<Type>>, "Type differs from its decayed form");
  64350. static const vtable_type vtable = fill_vtable<Type>(std::make_index_sequence<Concept::template impl<Type>::size>{});
  64351. if constexpr(is_mono) {
  64352. return std::get<0>(vtable);
  64353. } else {
  64354. return &vtable;
  64355. }
  64356. }
  64357. };
  64358. /**
  64359. * @brief Poly base class used to inject functionalities into concepts.
  64360. * @tparam Poly The outermost poly class.
  64361. */
  64362. template<typename Poly>
  64363. struct poly_base {
  64364. /**
  64365. * @brief Invokes a function from the static virtual table.
  64366. * @tparam Member Index of the function to invoke.
  64367. * @tparam Args Types of arguments to pass to the function.
  64368. * @param self A reference to the poly object that made the call.
  64369. * @param args The arguments to pass to the function.
  64370. * @return The return value of the invoked function, if any.
  64371. */
  64372. template<std::size_t Member, typename... Args>
  64373. [[nodiscard]] decltype(auto) invoke(const poly_base &self, Args &&...args) const {
  64374. const auto &poly = static_cast<const Poly &>(self);
  64375. if constexpr(std::is_function_v<std::remove_pointer_t<decltype(poly.vtable)>>) {
  64376. return poly.vtable(poly.storage, std::forward<Args>(args)...);
  64377. } else {
  64378. return std::get<Member>(*poly.vtable)(poly.storage, std::forward<Args>(args)...);
  64379. }
  64380. }
  64381. /*! @copydoc invoke */
  64382. template<std::size_t Member, typename... Args>
  64383. [[nodiscard]] decltype(auto) invoke(poly_base &self, Args &&...args) {
  64384. auto &poly = static_cast<Poly &>(self);
  64385. if constexpr(std::is_function_v<std::remove_pointer_t<decltype(poly.vtable)>>) {
  64386. static_assert(Member == 0u, "Unknown member");
  64387. return poly.vtable(poly.storage, std::forward<Args>(args)...);
  64388. } else {
  64389. return std::get<Member>(*poly.vtable)(poly.storage, std::forward<Args>(args)...);
  64390. }
  64391. }
  64392. };
  64393. /**
  64394. * @brief Shortcut for calling `poly_base<Type>::invoke`.
  64395. * @tparam Member Index of the function to invoke.
  64396. * @tparam Poly A fully defined poly object.
  64397. * @tparam Args Types of arguments to pass to the function.
  64398. * @param self A reference to the poly object that made the call.
  64399. * @param args The arguments to pass to the function.
  64400. * @return The return value of the invoked function, if any.
  64401. */
  64402. template<std::size_t Member, typename Poly, typename... Args>
  64403. decltype(auto) poly_call(Poly &&self, Args &&...args) {
  64404. return std::forward<Poly>(self).template invoke<Member>(self, std::forward<Args>(args)...);
  64405. }
  64406. /**
  64407. * @brief Static polymorphism made simple and within everyone's reach.
  64408. *
  64409. * Static polymorphism is a very powerful tool in C++, albeit sometimes
  64410. * cumbersome to obtain.<br/>
  64411. * This class aims to make it simple and easy to use.
  64412. *
  64413. * @note
  64414. * Both deduced and defined static virtual tables are supported.<br/>
  64415. * Moreover, the `poly` class template also works with unmanaged objects.
  64416. *
  64417. * @tparam Concept Concept descriptor.
  64418. * @tparam Len Size of the storage reserved for the small buffer optimization.
  64419. * @tparam Align Optional alignment requirement.
  64420. */
  64421. template<typename Concept, std::size_t Len, std::size_t Align>
  64422. class basic_poly: private Concept::template type<poly_base<basic_poly<Concept, Len, Align>>> {
  64423. friend struct poly_base<basic_poly>;
  64424. public:
  64425. /*! @brief Concept type. */
  64426. using concept_type = typename Concept::template type<poly_base<basic_poly>>;
  64427. /*! @brief Virtual table type. */
  64428. using vtable_type = typename poly_vtable<Concept, Len, Align>::type;
  64429. /*! @brief Default constructor. */
  64430. basic_poly() noexcept = default;
  64431. /**
  64432. * @brief Constructs a poly by directly initializing the new object.
  64433. * @tparam Type Type of object to use to initialize the poly.
  64434. * @tparam Args Types of arguments to use to construct the new instance.
  64435. * @param args Parameters to use to construct the instance.
  64436. */
  64437. template<typename Type, typename... Args>
  64438. explicit basic_poly(std::in_place_type_t<Type>, Args &&...args)
  64439. : storage{std::in_place_type<Type>, std::forward<Args>(args)...},
  64440. vtable{poly_vtable<Concept, Len, Align>::template instance<std::remove_const_t<std::remove_reference_t<Type>>>()} {}
  64441. /**
  64442. * @brief Constructs a poly from a given value.
  64443. * @tparam Type Type of object to use to initialize the poly.
  64444. * @param value An instance of an object to use to initialize the poly.
  64445. */
  64446. template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Type>>, basic_poly>>>
  64447. basic_poly(Type &&value) noexcept
  64448. : basic_poly{std::in_place_type<std::remove_const_t<std::remove_reference_t<Type>>>, std::forward<Type>(value)} {}
  64449. /**
  64450. * @brief Returns the object type info if any, `type_id<void>()` otherwise.
  64451. * @return The object type info if any, `type_id<void>()` otherwise.
  64452. */
  64453. [[nodiscard]] const type_info &info() const noexcept {
  64454. return storage.info();
  64455. }
  64456. /*! @copydoc info */
  64457. [[deprecated("use ::info instead")]] [[nodiscard]] const type_info &type() const noexcept {
  64458. return info();
  64459. }
  64460. /**
  64461. * @brief Returns an opaque pointer to the contained instance.
  64462. * @return An opaque pointer the contained instance, if any.
  64463. */
  64464. [[nodiscard]] const void *data() const noexcept {
  64465. return storage.data();
  64466. }
  64467. /*! @copydoc data */
  64468. [[nodiscard]] void *data() noexcept {
  64469. return storage.data();
  64470. }
  64471. /**
  64472. * @brief Replaces the contained object by creating a new instance directly.
  64473. * @tparam Type Type of object to use to initialize the poly.
  64474. * @tparam Args Types of arguments to use to construct the new instance.
  64475. * @param args Parameters to use to construct the instance.
  64476. */
  64477. template<typename Type, typename... Args>
  64478. void emplace(Args &&...args) {
  64479. storage.template emplace<Type>(std::forward<Args>(args)...);
  64480. vtable = poly_vtable<Concept, Len, Align>::template instance<std::remove_const_t<std::remove_reference_t<Type>>>();
  64481. }
  64482. /*! @brief Destroys contained object */
  64483. void reset() {
  64484. storage.reset();
  64485. vtable = {};
  64486. }
  64487. /**
  64488. * @brief Returns false if a poly is empty, true otherwise.
  64489. * @return False if the poly is empty, true otherwise.
  64490. */
  64491. [[nodiscard]] explicit operator bool() const noexcept {
  64492. return static_cast<bool>(storage);
  64493. }
  64494. /**
  64495. * @brief Returns a pointer to the underlying concept.
  64496. * @return A pointer to the underlying concept.
  64497. */
  64498. [[nodiscard]] concept_type *operator->() noexcept {
  64499. return this;
  64500. }
  64501. /*! @copydoc operator-> */
  64502. [[nodiscard]] const concept_type *operator->() const noexcept {
  64503. return this;
  64504. }
  64505. /**
  64506. * @brief Aliasing constructor.
  64507. * @return A poly that shares a reference to an unmanaged object.
  64508. */
  64509. [[nodiscard]] basic_poly as_ref() noexcept {
  64510. basic_poly ref{};
  64511. ref.storage = storage.as_ref();
  64512. ref.vtable = vtable;
  64513. return ref;
  64514. }
  64515. /*! @copydoc as_ref */
  64516. [[nodiscard]] basic_poly as_ref() const noexcept {
  64517. basic_poly ref{};
  64518. ref.storage = storage.as_ref();
  64519. ref.vtable = vtable;
  64520. return ref;
  64521. }
  64522. private:
  64523. basic_any<Len, Align> storage{};
  64524. vtable_type vtable{};
  64525. };
  64526. } // namespace entt
  64527. #endif
  64528. // #include "process/process.hpp"
  64529. #ifndef ENTT_PROCESS_PROCESS_HPP
  64530. #define ENTT_PROCESS_PROCESS_HPP
  64531. #include <cstdint>
  64532. #include <memory>
  64533. #include <type_traits>
  64534. #include <utility>
  64535. // #include "../core/compressed_pair.hpp"
  64536. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  64537. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  64538. #include <cstddef>
  64539. #include <tuple>
  64540. #include <type_traits>
  64541. #include <utility>
  64542. // #include "fwd.hpp"
  64543. #ifndef ENTT_CORE_FWD_HPP
  64544. #define ENTT_CORE_FWD_HPP
  64545. #include <cstddef>
  64546. #include <cstdint>
  64547. // #include "../config/config.h"
  64548. #ifndef ENTT_CONFIG_CONFIG_H
  64549. #define ENTT_CONFIG_CONFIG_H
  64550. // #include "version.h"
  64551. #ifndef ENTT_CONFIG_VERSION_H
  64552. #define ENTT_CONFIG_VERSION_H
  64553. // #include "macro.h"
  64554. #ifndef ENTT_CONFIG_MACRO_H
  64555. #define ENTT_CONFIG_MACRO_H
  64556. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  64557. #define ENTT_STR(arg) #arg
  64558. #define ENTT_XSTR(arg) ENTT_STR(arg)
  64559. // NOLINTEND(cppcoreguidelines-macro-usage)
  64560. #endif
  64561. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  64562. #define ENTT_VERSION_MAJOR 3
  64563. #define ENTT_VERSION_MINOR 16
  64564. #define ENTT_VERSION_PATCH 0
  64565. #define ENTT_VERSION \
  64566. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  64567. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  64568. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  64569. #endif
  64570. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  64571. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  64572. # define ENTT_CONSTEXPR
  64573. # define ENTT_THROW throw
  64574. # define ENTT_TRY try
  64575. # define ENTT_CATCH catch(...)
  64576. #else
  64577. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  64578. # define ENTT_THROW
  64579. # define ENTT_TRY if(true)
  64580. # define ENTT_CATCH if(false)
  64581. #endif
  64582. #if __has_include(<version>)
  64583. # include <version>
  64584. #
  64585. # if defined(__cpp_consteval)
  64586. # define ENTT_CONSTEVAL consteval
  64587. # endif
  64588. #endif
  64589. #ifndef ENTT_CONSTEVAL
  64590. # define ENTT_CONSTEVAL constexpr
  64591. #endif
  64592. #ifdef ENTT_USE_ATOMIC
  64593. # include <atomic>
  64594. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  64595. #else
  64596. # define ENTT_MAYBE_ATOMIC(Type) Type
  64597. #endif
  64598. #ifndef ENTT_ID_TYPE
  64599. # include <cstdint>
  64600. # define ENTT_ID_TYPE std::uint32_t
  64601. #else
  64602. # include <cstdint> // provides coverage for types in the std namespace
  64603. #endif
  64604. #ifndef ENTT_SPARSE_PAGE
  64605. # define ENTT_SPARSE_PAGE 4096
  64606. #endif
  64607. #ifndef ENTT_PACKED_PAGE
  64608. # define ENTT_PACKED_PAGE 1024
  64609. #endif
  64610. #ifdef ENTT_DISABLE_ASSERT
  64611. # undef ENTT_ASSERT
  64612. # define ENTT_ASSERT(condition, msg) (void(0))
  64613. #elif !defined ENTT_ASSERT
  64614. # include <cassert>
  64615. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  64616. #endif
  64617. #ifdef ENTT_DISABLE_ASSERT
  64618. # undef ENTT_ASSERT_CONSTEXPR
  64619. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  64620. #elif !defined ENTT_ASSERT_CONSTEXPR
  64621. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  64622. #endif
  64623. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  64624. #ifdef ENTT_NO_ETO
  64625. # define ENTT_ETO_TYPE(Type) void
  64626. #else
  64627. # define ENTT_ETO_TYPE(Type) Type
  64628. #endif
  64629. #ifdef ENTT_NO_MIXIN
  64630. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  64631. #else
  64632. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  64633. #endif
  64634. #ifdef ENTT_STANDARD_CPP
  64635. # define ENTT_NONSTD false
  64636. #else
  64637. # define ENTT_NONSTD true
  64638. # if defined __clang__ || defined __GNUC__
  64639. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  64640. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  64641. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  64642. # elif defined _MSC_VER
  64643. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  64644. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  64645. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  64646. # endif
  64647. #endif
  64648. #ifndef ENTT_EXPORT
  64649. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  64650. # define ENTT_EXPORT __declspec(dllexport)
  64651. # define ENTT_IMPORT __declspec(dllimport)
  64652. # define ENTT_HIDDEN
  64653. # elif defined __GNUC__ && __GNUC__ >= 4
  64654. # define ENTT_EXPORT __attribute__((visibility("default")))
  64655. # define ENTT_IMPORT __attribute__((visibility("default")))
  64656. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  64657. # else /* Unsupported compiler */
  64658. # define ENTT_EXPORT
  64659. # define ENTT_IMPORT
  64660. # define ENTT_HIDDEN
  64661. # endif
  64662. #endif
  64663. #ifndef ENTT_API
  64664. # if defined ENTT_API_EXPORT
  64665. # define ENTT_API ENTT_EXPORT
  64666. # elif defined ENTT_API_IMPORT
  64667. # define ENTT_API ENTT_IMPORT
  64668. # else /* No API */
  64669. # define ENTT_API
  64670. # endif
  64671. #endif
  64672. #if defined _MSC_VER
  64673. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  64674. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  64675. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  64676. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  64677. #endif
  64678. // NOLINTEND(cppcoreguidelines-macro-usage)
  64679. #endif
  64680. namespace entt {
  64681. /*! @brief Possible modes of an any object. */
  64682. enum class any_policy : std::uint8_t {
  64683. /*! @brief Default mode, no element available. */
  64684. empty,
  64685. /*! @brief Owning mode, dynamically allocated element. */
  64686. dynamic,
  64687. /*! @brief Owning mode, embedded element. */
  64688. embedded,
  64689. /*! @brief Aliasing mode, non-const reference. */
  64690. ref,
  64691. /*! @brief Const aliasing mode, const reference. */
  64692. cref
  64693. };
  64694. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  64695. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  64696. class basic_any;
  64697. /*! @brief Alias declaration for type identifiers. */
  64698. using id_type = ENTT_ID_TYPE;
  64699. /*! @brief Alias declaration for the most common use case. */
  64700. using any = basic_any<>;
  64701. template<typename, typename>
  64702. class compressed_pair;
  64703. template<typename>
  64704. class basic_hashed_string;
  64705. /*! @brief Aliases for common character types. */
  64706. using hashed_string = basic_hashed_string<char>;
  64707. /*! @brief Aliases for common character types. */
  64708. using hashed_wstring = basic_hashed_string<wchar_t>;
  64709. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  64710. struct type_info;
  64711. } // namespace entt
  64712. #endif
  64713. // #include "type_traits.hpp"
  64714. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  64715. #define ENTT_CORE_TYPE_TRAITS_HPP
  64716. #include <cstddef>
  64717. #include <iterator>
  64718. #include <tuple>
  64719. #include <type_traits>
  64720. #include <utility>
  64721. // #include "../config/config.h"
  64722. // #include "fwd.hpp"
  64723. namespace entt {
  64724. /**
  64725. * @brief Utility class to disambiguate overloaded functions.
  64726. * @tparam N Number of choices available.
  64727. */
  64728. template<std::size_t N>
  64729. struct choice_t
  64730. // unfortunately, doxygen cannot parse such a construct
  64731. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  64732. {};
  64733. /*! @copybrief choice_t */
  64734. template<>
  64735. struct choice_t<0> {};
  64736. /**
  64737. * @brief Variable template for the choice trick.
  64738. * @tparam N Number of choices available.
  64739. */
  64740. template<std::size_t N>
  64741. inline constexpr choice_t<N> choice{};
  64742. /**
  64743. * @brief Identity type trait.
  64744. *
  64745. * Useful to establish non-deduced contexts in template argument deduction
  64746. * (waiting for C++20) or to provide types through function arguments.
  64747. *
  64748. * @tparam Type A type.
  64749. */
  64750. template<typename Type>
  64751. struct type_identity {
  64752. /*! @brief Identity type. */
  64753. using type = Type;
  64754. };
  64755. /**
  64756. * @brief Helper type.
  64757. * @tparam Type A type.
  64758. */
  64759. template<typename Type>
  64760. using type_identity_t = typename type_identity<Type>::type;
  64761. /**
  64762. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  64763. * @tparam Type The type of which to return the size.
  64764. */
  64765. template<typename Type, typename = void>
  64766. struct size_of: std::integral_constant<std::size_t, 0u> {};
  64767. /*! @copydoc size_of */
  64768. template<typename Type>
  64769. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  64770. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  64771. : std::integral_constant<std::size_t, sizeof(Type)> {};
  64772. /**
  64773. * @brief Helper variable template.
  64774. * @tparam Type The type of which to return the size.
  64775. */
  64776. template<typename Type>
  64777. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  64778. /**
  64779. * @brief Using declaration to be used to _repeat_ the same type a number of
  64780. * times equal to the size of a given parameter pack.
  64781. * @tparam Type A type to repeat.
  64782. */
  64783. template<typename Type, typename>
  64784. using unpack_as_type = Type;
  64785. /**
  64786. * @brief Helper variable template to be used to _repeat_ the same value a
  64787. * number of times equal to the size of a given parameter pack.
  64788. * @tparam Value A value to repeat.
  64789. */
  64790. template<auto Value, typename>
  64791. inline constexpr auto unpack_as_value = Value;
  64792. /**
  64793. * @brief Wraps a static constant.
  64794. * @tparam Value A static constant.
  64795. */
  64796. template<auto Value>
  64797. using integral_constant = std::integral_constant<decltype(Value), Value>;
  64798. /**
  64799. * @brief Alias template to facilitate the creation of named values.
  64800. * @tparam Value A constant value at least convertible to `id_type`.
  64801. */
  64802. template<id_type Value>
  64803. using tag = integral_constant<Value>;
  64804. /**
  64805. * @brief A class to use to push around lists of types, nothing more.
  64806. * @tparam Type Types provided by the type list.
  64807. */
  64808. template<typename... Type>
  64809. struct type_list {
  64810. /*! @brief Type list type. */
  64811. using type = type_list;
  64812. /*! @brief Compile-time number of elements in the type list. */
  64813. static constexpr auto size = sizeof...(Type);
  64814. };
  64815. /*! @brief Primary template isn't defined on purpose. */
  64816. template<std::size_t, typename>
  64817. struct type_list_element;
  64818. /**
  64819. * @brief Provides compile-time indexed access to the types of a type list.
  64820. * @tparam Index Index of the type to return.
  64821. * @tparam First First type provided by the type list.
  64822. * @tparam Other Other types provided by the type list.
  64823. */
  64824. template<std::size_t Index, typename First, typename... Other>
  64825. struct type_list_element<Index, type_list<First, Other...>>
  64826. : type_list_element<Index - 1u, type_list<Other...>> {};
  64827. /**
  64828. * @brief Provides compile-time indexed access to the types of a type list.
  64829. * @tparam First First type provided by the type list.
  64830. * @tparam Other Other types provided by the type list.
  64831. */
  64832. template<typename First, typename... Other>
  64833. struct type_list_element<0u, type_list<First, Other...>> {
  64834. /*! @brief Searched type. */
  64835. using type = First;
  64836. };
  64837. /**
  64838. * @brief Helper type.
  64839. * @tparam Index Index of the type to return.
  64840. * @tparam List Type list to search into.
  64841. */
  64842. template<std::size_t Index, typename List>
  64843. using type_list_element_t = typename type_list_element<Index, List>::type;
  64844. /*! @brief Primary template isn't defined on purpose. */
  64845. template<typename, typename>
  64846. struct type_list_index;
  64847. /**
  64848. * @brief Provides compile-time type access to the types of a type list.
  64849. * @tparam Type Type to look for and for which to return the index.
  64850. * @tparam First First type provided by the type list.
  64851. * @tparam Other Other types provided by the type list.
  64852. */
  64853. template<typename Type, typename First, typename... Other>
  64854. struct type_list_index<Type, type_list<First, Other...>> {
  64855. /*! @brief Unsigned integer type. */
  64856. using value_type = std::size_t;
  64857. /*! @brief Compile-time position of the given type in the sublist. */
  64858. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  64859. };
  64860. /**
  64861. * @brief Provides compile-time type access to the types of a type list.
  64862. * @tparam Type Type to look for and for which to return the index.
  64863. * @tparam Other Other types provided by the type list.
  64864. */
  64865. template<typename Type, typename... Other>
  64866. struct type_list_index<Type, type_list<Type, Other...>> {
  64867. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  64868. /*! @brief Unsigned integer type. */
  64869. using value_type = std::size_t;
  64870. /*! @brief Compile-time position of the given type in the sublist. */
  64871. static constexpr value_type value = 0u;
  64872. };
  64873. /**
  64874. * @brief Provides compile-time type access to the types of a type list.
  64875. * @tparam Type Type to look for and for which to return the index.
  64876. */
  64877. template<typename Type>
  64878. struct type_list_index<Type, type_list<>> {
  64879. /*! @brief Unsigned integer type. */
  64880. using value_type = std::size_t;
  64881. /*! @brief Compile-time position of the given type in the sublist. */
  64882. static constexpr value_type value = 0u;
  64883. };
  64884. /**
  64885. * @brief Helper variable template.
  64886. * @tparam List Type list.
  64887. * @tparam Type Type to look for and for which to return the index.
  64888. */
  64889. template<typename Type, typename List>
  64890. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  64891. /**
  64892. * @brief Concatenates multiple type lists.
  64893. * @tparam Type Types provided by the first type list.
  64894. * @tparam Other Types provided by the second type list.
  64895. * @return A type list composed by the types of both the type lists.
  64896. */
  64897. template<typename... Type, typename... Other>
  64898. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  64899. return {};
  64900. }
  64901. /*! @brief Primary template isn't defined on purpose. */
  64902. template<typename...>
  64903. struct type_list_cat;
  64904. /*! @brief Concatenates multiple type lists. */
  64905. template<>
  64906. struct type_list_cat<> {
  64907. /*! @brief A type list composed by the types of all the type lists. */
  64908. using type = type_list<>;
  64909. };
  64910. /**
  64911. * @brief Concatenates multiple type lists.
  64912. * @tparam Type Types provided by the first type list.
  64913. * @tparam Other Types provided by the second type list.
  64914. * @tparam List Other type lists, if any.
  64915. */
  64916. template<typename... Type, typename... Other, typename... List>
  64917. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  64918. /*! @brief A type list composed by the types of all the type lists. */
  64919. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  64920. };
  64921. /**
  64922. * @brief Concatenates multiple type lists.
  64923. * @tparam Type Types provided by the type list.
  64924. */
  64925. template<typename... Type>
  64926. struct type_list_cat<type_list<Type...>> {
  64927. /*! @brief A type list composed by the types of all the type lists. */
  64928. using type = type_list<Type...>;
  64929. };
  64930. /**
  64931. * @brief Helper type.
  64932. * @tparam List Type lists to concatenate.
  64933. */
  64934. template<typename... List>
  64935. using type_list_cat_t = typename type_list_cat<List...>::type;
  64936. /*! @cond TURN_OFF_DOXYGEN */
  64937. namespace internal {
  64938. template<typename...>
  64939. struct type_list_unique;
  64940. template<typename First, typename... Other, typename... Type>
  64941. struct type_list_unique<type_list<First, Other...>, Type...>
  64942. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  64943. template<typename... Type>
  64944. struct type_list_unique<type_list<>, Type...> {
  64945. using type = type_list<Type...>;
  64946. };
  64947. } // namespace internal
  64948. /*! @endcond */
  64949. /**
  64950. * @brief Removes duplicates types from a type list.
  64951. * @tparam List Type list.
  64952. */
  64953. template<typename List>
  64954. struct type_list_unique {
  64955. /*! @brief A type list without duplicate types. */
  64956. using type = typename internal::type_list_unique<List>::type;
  64957. };
  64958. /**
  64959. * @brief Helper type.
  64960. * @tparam List Type list.
  64961. */
  64962. template<typename List>
  64963. using type_list_unique_t = typename type_list_unique<List>::type;
  64964. /**
  64965. * @brief Provides the member constant `value` to true if a type list contains a
  64966. * given type, false otherwise.
  64967. * @tparam List Type list.
  64968. * @tparam Type Type to look for.
  64969. */
  64970. template<typename List, typename Type>
  64971. struct type_list_contains;
  64972. /**
  64973. * @copybrief type_list_contains
  64974. * @tparam Type Types provided by the type list.
  64975. * @tparam Other Type to look for.
  64976. */
  64977. template<typename... Type, typename Other>
  64978. struct type_list_contains<type_list<Type...>, Other>
  64979. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  64980. /**
  64981. * @brief Helper variable template.
  64982. * @tparam List Type list.
  64983. * @tparam Type Type to look for.
  64984. */
  64985. template<typename List, typename Type>
  64986. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  64987. /*! @brief Primary template isn't defined on purpose. */
  64988. template<typename...>
  64989. struct type_list_diff;
  64990. /**
  64991. * @brief Computes the difference between two type lists.
  64992. * @tparam Type Types provided by the first type list.
  64993. * @tparam Other Types provided by the second type list.
  64994. */
  64995. template<typename... Type, typename... Other>
  64996. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  64997. /*! @brief A type list that is the difference between the two type lists. */
  64998. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  64999. };
  65000. /**
  65001. * @brief Helper type.
  65002. * @tparam List Type lists between which to compute the difference.
  65003. */
  65004. template<typename... List>
  65005. using type_list_diff_t = typename type_list_diff<List...>::type;
  65006. /*! @brief Primary template isn't defined on purpose. */
  65007. template<typename, template<typename...> class>
  65008. struct type_list_transform;
  65009. /**
  65010. * @brief Applies a given _function_ to a type list and generate a new list.
  65011. * @tparam Type Types provided by the type list.
  65012. * @tparam Op Unary operation as template class with a type member named `type`.
  65013. */
  65014. template<typename... Type, template<typename...> class Op>
  65015. struct type_list_transform<type_list<Type...>, Op> {
  65016. /*! @brief Resulting type list after applying the transform function. */
  65017. // NOLINTNEXTLINE(modernize-type-traits)
  65018. using type = type_list<typename Op<Type>::type...>;
  65019. };
  65020. /**
  65021. * @brief Helper type.
  65022. * @tparam List Type list.
  65023. * @tparam Op Unary operation as template class with a type member named `type`.
  65024. */
  65025. template<typename List, template<typename...> class Op>
  65026. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  65027. /**
  65028. * @brief A class to use to push around lists of constant values, nothing more.
  65029. * @tparam Value Values provided by the value list.
  65030. */
  65031. template<auto... Value>
  65032. struct value_list {
  65033. /*! @brief Value list type. */
  65034. using type = value_list;
  65035. /*! @brief Compile-time number of elements in the value list. */
  65036. static constexpr auto size = sizeof...(Value);
  65037. };
  65038. /*! @brief Primary template isn't defined on purpose. */
  65039. template<std::size_t, typename>
  65040. struct value_list_element;
  65041. /**
  65042. * @brief Provides compile-time indexed access to the values of a value list.
  65043. * @tparam Index Index of the value to return.
  65044. * @tparam Value First value provided by the value list.
  65045. * @tparam Other Other values provided by the value list.
  65046. */
  65047. template<std::size_t Index, auto Value, auto... Other>
  65048. struct value_list_element<Index, value_list<Value, Other...>>
  65049. : value_list_element<Index - 1u, value_list<Other...>> {};
  65050. /**
  65051. * @brief Provides compile-time indexed access to the types of a type list.
  65052. * @tparam Value First value provided by the value list.
  65053. * @tparam Other Other values provided by the value list.
  65054. */
  65055. template<auto Value, auto... Other>
  65056. struct value_list_element<0u, value_list<Value, Other...>> {
  65057. /*! @brief Searched type. */
  65058. using type = decltype(Value);
  65059. /*! @brief Searched value. */
  65060. static constexpr auto value = Value;
  65061. };
  65062. /**
  65063. * @brief Helper type.
  65064. * @tparam Index Index of the type to return.
  65065. * @tparam List Value list to search into.
  65066. */
  65067. template<std::size_t Index, typename List>
  65068. using value_list_element_t = typename value_list_element<Index, List>::type;
  65069. /**
  65070. * @brief Helper type.
  65071. * @tparam Index Index of the value to return.
  65072. * @tparam List Value list to search into.
  65073. */
  65074. template<std::size_t Index, typename List>
  65075. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  65076. /*! @brief Primary template isn't defined on purpose. */
  65077. template<auto, typename>
  65078. struct value_list_index;
  65079. /**
  65080. * @brief Provides compile-time type access to the values of a value list.
  65081. * @tparam Value Value to look for and for which to return the index.
  65082. * @tparam First First value provided by the value list.
  65083. * @tparam Other Other values provided by the value list.
  65084. */
  65085. template<auto Value, auto First, auto... Other>
  65086. struct value_list_index<Value, value_list<First, Other...>> {
  65087. /*! @brief Unsigned integer type. */
  65088. using value_type = std::size_t;
  65089. /*! @brief Compile-time position of the given value in the sublist. */
  65090. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  65091. };
  65092. /**
  65093. * @brief Provides compile-time type access to the values of a value list.
  65094. * @tparam Value Value to look for and for which to return the index.
  65095. * @tparam Other Other values provided by the value list.
  65096. */
  65097. template<auto Value, auto... Other>
  65098. struct value_list_index<Value, value_list<Value, Other...>> {
  65099. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  65100. /*! @brief Unsigned integer type. */
  65101. using value_type = std::size_t;
  65102. /*! @brief Compile-time position of the given value in the sublist. */
  65103. static constexpr value_type value = 0u;
  65104. };
  65105. /**
  65106. * @brief Provides compile-time type access to the values of a value list.
  65107. * @tparam Value Value to look for and for which to return the index.
  65108. */
  65109. template<auto Value>
  65110. struct value_list_index<Value, value_list<>> {
  65111. /*! @brief Unsigned integer type. */
  65112. using value_type = std::size_t;
  65113. /*! @brief Compile-time position of the given type in the sublist. */
  65114. static constexpr value_type value = 0u;
  65115. };
  65116. /**
  65117. * @brief Helper variable template.
  65118. * @tparam List Value list.
  65119. * @tparam Value Value to look for and for which to return the index.
  65120. */
  65121. template<auto Value, typename List>
  65122. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  65123. /**
  65124. * @brief Concatenates multiple value lists.
  65125. * @tparam Value Values provided by the first value list.
  65126. * @tparam Other Values provided by the second value list.
  65127. * @return A value list composed by the values of both the value lists.
  65128. */
  65129. template<auto... Value, auto... Other>
  65130. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  65131. return {};
  65132. }
  65133. /*! @brief Primary template isn't defined on purpose. */
  65134. template<typename...>
  65135. struct value_list_cat;
  65136. /*! @brief Concatenates multiple value lists. */
  65137. template<>
  65138. struct value_list_cat<> {
  65139. /*! @brief A value list composed by the values of all the value lists. */
  65140. using type = value_list<>;
  65141. };
  65142. /**
  65143. * @brief Concatenates multiple value lists.
  65144. * @tparam Value Values provided by the first value list.
  65145. * @tparam Other Values provided by the second value list.
  65146. * @tparam List Other value lists, if any.
  65147. */
  65148. template<auto... Value, auto... Other, typename... List>
  65149. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  65150. /*! @brief A value list composed by the values of all the value lists. */
  65151. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  65152. };
  65153. /**
  65154. * @brief Concatenates multiple value lists.
  65155. * @tparam Value Values provided by the value list.
  65156. */
  65157. template<auto... Value>
  65158. struct value_list_cat<value_list<Value...>> {
  65159. /*! @brief A value list composed by the values of all the value lists. */
  65160. using type = value_list<Value...>;
  65161. };
  65162. /**
  65163. * @brief Helper type.
  65164. * @tparam List Value lists to concatenate.
  65165. */
  65166. template<typename... List>
  65167. using value_list_cat_t = typename value_list_cat<List...>::type;
  65168. /*! @brief Primary template isn't defined on purpose. */
  65169. template<typename>
  65170. struct value_list_unique;
  65171. /**
  65172. * @brief Removes duplicates values from a value list.
  65173. * @tparam Value One of the values provided by the given value list.
  65174. * @tparam Other The other values provided by the given value list.
  65175. */
  65176. template<auto Value, auto... Other>
  65177. struct value_list_unique<value_list<Value, Other...>> {
  65178. /*! @brief A value list without duplicate types. */
  65179. using type = std::conditional_t<
  65180. ((Value == Other) || ...),
  65181. typename value_list_unique<value_list<Other...>>::type,
  65182. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  65183. };
  65184. /*! @brief Removes duplicates values from a value list. */
  65185. template<>
  65186. struct value_list_unique<value_list<>> {
  65187. /*! @brief A value list without duplicate types. */
  65188. using type = value_list<>;
  65189. };
  65190. /**
  65191. * @brief Helper type.
  65192. * @tparam Type A value list.
  65193. */
  65194. template<typename Type>
  65195. using value_list_unique_t = typename value_list_unique<Type>::type;
  65196. /**
  65197. * @brief Provides the member constant `value` to true if a value list contains
  65198. * a given value, false otherwise.
  65199. * @tparam List Value list.
  65200. * @tparam Value Value to look for.
  65201. */
  65202. template<typename List, auto Value>
  65203. struct value_list_contains;
  65204. /**
  65205. * @copybrief value_list_contains
  65206. * @tparam Value Values provided by the value list.
  65207. * @tparam Other Value to look for.
  65208. */
  65209. template<auto... Value, auto Other>
  65210. struct value_list_contains<value_list<Value...>, Other>
  65211. : std::bool_constant<((Value == Other) || ...)> {};
  65212. /**
  65213. * @brief Helper variable template.
  65214. * @tparam List Value list.
  65215. * @tparam Value Value to look for.
  65216. */
  65217. template<typename List, auto Value>
  65218. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  65219. /*! @brief Primary template isn't defined on purpose. */
  65220. template<typename...>
  65221. struct value_list_diff;
  65222. /**
  65223. * @brief Computes the difference between two value lists.
  65224. * @tparam Value Values provided by the first value list.
  65225. * @tparam Other Values provided by the second value list.
  65226. */
  65227. template<auto... Value, auto... Other>
  65228. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  65229. /*! @brief A value list that is the difference between the two value lists. */
  65230. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  65231. };
  65232. /**
  65233. * @brief Helper type.
  65234. * @tparam List Value lists between which to compute the difference.
  65235. */
  65236. template<typename... List>
  65237. using value_list_diff_t = typename value_list_diff<List...>::type;
  65238. /*! @brief Same as std::is_invocable, but with tuples. */
  65239. template<typename, typename>
  65240. struct is_applicable: std::false_type {};
  65241. /**
  65242. * @copybrief is_applicable
  65243. * @tparam Func A valid function type.
  65244. * @tparam Tuple Tuple-like type.
  65245. * @tparam Args The list of arguments to use to probe the function type.
  65246. */
  65247. template<typename Func, template<typename...> class Tuple, typename... Args>
  65248. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  65249. /**
  65250. * @copybrief is_applicable
  65251. * @tparam Func A valid function type.
  65252. * @tparam Tuple Tuple-like type.
  65253. * @tparam Args The list of arguments to use to probe the function type.
  65254. */
  65255. template<typename Func, template<typename...> class Tuple, typename... Args>
  65256. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  65257. /**
  65258. * @brief Helper variable template.
  65259. * @tparam Func A valid function type.
  65260. * @tparam Args The list of arguments to use to probe the function type.
  65261. */
  65262. template<typename Func, typename Args>
  65263. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  65264. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  65265. template<typename, typename, typename>
  65266. struct is_applicable_r: std::false_type {};
  65267. /**
  65268. * @copybrief is_applicable_r
  65269. * @tparam Ret The type to which the return type of the function should be
  65270. * convertible.
  65271. * @tparam Func A valid function type.
  65272. * @tparam Args The list of arguments to use to probe the function type.
  65273. */
  65274. template<typename Ret, typename Func, typename... Args>
  65275. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  65276. /**
  65277. * @brief Helper variable template.
  65278. * @tparam Ret The type to which the return type of the function should be
  65279. * convertible.
  65280. * @tparam Func A valid function type.
  65281. * @tparam Args The list of arguments to use to probe the function type.
  65282. */
  65283. template<typename Ret, typename Func, typename Args>
  65284. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  65285. /**
  65286. * @brief Provides the member constant `value` to true if a given type is
  65287. * complete, false otherwise.
  65288. * @tparam Type The type to test.
  65289. */
  65290. template<typename Type, typename = void>
  65291. struct is_complete: std::false_type {};
  65292. /*! @copydoc is_complete */
  65293. template<typename Type>
  65294. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  65295. /**
  65296. * @brief Helper variable template.
  65297. * @tparam Type The type to test.
  65298. */
  65299. template<typename Type>
  65300. inline constexpr bool is_complete_v = is_complete<Type>::value;
  65301. /**
  65302. * @brief Provides the member constant `value` to true if a given type is an
  65303. * iterator, false otherwise.
  65304. * @tparam Type The type to test.
  65305. */
  65306. template<typename Type, typename = void>
  65307. struct is_iterator: std::false_type {};
  65308. /*! @cond TURN_OFF_DOXYGEN */
  65309. namespace internal {
  65310. template<typename, typename = void>
  65311. struct has_iterator_category: std::false_type {};
  65312. template<typename Type>
  65313. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  65314. } // namespace internal
  65315. /*! @endcond */
  65316. /*! @copydoc is_iterator */
  65317. template<typename Type>
  65318. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  65319. : internal::has_iterator_category<Type> {};
  65320. /**
  65321. * @brief Helper variable template.
  65322. * @tparam Type The type to test.
  65323. */
  65324. template<typename Type>
  65325. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  65326. /**
  65327. * @brief Provides the member constant `value` to true if a given type is both
  65328. * an empty and non-final class, false otherwise.
  65329. * @tparam Type The type to test
  65330. */
  65331. template<typename Type>
  65332. struct is_ebco_eligible
  65333. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  65334. /**
  65335. * @brief Helper variable template.
  65336. * @tparam Type The type to test.
  65337. */
  65338. template<typename Type>
  65339. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  65340. /**
  65341. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  65342. * is valid and denotes a type, false otherwise.
  65343. * @tparam Type The type to test.
  65344. */
  65345. template<typename Type, typename = void>
  65346. struct is_transparent: std::false_type {};
  65347. /*! @copydoc is_transparent */
  65348. template<typename Type>
  65349. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  65350. /**
  65351. * @brief Helper variable template.
  65352. * @tparam Type The type to test.
  65353. */
  65354. template<typename Type>
  65355. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  65356. /*! @cond TURN_OFF_DOXYGEN */
  65357. namespace internal {
  65358. template<typename, typename = void>
  65359. struct has_tuple_size_value: std::false_type {};
  65360. template<typename Type>
  65361. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  65362. template<typename, typename = void>
  65363. struct has_value_type: std::false_type {};
  65364. template<typename Type>
  65365. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  65366. template<typename>
  65367. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  65368. template<typename Type, std::size_t... Index>
  65369. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  65370. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  65371. }
  65372. template<typename>
  65373. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  65374. return false;
  65375. }
  65376. template<typename Type>
  65377. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  65378. return true;
  65379. }
  65380. template<typename Type>
  65381. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  65382. // NOLINTBEGIN(modernize-use-transparent-functors)
  65383. if constexpr(std::is_array_v<Type>) {
  65384. return false;
  65385. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  65386. if constexpr(has_tuple_size_value<Type>::value) {
  65387. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  65388. } else {
  65389. return maybe_equality_comparable<Type>(0);
  65390. }
  65391. } else if constexpr(has_value_type<Type>::value) {
  65392. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  65393. return maybe_equality_comparable<Type>(0);
  65394. } else {
  65395. return false;
  65396. }
  65397. } else {
  65398. return maybe_equality_comparable<Type>(0);
  65399. }
  65400. // NOLINTEND(modernize-use-transparent-functors)
  65401. }
  65402. } // namespace internal
  65403. /*! @endcond */
  65404. /**
  65405. * @brief Provides the member constant `value` to true if a given type is
  65406. * equality comparable, false otherwise.
  65407. * @tparam Type The type to test.
  65408. */
  65409. template<typename Type>
  65410. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  65411. /*! @copydoc is_equality_comparable */
  65412. template<typename Type>
  65413. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  65414. /**
  65415. * @brief Helper variable template.
  65416. * @tparam Type The type to test.
  65417. */
  65418. template<typename Type>
  65419. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  65420. /**
  65421. * @brief Transcribes the constness of a type to another type.
  65422. * @tparam To The type to which to transcribe the constness.
  65423. * @tparam From The type from which to transcribe the constness.
  65424. */
  65425. template<typename To, typename From>
  65426. struct constness_as {
  65427. /*! @brief The type resulting from the transcription of the constness. */
  65428. using type = std::remove_const_t<To>;
  65429. };
  65430. /*! @copydoc constness_as */
  65431. template<typename To, typename From>
  65432. struct constness_as<To, const From> {
  65433. /*! @brief The type resulting from the transcription of the constness. */
  65434. using type = const To;
  65435. };
  65436. /**
  65437. * @brief Alias template to facilitate the transcription of the constness.
  65438. * @tparam To The type to which to transcribe the constness.
  65439. * @tparam From The type from which to transcribe the constness.
  65440. */
  65441. template<typename To, typename From>
  65442. using constness_as_t = typename constness_as<To, From>::type;
  65443. /**
  65444. * @brief Extracts the class of a non-static member object or function.
  65445. * @tparam Member A pointer to a non-static member object or function.
  65446. */
  65447. template<typename Member>
  65448. class member_class {
  65449. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  65450. template<typename Class, typename Ret, typename... Args>
  65451. static Class *clazz(Ret (Class::*)(Args...));
  65452. template<typename Class, typename Ret, typename... Args>
  65453. static Class *clazz(Ret (Class::*)(Args...) const);
  65454. template<typename Class, typename Type>
  65455. static Class *clazz(Type Class::*);
  65456. public:
  65457. /*! @brief The class of the given non-static member object or function. */
  65458. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  65459. };
  65460. /**
  65461. * @brief Helper type.
  65462. * @tparam Member A pointer to a non-static member object or function.
  65463. */
  65464. template<typename Member>
  65465. using member_class_t = typename member_class<Member>::type;
  65466. /**
  65467. * @brief Extracts the n-th argument of a _callable_ type.
  65468. * @tparam Index The index of the argument to extract.
  65469. * @tparam Candidate A valid _callable_ type.
  65470. */
  65471. template<std::size_t Index, typename Candidate>
  65472. class nth_argument {
  65473. template<typename Ret, typename... Args>
  65474. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  65475. template<typename Ret, typename Class, typename... Args>
  65476. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  65477. template<typename Ret, typename Class, typename... Args>
  65478. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  65479. template<typename Type, typename Class>
  65480. static constexpr type_list<Type> pick_up(Type Class ::*);
  65481. template<typename Type>
  65482. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  65483. public:
  65484. /*! @brief N-th argument of the _callable_ type. */
  65485. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  65486. };
  65487. /**
  65488. * @brief Helper type.
  65489. * @tparam Index The index of the argument to extract.
  65490. * @tparam Candidate A valid function, member function or data member type.
  65491. */
  65492. template<std::size_t Index, typename Candidate>
  65493. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  65494. } // namespace entt
  65495. template<typename... Type>
  65496. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  65497. template<std::size_t Index, typename... Type>
  65498. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  65499. template<auto... Value>
  65500. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  65501. template<std::size_t Index, auto... Value>
  65502. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  65503. #endif
  65504. namespace entt {
  65505. /*! @cond TURN_OFF_DOXYGEN */
  65506. namespace internal {
  65507. template<typename Type, std::size_t, typename = void>
  65508. struct compressed_pair_element {
  65509. using reference = Type &;
  65510. using const_reference = const Type &;
  65511. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  65512. // NOLINTNEXTLINE(modernize-use-equals-default)
  65513. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  65514. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  65515. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  65516. : value{std::forward<Arg>(arg)} {}
  65517. template<typename... Args, std::size_t... Index>
  65518. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  65519. : value{std::forward<Args>(std::get<Index>(args))...} {}
  65520. [[nodiscard]] constexpr reference get() noexcept {
  65521. return value;
  65522. }
  65523. [[nodiscard]] constexpr const_reference get() const noexcept {
  65524. return value;
  65525. }
  65526. private:
  65527. Type value{};
  65528. };
  65529. template<typename Type, std::size_t Tag>
  65530. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  65531. using reference = Type &;
  65532. using const_reference = const Type &;
  65533. using base_type = Type;
  65534. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  65535. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  65536. : base_type{} {}
  65537. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  65538. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  65539. : base_type{std::forward<Arg>(arg)} {}
  65540. template<typename... Args, std::size_t... Index>
  65541. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  65542. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  65543. [[nodiscard]] constexpr reference get() noexcept {
  65544. return *this;
  65545. }
  65546. [[nodiscard]] constexpr const_reference get() const noexcept {
  65547. return *this;
  65548. }
  65549. };
  65550. } // namespace internal
  65551. /*! @endcond */
  65552. /**
  65553. * @brief A compressed pair.
  65554. *
  65555. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  65556. * reduce its final size to a minimum.
  65557. *
  65558. * @tparam First The type of the first element that the pair stores.
  65559. * @tparam Second The type of the second element that the pair stores.
  65560. */
  65561. template<typename First, typename Second>
  65562. class compressed_pair final
  65563. : internal::compressed_pair_element<First, 0u>,
  65564. internal::compressed_pair_element<Second, 1u> {
  65565. using first_base = internal::compressed_pair_element<First, 0u>;
  65566. using second_base = internal::compressed_pair_element<Second, 1u>;
  65567. public:
  65568. /*! @brief The type of the first element that the pair stores. */
  65569. using first_type = First;
  65570. /*! @brief The type of the second element that the pair stores. */
  65571. using second_type = Second;
  65572. /**
  65573. * @brief Default constructor, conditionally enabled.
  65574. *
  65575. * This constructor is only available when the types that the pair stores
  65576. * are both at least default constructible.
  65577. *
  65578. * @tparam Dummy Dummy template parameter used for internal purposes.
  65579. */
  65580. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  65581. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  65582. : first_base{},
  65583. second_base{} {}
  65584. /**
  65585. * @brief Copy constructor.
  65586. * @param other The instance to copy from.
  65587. */
  65588. constexpr compressed_pair(const compressed_pair &other) = default;
  65589. /**
  65590. * @brief Move constructor.
  65591. * @param other The instance to move from.
  65592. */
  65593. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  65594. /**
  65595. * @brief Constructs a pair from its values.
  65596. * @tparam Arg Type of value to use to initialize the first element.
  65597. * @tparam Other Type of value to use to initialize the second element.
  65598. * @param arg Value to use to initialize the first element.
  65599. * @param other Value to use to initialize the second element.
  65600. */
  65601. template<typename Arg, typename Other>
  65602. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  65603. : first_base{std::forward<Arg>(arg)},
  65604. second_base{std::forward<Other>(other)} {}
  65605. /**
  65606. * @brief Constructs a pair by forwarding the arguments to its parts.
  65607. * @tparam Args Types of arguments to use to initialize the first element.
  65608. * @tparam Other Types of arguments to use to initialize the second element.
  65609. * @param args Arguments to use to initialize the first element.
  65610. * @param other Arguments to use to initialize the second element.
  65611. */
  65612. template<typename... Args, typename... Other>
  65613. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  65614. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  65615. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  65616. /*! @brief Default destructor. */
  65617. ~compressed_pair() = default;
  65618. /**
  65619. * @brief Copy assignment operator.
  65620. * @param other The instance to copy from.
  65621. * @return This compressed pair object.
  65622. */
  65623. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  65624. /**
  65625. * @brief Move assignment operator.
  65626. * @param other The instance to move from.
  65627. * @return This compressed pair object.
  65628. */
  65629. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  65630. /**
  65631. * @brief Returns the first element that a pair stores.
  65632. * @return The first element that a pair stores.
  65633. */
  65634. [[nodiscard]] constexpr first_type &first() noexcept {
  65635. return static_cast<first_base &>(*this).get();
  65636. }
  65637. /*! @copydoc first */
  65638. [[nodiscard]] constexpr const first_type &first() const noexcept {
  65639. return static_cast<const first_base &>(*this).get();
  65640. }
  65641. /**
  65642. * @brief Returns the second element that a pair stores.
  65643. * @return The second element that a pair stores.
  65644. */
  65645. [[nodiscard]] constexpr second_type &second() noexcept {
  65646. return static_cast<second_base &>(*this).get();
  65647. }
  65648. /*! @copydoc second */
  65649. [[nodiscard]] constexpr const second_type &second() const noexcept {
  65650. return static_cast<const second_base &>(*this).get();
  65651. }
  65652. /**
  65653. * @brief Swaps two compressed pair objects.
  65654. * @param other The compressed pair to swap with.
  65655. */
  65656. constexpr void swap(compressed_pair &other) noexcept {
  65657. using std::swap;
  65658. swap(first(), other.first());
  65659. swap(second(), other.second());
  65660. }
  65661. /**
  65662. * @brief Extracts an element from the compressed pair.
  65663. * @tparam Index An integer value that is either 0 or 1.
  65664. * @return Returns a reference to the first element if `Index` is 0 and a
  65665. * reference to the second element if `Index` is 1.
  65666. */
  65667. template<std::size_t Index>
  65668. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  65669. if constexpr(Index == 0u) {
  65670. return first();
  65671. } else {
  65672. static_assert(Index == 1u, "Index out of bounds");
  65673. return second();
  65674. }
  65675. }
  65676. /*! @copydoc get */
  65677. template<std::size_t Index>
  65678. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  65679. if constexpr(Index == 0u) {
  65680. return first();
  65681. } else {
  65682. static_assert(Index == 1u, "Index out of bounds");
  65683. return second();
  65684. }
  65685. }
  65686. };
  65687. /**
  65688. * @brief Deduction guide.
  65689. * @tparam Type Type of value to use to initialize the first element.
  65690. * @tparam Other Type of value to use to initialize the second element.
  65691. */
  65692. template<typename Type, typename Other>
  65693. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  65694. /**
  65695. * @brief Swaps two compressed pair objects.
  65696. * @tparam First The type of the first element that the pairs store.
  65697. * @tparam Second The type of the second element that the pairs store.
  65698. * @param lhs A valid compressed pair object.
  65699. * @param rhs A valid compressed pair object.
  65700. */
  65701. template<typename First, typename Second>
  65702. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  65703. lhs.swap(rhs);
  65704. }
  65705. } // namespace entt
  65706. namespace std {
  65707. /**
  65708. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  65709. * @tparam First The type of the first element that the pair stores.
  65710. * @tparam Second The type of the second element that the pair stores.
  65711. */
  65712. template<typename First, typename Second>
  65713. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  65714. /**
  65715. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  65716. * @tparam Index The index of the type to return.
  65717. * @tparam First The type of the first element that the pair stores.
  65718. * @tparam Second The type of the second element that the pair stores.
  65719. */
  65720. template<size_t Index, typename First, typename Second>
  65721. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  65722. static_assert(Index < 2u, "Index out of bounds");
  65723. };
  65724. } // namespace std
  65725. #endif
  65726. // #include "../core/type_traits.hpp"
  65727. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  65728. #define ENTT_CORE_TYPE_TRAITS_HPP
  65729. #include <cstddef>
  65730. #include <iterator>
  65731. #include <tuple>
  65732. #include <type_traits>
  65733. #include <utility>
  65734. // #include "../config/config.h"
  65735. // #include "fwd.hpp"
  65736. namespace entt {
  65737. /**
  65738. * @brief Utility class to disambiguate overloaded functions.
  65739. * @tparam N Number of choices available.
  65740. */
  65741. template<std::size_t N>
  65742. struct choice_t
  65743. // unfortunately, doxygen cannot parse such a construct
  65744. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  65745. {};
  65746. /*! @copybrief choice_t */
  65747. template<>
  65748. struct choice_t<0> {};
  65749. /**
  65750. * @brief Variable template for the choice trick.
  65751. * @tparam N Number of choices available.
  65752. */
  65753. template<std::size_t N>
  65754. inline constexpr choice_t<N> choice{};
  65755. /**
  65756. * @brief Identity type trait.
  65757. *
  65758. * Useful to establish non-deduced contexts in template argument deduction
  65759. * (waiting for C++20) or to provide types through function arguments.
  65760. *
  65761. * @tparam Type A type.
  65762. */
  65763. template<typename Type>
  65764. struct type_identity {
  65765. /*! @brief Identity type. */
  65766. using type = Type;
  65767. };
  65768. /**
  65769. * @brief Helper type.
  65770. * @tparam Type A type.
  65771. */
  65772. template<typename Type>
  65773. using type_identity_t = typename type_identity<Type>::type;
  65774. /**
  65775. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  65776. * @tparam Type The type of which to return the size.
  65777. */
  65778. template<typename Type, typename = void>
  65779. struct size_of: std::integral_constant<std::size_t, 0u> {};
  65780. /*! @copydoc size_of */
  65781. template<typename Type>
  65782. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  65783. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  65784. : std::integral_constant<std::size_t, sizeof(Type)> {};
  65785. /**
  65786. * @brief Helper variable template.
  65787. * @tparam Type The type of which to return the size.
  65788. */
  65789. template<typename Type>
  65790. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  65791. /**
  65792. * @brief Using declaration to be used to _repeat_ the same type a number of
  65793. * times equal to the size of a given parameter pack.
  65794. * @tparam Type A type to repeat.
  65795. */
  65796. template<typename Type, typename>
  65797. using unpack_as_type = Type;
  65798. /**
  65799. * @brief Helper variable template to be used to _repeat_ the same value a
  65800. * number of times equal to the size of a given parameter pack.
  65801. * @tparam Value A value to repeat.
  65802. */
  65803. template<auto Value, typename>
  65804. inline constexpr auto unpack_as_value = Value;
  65805. /**
  65806. * @brief Wraps a static constant.
  65807. * @tparam Value A static constant.
  65808. */
  65809. template<auto Value>
  65810. using integral_constant = std::integral_constant<decltype(Value), Value>;
  65811. /**
  65812. * @brief Alias template to facilitate the creation of named values.
  65813. * @tparam Value A constant value at least convertible to `id_type`.
  65814. */
  65815. template<id_type Value>
  65816. using tag = integral_constant<Value>;
  65817. /**
  65818. * @brief A class to use to push around lists of types, nothing more.
  65819. * @tparam Type Types provided by the type list.
  65820. */
  65821. template<typename... Type>
  65822. struct type_list {
  65823. /*! @brief Type list type. */
  65824. using type = type_list;
  65825. /*! @brief Compile-time number of elements in the type list. */
  65826. static constexpr auto size = sizeof...(Type);
  65827. };
  65828. /*! @brief Primary template isn't defined on purpose. */
  65829. template<std::size_t, typename>
  65830. struct type_list_element;
  65831. /**
  65832. * @brief Provides compile-time indexed access to the types of a type list.
  65833. * @tparam Index Index of the type to return.
  65834. * @tparam First First type provided by the type list.
  65835. * @tparam Other Other types provided by the type list.
  65836. */
  65837. template<std::size_t Index, typename First, typename... Other>
  65838. struct type_list_element<Index, type_list<First, Other...>>
  65839. : type_list_element<Index - 1u, type_list<Other...>> {};
  65840. /**
  65841. * @brief Provides compile-time indexed access to the types of a type list.
  65842. * @tparam First First type provided by the type list.
  65843. * @tparam Other Other types provided by the type list.
  65844. */
  65845. template<typename First, typename... Other>
  65846. struct type_list_element<0u, type_list<First, Other...>> {
  65847. /*! @brief Searched type. */
  65848. using type = First;
  65849. };
  65850. /**
  65851. * @brief Helper type.
  65852. * @tparam Index Index of the type to return.
  65853. * @tparam List Type list to search into.
  65854. */
  65855. template<std::size_t Index, typename List>
  65856. using type_list_element_t = typename type_list_element<Index, List>::type;
  65857. /*! @brief Primary template isn't defined on purpose. */
  65858. template<typename, typename>
  65859. struct type_list_index;
  65860. /**
  65861. * @brief Provides compile-time type access to the types of a type list.
  65862. * @tparam Type Type to look for and for which to return the index.
  65863. * @tparam First First type provided by the type list.
  65864. * @tparam Other Other types provided by the type list.
  65865. */
  65866. template<typename Type, typename First, typename... Other>
  65867. struct type_list_index<Type, type_list<First, Other...>> {
  65868. /*! @brief Unsigned integer type. */
  65869. using value_type = std::size_t;
  65870. /*! @brief Compile-time position of the given type in the sublist. */
  65871. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  65872. };
  65873. /**
  65874. * @brief Provides compile-time type access to the types of a type list.
  65875. * @tparam Type Type to look for and for which to return the index.
  65876. * @tparam Other Other types provided by the type list.
  65877. */
  65878. template<typename Type, typename... Other>
  65879. struct type_list_index<Type, type_list<Type, Other...>> {
  65880. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  65881. /*! @brief Unsigned integer type. */
  65882. using value_type = std::size_t;
  65883. /*! @brief Compile-time position of the given type in the sublist. */
  65884. static constexpr value_type value = 0u;
  65885. };
  65886. /**
  65887. * @brief Provides compile-time type access to the types of a type list.
  65888. * @tparam Type Type to look for and for which to return the index.
  65889. */
  65890. template<typename Type>
  65891. struct type_list_index<Type, type_list<>> {
  65892. /*! @brief Unsigned integer type. */
  65893. using value_type = std::size_t;
  65894. /*! @brief Compile-time position of the given type in the sublist. */
  65895. static constexpr value_type value = 0u;
  65896. };
  65897. /**
  65898. * @brief Helper variable template.
  65899. * @tparam List Type list.
  65900. * @tparam Type Type to look for and for which to return the index.
  65901. */
  65902. template<typename Type, typename List>
  65903. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  65904. /**
  65905. * @brief Concatenates multiple type lists.
  65906. * @tparam Type Types provided by the first type list.
  65907. * @tparam Other Types provided by the second type list.
  65908. * @return A type list composed by the types of both the type lists.
  65909. */
  65910. template<typename... Type, typename... Other>
  65911. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  65912. return {};
  65913. }
  65914. /*! @brief Primary template isn't defined on purpose. */
  65915. template<typename...>
  65916. struct type_list_cat;
  65917. /*! @brief Concatenates multiple type lists. */
  65918. template<>
  65919. struct type_list_cat<> {
  65920. /*! @brief A type list composed by the types of all the type lists. */
  65921. using type = type_list<>;
  65922. };
  65923. /**
  65924. * @brief Concatenates multiple type lists.
  65925. * @tparam Type Types provided by the first type list.
  65926. * @tparam Other Types provided by the second type list.
  65927. * @tparam List Other type lists, if any.
  65928. */
  65929. template<typename... Type, typename... Other, typename... List>
  65930. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  65931. /*! @brief A type list composed by the types of all the type lists. */
  65932. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  65933. };
  65934. /**
  65935. * @brief Concatenates multiple type lists.
  65936. * @tparam Type Types provided by the type list.
  65937. */
  65938. template<typename... Type>
  65939. struct type_list_cat<type_list<Type...>> {
  65940. /*! @brief A type list composed by the types of all the type lists. */
  65941. using type = type_list<Type...>;
  65942. };
  65943. /**
  65944. * @brief Helper type.
  65945. * @tparam List Type lists to concatenate.
  65946. */
  65947. template<typename... List>
  65948. using type_list_cat_t = typename type_list_cat<List...>::type;
  65949. /*! @cond TURN_OFF_DOXYGEN */
  65950. namespace internal {
  65951. template<typename...>
  65952. struct type_list_unique;
  65953. template<typename First, typename... Other, typename... Type>
  65954. struct type_list_unique<type_list<First, Other...>, Type...>
  65955. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  65956. template<typename... Type>
  65957. struct type_list_unique<type_list<>, Type...> {
  65958. using type = type_list<Type...>;
  65959. };
  65960. } // namespace internal
  65961. /*! @endcond */
  65962. /**
  65963. * @brief Removes duplicates types from a type list.
  65964. * @tparam List Type list.
  65965. */
  65966. template<typename List>
  65967. struct type_list_unique {
  65968. /*! @brief A type list without duplicate types. */
  65969. using type = typename internal::type_list_unique<List>::type;
  65970. };
  65971. /**
  65972. * @brief Helper type.
  65973. * @tparam List Type list.
  65974. */
  65975. template<typename List>
  65976. using type_list_unique_t = typename type_list_unique<List>::type;
  65977. /**
  65978. * @brief Provides the member constant `value` to true if a type list contains a
  65979. * given type, false otherwise.
  65980. * @tparam List Type list.
  65981. * @tparam Type Type to look for.
  65982. */
  65983. template<typename List, typename Type>
  65984. struct type_list_contains;
  65985. /**
  65986. * @copybrief type_list_contains
  65987. * @tparam Type Types provided by the type list.
  65988. * @tparam Other Type to look for.
  65989. */
  65990. template<typename... Type, typename Other>
  65991. struct type_list_contains<type_list<Type...>, Other>
  65992. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  65993. /**
  65994. * @brief Helper variable template.
  65995. * @tparam List Type list.
  65996. * @tparam Type Type to look for.
  65997. */
  65998. template<typename List, typename Type>
  65999. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  66000. /*! @brief Primary template isn't defined on purpose. */
  66001. template<typename...>
  66002. struct type_list_diff;
  66003. /**
  66004. * @brief Computes the difference between two type lists.
  66005. * @tparam Type Types provided by the first type list.
  66006. * @tparam Other Types provided by the second type list.
  66007. */
  66008. template<typename... Type, typename... Other>
  66009. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  66010. /*! @brief A type list that is the difference between the two type lists. */
  66011. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  66012. };
  66013. /**
  66014. * @brief Helper type.
  66015. * @tparam List Type lists between which to compute the difference.
  66016. */
  66017. template<typename... List>
  66018. using type_list_diff_t = typename type_list_diff<List...>::type;
  66019. /*! @brief Primary template isn't defined on purpose. */
  66020. template<typename, template<typename...> class>
  66021. struct type_list_transform;
  66022. /**
  66023. * @brief Applies a given _function_ to a type list and generate a new list.
  66024. * @tparam Type Types provided by the type list.
  66025. * @tparam Op Unary operation as template class with a type member named `type`.
  66026. */
  66027. template<typename... Type, template<typename...> class Op>
  66028. struct type_list_transform<type_list<Type...>, Op> {
  66029. /*! @brief Resulting type list after applying the transform function. */
  66030. // NOLINTNEXTLINE(modernize-type-traits)
  66031. using type = type_list<typename Op<Type>::type...>;
  66032. };
  66033. /**
  66034. * @brief Helper type.
  66035. * @tparam List Type list.
  66036. * @tparam Op Unary operation as template class with a type member named `type`.
  66037. */
  66038. template<typename List, template<typename...> class Op>
  66039. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  66040. /**
  66041. * @brief A class to use to push around lists of constant values, nothing more.
  66042. * @tparam Value Values provided by the value list.
  66043. */
  66044. template<auto... Value>
  66045. struct value_list {
  66046. /*! @brief Value list type. */
  66047. using type = value_list;
  66048. /*! @brief Compile-time number of elements in the value list. */
  66049. static constexpr auto size = sizeof...(Value);
  66050. };
  66051. /*! @brief Primary template isn't defined on purpose. */
  66052. template<std::size_t, typename>
  66053. struct value_list_element;
  66054. /**
  66055. * @brief Provides compile-time indexed access to the values of a value list.
  66056. * @tparam Index Index of the value to return.
  66057. * @tparam Value First value provided by the value list.
  66058. * @tparam Other Other values provided by the value list.
  66059. */
  66060. template<std::size_t Index, auto Value, auto... Other>
  66061. struct value_list_element<Index, value_list<Value, Other...>>
  66062. : value_list_element<Index - 1u, value_list<Other...>> {};
  66063. /**
  66064. * @brief Provides compile-time indexed access to the types of a type list.
  66065. * @tparam Value First value provided by the value list.
  66066. * @tparam Other Other values provided by the value list.
  66067. */
  66068. template<auto Value, auto... Other>
  66069. struct value_list_element<0u, value_list<Value, Other...>> {
  66070. /*! @brief Searched type. */
  66071. using type = decltype(Value);
  66072. /*! @brief Searched value. */
  66073. static constexpr auto value = Value;
  66074. };
  66075. /**
  66076. * @brief Helper type.
  66077. * @tparam Index Index of the type to return.
  66078. * @tparam List Value list to search into.
  66079. */
  66080. template<std::size_t Index, typename List>
  66081. using value_list_element_t = typename value_list_element<Index, List>::type;
  66082. /**
  66083. * @brief Helper type.
  66084. * @tparam Index Index of the value to return.
  66085. * @tparam List Value list to search into.
  66086. */
  66087. template<std::size_t Index, typename List>
  66088. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  66089. /*! @brief Primary template isn't defined on purpose. */
  66090. template<auto, typename>
  66091. struct value_list_index;
  66092. /**
  66093. * @brief Provides compile-time type access to the values of a value list.
  66094. * @tparam Value Value to look for and for which to return the index.
  66095. * @tparam First First value provided by the value list.
  66096. * @tparam Other Other values provided by the value list.
  66097. */
  66098. template<auto Value, auto First, auto... Other>
  66099. struct value_list_index<Value, value_list<First, Other...>> {
  66100. /*! @brief Unsigned integer type. */
  66101. using value_type = std::size_t;
  66102. /*! @brief Compile-time position of the given value in the sublist. */
  66103. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  66104. };
  66105. /**
  66106. * @brief Provides compile-time type access to the values of a value list.
  66107. * @tparam Value Value to look for and for which to return the index.
  66108. * @tparam Other Other values provided by the value list.
  66109. */
  66110. template<auto Value, auto... Other>
  66111. struct value_list_index<Value, value_list<Value, Other...>> {
  66112. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  66113. /*! @brief Unsigned integer type. */
  66114. using value_type = std::size_t;
  66115. /*! @brief Compile-time position of the given value in the sublist. */
  66116. static constexpr value_type value = 0u;
  66117. };
  66118. /**
  66119. * @brief Provides compile-time type access to the values of a value list.
  66120. * @tparam Value Value to look for and for which to return the index.
  66121. */
  66122. template<auto Value>
  66123. struct value_list_index<Value, value_list<>> {
  66124. /*! @brief Unsigned integer type. */
  66125. using value_type = std::size_t;
  66126. /*! @brief Compile-time position of the given type in the sublist. */
  66127. static constexpr value_type value = 0u;
  66128. };
  66129. /**
  66130. * @brief Helper variable template.
  66131. * @tparam List Value list.
  66132. * @tparam Value Value to look for and for which to return the index.
  66133. */
  66134. template<auto Value, typename List>
  66135. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  66136. /**
  66137. * @brief Concatenates multiple value lists.
  66138. * @tparam Value Values provided by the first value list.
  66139. * @tparam Other Values provided by the second value list.
  66140. * @return A value list composed by the values of both the value lists.
  66141. */
  66142. template<auto... Value, auto... Other>
  66143. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  66144. return {};
  66145. }
  66146. /*! @brief Primary template isn't defined on purpose. */
  66147. template<typename...>
  66148. struct value_list_cat;
  66149. /*! @brief Concatenates multiple value lists. */
  66150. template<>
  66151. struct value_list_cat<> {
  66152. /*! @brief A value list composed by the values of all the value lists. */
  66153. using type = value_list<>;
  66154. };
  66155. /**
  66156. * @brief Concatenates multiple value lists.
  66157. * @tparam Value Values provided by the first value list.
  66158. * @tparam Other Values provided by the second value list.
  66159. * @tparam List Other value lists, if any.
  66160. */
  66161. template<auto... Value, auto... Other, typename... List>
  66162. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  66163. /*! @brief A value list composed by the values of all the value lists. */
  66164. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  66165. };
  66166. /**
  66167. * @brief Concatenates multiple value lists.
  66168. * @tparam Value Values provided by the value list.
  66169. */
  66170. template<auto... Value>
  66171. struct value_list_cat<value_list<Value...>> {
  66172. /*! @brief A value list composed by the values of all the value lists. */
  66173. using type = value_list<Value...>;
  66174. };
  66175. /**
  66176. * @brief Helper type.
  66177. * @tparam List Value lists to concatenate.
  66178. */
  66179. template<typename... List>
  66180. using value_list_cat_t = typename value_list_cat<List...>::type;
  66181. /*! @brief Primary template isn't defined on purpose. */
  66182. template<typename>
  66183. struct value_list_unique;
  66184. /**
  66185. * @brief Removes duplicates values from a value list.
  66186. * @tparam Value One of the values provided by the given value list.
  66187. * @tparam Other The other values provided by the given value list.
  66188. */
  66189. template<auto Value, auto... Other>
  66190. struct value_list_unique<value_list<Value, Other...>> {
  66191. /*! @brief A value list without duplicate types. */
  66192. using type = std::conditional_t<
  66193. ((Value == Other) || ...),
  66194. typename value_list_unique<value_list<Other...>>::type,
  66195. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  66196. };
  66197. /*! @brief Removes duplicates values from a value list. */
  66198. template<>
  66199. struct value_list_unique<value_list<>> {
  66200. /*! @brief A value list without duplicate types. */
  66201. using type = value_list<>;
  66202. };
  66203. /**
  66204. * @brief Helper type.
  66205. * @tparam Type A value list.
  66206. */
  66207. template<typename Type>
  66208. using value_list_unique_t = typename value_list_unique<Type>::type;
  66209. /**
  66210. * @brief Provides the member constant `value` to true if a value list contains
  66211. * a given value, false otherwise.
  66212. * @tparam List Value list.
  66213. * @tparam Value Value to look for.
  66214. */
  66215. template<typename List, auto Value>
  66216. struct value_list_contains;
  66217. /**
  66218. * @copybrief value_list_contains
  66219. * @tparam Value Values provided by the value list.
  66220. * @tparam Other Value to look for.
  66221. */
  66222. template<auto... Value, auto Other>
  66223. struct value_list_contains<value_list<Value...>, Other>
  66224. : std::bool_constant<((Value == Other) || ...)> {};
  66225. /**
  66226. * @brief Helper variable template.
  66227. * @tparam List Value list.
  66228. * @tparam Value Value to look for.
  66229. */
  66230. template<typename List, auto Value>
  66231. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  66232. /*! @brief Primary template isn't defined on purpose. */
  66233. template<typename...>
  66234. struct value_list_diff;
  66235. /**
  66236. * @brief Computes the difference between two value lists.
  66237. * @tparam Value Values provided by the first value list.
  66238. * @tparam Other Values provided by the second value list.
  66239. */
  66240. template<auto... Value, auto... Other>
  66241. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  66242. /*! @brief A value list that is the difference between the two value lists. */
  66243. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  66244. };
  66245. /**
  66246. * @brief Helper type.
  66247. * @tparam List Value lists between which to compute the difference.
  66248. */
  66249. template<typename... List>
  66250. using value_list_diff_t = typename value_list_diff<List...>::type;
  66251. /*! @brief Same as std::is_invocable, but with tuples. */
  66252. template<typename, typename>
  66253. struct is_applicable: std::false_type {};
  66254. /**
  66255. * @copybrief is_applicable
  66256. * @tparam Func A valid function type.
  66257. * @tparam Tuple Tuple-like type.
  66258. * @tparam Args The list of arguments to use to probe the function type.
  66259. */
  66260. template<typename Func, template<typename...> class Tuple, typename... Args>
  66261. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  66262. /**
  66263. * @copybrief is_applicable
  66264. * @tparam Func A valid function type.
  66265. * @tparam Tuple Tuple-like type.
  66266. * @tparam Args The list of arguments to use to probe the function type.
  66267. */
  66268. template<typename Func, template<typename...> class Tuple, typename... Args>
  66269. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  66270. /**
  66271. * @brief Helper variable template.
  66272. * @tparam Func A valid function type.
  66273. * @tparam Args The list of arguments to use to probe the function type.
  66274. */
  66275. template<typename Func, typename Args>
  66276. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  66277. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  66278. template<typename, typename, typename>
  66279. struct is_applicable_r: std::false_type {};
  66280. /**
  66281. * @copybrief is_applicable_r
  66282. * @tparam Ret The type to which the return type of the function should be
  66283. * convertible.
  66284. * @tparam Func A valid function type.
  66285. * @tparam Args The list of arguments to use to probe the function type.
  66286. */
  66287. template<typename Ret, typename Func, typename... Args>
  66288. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  66289. /**
  66290. * @brief Helper variable template.
  66291. * @tparam Ret The type to which the return type of the function should be
  66292. * convertible.
  66293. * @tparam Func A valid function type.
  66294. * @tparam Args The list of arguments to use to probe the function type.
  66295. */
  66296. template<typename Ret, typename Func, typename Args>
  66297. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  66298. /**
  66299. * @brief Provides the member constant `value` to true if a given type is
  66300. * complete, false otherwise.
  66301. * @tparam Type The type to test.
  66302. */
  66303. template<typename Type, typename = void>
  66304. struct is_complete: std::false_type {};
  66305. /*! @copydoc is_complete */
  66306. template<typename Type>
  66307. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  66308. /**
  66309. * @brief Helper variable template.
  66310. * @tparam Type The type to test.
  66311. */
  66312. template<typename Type>
  66313. inline constexpr bool is_complete_v = is_complete<Type>::value;
  66314. /**
  66315. * @brief Provides the member constant `value` to true if a given type is an
  66316. * iterator, false otherwise.
  66317. * @tparam Type The type to test.
  66318. */
  66319. template<typename Type, typename = void>
  66320. struct is_iterator: std::false_type {};
  66321. /*! @cond TURN_OFF_DOXYGEN */
  66322. namespace internal {
  66323. template<typename, typename = void>
  66324. struct has_iterator_category: std::false_type {};
  66325. template<typename Type>
  66326. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  66327. } // namespace internal
  66328. /*! @endcond */
  66329. /*! @copydoc is_iterator */
  66330. template<typename Type>
  66331. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  66332. : internal::has_iterator_category<Type> {};
  66333. /**
  66334. * @brief Helper variable template.
  66335. * @tparam Type The type to test.
  66336. */
  66337. template<typename Type>
  66338. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  66339. /**
  66340. * @brief Provides the member constant `value` to true if a given type is both
  66341. * an empty and non-final class, false otherwise.
  66342. * @tparam Type The type to test
  66343. */
  66344. template<typename Type>
  66345. struct is_ebco_eligible
  66346. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  66347. /**
  66348. * @brief Helper variable template.
  66349. * @tparam Type The type to test.
  66350. */
  66351. template<typename Type>
  66352. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  66353. /**
  66354. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  66355. * is valid and denotes a type, false otherwise.
  66356. * @tparam Type The type to test.
  66357. */
  66358. template<typename Type, typename = void>
  66359. struct is_transparent: std::false_type {};
  66360. /*! @copydoc is_transparent */
  66361. template<typename Type>
  66362. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  66363. /**
  66364. * @brief Helper variable template.
  66365. * @tparam Type The type to test.
  66366. */
  66367. template<typename Type>
  66368. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  66369. /*! @cond TURN_OFF_DOXYGEN */
  66370. namespace internal {
  66371. template<typename, typename = void>
  66372. struct has_tuple_size_value: std::false_type {};
  66373. template<typename Type>
  66374. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  66375. template<typename, typename = void>
  66376. struct has_value_type: std::false_type {};
  66377. template<typename Type>
  66378. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  66379. template<typename>
  66380. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  66381. template<typename Type, std::size_t... Index>
  66382. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  66383. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  66384. }
  66385. template<typename>
  66386. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  66387. return false;
  66388. }
  66389. template<typename Type>
  66390. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  66391. return true;
  66392. }
  66393. template<typename Type>
  66394. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  66395. // NOLINTBEGIN(modernize-use-transparent-functors)
  66396. if constexpr(std::is_array_v<Type>) {
  66397. return false;
  66398. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  66399. if constexpr(has_tuple_size_value<Type>::value) {
  66400. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  66401. } else {
  66402. return maybe_equality_comparable<Type>(0);
  66403. }
  66404. } else if constexpr(has_value_type<Type>::value) {
  66405. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  66406. return maybe_equality_comparable<Type>(0);
  66407. } else {
  66408. return false;
  66409. }
  66410. } else {
  66411. return maybe_equality_comparable<Type>(0);
  66412. }
  66413. // NOLINTEND(modernize-use-transparent-functors)
  66414. }
  66415. } // namespace internal
  66416. /*! @endcond */
  66417. /**
  66418. * @brief Provides the member constant `value` to true if a given type is
  66419. * equality comparable, false otherwise.
  66420. * @tparam Type The type to test.
  66421. */
  66422. template<typename Type>
  66423. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  66424. /*! @copydoc is_equality_comparable */
  66425. template<typename Type>
  66426. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  66427. /**
  66428. * @brief Helper variable template.
  66429. * @tparam Type The type to test.
  66430. */
  66431. template<typename Type>
  66432. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  66433. /**
  66434. * @brief Transcribes the constness of a type to another type.
  66435. * @tparam To The type to which to transcribe the constness.
  66436. * @tparam From The type from which to transcribe the constness.
  66437. */
  66438. template<typename To, typename From>
  66439. struct constness_as {
  66440. /*! @brief The type resulting from the transcription of the constness. */
  66441. using type = std::remove_const_t<To>;
  66442. };
  66443. /*! @copydoc constness_as */
  66444. template<typename To, typename From>
  66445. struct constness_as<To, const From> {
  66446. /*! @brief The type resulting from the transcription of the constness. */
  66447. using type = const To;
  66448. };
  66449. /**
  66450. * @brief Alias template to facilitate the transcription of the constness.
  66451. * @tparam To The type to which to transcribe the constness.
  66452. * @tparam From The type from which to transcribe the constness.
  66453. */
  66454. template<typename To, typename From>
  66455. using constness_as_t = typename constness_as<To, From>::type;
  66456. /**
  66457. * @brief Extracts the class of a non-static member object or function.
  66458. * @tparam Member A pointer to a non-static member object or function.
  66459. */
  66460. template<typename Member>
  66461. class member_class {
  66462. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  66463. template<typename Class, typename Ret, typename... Args>
  66464. static Class *clazz(Ret (Class::*)(Args...));
  66465. template<typename Class, typename Ret, typename... Args>
  66466. static Class *clazz(Ret (Class::*)(Args...) const);
  66467. template<typename Class, typename Type>
  66468. static Class *clazz(Type Class::*);
  66469. public:
  66470. /*! @brief The class of the given non-static member object or function. */
  66471. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  66472. };
  66473. /**
  66474. * @brief Helper type.
  66475. * @tparam Member A pointer to a non-static member object or function.
  66476. */
  66477. template<typename Member>
  66478. using member_class_t = typename member_class<Member>::type;
  66479. /**
  66480. * @brief Extracts the n-th argument of a _callable_ type.
  66481. * @tparam Index The index of the argument to extract.
  66482. * @tparam Candidate A valid _callable_ type.
  66483. */
  66484. template<std::size_t Index, typename Candidate>
  66485. class nth_argument {
  66486. template<typename Ret, typename... Args>
  66487. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  66488. template<typename Ret, typename Class, typename... Args>
  66489. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  66490. template<typename Ret, typename Class, typename... Args>
  66491. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  66492. template<typename Type, typename Class>
  66493. static constexpr type_list<Type> pick_up(Type Class ::*);
  66494. template<typename Type>
  66495. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  66496. public:
  66497. /*! @brief N-th argument of the _callable_ type. */
  66498. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  66499. };
  66500. /**
  66501. * @brief Helper type.
  66502. * @tparam Index The index of the argument to extract.
  66503. * @tparam Candidate A valid function, member function or data member type.
  66504. */
  66505. template<std::size_t Index, typename Candidate>
  66506. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  66507. } // namespace entt
  66508. template<typename... Type>
  66509. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  66510. template<std::size_t Index, typename... Type>
  66511. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  66512. template<auto... Value>
  66513. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  66514. template<std::size_t Index, auto... Value>
  66515. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  66516. #endif
  66517. // #include "fwd.hpp"
  66518. #ifndef ENTT_PROCESS_FWD_HPP
  66519. #define ENTT_PROCESS_FWD_HPP
  66520. #include <cstdint>
  66521. #include <memory>
  66522. namespace entt {
  66523. template<typename, typename = std::allocator<void>>
  66524. class basic_process;
  66525. /*! @brief Alias declaration for the most common use case. */
  66526. using process = basic_process<std::uint32_t>;
  66527. template<typename, typename = std::allocator<void>>
  66528. class basic_scheduler;
  66529. /*! @brief Alias declaration for the most common use case. */
  66530. using scheduler = basic_scheduler<std::uint32_t>;
  66531. } // namespace entt
  66532. #endif
  66533. namespace entt {
  66534. /*! @cond TURN_OFF_DOXYGEN */
  66535. namespace internal {
  66536. template<typename, typename, typename>
  66537. struct process_adaptor;
  66538. } // namespace internal
  66539. /*! @endcond */
  66540. /**
  66541. * @brief Base class for processes.
  66542. *
  66543. * Derived classes must specify what's the intended type for elapsed times.<br/>
  66544. * A process can implement the following member functions whether required:
  66545. *
  66546. * * @code{.cpp}
  66547. * void update(Delta, void *) override;
  66548. * @endcode
  66549. *
  66550. * It's invoked once per tick until a process is explicitly aborted or it
  66551. * terminates either with or without errors. Even though it's not mandatory to
  66552. * declare this member function, as a rule of thumb each process should at
  66553. * least define it to work properly. The `void *` parameter is an opaque
  66554. * pointer to user data (if any) forwarded directly to the process during an
  66555. * update.
  66556. *
  66557. * * @code{.cpp}
  66558. * void succeeded() override;
  66559. * @endcode
  66560. *
  66561. * It's invoked in case of success, immediately after an update and during the
  66562. * same tick.
  66563. *
  66564. * * @code{.cpp}
  66565. * void failed() override;
  66566. * @endcode
  66567. *
  66568. * It's invoked in case of errors, immediately after an update and during the
  66569. * same tick.
  66570. *
  66571. * * @code{.cpp}
  66572. * void aborted() override;
  66573. * @endcode
  66574. *
  66575. * It's invoked only if a process is explicitly aborted. There is no guarantee
  66576. * that it executes in the same tick, this depends solely on whether the
  66577. * process is aborted immediately or not.
  66578. *
  66579. * Derived classes can change the internal state of a process by invoking the
  66580. * `succeed` and `fail` member functions and even pause or unpause the process
  66581. * itself.
  66582. *
  66583. * @sa scheduler
  66584. *
  66585. * @tparam Delta Type to use to provide elapsed time.
  66586. * @tparam Allocator Type of allocator used to manage memory and elements.
  66587. */
  66588. template<typename Delta, typename Allocator>
  66589. class basic_process: public std::enable_shared_from_this<basic_process<Delta, Allocator>> {
  66590. enum class state : std::uint8_t {
  66591. idle = 0,
  66592. running,
  66593. paused,
  66594. succeeded,
  66595. failed,
  66596. aborted,
  66597. finished,
  66598. rejected
  66599. };
  66600. virtual void update(const Delta, void *) {
  66601. abort();
  66602. }
  66603. virtual void succeeded() {}
  66604. virtual void failed() {}
  66605. virtual void aborted() {}
  66606. public:
  66607. /*! @brief Allocator type. */
  66608. using allocator_type = Allocator;
  66609. /*! @brief Type used to provide elapsed time. */
  66610. using delta_type = Delta;
  66611. /*! @brief Handle type. */
  66612. using handle_type = std::shared_ptr<basic_process>;
  66613. /*! @brief Default constructor. */
  66614. basic_process()
  66615. : basic_process{allocator_type{}} {}
  66616. /**
  66617. * @brief Constructs a scheduler with a given allocator.
  66618. * @param allocator The allocator to use.
  66619. */
  66620. explicit basic_process(const allocator_type &allocator)
  66621. : next{nullptr, allocator},
  66622. current{state::idle} {}
  66623. /*! @brief Default copy constructor, deleted on purpose. */
  66624. basic_process(const basic_process &) = delete;
  66625. /*! @brief Default move constructor, deleted on purpose. */
  66626. basic_process(basic_process &&) = delete;
  66627. /*! @brief Default destructor. */
  66628. virtual ~basic_process() = default;
  66629. /**
  66630. * @brief Default copy assignment operator, deleted on purpose.
  66631. * @return This process scheduler.
  66632. */
  66633. basic_process &operator=(const basic_process &) = delete;
  66634. /**
  66635. * @brief Default move assignment operator, deleted on purpose.
  66636. * @return This process scheduler.
  66637. */
  66638. basic_process &operator=(basic_process &&) = delete;
  66639. /**
  66640. * @brief Returns the associated allocator.
  66641. * @return The associated allocator.
  66642. */
  66643. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  66644. return next.second();
  66645. }
  66646. /*! @brief Aborts a process if it's still alive, otherwise does nothing. */
  66647. void abort() {
  66648. if(alive()) {
  66649. current = state::aborted;
  66650. }
  66651. }
  66652. /**
  66653. * @brief Terminates a process with success if it's still alive, otherwise
  66654. * does nothing.
  66655. */
  66656. void succeed() noexcept {
  66657. if(alive()) {
  66658. current = state::succeeded;
  66659. }
  66660. }
  66661. /**
  66662. * @brief Terminates a process with errors if it's still alive, otherwise
  66663. * does nothing.
  66664. */
  66665. void fail() noexcept {
  66666. if(alive()) {
  66667. current = state::failed;
  66668. }
  66669. }
  66670. /*! @brief Stops a process if it's running, otherwise does nothing. */
  66671. void pause() noexcept {
  66672. if(alive()) {
  66673. current = state::paused;
  66674. }
  66675. }
  66676. /*! @brief Restarts a process if it's paused, otherwise does nothing. */
  66677. void unpause() noexcept {
  66678. if(alive()) {
  66679. current = state::running;
  66680. }
  66681. }
  66682. /**
  66683. * @brief Returns true if a process is either running or paused.
  66684. * @return True if the process is still alive, false otherwise.
  66685. */
  66686. [[nodiscard]] bool alive() const noexcept {
  66687. return current == state::running || current == state::paused;
  66688. }
  66689. /**
  66690. * @brief Returns true if a process is already terminated.
  66691. * @return True if the process is terminated, false otherwise.
  66692. */
  66693. [[nodiscard]] bool finished() const noexcept {
  66694. return current == state::finished;
  66695. }
  66696. /**
  66697. * @brief Returns true if a process is currently paused.
  66698. * @return True if the process is paused, false otherwise.
  66699. */
  66700. [[nodiscard]] bool paused() const noexcept {
  66701. return current == state::paused;
  66702. }
  66703. /**
  66704. * @brief Returns true if a process terminated with errors.
  66705. * @return True if the process terminated with errors, false otherwise.
  66706. */
  66707. [[nodiscard]] bool rejected() const noexcept {
  66708. return current == state::rejected;
  66709. }
  66710. /**
  66711. * @brief Assigns a child process to run in case of success.
  66712. * @tparam Type Type of child process to create.
  66713. * @tparam Args Types of arguments to use to initialize the child process.
  66714. * @param args Parameters to use to initialize the child process.
  66715. * @return A reference to the newly created child process.
  66716. */
  66717. template<typename Type, typename... Args>
  66718. basic_process &then(Args &&...args) {
  66719. const auto &allocator = next.second();
  66720. return *(next.first() = std::allocate_shared<Type>(allocator, allocator, std::forward<Args>(args)...));
  66721. }
  66722. /**
  66723. * @brief Assigns a child process to run in case of success.
  66724. * @tparam Func Type of child process to create.
  66725. * @param func Either a lambda or a functor to use as a child process.
  66726. * @return A reference to the newly created child process.
  66727. */
  66728. template<typename Func>
  66729. basic_process &then(Func func) {
  66730. const auto &allocator = next.second();
  66731. using process_type = internal::process_adaptor<delta_type, Func, allocator_type>;
  66732. return *(next.first() = std::allocate_shared<process_type>(allocator, allocator, std::move(func)));
  66733. }
  66734. /**
  66735. * @brief Returns the child process without releasing ownership, if any.
  66736. * @return The child process attached to the object, if any.
  66737. */
  66738. handle_type peek() {
  66739. return next.first();
  66740. }
  66741. /**
  66742. * @brief Updates a process and its internal state, if required.
  66743. * @param delta Elapsed time.
  66744. * @param data Optional data.
  66745. */
  66746. void tick(const Delta delta, void *data = nullptr) {
  66747. switch(current) {
  66748. case state::idle:
  66749. case state::running:
  66750. current = state::running;
  66751. update(delta, data);
  66752. break;
  66753. default:
  66754. // suppress warnings
  66755. break;
  66756. }
  66757. // if it's dead, it must be notified and removed immediately
  66758. switch(current) {
  66759. case state::succeeded:
  66760. succeeded();
  66761. current = state::finished;
  66762. break;
  66763. case state::failed:
  66764. failed();
  66765. current = state::rejected;
  66766. break;
  66767. case state::aborted:
  66768. aborted();
  66769. current = state::rejected;
  66770. break;
  66771. default:
  66772. // suppress warnings
  66773. break;
  66774. }
  66775. }
  66776. private:
  66777. compressed_pair<handle_type, allocator_type> next;
  66778. state current;
  66779. };
  66780. /*! @cond TURN_OFF_DOXYGEN */
  66781. namespace internal {
  66782. template<typename Delta, typename Func, typename Allocator>
  66783. struct process_adaptor: public basic_process<Delta, Allocator> {
  66784. using allocator_type = Allocator;
  66785. using base_type = basic_process<Delta, Allocator>;
  66786. using delta_type = typename base_type::delta_type;
  66787. process_adaptor(const allocator_type &allocator, Func proc)
  66788. : base_type{allocator},
  66789. func{std::move(proc)} {}
  66790. void update(const delta_type delta, void *data) override {
  66791. func(*this, delta, data);
  66792. }
  66793. private:
  66794. Func func;
  66795. };
  66796. } // namespace internal
  66797. /*! @endcond */
  66798. } // namespace entt
  66799. #endif
  66800. // #include "process/scheduler.hpp"
  66801. #ifndef ENTT_PROCESS_SCHEDULER_HPP
  66802. #define ENTT_PROCESS_SCHEDULER_HPP
  66803. #include <cstddef>
  66804. #include <memory>
  66805. #include <type_traits>
  66806. #include <utility>
  66807. #include <vector>
  66808. // #include "../config/config.h"
  66809. #ifndef ENTT_CONFIG_CONFIG_H
  66810. #define ENTT_CONFIG_CONFIG_H
  66811. // #include "version.h"
  66812. #ifndef ENTT_CONFIG_VERSION_H
  66813. #define ENTT_CONFIG_VERSION_H
  66814. // #include "macro.h"
  66815. #ifndef ENTT_CONFIG_MACRO_H
  66816. #define ENTT_CONFIG_MACRO_H
  66817. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  66818. #define ENTT_STR(arg) #arg
  66819. #define ENTT_XSTR(arg) ENTT_STR(arg)
  66820. // NOLINTEND(cppcoreguidelines-macro-usage)
  66821. #endif
  66822. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  66823. #define ENTT_VERSION_MAJOR 3
  66824. #define ENTT_VERSION_MINOR 16
  66825. #define ENTT_VERSION_PATCH 0
  66826. #define ENTT_VERSION \
  66827. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  66828. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  66829. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  66830. #endif
  66831. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  66832. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  66833. # define ENTT_CONSTEXPR
  66834. # define ENTT_THROW throw
  66835. # define ENTT_TRY try
  66836. # define ENTT_CATCH catch(...)
  66837. #else
  66838. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  66839. # define ENTT_THROW
  66840. # define ENTT_TRY if(true)
  66841. # define ENTT_CATCH if(false)
  66842. #endif
  66843. #if __has_include(<version>)
  66844. # include <version>
  66845. #
  66846. # if defined(__cpp_consteval)
  66847. # define ENTT_CONSTEVAL consteval
  66848. # endif
  66849. #endif
  66850. #ifndef ENTT_CONSTEVAL
  66851. # define ENTT_CONSTEVAL constexpr
  66852. #endif
  66853. #ifdef ENTT_USE_ATOMIC
  66854. # include <atomic>
  66855. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  66856. #else
  66857. # define ENTT_MAYBE_ATOMIC(Type) Type
  66858. #endif
  66859. #ifndef ENTT_ID_TYPE
  66860. # include <cstdint>
  66861. # define ENTT_ID_TYPE std::uint32_t
  66862. #else
  66863. # include <cstdint> // provides coverage for types in the std namespace
  66864. #endif
  66865. #ifndef ENTT_SPARSE_PAGE
  66866. # define ENTT_SPARSE_PAGE 4096
  66867. #endif
  66868. #ifndef ENTT_PACKED_PAGE
  66869. # define ENTT_PACKED_PAGE 1024
  66870. #endif
  66871. #ifdef ENTT_DISABLE_ASSERT
  66872. # undef ENTT_ASSERT
  66873. # define ENTT_ASSERT(condition, msg) (void(0))
  66874. #elif !defined ENTT_ASSERT
  66875. # include <cassert>
  66876. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  66877. #endif
  66878. #ifdef ENTT_DISABLE_ASSERT
  66879. # undef ENTT_ASSERT_CONSTEXPR
  66880. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  66881. #elif !defined ENTT_ASSERT_CONSTEXPR
  66882. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  66883. #endif
  66884. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  66885. #ifdef ENTT_NO_ETO
  66886. # define ENTT_ETO_TYPE(Type) void
  66887. #else
  66888. # define ENTT_ETO_TYPE(Type) Type
  66889. #endif
  66890. #ifdef ENTT_NO_MIXIN
  66891. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  66892. #else
  66893. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  66894. #endif
  66895. #ifdef ENTT_STANDARD_CPP
  66896. # define ENTT_NONSTD false
  66897. #else
  66898. # define ENTT_NONSTD true
  66899. # if defined __clang__ || defined __GNUC__
  66900. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  66901. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  66902. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  66903. # elif defined _MSC_VER
  66904. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  66905. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  66906. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  66907. # endif
  66908. #endif
  66909. #ifndef ENTT_EXPORT
  66910. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  66911. # define ENTT_EXPORT __declspec(dllexport)
  66912. # define ENTT_IMPORT __declspec(dllimport)
  66913. # define ENTT_HIDDEN
  66914. # elif defined __GNUC__ && __GNUC__ >= 4
  66915. # define ENTT_EXPORT __attribute__((visibility("default")))
  66916. # define ENTT_IMPORT __attribute__((visibility("default")))
  66917. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  66918. # else /* Unsupported compiler */
  66919. # define ENTT_EXPORT
  66920. # define ENTT_IMPORT
  66921. # define ENTT_HIDDEN
  66922. # endif
  66923. #endif
  66924. #ifndef ENTT_API
  66925. # if defined ENTT_API_EXPORT
  66926. # define ENTT_API ENTT_EXPORT
  66927. # elif defined ENTT_API_IMPORT
  66928. # define ENTT_API ENTT_IMPORT
  66929. # else /* No API */
  66930. # define ENTT_API
  66931. # endif
  66932. #endif
  66933. #if defined _MSC_VER
  66934. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  66935. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  66936. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  66937. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  66938. #endif
  66939. // NOLINTEND(cppcoreguidelines-macro-usage)
  66940. #endif
  66941. // #include "../core/compressed_pair.hpp"
  66942. // #include "fwd.hpp"
  66943. // #include "process.hpp"
  66944. #ifndef ENTT_PROCESS_PROCESS_HPP
  66945. #define ENTT_PROCESS_PROCESS_HPP
  66946. #include <cstdint>
  66947. #include <memory>
  66948. #include <type_traits>
  66949. #include <utility>
  66950. // #include "../core/compressed_pair.hpp"
  66951. // #include "../core/type_traits.hpp"
  66952. // #include "fwd.hpp"
  66953. namespace entt {
  66954. /*! @cond TURN_OFF_DOXYGEN */
  66955. namespace internal {
  66956. template<typename, typename, typename>
  66957. struct process_adaptor;
  66958. } // namespace internal
  66959. /*! @endcond */
  66960. /**
  66961. * @brief Base class for processes.
  66962. *
  66963. * Derived classes must specify what's the intended type for elapsed times.<br/>
  66964. * A process can implement the following member functions whether required:
  66965. *
  66966. * * @code{.cpp}
  66967. * void update(Delta, void *) override;
  66968. * @endcode
  66969. *
  66970. * It's invoked once per tick until a process is explicitly aborted or it
  66971. * terminates either with or without errors. Even though it's not mandatory to
  66972. * declare this member function, as a rule of thumb each process should at
  66973. * least define it to work properly. The `void *` parameter is an opaque
  66974. * pointer to user data (if any) forwarded directly to the process during an
  66975. * update.
  66976. *
  66977. * * @code{.cpp}
  66978. * void succeeded() override;
  66979. * @endcode
  66980. *
  66981. * It's invoked in case of success, immediately after an update and during the
  66982. * same tick.
  66983. *
  66984. * * @code{.cpp}
  66985. * void failed() override;
  66986. * @endcode
  66987. *
  66988. * It's invoked in case of errors, immediately after an update and during the
  66989. * same tick.
  66990. *
  66991. * * @code{.cpp}
  66992. * void aborted() override;
  66993. * @endcode
  66994. *
  66995. * It's invoked only if a process is explicitly aborted. There is no guarantee
  66996. * that it executes in the same tick, this depends solely on whether the
  66997. * process is aborted immediately or not.
  66998. *
  66999. * Derived classes can change the internal state of a process by invoking the
  67000. * `succeed` and `fail` member functions and even pause or unpause the process
  67001. * itself.
  67002. *
  67003. * @sa scheduler
  67004. *
  67005. * @tparam Delta Type to use to provide elapsed time.
  67006. * @tparam Allocator Type of allocator used to manage memory and elements.
  67007. */
  67008. template<typename Delta, typename Allocator>
  67009. class basic_process: public std::enable_shared_from_this<basic_process<Delta, Allocator>> {
  67010. enum class state : std::uint8_t {
  67011. idle = 0,
  67012. running,
  67013. paused,
  67014. succeeded,
  67015. failed,
  67016. aborted,
  67017. finished,
  67018. rejected
  67019. };
  67020. virtual void update(const Delta, void *) {
  67021. abort();
  67022. }
  67023. virtual void succeeded() {}
  67024. virtual void failed() {}
  67025. virtual void aborted() {}
  67026. public:
  67027. /*! @brief Allocator type. */
  67028. using allocator_type = Allocator;
  67029. /*! @brief Type used to provide elapsed time. */
  67030. using delta_type = Delta;
  67031. /*! @brief Handle type. */
  67032. using handle_type = std::shared_ptr<basic_process>;
  67033. /*! @brief Default constructor. */
  67034. basic_process()
  67035. : basic_process{allocator_type{}} {}
  67036. /**
  67037. * @brief Constructs a scheduler with a given allocator.
  67038. * @param allocator The allocator to use.
  67039. */
  67040. explicit basic_process(const allocator_type &allocator)
  67041. : next{nullptr, allocator},
  67042. current{state::idle} {}
  67043. /*! @brief Default copy constructor, deleted on purpose. */
  67044. basic_process(const basic_process &) = delete;
  67045. /*! @brief Default move constructor, deleted on purpose. */
  67046. basic_process(basic_process &&) = delete;
  67047. /*! @brief Default destructor. */
  67048. virtual ~basic_process() = default;
  67049. /**
  67050. * @brief Default copy assignment operator, deleted on purpose.
  67051. * @return This process scheduler.
  67052. */
  67053. basic_process &operator=(const basic_process &) = delete;
  67054. /**
  67055. * @brief Default move assignment operator, deleted on purpose.
  67056. * @return This process scheduler.
  67057. */
  67058. basic_process &operator=(basic_process &&) = delete;
  67059. /**
  67060. * @brief Returns the associated allocator.
  67061. * @return The associated allocator.
  67062. */
  67063. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  67064. return next.second();
  67065. }
  67066. /*! @brief Aborts a process if it's still alive, otherwise does nothing. */
  67067. void abort() {
  67068. if(alive()) {
  67069. current = state::aborted;
  67070. }
  67071. }
  67072. /**
  67073. * @brief Terminates a process with success if it's still alive, otherwise
  67074. * does nothing.
  67075. */
  67076. void succeed() noexcept {
  67077. if(alive()) {
  67078. current = state::succeeded;
  67079. }
  67080. }
  67081. /**
  67082. * @brief Terminates a process with errors if it's still alive, otherwise
  67083. * does nothing.
  67084. */
  67085. void fail() noexcept {
  67086. if(alive()) {
  67087. current = state::failed;
  67088. }
  67089. }
  67090. /*! @brief Stops a process if it's running, otherwise does nothing. */
  67091. void pause() noexcept {
  67092. if(alive()) {
  67093. current = state::paused;
  67094. }
  67095. }
  67096. /*! @brief Restarts a process if it's paused, otherwise does nothing. */
  67097. void unpause() noexcept {
  67098. if(alive()) {
  67099. current = state::running;
  67100. }
  67101. }
  67102. /**
  67103. * @brief Returns true if a process is either running or paused.
  67104. * @return True if the process is still alive, false otherwise.
  67105. */
  67106. [[nodiscard]] bool alive() const noexcept {
  67107. return current == state::running || current == state::paused;
  67108. }
  67109. /**
  67110. * @brief Returns true if a process is already terminated.
  67111. * @return True if the process is terminated, false otherwise.
  67112. */
  67113. [[nodiscard]] bool finished() const noexcept {
  67114. return current == state::finished;
  67115. }
  67116. /**
  67117. * @brief Returns true if a process is currently paused.
  67118. * @return True if the process is paused, false otherwise.
  67119. */
  67120. [[nodiscard]] bool paused() const noexcept {
  67121. return current == state::paused;
  67122. }
  67123. /**
  67124. * @brief Returns true if a process terminated with errors.
  67125. * @return True if the process terminated with errors, false otherwise.
  67126. */
  67127. [[nodiscard]] bool rejected() const noexcept {
  67128. return current == state::rejected;
  67129. }
  67130. /**
  67131. * @brief Assigns a child process to run in case of success.
  67132. * @tparam Type Type of child process to create.
  67133. * @tparam Args Types of arguments to use to initialize the child process.
  67134. * @param args Parameters to use to initialize the child process.
  67135. * @return A reference to the newly created child process.
  67136. */
  67137. template<typename Type, typename... Args>
  67138. basic_process &then(Args &&...args) {
  67139. const auto &allocator = next.second();
  67140. return *(next.first() = std::allocate_shared<Type>(allocator, allocator, std::forward<Args>(args)...));
  67141. }
  67142. /**
  67143. * @brief Assigns a child process to run in case of success.
  67144. * @tparam Func Type of child process to create.
  67145. * @param func Either a lambda or a functor to use as a child process.
  67146. * @return A reference to the newly created child process.
  67147. */
  67148. template<typename Func>
  67149. basic_process &then(Func func) {
  67150. const auto &allocator = next.second();
  67151. using process_type = internal::process_adaptor<delta_type, Func, allocator_type>;
  67152. return *(next.first() = std::allocate_shared<process_type>(allocator, allocator, std::move(func)));
  67153. }
  67154. /**
  67155. * @brief Returns the child process without releasing ownership, if any.
  67156. * @return The child process attached to the object, if any.
  67157. */
  67158. handle_type peek() {
  67159. return next.first();
  67160. }
  67161. /**
  67162. * @brief Updates a process and its internal state, if required.
  67163. * @param delta Elapsed time.
  67164. * @param data Optional data.
  67165. */
  67166. void tick(const Delta delta, void *data = nullptr) {
  67167. switch(current) {
  67168. case state::idle:
  67169. case state::running:
  67170. current = state::running;
  67171. update(delta, data);
  67172. break;
  67173. default:
  67174. // suppress warnings
  67175. break;
  67176. }
  67177. // if it's dead, it must be notified and removed immediately
  67178. switch(current) {
  67179. case state::succeeded:
  67180. succeeded();
  67181. current = state::finished;
  67182. break;
  67183. case state::failed:
  67184. failed();
  67185. current = state::rejected;
  67186. break;
  67187. case state::aborted:
  67188. aborted();
  67189. current = state::rejected;
  67190. break;
  67191. default:
  67192. // suppress warnings
  67193. break;
  67194. }
  67195. }
  67196. private:
  67197. compressed_pair<handle_type, allocator_type> next;
  67198. state current;
  67199. };
  67200. /*! @cond TURN_OFF_DOXYGEN */
  67201. namespace internal {
  67202. template<typename Delta, typename Func, typename Allocator>
  67203. struct process_adaptor: public basic_process<Delta, Allocator> {
  67204. using allocator_type = Allocator;
  67205. using base_type = basic_process<Delta, Allocator>;
  67206. using delta_type = typename base_type::delta_type;
  67207. process_adaptor(const allocator_type &allocator, Func proc)
  67208. : base_type{allocator},
  67209. func{std::move(proc)} {}
  67210. void update(const delta_type delta, void *data) override {
  67211. func(*this, delta, data);
  67212. }
  67213. private:
  67214. Func func;
  67215. };
  67216. } // namespace internal
  67217. /*! @endcond */
  67218. } // namespace entt
  67219. #endif
  67220. namespace entt {
  67221. /**
  67222. * @brief Cooperative scheduler for processes.
  67223. *
  67224. * A cooperative scheduler runs processes and helps managing their life cycles.
  67225. *
  67226. * Each process is invoked once per tick. If a process terminates, it's
  67227. * removed automatically from the scheduler and it's never invoked again.<br/>
  67228. * A process can also have a child. In this case, the process is replaced with
  67229. * its child when it terminates if it returns with success. In case of errors,
  67230. * both the process and its child are discarded.
  67231. *
  67232. * In order to invoke all scheduled processes, call the `update` member function
  67233. * passing it the elapsed time to forward to the tasks.
  67234. *
  67235. * @sa process
  67236. *
  67237. * @tparam Delta Type to use to provide elapsed time.
  67238. * @tparam Allocator Type of allocator used to manage memory and elements.
  67239. */
  67240. template<typename Delta, typename Allocator>
  67241. class basic_scheduler {
  67242. using base_type = basic_process<Delta, Allocator>;
  67243. using alloc_traits = std::allocator_traits<Allocator>;
  67244. using container_allocator = typename alloc_traits::template rebind_alloc<std::shared_ptr<base_type>>;
  67245. using container_type = std::vector<std::shared_ptr<base_type>, container_allocator>;
  67246. public:
  67247. /*! @brief Process type. */
  67248. using type = base_type;
  67249. /*! @brief Allocator type. */
  67250. using allocator_type = Allocator;
  67251. /*! @brief Unsigned integer type. */
  67252. using size_type = std::size_t;
  67253. /*! @brief Unsigned integer type. */
  67254. using delta_type = Delta;
  67255. /*! @brief Default constructor. */
  67256. basic_scheduler()
  67257. : basic_scheduler{allocator_type{}} {}
  67258. /**
  67259. * @brief Constructs a scheduler with a given allocator.
  67260. * @param allocator The allocator to use.
  67261. */
  67262. explicit basic_scheduler(const allocator_type &allocator)
  67263. : handlers{allocator, allocator} {}
  67264. /*! @brief Default copy constructor, deleted on purpose. */
  67265. basic_scheduler(const basic_scheduler &) = delete;
  67266. /**
  67267. * @brief Move constructor.
  67268. * @param other The instance to move from.
  67269. */
  67270. basic_scheduler(basic_scheduler &&other) noexcept
  67271. : handlers{std::move(other.handlers)} {}
  67272. /**
  67273. * @brief Allocator-extended move constructor.
  67274. * @param other The instance to move from.
  67275. * @param allocator The allocator to use.
  67276. */
  67277. basic_scheduler(basic_scheduler &&other, const allocator_type &allocator)
  67278. : handlers{container_type{std::move(other.handlers.first()), allocator}, allocator} {
  67279. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a scheduler is not allowed");
  67280. }
  67281. /*! @brief Default destructor. */
  67282. ~basic_scheduler() = default;
  67283. /**
  67284. * @brief Default copy assignment operator, deleted on purpose.
  67285. * @return This process scheduler.
  67286. */
  67287. basic_scheduler &operator=(const basic_scheduler &) = delete;
  67288. /**
  67289. * @brief Move assignment operator.
  67290. * @param other The instance to move from.
  67291. * @return This process scheduler.
  67292. */
  67293. basic_scheduler &operator=(basic_scheduler &&other) noexcept {
  67294. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a scheduler is not allowed");
  67295. swap(other);
  67296. return *this;
  67297. }
  67298. /**
  67299. * @brief Exchanges the contents with those of a given scheduler.
  67300. * @param other Scheduler to exchange the content with.
  67301. */
  67302. void swap(basic_scheduler &other) noexcept {
  67303. using std::swap;
  67304. swap(handlers, other.handlers);
  67305. }
  67306. /**
  67307. * @brief Returns the associated allocator.
  67308. * @return The associated allocator.
  67309. */
  67310. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  67311. return handlers.second();
  67312. }
  67313. /**
  67314. * @brief Number of processes currently scheduled.
  67315. * @return Number of processes currently scheduled.
  67316. */
  67317. [[nodiscard]] size_type size() const noexcept {
  67318. return handlers.first().size();
  67319. }
  67320. /**
  67321. * @brief Returns true if at least a process is currently scheduled.
  67322. * @return True if there are scheduled processes, false otherwise.
  67323. */
  67324. [[nodiscard]] bool empty() const noexcept {
  67325. return handlers.first().empty();
  67326. }
  67327. /**
  67328. * @brief Discards all scheduled processes.
  67329. *
  67330. * Processes aren't aborted. They are discarded along with their children
  67331. * and never executed again.
  67332. */
  67333. void clear() {
  67334. handlers.first().clear();
  67335. }
  67336. /**
  67337. * @brief Schedules a process for the next tick.
  67338. * @tparam Type Type of process to create.
  67339. * @tparam Args Types of arguments to use to initialize the process.
  67340. * @param args Parameters to use to initialize the process.
  67341. * @return A reference to the newly created process.
  67342. */
  67343. template<typename Type, typename... Args>
  67344. type &attach(Args &&...args) {
  67345. const auto &allocator = handlers.second();
  67346. return *handlers.first().emplace_back(std::allocate_shared<Type>(allocator, allocator, std::forward<Args>(args)...));
  67347. }
  67348. /**
  67349. * @brief Schedules a process for the next tick.
  67350. * @tparam Func Type of process to create.
  67351. * @param func Either a lambda or a functor to use as a process.
  67352. * @return A reference to the newly created process.
  67353. */
  67354. template<typename Func>
  67355. type &attach(Func func) {
  67356. const auto &allocator = handlers.second();
  67357. using process_type = internal::process_adaptor<delta_type, Func, allocator_type>;
  67358. return *handlers.first().emplace_back(std::allocate_shared<process_type>(allocator, allocator, std::move(func)));
  67359. }
  67360. /**
  67361. * @brief Updates all scheduled processes.
  67362. *
  67363. * All scheduled processes are executed in no specific order.<br/>
  67364. * If a process terminates with success, it's replaced with its child, if
  67365. * any. Otherwise, if a process terminates with an error, it's removed along
  67366. * with its child.
  67367. *
  67368. * @param delta Elapsed time.
  67369. * @param data Optional data.
  67370. */
  67371. void update(const delta_type delta, void *data = nullptr) {
  67372. for(auto next = handlers.first().size(); next; --next) {
  67373. const auto pos = next - 1u;
  67374. handlers.first()[pos]->tick(delta, data);
  67375. // updating might spawn/reallocate, cannot hold refs until here
  67376. auto &elem = handlers.first()[pos];
  67377. if(elem->finished()) {
  67378. elem = elem->peek();
  67379. }
  67380. if(!elem || elem->rejected()) {
  67381. elem = std::move(handlers.first().back());
  67382. handlers.first().pop_back();
  67383. }
  67384. }
  67385. }
  67386. /**
  67387. * @brief Aborts all scheduled processes.
  67388. *
  67389. * Unless an immediate operation is requested, the abort is scheduled for
  67390. * the next tick. Processes won't be executed anymore in any case.<br/>
  67391. * Once a process is fully aborted and thus finished, it's discarded along
  67392. * with its child, if any.
  67393. *
  67394. * @param immediate Requests an immediate operation.
  67395. */
  67396. void abort(const bool immediate = false) {
  67397. for(auto &&curr: handlers.first()) {
  67398. curr->abort();
  67399. if(immediate) {
  67400. curr->tick({});
  67401. }
  67402. }
  67403. }
  67404. private:
  67405. compressed_pair<container_type, allocator_type> handlers;
  67406. };
  67407. } // namespace entt
  67408. #endif
  67409. // #include "resource/cache.hpp"
  67410. #ifndef ENTT_RESOURCE_RESOURCE_CACHE_HPP
  67411. #define ENTT_RESOURCE_RESOURCE_CACHE_HPP
  67412. #include <cstddef>
  67413. #include <functional>
  67414. #include <iterator>
  67415. #include <memory>
  67416. #include <tuple>
  67417. #include <type_traits>
  67418. #include <utility>
  67419. // #include "../container/dense_map.hpp"
  67420. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  67421. #define ENTT_CONTAINER_DENSE_MAP_HPP
  67422. #include <cmath>
  67423. #include <cstddef>
  67424. #include <functional>
  67425. #include <iterator>
  67426. #include <limits>
  67427. #include <memory>
  67428. #include <tuple>
  67429. #include <type_traits>
  67430. #include <utility>
  67431. #include <vector>
  67432. // #include "../config/config.h"
  67433. #ifndef ENTT_CONFIG_CONFIG_H
  67434. #define ENTT_CONFIG_CONFIG_H
  67435. // #include "version.h"
  67436. #ifndef ENTT_CONFIG_VERSION_H
  67437. #define ENTT_CONFIG_VERSION_H
  67438. // #include "macro.h"
  67439. #ifndef ENTT_CONFIG_MACRO_H
  67440. #define ENTT_CONFIG_MACRO_H
  67441. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  67442. #define ENTT_STR(arg) #arg
  67443. #define ENTT_XSTR(arg) ENTT_STR(arg)
  67444. // NOLINTEND(cppcoreguidelines-macro-usage)
  67445. #endif
  67446. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  67447. #define ENTT_VERSION_MAJOR 3
  67448. #define ENTT_VERSION_MINOR 16
  67449. #define ENTT_VERSION_PATCH 0
  67450. #define ENTT_VERSION \
  67451. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  67452. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  67453. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  67454. #endif
  67455. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  67456. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  67457. # define ENTT_CONSTEXPR
  67458. # define ENTT_THROW throw
  67459. # define ENTT_TRY try
  67460. # define ENTT_CATCH catch(...)
  67461. #else
  67462. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  67463. # define ENTT_THROW
  67464. # define ENTT_TRY if(true)
  67465. # define ENTT_CATCH if(false)
  67466. #endif
  67467. #if __has_include(<version>)
  67468. # include <version>
  67469. #
  67470. # if defined(__cpp_consteval)
  67471. # define ENTT_CONSTEVAL consteval
  67472. # endif
  67473. #endif
  67474. #ifndef ENTT_CONSTEVAL
  67475. # define ENTT_CONSTEVAL constexpr
  67476. #endif
  67477. #ifdef ENTT_USE_ATOMIC
  67478. # include <atomic>
  67479. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  67480. #else
  67481. # define ENTT_MAYBE_ATOMIC(Type) Type
  67482. #endif
  67483. #ifndef ENTT_ID_TYPE
  67484. # include <cstdint>
  67485. # define ENTT_ID_TYPE std::uint32_t
  67486. #else
  67487. # include <cstdint> // provides coverage for types in the std namespace
  67488. #endif
  67489. #ifndef ENTT_SPARSE_PAGE
  67490. # define ENTT_SPARSE_PAGE 4096
  67491. #endif
  67492. #ifndef ENTT_PACKED_PAGE
  67493. # define ENTT_PACKED_PAGE 1024
  67494. #endif
  67495. #ifdef ENTT_DISABLE_ASSERT
  67496. # undef ENTT_ASSERT
  67497. # define ENTT_ASSERT(condition, msg) (void(0))
  67498. #elif !defined ENTT_ASSERT
  67499. # include <cassert>
  67500. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  67501. #endif
  67502. #ifdef ENTT_DISABLE_ASSERT
  67503. # undef ENTT_ASSERT_CONSTEXPR
  67504. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  67505. #elif !defined ENTT_ASSERT_CONSTEXPR
  67506. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  67507. #endif
  67508. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  67509. #ifdef ENTT_NO_ETO
  67510. # define ENTT_ETO_TYPE(Type) void
  67511. #else
  67512. # define ENTT_ETO_TYPE(Type) Type
  67513. #endif
  67514. #ifdef ENTT_NO_MIXIN
  67515. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  67516. #else
  67517. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  67518. #endif
  67519. #ifdef ENTT_STANDARD_CPP
  67520. # define ENTT_NONSTD false
  67521. #else
  67522. # define ENTT_NONSTD true
  67523. # if defined __clang__ || defined __GNUC__
  67524. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  67525. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  67526. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  67527. # elif defined _MSC_VER
  67528. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  67529. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  67530. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  67531. # endif
  67532. #endif
  67533. #ifndef ENTT_EXPORT
  67534. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  67535. # define ENTT_EXPORT __declspec(dllexport)
  67536. # define ENTT_IMPORT __declspec(dllimport)
  67537. # define ENTT_HIDDEN
  67538. # elif defined __GNUC__ && __GNUC__ >= 4
  67539. # define ENTT_EXPORT __attribute__((visibility("default")))
  67540. # define ENTT_IMPORT __attribute__((visibility("default")))
  67541. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  67542. # else /* Unsupported compiler */
  67543. # define ENTT_EXPORT
  67544. # define ENTT_IMPORT
  67545. # define ENTT_HIDDEN
  67546. # endif
  67547. #endif
  67548. #ifndef ENTT_API
  67549. # if defined ENTT_API_EXPORT
  67550. # define ENTT_API ENTT_EXPORT
  67551. # elif defined ENTT_API_IMPORT
  67552. # define ENTT_API ENTT_IMPORT
  67553. # else /* No API */
  67554. # define ENTT_API
  67555. # endif
  67556. #endif
  67557. #if defined _MSC_VER
  67558. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  67559. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  67560. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  67561. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  67562. #endif
  67563. // NOLINTEND(cppcoreguidelines-macro-usage)
  67564. #endif
  67565. // #include "../core/bit.hpp"
  67566. #ifndef ENTT_CORE_BIT_HPP
  67567. #define ENTT_CORE_BIT_HPP
  67568. #include <cstddef>
  67569. #include <limits>
  67570. #include <type_traits>
  67571. // #include "../config/config.h"
  67572. #ifndef ENTT_CONFIG_CONFIG_H
  67573. #define ENTT_CONFIG_CONFIG_H
  67574. // #include "version.h"
  67575. #ifndef ENTT_CONFIG_VERSION_H
  67576. #define ENTT_CONFIG_VERSION_H
  67577. // #include "macro.h"
  67578. #ifndef ENTT_CONFIG_MACRO_H
  67579. #define ENTT_CONFIG_MACRO_H
  67580. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  67581. #define ENTT_STR(arg) #arg
  67582. #define ENTT_XSTR(arg) ENTT_STR(arg)
  67583. // NOLINTEND(cppcoreguidelines-macro-usage)
  67584. #endif
  67585. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  67586. #define ENTT_VERSION_MAJOR 3
  67587. #define ENTT_VERSION_MINOR 16
  67588. #define ENTT_VERSION_PATCH 0
  67589. #define ENTT_VERSION \
  67590. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  67591. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  67592. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  67593. #endif
  67594. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  67595. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  67596. # define ENTT_CONSTEXPR
  67597. # define ENTT_THROW throw
  67598. # define ENTT_TRY try
  67599. # define ENTT_CATCH catch(...)
  67600. #else
  67601. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  67602. # define ENTT_THROW
  67603. # define ENTT_TRY if(true)
  67604. # define ENTT_CATCH if(false)
  67605. #endif
  67606. #if __has_include(<version>)
  67607. # include <version>
  67608. #
  67609. # if defined(__cpp_consteval)
  67610. # define ENTT_CONSTEVAL consteval
  67611. # endif
  67612. #endif
  67613. #ifndef ENTT_CONSTEVAL
  67614. # define ENTT_CONSTEVAL constexpr
  67615. #endif
  67616. #ifdef ENTT_USE_ATOMIC
  67617. # include <atomic>
  67618. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  67619. #else
  67620. # define ENTT_MAYBE_ATOMIC(Type) Type
  67621. #endif
  67622. #ifndef ENTT_ID_TYPE
  67623. # include <cstdint>
  67624. # define ENTT_ID_TYPE std::uint32_t
  67625. #else
  67626. # include <cstdint> // provides coverage for types in the std namespace
  67627. #endif
  67628. #ifndef ENTT_SPARSE_PAGE
  67629. # define ENTT_SPARSE_PAGE 4096
  67630. #endif
  67631. #ifndef ENTT_PACKED_PAGE
  67632. # define ENTT_PACKED_PAGE 1024
  67633. #endif
  67634. #ifdef ENTT_DISABLE_ASSERT
  67635. # undef ENTT_ASSERT
  67636. # define ENTT_ASSERT(condition, msg) (void(0))
  67637. #elif !defined ENTT_ASSERT
  67638. # include <cassert>
  67639. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  67640. #endif
  67641. #ifdef ENTT_DISABLE_ASSERT
  67642. # undef ENTT_ASSERT_CONSTEXPR
  67643. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  67644. #elif !defined ENTT_ASSERT_CONSTEXPR
  67645. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  67646. #endif
  67647. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  67648. #ifdef ENTT_NO_ETO
  67649. # define ENTT_ETO_TYPE(Type) void
  67650. #else
  67651. # define ENTT_ETO_TYPE(Type) Type
  67652. #endif
  67653. #ifdef ENTT_NO_MIXIN
  67654. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  67655. #else
  67656. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  67657. #endif
  67658. #ifdef ENTT_STANDARD_CPP
  67659. # define ENTT_NONSTD false
  67660. #else
  67661. # define ENTT_NONSTD true
  67662. # if defined __clang__ || defined __GNUC__
  67663. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  67664. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  67665. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  67666. # elif defined _MSC_VER
  67667. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  67668. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  67669. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  67670. # endif
  67671. #endif
  67672. #ifndef ENTT_EXPORT
  67673. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  67674. # define ENTT_EXPORT __declspec(dllexport)
  67675. # define ENTT_IMPORT __declspec(dllimport)
  67676. # define ENTT_HIDDEN
  67677. # elif defined __GNUC__ && __GNUC__ >= 4
  67678. # define ENTT_EXPORT __attribute__((visibility("default")))
  67679. # define ENTT_IMPORT __attribute__((visibility("default")))
  67680. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  67681. # else /* Unsupported compiler */
  67682. # define ENTT_EXPORT
  67683. # define ENTT_IMPORT
  67684. # define ENTT_HIDDEN
  67685. # endif
  67686. #endif
  67687. #ifndef ENTT_API
  67688. # if defined ENTT_API_EXPORT
  67689. # define ENTT_API ENTT_EXPORT
  67690. # elif defined ENTT_API_IMPORT
  67691. # define ENTT_API ENTT_IMPORT
  67692. # else /* No API */
  67693. # define ENTT_API
  67694. # endif
  67695. #endif
  67696. #if defined _MSC_VER
  67697. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  67698. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  67699. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  67700. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  67701. #endif
  67702. // NOLINTEND(cppcoreguidelines-macro-usage)
  67703. #endif
  67704. namespace entt {
  67705. /**
  67706. * @brief Returns the number of set bits in a value (waiting for C++20 and
  67707. * `std::popcount`).
  67708. * @tparam Type Unsigned integer type.
  67709. * @param value A value of unsigned integer type.
  67710. * @return The number of set bits in the value.
  67711. */
  67712. template<typename Type>
  67713. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  67714. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  67715. }
  67716. /**
  67717. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  67718. * `std::has_single_bit`).
  67719. * @tparam Type Unsigned integer type.
  67720. * @param value A value of unsigned integer type.
  67721. * @return True if the value is a power of two, false otherwise.
  67722. */
  67723. template<typename Type>
  67724. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  67725. return value && ((value & (value - 1)) == 0);
  67726. }
  67727. /**
  67728. * @brief Computes the smallest power of two greater than or equal to a value
  67729. * (waiting for C++20 and `std::bit_ceil`).
  67730. * @tparam Type Unsigned integer type.
  67731. * @param value A value of unsigned integer type.
  67732. * @return The smallest power of two greater than or equal to the given value.
  67733. */
  67734. template<typename Type>
  67735. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  67736. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  67737. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  67738. Type curr = value - (value != 0u);
  67739. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  67740. curr |= (curr >> next);
  67741. }
  67742. return ++curr;
  67743. }
  67744. /**
  67745. * @brief Fast module utility function (powers of two only).
  67746. * @tparam Type Unsigned integer type.
  67747. * @param value A value of unsigned integer type.
  67748. * @param mod _Modulus_, it must be a power of two.
  67749. * @return The common remainder.
  67750. */
  67751. template<typename Type>
  67752. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  67753. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  67754. return static_cast<Type>(value & (mod - 1u));
  67755. }
  67756. } // namespace entt
  67757. #endif
  67758. // #include "../core/compressed_pair.hpp"
  67759. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  67760. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  67761. #include <cstddef>
  67762. #include <tuple>
  67763. #include <type_traits>
  67764. #include <utility>
  67765. // #include "fwd.hpp"
  67766. #ifndef ENTT_CORE_FWD_HPP
  67767. #define ENTT_CORE_FWD_HPP
  67768. #include <cstddef>
  67769. #include <cstdint>
  67770. // #include "../config/config.h"
  67771. namespace entt {
  67772. /*! @brief Possible modes of an any object. */
  67773. enum class any_policy : std::uint8_t {
  67774. /*! @brief Default mode, no element available. */
  67775. empty,
  67776. /*! @brief Owning mode, dynamically allocated element. */
  67777. dynamic,
  67778. /*! @brief Owning mode, embedded element. */
  67779. embedded,
  67780. /*! @brief Aliasing mode, non-const reference. */
  67781. ref,
  67782. /*! @brief Const aliasing mode, const reference. */
  67783. cref
  67784. };
  67785. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  67786. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  67787. class basic_any;
  67788. /*! @brief Alias declaration for type identifiers. */
  67789. using id_type = ENTT_ID_TYPE;
  67790. /*! @brief Alias declaration for the most common use case. */
  67791. using any = basic_any<>;
  67792. template<typename, typename>
  67793. class compressed_pair;
  67794. template<typename>
  67795. class basic_hashed_string;
  67796. /*! @brief Aliases for common character types. */
  67797. using hashed_string = basic_hashed_string<char>;
  67798. /*! @brief Aliases for common character types. */
  67799. using hashed_wstring = basic_hashed_string<wchar_t>;
  67800. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  67801. struct type_info;
  67802. } // namespace entt
  67803. #endif
  67804. // #include "type_traits.hpp"
  67805. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  67806. #define ENTT_CORE_TYPE_TRAITS_HPP
  67807. #include <cstddef>
  67808. #include <iterator>
  67809. #include <tuple>
  67810. #include <type_traits>
  67811. #include <utility>
  67812. // #include "../config/config.h"
  67813. // #include "fwd.hpp"
  67814. namespace entt {
  67815. /**
  67816. * @brief Utility class to disambiguate overloaded functions.
  67817. * @tparam N Number of choices available.
  67818. */
  67819. template<std::size_t N>
  67820. struct choice_t
  67821. // unfortunately, doxygen cannot parse such a construct
  67822. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  67823. {};
  67824. /*! @copybrief choice_t */
  67825. template<>
  67826. struct choice_t<0> {};
  67827. /**
  67828. * @brief Variable template for the choice trick.
  67829. * @tparam N Number of choices available.
  67830. */
  67831. template<std::size_t N>
  67832. inline constexpr choice_t<N> choice{};
  67833. /**
  67834. * @brief Identity type trait.
  67835. *
  67836. * Useful to establish non-deduced contexts in template argument deduction
  67837. * (waiting for C++20) or to provide types through function arguments.
  67838. *
  67839. * @tparam Type A type.
  67840. */
  67841. template<typename Type>
  67842. struct type_identity {
  67843. /*! @brief Identity type. */
  67844. using type = Type;
  67845. };
  67846. /**
  67847. * @brief Helper type.
  67848. * @tparam Type A type.
  67849. */
  67850. template<typename Type>
  67851. using type_identity_t = typename type_identity<Type>::type;
  67852. /**
  67853. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  67854. * @tparam Type The type of which to return the size.
  67855. */
  67856. template<typename Type, typename = void>
  67857. struct size_of: std::integral_constant<std::size_t, 0u> {};
  67858. /*! @copydoc size_of */
  67859. template<typename Type>
  67860. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  67861. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  67862. : std::integral_constant<std::size_t, sizeof(Type)> {};
  67863. /**
  67864. * @brief Helper variable template.
  67865. * @tparam Type The type of which to return the size.
  67866. */
  67867. template<typename Type>
  67868. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  67869. /**
  67870. * @brief Using declaration to be used to _repeat_ the same type a number of
  67871. * times equal to the size of a given parameter pack.
  67872. * @tparam Type A type to repeat.
  67873. */
  67874. template<typename Type, typename>
  67875. using unpack_as_type = Type;
  67876. /**
  67877. * @brief Helper variable template to be used to _repeat_ the same value a
  67878. * number of times equal to the size of a given parameter pack.
  67879. * @tparam Value A value to repeat.
  67880. */
  67881. template<auto Value, typename>
  67882. inline constexpr auto unpack_as_value = Value;
  67883. /**
  67884. * @brief Wraps a static constant.
  67885. * @tparam Value A static constant.
  67886. */
  67887. template<auto Value>
  67888. using integral_constant = std::integral_constant<decltype(Value), Value>;
  67889. /**
  67890. * @brief Alias template to facilitate the creation of named values.
  67891. * @tparam Value A constant value at least convertible to `id_type`.
  67892. */
  67893. template<id_type Value>
  67894. using tag = integral_constant<Value>;
  67895. /**
  67896. * @brief A class to use to push around lists of types, nothing more.
  67897. * @tparam Type Types provided by the type list.
  67898. */
  67899. template<typename... Type>
  67900. struct type_list {
  67901. /*! @brief Type list type. */
  67902. using type = type_list;
  67903. /*! @brief Compile-time number of elements in the type list. */
  67904. static constexpr auto size = sizeof...(Type);
  67905. };
  67906. /*! @brief Primary template isn't defined on purpose. */
  67907. template<std::size_t, typename>
  67908. struct type_list_element;
  67909. /**
  67910. * @brief Provides compile-time indexed access to the types of a type list.
  67911. * @tparam Index Index of the type to return.
  67912. * @tparam First First type provided by the type list.
  67913. * @tparam Other Other types provided by the type list.
  67914. */
  67915. template<std::size_t Index, typename First, typename... Other>
  67916. struct type_list_element<Index, type_list<First, Other...>>
  67917. : type_list_element<Index - 1u, type_list<Other...>> {};
  67918. /**
  67919. * @brief Provides compile-time indexed access to the types of a type list.
  67920. * @tparam First First type provided by the type list.
  67921. * @tparam Other Other types provided by the type list.
  67922. */
  67923. template<typename First, typename... Other>
  67924. struct type_list_element<0u, type_list<First, Other...>> {
  67925. /*! @brief Searched type. */
  67926. using type = First;
  67927. };
  67928. /**
  67929. * @brief Helper type.
  67930. * @tparam Index Index of the type to return.
  67931. * @tparam List Type list to search into.
  67932. */
  67933. template<std::size_t Index, typename List>
  67934. using type_list_element_t = typename type_list_element<Index, List>::type;
  67935. /*! @brief Primary template isn't defined on purpose. */
  67936. template<typename, typename>
  67937. struct type_list_index;
  67938. /**
  67939. * @brief Provides compile-time type access to the types of a type list.
  67940. * @tparam Type Type to look for and for which to return the index.
  67941. * @tparam First First type provided by the type list.
  67942. * @tparam Other Other types provided by the type list.
  67943. */
  67944. template<typename Type, typename First, typename... Other>
  67945. struct type_list_index<Type, type_list<First, Other...>> {
  67946. /*! @brief Unsigned integer type. */
  67947. using value_type = std::size_t;
  67948. /*! @brief Compile-time position of the given type in the sublist. */
  67949. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  67950. };
  67951. /**
  67952. * @brief Provides compile-time type access to the types of a type list.
  67953. * @tparam Type Type to look for and for which to return the index.
  67954. * @tparam Other Other types provided by the type list.
  67955. */
  67956. template<typename Type, typename... Other>
  67957. struct type_list_index<Type, type_list<Type, Other...>> {
  67958. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  67959. /*! @brief Unsigned integer type. */
  67960. using value_type = std::size_t;
  67961. /*! @brief Compile-time position of the given type in the sublist. */
  67962. static constexpr value_type value = 0u;
  67963. };
  67964. /**
  67965. * @brief Provides compile-time type access to the types of a type list.
  67966. * @tparam Type Type to look for and for which to return the index.
  67967. */
  67968. template<typename Type>
  67969. struct type_list_index<Type, type_list<>> {
  67970. /*! @brief Unsigned integer type. */
  67971. using value_type = std::size_t;
  67972. /*! @brief Compile-time position of the given type in the sublist. */
  67973. static constexpr value_type value = 0u;
  67974. };
  67975. /**
  67976. * @brief Helper variable template.
  67977. * @tparam List Type list.
  67978. * @tparam Type Type to look for and for which to return the index.
  67979. */
  67980. template<typename Type, typename List>
  67981. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  67982. /**
  67983. * @brief Concatenates multiple type lists.
  67984. * @tparam Type Types provided by the first type list.
  67985. * @tparam Other Types provided by the second type list.
  67986. * @return A type list composed by the types of both the type lists.
  67987. */
  67988. template<typename... Type, typename... Other>
  67989. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  67990. return {};
  67991. }
  67992. /*! @brief Primary template isn't defined on purpose. */
  67993. template<typename...>
  67994. struct type_list_cat;
  67995. /*! @brief Concatenates multiple type lists. */
  67996. template<>
  67997. struct type_list_cat<> {
  67998. /*! @brief A type list composed by the types of all the type lists. */
  67999. using type = type_list<>;
  68000. };
  68001. /**
  68002. * @brief Concatenates multiple type lists.
  68003. * @tparam Type Types provided by the first type list.
  68004. * @tparam Other Types provided by the second type list.
  68005. * @tparam List Other type lists, if any.
  68006. */
  68007. template<typename... Type, typename... Other, typename... List>
  68008. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  68009. /*! @brief A type list composed by the types of all the type lists. */
  68010. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  68011. };
  68012. /**
  68013. * @brief Concatenates multiple type lists.
  68014. * @tparam Type Types provided by the type list.
  68015. */
  68016. template<typename... Type>
  68017. struct type_list_cat<type_list<Type...>> {
  68018. /*! @brief A type list composed by the types of all the type lists. */
  68019. using type = type_list<Type...>;
  68020. };
  68021. /**
  68022. * @brief Helper type.
  68023. * @tparam List Type lists to concatenate.
  68024. */
  68025. template<typename... List>
  68026. using type_list_cat_t = typename type_list_cat<List...>::type;
  68027. /*! @cond TURN_OFF_DOXYGEN */
  68028. namespace internal {
  68029. template<typename...>
  68030. struct type_list_unique;
  68031. template<typename First, typename... Other, typename... Type>
  68032. struct type_list_unique<type_list<First, Other...>, Type...>
  68033. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  68034. template<typename... Type>
  68035. struct type_list_unique<type_list<>, Type...> {
  68036. using type = type_list<Type...>;
  68037. };
  68038. } // namespace internal
  68039. /*! @endcond */
  68040. /**
  68041. * @brief Removes duplicates types from a type list.
  68042. * @tparam List Type list.
  68043. */
  68044. template<typename List>
  68045. struct type_list_unique {
  68046. /*! @brief A type list without duplicate types. */
  68047. using type = typename internal::type_list_unique<List>::type;
  68048. };
  68049. /**
  68050. * @brief Helper type.
  68051. * @tparam List Type list.
  68052. */
  68053. template<typename List>
  68054. using type_list_unique_t = typename type_list_unique<List>::type;
  68055. /**
  68056. * @brief Provides the member constant `value` to true if a type list contains a
  68057. * given type, false otherwise.
  68058. * @tparam List Type list.
  68059. * @tparam Type Type to look for.
  68060. */
  68061. template<typename List, typename Type>
  68062. struct type_list_contains;
  68063. /**
  68064. * @copybrief type_list_contains
  68065. * @tparam Type Types provided by the type list.
  68066. * @tparam Other Type to look for.
  68067. */
  68068. template<typename... Type, typename Other>
  68069. struct type_list_contains<type_list<Type...>, Other>
  68070. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  68071. /**
  68072. * @brief Helper variable template.
  68073. * @tparam List Type list.
  68074. * @tparam Type Type to look for.
  68075. */
  68076. template<typename List, typename Type>
  68077. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  68078. /*! @brief Primary template isn't defined on purpose. */
  68079. template<typename...>
  68080. struct type_list_diff;
  68081. /**
  68082. * @brief Computes the difference between two type lists.
  68083. * @tparam Type Types provided by the first type list.
  68084. * @tparam Other Types provided by the second type list.
  68085. */
  68086. template<typename... Type, typename... Other>
  68087. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  68088. /*! @brief A type list that is the difference between the two type lists. */
  68089. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  68090. };
  68091. /**
  68092. * @brief Helper type.
  68093. * @tparam List Type lists between which to compute the difference.
  68094. */
  68095. template<typename... List>
  68096. using type_list_diff_t = typename type_list_diff<List...>::type;
  68097. /*! @brief Primary template isn't defined on purpose. */
  68098. template<typename, template<typename...> class>
  68099. struct type_list_transform;
  68100. /**
  68101. * @brief Applies a given _function_ to a type list and generate a new list.
  68102. * @tparam Type Types provided by the type list.
  68103. * @tparam Op Unary operation as template class with a type member named `type`.
  68104. */
  68105. template<typename... Type, template<typename...> class Op>
  68106. struct type_list_transform<type_list<Type...>, Op> {
  68107. /*! @brief Resulting type list after applying the transform function. */
  68108. // NOLINTNEXTLINE(modernize-type-traits)
  68109. using type = type_list<typename Op<Type>::type...>;
  68110. };
  68111. /**
  68112. * @brief Helper type.
  68113. * @tparam List Type list.
  68114. * @tparam Op Unary operation as template class with a type member named `type`.
  68115. */
  68116. template<typename List, template<typename...> class Op>
  68117. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  68118. /**
  68119. * @brief A class to use to push around lists of constant values, nothing more.
  68120. * @tparam Value Values provided by the value list.
  68121. */
  68122. template<auto... Value>
  68123. struct value_list {
  68124. /*! @brief Value list type. */
  68125. using type = value_list;
  68126. /*! @brief Compile-time number of elements in the value list. */
  68127. static constexpr auto size = sizeof...(Value);
  68128. };
  68129. /*! @brief Primary template isn't defined on purpose. */
  68130. template<std::size_t, typename>
  68131. struct value_list_element;
  68132. /**
  68133. * @brief Provides compile-time indexed access to the values of a value list.
  68134. * @tparam Index Index of the value to return.
  68135. * @tparam Value First value provided by the value list.
  68136. * @tparam Other Other values provided by the value list.
  68137. */
  68138. template<std::size_t Index, auto Value, auto... Other>
  68139. struct value_list_element<Index, value_list<Value, Other...>>
  68140. : value_list_element<Index - 1u, value_list<Other...>> {};
  68141. /**
  68142. * @brief Provides compile-time indexed access to the types of a type list.
  68143. * @tparam Value First value provided by the value list.
  68144. * @tparam Other Other values provided by the value list.
  68145. */
  68146. template<auto Value, auto... Other>
  68147. struct value_list_element<0u, value_list<Value, Other...>> {
  68148. /*! @brief Searched type. */
  68149. using type = decltype(Value);
  68150. /*! @brief Searched value. */
  68151. static constexpr auto value = Value;
  68152. };
  68153. /**
  68154. * @brief Helper type.
  68155. * @tparam Index Index of the type to return.
  68156. * @tparam List Value list to search into.
  68157. */
  68158. template<std::size_t Index, typename List>
  68159. using value_list_element_t = typename value_list_element<Index, List>::type;
  68160. /**
  68161. * @brief Helper type.
  68162. * @tparam Index Index of the value to return.
  68163. * @tparam List Value list to search into.
  68164. */
  68165. template<std::size_t Index, typename List>
  68166. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  68167. /*! @brief Primary template isn't defined on purpose. */
  68168. template<auto, typename>
  68169. struct value_list_index;
  68170. /**
  68171. * @brief Provides compile-time type access to the values of a value list.
  68172. * @tparam Value Value to look for and for which to return the index.
  68173. * @tparam First First value provided by the value list.
  68174. * @tparam Other Other values provided by the value list.
  68175. */
  68176. template<auto Value, auto First, auto... Other>
  68177. struct value_list_index<Value, value_list<First, Other...>> {
  68178. /*! @brief Unsigned integer type. */
  68179. using value_type = std::size_t;
  68180. /*! @brief Compile-time position of the given value in the sublist. */
  68181. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  68182. };
  68183. /**
  68184. * @brief Provides compile-time type access to the values of a value list.
  68185. * @tparam Value Value to look for and for which to return the index.
  68186. * @tparam Other Other values provided by the value list.
  68187. */
  68188. template<auto Value, auto... Other>
  68189. struct value_list_index<Value, value_list<Value, Other...>> {
  68190. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  68191. /*! @brief Unsigned integer type. */
  68192. using value_type = std::size_t;
  68193. /*! @brief Compile-time position of the given value in the sublist. */
  68194. static constexpr value_type value = 0u;
  68195. };
  68196. /**
  68197. * @brief Provides compile-time type access to the values of a value list.
  68198. * @tparam Value Value to look for and for which to return the index.
  68199. */
  68200. template<auto Value>
  68201. struct value_list_index<Value, value_list<>> {
  68202. /*! @brief Unsigned integer type. */
  68203. using value_type = std::size_t;
  68204. /*! @brief Compile-time position of the given type in the sublist. */
  68205. static constexpr value_type value = 0u;
  68206. };
  68207. /**
  68208. * @brief Helper variable template.
  68209. * @tparam List Value list.
  68210. * @tparam Value Value to look for and for which to return the index.
  68211. */
  68212. template<auto Value, typename List>
  68213. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  68214. /**
  68215. * @brief Concatenates multiple value lists.
  68216. * @tparam Value Values provided by the first value list.
  68217. * @tparam Other Values provided by the second value list.
  68218. * @return A value list composed by the values of both the value lists.
  68219. */
  68220. template<auto... Value, auto... Other>
  68221. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  68222. return {};
  68223. }
  68224. /*! @brief Primary template isn't defined on purpose. */
  68225. template<typename...>
  68226. struct value_list_cat;
  68227. /*! @brief Concatenates multiple value lists. */
  68228. template<>
  68229. struct value_list_cat<> {
  68230. /*! @brief A value list composed by the values of all the value lists. */
  68231. using type = value_list<>;
  68232. };
  68233. /**
  68234. * @brief Concatenates multiple value lists.
  68235. * @tparam Value Values provided by the first value list.
  68236. * @tparam Other Values provided by the second value list.
  68237. * @tparam List Other value lists, if any.
  68238. */
  68239. template<auto... Value, auto... Other, typename... List>
  68240. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  68241. /*! @brief A value list composed by the values of all the value lists. */
  68242. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  68243. };
  68244. /**
  68245. * @brief Concatenates multiple value lists.
  68246. * @tparam Value Values provided by the value list.
  68247. */
  68248. template<auto... Value>
  68249. struct value_list_cat<value_list<Value...>> {
  68250. /*! @brief A value list composed by the values of all the value lists. */
  68251. using type = value_list<Value...>;
  68252. };
  68253. /**
  68254. * @brief Helper type.
  68255. * @tparam List Value lists to concatenate.
  68256. */
  68257. template<typename... List>
  68258. using value_list_cat_t = typename value_list_cat<List...>::type;
  68259. /*! @brief Primary template isn't defined on purpose. */
  68260. template<typename>
  68261. struct value_list_unique;
  68262. /**
  68263. * @brief Removes duplicates values from a value list.
  68264. * @tparam Value One of the values provided by the given value list.
  68265. * @tparam Other The other values provided by the given value list.
  68266. */
  68267. template<auto Value, auto... Other>
  68268. struct value_list_unique<value_list<Value, Other...>> {
  68269. /*! @brief A value list without duplicate types. */
  68270. using type = std::conditional_t<
  68271. ((Value == Other) || ...),
  68272. typename value_list_unique<value_list<Other...>>::type,
  68273. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  68274. };
  68275. /*! @brief Removes duplicates values from a value list. */
  68276. template<>
  68277. struct value_list_unique<value_list<>> {
  68278. /*! @brief A value list without duplicate types. */
  68279. using type = value_list<>;
  68280. };
  68281. /**
  68282. * @brief Helper type.
  68283. * @tparam Type A value list.
  68284. */
  68285. template<typename Type>
  68286. using value_list_unique_t = typename value_list_unique<Type>::type;
  68287. /**
  68288. * @brief Provides the member constant `value` to true if a value list contains
  68289. * a given value, false otherwise.
  68290. * @tparam List Value list.
  68291. * @tparam Value Value to look for.
  68292. */
  68293. template<typename List, auto Value>
  68294. struct value_list_contains;
  68295. /**
  68296. * @copybrief value_list_contains
  68297. * @tparam Value Values provided by the value list.
  68298. * @tparam Other Value to look for.
  68299. */
  68300. template<auto... Value, auto Other>
  68301. struct value_list_contains<value_list<Value...>, Other>
  68302. : std::bool_constant<((Value == Other) || ...)> {};
  68303. /**
  68304. * @brief Helper variable template.
  68305. * @tparam List Value list.
  68306. * @tparam Value Value to look for.
  68307. */
  68308. template<typename List, auto Value>
  68309. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  68310. /*! @brief Primary template isn't defined on purpose. */
  68311. template<typename...>
  68312. struct value_list_diff;
  68313. /**
  68314. * @brief Computes the difference between two value lists.
  68315. * @tparam Value Values provided by the first value list.
  68316. * @tparam Other Values provided by the second value list.
  68317. */
  68318. template<auto... Value, auto... Other>
  68319. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  68320. /*! @brief A value list that is the difference between the two value lists. */
  68321. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  68322. };
  68323. /**
  68324. * @brief Helper type.
  68325. * @tparam List Value lists between which to compute the difference.
  68326. */
  68327. template<typename... List>
  68328. using value_list_diff_t = typename value_list_diff<List...>::type;
  68329. /*! @brief Same as std::is_invocable, but with tuples. */
  68330. template<typename, typename>
  68331. struct is_applicable: std::false_type {};
  68332. /**
  68333. * @copybrief is_applicable
  68334. * @tparam Func A valid function type.
  68335. * @tparam Tuple Tuple-like type.
  68336. * @tparam Args The list of arguments to use to probe the function type.
  68337. */
  68338. template<typename Func, template<typename...> class Tuple, typename... Args>
  68339. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  68340. /**
  68341. * @copybrief is_applicable
  68342. * @tparam Func A valid function type.
  68343. * @tparam Tuple Tuple-like type.
  68344. * @tparam Args The list of arguments to use to probe the function type.
  68345. */
  68346. template<typename Func, template<typename...> class Tuple, typename... Args>
  68347. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  68348. /**
  68349. * @brief Helper variable template.
  68350. * @tparam Func A valid function type.
  68351. * @tparam Args The list of arguments to use to probe the function type.
  68352. */
  68353. template<typename Func, typename Args>
  68354. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  68355. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  68356. template<typename, typename, typename>
  68357. struct is_applicable_r: std::false_type {};
  68358. /**
  68359. * @copybrief is_applicable_r
  68360. * @tparam Ret The type to which the return type of the function should be
  68361. * convertible.
  68362. * @tparam Func A valid function type.
  68363. * @tparam Args The list of arguments to use to probe the function type.
  68364. */
  68365. template<typename Ret, typename Func, typename... Args>
  68366. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  68367. /**
  68368. * @brief Helper variable template.
  68369. * @tparam Ret The type to which the return type of the function should be
  68370. * convertible.
  68371. * @tparam Func A valid function type.
  68372. * @tparam Args The list of arguments to use to probe the function type.
  68373. */
  68374. template<typename Ret, typename Func, typename Args>
  68375. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  68376. /**
  68377. * @brief Provides the member constant `value` to true if a given type is
  68378. * complete, false otherwise.
  68379. * @tparam Type The type to test.
  68380. */
  68381. template<typename Type, typename = void>
  68382. struct is_complete: std::false_type {};
  68383. /*! @copydoc is_complete */
  68384. template<typename Type>
  68385. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  68386. /**
  68387. * @brief Helper variable template.
  68388. * @tparam Type The type to test.
  68389. */
  68390. template<typename Type>
  68391. inline constexpr bool is_complete_v = is_complete<Type>::value;
  68392. /**
  68393. * @brief Provides the member constant `value` to true if a given type is an
  68394. * iterator, false otherwise.
  68395. * @tparam Type The type to test.
  68396. */
  68397. template<typename Type, typename = void>
  68398. struct is_iterator: std::false_type {};
  68399. /*! @cond TURN_OFF_DOXYGEN */
  68400. namespace internal {
  68401. template<typename, typename = void>
  68402. struct has_iterator_category: std::false_type {};
  68403. template<typename Type>
  68404. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  68405. } // namespace internal
  68406. /*! @endcond */
  68407. /*! @copydoc is_iterator */
  68408. template<typename Type>
  68409. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  68410. : internal::has_iterator_category<Type> {};
  68411. /**
  68412. * @brief Helper variable template.
  68413. * @tparam Type The type to test.
  68414. */
  68415. template<typename Type>
  68416. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  68417. /**
  68418. * @brief Provides the member constant `value` to true if a given type is both
  68419. * an empty and non-final class, false otherwise.
  68420. * @tparam Type The type to test
  68421. */
  68422. template<typename Type>
  68423. struct is_ebco_eligible
  68424. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  68425. /**
  68426. * @brief Helper variable template.
  68427. * @tparam Type The type to test.
  68428. */
  68429. template<typename Type>
  68430. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  68431. /**
  68432. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  68433. * is valid and denotes a type, false otherwise.
  68434. * @tparam Type The type to test.
  68435. */
  68436. template<typename Type, typename = void>
  68437. struct is_transparent: std::false_type {};
  68438. /*! @copydoc is_transparent */
  68439. template<typename Type>
  68440. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  68441. /**
  68442. * @brief Helper variable template.
  68443. * @tparam Type The type to test.
  68444. */
  68445. template<typename Type>
  68446. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  68447. /*! @cond TURN_OFF_DOXYGEN */
  68448. namespace internal {
  68449. template<typename, typename = void>
  68450. struct has_tuple_size_value: std::false_type {};
  68451. template<typename Type>
  68452. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  68453. template<typename, typename = void>
  68454. struct has_value_type: std::false_type {};
  68455. template<typename Type>
  68456. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  68457. template<typename>
  68458. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  68459. template<typename Type, std::size_t... Index>
  68460. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  68461. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  68462. }
  68463. template<typename>
  68464. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  68465. return false;
  68466. }
  68467. template<typename Type>
  68468. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  68469. return true;
  68470. }
  68471. template<typename Type>
  68472. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  68473. // NOLINTBEGIN(modernize-use-transparent-functors)
  68474. if constexpr(std::is_array_v<Type>) {
  68475. return false;
  68476. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  68477. if constexpr(has_tuple_size_value<Type>::value) {
  68478. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  68479. } else {
  68480. return maybe_equality_comparable<Type>(0);
  68481. }
  68482. } else if constexpr(has_value_type<Type>::value) {
  68483. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  68484. return maybe_equality_comparable<Type>(0);
  68485. } else {
  68486. return false;
  68487. }
  68488. } else {
  68489. return maybe_equality_comparable<Type>(0);
  68490. }
  68491. // NOLINTEND(modernize-use-transparent-functors)
  68492. }
  68493. } // namespace internal
  68494. /*! @endcond */
  68495. /**
  68496. * @brief Provides the member constant `value` to true if a given type is
  68497. * equality comparable, false otherwise.
  68498. * @tparam Type The type to test.
  68499. */
  68500. template<typename Type>
  68501. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  68502. /*! @copydoc is_equality_comparable */
  68503. template<typename Type>
  68504. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  68505. /**
  68506. * @brief Helper variable template.
  68507. * @tparam Type The type to test.
  68508. */
  68509. template<typename Type>
  68510. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  68511. /**
  68512. * @brief Transcribes the constness of a type to another type.
  68513. * @tparam To The type to which to transcribe the constness.
  68514. * @tparam From The type from which to transcribe the constness.
  68515. */
  68516. template<typename To, typename From>
  68517. struct constness_as {
  68518. /*! @brief The type resulting from the transcription of the constness. */
  68519. using type = std::remove_const_t<To>;
  68520. };
  68521. /*! @copydoc constness_as */
  68522. template<typename To, typename From>
  68523. struct constness_as<To, const From> {
  68524. /*! @brief The type resulting from the transcription of the constness. */
  68525. using type = const To;
  68526. };
  68527. /**
  68528. * @brief Alias template to facilitate the transcription of the constness.
  68529. * @tparam To The type to which to transcribe the constness.
  68530. * @tparam From The type from which to transcribe the constness.
  68531. */
  68532. template<typename To, typename From>
  68533. using constness_as_t = typename constness_as<To, From>::type;
  68534. /**
  68535. * @brief Extracts the class of a non-static member object or function.
  68536. * @tparam Member A pointer to a non-static member object or function.
  68537. */
  68538. template<typename Member>
  68539. class member_class {
  68540. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  68541. template<typename Class, typename Ret, typename... Args>
  68542. static Class *clazz(Ret (Class::*)(Args...));
  68543. template<typename Class, typename Ret, typename... Args>
  68544. static Class *clazz(Ret (Class::*)(Args...) const);
  68545. template<typename Class, typename Type>
  68546. static Class *clazz(Type Class::*);
  68547. public:
  68548. /*! @brief The class of the given non-static member object or function. */
  68549. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  68550. };
  68551. /**
  68552. * @brief Helper type.
  68553. * @tparam Member A pointer to a non-static member object or function.
  68554. */
  68555. template<typename Member>
  68556. using member_class_t = typename member_class<Member>::type;
  68557. /**
  68558. * @brief Extracts the n-th argument of a _callable_ type.
  68559. * @tparam Index The index of the argument to extract.
  68560. * @tparam Candidate A valid _callable_ type.
  68561. */
  68562. template<std::size_t Index, typename Candidate>
  68563. class nth_argument {
  68564. template<typename Ret, typename... Args>
  68565. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  68566. template<typename Ret, typename Class, typename... Args>
  68567. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  68568. template<typename Ret, typename Class, typename... Args>
  68569. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  68570. template<typename Type, typename Class>
  68571. static constexpr type_list<Type> pick_up(Type Class ::*);
  68572. template<typename Type>
  68573. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  68574. public:
  68575. /*! @brief N-th argument of the _callable_ type. */
  68576. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  68577. };
  68578. /**
  68579. * @brief Helper type.
  68580. * @tparam Index The index of the argument to extract.
  68581. * @tparam Candidate A valid function, member function or data member type.
  68582. */
  68583. template<std::size_t Index, typename Candidate>
  68584. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  68585. } // namespace entt
  68586. template<typename... Type>
  68587. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  68588. template<std::size_t Index, typename... Type>
  68589. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  68590. template<auto... Value>
  68591. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  68592. template<std::size_t Index, auto... Value>
  68593. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  68594. #endif
  68595. namespace entt {
  68596. /*! @cond TURN_OFF_DOXYGEN */
  68597. namespace internal {
  68598. template<typename Type, std::size_t, typename = void>
  68599. struct compressed_pair_element {
  68600. using reference = Type &;
  68601. using const_reference = const Type &;
  68602. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  68603. // NOLINTNEXTLINE(modernize-use-equals-default)
  68604. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  68605. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  68606. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  68607. : value{std::forward<Arg>(arg)} {}
  68608. template<typename... Args, std::size_t... Index>
  68609. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  68610. : value{std::forward<Args>(std::get<Index>(args))...} {}
  68611. [[nodiscard]] constexpr reference get() noexcept {
  68612. return value;
  68613. }
  68614. [[nodiscard]] constexpr const_reference get() const noexcept {
  68615. return value;
  68616. }
  68617. private:
  68618. Type value{};
  68619. };
  68620. template<typename Type, std::size_t Tag>
  68621. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  68622. using reference = Type &;
  68623. using const_reference = const Type &;
  68624. using base_type = Type;
  68625. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  68626. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  68627. : base_type{} {}
  68628. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  68629. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  68630. : base_type{std::forward<Arg>(arg)} {}
  68631. template<typename... Args, std::size_t... Index>
  68632. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  68633. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  68634. [[nodiscard]] constexpr reference get() noexcept {
  68635. return *this;
  68636. }
  68637. [[nodiscard]] constexpr const_reference get() const noexcept {
  68638. return *this;
  68639. }
  68640. };
  68641. } // namespace internal
  68642. /*! @endcond */
  68643. /**
  68644. * @brief A compressed pair.
  68645. *
  68646. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  68647. * reduce its final size to a minimum.
  68648. *
  68649. * @tparam First The type of the first element that the pair stores.
  68650. * @tparam Second The type of the second element that the pair stores.
  68651. */
  68652. template<typename First, typename Second>
  68653. class compressed_pair final
  68654. : internal::compressed_pair_element<First, 0u>,
  68655. internal::compressed_pair_element<Second, 1u> {
  68656. using first_base = internal::compressed_pair_element<First, 0u>;
  68657. using second_base = internal::compressed_pair_element<Second, 1u>;
  68658. public:
  68659. /*! @brief The type of the first element that the pair stores. */
  68660. using first_type = First;
  68661. /*! @brief The type of the second element that the pair stores. */
  68662. using second_type = Second;
  68663. /**
  68664. * @brief Default constructor, conditionally enabled.
  68665. *
  68666. * This constructor is only available when the types that the pair stores
  68667. * are both at least default constructible.
  68668. *
  68669. * @tparam Dummy Dummy template parameter used for internal purposes.
  68670. */
  68671. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  68672. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  68673. : first_base{},
  68674. second_base{} {}
  68675. /**
  68676. * @brief Copy constructor.
  68677. * @param other The instance to copy from.
  68678. */
  68679. constexpr compressed_pair(const compressed_pair &other) = default;
  68680. /**
  68681. * @brief Move constructor.
  68682. * @param other The instance to move from.
  68683. */
  68684. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  68685. /**
  68686. * @brief Constructs a pair from its values.
  68687. * @tparam Arg Type of value to use to initialize the first element.
  68688. * @tparam Other Type of value to use to initialize the second element.
  68689. * @param arg Value to use to initialize the first element.
  68690. * @param other Value to use to initialize the second element.
  68691. */
  68692. template<typename Arg, typename Other>
  68693. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  68694. : first_base{std::forward<Arg>(arg)},
  68695. second_base{std::forward<Other>(other)} {}
  68696. /**
  68697. * @brief Constructs a pair by forwarding the arguments to its parts.
  68698. * @tparam Args Types of arguments to use to initialize the first element.
  68699. * @tparam Other Types of arguments to use to initialize the second element.
  68700. * @param args Arguments to use to initialize the first element.
  68701. * @param other Arguments to use to initialize the second element.
  68702. */
  68703. template<typename... Args, typename... Other>
  68704. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  68705. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  68706. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  68707. /*! @brief Default destructor. */
  68708. ~compressed_pair() = default;
  68709. /**
  68710. * @brief Copy assignment operator.
  68711. * @param other The instance to copy from.
  68712. * @return This compressed pair object.
  68713. */
  68714. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  68715. /**
  68716. * @brief Move assignment operator.
  68717. * @param other The instance to move from.
  68718. * @return This compressed pair object.
  68719. */
  68720. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  68721. /**
  68722. * @brief Returns the first element that a pair stores.
  68723. * @return The first element that a pair stores.
  68724. */
  68725. [[nodiscard]] constexpr first_type &first() noexcept {
  68726. return static_cast<first_base &>(*this).get();
  68727. }
  68728. /*! @copydoc first */
  68729. [[nodiscard]] constexpr const first_type &first() const noexcept {
  68730. return static_cast<const first_base &>(*this).get();
  68731. }
  68732. /**
  68733. * @brief Returns the second element that a pair stores.
  68734. * @return The second element that a pair stores.
  68735. */
  68736. [[nodiscard]] constexpr second_type &second() noexcept {
  68737. return static_cast<second_base &>(*this).get();
  68738. }
  68739. /*! @copydoc second */
  68740. [[nodiscard]] constexpr const second_type &second() const noexcept {
  68741. return static_cast<const second_base &>(*this).get();
  68742. }
  68743. /**
  68744. * @brief Swaps two compressed pair objects.
  68745. * @param other The compressed pair to swap with.
  68746. */
  68747. constexpr void swap(compressed_pair &other) noexcept {
  68748. using std::swap;
  68749. swap(first(), other.first());
  68750. swap(second(), other.second());
  68751. }
  68752. /**
  68753. * @brief Extracts an element from the compressed pair.
  68754. * @tparam Index An integer value that is either 0 or 1.
  68755. * @return Returns a reference to the first element if `Index` is 0 and a
  68756. * reference to the second element if `Index` is 1.
  68757. */
  68758. template<std::size_t Index>
  68759. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  68760. if constexpr(Index == 0u) {
  68761. return first();
  68762. } else {
  68763. static_assert(Index == 1u, "Index out of bounds");
  68764. return second();
  68765. }
  68766. }
  68767. /*! @copydoc get */
  68768. template<std::size_t Index>
  68769. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  68770. if constexpr(Index == 0u) {
  68771. return first();
  68772. } else {
  68773. static_assert(Index == 1u, "Index out of bounds");
  68774. return second();
  68775. }
  68776. }
  68777. };
  68778. /**
  68779. * @brief Deduction guide.
  68780. * @tparam Type Type of value to use to initialize the first element.
  68781. * @tparam Other Type of value to use to initialize the second element.
  68782. */
  68783. template<typename Type, typename Other>
  68784. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  68785. /**
  68786. * @brief Swaps two compressed pair objects.
  68787. * @tparam First The type of the first element that the pairs store.
  68788. * @tparam Second The type of the second element that the pairs store.
  68789. * @param lhs A valid compressed pair object.
  68790. * @param rhs A valid compressed pair object.
  68791. */
  68792. template<typename First, typename Second>
  68793. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  68794. lhs.swap(rhs);
  68795. }
  68796. } // namespace entt
  68797. namespace std {
  68798. /**
  68799. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  68800. * @tparam First The type of the first element that the pair stores.
  68801. * @tparam Second The type of the second element that the pair stores.
  68802. */
  68803. template<typename First, typename Second>
  68804. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  68805. /**
  68806. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  68807. * @tparam Index The index of the type to return.
  68808. * @tparam First The type of the first element that the pair stores.
  68809. * @tparam Second The type of the second element that the pair stores.
  68810. */
  68811. template<size_t Index, typename First, typename Second>
  68812. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  68813. static_assert(Index < 2u, "Index out of bounds");
  68814. };
  68815. } // namespace std
  68816. #endif
  68817. // #include "../core/iterator.hpp"
  68818. #ifndef ENTT_CORE_ITERATOR_HPP
  68819. #define ENTT_CORE_ITERATOR_HPP
  68820. #include <iterator>
  68821. #include <memory>
  68822. #include <type_traits>
  68823. #include <utility>
  68824. namespace entt {
  68825. /**
  68826. * @brief Helper type to use as pointer with input iterators.
  68827. * @tparam Type of wrapped value.
  68828. */
  68829. template<typename Type>
  68830. struct input_iterator_pointer final {
  68831. /*! @brief Value type. */
  68832. using value_type = Type;
  68833. /*! @brief Pointer type. */
  68834. using pointer = Type *;
  68835. /*! @brief Reference type. */
  68836. using reference = Type &;
  68837. /**
  68838. * @brief Constructs a proxy object by move.
  68839. * @param val Value to use to initialize the proxy object.
  68840. */
  68841. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  68842. : value{std::move(val)} {}
  68843. /**
  68844. * @brief Access operator for accessing wrapped values.
  68845. * @return A pointer to the wrapped value.
  68846. */
  68847. [[nodiscard]] constexpr pointer operator->() noexcept {
  68848. return std::addressof(value);
  68849. }
  68850. /**
  68851. * @brief Dereference operator for accessing wrapped values.
  68852. * @return A reference to the wrapped value.
  68853. */
  68854. [[nodiscard]] constexpr reference operator*() noexcept {
  68855. return value;
  68856. }
  68857. private:
  68858. Type value;
  68859. };
  68860. /**
  68861. * @brief Plain iota iterator (waiting for C++20).
  68862. * @tparam Type Value type.
  68863. */
  68864. template<typename Type>
  68865. class iota_iterator final {
  68866. static_assert(std::is_integral_v<Type>, "Not an integral type");
  68867. public:
  68868. /*! @brief Value type, likely an integral one. */
  68869. using value_type = Type;
  68870. /*! @brief Invalid pointer type. */
  68871. using pointer = void;
  68872. /*! @brief Non-reference type, same as value type. */
  68873. using reference = value_type;
  68874. /*! @brief Difference type. */
  68875. using difference_type = std::ptrdiff_t;
  68876. /*! @brief Iterator category. */
  68877. using iterator_category = std::input_iterator_tag;
  68878. /*! @brief Default constructor. */
  68879. constexpr iota_iterator() noexcept
  68880. : current{} {}
  68881. /**
  68882. * @brief Constructs an iota iterator from a given value.
  68883. * @param init The initial value assigned to the iota iterator.
  68884. */
  68885. constexpr iota_iterator(const value_type init) noexcept
  68886. : current{init} {}
  68887. /**
  68888. * @brief Pre-increment operator.
  68889. * @return This iota iterator.
  68890. */
  68891. constexpr iota_iterator &operator++() noexcept {
  68892. return ++current, *this;
  68893. }
  68894. /**
  68895. * @brief Post-increment operator.
  68896. * @return This iota iterator.
  68897. */
  68898. constexpr iota_iterator operator++(int) noexcept {
  68899. const iota_iterator orig = *this;
  68900. return ++(*this), orig;
  68901. }
  68902. /**
  68903. * @brief Dereference operator.
  68904. * @return The underlying value.
  68905. */
  68906. [[nodiscard]] constexpr reference operator*() const noexcept {
  68907. return current;
  68908. }
  68909. private:
  68910. value_type current;
  68911. };
  68912. /**
  68913. * @brief Comparison operator.
  68914. * @tparam Type Value type of the iota iterator.
  68915. * @param lhs A properly initialized iota iterator.
  68916. * @param rhs A properly initialized iota iterator.
  68917. * @return True if the two iterators are identical, false otherwise.
  68918. */
  68919. template<typename Type>
  68920. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  68921. return *lhs == *rhs;
  68922. }
  68923. /**
  68924. * @brief Comparison operator.
  68925. * @tparam Type Value type of the iota iterator.
  68926. * @param lhs A properly initialized iota iterator.
  68927. * @param rhs A properly initialized iota iterator.
  68928. * @return True if the two iterators differ, false otherwise.
  68929. */
  68930. template<typename Type>
  68931. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  68932. return !(lhs == rhs);
  68933. }
  68934. /**
  68935. * @brief Utility class to create an iterable object from a pair of iterators.
  68936. * @tparam It Type of iterator.
  68937. * @tparam Sentinel Type of sentinel.
  68938. */
  68939. template<typename It, typename Sentinel = It>
  68940. struct iterable_adaptor final {
  68941. /*! @brief Value type. */
  68942. using value_type = typename std::iterator_traits<It>::value_type;
  68943. /*! @brief Iterator type. */
  68944. using iterator = It;
  68945. /*! @brief Sentinel type. */
  68946. using sentinel = Sentinel;
  68947. /*! @brief Default constructor. */
  68948. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  68949. : first{},
  68950. last{} {}
  68951. /**
  68952. * @brief Creates an iterable object from a pair of iterators.
  68953. * @param from Begin iterator.
  68954. * @param to End iterator.
  68955. */
  68956. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  68957. : first{std::move(from)},
  68958. last{std::move(to)} {}
  68959. /**
  68960. * @brief Returns an iterator to the beginning.
  68961. * @return An iterator to the first element of the range.
  68962. */
  68963. [[nodiscard]] constexpr iterator begin() const noexcept {
  68964. return first;
  68965. }
  68966. /**
  68967. * @brief Returns an iterator to the end.
  68968. * @return An iterator to the element following the last element of the
  68969. * range.
  68970. */
  68971. [[nodiscard]] constexpr sentinel end() const noexcept {
  68972. return last;
  68973. }
  68974. /*! @copydoc begin */
  68975. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  68976. return begin();
  68977. }
  68978. /*! @copydoc end */
  68979. [[nodiscard]] constexpr sentinel cend() const noexcept {
  68980. return end();
  68981. }
  68982. private:
  68983. It first;
  68984. Sentinel last;
  68985. };
  68986. } // namespace entt
  68987. #endif
  68988. // #include "../core/memory.hpp"
  68989. #ifndef ENTT_CORE_MEMORY_HPP
  68990. #define ENTT_CORE_MEMORY_HPP
  68991. #include <cstddef>
  68992. #include <memory>
  68993. #include <tuple>
  68994. #include <type_traits>
  68995. #include <utility>
  68996. // #include "../config/config.h"
  68997. namespace entt {
  68998. /**
  68999. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  69000. * @tparam Type Pointer type.
  69001. * @param ptr Fancy or raw pointer.
  69002. * @return A raw pointer that represents the address of the original pointer.
  69003. */
  69004. template<typename Type>
  69005. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  69006. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  69007. return ptr;
  69008. } else {
  69009. return to_address(std::forward<Type>(ptr).operator->());
  69010. }
  69011. }
  69012. /**
  69013. * @brief Utility function to design allocation-aware containers.
  69014. * @tparam Allocator Type of allocator.
  69015. * @param lhs A valid allocator.
  69016. * @param rhs Another valid allocator.
  69017. */
  69018. template<typename Allocator>
  69019. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  69020. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  69021. lhs = rhs;
  69022. }
  69023. }
  69024. /**
  69025. * @brief Utility function to design allocation-aware containers.
  69026. * @tparam Allocator Type of allocator.
  69027. * @param lhs A valid allocator.
  69028. * @param rhs Another valid allocator.
  69029. */
  69030. template<typename Allocator>
  69031. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  69032. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  69033. lhs = std::move(rhs);
  69034. }
  69035. }
  69036. /**
  69037. * @brief Utility function to design allocation-aware containers.
  69038. * @tparam Allocator Type of allocator.
  69039. * @param lhs A valid allocator.
  69040. * @param rhs Another valid allocator.
  69041. */
  69042. template<typename Allocator>
  69043. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  69044. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  69045. using std::swap;
  69046. swap(lhs, rhs);
  69047. } else {
  69048. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  69049. }
  69050. }
  69051. /**
  69052. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  69053. * @tparam Allocator Type of allocator used to manage memory and elements.
  69054. */
  69055. template<typename Allocator>
  69056. struct allocation_deleter: private Allocator {
  69057. /*! @brief Allocator type. */
  69058. using allocator_type = Allocator;
  69059. /*! @brief Pointer type. */
  69060. using pointer = typename std::allocator_traits<Allocator>::pointer;
  69061. /**
  69062. * @brief Inherited constructors.
  69063. * @param alloc The allocator to use.
  69064. */
  69065. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  69066. : Allocator{alloc} {}
  69067. /**
  69068. * @brief Destroys the pointed object and deallocates its memory.
  69069. * @param ptr A valid pointer to an object of the given type.
  69070. */
  69071. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  69072. using alloc_traits = std::allocator_traits<Allocator>;
  69073. alloc_traits::destroy(*this, to_address(ptr));
  69074. alloc_traits::deallocate(*this, ptr, 1u);
  69075. }
  69076. };
  69077. /**
  69078. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  69079. * @tparam Type Type of object to allocate for and to construct.
  69080. * @tparam Allocator Type of allocator used to manage memory and elements.
  69081. * @tparam Args Types of arguments to use to construct the object.
  69082. * @param allocator The allocator to use.
  69083. * @param args Parameters to use to construct the object.
  69084. * @return A properly initialized unique pointer with a custom deleter.
  69085. */
  69086. template<typename Type, typename Allocator, typename... Args>
  69087. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  69088. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  69089. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  69090. using allocator_type = typename alloc_traits::allocator_type;
  69091. allocator_type alloc{allocator};
  69092. auto ptr = alloc_traits::allocate(alloc, 1u);
  69093. ENTT_TRY {
  69094. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  69095. }
  69096. ENTT_CATCH {
  69097. alloc_traits::deallocate(alloc, ptr, 1u);
  69098. ENTT_THROW;
  69099. }
  69100. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  69101. }
  69102. /*! @cond TURN_OFF_DOXYGEN */
  69103. namespace internal {
  69104. template<typename Type>
  69105. struct uses_allocator_construction {
  69106. template<typename Allocator, typename... Params>
  69107. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  69108. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  69109. return std::forward_as_tuple(std::forward<Params>(params)...);
  69110. } else {
  69111. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  69112. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  69113. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  69114. } else {
  69115. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  69116. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  69117. }
  69118. }
  69119. }
  69120. };
  69121. template<typename Type, typename Other>
  69122. struct uses_allocator_construction<std::pair<Type, Other>> {
  69123. using type = std::pair<Type, Other>;
  69124. template<typename Allocator, typename First, typename Second>
  69125. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  69126. return std::make_tuple(
  69127. std::piecewise_construct,
  69128. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  69129. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  69130. }
  69131. template<typename Allocator>
  69132. static constexpr auto args(const Allocator &allocator) noexcept {
  69133. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  69134. }
  69135. template<typename Allocator, typename First, typename Second>
  69136. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  69137. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  69138. }
  69139. template<typename Allocator, typename First, typename Second>
  69140. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  69141. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  69142. }
  69143. template<typename Allocator, typename First, typename Second>
  69144. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  69145. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  69146. }
  69147. };
  69148. } // namespace internal
  69149. /*! @endcond */
  69150. /**
  69151. * @brief Uses-allocator construction utility (waiting for C++20).
  69152. *
  69153. * Primarily intended for internal use. Prepares the argument list needed to
  69154. * create an object of a given type by means of uses-allocator construction.
  69155. *
  69156. * @tparam Type Type to return arguments for.
  69157. * @tparam Allocator Type of allocator used to manage memory and elements.
  69158. * @tparam Args Types of arguments to use to construct the object.
  69159. * @param allocator The allocator to use.
  69160. * @param args Parameters to use to construct the object.
  69161. * @return The arguments needed to create an object of the given type.
  69162. */
  69163. template<typename Type, typename Allocator, typename... Args>
  69164. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  69165. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  69166. }
  69167. /**
  69168. * @brief Uses-allocator construction utility (waiting for C++20).
  69169. *
  69170. * Primarily intended for internal use. Creates an object of a given type by
  69171. * means of uses-allocator construction.
  69172. *
  69173. * @tparam Type Type of object to create.
  69174. * @tparam Allocator Type of allocator used to manage memory and elements.
  69175. * @tparam Args Types of arguments to use to construct the object.
  69176. * @param allocator The allocator to use.
  69177. * @param args Parameters to use to construct the object.
  69178. * @return A newly created object of the given type.
  69179. */
  69180. template<typename Type, typename Allocator, typename... Args>
  69181. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  69182. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  69183. }
  69184. /**
  69185. * @brief Uses-allocator construction utility (waiting for C++20).
  69186. *
  69187. * Primarily intended for internal use. Creates an object of a given type by
  69188. * means of uses-allocator construction at an uninitialized memory location.
  69189. *
  69190. * @tparam Type Type of object to create.
  69191. * @tparam Allocator Type of allocator used to manage memory and elements.
  69192. * @tparam Args Types of arguments to use to construct the object.
  69193. * @param value Memory location in which to place the object.
  69194. * @param allocator The allocator to use.
  69195. * @param args Parameters to use to construct the object.
  69196. * @return A pointer to the newly created object of the given type.
  69197. */
  69198. template<typename Type, typename Allocator, typename... Args>
  69199. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  69200. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  69201. }
  69202. } // namespace entt
  69203. #endif
  69204. // #include "../core/type_traits.hpp"
  69205. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  69206. #define ENTT_CORE_TYPE_TRAITS_HPP
  69207. #include <cstddef>
  69208. #include <iterator>
  69209. #include <tuple>
  69210. #include <type_traits>
  69211. #include <utility>
  69212. // #include "../config/config.h"
  69213. // #include "fwd.hpp"
  69214. namespace entt {
  69215. /**
  69216. * @brief Utility class to disambiguate overloaded functions.
  69217. * @tparam N Number of choices available.
  69218. */
  69219. template<std::size_t N>
  69220. struct choice_t
  69221. // unfortunately, doxygen cannot parse such a construct
  69222. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  69223. {};
  69224. /*! @copybrief choice_t */
  69225. template<>
  69226. struct choice_t<0> {};
  69227. /**
  69228. * @brief Variable template for the choice trick.
  69229. * @tparam N Number of choices available.
  69230. */
  69231. template<std::size_t N>
  69232. inline constexpr choice_t<N> choice{};
  69233. /**
  69234. * @brief Identity type trait.
  69235. *
  69236. * Useful to establish non-deduced contexts in template argument deduction
  69237. * (waiting for C++20) or to provide types through function arguments.
  69238. *
  69239. * @tparam Type A type.
  69240. */
  69241. template<typename Type>
  69242. struct type_identity {
  69243. /*! @brief Identity type. */
  69244. using type = Type;
  69245. };
  69246. /**
  69247. * @brief Helper type.
  69248. * @tparam Type A type.
  69249. */
  69250. template<typename Type>
  69251. using type_identity_t = typename type_identity<Type>::type;
  69252. /**
  69253. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  69254. * @tparam Type The type of which to return the size.
  69255. */
  69256. template<typename Type, typename = void>
  69257. struct size_of: std::integral_constant<std::size_t, 0u> {};
  69258. /*! @copydoc size_of */
  69259. template<typename Type>
  69260. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  69261. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  69262. : std::integral_constant<std::size_t, sizeof(Type)> {};
  69263. /**
  69264. * @brief Helper variable template.
  69265. * @tparam Type The type of which to return the size.
  69266. */
  69267. template<typename Type>
  69268. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  69269. /**
  69270. * @brief Using declaration to be used to _repeat_ the same type a number of
  69271. * times equal to the size of a given parameter pack.
  69272. * @tparam Type A type to repeat.
  69273. */
  69274. template<typename Type, typename>
  69275. using unpack_as_type = Type;
  69276. /**
  69277. * @brief Helper variable template to be used to _repeat_ the same value a
  69278. * number of times equal to the size of a given parameter pack.
  69279. * @tparam Value A value to repeat.
  69280. */
  69281. template<auto Value, typename>
  69282. inline constexpr auto unpack_as_value = Value;
  69283. /**
  69284. * @brief Wraps a static constant.
  69285. * @tparam Value A static constant.
  69286. */
  69287. template<auto Value>
  69288. using integral_constant = std::integral_constant<decltype(Value), Value>;
  69289. /**
  69290. * @brief Alias template to facilitate the creation of named values.
  69291. * @tparam Value A constant value at least convertible to `id_type`.
  69292. */
  69293. template<id_type Value>
  69294. using tag = integral_constant<Value>;
  69295. /**
  69296. * @brief A class to use to push around lists of types, nothing more.
  69297. * @tparam Type Types provided by the type list.
  69298. */
  69299. template<typename... Type>
  69300. struct type_list {
  69301. /*! @brief Type list type. */
  69302. using type = type_list;
  69303. /*! @brief Compile-time number of elements in the type list. */
  69304. static constexpr auto size = sizeof...(Type);
  69305. };
  69306. /*! @brief Primary template isn't defined on purpose. */
  69307. template<std::size_t, typename>
  69308. struct type_list_element;
  69309. /**
  69310. * @brief Provides compile-time indexed access to the types of a type list.
  69311. * @tparam Index Index of the type to return.
  69312. * @tparam First First type provided by the type list.
  69313. * @tparam Other Other types provided by the type list.
  69314. */
  69315. template<std::size_t Index, typename First, typename... Other>
  69316. struct type_list_element<Index, type_list<First, Other...>>
  69317. : type_list_element<Index - 1u, type_list<Other...>> {};
  69318. /**
  69319. * @brief Provides compile-time indexed access to the types of a type list.
  69320. * @tparam First First type provided by the type list.
  69321. * @tparam Other Other types provided by the type list.
  69322. */
  69323. template<typename First, typename... Other>
  69324. struct type_list_element<0u, type_list<First, Other...>> {
  69325. /*! @brief Searched type. */
  69326. using type = First;
  69327. };
  69328. /**
  69329. * @brief Helper type.
  69330. * @tparam Index Index of the type to return.
  69331. * @tparam List Type list to search into.
  69332. */
  69333. template<std::size_t Index, typename List>
  69334. using type_list_element_t = typename type_list_element<Index, List>::type;
  69335. /*! @brief Primary template isn't defined on purpose. */
  69336. template<typename, typename>
  69337. struct type_list_index;
  69338. /**
  69339. * @brief Provides compile-time type access to the types of a type list.
  69340. * @tparam Type Type to look for and for which to return the index.
  69341. * @tparam First First type provided by the type list.
  69342. * @tparam Other Other types provided by the type list.
  69343. */
  69344. template<typename Type, typename First, typename... Other>
  69345. struct type_list_index<Type, type_list<First, Other...>> {
  69346. /*! @brief Unsigned integer type. */
  69347. using value_type = std::size_t;
  69348. /*! @brief Compile-time position of the given type in the sublist. */
  69349. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  69350. };
  69351. /**
  69352. * @brief Provides compile-time type access to the types of a type list.
  69353. * @tparam Type Type to look for and for which to return the index.
  69354. * @tparam Other Other types provided by the type list.
  69355. */
  69356. template<typename Type, typename... Other>
  69357. struct type_list_index<Type, type_list<Type, Other...>> {
  69358. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  69359. /*! @brief Unsigned integer type. */
  69360. using value_type = std::size_t;
  69361. /*! @brief Compile-time position of the given type in the sublist. */
  69362. static constexpr value_type value = 0u;
  69363. };
  69364. /**
  69365. * @brief Provides compile-time type access to the types of a type list.
  69366. * @tparam Type Type to look for and for which to return the index.
  69367. */
  69368. template<typename Type>
  69369. struct type_list_index<Type, type_list<>> {
  69370. /*! @brief Unsigned integer type. */
  69371. using value_type = std::size_t;
  69372. /*! @brief Compile-time position of the given type in the sublist. */
  69373. static constexpr value_type value = 0u;
  69374. };
  69375. /**
  69376. * @brief Helper variable template.
  69377. * @tparam List Type list.
  69378. * @tparam Type Type to look for and for which to return the index.
  69379. */
  69380. template<typename Type, typename List>
  69381. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  69382. /**
  69383. * @brief Concatenates multiple type lists.
  69384. * @tparam Type Types provided by the first type list.
  69385. * @tparam Other Types provided by the second type list.
  69386. * @return A type list composed by the types of both the type lists.
  69387. */
  69388. template<typename... Type, typename... Other>
  69389. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  69390. return {};
  69391. }
  69392. /*! @brief Primary template isn't defined on purpose. */
  69393. template<typename...>
  69394. struct type_list_cat;
  69395. /*! @brief Concatenates multiple type lists. */
  69396. template<>
  69397. struct type_list_cat<> {
  69398. /*! @brief A type list composed by the types of all the type lists. */
  69399. using type = type_list<>;
  69400. };
  69401. /**
  69402. * @brief Concatenates multiple type lists.
  69403. * @tparam Type Types provided by the first type list.
  69404. * @tparam Other Types provided by the second type list.
  69405. * @tparam List Other type lists, if any.
  69406. */
  69407. template<typename... Type, typename... Other, typename... List>
  69408. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  69409. /*! @brief A type list composed by the types of all the type lists. */
  69410. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  69411. };
  69412. /**
  69413. * @brief Concatenates multiple type lists.
  69414. * @tparam Type Types provided by the type list.
  69415. */
  69416. template<typename... Type>
  69417. struct type_list_cat<type_list<Type...>> {
  69418. /*! @brief A type list composed by the types of all the type lists. */
  69419. using type = type_list<Type...>;
  69420. };
  69421. /**
  69422. * @brief Helper type.
  69423. * @tparam List Type lists to concatenate.
  69424. */
  69425. template<typename... List>
  69426. using type_list_cat_t = typename type_list_cat<List...>::type;
  69427. /*! @cond TURN_OFF_DOXYGEN */
  69428. namespace internal {
  69429. template<typename...>
  69430. struct type_list_unique;
  69431. template<typename First, typename... Other, typename... Type>
  69432. struct type_list_unique<type_list<First, Other...>, Type...>
  69433. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  69434. template<typename... Type>
  69435. struct type_list_unique<type_list<>, Type...> {
  69436. using type = type_list<Type...>;
  69437. };
  69438. } // namespace internal
  69439. /*! @endcond */
  69440. /**
  69441. * @brief Removes duplicates types from a type list.
  69442. * @tparam List Type list.
  69443. */
  69444. template<typename List>
  69445. struct type_list_unique {
  69446. /*! @brief A type list without duplicate types. */
  69447. using type = typename internal::type_list_unique<List>::type;
  69448. };
  69449. /**
  69450. * @brief Helper type.
  69451. * @tparam List Type list.
  69452. */
  69453. template<typename List>
  69454. using type_list_unique_t = typename type_list_unique<List>::type;
  69455. /**
  69456. * @brief Provides the member constant `value` to true if a type list contains a
  69457. * given type, false otherwise.
  69458. * @tparam List Type list.
  69459. * @tparam Type Type to look for.
  69460. */
  69461. template<typename List, typename Type>
  69462. struct type_list_contains;
  69463. /**
  69464. * @copybrief type_list_contains
  69465. * @tparam Type Types provided by the type list.
  69466. * @tparam Other Type to look for.
  69467. */
  69468. template<typename... Type, typename Other>
  69469. struct type_list_contains<type_list<Type...>, Other>
  69470. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  69471. /**
  69472. * @brief Helper variable template.
  69473. * @tparam List Type list.
  69474. * @tparam Type Type to look for.
  69475. */
  69476. template<typename List, typename Type>
  69477. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  69478. /*! @brief Primary template isn't defined on purpose. */
  69479. template<typename...>
  69480. struct type_list_diff;
  69481. /**
  69482. * @brief Computes the difference between two type lists.
  69483. * @tparam Type Types provided by the first type list.
  69484. * @tparam Other Types provided by the second type list.
  69485. */
  69486. template<typename... Type, typename... Other>
  69487. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  69488. /*! @brief A type list that is the difference between the two type lists. */
  69489. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  69490. };
  69491. /**
  69492. * @brief Helper type.
  69493. * @tparam List Type lists between which to compute the difference.
  69494. */
  69495. template<typename... List>
  69496. using type_list_diff_t = typename type_list_diff<List...>::type;
  69497. /*! @brief Primary template isn't defined on purpose. */
  69498. template<typename, template<typename...> class>
  69499. struct type_list_transform;
  69500. /**
  69501. * @brief Applies a given _function_ to a type list and generate a new list.
  69502. * @tparam Type Types provided by the type list.
  69503. * @tparam Op Unary operation as template class with a type member named `type`.
  69504. */
  69505. template<typename... Type, template<typename...> class Op>
  69506. struct type_list_transform<type_list<Type...>, Op> {
  69507. /*! @brief Resulting type list after applying the transform function. */
  69508. // NOLINTNEXTLINE(modernize-type-traits)
  69509. using type = type_list<typename Op<Type>::type...>;
  69510. };
  69511. /**
  69512. * @brief Helper type.
  69513. * @tparam List Type list.
  69514. * @tparam Op Unary operation as template class with a type member named `type`.
  69515. */
  69516. template<typename List, template<typename...> class Op>
  69517. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  69518. /**
  69519. * @brief A class to use to push around lists of constant values, nothing more.
  69520. * @tparam Value Values provided by the value list.
  69521. */
  69522. template<auto... Value>
  69523. struct value_list {
  69524. /*! @brief Value list type. */
  69525. using type = value_list;
  69526. /*! @brief Compile-time number of elements in the value list. */
  69527. static constexpr auto size = sizeof...(Value);
  69528. };
  69529. /*! @brief Primary template isn't defined on purpose. */
  69530. template<std::size_t, typename>
  69531. struct value_list_element;
  69532. /**
  69533. * @brief Provides compile-time indexed access to the values of a value list.
  69534. * @tparam Index Index of the value to return.
  69535. * @tparam Value First value provided by the value list.
  69536. * @tparam Other Other values provided by the value list.
  69537. */
  69538. template<std::size_t Index, auto Value, auto... Other>
  69539. struct value_list_element<Index, value_list<Value, Other...>>
  69540. : value_list_element<Index - 1u, value_list<Other...>> {};
  69541. /**
  69542. * @brief Provides compile-time indexed access to the types of a type list.
  69543. * @tparam Value First value provided by the value list.
  69544. * @tparam Other Other values provided by the value list.
  69545. */
  69546. template<auto Value, auto... Other>
  69547. struct value_list_element<0u, value_list<Value, Other...>> {
  69548. /*! @brief Searched type. */
  69549. using type = decltype(Value);
  69550. /*! @brief Searched value. */
  69551. static constexpr auto value = Value;
  69552. };
  69553. /**
  69554. * @brief Helper type.
  69555. * @tparam Index Index of the type to return.
  69556. * @tparam List Value list to search into.
  69557. */
  69558. template<std::size_t Index, typename List>
  69559. using value_list_element_t = typename value_list_element<Index, List>::type;
  69560. /**
  69561. * @brief Helper type.
  69562. * @tparam Index Index of the value to return.
  69563. * @tparam List Value list to search into.
  69564. */
  69565. template<std::size_t Index, typename List>
  69566. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  69567. /*! @brief Primary template isn't defined on purpose. */
  69568. template<auto, typename>
  69569. struct value_list_index;
  69570. /**
  69571. * @brief Provides compile-time type access to the values of a value list.
  69572. * @tparam Value Value to look for and for which to return the index.
  69573. * @tparam First First value provided by the value list.
  69574. * @tparam Other Other values provided by the value list.
  69575. */
  69576. template<auto Value, auto First, auto... Other>
  69577. struct value_list_index<Value, value_list<First, Other...>> {
  69578. /*! @brief Unsigned integer type. */
  69579. using value_type = std::size_t;
  69580. /*! @brief Compile-time position of the given value in the sublist. */
  69581. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  69582. };
  69583. /**
  69584. * @brief Provides compile-time type access to the values of a value list.
  69585. * @tparam Value Value to look for and for which to return the index.
  69586. * @tparam Other Other values provided by the value list.
  69587. */
  69588. template<auto Value, auto... Other>
  69589. struct value_list_index<Value, value_list<Value, Other...>> {
  69590. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  69591. /*! @brief Unsigned integer type. */
  69592. using value_type = std::size_t;
  69593. /*! @brief Compile-time position of the given value in the sublist. */
  69594. static constexpr value_type value = 0u;
  69595. };
  69596. /**
  69597. * @brief Provides compile-time type access to the values of a value list.
  69598. * @tparam Value Value to look for and for which to return the index.
  69599. */
  69600. template<auto Value>
  69601. struct value_list_index<Value, value_list<>> {
  69602. /*! @brief Unsigned integer type. */
  69603. using value_type = std::size_t;
  69604. /*! @brief Compile-time position of the given type in the sublist. */
  69605. static constexpr value_type value = 0u;
  69606. };
  69607. /**
  69608. * @brief Helper variable template.
  69609. * @tparam List Value list.
  69610. * @tparam Value Value to look for and for which to return the index.
  69611. */
  69612. template<auto Value, typename List>
  69613. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  69614. /**
  69615. * @brief Concatenates multiple value lists.
  69616. * @tparam Value Values provided by the first value list.
  69617. * @tparam Other Values provided by the second value list.
  69618. * @return A value list composed by the values of both the value lists.
  69619. */
  69620. template<auto... Value, auto... Other>
  69621. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  69622. return {};
  69623. }
  69624. /*! @brief Primary template isn't defined on purpose. */
  69625. template<typename...>
  69626. struct value_list_cat;
  69627. /*! @brief Concatenates multiple value lists. */
  69628. template<>
  69629. struct value_list_cat<> {
  69630. /*! @brief A value list composed by the values of all the value lists. */
  69631. using type = value_list<>;
  69632. };
  69633. /**
  69634. * @brief Concatenates multiple value lists.
  69635. * @tparam Value Values provided by the first value list.
  69636. * @tparam Other Values provided by the second value list.
  69637. * @tparam List Other value lists, if any.
  69638. */
  69639. template<auto... Value, auto... Other, typename... List>
  69640. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  69641. /*! @brief A value list composed by the values of all the value lists. */
  69642. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  69643. };
  69644. /**
  69645. * @brief Concatenates multiple value lists.
  69646. * @tparam Value Values provided by the value list.
  69647. */
  69648. template<auto... Value>
  69649. struct value_list_cat<value_list<Value...>> {
  69650. /*! @brief A value list composed by the values of all the value lists. */
  69651. using type = value_list<Value...>;
  69652. };
  69653. /**
  69654. * @brief Helper type.
  69655. * @tparam List Value lists to concatenate.
  69656. */
  69657. template<typename... List>
  69658. using value_list_cat_t = typename value_list_cat<List...>::type;
  69659. /*! @brief Primary template isn't defined on purpose. */
  69660. template<typename>
  69661. struct value_list_unique;
  69662. /**
  69663. * @brief Removes duplicates values from a value list.
  69664. * @tparam Value One of the values provided by the given value list.
  69665. * @tparam Other The other values provided by the given value list.
  69666. */
  69667. template<auto Value, auto... Other>
  69668. struct value_list_unique<value_list<Value, Other...>> {
  69669. /*! @brief A value list without duplicate types. */
  69670. using type = std::conditional_t<
  69671. ((Value == Other) || ...),
  69672. typename value_list_unique<value_list<Other...>>::type,
  69673. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  69674. };
  69675. /*! @brief Removes duplicates values from a value list. */
  69676. template<>
  69677. struct value_list_unique<value_list<>> {
  69678. /*! @brief A value list without duplicate types. */
  69679. using type = value_list<>;
  69680. };
  69681. /**
  69682. * @brief Helper type.
  69683. * @tparam Type A value list.
  69684. */
  69685. template<typename Type>
  69686. using value_list_unique_t = typename value_list_unique<Type>::type;
  69687. /**
  69688. * @brief Provides the member constant `value` to true if a value list contains
  69689. * a given value, false otherwise.
  69690. * @tparam List Value list.
  69691. * @tparam Value Value to look for.
  69692. */
  69693. template<typename List, auto Value>
  69694. struct value_list_contains;
  69695. /**
  69696. * @copybrief value_list_contains
  69697. * @tparam Value Values provided by the value list.
  69698. * @tparam Other Value to look for.
  69699. */
  69700. template<auto... Value, auto Other>
  69701. struct value_list_contains<value_list<Value...>, Other>
  69702. : std::bool_constant<((Value == Other) || ...)> {};
  69703. /**
  69704. * @brief Helper variable template.
  69705. * @tparam List Value list.
  69706. * @tparam Value Value to look for.
  69707. */
  69708. template<typename List, auto Value>
  69709. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  69710. /*! @brief Primary template isn't defined on purpose. */
  69711. template<typename...>
  69712. struct value_list_diff;
  69713. /**
  69714. * @brief Computes the difference between two value lists.
  69715. * @tparam Value Values provided by the first value list.
  69716. * @tparam Other Values provided by the second value list.
  69717. */
  69718. template<auto... Value, auto... Other>
  69719. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  69720. /*! @brief A value list that is the difference between the two value lists. */
  69721. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  69722. };
  69723. /**
  69724. * @brief Helper type.
  69725. * @tparam List Value lists between which to compute the difference.
  69726. */
  69727. template<typename... List>
  69728. using value_list_diff_t = typename value_list_diff<List...>::type;
  69729. /*! @brief Same as std::is_invocable, but with tuples. */
  69730. template<typename, typename>
  69731. struct is_applicable: std::false_type {};
  69732. /**
  69733. * @copybrief is_applicable
  69734. * @tparam Func A valid function type.
  69735. * @tparam Tuple Tuple-like type.
  69736. * @tparam Args The list of arguments to use to probe the function type.
  69737. */
  69738. template<typename Func, template<typename...> class Tuple, typename... Args>
  69739. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  69740. /**
  69741. * @copybrief is_applicable
  69742. * @tparam Func A valid function type.
  69743. * @tparam Tuple Tuple-like type.
  69744. * @tparam Args The list of arguments to use to probe the function type.
  69745. */
  69746. template<typename Func, template<typename...> class Tuple, typename... Args>
  69747. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  69748. /**
  69749. * @brief Helper variable template.
  69750. * @tparam Func A valid function type.
  69751. * @tparam Args The list of arguments to use to probe the function type.
  69752. */
  69753. template<typename Func, typename Args>
  69754. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  69755. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  69756. template<typename, typename, typename>
  69757. struct is_applicable_r: std::false_type {};
  69758. /**
  69759. * @copybrief is_applicable_r
  69760. * @tparam Ret The type to which the return type of the function should be
  69761. * convertible.
  69762. * @tparam Func A valid function type.
  69763. * @tparam Args The list of arguments to use to probe the function type.
  69764. */
  69765. template<typename Ret, typename Func, typename... Args>
  69766. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  69767. /**
  69768. * @brief Helper variable template.
  69769. * @tparam Ret The type to which the return type of the function should be
  69770. * convertible.
  69771. * @tparam Func A valid function type.
  69772. * @tparam Args The list of arguments to use to probe the function type.
  69773. */
  69774. template<typename Ret, typename Func, typename Args>
  69775. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  69776. /**
  69777. * @brief Provides the member constant `value` to true if a given type is
  69778. * complete, false otherwise.
  69779. * @tparam Type The type to test.
  69780. */
  69781. template<typename Type, typename = void>
  69782. struct is_complete: std::false_type {};
  69783. /*! @copydoc is_complete */
  69784. template<typename Type>
  69785. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  69786. /**
  69787. * @brief Helper variable template.
  69788. * @tparam Type The type to test.
  69789. */
  69790. template<typename Type>
  69791. inline constexpr bool is_complete_v = is_complete<Type>::value;
  69792. /**
  69793. * @brief Provides the member constant `value` to true if a given type is an
  69794. * iterator, false otherwise.
  69795. * @tparam Type The type to test.
  69796. */
  69797. template<typename Type, typename = void>
  69798. struct is_iterator: std::false_type {};
  69799. /*! @cond TURN_OFF_DOXYGEN */
  69800. namespace internal {
  69801. template<typename, typename = void>
  69802. struct has_iterator_category: std::false_type {};
  69803. template<typename Type>
  69804. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  69805. } // namespace internal
  69806. /*! @endcond */
  69807. /*! @copydoc is_iterator */
  69808. template<typename Type>
  69809. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  69810. : internal::has_iterator_category<Type> {};
  69811. /**
  69812. * @brief Helper variable template.
  69813. * @tparam Type The type to test.
  69814. */
  69815. template<typename Type>
  69816. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  69817. /**
  69818. * @brief Provides the member constant `value` to true if a given type is both
  69819. * an empty and non-final class, false otherwise.
  69820. * @tparam Type The type to test
  69821. */
  69822. template<typename Type>
  69823. struct is_ebco_eligible
  69824. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  69825. /**
  69826. * @brief Helper variable template.
  69827. * @tparam Type The type to test.
  69828. */
  69829. template<typename Type>
  69830. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  69831. /**
  69832. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  69833. * is valid and denotes a type, false otherwise.
  69834. * @tparam Type The type to test.
  69835. */
  69836. template<typename Type, typename = void>
  69837. struct is_transparent: std::false_type {};
  69838. /*! @copydoc is_transparent */
  69839. template<typename Type>
  69840. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  69841. /**
  69842. * @brief Helper variable template.
  69843. * @tparam Type The type to test.
  69844. */
  69845. template<typename Type>
  69846. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  69847. /*! @cond TURN_OFF_DOXYGEN */
  69848. namespace internal {
  69849. template<typename, typename = void>
  69850. struct has_tuple_size_value: std::false_type {};
  69851. template<typename Type>
  69852. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  69853. template<typename, typename = void>
  69854. struct has_value_type: std::false_type {};
  69855. template<typename Type>
  69856. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  69857. template<typename>
  69858. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  69859. template<typename Type, std::size_t... Index>
  69860. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  69861. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  69862. }
  69863. template<typename>
  69864. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  69865. return false;
  69866. }
  69867. template<typename Type>
  69868. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  69869. return true;
  69870. }
  69871. template<typename Type>
  69872. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  69873. // NOLINTBEGIN(modernize-use-transparent-functors)
  69874. if constexpr(std::is_array_v<Type>) {
  69875. return false;
  69876. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  69877. if constexpr(has_tuple_size_value<Type>::value) {
  69878. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  69879. } else {
  69880. return maybe_equality_comparable<Type>(0);
  69881. }
  69882. } else if constexpr(has_value_type<Type>::value) {
  69883. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  69884. return maybe_equality_comparable<Type>(0);
  69885. } else {
  69886. return false;
  69887. }
  69888. } else {
  69889. return maybe_equality_comparable<Type>(0);
  69890. }
  69891. // NOLINTEND(modernize-use-transparent-functors)
  69892. }
  69893. } // namespace internal
  69894. /*! @endcond */
  69895. /**
  69896. * @brief Provides the member constant `value` to true if a given type is
  69897. * equality comparable, false otherwise.
  69898. * @tparam Type The type to test.
  69899. */
  69900. template<typename Type>
  69901. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  69902. /*! @copydoc is_equality_comparable */
  69903. template<typename Type>
  69904. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  69905. /**
  69906. * @brief Helper variable template.
  69907. * @tparam Type The type to test.
  69908. */
  69909. template<typename Type>
  69910. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  69911. /**
  69912. * @brief Transcribes the constness of a type to another type.
  69913. * @tparam To The type to which to transcribe the constness.
  69914. * @tparam From The type from which to transcribe the constness.
  69915. */
  69916. template<typename To, typename From>
  69917. struct constness_as {
  69918. /*! @brief The type resulting from the transcription of the constness. */
  69919. using type = std::remove_const_t<To>;
  69920. };
  69921. /*! @copydoc constness_as */
  69922. template<typename To, typename From>
  69923. struct constness_as<To, const From> {
  69924. /*! @brief The type resulting from the transcription of the constness. */
  69925. using type = const To;
  69926. };
  69927. /**
  69928. * @brief Alias template to facilitate the transcription of the constness.
  69929. * @tparam To The type to which to transcribe the constness.
  69930. * @tparam From The type from which to transcribe the constness.
  69931. */
  69932. template<typename To, typename From>
  69933. using constness_as_t = typename constness_as<To, From>::type;
  69934. /**
  69935. * @brief Extracts the class of a non-static member object or function.
  69936. * @tparam Member A pointer to a non-static member object or function.
  69937. */
  69938. template<typename Member>
  69939. class member_class {
  69940. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  69941. template<typename Class, typename Ret, typename... Args>
  69942. static Class *clazz(Ret (Class::*)(Args...));
  69943. template<typename Class, typename Ret, typename... Args>
  69944. static Class *clazz(Ret (Class::*)(Args...) const);
  69945. template<typename Class, typename Type>
  69946. static Class *clazz(Type Class::*);
  69947. public:
  69948. /*! @brief The class of the given non-static member object or function. */
  69949. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  69950. };
  69951. /**
  69952. * @brief Helper type.
  69953. * @tparam Member A pointer to a non-static member object or function.
  69954. */
  69955. template<typename Member>
  69956. using member_class_t = typename member_class<Member>::type;
  69957. /**
  69958. * @brief Extracts the n-th argument of a _callable_ type.
  69959. * @tparam Index The index of the argument to extract.
  69960. * @tparam Candidate A valid _callable_ type.
  69961. */
  69962. template<std::size_t Index, typename Candidate>
  69963. class nth_argument {
  69964. template<typename Ret, typename... Args>
  69965. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  69966. template<typename Ret, typename Class, typename... Args>
  69967. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  69968. template<typename Ret, typename Class, typename... Args>
  69969. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  69970. template<typename Type, typename Class>
  69971. static constexpr type_list<Type> pick_up(Type Class ::*);
  69972. template<typename Type>
  69973. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  69974. public:
  69975. /*! @brief N-th argument of the _callable_ type. */
  69976. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  69977. };
  69978. /**
  69979. * @brief Helper type.
  69980. * @tparam Index The index of the argument to extract.
  69981. * @tparam Candidate A valid function, member function or data member type.
  69982. */
  69983. template<std::size_t Index, typename Candidate>
  69984. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  69985. } // namespace entt
  69986. template<typename... Type>
  69987. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  69988. template<std::size_t Index, typename... Type>
  69989. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  69990. template<auto... Value>
  69991. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  69992. template<std::size_t Index, auto... Value>
  69993. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  69994. #endif
  69995. // #include "fwd.hpp"
  69996. #ifndef ENTT_CONTAINER_FWD_HPP
  69997. #define ENTT_CONTAINER_FWD_HPP
  69998. #include <functional>
  69999. #include <memory>
  70000. #include <utility>
  70001. #include <vector>
  70002. namespace entt {
  70003. template<
  70004. typename Key,
  70005. typename Type,
  70006. typename = std::hash<Key>,
  70007. typename = std::equal_to<>,
  70008. typename = std::allocator<std::pair<const Key, Type>>>
  70009. class dense_map;
  70010. template<
  70011. typename Type,
  70012. typename = std::hash<Type>,
  70013. typename = std::equal_to<>,
  70014. typename = std::allocator<Type>>
  70015. class dense_set;
  70016. template<typename...>
  70017. class basic_table;
  70018. /**
  70019. * @brief Alias declaration for the most common use case.
  70020. * @tparam Type Element types.
  70021. */
  70022. template<typename... Type>
  70023. using table = basic_table<std::vector<Type>...>;
  70024. } // namespace entt
  70025. #endif
  70026. namespace entt {
  70027. /*! @cond TURN_OFF_DOXYGEN */
  70028. namespace internal {
  70029. static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  70030. template<typename Key, typename Type>
  70031. struct dense_map_node final {
  70032. using value_type = std::pair<Key, Type>;
  70033. template<typename... Args>
  70034. dense_map_node(const std::size_t pos, Args &&...args)
  70035. : next{pos},
  70036. element{std::forward<Args>(args)...} {}
  70037. template<typename Allocator, typename... Args>
  70038. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  70039. : next{pos},
  70040. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  70041. template<typename Allocator>
  70042. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  70043. : next{other.next},
  70044. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  70045. template<typename Allocator>
  70046. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  70047. : next{other.next},
  70048. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  70049. std::size_t next;
  70050. value_type element;
  70051. };
  70052. template<typename It>
  70053. class dense_map_iterator final {
  70054. template<typename>
  70055. friend class dense_map_iterator;
  70056. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  70057. using second_type = decltype((std::declval<It>()->element.second));
  70058. public:
  70059. using value_type = std::pair<first_type, second_type>;
  70060. using pointer = input_iterator_pointer<value_type>;
  70061. using reference = value_type;
  70062. using difference_type = std::ptrdiff_t;
  70063. using iterator_category = std::input_iterator_tag;
  70064. using iterator_concept = std::random_access_iterator_tag;
  70065. constexpr dense_map_iterator() noexcept
  70066. : it{} {}
  70067. constexpr dense_map_iterator(const It iter) noexcept
  70068. : it{iter} {}
  70069. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  70070. constexpr dense_map_iterator(const dense_map_iterator<Other> &other) noexcept
  70071. : it{other.it} {}
  70072. constexpr dense_map_iterator &operator++() noexcept {
  70073. return ++it, *this;
  70074. }
  70075. constexpr dense_map_iterator operator++(int) noexcept {
  70076. const dense_map_iterator orig = *this;
  70077. return ++(*this), orig;
  70078. }
  70079. constexpr dense_map_iterator &operator--() noexcept {
  70080. return --it, *this;
  70081. }
  70082. constexpr dense_map_iterator operator--(int) noexcept {
  70083. const dense_map_iterator orig = *this;
  70084. return operator--(), orig;
  70085. }
  70086. constexpr dense_map_iterator &operator+=(const difference_type value) noexcept {
  70087. it += value;
  70088. return *this;
  70089. }
  70090. constexpr dense_map_iterator operator+(const difference_type value) const noexcept {
  70091. dense_map_iterator copy = *this;
  70092. return (copy += value);
  70093. }
  70094. constexpr dense_map_iterator &operator-=(const difference_type value) noexcept {
  70095. return (*this += -value);
  70096. }
  70097. constexpr dense_map_iterator operator-(const difference_type value) const noexcept {
  70098. return (*this + -value);
  70099. }
  70100. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  70101. return {it[value].element.first, it[value].element.second};
  70102. }
  70103. [[nodiscard]] constexpr pointer operator->() const noexcept {
  70104. return operator*();
  70105. }
  70106. [[nodiscard]] constexpr reference operator*() const noexcept {
  70107. return operator[](0);
  70108. }
  70109. template<typename Lhs, typename Rhs>
  70110. friend constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  70111. template<typename Lhs, typename Rhs>
  70112. friend constexpr bool operator==(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  70113. template<typename Lhs, typename Rhs>
  70114. friend constexpr bool operator<(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  70115. private:
  70116. It it;
  70117. };
  70118. template<typename Lhs, typename Rhs>
  70119. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  70120. return lhs.it - rhs.it;
  70121. }
  70122. template<typename Lhs, typename Rhs>
  70123. [[nodiscard]] constexpr bool operator==(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  70124. return lhs.it == rhs.it;
  70125. }
  70126. template<typename Lhs, typename Rhs>
  70127. [[nodiscard]] constexpr bool operator!=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  70128. return !(lhs == rhs);
  70129. }
  70130. template<typename Lhs, typename Rhs>
  70131. [[nodiscard]] constexpr bool operator<(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  70132. return lhs.it < rhs.it;
  70133. }
  70134. template<typename Lhs, typename Rhs>
  70135. [[nodiscard]] constexpr bool operator>(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  70136. return rhs < lhs;
  70137. }
  70138. template<typename Lhs, typename Rhs>
  70139. [[nodiscard]] constexpr bool operator<=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  70140. return !(lhs > rhs);
  70141. }
  70142. template<typename Lhs, typename Rhs>
  70143. [[nodiscard]] constexpr bool operator>=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  70144. return !(lhs < rhs);
  70145. }
  70146. template<typename It>
  70147. class dense_map_local_iterator final {
  70148. template<typename>
  70149. friend class dense_map_local_iterator;
  70150. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  70151. using second_type = decltype((std::declval<It>()->element.second));
  70152. public:
  70153. using value_type = std::pair<first_type, second_type>;
  70154. using pointer = input_iterator_pointer<value_type>;
  70155. using reference = value_type;
  70156. using difference_type = std::ptrdiff_t;
  70157. using iterator_category = std::input_iterator_tag;
  70158. using iterator_concept = std::forward_iterator_tag;
  70159. constexpr dense_map_local_iterator() noexcept = default;
  70160. constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept
  70161. : it{iter},
  70162. offset{pos} {}
  70163. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  70164. constexpr dense_map_local_iterator(const dense_map_local_iterator<Other> &other) noexcept
  70165. : it{other.it},
  70166. offset{other.offset} {}
  70167. constexpr dense_map_local_iterator &operator++() noexcept {
  70168. return (offset = it[static_cast<typename It::difference_type>(offset)].next), *this;
  70169. }
  70170. constexpr dense_map_local_iterator operator++(int) noexcept {
  70171. const dense_map_local_iterator orig = *this;
  70172. return ++(*this), orig;
  70173. }
  70174. [[nodiscard]] constexpr pointer operator->() const noexcept {
  70175. return operator*();
  70176. }
  70177. [[nodiscard]] constexpr reference operator*() const noexcept {
  70178. const auto idx = static_cast<typename It::difference_type>(offset);
  70179. return {it[idx].element.first, it[idx].element.second};
  70180. }
  70181. [[nodiscard]] constexpr std::size_t index() const noexcept {
  70182. return offset;
  70183. }
  70184. private:
  70185. It it{};
  70186. std::size_t offset{dense_map_placeholder_position};
  70187. };
  70188. template<typename Lhs, typename Rhs>
  70189. [[nodiscard]] constexpr bool operator==(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  70190. return lhs.index() == rhs.index();
  70191. }
  70192. template<typename Lhs, typename Rhs>
  70193. [[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  70194. return !(lhs == rhs);
  70195. }
  70196. } // namespace internal
  70197. /*! @endcond */
  70198. /**
  70199. * @brief Associative container for key-value pairs with unique keys.
  70200. *
  70201. * Internally, elements are organized into buckets. Which bucket an element is
  70202. * placed into depends entirely on the hash of its key. Keys with the same hash
  70203. * code appear in the same bucket.
  70204. *
  70205. * @tparam Key Key type of the associative container.
  70206. * @tparam Type Mapped type of the associative container.
  70207. * @tparam Hash Type of function to use to hash the keys.
  70208. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  70209. * @tparam Allocator Type of allocator used to manage memory and elements.
  70210. */
  70211. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  70212. class dense_map {
  70213. static constexpr float default_threshold = 0.875f;
  70214. static constexpr std::size_t minimum_capacity = 8u;
  70215. static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position;
  70216. using node_type = internal::dense_map_node<Key, Type>;
  70217. using alloc_traits = std::allocator_traits<Allocator>;
  70218. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  70219. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  70220. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  70221. template<typename Other>
  70222. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept {
  70223. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  70224. return fast_mod(static_cast<size_type>(sparse.second()(key)), bucket_count());
  70225. }
  70226. template<typename Other>
  70227. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) {
  70228. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  70229. if(packed.second()(packed.first()[offset].element.first, key)) {
  70230. return begin() + static_cast<typename iterator::difference_type>(offset);
  70231. }
  70232. }
  70233. return end();
  70234. }
  70235. template<typename Other>
  70236. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const {
  70237. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  70238. if(packed.second()(packed.first()[offset].element.first, key)) {
  70239. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  70240. }
  70241. }
  70242. return cend();
  70243. }
  70244. template<typename Other, typename... Args>
  70245. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  70246. const auto index = key_to_bucket(key);
  70247. if(auto it = constrained_find(key, index); it != end()) {
  70248. return std::make_pair(it, false);
  70249. }
  70250. packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward<Other>(key)), std::forward_as_tuple(std::forward<Args>(args)...));
  70251. sparse.first()[index] = packed.first().size() - 1u;
  70252. rehash_if_required();
  70253. return std::make_pair(--end(), true);
  70254. }
  70255. template<typename Other, typename Arg>
  70256. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  70257. const auto index = key_to_bucket(key);
  70258. if(auto it = constrained_find(key, index); it != end()) {
  70259. it->second = std::forward<Arg>(value);
  70260. return std::make_pair(it, false);
  70261. }
  70262. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  70263. sparse.first()[index] = packed.first().size() - 1u;
  70264. rehash_if_required();
  70265. return std::make_pair(--end(), true);
  70266. }
  70267. void move_and_pop(const std::size_t pos) {
  70268. if(const auto last = size() - 1u; pos != last) {
  70269. size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)];
  70270. packed.first()[pos] = std::move(packed.first().back());
  70271. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  70272. *curr = pos;
  70273. }
  70274. packed.first().pop_back();
  70275. }
  70276. void rehash_if_required() {
  70277. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  70278. rehash(bc * 2u);
  70279. }
  70280. }
  70281. public:
  70282. /*! @brief Allocator type. */
  70283. using allocator_type = Allocator;
  70284. /*! @brief Key type of the container. */
  70285. using key_type = Key;
  70286. /*! @brief Mapped type of the container. */
  70287. using mapped_type = Type;
  70288. /*! @brief Key-value type of the container. */
  70289. using value_type = std::pair<const Key, Type>;
  70290. /*! @brief Unsigned integer type. */
  70291. using size_type = std::size_t;
  70292. /*! @brief Signed integer type. */
  70293. using difference_type = std::ptrdiff_t;
  70294. /*! @brief Type of function to use to hash the keys. */
  70295. using hasher = Hash;
  70296. /*! @brief Type of function to use to compare the keys for equality. */
  70297. using key_equal = KeyEqual;
  70298. /*! @brief Input iterator type. */
  70299. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  70300. /*! @brief Constant input iterator type. */
  70301. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  70302. /*! @brief Input iterator type. */
  70303. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  70304. /*! @brief Constant input iterator type. */
  70305. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  70306. /*! @brief Default constructor. */
  70307. dense_map()
  70308. : dense_map{minimum_capacity} {}
  70309. /**
  70310. * @brief Constructs an empty container with a given allocator.
  70311. * @param allocator The allocator to use.
  70312. */
  70313. explicit dense_map(const allocator_type &allocator)
  70314. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  70315. /**
  70316. * @brief Constructs an empty container with a given allocator and user
  70317. * supplied minimal number of buckets.
  70318. * @param cnt Minimal number of buckets.
  70319. * @param allocator The allocator to use.
  70320. */
  70321. dense_map(const size_type cnt, const allocator_type &allocator)
  70322. : dense_map{cnt, hasher{}, key_equal{}, allocator} {}
  70323. /**
  70324. * @brief Constructs an empty container with a given allocator, hash
  70325. * function and user supplied minimal number of buckets.
  70326. * @param cnt Minimal number of buckets.
  70327. * @param hash Hash function to use.
  70328. * @param allocator The allocator to use.
  70329. */
  70330. dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  70331. : dense_map{cnt, hash, key_equal{}, allocator} {}
  70332. /**
  70333. * @brief Constructs an empty container with a given allocator, hash
  70334. * function, compare function and user supplied minimal number of buckets.
  70335. * @param cnt Minimal number of buckets.
  70336. * @param hash Hash function to use.
  70337. * @param equal Compare function to use.
  70338. * @param allocator The allocator to use.
  70339. */
  70340. explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  70341. : sparse{allocator, hash},
  70342. packed{allocator, equal} {
  70343. rehash(cnt);
  70344. }
  70345. /*! @brief Default copy constructor. */
  70346. dense_map(const dense_map &) = default;
  70347. /**
  70348. * @brief Allocator-extended copy constructor.
  70349. * @param other The instance to copy from.
  70350. * @param allocator The allocator to use.
  70351. */
  70352. dense_map(const dense_map &other, const allocator_type &allocator)
  70353. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  70354. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  70355. threshold{other.threshold} {}
  70356. /*! @brief Default move constructor. */
  70357. dense_map(dense_map &&) noexcept = default;
  70358. /**
  70359. * @brief Allocator-extended move constructor.
  70360. * @param other The instance to move from.
  70361. * @param allocator The allocator to use.
  70362. */
  70363. dense_map(dense_map &&other, const allocator_type &allocator)
  70364. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  70365. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  70366. threshold{other.threshold} {}
  70367. /*! @brief Default destructor. */
  70368. ~dense_map() = default;
  70369. /**
  70370. * @brief Default copy assignment operator.
  70371. * @return This container.
  70372. */
  70373. dense_map &operator=(const dense_map &) = default;
  70374. /**
  70375. * @brief Default move assignment operator.
  70376. * @return This container.
  70377. */
  70378. dense_map &operator=(dense_map &&) noexcept = default;
  70379. /**
  70380. * @brief Exchanges the contents with those of a given container.
  70381. * @param other Container to exchange the content with.
  70382. */
  70383. void swap(dense_map &other) noexcept {
  70384. using std::swap;
  70385. swap(sparse, other.sparse);
  70386. swap(packed, other.packed);
  70387. swap(threshold, other.threshold);
  70388. }
  70389. /**
  70390. * @brief Returns the associated allocator.
  70391. * @return The associated allocator.
  70392. */
  70393. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  70394. return sparse.first().get_allocator();
  70395. }
  70396. /**
  70397. * @brief Returns an iterator to the beginning.
  70398. *
  70399. * If the array is empty, the returned iterator will be equal to `end()`.
  70400. *
  70401. * @return An iterator to the first instance of the internal array.
  70402. */
  70403. [[nodiscard]] const_iterator cbegin() const noexcept {
  70404. return packed.first().begin();
  70405. }
  70406. /*! @copydoc cbegin */
  70407. [[nodiscard]] const_iterator begin() const noexcept {
  70408. return cbegin();
  70409. }
  70410. /*! @copydoc begin */
  70411. [[nodiscard]] iterator begin() noexcept {
  70412. return packed.first().begin();
  70413. }
  70414. /**
  70415. * @brief Returns an iterator to the end.
  70416. * @return An iterator to the element following the last instance of the
  70417. * internal array.
  70418. */
  70419. [[nodiscard]] const_iterator cend() const noexcept {
  70420. return packed.first().end();
  70421. }
  70422. /*! @copydoc cend */
  70423. [[nodiscard]] const_iterator end() const noexcept {
  70424. return cend();
  70425. }
  70426. /*! @copydoc end */
  70427. [[nodiscard]] iterator end() noexcept {
  70428. return packed.first().end();
  70429. }
  70430. /**
  70431. * @brief Checks whether a container is empty.
  70432. * @return True if the container is empty, false otherwise.
  70433. */
  70434. [[nodiscard]] bool empty() const noexcept {
  70435. return packed.first().empty();
  70436. }
  70437. /**
  70438. * @brief Returns the number of elements in a container.
  70439. * @return Number of elements in a container.
  70440. */
  70441. [[nodiscard]] size_type size() const noexcept {
  70442. return packed.first().size();
  70443. }
  70444. /**
  70445. * @brief Returns the maximum possible number of elements.
  70446. * @return Maximum possible number of elements.
  70447. */
  70448. [[nodiscard]] size_type max_size() const noexcept {
  70449. return packed.first().max_size();
  70450. }
  70451. /*! @brief Clears the container. */
  70452. void clear() noexcept {
  70453. sparse.first().clear();
  70454. packed.first().clear();
  70455. rehash(0u);
  70456. }
  70457. /**
  70458. * @brief Inserts an element into the container, if the key does not exist.
  70459. * @param value A key-value pair eventually convertible to the value type.
  70460. * @return A pair consisting of an iterator to the inserted element (or to
  70461. * the element that prevented the insertion) and a bool denoting whether the
  70462. * insertion took place.
  70463. */
  70464. std::pair<iterator, bool> insert(const value_type &value) {
  70465. return insert_or_do_nothing(value.first, value.second);
  70466. }
  70467. /*! @copydoc insert */
  70468. std::pair<iterator, bool> insert(value_type &&value) {
  70469. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  70470. }
  70471. /**
  70472. * @copydoc insert
  70473. * @tparam Arg Type of the key-value pair to insert into the container.
  70474. */
  70475. template<typename Arg>
  70476. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  70477. insert(Arg &&value) {
  70478. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  70479. }
  70480. /**
  70481. * @brief Inserts elements into the container, if their keys do not exist.
  70482. * @tparam It Type of input iterator.
  70483. * @param first An iterator to the first element of the range of elements.
  70484. * @param last An iterator past the last element of the range of elements.
  70485. */
  70486. template<typename It>
  70487. void insert(It first, It last) {
  70488. for(; first != last; ++first) {
  70489. insert(*first);
  70490. }
  70491. }
  70492. /**
  70493. * @brief Inserts an element into the container or assigns to the current
  70494. * element if the key already exists.
  70495. * @tparam Arg Type of the value to insert or assign.
  70496. * @param key A key used both to look up and to insert if not found.
  70497. * @param value A value to insert or assign.
  70498. * @return A pair consisting of an iterator to the element and a bool
  70499. * denoting whether the insertion took place.
  70500. */
  70501. template<typename Arg>
  70502. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  70503. return insert_or_overwrite(key, std::forward<Arg>(value));
  70504. }
  70505. /*! @copydoc insert_or_assign */
  70506. template<typename Arg>
  70507. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  70508. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  70509. }
  70510. /**
  70511. * @brief Constructs an element in-place, if the key does not exist.
  70512. *
  70513. * The element is also constructed when the container already has the key,
  70514. * in which case the newly constructed object is destroyed immediately.
  70515. *
  70516. * @tparam Args Types of arguments to forward to the constructor of the
  70517. * element.
  70518. * @param args Arguments to forward to the constructor of the element.
  70519. * @return A pair consisting of an iterator to the inserted element (or to
  70520. * the element that prevented the insertion) and a bool denoting whether the
  70521. * insertion took place.
  70522. */
  70523. template<typename... Args>
  70524. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  70525. if constexpr(sizeof...(Args) == 0u) {
  70526. return insert_or_do_nothing(key_type{});
  70527. } else if constexpr(sizeof...(Args) == 1u) {
  70528. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  70529. } else if constexpr(sizeof...(Args) == 2u) {
  70530. return insert_or_do_nothing(std::forward<Args>(args)...);
  70531. } else {
  70532. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  70533. const auto index = key_to_bucket(node.element.first);
  70534. if(auto it = constrained_find(node.element.first, index); it != end()) {
  70535. packed.first().pop_back();
  70536. return std::make_pair(it, false);
  70537. }
  70538. std::swap(node.next, sparse.first()[index]);
  70539. rehash_if_required();
  70540. return std::make_pair(--end(), true);
  70541. }
  70542. }
  70543. /**
  70544. * @brief Inserts in-place if the key does not exist, does nothing if the
  70545. * key exists.
  70546. * @tparam Args Types of arguments to forward to the constructor of the
  70547. * element.
  70548. * @param key A key used both to look up and to insert if not found.
  70549. * @param args Arguments to forward to the constructor of the element.
  70550. * @return A pair consisting of an iterator to the inserted element (or to
  70551. * the element that prevented the insertion) and a bool denoting whether the
  70552. * insertion took place.
  70553. */
  70554. template<typename... Args>
  70555. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  70556. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  70557. }
  70558. /*! @copydoc try_emplace */
  70559. template<typename... Args>
  70560. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  70561. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  70562. }
  70563. /**
  70564. * @brief Removes an element from a given position.
  70565. * @param pos An iterator to the element to remove.
  70566. * @return An iterator following the removed element.
  70567. */
  70568. iterator erase(const_iterator pos) {
  70569. const auto diff = pos - cbegin();
  70570. erase(pos->first);
  70571. return begin() + diff;
  70572. }
  70573. /**
  70574. * @brief Removes the given elements from a container.
  70575. * @param first An iterator to the first element of the range of elements.
  70576. * @param last An iterator past the last element of the range of elements.
  70577. * @return An iterator following the last removed element.
  70578. */
  70579. iterator erase(const_iterator first, const_iterator last) {
  70580. const auto dist = first - cbegin();
  70581. for(auto from = last - cbegin(); from != dist; --from) {
  70582. erase(packed.first()[static_cast<size_type>(from) - 1u].element.first);
  70583. }
  70584. return (begin() + dist);
  70585. }
  70586. /**
  70587. * @brief Removes the element associated with a given key.
  70588. * @param key A key value of an element to remove.
  70589. * @return Number of elements removed (either 0 or 1).
  70590. */
  70591. size_type erase(const key_type &key) {
  70592. for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) {
  70593. if(packed.second()(packed.first()[*curr].element.first, key)) {
  70594. const auto index = *curr;
  70595. *curr = packed.first()[*curr].next;
  70596. move_and_pop(index);
  70597. return 1u;
  70598. }
  70599. }
  70600. return 0u;
  70601. }
  70602. /**
  70603. * @brief Accesses a given element with bounds checking.
  70604. * @param key A key of an element to find.
  70605. * @return A reference to the mapped value of the requested element.
  70606. */
  70607. [[nodiscard]] mapped_type &at(const key_type &key) {
  70608. auto it = find(key);
  70609. ENTT_ASSERT(it != end(), "Invalid key");
  70610. return it->second;
  70611. }
  70612. /*! @copydoc at */
  70613. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  70614. auto it = find(key);
  70615. ENTT_ASSERT(it != cend(), "Invalid key");
  70616. return it->second;
  70617. }
  70618. /**
  70619. * @brief Accesses a given element with bounds checking.
  70620. * @tparam Other Type of the key of an element to find.
  70621. * @param key A key of an element to find.
  70622. * @return A reference to the mapped value of the requested element.
  70623. */
  70624. template<typename Other>
  70625. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type const &>>
  70626. at(const Other &key) const {
  70627. auto it = find(key);
  70628. ENTT_ASSERT(it != cend(), "Invalid key");
  70629. return it->second;
  70630. }
  70631. /*! @copydoc at */
  70632. template<typename Other>
  70633. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type &>>
  70634. at(const Other &key) {
  70635. auto it = find(key);
  70636. ENTT_ASSERT(it != end(), "Invalid key");
  70637. return it->second;
  70638. }
  70639. /**
  70640. * @brief Accesses or inserts a given element.
  70641. * @param key A key of an element to find or insert.
  70642. * @return A reference to the mapped value of the requested element.
  70643. */
  70644. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  70645. return insert_or_do_nothing(key).first->second;
  70646. }
  70647. /**
  70648. * @brief Accesses or inserts a given element.
  70649. * @param key A key of an element to find or insert.
  70650. * @return A reference to the mapped value of the requested element.
  70651. */
  70652. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  70653. return insert_or_do_nothing(std::move(key)).first->second;
  70654. }
  70655. /**
  70656. * @brief Returns the number of elements matching a key (either 1 or 0).
  70657. * @param key Key value of an element to search for.
  70658. * @return Number of elements matching the key (either 1 or 0).
  70659. */
  70660. [[nodiscard]] size_type count(const key_type &key) const {
  70661. return find(key) != end();
  70662. }
  70663. /**
  70664. * @brief Returns the number of elements matching a key (either 1 or 0).
  70665. * @tparam Other Type of the key value of an element to search for.
  70666. * @param key Key value of an element to search for.
  70667. * @return Number of elements matching the key (either 1 or 0).
  70668. */
  70669. template<typename Other>
  70670. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  70671. count(const Other &key) const {
  70672. return find(key) != end();
  70673. }
  70674. /**
  70675. * @brief Finds an element with a given key.
  70676. * @param key Key value of an element to search for.
  70677. * @return An iterator to an element with the given key. If no such element
  70678. * is found, a past-the-end iterator is returned.
  70679. */
  70680. [[nodiscard]] iterator find(const key_type &key) {
  70681. return constrained_find(key, key_to_bucket(key));
  70682. }
  70683. /*! @copydoc find */
  70684. [[nodiscard]] const_iterator find(const key_type &key) const {
  70685. return constrained_find(key, key_to_bucket(key));
  70686. }
  70687. /**
  70688. * @brief Finds an element with a key that compares _equivalent_ to a given
  70689. * key.
  70690. * @tparam Other Type of the key value of an element to search for.
  70691. * @param key Key value of an element to search for.
  70692. * @return An iterator to an element with the given key. If no such element
  70693. * is found, a past-the-end iterator is returned.
  70694. */
  70695. template<typename Other>
  70696. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  70697. find(const Other &key) {
  70698. return constrained_find(key, key_to_bucket(key));
  70699. }
  70700. /*! @copydoc find */
  70701. template<typename Other>
  70702. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  70703. find(const Other &key) const {
  70704. return constrained_find(key, key_to_bucket(key));
  70705. }
  70706. /**
  70707. * @brief Returns a range containing all elements with a given key.
  70708. * @param key Key value of an element to search for.
  70709. * @return A pair of iterators pointing to the first element and past the
  70710. * last element of the range.
  70711. */
  70712. [[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
  70713. const auto it = find(key);
  70714. return {it, it + !(it == end())};
  70715. }
  70716. /*! @copydoc equal_range */
  70717. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
  70718. const auto it = find(key);
  70719. return {it, it + !(it == cend())};
  70720. }
  70721. /**
  70722. * @brief Returns a range containing all elements that compare _equivalent_
  70723. * to a given key.
  70724. * @tparam Other Type of an element to search for.
  70725. * @param key Key value of an element to search for.
  70726. * @return A pair of iterators pointing to the first element and past the
  70727. * last element of the range.
  70728. */
  70729. template<typename Other>
  70730. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  70731. equal_range(const Other &key) {
  70732. const auto it = find(key);
  70733. return {it, it + !(it == end())};
  70734. }
  70735. /*! @copydoc equal_range */
  70736. template<typename Other>
  70737. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  70738. equal_range(const Other &key) const {
  70739. const auto it = find(key);
  70740. return {it, it + !(it == cend())};
  70741. }
  70742. /**
  70743. * @brief Checks if the container contains an element with a given key.
  70744. * @param key Key value of an element to search for.
  70745. * @return True if there is such an element, false otherwise.
  70746. */
  70747. [[nodiscard]] bool contains(const key_type &key) const {
  70748. return (find(key) != cend());
  70749. }
  70750. /**
  70751. * @brief Checks if the container contains an element with a key that
  70752. * compares _equivalent_ to a given value.
  70753. * @tparam Other Type of the key value of an element to search for.
  70754. * @param key Key value of an element to search for.
  70755. * @return True if there is such an element, false otherwise.
  70756. */
  70757. template<typename Other>
  70758. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  70759. contains(const Other &key) const {
  70760. return (find(key) != cend());
  70761. }
  70762. /**
  70763. * @brief Returns an iterator to the beginning of a given bucket.
  70764. * @param index An index of a bucket to access.
  70765. * @return An iterator to the beginning of the given bucket.
  70766. */
  70767. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  70768. return {packed.first().begin(), sparse.first()[index]};
  70769. }
  70770. /**
  70771. * @brief Returns an iterator to the beginning of a given bucket.
  70772. * @param index An index of a bucket to access.
  70773. * @return An iterator to the beginning of the given bucket.
  70774. */
  70775. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  70776. return cbegin(index);
  70777. }
  70778. /**
  70779. * @brief Returns an iterator to the beginning of a given bucket.
  70780. * @param index An index of a bucket to access.
  70781. * @return An iterator to the beginning of the given bucket.
  70782. */
  70783. [[nodiscard]] local_iterator begin(const size_type index) {
  70784. return {packed.first().begin(), sparse.first()[index]};
  70785. }
  70786. /**
  70787. * @brief Returns an iterator to the end of a given bucket.
  70788. * @param index An index of a bucket to access.
  70789. * @return An iterator to the end of the given bucket.
  70790. */
  70791. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  70792. return {};
  70793. }
  70794. /**
  70795. * @brief Returns an iterator to the end of a given bucket.
  70796. * @param index An index of a bucket to access.
  70797. * @return An iterator to the end of the given bucket.
  70798. */
  70799. [[nodiscard]] const_local_iterator end(const size_type index) const {
  70800. return cend(index);
  70801. }
  70802. /**
  70803. * @brief Returns an iterator to the end of a given bucket.
  70804. * @param index An index of a bucket to access.
  70805. * @return An iterator to the end of the given bucket.
  70806. */
  70807. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  70808. return {};
  70809. }
  70810. /**
  70811. * @brief Returns the number of buckets.
  70812. * @return The number of buckets.
  70813. */
  70814. [[nodiscard]] size_type bucket_count() const {
  70815. return sparse.first().size();
  70816. }
  70817. /**
  70818. * @brief Returns the maximum number of buckets.
  70819. * @return The maximum number of buckets.
  70820. */
  70821. [[nodiscard]] size_type max_bucket_count() const {
  70822. return sparse.first().max_size();
  70823. }
  70824. /**
  70825. * @brief Returns the number of elements in a given bucket.
  70826. * @param index The index of the bucket to examine.
  70827. * @return The number of elements in the given bucket.
  70828. */
  70829. [[nodiscard]] size_type bucket_size(const size_type index) const {
  70830. return static_cast<size_type>(std::distance(begin(index), end(index)));
  70831. }
  70832. /**
  70833. * @brief Returns the bucket for a given key.
  70834. * @param key The value of the key to examine.
  70835. * @return The bucket for the given key.
  70836. */
  70837. [[nodiscard]] size_type bucket(const key_type &key) const {
  70838. return key_to_bucket(key);
  70839. }
  70840. /**
  70841. * @brief Returns the average number of elements per bucket.
  70842. * @return The average number of elements per bucket.
  70843. */
  70844. [[nodiscard]] float load_factor() const {
  70845. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  70846. }
  70847. /**
  70848. * @brief Returns the maximum average number of elements per bucket.
  70849. * @return The maximum average number of elements per bucket.
  70850. */
  70851. [[nodiscard]] float max_load_factor() const {
  70852. return threshold;
  70853. }
  70854. /**
  70855. * @brief Sets the desired maximum average number of elements per bucket.
  70856. * @param value A desired maximum average number of elements per bucket.
  70857. */
  70858. void max_load_factor(const float value) {
  70859. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  70860. threshold = value;
  70861. rehash(0u);
  70862. }
  70863. /**
  70864. * @brief Reserves at least the specified number of buckets and regenerates
  70865. * the hash table.
  70866. * @param cnt New number of buckets.
  70867. */
  70868. void rehash(const size_type cnt) {
  70869. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  70870. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  70871. value = value > cap ? value : cap;
  70872. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  70873. sparse.first().resize(sz);
  70874. for(auto &&elem: sparse.first()) {
  70875. elem = placeholder_position;
  70876. }
  70877. for(size_type pos{}, last = size(); pos < last; ++pos) {
  70878. const auto index = key_to_bucket(packed.first()[pos].element.first);
  70879. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  70880. }
  70881. }
  70882. }
  70883. /**
  70884. * @brief Reserves space for at least the specified number of elements and
  70885. * regenerates the hash table.
  70886. * @param cnt New number of elements.
  70887. */
  70888. void reserve(const size_type cnt) {
  70889. packed.first().reserve(cnt);
  70890. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  70891. }
  70892. /**
  70893. * @brief Returns the function used to hash the keys.
  70894. * @return The function used to hash the keys.
  70895. */
  70896. [[nodiscard]] hasher hash_function() const {
  70897. return sparse.second();
  70898. }
  70899. /**
  70900. * @brief Returns the function used to compare keys for equality.
  70901. * @return The function used to compare keys for equality.
  70902. */
  70903. [[nodiscard]] key_equal key_eq() const {
  70904. return packed.second();
  70905. }
  70906. private:
  70907. compressed_pair<sparse_container_type, hasher> sparse;
  70908. compressed_pair<packed_container_type, key_equal> packed;
  70909. float threshold{default_threshold};
  70910. };
  70911. } // namespace entt
  70912. /*! @cond TURN_OFF_DOXYGEN */
  70913. namespace std {
  70914. template<typename Key, typename Value, typename Allocator>
  70915. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  70916. : std::true_type {};
  70917. } // namespace std
  70918. /*! @endcond */
  70919. #endif
  70920. // #include "../core/compressed_pair.hpp"
  70921. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  70922. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  70923. #include <cstddef>
  70924. #include <tuple>
  70925. #include <type_traits>
  70926. #include <utility>
  70927. // #include "fwd.hpp"
  70928. #ifndef ENTT_CORE_FWD_HPP
  70929. #define ENTT_CORE_FWD_HPP
  70930. #include <cstddef>
  70931. #include <cstdint>
  70932. // #include "../config/config.h"
  70933. #ifndef ENTT_CONFIG_CONFIG_H
  70934. #define ENTT_CONFIG_CONFIG_H
  70935. // #include "version.h"
  70936. #ifndef ENTT_CONFIG_VERSION_H
  70937. #define ENTT_CONFIG_VERSION_H
  70938. // #include "macro.h"
  70939. #ifndef ENTT_CONFIG_MACRO_H
  70940. #define ENTT_CONFIG_MACRO_H
  70941. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  70942. #define ENTT_STR(arg) #arg
  70943. #define ENTT_XSTR(arg) ENTT_STR(arg)
  70944. // NOLINTEND(cppcoreguidelines-macro-usage)
  70945. #endif
  70946. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  70947. #define ENTT_VERSION_MAJOR 3
  70948. #define ENTT_VERSION_MINOR 16
  70949. #define ENTT_VERSION_PATCH 0
  70950. #define ENTT_VERSION \
  70951. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  70952. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  70953. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  70954. #endif
  70955. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  70956. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  70957. # define ENTT_CONSTEXPR
  70958. # define ENTT_THROW throw
  70959. # define ENTT_TRY try
  70960. # define ENTT_CATCH catch(...)
  70961. #else
  70962. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  70963. # define ENTT_THROW
  70964. # define ENTT_TRY if(true)
  70965. # define ENTT_CATCH if(false)
  70966. #endif
  70967. #if __has_include(<version>)
  70968. # include <version>
  70969. #
  70970. # if defined(__cpp_consteval)
  70971. # define ENTT_CONSTEVAL consteval
  70972. # endif
  70973. #endif
  70974. #ifndef ENTT_CONSTEVAL
  70975. # define ENTT_CONSTEVAL constexpr
  70976. #endif
  70977. #ifdef ENTT_USE_ATOMIC
  70978. # include <atomic>
  70979. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  70980. #else
  70981. # define ENTT_MAYBE_ATOMIC(Type) Type
  70982. #endif
  70983. #ifndef ENTT_ID_TYPE
  70984. # include <cstdint>
  70985. # define ENTT_ID_TYPE std::uint32_t
  70986. #else
  70987. # include <cstdint> // provides coverage for types in the std namespace
  70988. #endif
  70989. #ifndef ENTT_SPARSE_PAGE
  70990. # define ENTT_SPARSE_PAGE 4096
  70991. #endif
  70992. #ifndef ENTT_PACKED_PAGE
  70993. # define ENTT_PACKED_PAGE 1024
  70994. #endif
  70995. #ifdef ENTT_DISABLE_ASSERT
  70996. # undef ENTT_ASSERT
  70997. # define ENTT_ASSERT(condition, msg) (void(0))
  70998. #elif !defined ENTT_ASSERT
  70999. # include <cassert>
  71000. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  71001. #endif
  71002. #ifdef ENTT_DISABLE_ASSERT
  71003. # undef ENTT_ASSERT_CONSTEXPR
  71004. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  71005. #elif !defined ENTT_ASSERT_CONSTEXPR
  71006. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  71007. #endif
  71008. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  71009. #ifdef ENTT_NO_ETO
  71010. # define ENTT_ETO_TYPE(Type) void
  71011. #else
  71012. # define ENTT_ETO_TYPE(Type) Type
  71013. #endif
  71014. #ifdef ENTT_NO_MIXIN
  71015. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  71016. #else
  71017. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  71018. #endif
  71019. #ifdef ENTT_STANDARD_CPP
  71020. # define ENTT_NONSTD false
  71021. #else
  71022. # define ENTT_NONSTD true
  71023. # if defined __clang__ || defined __GNUC__
  71024. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  71025. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  71026. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  71027. # elif defined _MSC_VER
  71028. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  71029. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  71030. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  71031. # endif
  71032. #endif
  71033. #ifndef ENTT_EXPORT
  71034. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  71035. # define ENTT_EXPORT __declspec(dllexport)
  71036. # define ENTT_IMPORT __declspec(dllimport)
  71037. # define ENTT_HIDDEN
  71038. # elif defined __GNUC__ && __GNUC__ >= 4
  71039. # define ENTT_EXPORT __attribute__((visibility("default")))
  71040. # define ENTT_IMPORT __attribute__((visibility("default")))
  71041. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  71042. # else /* Unsupported compiler */
  71043. # define ENTT_EXPORT
  71044. # define ENTT_IMPORT
  71045. # define ENTT_HIDDEN
  71046. # endif
  71047. #endif
  71048. #ifndef ENTT_API
  71049. # if defined ENTT_API_EXPORT
  71050. # define ENTT_API ENTT_EXPORT
  71051. # elif defined ENTT_API_IMPORT
  71052. # define ENTT_API ENTT_IMPORT
  71053. # else /* No API */
  71054. # define ENTT_API
  71055. # endif
  71056. #endif
  71057. #if defined _MSC_VER
  71058. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  71059. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  71060. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  71061. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  71062. #endif
  71063. // NOLINTEND(cppcoreguidelines-macro-usage)
  71064. #endif
  71065. namespace entt {
  71066. /*! @brief Possible modes of an any object. */
  71067. enum class any_policy : std::uint8_t {
  71068. /*! @brief Default mode, no element available. */
  71069. empty,
  71070. /*! @brief Owning mode, dynamically allocated element. */
  71071. dynamic,
  71072. /*! @brief Owning mode, embedded element. */
  71073. embedded,
  71074. /*! @brief Aliasing mode, non-const reference. */
  71075. ref,
  71076. /*! @brief Const aliasing mode, const reference. */
  71077. cref
  71078. };
  71079. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  71080. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  71081. class basic_any;
  71082. /*! @brief Alias declaration for type identifiers. */
  71083. using id_type = ENTT_ID_TYPE;
  71084. /*! @brief Alias declaration for the most common use case. */
  71085. using any = basic_any<>;
  71086. template<typename, typename>
  71087. class compressed_pair;
  71088. template<typename>
  71089. class basic_hashed_string;
  71090. /*! @brief Aliases for common character types. */
  71091. using hashed_string = basic_hashed_string<char>;
  71092. /*! @brief Aliases for common character types. */
  71093. using hashed_wstring = basic_hashed_string<wchar_t>;
  71094. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  71095. struct type_info;
  71096. } // namespace entt
  71097. #endif
  71098. // #include "type_traits.hpp"
  71099. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  71100. #define ENTT_CORE_TYPE_TRAITS_HPP
  71101. #include <cstddef>
  71102. #include <iterator>
  71103. #include <tuple>
  71104. #include <type_traits>
  71105. #include <utility>
  71106. // #include "../config/config.h"
  71107. // #include "fwd.hpp"
  71108. namespace entt {
  71109. /**
  71110. * @brief Utility class to disambiguate overloaded functions.
  71111. * @tparam N Number of choices available.
  71112. */
  71113. template<std::size_t N>
  71114. struct choice_t
  71115. // unfortunately, doxygen cannot parse such a construct
  71116. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  71117. {};
  71118. /*! @copybrief choice_t */
  71119. template<>
  71120. struct choice_t<0> {};
  71121. /**
  71122. * @brief Variable template for the choice trick.
  71123. * @tparam N Number of choices available.
  71124. */
  71125. template<std::size_t N>
  71126. inline constexpr choice_t<N> choice{};
  71127. /**
  71128. * @brief Identity type trait.
  71129. *
  71130. * Useful to establish non-deduced contexts in template argument deduction
  71131. * (waiting for C++20) or to provide types through function arguments.
  71132. *
  71133. * @tparam Type A type.
  71134. */
  71135. template<typename Type>
  71136. struct type_identity {
  71137. /*! @brief Identity type. */
  71138. using type = Type;
  71139. };
  71140. /**
  71141. * @brief Helper type.
  71142. * @tparam Type A type.
  71143. */
  71144. template<typename Type>
  71145. using type_identity_t = typename type_identity<Type>::type;
  71146. /**
  71147. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  71148. * @tparam Type The type of which to return the size.
  71149. */
  71150. template<typename Type, typename = void>
  71151. struct size_of: std::integral_constant<std::size_t, 0u> {};
  71152. /*! @copydoc size_of */
  71153. template<typename Type>
  71154. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  71155. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  71156. : std::integral_constant<std::size_t, sizeof(Type)> {};
  71157. /**
  71158. * @brief Helper variable template.
  71159. * @tparam Type The type of which to return the size.
  71160. */
  71161. template<typename Type>
  71162. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  71163. /**
  71164. * @brief Using declaration to be used to _repeat_ the same type a number of
  71165. * times equal to the size of a given parameter pack.
  71166. * @tparam Type A type to repeat.
  71167. */
  71168. template<typename Type, typename>
  71169. using unpack_as_type = Type;
  71170. /**
  71171. * @brief Helper variable template to be used to _repeat_ the same value a
  71172. * number of times equal to the size of a given parameter pack.
  71173. * @tparam Value A value to repeat.
  71174. */
  71175. template<auto Value, typename>
  71176. inline constexpr auto unpack_as_value = Value;
  71177. /**
  71178. * @brief Wraps a static constant.
  71179. * @tparam Value A static constant.
  71180. */
  71181. template<auto Value>
  71182. using integral_constant = std::integral_constant<decltype(Value), Value>;
  71183. /**
  71184. * @brief Alias template to facilitate the creation of named values.
  71185. * @tparam Value A constant value at least convertible to `id_type`.
  71186. */
  71187. template<id_type Value>
  71188. using tag = integral_constant<Value>;
  71189. /**
  71190. * @brief A class to use to push around lists of types, nothing more.
  71191. * @tparam Type Types provided by the type list.
  71192. */
  71193. template<typename... Type>
  71194. struct type_list {
  71195. /*! @brief Type list type. */
  71196. using type = type_list;
  71197. /*! @brief Compile-time number of elements in the type list. */
  71198. static constexpr auto size = sizeof...(Type);
  71199. };
  71200. /*! @brief Primary template isn't defined on purpose. */
  71201. template<std::size_t, typename>
  71202. struct type_list_element;
  71203. /**
  71204. * @brief Provides compile-time indexed access to the types of a type list.
  71205. * @tparam Index Index of the type to return.
  71206. * @tparam First First type provided by the type list.
  71207. * @tparam Other Other types provided by the type list.
  71208. */
  71209. template<std::size_t Index, typename First, typename... Other>
  71210. struct type_list_element<Index, type_list<First, Other...>>
  71211. : type_list_element<Index - 1u, type_list<Other...>> {};
  71212. /**
  71213. * @brief Provides compile-time indexed access to the types of a type list.
  71214. * @tparam First First type provided by the type list.
  71215. * @tparam Other Other types provided by the type list.
  71216. */
  71217. template<typename First, typename... Other>
  71218. struct type_list_element<0u, type_list<First, Other...>> {
  71219. /*! @brief Searched type. */
  71220. using type = First;
  71221. };
  71222. /**
  71223. * @brief Helper type.
  71224. * @tparam Index Index of the type to return.
  71225. * @tparam List Type list to search into.
  71226. */
  71227. template<std::size_t Index, typename List>
  71228. using type_list_element_t = typename type_list_element<Index, List>::type;
  71229. /*! @brief Primary template isn't defined on purpose. */
  71230. template<typename, typename>
  71231. struct type_list_index;
  71232. /**
  71233. * @brief Provides compile-time type access to the types of a type list.
  71234. * @tparam Type Type to look for and for which to return the index.
  71235. * @tparam First First type provided by the type list.
  71236. * @tparam Other Other types provided by the type list.
  71237. */
  71238. template<typename Type, typename First, typename... Other>
  71239. struct type_list_index<Type, type_list<First, Other...>> {
  71240. /*! @brief Unsigned integer type. */
  71241. using value_type = std::size_t;
  71242. /*! @brief Compile-time position of the given type in the sublist. */
  71243. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  71244. };
  71245. /**
  71246. * @brief Provides compile-time type access to the types of a type list.
  71247. * @tparam Type Type to look for and for which to return the index.
  71248. * @tparam Other Other types provided by the type list.
  71249. */
  71250. template<typename Type, typename... Other>
  71251. struct type_list_index<Type, type_list<Type, Other...>> {
  71252. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  71253. /*! @brief Unsigned integer type. */
  71254. using value_type = std::size_t;
  71255. /*! @brief Compile-time position of the given type in the sublist. */
  71256. static constexpr value_type value = 0u;
  71257. };
  71258. /**
  71259. * @brief Provides compile-time type access to the types of a type list.
  71260. * @tparam Type Type to look for and for which to return the index.
  71261. */
  71262. template<typename Type>
  71263. struct type_list_index<Type, type_list<>> {
  71264. /*! @brief Unsigned integer type. */
  71265. using value_type = std::size_t;
  71266. /*! @brief Compile-time position of the given type in the sublist. */
  71267. static constexpr value_type value = 0u;
  71268. };
  71269. /**
  71270. * @brief Helper variable template.
  71271. * @tparam List Type list.
  71272. * @tparam Type Type to look for and for which to return the index.
  71273. */
  71274. template<typename Type, typename List>
  71275. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  71276. /**
  71277. * @brief Concatenates multiple type lists.
  71278. * @tparam Type Types provided by the first type list.
  71279. * @tparam Other Types provided by the second type list.
  71280. * @return A type list composed by the types of both the type lists.
  71281. */
  71282. template<typename... Type, typename... Other>
  71283. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  71284. return {};
  71285. }
  71286. /*! @brief Primary template isn't defined on purpose. */
  71287. template<typename...>
  71288. struct type_list_cat;
  71289. /*! @brief Concatenates multiple type lists. */
  71290. template<>
  71291. struct type_list_cat<> {
  71292. /*! @brief A type list composed by the types of all the type lists. */
  71293. using type = type_list<>;
  71294. };
  71295. /**
  71296. * @brief Concatenates multiple type lists.
  71297. * @tparam Type Types provided by the first type list.
  71298. * @tparam Other Types provided by the second type list.
  71299. * @tparam List Other type lists, if any.
  71300. */
  71301. template<typename... Type, typename... Other, typename... List>
  71302. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  71303. /*! @brief A type list composed by the types of all the type lists. */
  71304. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  71305. };
  71306. /**
  71307. * @brief Concatenates multiple type lists.
  71308. * @tparam Type Types provided by the type list.
  71309. */
  71310. template<typename... Type>
  71311. struct type_list_cat<type_list<Type...>> {
  71312. /*! @brief A type list composed by the types of all the type lists. */
  71313. using type = type_list<Type...>;
  71314. };
  71315. /**
  71316. * @brief Helper type.
  71317. * @tparam List Type lists to concatenate.
  71318. */
  71319. template<typename... List>
  71320. using type_list_cat_t = typename type_list_cat<List...>::type;
  71321. /*! @cond TURN_OFF_DOXYGEN */
  71322. namespace internal {
  71323. template<typename...>
  71324. struct type_list_unique;
  71325. template<typename First, typename... Other, typename... Type>
  71326. struct type_list_unique<type_list<First, Other...>, Type...>
  71327. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  71328. template<typename... Type>
  71329. struct type_list_unique<type_list<>, Type...> {
  71330. using type = type_list<Type...>;
  71331. };
  71332. } // namespace internal
  71333. /*! @endcond */
  71334. /**
  71335. * @brief Removes duplicates types from a type list.
  71336. * @tparam List Type list.
  71337. */
  71338. template<typename List>
  71339. struct type_list_unique {
  71340. /*! @brief A type list without duplicate types. */
  71341. using type = typename internal::type_list_unique<List>::type;
  71342. };
  71343. /**
  71344. * @brief Helper type.
  71345. * @tparam List Type list.
  71346. */
  71347. template<typename List>
  71348. using type_list_unique_t = typename type_list_unique<List>::type;
  71349. /**
  71350. * @brief Provides the member constant `value` to true if a type list contains a
  71351. * given type, false otherwise.
  71352. * @tparam List Type list.
  71353. * @tparam Type Type to look for.
  71354. */
  71355. template<typename List, typename Type>
  71356. struct type_list_contains;
  71357. /**
  71358. * @copybrief type_list_contains
  71359. * @tparam Type Types provided by the type list.
  71360. * @tparam Other Type to look for.
  71361. */
  71362. template<typename... Type, typename Other>
  71363. struct type_list_contains<type_list<Type...>, Other>
  71364. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  71365. /**
  71366. * @brief Helper variable template.
  71367. * @tparam List Type list.
  71368. * @tparam Type Type to look for.
  71369. */
  71370. template<typename List, typename Type>
  71371. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  71372. /*! @brief Primary template isn't defined on purpose. */
  71373. template<typename...>
  71374. struct type_list_diff;
  71375. /**
  71376. * @brief Computes the difference between two type lists.
  71377. * @tparam Type Types provided by the first type list.
  71378. * @tparam Other Types provided by the second type list.
  71379. */
  71380. template<typename... Type, typename... Other>
  71381. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  71382. /*! @brief A type list that is the difference between the two type lists. */
  71383. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  71384. };
  71385. /**
  71386. * @brief Helper type.
  71387. * @tparam List Type lists between which to compute the difference.
  71388. */
  71389. template<typename... List>
  71390. using type_list_diff_t = typename type_list_diff<List...>::type;
  71391. /*! @brief Primary template isn't defined on purpose. */
  71392. template<typename, template<typename...> class>
  71393. struct type_list_transform;
  71394. /**
  71395. * @brief Applies a given _function_ to a type list and generate a new list.
  71396. * @tparam Type Types provided by the type list.
  71397. * @tparam Op Unary operation as template class with a type member named `type`.
  71398. */
  71399. template<typename... Type, template<typename...> class Op>
  71400. struct type_list_transform<type_list<Type...>, Op> {
  71401. /*! @brief Resulting type list after applying the transform function. */
  71402. // NOLINTNEXTLINE(modernize-type-traits)
  71403. using type = type_list<typename Op<Type>::type...>;
  71404. };
  71405. /**
  71406. * @brief Helper type.
  71407. * @tparam List Type list.
  71408. * @tparam Op Unary operation as template class with a type member named `type`.
  71409. */
  71410. template<typename List, template<typename...> class Op>
  71411. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  71412. /**
  71413. * @brief A class to use to push around lists of constant values, nothing more.
  71414. * @tparam Value Values provided by the value list.
  71415. */
  71416. template<auto... Value>
  71417. struct value_list {
  71418. /*! @brief Value list type. */
  71419. using type = value_list;
  71420. /*! @brief Compile-time number of elements in the value list. */
  71421. static constexpr auto size = sizeof...(Value);
  71422. };
  71423. /*! @brief Primary template isn't defined on purpose. */
  71424. template<std::size_t, typename>
  71425. struct value_list_element;
  71426. /**
  71427. * @brief Provides compile-time indexed access to the values of a value list.
  71428. * @tparam Index Index of the value to return.
  71429. * @tparam Value First value provided by the value list.
  71430. * @tparam Other Other values provided by the value list.
  71431. */
  71432. template<std::size_t Index, auto Value, auto... Other>
  71433. struct value_list_element<Index, value_list<Value, Other...>>
  71434. : value_list_element<Index - 1u, value_list<Other...>> {};
  71435. /**
  71436. * @brief Provides compile-time indexed access to the types of a type list.
  71437. * @tparam Value First value provided by the value list.
  71438. * @tparam Other Other values provided by the value list.
  71439. */
  71440. template<auto Value, auto... Other>
  71441. struct value_list_element<0u, value_list<Value, Other...>> {
  71442. /*! @brief Searched type. */
  71443. using type = decltype(Value);
  71444. /*! @brief Searched value. */
  71445. static constexpr auto value = Value;
  71446. };
  71447. /**
  71448. * @brief Helper type.
  71449. * @tparam Index Index of the type to return.
  71450. * @tparam List Value list to search into.
  71451. */
  71452. template<std::size_t Index, typename List>
  71453. using value_list_element_t = typename value_list_element<Index, List>::type;
  71454. /**
  71455. * @brief Helper type.
  71456. * @tparam Index Index of the value to return.
  71457. * @tparam List Value list to search into.
  71458. */
  71459. template<std::size_t Index, typename List>
  71460. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  71461. /*! @brief Primary template isn't defined on purpose. */
  71462. template<auto, typename>
  71463. struct value_list_index;
  71464. /**
  71465. * @brief Provides compile-time type access to the values of a value list.
  71466. * @tparam Value Value to look for and for which to return the index.
  71467. * @tparam First First value provided by the value list.
  71468. * @tparam Other Other values provided by the value list.
  71469. */
  71470. template<auto Value, auto First, auto... Other>
  71471. struct value_list_index<Value, value_list<First, Other...>> {
  71472. /*! @brief Unsigned integer type. */
  71473. using value_type = std::size_t;
  71474. /*! @brief Compile-time position of the given value in the sublist. */
  71475. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  71476. };
  71477. /**
  71478. * @brief Provides compile-time type access to the values of a value list.
  71479. * @tparam Value Value to look for and for which to return the index.
  71480. * @tparam Other Other values provided by the value list.
  71481. */
  71482. template<auto Value, auto... Other>
  71483. struct value_list_index<Value, value_list<Value, Other...>> {
  71484. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  71485. /*! @brief Unsigned integer type. */
  71486. using value_type = std::size_t;
  71487. /*! @brief Compile-time position of the given value in the sublist. */
  71488. static constexpr value_type value = 0u;
  71489. };
  71490. /**
  71491. * @brief Provides compile-time type access to the values of a value list.
  71492. * @tparam Value Value to look for and for which to return the index.
  71493. */
  71494. template<auto Value>
  71495. struct value_list_index<Value, value_list<>> {
  71496. /*! @brief Unsigned integer type. */
  71497. using value_type = std::size_t;
  71498. /*! @brief Compile-time position of the given type in the sublist. */
  71499. static constexpr value_type value = 0u;
  71500. };
  71501. /**
  71502. * @brief Helper variable template.
  71503. * @tparam List Value list.
  71504. * @tparam Value Value to look for and for which to return the index.
  71505. */
  71506. template<auto Value, typename List>
  71507. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  71508. /**
  71509. * @brief Concatenates multiple value lists.
  71510. * @tparam Value Values provided by the first value list.
  71511. * @tparam Other Values provided by the second value list.
  71512. * @return A value list composed by the values of both the value lists.
  71513. */
  71514. template<auto... Value, auto... Other>
  71515. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  71516. return {};
  71517. }
  71518. /*! @brief Primary template isn't defined on purpose. */
  71519. template<typename...>
  71520. struct value_list_cat;
  71521. /*! @brief Concatenates multiple value lists. */
  71522. template<>
  71523. struct value_list_cat<> {
  71524. /*! @brief A value list composed by the values of all the value lists. */
  71525. using type = value_list<>;
  71526. };
  71527. /**
  71528. * @brief Concatenates multiple value lists.
  71529. * @tparam Value Values provided by the first value list.
  71530. * @tparam Other Values provided by the second value list.
  71531. * @tparam List Other value lists, if any.
  71532. */
  71533. template<auto... Value, auto... Other, typename... List>
  71534. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  71535. /*! @brief A value list composed by the values of all the value lists. */
  71536. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  71537. };
  71538. /**
  71539. * @brief Concatenates multiple value lists.
  71540. * @tparam Value Values provided by the value list.
  71541. */
  71542. template<auto... Value>
  71543. struct value_list_cat<value_list<Value...>> {
  71544. /*! @brief A value list composed by the values of all the value lists. */
  71545. using type = value_list<Value...>;
  71546. };
  71547. /**
  71548. * @brief Helper type.
  71549. * @tparam List Value lists to concatenate.
  71550. */
  71551. template<typename... List>
  71552. using value_list_cat_t = typename value_list_cat<List...>::type;
  71553. /*! @brief Primary template isn't defined on purpose. */
  71554. template<typename>
  71555. struct value_list_unique;
  71556. /**
  71557. * @brief Removes duplicates values from a value list.
  71558. * @tparam Value One of the values provided by the given value list.
  71559. * @tparam Other The other values provided by the given value list.
  71560. */
  71561. template<auto Value, auto... Other>
  71562. struct value_list_unique<value_list<Value, Other...>> {
  71563. /*! @brief A value list without duplicate types. */
  71564. using type = std::conditional_t<
  71565. ((Value == Other) || ...),
  71566. typename value_list_unique<value_list<Other...>>::type,
  71567. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  71568. };
  71569. /*! @brief Removes duplicates values from a value list. */
  71570. template<>
  71571. struct value_list_unique<value_list<>> {
  71572. /*! @brief A value list without duplicate types. */
  71573. using type = value_list<>;
  71574. };
  71575. /**
  71576. * @brief Helper type.
  71577. * @tparam Type A value list.
  71578. */
  71579. template<typename Type>
  71580. using value_list_unique_t = typename value_list_unique<Type>::type;
  71581. /**
  71582. * @brief Provides the member constant `value` to true if a value list contains
  71583. * a given value, false otherwise.
  71584. * @tparam List Value list.
  71585. * @tparam Value Value to look for.
  71586. */
  71587. template<typename List, auto Value>
  71588. struct value_list_contains;
  71589. /**
  71590. * @copybrief value_list_contains
  71591. * @tparam Value Values provided by the value list.
  71592. * @tparam Other Value to look for.
  71593. */
  71594. template<auto... Value, auto Other>
  71595. struct value_list_contains<value_list<Value...>, Other>
  71596. : std::bool_constant<((Value == Other) || ...)> {};
  71597. /**
  71598. * @brief Helper variable template.
  71599. * @tparam List Value list.
  71600. * @tparam Value Value to look for.
  71601. */
  71602. template<typename List, auto Value>
  71603. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  71604. /*! @brief Primary template isn't defined on purpose. */
  71605. template<typename...>
  71606. struct value_list_diff;
  71607. /**
  71608. * @brief Computes the difference between two value lists.
  71609. * @tparam Value Values provided by the first value list.
  71610. * @tparam Other Values provided by the second value list.
  71611. */
  71612. template<auto... Value, auto... Other>
  71613. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  71614. /*! @brief A value list that is the difference between the two value lists. */
  71615. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  71616. };
  71617. /**
  71618. * @brief Helper type.
  71619. * @tparam List Value lists between which to compute the difference.
  71620. */
  71621. template<typename... List>
  71622. using value_list_diff_t = typename value_list_diff<List...>::type;
  71623. /*! @brief Same as std::is_invocable, but with tuples. */
  71624. template<typename, typename>
  71625. struct is_applicable: std::false_type {};
  71626. /**
  71627. * @copybrief is_applicable
  71628. * @tparam Func A valid function type.
  71629. * @tparam Tuple Tuple-like type.
  71630. * @tparam Args The list of arguments to use to probe the function type.
  71631. */
  71632. template<typename Func, template<typename...> class Tuple, typename... Args>
  71633. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  71634. /**
  71635. * @copybrief is_applicable
  71636. * @tparam Func A valid function type.
  71637. * @tparam Tuple Tuple-like type.
  71638. * @tparam Args The list of arguments to use to probe the function type.
  71639. */
  71640. template<typename Func, template<typename...> class Tuple, typename... Args>
  71641. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  71642. /**
  71643. * @brief Helper variable template.
  71644. * @tparam Func A valid function type.
  71645. * @tparam Args The list of arguments to use to probe the function type.
  71646. */
  71647. template<typename Func, typename Args>
  71648. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  71649. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  71650. template<typename, typename, typename>
  71651. struct is_applicable_r: std::false_type {};
  71652. /**
  71653. * @copybrief is_applicable_r
  71654. * @tparam Ret The type to which the return type of the function should be
  71655. * convertible.
  71656. * @tparam Func A valid function type.
  71657. * @tparam Args The list of arguments to use to probe the function type.
  71658. */
  71659. template<typename Ret, typename Func, typename... Args>
  71660. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  71661. /**
  71662. * @brief Helper variable template.
  71663. * @tparam Ret The type to which the return type of the function should be
  71664. * convertible.
  71665. * @tparam Func A valid function type.
  71666. * @tparam Args The list of arguments to use to probe the function type.
  71667. */
  71668. template<typename Ret, typename Func, typename Args>
  71669. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  71670. /**
  71671. * @brief Provides the member constant `value` to true if a given type is
  71672. * complete, false otherwise.
  71673. * @tparam Type The type to test.
  71674. */
  71675. template<typename Type, typename = void>
  71676. struct is_complete: std::false_type {};
  71677. /*! @copydoc is_complete */
  71678. template<typename Type>
  71679. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  71680. /**
  71681. * @brief Helper variable template.
  71682. * @tparam Type The type to test.
  71683. */
  71684. template<typename Type>
  71685. inline constexpr bool is_complete_v = is_complete<Type>::value;
  71686. /**
  71687. * @brief Provides the member constant `value` to true if a given type is an
  71688. * iterator, false otherwise.
  71689. * @tparam Type The type to test.
  71690. */
  71691. template<typename Type, typename = void>
  71692. struct is_iterator: std::false_type {};
  71693. /*! @cond TURN_OFF_DOXYGEN */
  71694. namespace internal {
  71695. template<typename, typename = void>
  71696. struct has_iterator_category: std::false_type {};
  71697. template<typename Type>
  71698. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  71699. } // namespace internal
  71700. /*! @endcond */
  71701. /*! @copydoc is_iterator */
  71702. template<typename Type>
  71703. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  71704. : internal::has_iterator_category<Type> {};
  71705. /**
  71706. * @brief Helper variable template.
  71707. * @tparam Type The type to test.
  71708. */
  71709. template<typename Type>
  71710. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  71711. /**
  71712. * @brief Provides the member constant `value` to true if a given type is both
  71713. * an empty and non-final class, false otherwise.
  71714. * @tparam Type The type to test
  71715. */
  71716. template<typename Type>
  71717. struct is_ebco_eligible
  71718. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  71719. /**
  71720. * @brief Helper variable template.
  71721. * @tparam Type The type to test.
  71722. */
  71723. template<typename Type>
  71724. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  71725. /**
  71726. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  71727. * is valid and denotes a type, false otherwise.
  71728. * @tparam Type The type to test.
  71729. */
  71730. template<typename Type, typename = void>
  71731. struct is_transparent: std::false_type {};
  71732. /*! @copydoc is_transparent */
  71733. template<typename Type>
  71734. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  71735. /**
  71736. * @brief Helper variable template.
  71737. * @tparam Type The type to test.
  71738. */
  71739. template<typename Type>
  71740. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  71741. /*! @cond TURN_OFF_DOXYGEN */
  71742. namespace internal {
  71743. template<typename, typename = void>
  71744. struct has_tuple_size_value: std::false_type {};
  71745. template<typename Type>
  71746. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  71747. template<typename, typename = void>
  71748. struct has_value_type: std::false_type {};
  71749. template<typename Type>
  71750. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  71751. template<typename>
  71752. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  71753. template<typename Type, std::size_t... Index>
  71754. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  71755. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  71756. }
  71757. template<typename>
  71758. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  71759. return false;
  71760. }
  71761. template<typename Type>
  71762. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  71763. return true;
  71764. }
  71765. template<typename Type>
  71766. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  71767. // NOLINTBEGIN(modernize-use-transparent-functors)
  71768. if constexpr(std::is_array_v<Type>) {
  71769. return false;
  71770. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  71771. if constexpr(has_tuple_size_value<Type>::value) {
  71772. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  71773. } else {
  71774. return maybe_equality_comparable<Type>(0);
  71775. }
  71776. } else if constexpr(has_value_type<Type>::value) {
  71777. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  71778. return maybe_equality_comparable<Type>(0);
  71779. } else {
  71780. return false;
  71781. }
  71782. } else {
  71783. return maybe_equality_comparable<Type>(0);
  71784. }
  71785. // NOLINTEND(modernize-use-transparent-functors)
  71786. }
  71787. } // namespace internal
  71788. /*! @endcond */
  71789. /**
  71790. * @brief Provides the member constant `value` to true if a given type is
  71791. * equality comparable, false otherwise.
  71792. * @tparam Type The type to test.
  71793. */
  71794. template<typename Type>
  71795. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  71796. /*! @copydoc is_equality_comparable */
  71797. template<typename Type>
  71798. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  71799. /**
  71800. * @brief Helper variable template.
  71801. * @tparam Type The type to test.
  71802. */
  71803. template<typename Type>
  71804. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  71805. /**
  71806. * @brief Transcribes the constness of a type to another type.
  71807. * @tparam To The type to which to transcribe the constness.
  71808. * @tparam From The type from which to transcribe the constness.
  71809. */
  71810. template<typename To, typename From>
  71811. struct constness_as {
  71812. /*! @brief The type resulting from the transcription of the constness. */
  71813. using type = std::remove_const_t<To>;
  71814. };
  71815. /*! @copydoc constness_as */
  71816. template<typename To, typename From>
  71817. struct constness_as<To, const From> {
  71818. /*! @brief The type resulting from the transcription of the constness. */
  71819. using type = const To;
  71820. };
  71821. /**
  71822. * @brief Alias template to facilitate the transcription of the constness.
  71823. * @tparam To The type to which to transcribe the constness.
  71824. * @tparam From The type from which to transcribe the constness.
  71825. */
  71826. template<typename To, typename From>
  71827. using constness_as_t = typename constness_as<To, From>::type;
  71828. /**
  71829. * @brief Extracts the class of a non-static member object or function.
  71830. * @tparam Member A pointer to a non-static member object or function.
  71831. */
  71832. template<typename Member>
  71833. class member_class {
  71834. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  71835. template<typename Class, typename Ret, typename... Args>
  71836. static Class *clazz(Ret (Class::*)(Args...));
  71837. template<typename Class, typename Ret, typename... Args>
  71838. static Class *clazz(Ret (Class::*)(Args...) const);
  71839. template<typename Class, typename Type>
  71840. static Class *clazz(Type Class::*);
  71841. public:
  71842. /*! @brief The class of the given non-static member object or function. */
  71843. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  71844. };
  71845. /**
  71846. * @brief Helper type.
  71847. * @tparam Member A pointer to a non-static member object or function.
  71848. */
  71849. template<typename Member>
  71850. using member_class_t = typename member_class<Member>::type;
  71851. /**
  71852. * @brief Extracts the n-th argument of a _callable_ type.
  71853. * @tparam Index The index of the argument to extract.
  71854. * @tparam Candidate A valid _callable_ type.
  71855. */
  71856. template<std::size_t Index, typename Candidate>
  71857. class nth_argument {
  71858. template<typename Ret, typename... Args>
  71859. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  71860. template<typename Ret, typename Class, typename... Args>
  71861. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  71862. template<typename Ret, typename Class, typename... Args>
  71863. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  71864. template<typename Type, typename Class>
  71865. static constexpr type_list<Type> pick_up(Type Class ::*);
  71866. template<typename Type>
  71867. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  71868. public:
  71869. /*! @brief N-th argument of the _callable_ type. */
  71870. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  71871. };
  71872. /**
  71873. * @brief Helper type.
  71874. * @tparam Index The index of the argument to extract.
  71875. * @tparam Candidate A valid function, member function or data member type.
  71876. */
  71877. template<std::size_t Index, typename Candidate>
  71878. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  71879. } // namespace entt
  71880. template<typename... Type>
  71881. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  71882. template<std::size_t Index, typename... Type>
  71883. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  71884. template<auto... Value>
  71885. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  71886. template<std::size_t Index, auto... Value>
  71887. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  71888. #endif
  71889. namespace entt {
  71890. /*! @cond TURN_OFF_DOXYGEN */
  71891. namespace internal {
  71892. template<typename Type, std::size_t, typename = void>
  71893. struct compressed_pair_element {
  71894. using reference = Type &;
  71895. using const_reference = const Type &;
  71896. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  71897. // NOLINTNEXTLINE(modernize-use-equals-default)
  71898. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  71899. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  71900. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  71901. : value{std::forward<Arg>(arg)} {}
  71902. template<typename... Args, std::size_t... Index>
  71903. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  71904. : value{std::forward<Args>(std::get<Index>(args))...} {}
  71905. [[nodiscard]] constexpr reference get() noexcept {
  71906. return value;
  71907. }
  71908. [[nodiscard]] constexpr const_reference get() const noexcept {
  71909. return value;
  71910. }
  71911. private:
  71912. Type value{};
  71913. };
  71914. template<typename Type, std::size_t Tag>
  71915. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  71916. using reference = Type &;
  71917. using const_reference = const Type &;
  71918. using base_type = Type;
  71919. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  71920. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  71921. : base_type{} {}
  71922. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  71923. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  71924. : base_type{std::forward<Arg>(arg)} {}
  71925. template<typename... Args, std::size_t... Index>
  71926. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  71927. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  71928. [[nodiscard]] constexpr reference get() noexcept {
  71929. return *this;
  71930. }
  71931. [[nodiscard]] constexpr const_reference get() const noexcept {
  71932. return *this;
  71933. }
  71934. };
  71935. } // namespace internal
  71936. /*! @endcond */
  71937. /**
  71938. * @brief A compressed pair.
  71939. *
  71940. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  71941. * reduce its final size to a minimum.
  71942. *
  71943. * @tparam First The type of the first element that the pair stores.
  71944. * @tparam Second The type of the second element that the pair stores.
  71945. */
  71946. template<typename First, typename Second>
  71947. class compressed_pair final
  71948. : internal::compressed_pair_element<First, 0u>,
  71949. internal::compressed_pair_element<Second, 1u> {
  71950. using first_base = internal::compressed_pair_element<First, 0u>;
  71951. using second_base = internal::compressed_pair_element<Second, 1u>;
  71952. public:
  71953. /*! @brief The type of the first element that the pair stores. */
  71954. using first_type = First;
  71955. /*! @brief The type of the second element that the pair stores. */
  71956. using second_type = Second;
  71957. /**
  71958. * @brief Default constructor, conditionally enabled.
  71959. *
  71960. * This constructor is only available when the types that the pair stores
  71961. * are both at least default constructible.
  71962. *
  71963. * @tparam Dummy Dummy template parameter used for internal purposes.
  71964. */
  71965. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  71966. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  71967. : first_base{},
  71968. second_base{} {}
  71969. /**
  71970. * @brief Copy constructor.
  71971. * @param other The instance to copy from.
  71972. */
  71973. constexpr compressed_pair(const compressed_pair &other) = default;
  71974. /**
  71975. * @brief Move constructor.
  71976. * @param other The instance to move from.
  71977. */
  71978. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  71979. /**
  71980. * @brief Constructs a pair from its values.
  71981. * @tparam Arg Type of value to use to initialize the first element.
  71982. * @tparam Other Type of value to use to initialize the second element.
  71983. * @param arg Value to use to initialize the first element.
  71984. * @param other Value to use to initialize the second element.
  71985. */
  71986. template<typename Arg, typename Other>
  71987. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  71988. : first_base{std::forward<Arg>(arg)},
  71989. second_base{std::forward<Other>(other)} {}
  71990. /**
  71991. * @brief Constructs a pair by forwarding the arguments to its parts.
  71992. * @tparam Args Types of arguments to use to initialize the first element.
  71993. * @tparam Other Types of arguments to use to initialize the second element.
  71994. * @param args Arguments to use to initialize the first element.
  71995. * @param other Arguments to use to initialize the second element.
  71996. */
  71997. template<typename... Args, typename... Other>
  71998. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  71999. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  72000. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  72001. /*! @brief Default destructor. */
  72002. ~compressed_pair() = default;
  72003. /**
  72004. * @brief Copy assignment operator.
  72005. * @param other The instance to copy from.
  72006. * @return This compressed pair object.
  72007. */
  72008. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  72009. /**
  72010. * @brief Move assignment operator.
  72011. * @param other The instance to move from.
  72012. * @return This compressed pair object.
  72013. */
  72014. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  72015. /**
  72016. * @brief Returns the first element that a pair stores.
  72017. * @return The first element that a pair stores.
  72018. */
  72019. [[nodiscard]] constexpr first_type &first() noexcept {
  72020. return static_cast<first_base &>(*this).get();
  72021. }
  72022. /*! @copydoc first */
  72023. [[nodiscard]] constexpr const first_type &first() const noexcept {
  72024. return static_cast<const first_base &>(*this).get();
  72025. }
  72026. /**
  72027. * @brief Returns the second element that a pair stores.
  72028. * @return The second element that a pair stores.
  72029. */
  72030. [[nodiscard]] constexpr second_type &second() noexcept {
  72031. return static_cast<second_base &>(*this).get();
  72032. }
  72033. /*! @copydoc second */
  72034. [[nodiscard]] constexpr const second_type &second() const noexcept {
  72035. return static_cast<const second_base &>(*this).get();
  72036. }
  72037. /**
  72038. * @brief Swaps two compressed pair objects.
  72039. * @param other The compressed pair to swap with.
  72040. */
  72041. constexpr void swap(compressed_pair &other) noexcept {
  72042. using std::swap;
  72043. swap(first(), other.first());
  72044. swap(second(), other.second());
  72045. }
  72046. /**
  72047. * @brief Extracts an element from the compressed pair.
  72048. * @tparam Index An integer value that is either 0 or 1.
  72049. * @return Returns a reference to the first element if `Index` is 0 and a
  72050. * reference to the second element if `Index` is 1.
  72051. */
  72052. template<std::size_t Index>
  72053. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  72054. if constexpr(Index == 0u) {
  72055. return first();
  72056. } else {
  72057. static_assert(Index == 1u, "Index out of bounds");
  72058. return second();
  72059. }
  72060. }
  72061. /*! @copydoc get */
  72062. template<std::size_t Index>
  72063. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  72064. if constexpr(Index == 0u) {
  72065. return first();
  72066. } else {
  72067. static_assert(Index == 1u, "Index out of bounds");
  72068. return second();
  72069. }
  72070. }
  72071. };
  72072. /**
  72073. * @brief Deduction guide.
  72074. * @tparam Type Type of value to use to initialize the first element.
  72075. * @tparam Other Type of value to use to initialize the second element.
  72076. */
  72077. template<typename Type, typename Other>
  72078. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  72079. /**
  72080. * @brief Swaps two compressed pair objects.
  72081. * @tparam First The type of the first element that the pairs store.
  72082. * @tparam Second The type of the second element that the pairs store.
  72083. * @param lhs A valid compressed pair object.
  72084. * @param rhs A valid compressed pair object.
  72085. */
  72086. template<typename First, typename Second>
  72087. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  72088. lhs.swap(rhs);
  72089. }
  72090. } // namespace entt
  72091. namespace std {
  72092. /**
  72093. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  72094. * @tparam First The type of the first element that the pair stores.
  72095. * @tparam Second The type of the second element that the pair stores.
  72096. */
  72097. template<typename First, typename Second>
  72098. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  72099. /**
  72100. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  72101. * @tparam Index The index of the type to return.
  72102. * @tparam First The type of the first element that the pair stores.
  72103. * @tparam Second The type of the second element that the pair stores.
  72104. */
  72105. template<size_t Index, typename First, typename Second>
  72106. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  72107. static_assert(Index < 2u, "Index out of bounds");
  72108. };
  72109. } // namespace std
  72110. #endif
  72111. // #include "../core/fwd.hpp"
  72112. #ifndef ENTT_CORE_FWD_HPP
  72113. #define ENTT_CORE_FWD_HPP
  72114. #include <cstddef>
  72115. #include <cstdint>
  72116. // #include "../config/config.h"
  72117. namespace entt {
  72118. /*! @brief Possible modes of an any object. */
  72119. enum class any_policy : std::uint8_t {
  72120. /*! @brief Default mode, no element available. */
  72121. empty,
  72122. /*! @brief Owning mode, dynamically allocated element. */
  72123. dynamic,
  72124. /*! @brief Owning mode, embedded element. */
  72125. embedded,
  72126. /*! @brief Aliasing mode, non-const reference. */
  72127. ref,
  72128. /*! @brief Const aliasing mode, const reference. */
  72129. cref
  72130. };
  72131. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  72132. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  72133. class basic_any;
  72134. /*! @brief Alias declaration for type identifiers. */
  72135. using id_type = ENTT_ID_TYPE;
  72136. /*! @brief Alias declaration for the most common use case. */
  72137. using any = basic_any<>;
  72138. template<typename, typename>
  72139. class compressed_pair;
  72140. template<typename>
  72141. class basic_hashed_string;
  72142. /*! @brief Aliases for common character types. */
  72143. using hashed_string = basic_hashed_string<char>;
  72144. /*! @brief Aliases for common character types. */
  72145. using hashed_wstring = basic_hashed_string<wchar_t>;
  72146. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  72147. struct type_info;
  72148. } // namespace entt
  72149. #endif
  72150. // #include "../core/iterator.hpp"
  72151. #ifndef ENTT_CORE_ITERATOR_HPP
  72152. #define ENTT_CORE_ITERATOR_HPP
  72153. #include <iterator>
  72154. #include <memory>
  72155. #include <type_traits>
  72156. #include <utility>
  72157. namespace entt {
  72158. /**
  72159. * @brief Helper type to use as pointer with input iterators.
  72160. * @tparam Type of wrapped value.
  72161. */
  72162. template<typename Type>
  72163. struct input_iterator_pointer final {
  72164. /*! @brief Value type. */
  72165. using value_type = Type;
  72166. /*! @brief Pointer type. */
  72167. using pointer = Type *;
  72168. /*! @brief Reference type. */
  72169. using reference = Type &;
  72170. /**
  72171. * @brief Constructs a proxy object by move.
  72172. * @param val Value to use to initialize the proxy object.
  72173. */
  72174. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  72175. : value{std::move(val)} {}
  72176. /**
  72177. * @brief Access operator for accessing wrapped values.
  72178. * @return A pointer to the wrapped value.
  72179. */
  72180. [[nodiscard]] constexpr pointer operator->() noexcept {
  72181. return std::addressof(value);
  72182. }
  72183. /**
  72184. * @brief Dereference operator for accessing wrapped values.
  72185. * @return A reference to the wrapped value.
  72186. */
  72187. [[nodiscard]] constexpr reference operator*() noexcept {
  72188. return value;
  72189. }
  72190. private:
  72191. Type value;
  72192. };
  72193. /**
  72194. * @brief Plain iota iterator (waiting for C++20).
  72195. * @tparam Type Value type.
  72196. */
  72197. template<typename Type>
  72198. class iota_iterator final {
  72199. static_assert(std::is_integral_v<Type>, "Not an integral type");
  72200. public:
  72201. /*! @brief Value type, likely an integral one. */
  72202. using value_type = Type;
  72203. /*! @brief Invalid pointer type. */
  72204. using pointer = void;
  72205. /*! @brief Non-reference type, same as value type. */
  72206. using reference = value_type;
  72207. /*! @brief Difference type. */
  72208. using difference_type = std::ptrdiff_t;
  72209. /*! @brief Iterator category. */
  72210. using iterator_category = std::input_iterator_tag;
  72211. /*! @brief Default constructor. */
  72212. constexpr iota_iterator() noexcept
  72213. : current{} {}
  72214. /**
  72215. * @brief Constructs an iota iterator from a given value.
  72216. * @param init The initial value assigned to the iota iterator.
  72217. */
  72218. constexpr iota_iterator(const value_type init) noexcept
  72219. : current{init} {}
  72220. /**
  72221. * @brief Pre-increment operator.
  72222. * @return This iota iterator.
  72223. */
  72224. constexpr iota_iterator &operator++() noexcept {
  72225. return ++current, *this;
  72226. }
  72227. /**
  72228. * @brief Post-increment operator.
  72229. * @return This iota iterator.
  72230. */
  72231. constexpr iota_iterator operator++(int) noexcept {
  72232. const iota_iterator orig = *this;
  72233. return ++(*this), orig;
  72234. }
  72235. /**
  72236. * @brief Dereference operator.
  72237. * @return The underlying value.
  72238. */
  72239. [[nodiscard]] constexpr reference operator*() const noexcept {
  72240. return current;
  72241. }
  72242. private:
  72243. value_type current;
  72244. };
  72245. /**
  72246. * @brief Comparison operator.
  72247. * @tparam Type Value type of the iota iterator.
  72248. * @param lhs A properly initialized iota iterator.
  72249. * @param rhs A properly initialized iota iterator.
  72250. * @return True if the two iterators are identical, false otherwise.
  72251. */
  72252. template<typename Type>
  72253. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  72254. return *lhs == *rhs;
  72255. }
  72256. /**
  72257. * @brief Comparison operator.
  72258. * @tparam Type Value type of the iota iterator.
  72259. * @param lhs A properly initialized iota iterator.
  72260. * @param rhs A properly initialized iota iterator.
  72261. * @return True if the two iterators differ, false otherwise.
  72262. */
  72263. template<typename Type>
  72264. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  72265. return !(lhs == rhs);
  72266. }
  72267. /**
  72268. * @brief Utility class to create an iterable object from a pair of iterators.
  72269. * @tparam It Type of iterator.
  72270. * @tparam Sentinel Type of sentinel.
  72271. */
  72272. template<typename It, typename Sentinel = It>
  72273. struct iterable_adaptor final {
  72274. /*! @brief Value type. */
  72275. using value_type = typename std::iterator_traits<It>::value_type;
  72276. /*! @brief Iterator type. */
  72277. using iterator = It;
  72278. /*! @brief Sentinel type. */
  72279. using sentinel = Sentinel;
  72280. /*! @brief Default constructor. */
  72281. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  72282. : first{},
  72283. last{} {}
  72284. /**
  72285. * @brief Creates an iterable object from a pair of iterators.
  72286. * @param from Begin iterator.
  72287. * @param to End iterator.
  72288. */
  72289. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  72290. : first{std::move(from)},
  72291. last{std::move(to)} {}
  72292. /**
  72293. * @brief Returns an iterator to the beginning.
  72294. * @return An iterator to the first element of the range.
  72295. */
  72296. [[nodiscard]] constexpr iterator begin() const noexcept {
  72297. return first;
  72298. }
  72299. /**
  72300. * @brief Returns an iterator to the end.
  72301. * @return An iterator to the element following the last element of the
  72302. * range.
  72303. */
  72304. [[nodiscard]] constexpr sentinel end() const noexcept {
  72305. return last;
  72306. }
  72307. /*! @copydoc begin */
  72308. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  72309. return begin();
  72310. }
  72311. /*! @copydoc end */
  72312. [[nodiscard]] constexpr sentinel cend() const noexcept {
  72313. return end();
  72314. }
  72315. private:
  72316. It first;
  72317. Sentinel last;
  72318. };
  72319. } // namespace entt
  72320. #endif
  72321. // #include "../core/utility.hpp"
  72322. #ifndef ENTT_CORE_UTILITY_HPP
  72323. #define ENTT_CORE_UTILITY_HPP
  72324. #include <type_traits>
  72325. #include <utility>
  72326. namespace entt {
  72327. /*! @brief Identity function object (waiting for C++20). */
  72328. struct identity {
  72329. /*! @brief Indicates that this is a transparent function object. */
  72330. using is_transparent = void;
  72331. /**
  72332. * @brief Returns its argument unchanged.
  72333. * @tparam Type Type of the argument.
  72334. * @param value The actual argument.
  72335. * @return The submitted value as-is.
  72336. */
  72337. template<typename Type>
  72338. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  72339. return std::forward<Type>(value);
  72340. }
  72341. };
  72342. /**
  72343. * @brief Constant utility to disambiguate overloaded members of a class.
  72344. * @tparam Type Type of the desired overload.
  72345. * @tparam Class Type of class to which the member belongs.
  72346. * @param member A valid pointer to a member.
  72347. * @return Pointer to the member.
  72348. */
  72349. template<typename Type, typename Class>
  72350. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  72351. return member;
  72352. }
  72353. /**
  72354. * @brief Constant utility to disambiguate overloaded functions.
  72355. * @tparam Func Function type of the desired overload.
  72356. * @param func A valid pointer to a function.
  72357. * @return Pointer to the function.
  72358. */
  72359. template<typename Func>
  72360. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  72361. return func;
  72362. }
  72363. /**
  72364. * @brief Helper type for visitors.
  72365. * @tparam Func Types of function objects.
  72366. */
  72367. template<typename... Func>
  72368. struct overloaded: Func... {
  72369. using Func::operator()...;
  72370. };
  72371. /**
  72372. * @brief Deduction guide.
  72373. * @tparam Func Types of function objects.
  72374. */
  72375. template<typename... Func>
  72376. overloaded(Func...) -> overloaded<Func...>;
  72377. /**
  72378. * @brief Basic implementation of a y-combinator.
  72379. * @tparam Func Type of a potentially recursive function.
  72380. */
  72381. template<typename Func>
  72382. struct y_combinator {
  72383. /**
  72384. * @brief Constructs a y-combinator from a given function.
  72385. * @param recursive A potentially recursive function.
  72386. */
  72387. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  72388. : func{std::move(recursive)} {}
  72389. /**
  72390. * @brief Invokes a y-combinator and therefore its underlying function.
  72391. * @tparam Args Types of arguments to use to invoke the underlying function.
  72392. * @param args Parameters to use to invoke the underlying function.
  72393. * @return Return value of the underlying function, if any.
  72394. */
  72395. template<typename... Args>
  72396. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  72397. return func(*this, std::forward<Args>(args)...);
  72398. }
  72399. /*! @copydoc operator()() */
  72400. template<typename... Args>
  72401. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  72402. return func(*this, std::forward<Args>(args)...);
  72403. }
  72404. private:
  72405. Func func;
  72406. };
  72407. } // namespace entt
  72408. #endif
  72409. // #include "fwd.hpp"
  72410. #ifndef ENTT_RESOURCE_FWD_HPP
  72411. #define ENTT_RESOURCE_FWD_HPP
  72412. #include <memory>
  72413. namespace entt {
  72414. template<typename>
  72415. struct resource_loader;
  72416. template<typename Type, typename = resource_loader<Type>, typename = std::allocator<Type>>
  72417. class resource_cache;
  72418. template<typename>
  72419. class resource;
  72420. } // namespace entt
  72421. #endif
  72422. // #include "loader.hpp"
  72423. #ifndef ENTT_RESOURCE_LOADER_HPP
  72424. #define ENTT_RESOURCE_LOADER_HPP
  72425. #include <memory>
  72426. #include <utility>
  72427. // #include "fwd.hpp"
  72428. namespace entt {
  72429. /**
  72430. * @brief Transparent loader for shared resources.
  72431. * @tparam Type Type of resources created by the loader.
  72432. */
  72433. template<typename Type>
  72434. struct resource_loader {
  72435. /*! @brief Result type. */
  72436. using result_type = std::shared_ptr<Type>;
  72437. /**
  72438. * @brief Constructs a shared pointer to a resource from its arguments.
  72439. * @tparam Args Types of arguments to use to construct the resource.
  72440. * @param args Parameters to use to construct the resource.
  72441. * @return A shared pointer to a resource of the given type.
  72442. */
  72443. template<typename... Args>
  72444. result_type operator()(Args &&...args) const {
  72445. return std::make_shared<Type>(std::forward<Args>(args)...);
  72446. }
  72447. };
  72448. } // namespace entt
  72449. #endif
  72450. // #include "resource.hpp"
  72451. #ifndef ENTT_RESOURCE_RESOURCE_HPP
  72452. #define ENTT_RESOURCE_RESOURCE_HPP
  72453. #include <memory>
  72454. #include <type_traits>
  72455. #include <utility>
  72456. // #include "fwd.hpp"
  72457. namespace entt {
  72458. /**
  72459. * @brief Basic resource handle.
  72460. *
  72461. * A handle wraps a resource and extends its lifetime. It also shares the same
  72462. * resource with all other handles constructed from the same element.<br/>
  72463. * As a rule of thumb, resources should never be copied nor moved. Handles are
  72464. * the way to go to push references around.
  72465. *
  72466. * @tparam Type Type of resource managed by a handle.
  72467. */
  72468. template<typename Type>
  72469. class resource {
  72470. template<typename>
  72471. friend class resource;
  72472. template<typename Other>
  72473. static constexpr bool is_acceptable = !std::is_same_v<Type, Other> && std::is_constructible_v<Type &, Other &>;
  72474. public:
  72475. /*! @brief Resource type. */
  72476. using element_type = Type;
  72477. /*! @brief Handle type. */
  72478. using handle_type = std::shared_ptr<element_type>;
  72479. /*! @brief Default constructor. */
  72480. resource() noexcept
  72481. : value{} {}
  72482. /**
  72483. * @brief Creates a new resource handle.
  72484. * @param res A handle to a resource.
  72485. */
  72486. explicit resource(handle_type res) noexcept
  72487. : value{std::move(res)} {}
  72488. /*! @brief Default copy constructor. */
  72489. resource(const resource &) noexcept = default;
  72490. /*! @brief Default move constructor. */
  72491. resource(resource &&) noexcept = default;
  72492. /**
  72493. * @brief Aliasing constructor.
  72494. * @tparam Other Type of resource managed by the received handle.
  72495. * @param other The handle with which to share ownership information.
  72496. * @param res Unrelated and unmanaged resources.
  72497. */
  72498. template<typename Other>
  72499. resource(const resource<Other> &other, element_type &res) noexcept
  72500. : value{other.value, std::addressof(res)} {}
  72501. /**
  72502. * @brief Copy constructs a handle which shares ownership of the resource.
  72503. * @tparam Other Type of resource managed by the received handle.
  72504. * @param other The handle to copy from.
  72505. */
  72506. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  72507. resource(const resource<Other> &other) noexcept
  72508. : value{other.value} {}
  72509. /**
  72510. * @brief Move constructs a handle which takes ownership of the resource.
  72511. * @tparam Other Type of resource managed by the received handle.
  72512. * @param other The handle to move from.
  72513. */
  72514. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  72515. resource(resource<Other> &&other) noexcept
  72516. : value{std::move(other.value)} {}
  72517. /*! @brief Default destructor. */
  72518. ~resource() = default;
  72519. /**
  72520. * @brief Default copy assignment operator.
  72521. * @return This resource handle.
  72522. */
  72523. resource &operator=(const resource &) noexcept = default;
  72524. /**
  72525. * @brief Default move assignment operator.
  72526. * @return This resource handle.
  72527. */
  72528. resource &operator=(resource &&) noexcept = default;
  72529. /**
  72530. * @brief Copy assignment operator from foreign handle.
  72531. * @tparam Other Type of resource managed by the received handle.
  72532. * @param other The handle to copy from.
  72533. * @return This resource handle.
  72534. */
  72535. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  72536. resource &operator=(const resource<Other> &other) noexcept {
  72537. value = other.value;
  72538. return *this;
  72539. }
  72540. /**
  72541. * @brief Move assignment operator from foreign handle.
  72542. * @tparam Other Type of resource managed by the received handle.
  72543. * @param other The handle to move from.
  72544. * @return This resource handle.
  72545. */
  72546. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  72547. resource &operator=(resource<Other> &&other) noexcept {
  72548. value = std::move(other.value);
  72549. return *this;
  72550. }
  72551. /**
  72552. * @brief Exchanges the content with that of a given resource.
  72553. * @param other Resource to exchange the content with.
  72554. */
  72555. void swap(resource &other) noexcept {
  72556. using std::swap;
  72557. swap(value, other.value);
  72558. }
  72559. /**
  72560. * @brief Returns a reference to the managed resource.
  72561. *
  72562. * @warning
  72563. * The behavior is undefined if the handle doesn't contain a resource.
  72564. *
  72565. * @return A reference to the managed resource.
  72566. */
  72567. [[nodiscard]] element_type &operator*() const noexcept {
  72568. return *value;
  72569. }
  72570. /*! @copydoc operator* */
  72571. [[nodiscard]] operator element_type &() const noexcept {
  72572. return *value;
  72573. }
  72574. /**
  72575. * @brief Returns a pointer to the managed resource.
  72576. * @return A pointer to the managed resource.
  72577. */
  72578. [[nodiscard]] element_type *operator->() const noexcept {
  72579. return value.get();
  72580. }
  72581. /**
  72582. * @brief Returns true if a handle contains a resource, false otherwise.
  72583. * @return True if the handle contains a resource, false otherwise.
  72584. */
  72585. [[nodiscard]] explicit operator bool() const noexcept {
  72586. return static_cast<bool>(value);
  72587. }
  72588. /*! @brief Releases the ownership of the managed resource. */
  72589. void reset() {
  72590. value.reset();
  72591. }
  72592. /**
  72593. * @brief Replaces the managed resource.
  72594. * @param other A handle to a resource.
  72595. */
  72596. void reset(handle_type other) {
  72597. value = std::move(other);
  72598. }
  72599. /**
  72600. * @brief Returns the underlying resource handle.
  72601. * @return The underlying resource handle.
  72602. */
  72603. [[nodiscard]] handle_type handle() const noexcept {
  72604. return value;
  72605. }
  72606. private:
  72607. handle_type value;
  72608. };
  72609. /**
  72610. * @brief Compares two handles.
  72611. * @tparam Lhs Type of resource managed by the first handle.
  72612. * @tparam Rhs Type of resource managed by the second handle.
  72613. * @param lhs A valid handle.
  72614. * @param rhs A valid handle.
  72615. * @return True if both handles refer to the same resource, false otherwise.
  72616. */
  72617. template<typename Lhs, typename Rhs>
  72618. [[nodiscard]] bool operator==(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  72619. return (std::addressof(*lhs) == std::addressof(*rhs));
  72620. }
  72621. /**
  72622. * @brief Compares two handles.
  72623. * @tparam Lhs Type of resource managed by the first handle.
  72624. * @tparam Rhs Type of resource managed by the second handle.
  72625. * @param lhs A valid handle.
  72626. * @param rhs A valid handle.
  72627. * @return False if both handles refer to the same resource, true otherwise.
  72628. */
  72629. template<typename Lhs, typename Rhs>
  72630. [[nodiscard]] bool operator!=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  72631. return !(lhs == rhs);
  72632. }
  72633. /**
  72634. * @brief Compares two handles.
  72635. * @tparam Lhs Type of resource managed by the first handle.
  72636. * @tparam Rhs Type of resource managed by the second handle.
  72637. * @param lhs A valid handle.
  72638. * @param rhs A valid handle.
  72639. * @return True if the first handle is less than the second, false otherwise.
  72640. */
  72641. template<typename Lhs, typename Rhs>
  72642. [[nodiscard]] bool operator<(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  72643. return (std::addressof(*lhs) < std::addressof(*rhs));
  72644. }
  72645. /**
  72646. * @brief Compares two handles.
  72647. * @tparam Lhs Type of resource managed by the first handle.
  72648. * @tparam Rhs Type of resource managed by the second handle.
  72649. * @param lhs A valid handle.
  72650. * @param rhs A valid handle.
  72651. * @return True if the first handle is greater than the second, false otherwise.
  72652. */
  72653. template<typename Lhs, typename Rhs>
  72654. [[nodiscard]] bool operator>(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  72655. return rhs < lhs;
  72656. }
  72657. /**
  72658. * @brief Compares two handles.
  72659. * @tparam Lhs Type of resource managed by the first handle.
  72660. * @tparam Rhs Type of resource managed by the second handle.
  72661. * @param lhs A valid handle.
  72662. * @param rhs A valid handle.
  72663. * @return True if the first handle is less than or equal to the second, false
  72664. * otherwise.
  72665. */
  72666. template<typename Lhs, typename Rhs>
  72667. [[nodiscard]] bool operator<=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  72668. return !(lhs > rhs);
  72669. }
  72670. /**
  72671. * @brief Compares two handles.
  72672. * @tparam Lhs Type of resource managed by the first handle.
  72673. * @tparam Rhs Type of resource managed by the second handle.
  72674. * @param lhs A valid handle.
  72675. * @param rhs A valid handle.
  72676. * @return True if the first handle is greater than or equal to the second,
  72677. * false otherwise.
  72678. */
  72679. template<typename Lhs, typename Rhs>
  72680. [[nodiscard]] bool operator>=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  72681. return !(lhs < rhs);
  72682. }
  72683. } // namespace entt
  72684. #endif
  72685. namespace entt {
  72686. /*! @cond TURN_OFF_DOXYGEN */
  72687. namespace internal {
  72688. template<typename Type, typename It>
  72689. class resource_cache_iterator final {
  72690. template<typename, typename>
  72691. friend class resource_cache_iterator;
  72692. public:
  72693. using value_type = std::pair<id_type, resource<Type>>;
  72694. using pointer = input_iterator_pointer<value_type>;
  72695. using reference = value_type;
  72696. using difference_type = std::ptrdiff_t;
  72697. using iterator_category = std::input_iterator_tag;
  72698. using iterator_concept = std::random_access_iterator_tag;
  72699. constexpr resource_cache_iterator() noexcept = default;
  72700. constexpr resource_cache_iterator(const It iter) noexcept
  72701. : it{iter} {}
  72702. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  72703. constexpr resource_cache_iterator(const resource_cache_iterator<std::remove_const_t<Type>, Other> &other) noexcept
  72704. : it{other.it} {}
  72705. constexpr resource_cache_iterator &operator++() noexcept {
  72706. return ++it, *this;
  72707. }
  72708. constexpr resource_cache_iterator operator++(int) noexcept {
  72709. const resource_cache_iterator orig = *this;
  72710. return ++(*this), orig;
  72711. }
  72712. constexpr resource_cache_iterator &operator--() noexcept {
  72713. return --it, *this;
  72714. }
  72715. constexpr resource_cache_iterator operator--(int) noexcept {
  72716. const resource_cache_iterator orig = *this;
  72717. return operator--(), orig;
  72718. }
  72719. constexpr resource_cache_iterator &operator+=(const difference_type value) noexcept {
  72720. it += value;
  72721. return *this;
  72722. }
  72723. constexpr resource_cache_iterator operator+(const difference_type value) const noexcept {
  72724. resource_cache_iterator copy = *this;
  72725. return (copy += value);
  72726. }
  72727. constexpr resource_cache_iterator &operator-=(const difference_type value) noexcept {
  72728. return (*this += -value);
  72729. }
  72730. constexpr resource_cache_iterator operator-(const difference_type value) const noexcept {
  72731. return (*this + -value);
  72732. }
  72733. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  72734. return {it[value].first, resource<Type>{it[value].second}};
  72735. }
  72736. [[nodiscard]] constexpr reference operator*() const noexcept {
  72737. return operator[](0);
  72738. }
  72739. [[nodiscard]] constexpr pointer operator->() const noexcept {
  72740. return operator*();
  72741. }
  72742. template<typename... Lhs, typename... Rhs>
  72743. friend constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
  72744. template<typename... Lhs, typename... Rhs>
  72745. friend constexpr bool operator==(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
  72746. template<typename... Lhs, typename... Rhs>
  72747. friend constexpr bool operator<(const resource_cache_iterator<Lhs...> &, const resource_cache_iterator<Rhs...> &) noexcept;
  72748. private:
  72749. It it;
  72750. };
  72751. template<typename... Lhs, typename... Rhs>
  72752. [[nodiscard]] constexpr std::ptrdiff_t operator-(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
  72753. return lhs.it - rhs.it;
  72754. }
  72755. template<typename... Lhs, typename... Rhs>
  72756. [[nodiscard]] constexpr bool operator==(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
  72757. return lhs.it == rhs.it;
  72758. }
  72759. template<typename... Lhs, typename... Rhs>
  72760. [[nodiscard]] constexpr bool operator!=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
  72761. return !(lhs == rhs);
  72762. }
  72763. template<typename... Lhs, typename... Rhs>
  72764. [[nodiscard]] constexpr bool operator<(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
  72765. return lhs.it < rhs.it;
  72766. }
  72767. template<typename... Lhs, typename... Rhs>
  72768. [[nodiscard]] constexpr bool operator>(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
  72769. return rhs < lhs;
  72770. }
  72771. template<typename... Lhs, typename... Rhs>
  72772. [[nodiscard]] constexpr bool operator<=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
  72773. return !(lhs > rhs);
  72774. }
  72775. template<typename... Lhs, typename... Rhs>
  72776. [[nodiscard]] constexpr bool operator>=(const resource_cache_iterator<Lhs...> &lhs, const resource_cache_iterator<Rhs...> &rhs) noexcept {
  72777. return !(lhs < rhs);
  72778. }
  72779. } // namespace internal
  72780. /*! @endcond */
  72781. /**
  72782. * @brief Basic cache for resources of any type.
  72783. * @tparam Type Type of resources managed by a cache.
  72784. * @tparam Loader Type of loader used to create the resources.
  72785. * @tparam Allocator Type of allocator used to manage memory and elements.
  72786. */
  72787. template<typename Type, typename Loader, typename Allocator>
  72788. class resource_cache {
  72789. using alloc_traits = std::allocator_traits<Allocator>;
  72790. static_assert(std::is_same_v<typename alloc_traits::value_type, Type>, "Invalid value type");
  72791. using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const id_type, typename Loader::result_type>>;
  72792. using container_type = dense_map<id_type, typename Loader::result_type, identity, std::equal_to<>, container_allocator>;
  72793. public:
  72794. /*! @brief Allocator type. */
  72795. using allocator_type = Allocator;
  72796. /*! @brief Resource type. */
  72797. using value_type = Type;
  72798. /*! @brief Unsigned integer type. */
  72799. using size_type = std::size_t;
  72800. /*! @brief Loader type. */
  72801. using loader_type = Loader;
  72802. /*! @brief Input iterator type. */
  72803. using iterator = internal::resource_cache_iterator<Type, typename container_type::iterator>;
  72804. /*! @brief Constant input iterator type. */
  72805. using const_iterator = internal::resource_cache_iterator<const Type, typename container_type::const_iterator>;
  72806. /*! @brief Default constructor. */
  72807. resource_cache()
  72808. : resource_cache{loader_type{}} {}
  72809. /**
  72810. * @brief Constructs an empty cache with a given allocator.
  72811. * @param allocator The allocator to use.
  72812. */
  72813. explicit resource_cache(const allocator_type &allocator)
  72814. : resource_cache{loader_type{}, allocator} {}
  72815. /**
  72816. * @brief Constructs an empty cache with a given allocator and loader.
  72817. * @param callable The loader to use.
  72818. * @param allocator The allocator to use.
  72819. */
  72820. explicit resource_cache(const loader_type &callable, const allocator_type &allocator = allocator_type{})
  72821. : pool{container_type{allocator}, callable} {}
  72822. /*! @brief Default copy constructor. */
  72823. resource_cache(const resource_cache &) = default;
  72824. /**
  72825. * @brief Allocator-extended copy constructor.
  72826. * @param other The instance to copy from.
  72827. * @param allocator The allocator to use.
  72828. */
  72829. resource_cache(const resource_cache &other, const allocator_type &allocator)
  72830. : pool{std::piecewise_construct, std::forward_as_tuple(other.pool.first(), allocator), std::forward_as_tuple(other.pool.second())} {}
  72831. /*! @brief Default move constructor. */
  72832. resource_cache(resource_cache &&) noexcept = default;
  72833. /**
  72834. * @brief Allocator-extended move constructor.
  72835. * @param other The instance to move from.
  72836. * @param allocator The allocator to use.
  72837. */
  72838. resource_cache(resource_cache &&other, const allocator_type &allocator)
  72839. : pool{std::piecewise_construct, std::forward_as_tuple(std::move(other.pool.first()), allocator), std::forward_as_tuple(std::move(other.pool.second()))} {}
  72840. /*! @brief Default destructor. */
  72841. ~resource_cache() = default;
  72842. /**
  72843. * @brief Default copy assignment operator.
  72844. * @return This cache.
  72845. */
  72846. resource_cache &operator=(const resource_cache &) = default;
  72847. /**
  72848. * @brief Default move assignment operator.
  72849. * @return This cache.
  72850. */
  72851. resource_cache &operator=(resource_cache &&) noexcept = default;
  72852. /**
  72853. * @brief Returns the associated allocator.
  72854. * @return The associated allocator.
  72855. */
  72856. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  72857. return pool.first().get_allocator();
  72858. }
  72859. /**
  72860. * @brief Returns an iterator to the beginning.
  72861. *
  72862. * If the cache is empty, the returned iterator will be equal to `end()`.
  72863. *
  72864. * @return An iterator to the first instance of the internal cache.
  72865. */
  72866. [[nodiscard]] const_iterator cbegin() const noexcept {
  72867. return pool.first().begin();
  72868. }
  72869. /*! @copydoc cbegin */
  72870. [[nodiscard]] const_iterator begin() const noexcept {
  72871. return cbegin();
  72872. }
  72873. /*! @copydoc begin */
  72874. [[nodiscard]] iterator begin() noexcept {
  72875. return pool.first().begin();
  72876. }
  72877. /**
  72878. * @brief Returns an iterator to the end.
  72879. * @return An iterator to the element following the last instance of the
  72880. * internal cache.
  72881. */
  72882. [[nodiscard]] const_iterator cend() const noexcept {
  72883. return pool.first().end();
  72884. }
  72885. /*! @copydoc cend */
  72886. [[nodiscard]] const_iterator end() const noexcept {
  72887. return cend();
  72888. }
  72889. /*! @copydoc end */
  72890. [[nodiscard]] iterator end() noexcept {
  72891. return pool.first().end();
  72892. }
  72893. /**
  72894. * @brief Returns true if a cache contains no resources, false otherwise.
  72895. * @return True if the cache contains no resources, false otherwise.
  72896. */
  72897. [[nodiscard]] bool empty() const noexcept {
  72898. return pool.first().empty();
  72899. }
  72900. /**
  72901. * @brief Number of resources managed by a cache.
  72902. * @return Number of resources currently stored.
  72903. */
  72904. [[nodiscard]] size_type size() const noexcept {
  72905. return pool.first().size();
  72906. }
  72907. /*! @brief Clears a cache. */
  72908. void clear() noexcept {
  72909. pool.first().clear();
  72910. }
  72911. /**
  72912. * @brief Loads a resource, if its identifier does not exist.
  72913. *
  72914. * Arguments are forwarded directly to the loader and _consumed_ only if the
  72915. * resource doesn't already exist.
  72916. *
  72917. * @warning
  72918. * If the resource isn't loaded correctly, the returned handle could be
  72919. * invalid and any use of it will result in undefined behavior.
  72920. *
  72921. * @tparam Args Types of arguments to use to load the resource if required.
  72922. * @param id Unique resource identifier.
  72923. * @param args Arguments to use to load the resource if required.
  72924. * @return A pair consisting of an iterator to the inserted element (or to
  72925. * the element that prevented the insertion) and a bool denoting whether the
  72926. * insertion took place.
  72927. */
  72928. template<typename... Args>
  72929. std::pair<iterator, bool> load(const id_type id, Args &&...args) {
  72930. if(auto it = pool.first().find(id); it != pool.first().end()) {
  72931. return {it, false};
  72932. }
  72933. return pool.first().emplace(id, pool.second()(std::forward<Args>(args)...));
  72934. }
  72935. /**
  72936. * @brief Force loads a resource, if its identifier does not exist.
  72937. * @copydetails load
  72938. */
  72939. template<typename... Args>
  72940. std::pair<iterator, bool> force_load(const id_type id, Args &&...args) {
  72941. return {pool.first().insert_or_assign(id, pool.second()(std::forward<Args>(args)...)).first, true};
  72942. }
  72943. /**
  72944. * @brief Returns a handle for a given resource identifier.
  72945. *
  72946. * @warning
  72947. * There is no guarantee that the returned handle is valid.<br/>
  72948. * If it is not, any use will result in indefinite behavior.
  72949. *
  72950. * @param id Unique resource identifier.
  72951. * @return A handle for the given resource.
  72952. */
  72953. [[nodiscard]] resource<const value_type> operator[](const id_type id) const {
  72954. if(auto it = pool.first().find(id); it != pool.first().cend()) {
  72955. return resource<const value_type>{it->second};
  72956. }
  72957. return {};
  72958. }
  72959. /*! @copydoc operator[] */
  72960. [[nodiscard]] resource<value_type> operator[](const id_type id) {
  72961. if(auto it = pool.first().find(id); it != pool.first().end()) {
  72962. return resource<value_type>{it->second};
  72963. }
  72964. return {};
  72965. }
  72966. /**
  72967. * @brief Checks if a cache contains a given identifier.
  72968. * @param id Unique resource identifier.
  72969. * @return True if the cache contains the resource, false otherwise.
  72970. */
  72971. [[nodiscard]] bool contains(const id_type id) const {
  72972. return pool.first().contains(id);
  72973. }
  72974. /**
  72975. * @brief Removes an element from a given position.
  72976. * @param pos An iterator to the element to remove.
  72977. * @return An iterator following the removed element.
  72978. */
  72979. iterator erase(const_iterator pos) {
  72980. const auto it = pool.first().begin();
  72981. return pool.first().erase(it + (pos - const_iterator{it}));
  72982. }
  72983. /**
  72984. * @brief Removes the given elements from a cache.
  72985. * @param first An iterator to the first element of the range of elements.
  72986. * @param last An iterator past the last element of the range of elements.
  72987. * @return An iterator following the last removed element.
  72988. */
  72989. iterator erase(const_iterator first, const_iterator last) {
  72990. const auto it = pool.first().begin();
  72991. return pool.first().erase(it + (first - const_iterator{it}), it + (last - const_iterator{it}));
  72992. }
  72993. /**
  72994. * @brief Removes the given elements from a cache.
  72995. * @param id Unique resource identifier.
  72996. * @return Number of resources erased (either 0 or 1).
  72997. */
  72998. size_type erase(const id_type id) {
  72999. return pool.first().erase(id);
  73000. }
  73001. /**
  73002. * @brief Returns the loader used to create resources.
  73003. * @return The loader used to create resources.
  73004. */
  73005. [[nodiscard]] loader_type loader() const {
  73006. return pool.second();
  73007. }
  73008. private:
  73009. compressed_pair<container_type, loader_type> pool;
  73010. };
  73011. } // namespace entt
  73012. #endif
  73013. // #include "resource/loader.hpp"
  73014. #ifndef ENTT_RESOURCE_LOADER_HPP
  73015. #define ENTT_RESOURCE_LOADER_HPP
  73016. #include <memory>
  73017. #include <utility>
  73018. // #include "fwd.hpp"
  73019. namespace entt {
  73020. /**
  73021. * @brief Transparent loader for shared resources.
  73022. * @tparam Type Type of resources created by the loader.
  73023. */
  73024. template<typename Type>
  73025. struct resource_loader {
  73026. /*! @brief Result type. */
  73027. using result_type = std::shared_ptr<Type>;
  73028. /**
  73029. * @brief Constructs a shared pointer to a resource from its arguments.
  73030. * @tparam Args Types of arguments to use to construct the resource.
  73031. * @param args Parameters to use to construct the resource.
  73032. * @return A shared pointer to a resource of the given type.
  73033. */
  73034. template<typename... Args>
  73035. result_type operator()(Args &&...args) const {
  73036. return std::make_shared<Type>(std::forward<Args>(args)...);
  73037. }
  73038. };
  73039. } // namespace entt
  73040. #endif
  73041. // #include "resource/resource.hpp"
  73042. #ifndef ENTT_RESOURCE_RESOURCE_HPP
  73043. #define ENTT_RESOURCE_RESOURCE_HPP
  73044. #include <memory>
  73045. #include <type_traits>
  73046. #include <utility>
  73047. // #include "fwd.hpp"
  73048. namespace entt {
  73049. /**
  73050. * @brief Basic resource handle.
  73051. *
  73052. * A handle wraps a resource and extends its lifetime. It also shares the same
  73053. * resource with all other handles constructed from the same element.<br/>
  73054. * As a rule of thumb, resources should never be copied nor moved. Handles are
  73055. * the way to go to push references around.
  73056. *
  73057. * @tparam Type Type of resource managed by a handle.
  73058. */
  73059. template<typename Type>
  73060. class resource {
  73061. template<typename>
  73062. friend class resource;
  73063. template<typename Other>
  73064. static constexpr bool is_acceptable = !std::is_same_v<Type, Other> && std::is_constructible_v<Type &, Other &>;
  73065. public:
  73066. /*! @brief Resource type. */
  73067. using element_type = Type;
  73068. /*! @brief Handle type. */
  73069. using handle_type = std::shared_ptr<element_type>;
  73070. /*! @brief Default constructor. */
  73071. resource() noexcept
  73072. : value{} {}
  73073. /**
  73074. * @brief Creates a new resource handle.
  73075. * @param res A handle to a resource.
  73076. */
  73077. explicit resource(handle_type res) noexcept
  73078. : value{std::move(res)} {}
  73079. /*! @brief Default copy constructor. */
  73080. resource(const resource &) noexcept = default;
  73081. /*! @brief Default move constructor. */
  73082. resource(resource &&) noexcept = default;
  73083. /**
  73084. * @brief Aliasing constructor.
  73085. * @tparam Other Type of resource managed by the received handle.
  73086. * @param other The handle with which to share ownership information.
  73087. * @param res Unrelated and unmanaged resources.
  73088. */
  73089. template<typename Other>
  73090. resource(const resource<Other> &other, element_type &res) noexcept
  73091. : value{other.value, std::addressof(res)} {}
  73092. /**
  73093. * @brief Copy constructs a handle which shares ownership of the resource.
  73094. * @tparam Other Type of resource managed by the received handle.
  73095. * @param other The handle to copy from.
  73096. */
  73097. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  73098. resource(const resource<Other> &other) noexcept
  73099. : value{other.value} {}
  73100. /**
  73101. * @brief Move constructs a handle which takes ownership of the resource.
  73102. * @tparam Other Type of resource managed by the received handle.
  73103. * @param other The handle to move from.
  73104. */
  73105. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  73106. resource(resource<Other> &&other) noexcept
  73107. : value{std::move(other.value)} {}
  73108. /*! @brief Default destructor. */
  73109. ~resource() = default;
  73110. /**
  73111. * @brief Default copy assignment operator.
  73112. * @return This resource handle.
  73113. */
  73114. resource &operator=(const resource &) noexcept = default;
  73115. /**
  73116. * @brief Default move assignment operator.
  73117. * @return This resource handle.
  73118. */
  73119. resource &operator=(resource &&) noexcept = default;
  73120. /**
  73121. * @brief Copy assignment operator from foreign handle.
  73122. * @tparam Other Type of resource managed by the received handle.
  73123. * @param other The handle to copy from.
  73124. * @return This resource handle.
  73125. */
  73126. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  73127. resource &operator=(const resource<Other> &other) noexcept {
  73128. value = other.value;
  73129. return *this;
  73130. }
  73131. /**
  73132. * @brief Move assignment operator from foreign handle.
  73133. * @tparam Other Type of resource managed by the received handle.
  73134. * @param other The handle to move from.
  73135. * @return This resource handle.
  73136. */
  73137. template<typename Other, typename = std::enable_if_t<is_acceptable<Other>>>
  73138. resource &operator=(resource<Other> &&other) noexcept {
  73139. value = std::move(other.value);
  73140. return *this;
  73141. }
  73142. /**
  73143. * @brief Exchanges the content with that of a given resource.
  73144. * @param other Resource to exchange the content with.
  73145. */
  73146. void swap(resource &other) noexcept {
  73147. using std::swap;
  73148. swap(value, other.value);
  73149. }
  73150. /**
  73151. * @brief Returns a reference to the managed resource.
  73152. *
  73153. * @warning
  73154. * The behavior is undefined if the handle doesn't contain a resource.
  73155. *
  73156. * @return A reference to the managed resource.
  73157. */
  73158. [[nodiscard]] element_type &operator*() const noexcept {
  73159. return *value;
  73160. }
  73161. /*! @copydoc operator* */
  73162. [[nodiscard]] operator element_type &() const noexcept {
  73163. return *value;
  73164. }
  73165. /**
  73166. * @brief Returns a pointer to the managed resource.
  73167. * @return A pointer to the managed resource.
  73168. */
  73169. [[nodiscard]] element_type *operator->() const noexcept {
  73170. return value.get();
  73171. }
  73172. /**
  73173. * @brief Returns true if a handle contains a resource, false otherwise.
  73174. * @return True if the handle contains a resource, false otherwise.
  73175. */
  73176. [[nodiscard]] explicit operator bool() const noexcept {
  73177. return static_cast<bool>(value);
  73178. }
  73179. /*! @brief Releases the ownership of the managed resource. */
  73180. void reset() {
  73181. value.reset();
  73182. }
  73183. /**
  73184. * @brief Replaces the managed resource.
  73185. * @param other A handle to a resource.
  73186. */
  73187. void reset(handle_type other) {
  73188. value = std::move(other);
  73189. }
  73190. /**
  73191. * @brief Returns the underlying resource handle.
  73192. * @return The underlying resource handle.
  73193. */
  73194. [[nodiscard]] handle_type handle() const noexcept {
  73195. return value;
  73196. }
  73197. private:
  73198. handle_type value;
  73199. };
  73200. /**
  73201. * @brief Compares two handles.
  73202. * @tparam Lhs Type of resource managed by the first handle.
  73203. * @tparam Rhs Type of resource managed by the second handle.
  73204. * @param lhs A valid handle.
  73205. * @param rhs A valid handle.
  73206. * @return True if both handles refer to the same resource, false otherwise.
  73207. */
  73208. template<typename Lhs, typename Rhs>
  73209. [[nodiscard]] bool operator==(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  73210. return (std::addressof(*lhs) == std::addressof(*rhs));
  73211. }
  73212. /**
  73213. * @brief Compares two handles.
  73214. * @tparam Lhs Type of resource managed by the first handle.
  73215. * @tparam Rhs Type of resource managed by the second handle.
  73216. * @param lhs A valid handle.
  73217. * @param rhs A valid handle.
  73218. * @return False if both handles refer to the same resource, true otherwise.
  73219. */
  73220. template<typename Lhs, typename Rhs>
  73221. [[nodiscard]] bool operator!=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  73222. return !(lhs == rhs);
  73223. }
  73224. /**
  73225. * @brief Compares two handles.
  73226. * @tparam Lhs Type of resource managed by the first handle.
  73227. * @tparam Rhs Type of resource managed by the second handle.
  73228. * @param lhs A valid handle.
  73229. * @param rhs A valid handle.
  73230. * @return True if the first handle is less than the second, false otherwise.
  73231. */
  73232. template<typename Lhs, typename Rhs>
  73233. [[nodiscard]] bool operator<(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  73234. return (std::addressof(*lhs) < std::addressof(*rhs));
  73235. }
  73236. /**
  73237. * @brief Compares two handles.
  73238. * @tparam Lhs Type of resource managed by the first handle.
  73239. * @tparam Rhs Type of resource managed by the second handle.
  73240. * @param lhs A valid handle.
  73241. * @param rhs A valid handle.
  73242. * @return True if the first handle is greater than the second, false otherwise.
  73243. */
  73244. template<typename Lhs, typename Rhs>
  73245. [[nodiscard]] bool operator>(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  73246. return rhs < lhs;
  73247. }
  73248. /**
  73249. * @brief Compares two handles.
  73250. * @tparam Lhs Type of resource managed by the first handle.
  73251. * @tparam Rhs Type of resource managed by the second handle.
  73252. * @param lhs A valid handle.
  73253. * @param rhs A valid handle.
  73254. * @return True if the first handle is less than or equal to the second, false
  73255. * otherwise.
  73256. */
  73257. template<typename Lhs, typename Rhs>
  73258. [[nodiscard]] bool operator<=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  73259. return !(lhs > rhs);
  73260. }
  73261. /**
  73262. * @brief Compares two handles.
  73263. * @tparam Lhs Type of resource managed by the first handle.
  73264. * @tparam Rhs Type of resource managed by the second handle.
  73265. * @param lhs A valid handle.
  73266. * @param rhs A valid handle.
  73267. * @return True if the first handle is greater than or equal to the second,
  73268. * false otherwise.
  73269. */
  73270. template<typename Lhs, typename Rhs>
  73271. [[nodiscard]] bool operator>=(const resource<Lhs> &lhs, const resource<Rhs> &rhs) noexcept {
  73272. return !(lhs < rhs);
  73273. }
  73274. } // namespace entt
  73275. #endif
  73276. // #include "signal/delegate.hpp"
  73277. #ifndef ENTT_SIGNAL_DELEGATE_HPP
  73278. #define ENTT_SIGNAL_DELEGATE_HPP
  73279. #include <cstddef>
  73280. #include <functional>
  73281. #include <tuple>
  73282. #include <type_traits>
  73283. #include <utility>
  73284. // #include "../config/config.h"
  73285. #ifndef ENTT_CONFIG_CONFIG_H
  73286. #define ENTT_CONFIG_CONFIG_H
  73287. // #include "version.h"
  73288. #ifndef ENTT_CONFIG_VERSION_H
  73289. #define ENTT_CONFIG_VERSION_H
  73290. // #include "macro.h"
  73291. #ifndef ENTT_CONFIG_MACRO_H
  73292. #define ENTT_CONFIG_MACRO_H
  73293. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  73294. #define ENTT_STR(arg) #arg
  73295. #define ENTT_XSTR(arg) ENTT_STR(arg)
  73296. // NOLINTEND(cppcoreguidelines-macro-usage)
  73297. #endif
  73298. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  73299. #define ENTT_VERSION_MAJOR 3
  73300. #define ENTT_VERSION_MINOR 16
  73301. #define ENTT_VERSION_PATCH 0
  73302. #define ENTT_VERSION \
  73303. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  73304. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  73305. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  73306. #endif
  73307. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  73308. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  73309. # define ENTT_CONSTEXPR
  73310. # define ENTT_THROW throw
  73311. # define ENTT_TRY try
  73312. # define ENTT_CATCH catch(...)
  73313. #else
  73314. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  73315. # define ENTT_THROW
  73316. # define ENTT_TRY if(true)
  73317. # define ENTT_CATCH if(false)
  73318. #endif
  73319. #if __has_include(<version>)
  73320. # include <version>
  73321. #
  73322. # if defined(__cpp_consteval)
  73323. # define ENTT_CONSTEVAL consteval
  73324. # endif
  73325. #endif
  73326. #ifndef ENTT_CONSTEVAL
  73327. # define ENTT_CONSTEVAL constexpr
  73328. #endif
  73329. #ifdef ENTT_USE_ATOMIC
  73330. # include <atomic>
  73331. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  73332. #else
  73333. # define ENTT_MAYBE_ATOMIC(Type) Type
  73334. #endif
  73335. #ifndef ENTT_ID_TYPE
  73336. # include <cstdint>
  73337. # define ENTT_ID_TYPE std::uint32_t
  73338. #else
  73339. # include <cstdint> // provides coverage for types in the std namespace
  73340. #endif
  73341. #ifndef ENTT_SPARSE_PAGE
  73342. # define ENTT_SPARSE_PAGE 4096
  73343. #endif
  73344. #ifndef ENTT_PACKED_PAGE
  73345. # define ENTT_PACKED_PAGE 1024
  73346. #endif
  73347. #ifdef ENTT_DISABLE_ASSERT
  73348. # undef ENTT_ASSERT
  73349. # define ENTT_ASSERT(condition, msg) (void(0))
  73350. #elif !defined ENTT_ASSERT
  73351. # include <cassert>
  73352. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  73353. #endif
  73354. #ifdef ENTT_DISABLE_ASSERT
  73355. # undef ENTT_ASSERT_CONSTEXPR
  73356. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  73357. #elif !defined ENTT_ASSERT_CONSTEXPR
  73358. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  73359. #endif
  73360. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  73361. #ifdef ENTT_NO_ETO
  73362. # define ENTT_ETO_TYPE(Type) void
  73363. #else
  73364. # define ENTT_ETO_TYPE(Type) Type
  73365. #endif
  73366. #ifdef ENTT_NO_MIXIN
  73367. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  73368. #else
  73369. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  73370. #endif
  73371. #ifdef ENTT_STANDARD_CPP
  73372. # define ENTT_NONSTD false
  73373. #else
  73374. # define ENTT_NONSTD true
  73375. # if defined __clang__ || defined __GNUC__
  73376. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  73377. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  73378. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  73379. # elif defined _MSC_VER
  73380. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  73381. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  73382. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  73383. # endif
  73384. #endif
  73385. #ifndef ENTT_EXPORT
  73386. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  73387. # define ENTT_EXPORT __declspec(dllexport)
  73388. # define ENTT_IMPORT __declspec(dllimport)
  73389. # define ENTT_HIDDEN
  73390. # elif defined __GNUC__ && __GNUC__ >= 4
  73391. # define ENTT_EXPORT __attribute__((visibility("default")))
  73392. # define ENTT_IMPORT __attribute__((visibility("default")))
  73393. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  73394. # else /* Unsupported compiler */
  73395. # define ENTT_EXPORT
  73396. # define ENTT_IMPORT
  73397. # define ENTT_HIDDEN
  73398. # endif
  73399. #endif
  73400. #ifndef ENTT_API
  73401. # if defined ENTT_API_EXPORT
  73402. # define ENTT_API ENTT_EXPORT
  73403. # elif defined ENTT_API_IMPORT
  73404. # define ENTT_API ENTT_IMPORT
  73405. # else /* No API */
  73406. # define ENTT_API
  73407. # endif
  73408. #endif
  73409. #if defined _MSC_VER
  73410. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  73411. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  73412. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  73413. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  73414. #endif
  73415. // NOLINTEND(cppcoreguidelines-macro-usage)
  73416. #endif
  73417. // #include "../core/type_traits.hpp"
  73418. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  73419. #define ENTT_CORE_TYPE_TRAITS_HPP
  73420. #include <cstddef>
  73421. #include <iterator>
  73422. #include <tuple>
  73423. #include <type_traits>
  73424. #include <utility>
  73425. // #include "../config/config.h"
  73426. #ifndef ENTT_CONFIG_CONFIG_H
  73427. #define ENTT_CONFIG_CONFIG_H
  73428. // #include "version.h"
  73429. #ifndef ENTT_CONFIG_VERSION_H
  73430. #define ENTT_CONFIG_VERSION_H
  73431. // #include "macro.h"
  73432. #ifndef ENTT_CONFIG_MACRO_H
  73433. #define ENTT_CONFIG_MACRO_H
  73434. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  73435. #define ENTT_STR(arg) #arg
  73436. #define ENTT_XSTR(arg) ENTT_STR(arg)
  73437. // NOLINTEND(cppcoreguidelines-macro-usage)
  73438. #endif
  73439. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  73440. #define ENTT_VERSION_MAJOR 3
  73441. #define ENTT_VERSION_MINOR 16
  73442. #define ENTT_VERSION_PATCH 0
  73443. #define ENTT_VERSION \
  73444. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  73445. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  73446. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  73447. #endif
  73448. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  73449. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  73450. # define ENTT_CONSTEXPR
  73451. # define ENTT_THROW throw
  73452. # define ENTT_TRY try
  73453. # define ENTT_CATCH catch(...)
  73454. #else
  73455. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  73456. # define ENTT_THROW
  73457. # define ENTT_TRY if(true)
  73458. # define ENTT_CATCH if(false)
  73459. #endif
  73460. #if __has_include(<version>)
  73461. # include <version>
  73462. #
  73463. # if defined(__cpp_consteval)
  73464. # define ENTT_CONSTEVAL consteval
  73465. # endif
  73466. #endif
  73467. #ifndef ENTT_CONSTEVAL
  73468. # define ENTT_CONSTEVAL constexpr
  73469. #endif
  73470. #ifdef ENTT_USE_ATOMIC
  73471. # include <atomic>
  73472. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  73473. #else
  73474. # define ENTT_MAYBE_ATOMIC(Type) Type
  73475. #endif
  73476. #ifndef ENTT_ID_TYPE
  73477. # include <cstdint>
  73478. # define ENTT_ID_TYPE std::uint32_t
  73479. #else
  73480. # include <cstdint> // provides coverage for types in the std namespace
  73481. #endif
  73482. #ifndef ENTT_SPARSE_PAGE
  73483. # define ENTT_SPARSE_PAGE 4096
  73484. #endif
  73485. #ifndef ENTT_PACKED_PAGE
  73486. # define ENTT_PACKED_PAGE 1024
  73487. #endif
  73488. #ifdef ENTT_DISABLE_ASSERT
  73489. # undef ENTT_ASSERT
  73490. # define ENTT_ASSERT(condition, msg) (void(0))
  73491. #elif !defined ENTT_ASSERT
  73492. # include <cassert>
  73493. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  73494. #endif
  73495. #ifdef ENTT_DISABLE_ASSERT
  73496. # undef ENTT_ASSERT_CONSTEXPR
  73497. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  73498. #elif !defined ENTT_ASSERT_CONSTEXPR
  73499. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  73500. #endif
  73501. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  73502. #ifdef ENTT_NO_ETO
  73503. # define ENTT_ETO_TYPE(Type) void
  73504. #else
  73505. # define ENTT_ETO_TYPE(Type) Type
  73506. #endif
  73507. #ifdef ENTT_NO_MIXIN
  73508. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  73509. #else
  73510. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  73511. #endif
  73512. #ifdef ENTT_STANDARD_CPP
  73513. # define ENTT_NONSTD false
  73514. #else
  73515. # define ENTT_NONSTD true
  73516. # if defined __clang__ || defined __GNUC__
  73517. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  73518. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  73519. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  73520. # elif defined _MSC_VER
  73521. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  73522. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  73523. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  73524. # endif
  73525. #endif
  73526. #ifndef ENTT_EXPORT
  73527. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  73528. # define ENTT_EXPORT __declspec(dllexport)
  73529. # define ENTT_IMPORT __declspec(dllimport)
  73530. # define ENTT_HIDDEN
  73531. # elif defined __GNUC__ && __GNUC__ >= 4
  73532. # define ENTT_EXPORT __attribute__((visibility("default")))
  73533. # define ENTT_IMPORT __attribute__((visibility("default")))
  73534. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  73535. # else /* Unsupported compiler */
  73536. # define ENTT_EXPORT
  73537. # define ENTT_IMPORT
  73538. # define ENTT_HIDDEN
  73539. # endif
  73540. #endif
  73541. #ifndef ENTT_API
  73542. # if defined ENTT_API_EXPORT
  73543. # define ENTT_API ENTT_EXPORT
  73544. # elif defined ENTT_API_IMPORT
  73545. # define ENTT_API ENTT_IMPORT
  73546. # else /* No API */
  73547. # define ENTT_API
  73548. # endif
  73549. #endif
  73550. #if defined _MSC_VER
  73551. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  73552. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  73553. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  73554. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  73555. #endif
  73556. // NOLINTEND(cppcoreguidelines-macro-usage)
  73557. #endif
  73558. // #include "fwd.hpp"
  73559. #ifndef ENTT_CORE_FWD_HPP
  73560. #define ENTT_CORE_FWD_HPP
  73561. #include <cstddef>
  73562. #include <cstdint>
  73563. // #include "../config/config.h"
  73564. namespace entt {
  73565. /*! @brief Possible modes of an any object. */
  73566. enum class any_policy : std::uint8_t {
  73567. /*! @brief Default mode, no element available. */
  73568. empty,
  73569. /*! @brief Owning mode, dynamically allocated element. */
  73570. dynamic,
  73571. /*! @brief Owning mode, embedded element. */
  73572. embedded,
  73573. /*! @brief Aliasing mode, non-const reference. */
  73574. ref,
  73575. /*! @brief Const aliasing mode, const reference. */
  73576. cref
  73577. };
  73578. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  73579. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  73580. class basic_any;
  73581. /*! @brief Alias declaration for type identifiers. */
  73582. using id_type = ENTT_ID_TYPE;
  73583. /*! @brief Alias declaration for the most common use case. */
  73584. using any = basic_any<>;
  73585. template<typename, typename>
  73586. class compressed_pair;
  73587. template<typename>
  73588. class basic_hashed_string;
  73589. /*! @brief Aliases for common character types. */
  73590. using hashed_string = basic_hashed_string<char>;
  73591. /*! @brief Aliases for common character types. */
  73592. using hashed_wstring = basic_hashed_string<wchar_t>;
  73593. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  73594. struct type_info;
  73595. } // namespace entt
  73596. #endif
  73597. namespace entt {
  73598. /**
  73599. * @brief Utility class to disambiguate overloaded functions.
  73600. * @tparam N Number of choices available.
  73601. */
  73602. template<std::size_t N>
  73603. struct choice_t
  73604. // unfortunately, doxygen cannot parse such a construct
  73605. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  73606. {};
  73607. /*! @copybrief choice_t */
  73608. template<>
  73609. struct choice_t<0> {};
  73610. /**
  73611. * @brief Variable template for the choice trick.
  73612. * @tparam N Number of choices available.
  73613. */
  73614. template<std::size_t N>
  73615. inline constexpr choice_t<N> choice{};
  73616. /**
  73617. * @brief Identity type trait.
  73618. *
  73619. * Useful to establish non-deduced contexts in template argument deduction
  73620. * (waiting for C++20) or to provide types through function arguments.
  73621. *
  73622. * @tparam Type A type.
  73623. */
  73624. template<typename Type>
  73625. struct type_identity {
  73626. /*! @brief Identity type. */
  73627. using type = Type;
  73628. };
  73629. /**
  73630. * @brief Helper type.
  73631. * @tparam Type A type.
  73632. */
  73633. template<typename Type>
  73634. using type_identity_t = typename type_identity<Type>::type;
  73635. /**
  73636. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  73637. * @tparam Type The type of which to return the size.
  73638. */
  73639. template<typename Type, typename = void>
  73640. struct size_of: std::integral_constant<std::size_t, 0u> {};
  73641. /*! @copydoc size_of */
  73642. template<typename Type>
  73643. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  73644. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  73645. : std::integral_constant<std::size_t, sizeof(Type)> {};
  73646. /**
  73647. * @brief Helper variable template.
  73648. * @tparam Type The type of which to return the size.
  73649. */
  73650. template<typename Type>
  73651. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  73652. /**
  73653. * @brief Using declaration to be used to _repeat_ the same type a number of
  73654. * times equal to the size of a given parameter pack.
  73655. * @tparam Type A type to repeat.
  73656. */
  73657. template<typename Type, typename>
  73658. using unpack_as_type = Type;
  73659. /**
  73660. * @brief Helper variable template to be used to _repeat_ the same value a
  73661. * number of times equal to the size of a given parameter pack.
  73662. * @tparam Value A value to repeat.
  73663. */
  73664. template<auto Value, typename>
  73665. inline constexpr auto unpack_as_value = Value;
  73666. /**
  73667. * @brief Wraps a static constant.
  73668. * @tparam Value A static constant.
  73669. */
  73670. template<auto Value>
  73671. using integral_constant = std::integral_constant<decltype(Value), Value>;
  73672. /**
  73673. * @brief Alias template to facilitate the creation of named values.
  73674. * @tparam Value A constant value at least convertible to `id_type`.
  73675. */
  73676. template<id_type Value>
  73677. using tag = integral_constant<Value>;
  73678. /**
  73679. * @brief A class to use to push around lists of types, nothing more.
  73680. * @tparam Type Types provided by the type list.
  73681. */
  73682. template<typename... Type>
  73683. struct type_list {
  73684. /*! @brief Type list type. */
  73685. using type = type_list;
  73686. /*! @brief Compile-time number of elements in the type list. */
  73687. static constexpr auto size = sizeof...(Type);
  73688. };
  73689. /*! @brief Primary template isn't defined on purpose. */
  73690. template<std::size_t, typename>
  73691. struct type_list_element;
  73692. /**
  73693. * @brief Provides compile-time indexed access to the types of a type list.
  73694. * @tparam Index Index of the type to return.
  73695. * @tparam First First type provided by the type list.
  73696. * @tparam Other Other types provided by the type list.
  73697. */
  73698. template<std::size_t Index, typename First, typename... Other>
  73699. struct type_list_element<Index, type_list<First, Other...>>
  73700. : type_list_element<Index - 1u, type_list<Other...>> {};
  73701. /**
  73702. * @brief Provides compile-time indexed access to the types of a type list.
  73703. * @tparam First First type provided by the type list.
  73704. * @tparam Other Other types provided by the type list.
  73705. */
  73706. template<typename First, typename... Other>
  73707. struct type_list_element<0u, type_list<First, Other...>> {
  73708. /*! @brief Searched type. */
  73709. using type = First;
  73710. };
  73711. /**
  73712. * @brief Helper type.
  73713. * @tparam Index Index of the type to return.
  73714. * @tparam List Type list to search into.
  73715. */
  73716. template<std::size_t Index, typename List>
  73717. using type_list_element_t = typename type_list_element<Index, List>::type;
  73718. /*! @brief Primary template isn't defined on purpose. */
  73719. template<typename, typename>
  73720. struct type_list_index;
  73721. /**
  73722. * @brief Provides compile-time type access to the types of a type list.
  73723. * @tparam Type Type to look for and for which to return the index.
  73724. * @tparam First First type provided by the type list.
  73725. * @tparam Other Other types provided by the type list.
  73726. */
  73727. template<typename Type, typename First, typename... Other>
  73728. struct type_list_index<Type, type_list<First, Other...>> {
  73729. /*! @brief Unsigned integer type. */
  73730. using value_type = std::size_t;
  73731. /*! @brief Compile-time position of the given type in the sublist. */
  73732. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  73733. };
  73734. /**
  73735. * @brief Provides compile-time type access to the types of a type list.
  73736. * @tparam Type Type to look for and for which to return the index.
  73737. * @tparam Other Other types provided by the type list.
  73738. */
  73739. template<typename Type, typename... Other>
  73740. struct type_list_index<Type, type_list<Type, Other...>> {
  73741. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  73742. /*! @brief Unsigned integer type. */
  73743. using value_type = std::size_t;
  73744. /*! @brief Compile-time position of the given type in the sublist. */
  73745. static constexpr value_type value = 0u;
  73746. };
  73747. /**
  73748. * @brief Provides compile-time type access to the types of a type list.
  73749. * @tparam Type Type to look for and for which to return the index.
  73750. */
  73751. template<typename Type>
  73752. struct type_list_index<Type, type_list<>> {
  73753. /*! @brief Unsigned integer type. */
  73754. using value_type = std::size_t;
  73755. /*! @brief Compile-time position of the given type in the sublist. */
  73756. static constexpr value_type value = 0u;
  73757. };
  73758. /**
  73759. * @brief Helper variable template.
  73760. * @tparam List Type list.
  73761. * @tparam Type Type to look for and for which to return the index.
  73762. */
  73763. template<typename Type, typename List>
  73764. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  73765. /**
  73766. * @brief Concatenates multiple type lists.
  73767. * @tparam Type Types provided by the first type list.
  73768. * @tparam Other Types provided by the second type list.
  73769. * @return A type list composed by the types of both the type lists.
  73770. */
  73771. template<typename... Type, typename... Other>
  73772. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  73773. return {};
  73774. }
  73775. /*! @brief Primary template isn't defined on purpose. */
  73776. template<typename...>
  73777. struct type_list_cat;
  73778. /*! @brief Concatenates multiple type lists. */
  73779. template<>
  73780. struct type_list_cat<> {
  73781. /*! @brief A type list composed by the types of all the type lists. */
  73782. using type = type_list<>;
  73783. };
  73784. /**
  73785. * @brief Concatenates multiple type lists.
  73786. * @tparam Type Types provided by the first type list.
  73787. * @tparam Other Types provided by the second type list.
  73788. * @tparam List Other type lists, if any.
  73789. */
  73790. template<typename... Type, typename... Other, typename... List>
  73791. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  73792. /*! @brief A type list composed by the types of all the type lists. */
  73793. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  73794. };
  73795. /**
  73796. * @brief Concatenates multiple type lists.
  73797. * @tparam Type Types provided by the type list.
  73798. */
  73799. template<typename... Type>
  73800. struct type_list_cat<type_list<Type...>> {
  73801. /*! @brief A type list composed by the types of all the type lists. */
  73802. using type = type_list<Type...>;
  73803. };
  73804. /**
  73805. * @brief Helper type.
  73806. * @tparam List Type lists to concatenate.
  73807. */
  73808. template<typename... List>
  73809. using type_list_cat_t = typename type_list_cat<List...>::type;
  73810. /*! @cond TURN_OFF_DOXYGEN */
  73811. namespace internal {
  73812. template<typename...>
  73813. struct type_list_unique;
  73814. template<typename First, typename... Other, typename... Type>
  73815. struct type_list_unique<type_list<First, Other...>, Type...>
  73816. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  73817. template<typename... Type>
  73818. struct type_list_unique<type_list<>, Type...> {
  73819. using type = type_list<Type...>;
  73820. };
  73821. } // namespace internal
  73822. /*! @endcond */
  73823. /**
  73824. * @brief Removes duplicates types from a type list.
  73825. * @tparam List Type list.
  73826. */
  73827. template<typename List>
  73828. struct type_list_unique {
  73829. /*! @brief A type list without duplicate types. */
  73830. using type = typename internal::type_list_unique<List>::type;
  73831. };
  73832. /**
  73833. * @brief Helper type.
  73834. * @tparam List Type list.
  73835. */
  73836. template<typename List>
  73837. using type_list_unique_t = typename type_list_unique<List>::type;
  73838. /**
  73839. * @brief Provides the member constant `value` to true if a type list contains a
  73840. * given type, false otherwise.
  73841. * @tparam List Type list.
  73842. * @tparam Type Type to look for.
  73843. */
  73844. template<typename List, typename Type>
  73845. struct type_list_contains;
  73846. /**
  73847. * @copybrief type_list_contains
  73848. * @tparam Type Types provided by the type list.
  73849. * @tparam Other Type to look for.
  73850. */
  73851. template<typename... Type, typename Other>
  73852. struct type_list_contains<type_list<Type...>, Other>
  73853. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  73854. /**
  73855. * @brief Helper variable template.
  73856. * @tparam List Type list.
  73857. * @tparam Type Type to look for.
  73858. */
  73859. template<typename List, typename Type>
  73860. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  73861. /*! @brief Primary template isn't defined on purpose. */
  73862. template<typename...>
  73863. struct type_list_diff;
  73864. /**
  73865. * @brief Computes the difference between two type lists.
  73866. * @tparam Type Types provided by the first type list.
  73867. * @tparam Other Types provided by the second type list.
  73868. */
  73869. template<typename... Type, typename... Other>
  73870. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  73871. /*! @brief A type list that is the difference between the two type lists. */
  73872. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  73873. };
  73874. /**
  73875. * @brief Helper type.
  73876. * @tparam List Type lists between which to compute the difference.
  73877. */
  73878. template<typename... List>
  73879. using type_list_diff_t = typename type_list_diff<List...>::type;
  73880. /*! @brief Primary template isn't defined on purpose. */
  73881. template<typename, template<typename...> class>
  73882. struct type_list_transform;
  73883. /**
  73884. * @brief Applies a given _function_ to a type list and generate a new list.
  73885. * @tparam Type Types provided by the type list.
  73886. * @tparam Op Unary operation as template class with a type member named `type`.
  73887. */
  73888. template<typename... Type, template<typename...> class Op>
  73889. struct type_list_transform<type_list<Type...>, Op> {
  73890. /*! @brief Resulting type list after applying the transform function. */
  73891. // NOLINTNEXTLINE(modernize-type-traits)
  73892. using type = type_list<typename Op<Type>::type...>;
  73893. };
  73894. /**
  73895. * @brief Helper type.
  73896. * @tparam List Type list.
  73897. * @tparam Op Unary operation as template class with a type member named `type`.
  73898. */
  73899. template<typename List, template<typename...> class Op>
  73900. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  73901. /**
  73902. * @brief A class to use to push around lists of constant values, nothing more.
  73903. * @tparam Value Values provided by the value list.
  73904. */
  73905. template<auto... Value>
  73906. struct value_list {
  73907. /*! @brief Value list type. */
  73908. using type = value_list;
  73909. /*! @brief Compile-time number of elements in the value list. */
  73910. static constexpr auto size = sizeof...(Value);
  73911. };
  73912. /*! @brief Primary template isn't defined on purpose. */
  73913. template<std::size_t, typename>
  73914. struct value_list_element;
  73915. /**
  73916. * @brief Provides compile-time indexed access to the values of a value list.
  73917. * @tparam Index Index of the value to return.
  73918. * @tparam Value First value provided by the value list.
  73919. * @tparam Other Other values provided by the value list.
  73920. */
  73921. template<std::size_t Index, auto Value, auto... Other>
  73922. struct value_list_element<Index, value_list<Value, Other...>>
  73923. : value_list_element<Index - 1u, value_list<Other...>> {};
  73924. /**
  73925. * @brief Provides compile-time indexed access to the types of a type list.
  73926. * @tparam Value First value provided by the value list.
  73927. * @tparam Other Other values provided by the value list.
  73928. */
  73929. template<auto Value, auto... Other>
  73930. struct value_list_element<0u, value_list<Value, Other...>> {
  73931. /*! @brief Searched type. */
  73932. using type = decltype(Value);
  73933. /*! @brief Searched value. */
  73934. static constexpr auto value = Value;
  73935. };
  73936. /**
  73937. * @brief Helper type.
  73938. * @tparam Index Index of the type to return.
  73939. * @tparam List Value list to search into.
  73940. */
  73941. template<std::size_t Index, typename List>
  73942. using value_list_element_t = typename value_list_element<Index, List>::type;
  73943. /**
  73944. * @brief Helper type.
  73945. * @tparam Index Index of the value to return.
  73946. * @tparam List Value list to search into.
  73947. */
  73948. template<std::size_t Index, typename List>
  73949. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  73950. /*! @brief Primary template isn't defined on purpose. */
  73951. template<auto, typename>
  73952. struct value_list_index;
  73953. /**
  73954. * @brief Provides compile-time type access to the values of a value list.
  73955. * @tparam Value Value to look for and for which to return the index.
  73956. * @tparam First First value provided by the value list.
  73957. * @tparam Other Other values provided by the value list.
  73958. */
  73959. template<auto Value, auto First, auto... Other>
  73960. struct value_list_index<Value, value_list<First, Other...>> {
  73961. /*! @brief Unsigned integer type. */
  73962. using value_type = std::size_t;
  73963. /*! @brief Compile-time position of the given value in the sublist. */
  73964. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  73965. };
  73966. /**
  73967. * @brief Provides compile-time type access to the values of a value list.
  73968. * @tparam Value Value to look for and for which to return the index.
  73969. * @tparam Other Other values provided by the value list.
  73970. */
  73971. template<auto Value, auto... Other>
  73972. struct value_list_index<Value, value_list<Value, Other...>> {
  73973. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  73974. /*! @brief Unsigned integer type. */
  73975. using value_type = std::size_t;
  73976. /*! @brief Compile-time position of the given value in the sublist. */
  73977. static constexpr value_type value = 0u;
  73978. };
  73979. /**
  73980. * @brief Provides compile-time type access to the values of a value list.
  73981. * @tparam Value Value to look for and for which to return the index.
  73982. */
  73983. template<auto Value>
  73984. struct value_list_index<Value, value_list<>> {
  73985. /*! @brief Unsigned integer type. */
  73986. using value_type = std::size_t;
  73987. /*! @brief Compile-time position of the given type in the sublist. */
  73988. static constexpr value_type value = 0u;
  73989. };
  73990. /**
  73991. * @brief Helper variable template.
  73992. * @tparam List Value list.
  73993. * @tparam Value Value to look for and for which to return the index.
  73994. */
  73995. template<auto Value, typename List>
  73996. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  73997. /**
  73998. * @brief Concatenates multiple value lists.
  73999. * @tparam Value Values provided by the first value list.
  74000. * @tparam Other Values provided by the second value list.
  74001. * @return A value list composed by the values of both the value lists.
  74002. */
  74003. template<auto... Value, auto... Other>
  74004. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  74005. return {};
  74006. }
  74007. /*! @brief Primary template isn't defined on purpose. */
  74008. template<typename...>
  74009. struct value_list_cat;
  74010. /*! @brief Concatenates multiple value lists. */
  74011. template<>
  74012. struct value_list_cat<> {
  74013. /*! @brief A value list composed by the values of all the value lists. */
  74014. using type = value_list<>;
  74015. };
  74016. /**
  74017. * @brief Concatenates multiple value lists.
  74018. * @tparam Value Values provided by the first value list.
  74019. * @tparam Other Values provided by the second value list.
  74020. * @tparam List Other value lists, if any.
  74021. */
  74022. template<auto... Value, auto... Other, typename... List>
  74023. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  74024. /*! @brief A value list composed by the values of all the value lists. */
  74025. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  74026. };
  74027. /**
  74028. * @brief Concatenates multiple value lists.
  74029. * @tparam Value Values provided by the value list.
  74030. */
  74031. template<auto... Value>
  74032. struct value_list_cat<value_list<Value...>> {
  74033. /*! @brief A value list composed by the values of all the value lists. */
  74034. using type = value_list<Value...>;
  74035. };
  74036. /**
  74037. * @brief Helper type.
  74038. * @tparam List Value lists to concatenate.
  74039. */
  74040. template<typename... List>
  74041. using value_list_cat_t = typename value_list_cat<List...>::type;
  74042. /*! @brief Primary template isn't defined on purpose. */
  74043. template<typename>
  74044. struct value_list_unique;
  74045. /**
  74046. * @brief Removes duplicates values from a value list.
  74047. * @tparam Value One of the values provided by the given value list.
  74048. * @tparam Other The other values provided by the given value list.
  74049. */
  74050. template<auto Value, auto... Other>
  74051. struct value_list_unique<value_list<Value, Other...>> {
  74052. /*! @brief A value list without duplicate types. */
  74053. using type = std::conditional_t<
  74054. ((Value == Other) || ...),
  74055. typename value_list_unique<value_list<Other...>>::type,
  74056. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  74057. };
  74058. /*! @brief Removes duplicates values from a value list. */
  74059. template<>
  74060. struct value_list_unique<value_list<>> {
  74061. /*! @brief A value list without duplicate types. */
  74062. using type = value_list<>;
  74063. };
  74064. /**
  74065. * @brief Helper type.
  74066. * @tparam Type A value list.
  74067. */
  74068. template<typename Type>
  74069. using value_list_unique_t = typename value_list_unique<Type>::type;
  74070. /**
  74071. * @brief Provides the member constant `value` to true if a value list contains
  74072. * a given value, false otherwise.
  74073. * @tparam List Value list.
  74074. * @tparam Value Value to look for.
  74075. */
  74076. template<typename List, auto Value>
  74077. struct value_list_contains;
  74078. /**
  74079. * @copybrief value_list_contains
  74080. * @tparam Value Values provided by the value list.
  74081. * @tparam Other Value to look for.
  74082. */
  74083. template<auto... Value, auto Other>
  74084. struct value_list_contains<value_list<Value...>, Other>
  74085. : std::bool_constant<((Value == Other) || ...)> {};
  74086. /**
  74087. * @brief Helper variable template.
  74088. * @tparam List Value list.
  74089. * @tparam Value Value to look for.
  74090. */
  74091. template<typename List, auto Value>
  74092. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  74093. /*! @brief Primary template isn't defined on purpose. */
  74094. template<typename...>
  74095. struct value_list_diff;
  74096. /**
  74097. * @brief Computes the difference between two value lists.
  74098. * @tparam Value Values provided by the first value list.
  74099. * @tparam Other Values provided by the second value list.
  74100. */
  74101. template<auto... Value, auto... Other>
  74102. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  74103. /*! @brief A value list that is the difference between the two value lists. */
  74104. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  74105. };
  74106. /**
  74107. * @brief Helper type.
  74108. * @tparam List Value lists between which to compute the difference.
  74109. */
  74110. template<typename... List>
  74111. using value_list_diff_t = typename value_list_diff<List...>::type;
  74112. /*! @brief Same as std::is_invocable, but with tuples. */
  74113. template<typename, typename>
  74114. struct is_applicable: std::false_type {};
  74115. /**
  74116. * @copybrief is_applicable
  74117. * @tparam Func A valid function type.
  74118. * @tparam Tuple Tuple-like type.
  74119. * @tparam Args The list of arguments to use to probe the function type.
  74120. */
  74121. template<typename Func, template<typename...> class Tuple, typename... Args>
  74122. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  74123. /**
  74124. * @copybrief is_applicable
  74125. * @tparam Func A valid function type.
  74126. * @tparam Tuple Tuple-like type.
  74127. * @tparam Args The list of arguments to use to probe the function type.
  74128. */
  74129. template<typename Func, template<typename...> class Tuple, typename... Args>
  74130. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  74131. /**
  74132. * @brief Helper variable template.
  74133. * @tparam Func A valid function type.
  74134. * @tparam Args The list of arguments to use to probe the function type.
  74135. */
  74136. template<typename Func, typename Args>
  74137. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  74138. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  74139. template<typename, typename, typename>
  74140. struct is_applicable_r: std::false_type {};
  74141. /**
  74142. * @copybrief is_applicable_r
  74143. * @tparam Ret The type to which the return type of the function should be
  74144. * convertible.
  74145. * @tparam Func A valid function type.
  74146. * @tparam Args The list of arguments to use to probe the function type.
  74147. */
  74148. template<typename Ret, typename Func, typename... Args>
  74149. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  74150. /**
  74151. * @brief Helper variable template.
  74152. * @tparam Ret The type to which the return type of the function should be
  74153. * convertible.
  74154. * @tparam Func A valid function type.
  74155. * @tparam Args The list of arguments to use to probe the function type.
  74156. */
  74157. template<typename Ret, typename Func, typename Args>
  74158. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  74159. /**
  74160. * @brief Provides the member constant `value` to true if a given type is
  74161. * complete, false otherwise.
  74162. * @tparam Type The type to test.
  74163. */
  74164. template<typename Type, typename = void>
  74165. struct is_complete: std::false_type {};
  74166. /*! @copydoc is_complete */
  74167. template<typename Type>
  74168. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  74169. /**
  74170. * @brief Helper variable template.
  74171. * @tparam Type The type to test.
  74172. */
  74173. template<typename Type>
  74174. inline constexpr bool is_complete_v = is_complete<Type>::value;
  74175. /**
  74176. * @brief Provides the member constant `value` to true if a given type is an
  74177. * iterator, false otherwise.
  74178. * @tparam Type The type to test.
  74179. */
  74180. template<typename Type, typename = void>
  74181. struct is_iterator: std::false_type {};
  74182. /*! @cond TURN_OFF_DOXYGEN */
  74183. namespace internal {
  74184. template<typename, typename = void>
  74185. struct has_iterator_category: std::false_type {};
  74186. template<typename Type>
  74187. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  74188. } // namespace internal
  74189. /*! @endcond */
  74190. /*! @copydoc is_iterator */
  74191. template<typename Type>
  74192. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  74193. : internal::has_iterator_category<Type> {};
  74194. /**
  74195. * @brief Helper variable template.
  74196. * @tparam Type The type to test.
  74197. */
  74198. template<typename Type>
  74199. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  74200. /**
  74201. * @brief Provides the member constant `value` to true if a given type is both
  74202. * an empty and non-final class, false otherwise.
  74203. * @tparam Type The type to test
  74204. */
  74205. template<typename Type>
  74206. struct is_ebco_eligible
  74207. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  74208. /**
  74209. * @brief Helper variable template.
  74210. * @tparam Type The type to test.
  74211. */
  74212. template<typename Type>
  74213. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  74214. /**
  74215. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  74216. * is valid and denotes a type, false otherwise.
  74217. * @tparam Type The type to test.
  74218. */
  74219. template<typename Type, typename = void>
  74220. struct is_transparent: std::false_type {};
  74221. /*! @copydoc is_transparent */
  74222. template<typename Type>
  74223. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  74224. /**
  74225. * @brief Helper variable template.
  74226. * @tparam Type The type to test.
  74227. */
  74228. template<typename Type>
  74229. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  74230. /*! @cond TURN_OFF_DOXYGEN */
  74231. namespace internal {
  74232. template<typename, typename = void>
  74233. struct has_tuple_size_value: std::false_type {};
  74234. template<typename Type>
  74235. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  74236. template<typename, typename = void>
  74237. struct has_value_type: std::false_type {};
  74238. template<typename Type>
  74239. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  74240. template<typename>
  74241. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  74242. template<typename Type, std::size_t... Index>
  74243. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  74244. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  74245. }
  74246. template<typename>
  74247. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  74248. return false;
  74249. }
  74250. template<typename Type>
  74251. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  74252. return true;
  74253. }
  74254. template<typename Type>
  74255. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  74256. // NOLINTBEGIN(modernize-use-transparent-functors)
  74257. if constexpr(std::is_array_v<Type>) {
  74258. return false;
  74259. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  74260. if constexpr(has_tuple_size_value<Type>::value) {
  74261. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  74262. } else {
  74263. return maybe_equality_comparable<Type>(0);
  74264. }
  74265. } else if constexpr(has_value_type<Type>::value) {
  74266. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  74267. return maybe_equality_comparable<Type>(0);
  74268. } else {
  74269. return false;
  74270. }
  74271. } else {
  74272. return maybe_equality_comparable<Type>(0);
  74273. }
  74274. // NOLINTEND(modernize-use-transparent-functors)
  74275. }
  74276. } // namespace internal
  74277. /*! @endcond */
  74278. /**
  74279. * @brief Provides the member constant `value` to true if a given type is
  74280. * equality comparable, false otherwise.
  74281. * @tparam Type The type to test.
  74282. */
  74283. template<typename Type>
  74284. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  74285. /*! @copydoc is_equality_comparable */
  74286. template<typename Type>
  74287. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  74288. /**
  74289. * @brief Helper variable template.
  74290. * @tparam Type The type to test.
  74291. */
  74292. template<typename Type>
  74293. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  74294. /**
  74295. * @brief Transcribes the constness of a type to another type.
  74296. * @tparam To The type to which to transcribe the constness.
  74297. * @tparam From The type from which to transcribe the constness.
  74298. */
  74299. template<typename To, typename From>
  74300. struct constness_as {
  74301. /*! @brief The type resulting from the transcription of the constness. */
  74302. using type = std::remove_const_t<To>;
  74303. };
  74304. /*! @copydoc constness_as */
  74305. template<typename To, typename From>
  74306. struct constness_as<To, const From> {
  74307. /*! @brief The type resulting from the transcription of the constness. */
  74308. using type = const To;
  74309. };
  74310. /**
  74311. * @brief Alias template to facilitate the transcription of the constness.
  74312. * @tparam To The type to which to transcribe the constness.
  74313. * @tparam From The type from which to transcribe the constness.
  74314. */
  74315. template<typename To, typename From>
  74316. using constness_as_t = typename constness_as<To, From>::type;
  74317. /**
  74318. * @brief Extracts the class of a non-static member object or function.
  74319. * @tparam Member A pointer to a non-static member object or function.
  74320. */
  74321. template<typename Member>
  74322. class member_class {
  74323. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  74324. template<typename Class, typename Ret, typename... Args>
  74325. static Class *clazz(Ret (Class::*)(Args...));
  74326. template<typename Class, typename Ret, typename... Args>
  74327. static Class *clazz(Ret (Class::*)(Args...) const);
  74328. template<typename Class, typename Type>
  74329. static Class *clazz(Type Class::*);
  74330. public:
  74331. /*! @brief The class of the given non-static member object or function. */
  74332. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  74333. };
  74334. /**
  74335. * @brief Helper type.
  74336. * @tparam Member A pointer to a non-static member object or function.
  74337. */
  74338. template<typename Member>
  74339. using member_class_t = typename member_class<Member>::type;
  74340. /**
  74341. * @brief Extracts the n-th argument of a _callable_ type.
  74342. * @tparam Index The index of the argument to extract.
  74343. * @tparam Candidate A valid _callable_ type.
  74344. */
  74345. template<std::size_t Index, typename Candidate>
  74346. class nth_argument {
  74347. template<typename Ret, typename... Args>
  74348. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  74349. template<typename Ret, typename Class, typename... Args>
  74350. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  74351. template<typename Ret, typename Class, typename... Args>
  74352. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  74353. template<typename Type, typename Class>
  74354. static constexpr type_list<Type> pick_up(Type Class ::*);
  74355. template<typename Type>
  74356. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  74357. public:
  74358. /*! @brief N-th argument of the _callable_ type. */
  74359. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  74360. };
  74361. /**
  74362. * @brief Helper type.
  74363. * @tparam Index The index of the argument to extract.
  74364. * @tparam Candidate A valid function, member function or data member type.
  74365. */
  74366. template<std::size_t Index, typename Candidate>
  74367. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  74368. } // namespace entt
  74369. template<typename... Type>
  74370. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  74371. template<std::size_t Index, typename... Type>
  74372. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  74373. template<auto... Value>
  74374. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  74375. template<std::size_t Index, auto... Value>
  74376. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  74377. #endif
  74378. // #include "fwd.hpp"
  74379. #ifndef ENTT_SIGNAL_FWD_HPP
  74380. #define ENTT_SIGNAL_FWD_HPP
  74381. #include <memory>
  74382. namespace entt {
  74383. template<typename>
  74384. class delegate;
  74385. template<typename = std::allocator<void>>
  74386. class basic_dispatcher;
  74387. template<typename, typename = std::allocator<void>>
  74388. class emitter;
  74389. class connection;
  74390. struct scoped_connection;
  74391. template<typename>
  74392. class sink;
  74393. template<typename Type, typename = std::allocator<void>>
  74394. class sigh;
  74395. /*! @brief Alias declaration for the most common use case. */
  74396. using dispatcher = basic_dispatcher<>;
  74397. /*! @brief Disambiguation tag for constructors and the like. */
  74398. template<auto>
  74399. struct connect_arg_t {
  74400. /*! @brief Default constructor. */
  74401. explicit connect_arg_t() = default;
  74402. };
  74403. /**
  74404. * @brief Constant of type connect_arg_t used to disambiguate calls.
  74405. * @tparam Candidate Element to connect (likely a free or member function).
  74406. */
  74407. template<auto Candidate>
  74408. inline constexpr connect_arg_t<Candidate> connect_arg{};
  74409. } // namespace entt
  74410. #endif
  74411. namespace entt {
  74412. /*! @cond TURN_OFF_DOXYGEN */
  74413. namespace internal {
  74414. template<typename Ret, typename... Args>
  74415. constexpr auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...);
  74416. template<typename Ret, typename Type, typename... Args, typename Other>
  74417. constexpr auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...);
  74418. template<typename Class, typename Ret, typename... Args, typename... Other>
  74419. constexpr auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...);
  74420. template<typename Class, typename Ret, typename... Args, typename... Other>
  74421. constexpr auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...);
  74422. template<typename Class, typename Type, typename... Other, typename = std::enable_if_t<std::is_member_object_pointer_v<Type Class::*>>>
  74423. constexpr auto function_pointer(Type Class::*, Other &&...) -> Type (*)();
  74424. template<typename... Type>
  74425. using function_pointer_t = decltype(function_pointer(std::declval<Type>()...));
  74426. template<typename... Class, typename Ret, typename... Args>
  74427. [[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) {
  74428. return std::index_sequence_for<Class..., Args...>{};
  74429. }
  74430. } // namespace internal
  74431. /*! @endcond */
  74432. /**
  74433. * @brief Basic delegate implementation.
  74434. *
  74435. * Primary template isn't defined on purpose. All the specializations give a
  74436. * compile-time error unless the template parameter is a function type.
  74437. */
  74438. template<typename>
  74439. class delegate;
  74440. /**
  74441. * @brief Utility class to use to send around functions and members.
  74442. *
  74443. * Unmanaged delegate for function pointers and members. Users of this class are
  74444. * in charge of disconnecting instances before deleting them.
  74445. *
  74446. * A delegate can be used as a general purpose invoker without memory overhead
  74447. * for free functions possibly with payloads and bound or unbound members.
  74448. *
  74449. * @tparam Ret Return type of a function type.
  74450. * @tparam Args Types of arguments of a function type.
  74451. */
  74452. template<typename Ret, typename... Args>
  74453. class delegate<Ret(Args...)> {
  74454. using return_type = std::remove_const_t<Ret>;
  74455. using delegate_type = return_type(const void *, Args...);
  74456. template<auto Candidate, std::size_t... Index>
  74457. [[nodiscard]] auto wrap(std::index_sequence<Index...>) noexcept {
  74458. return [](const void *, Args... args) -> return_type {
  74459. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  74460. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  74461. return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  74462. };
  74463. }
  74464. template<auto Candidate, typename Type, std::size_t... Index>
  74465. [[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) noexcept {
  74466. return [](const void *payload, Args... args) -> return_type {
  74467. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  74468. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  74469. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type &, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  74470. return static_cast<Ret>(std::invoke(Candidate, *curr, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  74471. };
  74472. }
  74473. template<auto Candidate, typename Type, std::size_t... Index>
  74474. [[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) noexcept {
  74475. return [](const void *payload, Args... args) -> return_type {
  74476. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  74477. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  74478. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type *, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  74479. return static_cast<Ret>(std::invoke(Candidate, curr, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  74480. };
  74481. }
  74482. public:
  74483. /*! @brief Function type of the contained target. */
  74484. using function_type = Ret(const void *, Args...);
  74485. /*! @brief Function type of the delegate. */
  74486. using type = Ret(Args...);
  74487. /*! @brief Return type of the delegate. */
  74488. using result_type = Ret;
  74489. /*! @brief Default constructor. */
  74490. delegate() noexcept = default;
  74491. /**
  74492. * @brief Constructs a delegate with a given object or payload, if any.
  74493. * @tparam Candidate Function or member to connect to the delegate.
  74494. * @tparam Type Type of class or type of payload, if any.
  74495. * @param value_or_instance Optional valid object that fits the purpose.
  74496. */
  74497. template<auto Candidate, typename... Type>
  74498. delegate(connect_arg_t<Candidate>, Type &&...value_or_instance) noexcept {
  74499. connect<Candidate>(std::forward<Type>(value_or_instance)...);
  74500. }
  74501. /**
  74502. * @brief Constructs a delegate and connects an user defined function with
  74503. * optional payload.
  74504. * @param function Function to connect to the delegate.
  74505. * @param payload User defined arbitrary data.
  74506. */
  74507. delegate(function_type *function, const void *payload = nullptr) noexcept {
  74508. connect(function, payload);
  74509. }
  74510. /**
  74511. * @brief Connects a free function or an unbound member to a delegate.
  74512. * @tparam Candidate Function or member to connect to the delegate.
  74513. */
  74514. template<auto Candidate>
  74515. void connect() noexcept {
  74516. instance = nullptr;
  74517. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  74518. fn = [](const void *, Args... args) -> return_type {
  74519. return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
  74520. };
  74521. } else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
  74522. fn = wrap<Candidate>(internal::index_sequence_for<type_list_element_t<0, type_list<Args...>>>(internal::function_pointer_t<decltype(Candidate)>{}));
  74523. } else {
  74524. fn = wrap<Candidate>(internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate)>{}));
  74525. }
  74526. }
  74527. /**
  74528. * @brief Connects a free function with payload or a bound member to a
  74529. * delegate.
  74530. *
  74531. * The delegate isn't responsible for the connected object or the payload.
  74532. * Users must always guarantee that the lifetime of the instance overcomes
  74533. * the one of the delegate.<br/>
  74534. * When used to connect a free function with payload, its signature must be
  74535. * such that the instance is the first argument before the ones used to
  74536. * define the delegate itself.
  74537. *
  74538. * @tparam Candidate Function or member to connect to the delegate.
  74539. * @tparam Type Type of class or type of payload.
  74540. * @param value_or_instance A valid reference that fits the purpose.
  74541. */
  74542. template<auto Candidate, typename Type>
  74543. void connect(Type &value_or_instance) noexcept {
  74544. instance = &value_or_instance;
  74545. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
  74546. fn = [](const void *payload, Args... args) -> return_type {
  74547. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  74548. return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
  74549. };
  74550. } else {
  74551. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  74552. }
  74553. }
  74554. /**
  74555. * @brief Connects a free function with payload or a bound member to a
  74556. * delegate.
  74557. *
  74558. * @sa connect(Type &)
  74559. *
  74560. * @tparam Candidate Function or member to connect to the delegate.
  74561. * @tparam Type Type of class or type of payload.
  74562. * @param value_or_instance A valid pointer that fits the purpose.
  74563. */
  74564. template<auto Candidate, typename Type>
  74565. void connect(Type *value_or_instance) noexcept {
  74566. instance = value_or_instance;
  74567. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
  74568. fn = [](const void *payload, Args... args) -> return_type {
  74569. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  74570. return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
  74571. };
  74572. } else {
  74573. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  74574. }
  74575. }
  74576. /**
  74577. * @brief Connects an user defined function with optional payload to a
  74578. * delegate.
  74579. *
  74580. * The delegate isn't responsible for the connected object or the payload.
  74581. * Users must always guarantee that the lifetime of an instance overcomes
  74582. * the one of the delegate.<br/>
  74583. * The payload is returned as the first argument to the target function in
  74584. * all cases.
  74585. *
  74586. * @param function Function to connect to the delegate.
  74587. * @param payload User defined arbitrary data.
  74588. */
  74589. void connect(function_type *function, const void *payload = nullptr) noexcept {
  74590. ENTT_ASSERT(function != nullptr, "Uninitialized function pointer");
  74591. instance = payload;
  74592. fn = function;
  74593. }
  74594. /**
  74595. * @brief Resets a delegate.
  74596. *
  74597. * After a reset, a delegate cannot be invoked anymore.
  74598. */
  74599. void reset() noexcept {
  74600. instance = nullptr;
  74601. fn = nullptr;
  74602. }
  74603. /**
  74604. * @brief Returns a pointer to the stored callable function target, if any.
  74605. * @return An opaque pointer to the stored callable function target.
  74606. */
  74607. [[nodiscard]] function_type *target() const noexcept {
  74608. return fn;
  74609. }
  74610. /**
  74611. * @brief Returns the instance or the payload linked to a delegate, if any.
  74612. * @return An opaque pointer to the underlying data.
  74613. */
  74614. [[nodiscard]] const void *data() const noexcept {
  74615. return instance;
  74616. }
  74617. /**
  74618. * @brief Triggers a delegate.
  74619. *
  74620. * The delegate invokes the underlying function and returns the result.
  74621. *
  74622. * @warning
  74623. * Attempting to trigger an invalid delegate results in undefined
  74624. * behavior.
  74625. *
  74626. * @param args Arguments to use to invoke the underlying function.
  74627. * @return The value returned by the underlying function.
  74628. */
  74629. Ret operator()(Args... args) const {
  74630. ENTT_ASSERT(static_cast<bool>(*this), "Uninitialized delegate");
  74631. return fn(instance, std::forward<Args>(args)...);
  74632. }
  74633. /**
  74634. * @brief Checks whether a delegate actually stores a listener.
  74635. * @return False if the delegate is empty, true otherwise.
  74636. */
  74637. [[nodiscard]] explicit operator bool() const noexcept {
  74638. // no need to also test instance
  74639. return !(fn == nullptr);
  74640. }
  74641. /**
  74642. * @brief Compares the contents of two delegates.
  74643. * @param other Delegate with which to compare.
  74644. * @return False if the two contents differ, true otherwise.
  74645. */
  74646. [[nodiscard]] bool operator==(const delegate<Ret(Args...)> &other) const noexcept {
  74647. return fn == other.fn && instance == other.instance;
  74648. }
  74649. private:
  74650. const void *instance{};
  74651. delegate_type *fn{};
  74652. };
  74653. /**
  74654. * @brief Compares the contents of two delegates.
  74655. * @tparam Ret Return type of a function type.
  74656. * @tparam Args Types of arguments of a function type.
  74657. * @param lhs A valid delegate object.
  74658. * @param rhs A valid delegate object.
  74659. * @return True if the two contents differ, false otherwise.
  74660. */
  74661. template<typename Ret, typename... Args>
  74662. [[nodiscard]] bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) noexcept {
  74663. return !(lhs == rhs);
  74664. }
  74665. /**
  74666. * @brief Deduction guide.
  74667. * @tparam Candidate Function or member to connect to the delegate.
  74668. */
  74669. template<auto Candidate>
  74670. delegate(connect_arg_t<Candidate>) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate)>>>;
  74671. /**
  74672. * @brief Deduction guide.
  74673. * @tparam Candidate Function or member to connect to the delegate.
  74674. * @tparam Type Type of class or type of payload.
  74675. */
  74676. template<auto Candidate, typename Type>
  74677. delegate(connect_arg_t<Candidate>, Type &&) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate), Type>>>;
  74678. /**
  74679. * @brief Deduction guide.
  74680. * @tparam Ret Return type of a function type.
  74681. * @tparam Args Types of arguments of a function type.
  74682. */
  74683. template<typename Ret, typename... Args>
  74684. delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate<Ret(Args...)>;
  74685. } // namespace entt
  74686. #endif
  74687. // #include "signal/dispatcher.hpp"
  74688. #ifndef ENTT_SIGNAL_DISPATCHER_HPP
  74689. #define ENTT_SIGNAL_DISPATCHER_HPP
  74690. #include <cstddef>
  74691. #include <functional>
  74692. #include <memory>
  74693. #include <type_traits>
  74694. #include <utility>
  74695. #include <vector>
  74696. // #include "../container/dense_map.hpp"
  74697. #ifndef ENTT_CONTAINER_DENSE_MAP_HPP
  74698. #define ENTT_CONTAINER_DENSE_MAP_HPP
  74699. #include <cmath>
  74700. #include <cstddef>
  74701. #include <functional>
  74702. #include <iterator>
  74703. #include <limits>
  74704. #include <memory>
  74705. #include <tuple>
  74706. #include <type_traits>
  74707. #include <utility>
  74708. #include <vector>
  74709. // #include "../config/config.h"
  74710. #ifndef ENTT_CONFIG_CONFIG_H
  74711. #define ENTT_CONFIG_CONFIG_H
  74712. // #include "version.h"
  74713. #ifndef ENTT_CONFIG_VERSION_H
  74714. #define ENTT_CONFIG_VERSION_H
  74715. // #include "macro.h"
  74716. #ifndef ENTT_CONFIG_MACRO_H
  74717. #define ENTT_CONFIG_MACRO_H
  74718. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  74719. #define ENTT_STR(arg) #arg
  74720. #define ENTT_XSTR(arg) ENTT_STR(arg)
  74721. // NOLINTEND(cppcoreguidelines-macro-usage)
  74722. #endif
  74723. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  74724. #define ENTT_VERSION_MAJOR 3
  74725. #define ENTT_VERSION_MINOR 16
  74726. #define ENTT_VERSION_PATCH 0
  74727. #define ENTT_VERSION \
  74728. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  74729. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  74730. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  74731. #endif
  74732. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  74733. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  74734. # define ENTT_CONSTEXPR
  74735. # define ENTT_THROW throw
  74736. # define ENTT_TRY try
  74737. # define ENTT_CATCH catch(...)
  74738. #else
  74739. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  74740. # define ENTT_THROW
  74741. # define ENTT_TRY if(true)
  74742. # define ENTT_CATCH if(false)
  74743. #endif
  74744. #if __has_include(<version>)
  74745. # include <version>
  74746. #
  74747. # if defined(__cpp_consteval)
  74748. # define ENTT_CONSTEVAL consteval
  74749. # endif
  74750. #endif
  74751. #ifndef ENTT_CONSTEVAL
  74752. # define ENTT_CONSTEVAL constexpr
  74753. #endif
  74754. #ifdef ENTT_USE_ATOMIC
  74755. # include <atomic>
  74756. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  74757. #else
  74758. # define ENTT_MAYBE_ATOMIC(Type) Type
  74759. #endif
  74760. #ifndef ENTT_ID_TYPE
  74761. # include <cstdint>
  74762. # define ENTT_ID_TYPE std::uint32_t
  74763. #else
  74764. # include <cstdint> // provides coverage for types in the std namespace
  74765. #endif
  74766. #ifndef ENTT_SPARSE_PAGE
  74767. # define ENTT_SPARSE_PAGE 4096
  74768. #endif
  74769. #ifndef ENTT_PACKED_PAGE
  74770. # define ENTT_PACKED_PAGE 1024
  74771. #endif
  74772. #ifdef ENTT_DISABLE_ASSERT
  74773. # undef ENTT_ASSERT
  74774. # define ENTT_ASSERT(condition, msg) (void(0))
  74775. #elif !defined ENTT_ASSERT
  74776. # include <cassert>
  74777. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  74778. #endif
  74779. #ifdef ENTT_DISABLE_ASSERT
  74780. # undef ENTT_ASSERT_CONSTEXPR
  74781. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  74782. #elif !defined ENTT_ASSERT_CONSTEXPR
  74783. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  74784. #endif
  74785. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  74786. #ifdef ENTT_NO_ETO
  74787. # define ENTT_ETO_TYPE(Type) void
  74788. #else
  74789. # define ENTT_ETO_TYPE(Type) Type
  74790. #endif
  74791. #ifdef ENTT_NO_MIXIN
  74792. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  74793. #else
  74794. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  74795. #endif
  74796. #ifdef ENTT_STANDARD_CPP
  74797. # define ENTT_NONSTD false
  74798. #else
  74799. # define ENTT_NONSTD true
  74800. # if defined __clang__ || defined __GNUC__
  74801. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  74802. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  74803. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  74804. # elif defined _MSC_VER
  74805. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  74806. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  74807. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  74808. # endif
  74809. #endif
  74810. #ifndef ENTT_EXPORT
  74811. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  74812. # define ENTT_EXPORT __declspec(dllexport)
  74813. # define ENTT_IMPORT __declspec(dllimport)
  74814. # define ENTT_HIDDEN
  74815. # elif defined __GNUC__ && __GNUC__ >= 4
  74816. # define ENTT_EXPORT __attribute__((visibility("default")))
  74817. # define ENTT_IMPORT __attribute__((visibility("default")))
  74818. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  74819. # else /* Unsupported compiler */
  74820. # define ENTT_EXPORT
  74821. # define ENTT_IMPORT
  74822. # define ENTT_HIDDEN
  74823. # endif
  74824. #endif
  74825. #ifndef ENTT_API
  74826. # if defined ENTT_API_EXPORT
  74827. # define ENTT_API ENTT_EXPORT
  74828. # elif defined ENTT_API_IMPORT
  74829. # define ENTT_API ENTT_IMPORT
  74830. # else /* No API */
  74831. # define ENTT_API
  74832. # endif
  74833. #endif
  74834. #if defined _MSC_VER
  74835. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  74836. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  74837. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  74838. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  74839. #endif
  74840. // NOLINTEND(cppcoreguidelines-macro-usage)
  74841. #endif
  74842. // #include "../core/bit.hpp"
  74843. #ifndef ENTT_CORE_BIT_HPP
  74844. #define ENTT_CORE_BIT_HPP
  74845. #include <cstddef>
  74846. #include <limits>
  74847. #include <type_traits>
  74848. // #include "../config/config.h"
  74849. #ifndef ENTT_CONFIG_CONFIG_H
  74850. #define ENTT_CONFIG_CONFIG_H
  74851. // #include "version.h"
  74852. #ifndef ENTT_CONFIG_VERSION_H
  74853. #define ENTT_CONFIG_VERSION_H
  74854. // #include "macro.h"
  74855. #ifndef ENTT_CONFIG_MACRO_H
  74856. #define ENTT_CONFIG_MACRO_H
  74857. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  74858. #define ENTT_STR(arg) #arg
  74859. #define ENTT_XSTR(arg) ENTT_STR(arg)
  74860. // NOLINTEND(cppcoreguidelines-macro-usage)
  74861. #endif
  74862. // NOLINTBEGIN(cppcoreguidelines-macro-*,modernize-macro-*)
  74863. #define ENTT_VERSION_MAJOR 3
  74864. #define ENTT_VERSION_MINOR 16
  74865. #define ENTT_VERSION_PATCH 0
  74866. #define ENTT_VERSION \
  74867. ENTT_XSTR(ENTT_VERSION_MAJOR) \
  74868. "." ENTT_XSTR(ENTT_VERSION_MINOR) "." ENTT_XSTR(ENTT_VERSION_PATCH)
  74869. // NOLINTEND(cppcoreguidelines-macro-*,modernize-macro-*)
  74870. #endif
  74871. // NOLINTBEGIN(cppcoreguidelines-macro-usage)
  74872. #if defined(__cpp_exceptions) && !defined(ENTT_NOEXCEPTION)
  74873. # define ENTT_CONSTEXPR
  74874. # define ENTT_THROW throw
  74875. # define ENTT_TRY try
  74876. # define ENTT_CATCH catch(...)
  74877. #else
  74878. # define ENTT_CONSTEXPR constexpr // use only with throwing functions (waiting for C++20)
  74879. # define ENTT_THROW
  74880. # define ENTT_TRY if(true)
  74881. # define ENTT_CATCH if(false)
  74882. #endif
  74883. #if __has_include(<version>)
  74884. # include <version>
  74885. #
  74886. # if defined(__cpp_consteval)
  74887. # define ENTT_CONSTEVAL consteval
  74888. # endif
  74889. #endif
  74890. #ifndef ENTT_CONSTEVAL
  74891. # define ENTT_CONSTEVAL constexpr
  74892. #endif
  74893. #ifdef ENTT_USE_ATOMIC
  74894. # include <atomic>
  74895. # define ENTT_MAYBE_ATOMIC(Type) std::atomic<Type>
  74896. #else
  74897. # define ENTT_MAYBE_ATOMIC(Type) Type
  74898. #endif
  74899. #ifndef ENTT_ID_TYPE
  74900. # include <cstdint>
  74901. # define ENTT_ID_TYPE std::uint32_t
  74902. #else
  74903. # include <cstdint> // provides coverage for types in the std namespace
  74904. #endif
  74905. #ifndef ENTT_SPARSE_PAGE
  74906. # define ENTT_SPARSE_PAGE 4096
  74907. #endif
  74908. #ifndef ENTT_PACKED_PAGE
  74909. # define ENTT_PACKED_PAGE 1024
  74910. #endif
  74911. #ifdef ENTT_DISABLE_ASSERT
  74912. # undef ENTT_ASSERT
  74913. # define ENTT_ASSERT(condition, msg) (void(0))
  74914. #elif !defined ENTT_ASSERT
  74915. # include <cassert>
  74916. # define ENTT_ASSERT(condition, msg) assert(((condition) && (msg)))
  74917. #endif
  74918. #ifdef ENTT_DISABLE_ASSERT
  74919. # undef ENTT_ASSERT_CONSTEXPR
  74920. # define ENTT_ASSERT_CONSTEXPR(condition, msg) (void(0))
  74921. #elif !defined ENTT_ASSERT_CONSTEXPR
  74922. # define ENTT_ASSERT_CONSTEXPR(condition, msg) ENTT_ASSERT(condition, msg)
  74923. #endif
  74924. #define ENTT_FAIL(msg) ENTT_ASSERT(false, msg);
  74925. #ifdef ENTT_NO_ETO
  74926. # define ENTT_ETO_TYPE(Type) void
  74927. #else
  74928. # define ENTT_ETO_TYPE(Type) Type
  74929. #endif
  74930. #ifdef ENTT_NO_MIXIN
  74931. # define ENTT_STORAGE(Mixin, ...) __VA_ARGS__
  74932. #else
  74933. # define ENTT_STORAGE(Mixin, ...) Mixin<__VA_ARGS__>
  74934. #endif
  74935. #ifdef ENTT_STANDARD_CPP
  74936. # define ENTT_NONSTD false
  74937. #else
  74938. # define ENTT_NONSTD true
  74939. # if defined __clang__ || defined __GNUC__
  74940. # define ENTT_PRETTY_FUNCTION __PRETTY_FUNCTION__
  74941. # define ENTT_PRETTY_FUNCTION_PREFIX '='
  74942. # define ENTT_PRETTY_FUNCTION_SUFFIX ']'
  74943. # elif defined _MSC_VER
  74944. # define ENTT_PRETTY_FUNCTION __FUNCSIG__
  74945. # define ENTT_PRETTY_FUNCTION_PREFIX '<'
  74946. # define ENTT_PRETTY_FUNCTION_SUFFIX '>'
  74947. # endif
  74948. #endif
  74949. #ifndef ENTT_EXPORT
  74950. # if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
  74951. # define ENTT_EXPORT __declspec(dllexport)
  74952. # define ENTT_IMPORT __declspec(dllimport)
  74953. # define ENTT_HIDDEN
  74954. # elif defined __GNUC__ && __GNUC__ >= 4
  74955. # define ENTT_EXPORT __attribute__((visibility("default")))
  74956. # define ENTT_IMPORT __attribute__((visibility("default")))
  74957. # define ENTT_HIDDEN __attribute__((visibility("hidden")))
  74958. # else /* Unsupported compiler */
  74959. # define ENTT_EXPORT
  74960. # define ENTT_IMPORT
  74961. # define ENTT_HIDDEN
  74962. # endif
  74963. #endif
  74964. #ifndef ENTT_API
  74965. # if defined ENTT_API_EXPORT
  74966. # define ENTT_API ENTT_EXPORT
  74967. # elif defined ENTT_API_IMPORT
  74968. # define ENTT_API ENTT_IMPORT
  74969. # else /* No API */
  74970. # define ENTT_API
  74971. # endif
  74972. #endif
  74973. #if defined _MSC_VER
  74974. # pragma detect_mismatch("entt.version", ENTT_VERSION)
  74975. # pragma detect_mismatch("entt.noexcept", ENTT_XSTR(ENTT_TRY))
  74976. # pragma detect_mismatch("entt.id", ENTT_XSTR(ENTT_ID_TYPE))
  74977. # pragma detect_mismatch("entt.nonstd", ENTT_XSTR(ENTT_NONSTD))
  74978. #endif
  74979. // NOLINTEND(cppcoreguidelines-macro-usage)
  74980. #endif
  74981. namespace entt {
  74982. /**
  74983. * @brief Returns the number of set bits in a value (waiting for C++20 and
  74984. * `std::popcount`).
  74985. * @tparam Type Unsigned integer type.
  74986. * @param value A value of unsigned integer type.
  74987. * @return The number of set bits in the value.
  74988. */
  74989. template<typename Type>
  74990. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, int> popcount(const Type value) noexcept {
  74991. return value ? (int(value & 1) + popcount(static_cast<Type>(value >> 1))) : 0;
  74992. }
  74993. /**
  74994. * @brief Checks whether a value is a power of two or not (waiting for C++20 and
  74995. * `std::has_single_bit`).
  74996. * @tparam Type Unsigned integer type.
  74997. * @param value A value of unsigned integer type.
  74998. * @return True if the value is a power of two, false otherwise.
  74999. */
  75000. template<typename Type>
  75001. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, bool> has_single_bit(const Type value) noexcept {
  75002. return value && ((value & (value - 1)) == 0);
  75003. }
  75004. /**
  75005. * @brief Computes the smallest power of two greater than or equal to a value
  75006. * (waiting for C++20 and `std::bit_ceil`).
  75007. * @tparam Type Unsigned integer type.
  75008. * @param value A value of unsigned integer type.
  75009. * @return The smallest power of two greater than or equal to the given value.
  75010. */
  75011. template<typename Type>
  75012. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> next_power_of_two(const Type value) noexcept {
  75013. // NOLINTNEXTLINE(bugprone-assert-side-effect)
  75014. ENTT_ASSERT_CONSTEXPR(value < (Type{1u} << (std::numeric_limits<Type>::digits - 1)), "Numeric limits exceeded");
  75015. Type curr = value - (value != 0u);
  75016. for(int next = 1; next < std::numeric_limits<Type>::digits; next = next * 2) {
  75017. curr |= (curr >> next);
  75018. }
  75019. return ++curr;
  75020. }
  75021. /**
  75022. * @brief Fast module utility function (powers of two only).
  75023. * @tparam Type Unsigned integer type.
  75024. * @param value A value of unsigned integer type.
  75025. * @param mod _Modulus_, it must be a power of two.
  75026. * @return The common remainder.
  75027. */
  75028. template<typename Type>
  75029. [[nodiscard]] constexpr std::enable_if_t<std::is_unsigned_v<Type>, Type> fast_mod(const Type value, const std::size_t mod) noexcept {
  75030. ENTT_ASSERT_CONSTEXPR(has_single_bit(mod), "Value must be a power of two");
  75031. return static_cast<Type>(value & (mod - 1u));
  75032. }
  75033. } // namespace entt
  75034. #endif
  75035. // #include "../core/compressed_pair.hpp"
  75036. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  75037. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  75038. #include <cstddef>
  75039. #include <tuple>
  75040. #include <type_traits>
  75041. #include <utility>
  75042. // #include "fwd.hpp"
  75043. #ifndef ENTT_CORE_FWD_HPP
  75044. #define ENTT_CORE_FWD_HPP
  75045. #include <cstddef>
  75046. #include <cstdint>
  75047. // #include "../config/config.h"
  75048. namespace entt {
  75049. /*! @brief Possible modes of an any object. */
  75050. enum class any_policy : std::uint8_t {
  75051. /*! @brief Default mode, no element available. */
  75052. empty,
  75053. /*! @brief Owning mode, dynamically allocated element. */
  75054. dynamic,
  75055. /*! @brief Owning mode, embedded element. */
  75056. embedded,
  75057. /*! @brief Aliasing mode, non-const reference. */
  75058. ref,
  75059. /*! @brief Const aliasing mode, const reference. */
  75060. cref
  75061. };
  75062. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  75063. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  75064. class basic_any;
  75065. /*! @brief Alias declaration for type identifiers. */
  75066. using id_type = ENTT_ID_TYPE;
  75067. /*! @brief Alias declaration for the most common use case. */
  75068. using any = basic_any<>;
  75069. template<typename, typename>
  75070. class compressed_pair;
  75071. template<typename>
  75072. class basic_hashed_string;
  75073. /*! @brief Aliases for common character types. */
  75074. using hashed_string = basic_hashed_string<char>;
  75075. /*! @brief Aliases for common character types. */
  75076. using hashed_wstring = basic_hashed_string<wchar_t>;
  75077. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  75078. struct type_info;
  75079. } // namespace entt
  75080. #endif
  75081. // #include "type_traits.hpp"
  75082. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  75083. #define ENTT_CORE_TYPE_TRAITS_HPP
  75084. #include <cstddef>
  75085. #include <iterator>
  75086. #include <tuple>
  75087. #include <type_traits>
  75088. #include <utility>
  75089. // #include "../config/config.h"
  75090. // #include "fwd.hpp"
  75091. namespace entt {
  75092. /**
  75093. * @brief Utility class to disambiguate overloaded functions.
  75094. * @tparam N Number of choices available.
  75095. */
  75096. template<std::size_t N>
  75097. struct choice_t
  75098. // unfortunately, doxygen cannot parse such a construct
  75099. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  75100. {};
  75101. /*! @copybrief choice_t */
  75102. template<>
  75103. struct choice_t<0> {};
  75104. /**
  75105. * @brief Variable template for the choice trick.
  75106. * @tparam N Number of choices available.
  75107. */
  75108. template<std::size_t N>
  75109. inline constexpr choice_t<N> choice{};
  75110. /**
  75111. * @brief Identity type trait.
  75112. *
  75113. * Useful to establish non-deduced contexts in template argument deduction
  75114. * (waiting for C++20) or to provide types through function arguments.
  75115. *
  75116. * @tparam Type A type.
  75117. */
  75118. template<typename Type>
  75119. struct type_identity {
  75120. /*! @brief Identity type. */
  75121. using type = Type;
  75122. };
  75123. /**
  75124. * @brief Helper type.
  75125. * @tparam Type A type.
  75126. */
  75127. template<typename Type>
  75128. using type_identity_t = typename type_identity<Type>::type;
  75129. /**
  75130. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  75131. * @tparam Type The type of which to return the size.
  75132. */
  75133. template<typename Type, typename = void>
  75134. struct size_of: std::integral_constant<std::size_t, 0u> {};
  75135. /*! @copydoc size_of */
  75136. template<typename Type>
  75137. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  75138. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  75139. : std::integral_constant<std::size_t, sizeof(Type)> {};
  75140. /**
  75141. * @brief Helper variable template.
  75142. * @tparam Type The type of which to return the size.
  75143. */
  75144. template<typename Type>
  75145. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  75146. /**
  75147. * @brief Using declaration to be used to _repeat_ the same type a number of
  75148. * times equal to the size of a given parameter pack.
  75149. * @tparam Type A type to repeat.
  75150. */
  75151. template<typename Type, typename>
  75152. using unpack_as_type = Type;
  75153. /**
  75154. * @brief Helper variable template to be used to _repeat_ the same value a
  75155. * number of times equal to the size of a given parameter pack.
  75156. * @tparam Value A value to repeat.
  75157. */
  75158. template<auto Value, typename>
  75159. inline constexpr auto unpack_as_value = Value;
  75160. /**
  75161. * @brief Wraps a static constant.
  75162. * @tparam Value A static constant.
  75163. */
  75164. template<auto Value>
  75165. using integral_constant = std::integral_constant<decltype(Value), Value>;
  75166. /**
  75167. * @brief Alias template to facilitate the creation of named values.
  75168. * @tparam Value A constant value at least convertible to `id_type`.
  75169. */
  75170. template<id_type Value>
  75171. using tag = integral_constant<Value>;
  75172. /**
  75173. * @brief A class to use to push around lists of types, nothing more.
  75174. * @tparam Type Types provided by the type list.
  75175. */
  75176. template<typename... Type>
  75177. struct type_list {
  75178. /*! @brief Type list type. */
  75179. using type = type_list;
  75180. /*! @brief Compile-time number of elements in the type list. */
  75181. static constexpr auto size = sizeof...(Type);
  75182. };
  75183. /*! @brief Primary template isn't defined on purpose. */
  75184. template<std::size_t, typename>
  75185. struct type_list_element;
  75186. /**
  75187. * @brief Provides compile-time indexed access to the types of a type list.
  75188. * @tparam Index Index of the type to return.
  75189. * @tparam First First type provided by the type list.
  75190. * @tparam Other Other types provided by the type list.
  75191. */
  75192. template<std::size_t Index, typename First, typename... Other>
  75193. struct type_list_element<Index, type_list<First, Other...>>
  75194. : type_list_element<Index - 1u, type_list<Other...>> {};
  75195. /**
  75196. * @brief Provides compile-time indexed access to the types of a type list.
  75197. * @tparam First First type provided by the type list.
  75198. * @tparam Other Other types provided by the type list.
  75199. */
  75200. template<typename First, typename... Other>
  75201. struct type_list_element<0u, type_list<First, Other...>> {
  75202. /*! @brief Searched type. */
  75203. using type = First;
  75204. };
  75205. /**
  75206. * @brief Helper type.
  75207. * @tparam Index Index of the type to return.
  75208. * @tparam List Type list to search into.
  75209. */
  75210. template<std::size_t Index, typename List>
  75211. using type_list_element_t = typename type_list_element<Index, List>::type;
  75212. /*! @brief Primary template isn't defined on purpose. */
  75213. template<typename, typename>
  75214. struct type_list_index;
  75215. /**
  75216. * @brief Provides compile-time type access to the types of a type list.
  75217. * @tparam Type Type to look for and for which to return the index.
  75218. * @tparam First First type provided by the type list.
  75219. * @tparam Other Other types provided by the type list.
  75220. */
  75221. template<typename Type, typename First, typename... Other>
  75222. struct type_list_index<Type, type_list<First, Other...>> {
  75223. /*! @brief Unsigned integer type. */
  75224. using value_type = std::size_t;
  75225. /*! @brief Compile-time position of the given type in the sublist. */
  75226. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  75227. };
  75228. /**
  75229. * @brief Provides compile-time type access to the types of a type list.
  75230. * @tparam Type Type to look for and for which to return the index.
  75231. * @tparam Other Other types provided by the type list.
  75232. */
  75233. template<typename Type, typename... Other>
  75234. struct type_list_index<Type, type_list<Type, Other...>> {
  75235. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  75236. /*! @brief Unsigned integer type. */
  75237. using value_type = std::size_t;
  75238. /*! @brief Compile-time position of the given type in the sublist. */
  75239. static constexpr value_type value = 0u;
  75240. };
  75241. /**
  75242. * @brief Provides compile-time type access to the types of a type list.
  75243. * @tparam Type Type to look for and for which to return the index.
  75244. */
  75245. template<typename Type>
  75246. struct type_list_index<Type, type_list<>> {
  75247. /*! @brief Unsigned integer type. */
  75248. using value_type = std::size_t;
  75249. /*! @brief Compile-time position of the given type in the sublist. */
  75250. static constexpr value_type value = 0u;
  75251. };
  75252. /**
  75253. * @brief Helper variable template.
  75254. * @tparam List Type list.
  75255. * @tparam Type Type to look for and for which to return the index.
  75256. */
  75257. template<typename Type, typename List>
  75258. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  75259. /**
  75260. * @brief Concatenates multiple type lists.
  75261. * @tparam Type Types provided by the first type list.
  75262. * @tparam Other Types provided by the second type list.
  75263. * @return A type list composed by the types of both the type lists.
  75264. */
  75265. template<typename... Type, typename... Other>
  75266. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  75267. return {};
  75268. }
  75269. /*! @brief Primary template isn't defined on purpose. */
  75270. template<typename...>
  75271. struct type_list_cat;
  75272. /*! @brief Concatenates multiple type lists. */
  75273. template<>
  75274. struct type_list_cat<> {
  75275. /*! @brief A type list composed by the types of all the type lists. */
  75276. using type = type_list<>;
  75277. };
  75278. /**
  75279. * @brief Concatenates multiple type lists.
  75280. * @tparam Type Types provided by the first type list.
  75281. * @tparam Other Types provided by the second type list.
  75282. * @tparam List Other type lists, if any.
  75283. */
  75284. template<typename... Type, typename... Other, typename... List>
  75285. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  75286. /*! @brief A type list composed by the types of all the type lists. */
  75287. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  75288. };
  75289. /**
  75290. * @brief Concatenates multiple type lists.
  75291. * @tparam Type Types provided by the type list.
  75292. */
  75293. template<typename... Type>
  75294. struct type_list_cat<type_list<Type...>> {
  75295. /*! @brief A type list composed by the types of all the type lists. */
  75296. using type = type_list<Type...>;
  75297. };
  75298. /**
  75299. * @brief Helper type.
  75300. * @tparam List Type lists to concatenate.
  75301. */
  75302. template<typename... List>
  75303. using type_list_cat_t = typename type_list_cat<List...>::type;
  75304. /*! @cond TURN_OFF_DOXYGEN */
  75305. namespace internal {
  75306. template<typename...>
  75307. struct type_list_unique;
  75308. template<typename First, typename... Other, typename... Type>
  75309. struct type_list_unique<type_list<First, Other...>, Type...>
  75310. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  75311. template<typename... Type>
  75312. struct type_list_unique<type_list<>, Type...> {
  75313. using type = type_list<Type...>;
  75314. };
  75315. } // namespace internal
  75316. /*! @endcond */
  75317. /**
  75318. * @brief Removes duplicates types from a type list.
  75319. * @tparam List Type list.
  75320. */
  75321. template<typename List>
  75322. struct type_list_unique {
  75323. /*! @brief A type list without duplicate types. */
  75324. using type = typename internal::type_list_unique<List>::type;
  75325. };
  75326. /**
  75327. * @brief Helper type.
  75328. * @tparam List Type list.
  75329. */
  75330. template<typename List>
  75331. using type_list_unique_t = typename type_list_unique<List>::type;
  75332. /**
  75333. * @brief Provides the member constant `value` to true if a type list contains a
  75334. * given type, false otherwise.
  75335. * @tparam List Type list.
  75336. * @tparam Type Type to look for.
  75337. */
  75338. template<typename List, typename Type>
  75339. struct type_list_contains;
  75340. /**
  75341. * @copybrief type_list_contains
  75342. * @tparam Type Types provided by the type list.
  75343. * @tparam Other Type to look for.
  75344. */
  75345. template<typename... Type, typename Other>
  75346. struct type_list_contains<type_list<Type...>, Other>
  75347. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  75348. /**
  75349. * @brief Helper variable template.
  75350. * @tparam List Type list.
  75351. * @tparam Type Type to look for.
  75352. */
  75353. template<typename List, typename Type>
  75354. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  75355. /*! @brief Primary template isn't defined on purpose. */
  75356. template<typename...>
  75357. struct type_list_diff;
  75358. /**
  75359. * @brief Computes the difference between two type lists.
  75360. * @tparam Type Types provided by the first type list.
  75361. * @tparam Other Types provided by the second type list.
  75362. */
  75363. template<typename... Type, typename... Other>
  75364. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  75365. /*! @brief A type list that is the difference between the two type lists. */
  75366. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  75367. };
  75368. /**
  75369. * @brief Helper type.
  75370. * @tparam List Type lists between which to compute the difference.
  75371. */
  75372. template<typename... List>
  75373. using type_list_diff_t = typename type_list_diff<List...>::type;
  75374. /*! @brief Primary template isn't defined on purpose. */
  75375. template<typename, template<typename...> class>
  75376. struct type_list_transform;
  75377. /**
  75378. * @brief Applies a given _function_ to a type list and generate a new list.
  75379. * @tparam Type Types provided by the type list.
  75380. * @tparam Op Unary operation as template class with a type member named `type`.
  75381. */
  75382. template<typename... Type, template<typename...> class Op>
  75383. struct type_list_transform<type_list<Type...>, Op> {
  75384. /*! @brief Resulting type list after applying the transform function. */
  75385. // NOLINTNEXTLINE(modernize-type-traits)
  75386. using type = type_list<typename Op<Type>::type...>;
  75387. };
  75388. /**
  75389. * @brief Helper type.
  75390. * @tparam List Type list.
  75391. * @tparam Op Unary operation as template class with a type member named `type`.
  75392. */
  75393. template<typename List, template<typename...> class Op>
  75394. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  75395. /**
  75396. * @brief A class to use to push around lists of constant values, nothing more.
  75397. * @tparam Value Values provided by the value list.
  75398. */
  75399. template<auto... Value>
  75400. struct value_list {
  75401. /*! @brief Value list type. */
  75402. using type = value_list;
  75403. /*! @brief Compile-time number of elements in the value list. */
  75404. static constexpr auto size = sizeof...(Value);
  75405. };
  75406. /*! @brief Primary template isn't defined on purpose. */
  75407. template<std::size_t, typename>
  75408. struct value_list_element;
  75409. /**
  75410. * @brief Provides compile-time indexed access to the values of a value list.
  75411. * @tparam Index Index of the value to return.
  75412. * @tparam Value First value provided by the value list.
  75413. * @tparam Other Other values provided by the value list.
  75414. */
  75415. template<std::size_t Index, auto Value, auto... Other>
  75416. struct value_list_element<Index, value_list<Value, Other...>>
  75417. : value_list_element<Index - 1u, value_list<Other...>> {};
  75418. /**
  75419. * @brief Provides compile-time indexed access to the types of a type list.
  75420. * @tparam Value First value provided by the value list.
  75421. * @tparam Other Other values provided by the value list.
  75422. */
  75423. template<auto Value, auto... Other>
  75424. struct value_list_element<0u, value_list<Value, Other...>> {
  75425. /*! @brief Searched type. */
  75426. using type = decltype(Value);
  75427. /*! @brief Searched value. */
  75428. static constexpr auto value = Value;
  75429. };
  75430. /**
  75431. * @brief Helper type.
  75432. * @tparam Index Index of the type to return.
  75433. * @tparam List Value list to search into.
  75434. */
  75435. template<std::size_t Index, typename List>
  75436. using value_list_element_t = typename value_list_element<Index, List>::type;
  75437. /**
  75438. * @brief Helper type.
  75439. * @tparam Index Index of the value to return.
  75440. * @tparam List Value list to search into.
  75441. */
  75442. template<std::size_t Index, typename List>
  75443. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  75444. /*! @brief Primary template isn't defined on purpose. */
  75445. template<auto, typename>
  75446. struct value_list_index;
  75447. /**
  75448. * @brief Provides compile-time type access to the values of a value list.
  75449. * @tparam Value Value to look for and for which to return the index.
  75450. * @tparam First First value provided by the value list.
  75451. * @tparam Other Other values provided by the value list.
  75452. */
  75453. template<auto Value, auto First, auto... Other>
  75454. struct value_list_index<Value, value_list<First, Other...>> {
  75455. /*! @brief Unsigned integer type. */
  75456. using value_type = std::size_t;
  75457. /*! @brief Compile-time position of the given value in the sublist. */
  75458. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  75459. };
  75460. /**
  75461. * @brief Provides compile-time type access to the values of a value list.
  75462. * @tparam Value Value to look for and for which to return the index.
  75463. * @tparam Other Other values provided by the value list.
  75464. */
  75465. template<auto Value, auto... Other>
  75466. struct value_list_index<Value, value_list<Value, Other...>> {
  75467. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  75468. /*! @brief Unsigned integer type. */
  75469. using value_type = std::size_t;
  75470. /*! @brief Compile-time position of the given value in the sublist. */
  75471. static constexpr value_type value = 0u;
  75472. };
  75473. /**
  75474. * @brief Provides compile-time type access to the values of a value list.
  75475. * @tparam Value Value to look for and for which to return the index.
  75476. */
  75477. template<auto Value>
  75478. struct value_list_index<Value, value_list<>> {
  75479. /*! @brief Unsigned integer type. */
  75480. using value_type = std::size_t;
  75481. /*! @brief Compile-time position of the given type in the sublist. */
  75482. static constexpr value_type value = 0u;
  75483. };
  75484. /**
  75485. * @brief Helper variable template.
  75486. * @tparam List Value list.
  75487. * @tparam Value Value to look for and for which to return the index.
  75488. */
  75489. template<auto Value, typename List>
  75490. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  75491. /**
  75492. * @brief Concatenates multiple value lists.
  75493. * @tparam Value Values provided by the first value list.
  75494. * @tparam Other Values provided by the second value list.
  75495. * @return A value list composed by the values of both the value lists.
  75496. */
  75497. template<auto... Value, auto... Other>
  75498. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  75499. return {};
  75500. }
  75501. /*! @brief Primary template isn't defined on purpose. */
  75502. template<typename...>
  75503. struct value_list_cat;
  75504. /*! @brief Concatenates multiple value lists. */
  75505. template<>
  75506. struct value_list_cat<> {
  75507. /*! @brief A value list composed by the values of all the value lists. */
  75508. using type = value_list<>;
  75509. };
  75510. /**
  75511. * @brief Concatenates multiple value lists.
  75512. * @tparam Value Values provided by the first value list.
  75513. * @tparam Other Values provided by the second value list.
  75514. * @tparam List Other value lists, if any.
  75515. */
  75516. template<auto... Value, auto... Other, typename... List>
  75517. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  75518. /*! @brief A value list composed by the values of all the value lists. */
  75519. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  75520. };
  75521. /**
  75522. * @brief Concatenates multiple value lists.
  75523. * @tparam Value Values provided by the value list.
  75524. */
  75525. template<auto... Value>
  75526. struct value_list_cat<value_list<Value...>> {
  75527. /*! @brief A value list composed by the values of all the value lists. */
  75528. using type = value_list<Value...>;
  75529. };
  75530. /**
  75531. * @brief Helper type.
  75532. * @tparam List Value lists to concatenate.
  75533. */
  75534. template<typename... List>
  75535. using value_list_cat_t = typename value_list_cat<List...>::type;
  75536. /*! @brief Primary template isn't defined on purpose. */
  75537. template<typename>
  75538. struct value_list_unique;
  75539. /**
  75540. * @brief Removes duplicates values from a value list.
  75541. * @tparam Value One of the values provided by the given value list.
  75542. * @tparam Other The other values provided by the given value list.
  75543. */
  75544. template<auto Value, auto... Other>
  75545. struct value_list_unique<value_list<Value, Other...>> {
  75546. /*! @brief A value list without duplicate types. */
  75547. using type = std::conditional_t<
  75548. ((Value == Other) || ...),
  75549. typename value_list_unique<value_list<Other...>>::type,
  75550. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  75551. };
  75552. /*! @brief Removes duplicates values from a value list. */
  75553. template<>
  75554. struct value_list_unique<value_list<>> {
  75555. /*! @brief A value list without duplicate types. */
  75556. using type = value_list<>;
  75557. };
  75558. /**
  75559. * @brief Helper type.
  75560. * @tparam Type A value list.
  75561. */
  75562. template<typename Type>
  75563. using value_list_unique_t = typename value_list_unique<Type>::type;
  75564. /**
  75565. * @brief Provides the member constant `value` to true if a value list contains
  75566. * a given value, false otherwise.
  75567. * @tparam List Value list.
  75568. * @tparam Value Value to look for.
  75569. */
  75570. template<typename List, auto Value>
  75571. struct value_list_contains;
  75572. /**
  75573. * @copybrief value_list_contains
  75574. * @tparam Value Values provided by the value list.
  75575. * @tparam Other Value to look for.
  75576. */
  75577. template<auto... Value, auto Other>
  75578. struct value_list_contains<value_list<Value...>, Other>
  75579. : std::bool_constant<((Value == Other) || ...)> {};
  75580. /**
  75581. * @brief Helper variable template.
  75582. * @tparam List Value list.
  75583. * @tparam Value Value to look for.
  75584. */
  75585. template<typename List, auto Value>
  75586. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  75587. /*! @brief Primary template isn't defined on purpose. */
  75588. template<typename...>
  75589. struct value_list_diff;
  75590. /**
  75591. * @brief Computes the difference between two value lists.
  75592. * @tparam Value Values provided by the first value list.
  75593. * @tparam Other Values provided by the second value list.
  75594. */
  75595. template<auto... Value, auto... Other>
  75596. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  75597. /*! @brief A value list that is the difference between the two value lists. */
  75598. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  75599. };
  75600. /**
  75601. * @brief Helper type.
  75602. * @tparam List Value lists between which to compute the difference.
  75603. */
  75604. template<typename... List>
  75605. using value_list_diff_t = typename value_list_diff<List...>::type;
  75606. /*! @brief Same as std::is_invocable, but with tuples. */
  75607. template<typename, typename>
  75608. struct is_applicable: std::false_type {};
  75609. /**
  75610. * @copybrief is_applicable
  75611. * @tparam Func A valid function type.
  75612. * @tparam Tuple Tuple-like type.
  75613. * @tparam Args The list of arguments to use to probe the function type.
  75614. */
  75615. template<typename Func, template<typename...> class Tuple, typename... Args>
  75616. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  75617. /**
  75618. * @copybrief is_applicable
  75619. * @tparam Func A valid function type.
  75620. * @tparam Tuple Tuple-like type.
  75621. * @tparam Args The list of arguments to use to probe the function type.
  75622. */
  75623. template<typename Func, template<typename...> class Tuple, typename... Args>
  75624. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  75625. /**
  75626. * @brief Helper variable template.
  75627. * @tparam Func A valid function type.
  75628. * @tparam Args The list of arguments to use to probe the function type.
  75629. */
  75630. template<typename Func, typename Args>
  75631. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  75632. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  75633. template<typename, typename, typename>
  75634. struct is_applicable_r: std::false_type {};
  75635. /**
  75636. * @copybrief is_applicable_r
  75637. * @tparam Ret The type to which the return type of the function should be
  75638. * convertible.
  75639. * @tparam Func A valid function type.
  75640. * @tparam Args The list of arguments to use to probe the function type.
  75641. */
  75642. template<typename Ret, typename Func, typename... Args>
  75643. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  75644. /**
  75645. * @brief Helper variable template.
  75646. * @tparam Ret The type to which the return type of the function should be
  75647. * convertible.
  75648. * @tparam Func A valid function type.
  75649. * @tparam Args The list of arguments to use to probe the function type.
  75650. */
  75651. template<typename Ret, typename Func, typename Args>
  75652. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  75653. /**
  75654. * @brief Provides the member constant `value` to true if a given type is
  75655. * complete, false otherwise.
  75656. * @tparam Type The type to test.
  75657. */
  75658. template<typename Type, typename = void>
  75659. struct is_complete: std::false_type {};
  75660. /*! @copydoc is_complete */
  75661. template<typename Type>
  75662. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  75663. /**
  75664. * @brief Helper variable template.
  75665. * @tparam Type The type to test.
  75666. */
  75667. template<typename Type>
  75668. inline constexpr bool is_complete_v = is_complete<Type>::value;
  75669. /**
  75670. * @brief Provides the member constant `value` to true if a given type is an
  75671. * iterator, false otherwise.
  75672. * @tparam Type The type to test.
  75673. */
  75674. template<typename Type, typename = void>
  75675. struct is_iterator: std::false_type {};
  75676. /*! @cond TURN_OFF_DOXYGEN */
  75677. namespace internal {
  75678. template<typename, typename = void>
  75679. struct has_iterator_category: std::false_type {};
  75680. template<typename Type>
  75681. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  75682. } // namespace internal
  75683. /*! @endcond */
  75684. /*! @copydoc is_iterator */
  75685. template<typename Type>
  75686. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  75687. : internal::has_iterator_category<Type> {};
  75688. /**
  75689. * @brief Helper variable template.
  75690. * @tparam Type The type to test.
  75691. */
  75692. template<typename Type>
  75693. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  75694. /**
  75695. * @brief Provides the member constant `value` to true if a given type is both
  75696. * an empty and non-final class, false otherwise.
  75697. * @tparam Type The type to test
  75698. */
  75699. template<typename Type>
  75700. struct is_ebco_eligible
  75701. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  75702. /**
  75703. * @brief Helper variable template.
  75704. * @tparam Type The type to test.
  75705. */
  75706. template<typename Type>
  75707. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  75708. /**
  75709. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  75710. * is valid and denotes a type, false otherwise.
  75711. * @tparam Type The type to test.
  75712. */
  75713. template<typename Type, typename = void>
  75714. struct is_transparent: std::false_type {};
  75715. /*! @copydoc is_transparent */
  75716. template<typename Type>
  75717. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  75718. /**
  75719. * @brief Helper variable template.
  75720. * @tparam Type The type to test.
  75721. */
  75722. template<typename Type>
  75723. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  75724. /*! @cond TURN_OFF_DOXYGEN */
  75725. namespace internal {
  75726. template<typename, typename = void>
  75727. struct has_tuple_size_value: std::false_type {};
  75728. template<typename Type>
  75729. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  75730. template<typename, typename = void>
  75731. struct has_value_type: std::false_type {};
  75732. template<typename Type>
  75733. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  75734. template<typename>
  75735. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  75736. template<typename Type, std::size_t... Index>
  75737. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  75738. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  75739. }
  75740. template<typename>
  75741. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  75742. return false;
  75743. }
  75744. template<typename Type>
  75745. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  75746. return true;
  75747. }
  75748. template<typename Type>
  75749. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  75750. // NOLINTBEGIN(modernize-use-transparent-functors)
  75751. if constexpr(std::is_array_v<Type>) {
  75752. return false;
  75753. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  75754. if constexpr(has_tuple_size_value<Type>::value) {
  75755. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  75756. } else {
  75757. return maybe_equality_comparable<Type>(0);
  75758. }
  75759. } else if constexpr(has_value_type<Type>::value) {
  75760. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  75761. return maybe_equality_comparable<Type>(0);
  75762. } else {
  75763. return false;
  75764. }
  75765. } else {
  75766. return maybe_equality_comparable<Type>(0);
  75767. }
  75768. // NOLINTEND(modernize-use-transparent-functors)
  75769. }
  75770. } // namespace internal
  75771. /*! @endcond */
  75772. /**
  75773. * @brief Provides the member constant `value` to true if a given type is
  75774. * equality comparable, false otherwise.
  75775. * @tparam Type The type to test.
  75776. */
  75777. template<typename Type>
  75778. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  75779. /*! @copydoc is_equality_comparable */
  75780. template<typename Type>
  75781. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  75782. /**
  75783. * @brief Helper variable template.
  75784. * @tparam Type The type to test.
  75785. */
  75786. template<typename Type>
  75787. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  75788. /**
  75789. * @brief Transcribes the constness of a type to another type.
  75790. * @tparam To The type to which to transcribe the constness.
  75791. * @tparam From The type from which to transcribe the constness.
  75792. */
  75793. template<typename To, typename From>
  75794. struct constness_as {
  75795. /*! @brief The type resulting from the transcription of the constness. */
  75796. using type = std::remove_const_t<To>;
  75797. };
  75798. /*! @copydoc constness_as */
  75799. template<typename To, typename From>
  75800. struct constness_as<To, const From> {
  75801. /*! @brief The type resulting from the transcription of the constness. */
  75802. using type = const To;
  75803. };
  75804. /**
  75805. * @brief Alias template to facilitate the transcription of the constness.
  75806. * @tparam To The type to which to transcribe the constness.
  75807. * @tparam From The type from which to transcribe the constness.
  75808. */
  75809. template<typename To, typename From>
  75810. using constness_as_t = typename constness_as<To, From>::type;
  75811. /**
  75812. * @brief Extracts the class of a non-static member object or function.
  75813. * @tparam Member A pointer to a non-static member object or function.
  75814. */
  75815. template<typename Member>
  75816. class member_class {
  75817. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  75818. template<typename Class, typename Ret, typename... Args>
  75819. static Class *clazz(Ret (Class::*)(Args...));
  75820. template<typename Class, typename Ret, typename... Args>
  75821. static Class *clazz(Ret (Class::*)(Args...) const);
  75822. template<typename Class, typename Type>
  75823. static Class *clazz(Type Class::*);
  75824. public:
  75825. /*! @brief The class of the given non-static member object or function. */
  75826. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  75827. };
  75828. /**
  75829. * @brief Helper type.
  75830. * @tparam Member A pointer to a non-static member object or function.
  75831. */
  75832. template<typename Member>
  75833. using member_class_t = typename member_class<Member>::type;
  75834. /**
  75835. * @brief Extracts the n-th argument of a _callable_ type.
  75836. * @tparam Index The index of the argument to extract.
  75837. * @tparam Candidate A valid _callable_ type.
  75838. */
  75839. template<std::size_t Index, typename Candidate>
  75840. class nth_argument {
  75841. template<typename Ret, typename... Args>
  75842. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  75843. template<typename Ret, typename Class, typename... Args>
  75844. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  75845. template<typename Ret, typename Class, typename... Args>
  75846. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  75847. template<typename Type, typename Class>
  75848. static constexpr type_list<Type> pick_up(Type Class ::*);
  75849. template<typename Type>
  75850. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  75851. public:
  75852. /*! @brief N-th argument of the _callable_ type. */
  75853. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  75854. };
  75855. /**
  75856. * @brief Helper type.
  75857. * @tparam Index The index of the argument to extract.
  75858. * @tparam Candidate A valid function, member function or data member type.
  75859. */
  75860. template<std::size_t Index, typename Candidate>
  75861. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  75862. } // namespace entt
  75863. template<typename... Type>
  75864. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  75865. template<std::size_t Index, typename... Type>
  75866. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  75867. template<auto... Value>
  75868. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  75869. template<std::size_t Index, auto... Value>
  75870. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  75871. #endif
  75872. namespace entt {
  75873. /*! @cond TURN_OFF_DOXYGEN */
  75874. namespace internal {
  75875. template<typename Type, std::size_t, typename = void>
  75876. struct compressed_pair_element {
  75877. using reference = Type &;
  75878. using const_reference = const Type &;
  75879. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  75880. // NOLINTNEXTLINE(modernize-use-equals-default)
  75881. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  75882. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  75883. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  75884. : value{std::forward<Arg>(arg)} {}
  75885. template<typename... Args, std::size_t... Index>
  75886. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  75887. : value{std::forward<Args>(std::get<Index>(args))...} {}
  75888. [[nodiscard]] constexpr reference get() noexcept {
  75889. return value;
  75890. }
  75891. [[nodiscard]] constexpr const_reference get() const noexcept {
  75892. return value;
  75893. }
  75894. private:
  75895. Type value{};
  75896. };
  75897. template<typename Type, std::size_t Tag>
  75898. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  75899. using reference = Type &;
  75900. using const_reference = const Type &;
  75901. using base_type = Type;
  75902. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  75903. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  75904. : base_type{} {}
  75905. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  75906. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  75907. : base_type{std::forward<Arg>(arg)} {}
  75908. template<typename... Args, std::size_t... Index>
  75909. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  75910. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  75911. [[nodiscard]] constexpr reference get() noexcept {
  75912. return *this;
  75913. }
  75914. [[nodiscard]] constexpr const_reference get() const noexcept {
  75915. return *this;
  75916. }
  75917. };
  75918. } // namespace internal
  75919. /*! @endcond */
  75920. /**
  75921. * @brief A compressed pair.
  75922. *
  75923. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  75924. * reduce its final size to a minimum.
  75925. *
  75926. * @tparam First The type of the first element that the pair stores.
  75927. * @tparam Second The type of the second element that the pair stores.
  75928. */
  75929. template<typename First, typename Second>
  75930. class compressed_pair final
  75931. : internal::compressed_pair_element<First, 0u>,
  75932. internal::compressed_pair_element<Second, 1u> {
  75933. using first_base = internal::compressed_pair_element<First, 0u>;
  75934. using second_base = internal::compressed_pair_element<Second, 1u>;
  75935. public:
  75936. /*! @brief The type of the first element that the pair stores. */
  75937. using first_type = First;
  75938. /*! @brief The type of the second element that the pair stores. */
  75939. using second_type = Second;
  75940. /**
  75941. * @brief Default constructor, conditionally enabled.
  75942. *
  75943. * This constructor is only available when the types that the pair stores
  75944. * are both at least default constructible.
  75945. *
  75946. * @tparam Dummy Dummy template parameter used for internal purposes.
  75947. */
  75948. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  75949. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  75950. : first_base{},
  75951. second_base{} {}
  75952. /**
  75953. * @brief Copy constructor.
  75954. * @param other The instance to copy from.
  75955. */
  75956. constexpr compressed_pair(const compressed_pair &other) = default;
  75957. /**
  75958. * @brief Move constructor.
  75959. * @param other The instance to move from.
  75960. */
  75961. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  75962. /**
  75963. * @brief Constructs a pair from its values.
  75964. * @tparam Arg Type of value to use to initialize the first element.
  75965. * @tparam Other Type of value to use to initialize the second element.
  75966. * @param arg Value to use to initialize the first element.
  75967. * @param other Value to use to initialize the second element.
  75968. */
  75969. template<typename Arg, typename Other>
  75970. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  75971. : first_base{std::forward<Arg>(arg)},
  75972. second_base{std::forward<Other>(other)} {}
  75973. /**
  75974. * @brief Constructs a pair by forwarding the arguments to its parts.
  75975. * @tparam Args Types of arguments to use to initialize the first element.
  75976. * @tparam Other Types of arguments to use to initialize the second element.
  75977. * @param args Arguments to use to initialize the first element.
  75978. * @param other Arguments to use to initialize the second element.
  75979. */
  75980. template<typename... Args, typename... Other>
  75981. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  75982. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  75983. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  75984. /*! @brief Default destructor. */
  75985. ~compressed_pair() = default;
  75986. /**
  75987. * @brief Copy assignment operator.
  75988. * @param other The instance to copy from.
  75989. * @return This compressed pair object.
  75990. */
  75991. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  75992. /**
  75993. * @brief Move assignment operator.
  75994. * @param other The instance to move from.
  75995. * @return This compressed pair object.
  75996. */
  75997. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  75998. /**
  75999. * @brief Returns the first element that a pair stores.
  76000. * @return The first element that a pair stores.
  76001. */
  76002. [[nodiscard]] constexpr first_type &first() noexcept {
  76003. return static_cast<first_base &>(*this).get();
  76004. }
  76005. /*! @copydoc first */
  76006. [[nodiscard]] constexpr const first_type &first() const noexcept {
  76007. return static_cast<const first_base &>(*this).get();
  76008. }
  76009. /**
  76010. * @brief Returns the second element that a pair stores.
  76011. * @return The second element that a pair stores.
  76012. */
  76013. [[nodiscard]] constexpr second_type &second() noexcept {
  76014. return static_cast<second_base &>(*this).get();
  76015. }
  76016. /*! @copydoc second */
  76017. [[nodiscard]] constexpr const second_type &second() const noexcept {
  76018. return static_cast<const second_base &>(*this).get();
  76019. }
  76020. /**
  76021. * @brief Swaps two compressed pair objects.
  76022. * @param other The compressed pair to swap with.
  76023. */
  76024. constexpr void swap(compressed_pair &other) noexcept {
  76025. using std::swap;
  76026. swap(first(), other.first());
  76027. swap(second(), other.second());
  76028. }
  76029. /**
  76030. * @brief Extracts an element from the compressed pair.
  76031. * @tparam Index An integer value that is either 0 or 1.
  76032. * @return Returns a reference to the first element if `Index` is 0 and a
  76033. * reference to the second element if `Index` is 1.
  76034. */
  76035. template<std::size_t Index>
  76036. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  76037. if constexpr(Index == 0u) {
  76038. return first();
  76039. } else {
  76040. static_assert(Index == 1u, "Index out of bounds");
  76041. return second();
  76042. }
  76043. }
  76044. /*! @copydoc get */
  76045. template<std::size_t Index>
  76046. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  76047. if constexpr(Index == 0u) {
  76048. return first();
  76049. } else {
  76050. static_assert(Index == 1u, "Index out of bounds");
  76051. return second();
  76052. }
  76053. }
  76054. };
  76055. /**
  76056. * @brief Deduction guide.
  76057. * @tparam Type Type of value to use to initialize the first element.
  76058. * @tparam Other Type of value to use to initialize the second element.
  76059. */
  76060. template<typename Type, typename Other>
  76061. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  76062. /**
  76063. * @brief Swaps two compressed pair objects.
  76064. * @tparam First The type of the first element that the pairs store.
  76065. * @tparam Second The type of the second element that the pairs store.
  76066. * @param lhs A valid compressed pair object.
  76067. * @param rhs A valid compressed pair object.
  76068. */
  76069. template<typename First, typename Second>
  76070. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  76071. lhs.swap(rhs);
  76072. }
  76073. } // namespace entt
  76074. namespace std {
  76075. /**
  76076. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  76077. * @tparam First The type of the first element that the pair stores.
  76078. * @tparam Second The type of the second element that the pair stores.
  76079. */
  76080. template<typename First, typename Second>
  76081. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  76082. /**
  76083. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  76084. * @tparam Index The index of the type to return.
  76085. * @tparam First The type of the first element that the pair stores.
  76086. * @tparam Second The type of the second element that the pair stores.
  76087. */
  76088. template<size_t Index, typename First, typename Second>
  76089. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  76090. static_assert(Index < 2u, "Index out of bounds");
  76091. };
  76092. } // namespace std
  76093. #endif
  76094. // #include "../core/iterator.hpp"
  76095. #ifndef ENTT_CORE_ITERATOR_HPP
  76096. #define ENTT_CORE_ITERATOR_HPP
  76097. #include <iterator>
  76098. #include <memory>
  76099. #include <type_traits>
  76100. #include <utility>
  76101. namespace entt {
  76102. /**
  76103. * @brief Helper type to use as pointer with input iterators.
  76104. * @tparam Type of wrapped value.
  76105. */
  76106. template<typename Type>
  76107. struct input_iterator_pointer final {
  76108. /*! @brief Value type. */
  76109. using value_type = Type;
  76110. /*! @brief Pointer type. */
  76111. using pointer = Type *;
  76112. /*! @brief Reference type. */
  76113. using reference = Type &;
  76114. /**
  76115. * @brief Constructs a proxy object by move.
  76116. * @param val Value to use to initialize the proxy object.
  76117. */
  76118. constexpr input_iterator_pointer(value_type &&val) noexcept(std::is_nothrow_move_constructible_v<value_type>)
  76119. : value{std::move(val)} {}
  76120. /**
  76121. * @brief Access operator for accessing wrapped values.
  76122. * @return A pointer to the wrapped value.
  76123. */
  76124. [[nodiscard]] constexpr pointer operator->() noexcept {
  76125. return std::addressof(value);
  76126. }
  76127. /**
  76128. * @brief Dereference operator for accessing wrapped values.
  76129. * @return A reference to the wrapped value.
  76130. */
  76131. [[nodiscard]] constexpr reference operator*() noexcept {
  76132. return value;
  76133. }
  76134. private:
  76135. Type value;
  76136. };
  76137. /**
  76138. * @brief Plain iota iterator (waiting for C++20).
  76139. * @tparam Type Value type.
  76140. */
  76141. template<typename Type>
  76142. class iota_iterator final {
  76143. static_assert(std::is_integral_v<Type>, "Not an integral type");
  76144. public:
  76145. /*! @brief Value type, likely an integral one. */
  76146. using value_type = Type;
  76147. /*! @brief Invalid pointer type. */
  76148. using pointer = void;
  76149. /*! @brief Non-reference type, same as value type. */
  76150. using reference = value_type;
  76151. /*! @brief Difference type. */
  76152. using difference_type = std::ptrdiff_t;
  76153. /*! @brief Iterator category. */
  76154. using iterator_category = std::input_iterator_tag;
  76155. /*! @brief Default constructor. */
  76156. constexpr iota_iterator() noexcept
  76157. : current{} {}
  76158. /**
  76159. * @brief Constructs an iota iterator from a given value.
  76160. * @param init The initial value assigned to the iota iterator.
  76161. */
  76162. constexpr iota_iterator(const value_type init) noexcept
  76163. : current{init} {}
  76164. /**
  76165. * @brief Pre-increment operator.
  76166. * @return This iota iterator.
  76167. */
  76168. constexpr iota_iterator &operator++() noexcept {
  76169. return ++current, *this;
  76170. }
  76171. /**
  76172. * @brief Post-increment operator.
  76173. * @return This iota iterator.
  76174. */
  76175. constexpr iota_iterator operator++(int) noexcept {
  76176. const iota_iterator orig = *this;
  76177. return ++(*this), orig;
  76178. }
  76179. /**
  76180. * @brief Dereference operator.
  76181. * @return The underlying value.
  76182. */
  76183. [[nodiscard]] constexpr reference operator*() const noexcept {
  76184. return current;
  76185. }
  76186. private:
  76187. value_type current;
  76188. };
  76189. /**
  76190. * @brief Comparison operator.
  76191. * @tparam Type Value type of the iota iterator.
  76192. * @param lhs A properly initialized iota iterator.
  76193. * @param rhs A properly initialized iota iterator.
  76194. * @return True if the two iterators are identical, false otherwise.
  76195. */
  76196. template<typename Type>
  76197. [[nodiscard]] constexpr bool operator==(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  76198. return *lhs == *rhs;
  76199. }
  76200. /**
  76201. * @brief Comparison operator.
  76202. * @tparam Type Value type of the iota iterator.
  76203. * @param lhs A properly initialized iota iterator.
  76204. * @param rhs A properly initialized iota iterator.
  76205. * @return True if the two iterators differ, false otherwise.
  76206. */
  76207. template<typename Type>
  76208. [[nodiscard]] constexpr bool operator!=(const iota_iterator<Type> &lhs, const iota_iterator<Type> &rhs) noexcept {
  76209. return !(lhs == rhs);
  76210. }
  76211. /**
  76212. * @brief Utility class to create an iterable object from a pair of iterators.
  76213. * @tparam It Type of iterator.
  76214. * @tparam Sentinel Type of sentinel.
  76215. */
  76216. template<typename It, typename Sentinel = It>
  76217. struct iterable_adaptor final {
  76218. /*! @brief Value type. */
  76219. using value_type = typename std::iterator_traits<It>::value_type;
  76220. /*! @brief Iterator type. */
  76221. using iterator = It;
  76222. /*! @brief Sentinel type. */
  76223. using sentinel = Sentinel;
  76224. /*! @brief Default constructor. */
  76225. constexpr iterable_adaptor() noexcept(std::is_nothrow_default_constructible_v<iterator> && std::is_nothrow_default_constructible_v<sentinel>)
  76226. : first{},
  76227. last{} {}
  76228. /**
  76229. * @brief Creates an iterable object from a pair of iterators.
  76230. * @param from Begin iterator.
  76231. * @param to End iterator.
  76232. */
  76233. constexpr iterable_adaptor(iterator from, sentinel to) noexcept(std::is_nothrow_move_constructible_v<iterator> && std::is_nothrow_move_constructible_v<sentinel>)
  76234. : first{std::move(from)},
  76235. last{std::move(to)} {}
  76236. /**
  76237. * @brief Returns an iterator to the beginning.
  76238. * @return An iterator to the first element of the range.
  76239. */
  76240. [[nodiscard]] constexpr iterator begin() const noexcept {
  76241. return first;
  76242. }
  76243. /**
  76244. * @brief Returns an iterator to the end.
  76245. * @return An iterator to the element following the last element of the
  76246. * range.
  76247. */
  76248. [[nodiscard]] constexpr sentinel end() const noexcept {
  76249. return last;
  76250. }
  76251. /*! @copydoc begin */
  76252. [[nodiscard]] constexpr iterator cbegin() const noexcept {
  76253. return begin();
  76254. }
  76255. /*! @copydoc end */
  76256. [[nodiscard]] constexpr sentinel cend() const noexcept {
  76257. return end();
  76258. }
  76259. private:
  76260. It first;
  76261. Sentinel last;
  76262. };
  76263. } // namespace entt
  76264. #endif
  76265. // #include "../core/memory.hpp"
  76266. #ifndef ENTT_CORE_MEMORY_HPP
  76267. #define ENTT_CORE_MEMORY_HPP
  76268. #include <cstddef>
  76269. #include <memory>
  76270. #include <tuple>
  76271. #include <type_traits>
  76272. #include <utility>
  76273. // #include "../config/config.h"
  76274. namespace entt {
  76275. /**
  76276. * @brief Unwraps fancy pointers, does nothing otherwise (waiting for C++20).
  76277. * @tparam Type Pointer type.
  76278. * @param ptr Fancy or raw pointer.
  76279. * @return A raw pointer that represents the address of the original pointer.
  76280. */
  76281. template<typename Type>
  76282. [[nodiscard]] constexpr auto to_address(Type &&ptr) noexcept {
  76283. if constexpr(std::is_pointer_v<std::decay_t<Type>>) {
  76284. return ptr;
  76285. } else {
  76286. return to_address(std::forward<Type>(ptr).operator->());
  76287. }
  76288. }
  76289. /**
  76290. * @brief Utility function to design allocation-aware containers.
  76291. * @tparam Allocator Type of allocator.
  76292. * @param lhs A valid allocator.
  76293. * @param rhs Another valid allocator.
  76294. */
  76295. template<typename Allocator>
  76296. constexpr void propagate_on_container_copy_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  76297. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_copy_assignment::value) {
  76298. lhs = rhs;
  76299. }
  76300. }
  76301. /**
  76302. * @brief Utility function to design allocation-aware containers.
  76303. * @tparam Allocator Type of allocator.
  76304. * @param lhs A valid allocator.
  76305. * @param rhs Another valid allocator.
  76306. */
  76307. template<typename Allocator>
  76308. constexpr void propagate_on_container_move_assignment([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  76309. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value) {
  76310. lhs = std::move(rhs);
  76311. }
  76312. }
  76313. /**
  76314. * @brief Utility function to design allocation-aware containers.
  76315. * @tparam Allocator Type of allocator.
  76316. * @param lhs A valid allocator.
  76317. * @param rhs Another valid allocator.
  76318. */
  76319. template<typename Allocator>
  76320. constexpr void propagate_on_container_swap([[maybe_unused]] Allocator &lhs, [[maybe_unused]] Allocator &rhs) noexcept {
  76321. if constexpr(std::allocator_traits<Allocator>::propagate_on_container_swap::value) {
  76322. using std::swap;
  76323. swap(lhs, rhs);
  76324. } else {
  76325. ENTT_ASSERT_CONSTEXPR(lhs == rhs, "Cannot swap the containers");
  76326. }
  76327. }
  76328. /**
  76329. * @brief Deleter for allocator-aware unique pointers (waiting for C++20).
  76330. * @tparam Allocator Type of allocator used to manage memory and elements.
  76331. */
  76332. template<typename Allocator>
  76333. struct allocation_deleter: private Allocator {
  76334. /*! @brief Allocator type. */
  76335. using allocator_type = Allocator;
  76336. /*! @brief Pointer type. */
  76337. using pointer = typename std::allocator_traits<Allocator>::pointer;
  76338. /**
  76339. * @brief Inherited constructors.
  76340. * @param alloc The allocator to use.
  76341. */
  76342. constexpr allocation_deleter(const allocator_type &alloc) noexcept(std::is_nothrow_copy_constructible_v<allocator_type>)
  76343. : Allocator{alloc} {}
  76344. /**
  76345. * @brief Destroys the pointed object and deallocates its memory.
  76346. * @param ptr A valid pointer to an object of the given type.
  76347. */
  76348. constexpr void operator()(pointer ptr) noexcept(std::is_nothrow_destructible_v<typename allocator_type::value_type>) {
  76349. using alloc_traits = std::allocator_traits<Allocator>;
  76350. alloc_traits::destroy(*this, to_address(ptr));
  76351. alloc_traits::deallocate(*this, ptr, 1u);
  76352. }
  76353. };
  76354. /**
  76355. * @brief Allows `std::unique_ptr` to use allocators (waiting for C++20).
  76356. * @tparam Type Type of object to allocate for and to construct.
  76357. * @tparam Allocator Type of allocator used to manage memory and elements.
  76358. * @tparam Args Types of arguments to use to construct the object.
  76359. * @param allocator The allocator to use.
  76360. * @param args Parameters to use to construct the object.
  76361. * @return A properly initialized unique pointer with a custom deleter.
  76362. */
  76363. template<typename Type, typename Allocator, typename... Args>
  76364. ENTT_CONSTEXPR auto allocate_unique(Allocator &allocator, Args &&...args) {
  76365. static_assert(!std::is_array_v<Type>, "Array types are not supported");
  76366. using alloc_traits = typename std::allocator_traits<Allocator>::template rebind_traits<Type>;
  76367. using allocator_type = typename alloc_traits::allocator_type;
  76368. allocator_type alloc{allocator};
  76369. auto ptr = alloc_traits::allocate(alloc, 1u);
  76370. ENTT_TRY {
  76371. alloc_traits::construct(alloc, to_address(ptr), std::forward<Args>(args)...);
  76372. }
  76373. ENTT_CATCH {
  76374. alloc_traits::deallocate(alloc, ptr, 1u);
  76375. ENTT_THROW;
  76376. }
  76377. return std::unique_ptr<Type, allocation_deleter<allocator_type>>{ptr, alloc};
  76378. }
  76379. /*! @cond TURN_OFF_DOXYGEN */
  76380. namespace internal {
  76381. template<typename Type>
  76382. struct uses_allocator_construction {
  76383. template<typename Allocator, typename... Params>
  76384. static constexpr auto args([[maybe_unused]] const Allocator &allocator, Params &&...params) noexcept {
  76385. if constexpr(!std::uses_allocator_v<Type, Allocator> && std::is_constructible_v<Type, Params...>) {
  76386. return std::forward_as_tuple(std::forward<Params>(params)...);
  76387. } else {
  76388. static_assert(std::uses_allocator_v<Type, Allocator>, "Ill-formed request");
  76389. if constexpr(std::is_constructible_v<Type, std::allocator_arg_t, const Allocator &, Params...>) {
  76390. return std::tuple<std::allocator_arg_t, const Allocator &, Params &&...>{std::allocator_arg, allocator, std::forward<Params>(params)...};
  76391. } else {
  76392. static_assert(std::is_constructible_v<Type, Params..., const Allocator &>, "Ill-formed request");
  76393. return std::forward_as_tuple(std::forward<Params>(params)..., allocator);
  76394. }
  76395. }
  76396. }
  76397. };
  76398. template<typename Type, typename Other>
  76399. struct uses_allocator_construction<std::pair<Type, Other>> {
  76400. using type = std::pair<Type, Other>;
  76401. template<typename Allocator, typename First, typename Second>
  76402. static constexpr auto args(const Allocator &allocator, std::piecewise_construct_t, First &&first, Second &&second) noexcept {
  76403. return std::make_tuple(
  76404. std::piecewise_construct,
  76405. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Type>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<First>(first)),
  76406. std::apply([&allocator](auto &&...curr) { return uses_allocator_construction<Other>::args(allocator, std::forward<decltype(curr)>(curr)...); }, std::forward<Second>(second)));
  76407. }
  76408. template<typename Allocator>
  76409. static constexpr auto args(const Allocator &allocator) noexcept {
  76410. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::tuple<>{}, std::tuple<>{});
  76411. }
  76412. template<typename Allocator, typename First, typename Second>
  76413. static constexpr auto args(const Allocator &allocator, First &&first, Second &&second) noexcept {
  76414. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::forward<First>(first)), std::forward_as_tuple(std::forward<Second>(second)));
  76415. }
  76416. template<typename Allocator, typename First, typename Second>
  76417. static constexpr auto args(const Allocator &allocator, const std::pair<First, Second> &value) noexcept {
  76418. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(value.first), std::forward_as_tuple(value.second));
  76419. }
  76420. template<typename Allocator, typename First, typename Second>
  76421. static constexpr auto args(const Allocator &allocator, std::pair<First, Second> &&value) noexcept {
  76422. return uses_allocator_construction<type>::args(allocator, std::piecewise_construct, std::forward_as_tuple(std::move(value.first)), std::forward_as_tuple(std::move(value.second)));
  76423. }
  76424. };
  76425. } // namespace internal
  76426. /*! @endcond */
  76427. /**
  76428. * @brief Uses-allocator construction utility (waiting for C++20).
  76429. *
  76430. * Primarily intended for internal use. Prepares the argument list needed to
  76431. * create an object of a given type by means of uses-allocator construction.
  76432. *
  76433. * @tparam Type Type to return arguments for.
  76434. * @tparam Allocator Type of allocator used to manage memory and elements.
  76435. * @tparam Args Types of arguments to use to construct the object.
  76436. * @param allocator The allocator to use.
  76437. * @param args Parameters to use to construct the object.
  76438. * @return The arguments needed to create an object of the given type.
  76439. */
  76440. template<typename Type, typename Allocator, typename... Args>
  76441. constexpr auto uses_allocator_construction_args(const Allocator &allocator, Args &&...args) noexcept {
  76442. return internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...);
  76443. }
  76444. /**
  76445. * @brief Uses-allocator construction utility (waiting for C++20).
  76446. *
  76447. * Primarily intended for internal use. Creates an object of a given type by
  76448. * means of uses-allocator construction.
  76449. *
  76450. * @tparam Type Type of object to create.
  76451. * @tparam Allocator Type of allocator used to manage memory and elements.
  76452. * @tparam Args Types of arguments to use to construct the object.
  76453. * @param allocator The allocator to use.
  76454. * @param args Parameters to use to construct the object.
  76455. * @return A newly created object of the given type.
  76456. */
  76457. template<typename Type, typename Allocator, typename... Args>
  76458. constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args) {
  76459. return std::make_from_tuple<Type>(internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  76460. }
  76461. /**
  76462. * @brief Uses-allocator construction utility (waiting for C++20).
  76463. *
  76464. * Primarily intended for internal use. Creates an object of a given type by
  76465. * means of uses-allocator construction at an uninitialized memory location.
  76466. *
  76467. * @tparam Type Type of object to create.
  76468. * @tparam Allocator Type of allocator used to manage memory and elements.
  76469. * @tparam Args Types of arguments to use to construct the object.
  76470. * @param value Memory location in which to place the object.
  76471. * @param allocator The allocator to use.
  76472. * @param args Parameters to use to construct the object.
  76473. * @return A pointer to the newly created object of the given type.
  76474. */
  76475. template<typename Type, typename Allocator, typename... Args>
  76476. constexpr Type *uninitialized_construct_using_allocator(Type *value, const Allocator &allocator, Args &&...args) {
  76477. return std::apply([value](auto &&...curr) { return ::new(value) Type(std::forward<decltype(curr)>(curr)...); }, internal::uses_allocator_construction<Type>::args(allocator, std::forward<Args>(args)...));
  76478. }
  76479. } // namespace entt
  76480. #endif
  76481. // #include "../core/type_traits.hpp"
  76482. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  76483. #define ENTT_CORE_TYPE_TRAITS_HPP
  76484. #include <cstddef>
  76485. #include <iterator>
  76486. #include <tuple>
  76487. #include <type_traits>
  76488. #include <utility>
  76489. // #include "../config/config.h"
  76490. // #include "fwd.hpp"
  76491. namespace entt {
  76492. /**
  76493. * @brief Utility class to disambiguate overloaded functions.
  76494. * @tparam N Number of choices available.
  76495. */
  76496. template<std::size_t N>
  76497. struct choice_t
  76498. // unfortunately, doxygen cannot parse such a construct
  76499. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  76500. {};
  76501. /*! @copybrief choice_t */
  76502. template<>
  76503. struct choice_t<0> {};
  76504. /**
  76505. * @brief Variable template for the choice trick.
  76506. * @tparam N Number of choices available.
  76507. */
  76508. template<std::size_t N>
  76509. inline constexpr choice_t<N> choice{};
  76510. /**
  76511. * @brief Identity type trait.
  76512. *
  76513. * Useful to establish non-deduced contexts in template argument deduction
  76514. * (waiting for C++20) or to provide types through function arguments.
  76515. *
  76516. * @tparam Type A type.
  76517. */
  76518. template<typename Type>
  76519. struct type_identity {
  76520. /*! @brief Identity type. */
  76521. using type = Type;
  76522. };
  76523. /**
  76524. * @brief Helper type.
  76525. * @tparam Type A type.
  76526. */
  76527. template<typename Type>
  76528. using type_identity_t = typename type_identity<Type>::type;
  76529. /**
  76530. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  76531. * @tparam Type The type of which to return the size.
  76532. */
  76533. template<typename Type, typename = void>
  76534. struct size_of: std::integral_constant<std::size_t, 0u> {};
  76535. /*! @copydoc size_of */
  76536. template<typename Type>
  76537. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  76538. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  76539. : std::integral_constant<std::size_t, sizeof(Type)> {};
  76540. /**
  76541. * @brief Helper variable template.
  76542. * @tparam Type The type of which to return the size.
  76543. */
  76544. template<typename Type>
  76545. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  76546. /**
  76547. * @brief Using declaration to be used to _repeat_ the same type a number of
  76548. * times equal to the size of a given parameter pack.
  76549. * @tparam Type A type to repeat.
  76550. */
  76551. template<typename Type, typename>
  76552. using unpack_as_type = Type;
  76553. /**
  76554. * @brief Helper variable template to be used to _repeat_ the same value a
  76555. * number of times equal to the size of a given parameter pack.
  76556. * @tparam Value A value to repeat.
  76557. */
  76558. template<auto Value, typename>
  76559. inline constexpr auto unpack_as_value = Value;
  76560. /**
  76561. * @brief Wraps a static constant.
  76562. * @tparam Value A static constant.
  76563. */
  76564. template<auto Value>
  76565. using integral_constant = std::integral_constant<decltype(Value), Value>;
  76566. /**
  76567. * @brief Alias template to facilitate the creation of named values.
  76568. * @tparam Value A constant value at least convertible to `id_type`.
  76569. */
  76570. template<id_type Value>
  76571. using tag = integral_constant<Value>;
  76572. /**
  76573. * @brief A class to use to push around lists of types, nothing more.
  76574. * @tparam Type Types provided by the type list.
  76575. */
  76576. template<typename... Type>
  76577. struct type_list {
  76578. /*! @brief Type list type. */
  76579. using type = type_list;
  76580. /*! @brief Compile-time number of elements in the type list. */
  76581. static constexpr auto size = sizeof...(Type);
  76582. };
  76583. /*! @brief Primary template isn't defined on purpose. */
  76584. template<std::size_t, typename>
  76585. struct type_list_element;
  76586. /**
  76587. * @brief Provides compile-time indexed access to the types of a type list.
  76588. * @tparam Index Index of the type to return.
  76589. * @tparam First First type provided by the type list.
  76590. * @tparam Other Other types provided by the type list.
  76591. */
  76592. template<std::size_t Index, typename First, typename... Other>
  76593. struct type_list_element<Index, type_list<First, Other...>>
  76594. : type_list_element<Index - 1u, type_list<Other...>> {};
  76595. /**
  76596. * @brief Provides compile-time indexed access to the types of a type list.
  76597. * @tparam First First type provided by the type list.
  76598. * @tparam Other Other types provided by the type list.
  76599. */
  76600. template<typename First, typename... Other>
  76601. struct type_list_element<0u, type_list<First, Other...>> {
  76602. /*! @brief Searched type. */
  76603. using type = First;
  76604. };
  76605. /**
  76606. * @brief Helper type.
  76607. * @tparam Index Index of the type to return.
  76608. * @tparam List Type list to search into.
  76609. */
  76610. template<std::size_t Index, typename List>
  76611. using type_list_element_t = typename type_list_element<Index, List>::type;
  76612. /*! @brief Primary template isn't defined on purpose. */
  76613. template<typename, typename>
  76614. struct type_list_index;
  76615. /**
  76616. * @brief Provides compile-time type access to the types of a type list.
  76617. * @tparam Type Type to look for and for which to return the index.
  76618. * @tparam First First type provided by the type list.
  76619. * @tparam Other Other types provided by the type list.
  76620. */
  76621. template<typename Type, typename First, typename... Other>
  76622. struct type_list_index<Type, type_list<First, Other...>> {
  76623. /*! @brief Unsigned integer type. */
  76624. using value_type = std::size_t;
  76625. /*! @brief Compile-time position of the given type in the sublist. */
  76626. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  76627. };
  76628. /**
  76629. * @brief Provides compile-time type access to the types of a type list.
  76630. * @tparam Type Type to look for and for which to return the index.
  76631. * @tparam Other Other types provided by the type list.
  76632. */
  76633. template<typename Type, typename... Other>
  76634. struct type_list_index<Type, type_list<Type, Other...>> {
  76635. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  76636. /*! @brief Unsigned integer type. */
  76637. using value_type = std::size_t;
  76638. /*! @brief Compile-time position of the given type in the sublist. */
  76639. static constexpr value_type value = 0u;
  76640. };
  76641. /**
  76642. * @brief Provides compile-time type access to the types of a type list.
  76643. * @tparam Type Type to look for and for which to return the index.
  76644. */
  76645. template<typename Type>
  76646. struct type_list_index<Type, type_list<>> {
  76647. /*! @brief Unsigned integer type. */
  76648. using value_type = std::size_t;
  76649. /*! @brief Compile-time position of the given type in the sublist. */
  76650. static constexpr value_type value = 0u;
  76651. };
  76652. /**
  76653. * @brief Helper variable template.
  76654. * @tparam List Type list.
  76655. * @tparam Type Type to look for and for which to return the index.
  76656. */
  76657. template<typename Type, typename List>
  76658. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  76659. /**
  76660. * @brief Concatenates multiple type lists.
  76661. * @tparam Type Types provided by the first type list.
  76662. * @tparam Other Types provided by the second type list.
  76663. * @return A type list composed by the types of both the type lists.
  76664. */
  76665. template<typename... Type, typename... Other>
  76666. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  76667. return {};
  76668. }
  76669. /*! @brief Primary template isn't defined on purpose. */
  76670. template<typename...>
  76671. struct type_list_cat;
  76672. /*! @brief Concatenates multiple type lists. */
  76673. template<>
  76674. struct type_list_cat<> {
  76675. /*! @brief A type list composed by the types of all the type lists. */
  76676. using type = type_list<>;
  76677. };
  76678. /**
  76679. * @brief Concatenates multiple type lists.
  76680. * @tparam Type Types provided by the first type list.
  76681. * @tparam Other Types provided by the second type list.
  76682. * @tparam List Other type lists, if any.
  76683. */
  76684. template<typename... Type, typename... Other, typename... List>
  76685. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  76686. /*! @brief A type list composed by the types of all the type lists. */
  76687. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  76688. };
  76689. /**
  76690. * @brief Concatenates multiple type lists.
  76691. * @tparam Type Types provided by the type list.
  76692. */
  76693. template<typename... Type>
  76694. struct type_list_cat<type_list<Type...>> {
  76695. /*! @brief A type list composed by the types of all the type lists. */
  76696. using type = type_list<Type...>;
  76697. };
  76698. /**
  76699. * @brief Helper type.
  76700. * @tparam List Type lists to concatenate.
  76701. */
  76702. template<typename... List>
  76703. using type_list_cat_t = typename type_list_cat<List...>::type;
  76704. /*! @cond TURN_OFF_DOXYGEN */
  76705. namespace internal {
  76706. template<typename...>
  76707. struct type_list_unique;
  76708. template<typename First, typename... Other, typename... Type>
  76709. struct type_list_unique<type_list<First, Other...>, Type...>
  76710. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  76711. template<typename... Type>
  76712. struct type_list_unique<type_list<>, Type...> {
  76713. using type = type_list<Type...>;
  76714. };
  76715. } // namespace internal
  76716. /*! @endcond */
  76717. /**
  76718. * @brief Removes duplicates types from a type list.
  76719. * @tparam List Type list.
  76720. */
  76721. template<typename List>
  76722. struct type_list_unique {
  76723. /*! @brief A type list without duplicate types. */
  76724. using type = typename internal::type_list_unique<List>::type;
  76725. };
  76726. /**
  76727. * @brief Helper type.
  76728. * @tparam List Type list.
  76729. */
  76730. template<typename List>
  76731. using type_list_unique_t = typename type_list_unique<List>::type;
  76732. /**
  76733. * @brief Provides the member constant `value` to true if a type list contains a
  76734. * given type, false otherwise.
  76735. * @tparam List Type list.
  76736. * @tparam Type Type to look for.
  76737. */
  76738. template<typename List, typename Type>
  76739. struct type_list_contains;
  76740. /**
  76741. * @copybrief type_list_contains
  76742. * @tparam Type Types provided by the type list.
  76743. * @tparam Other Type to look for.
  76744. */
  76745. template<typename... Type, typename Other>
  76746. struct type_list_contains<type_list<Type...>, Other>
  76747. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  76748. /**
  76749. * @brief Helper variable template.
  76750. * @tparam List Type list.
  76751. * @tparam Type Type to look for.
  76752. */
  76753. template<typename List, typename Type>
  76754. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  76755. /*! @brief Primary template isn't defined on purpose. */
  76756. template<typename...>
  76757. struct type_list_diff;
  76758. /**
  76759. * @brief Computes the difference between two type lists.
  76760. * @tparam Type Types provided by the first type list.
  76761. * @tparam Other Types provided by the second type list.
  76762. */
  76763. template<typename... Type, typename... Other>
  76764. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  76765. /*! @brief A type list that is the difference between the two type lists. */
  76766. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  76767. };
  76768. /**
  76769. * @brief Helper type.
  76770. * @tparam List Type lists between which to compute the difference.
  76771. */
  76772. template<typename... List>
  76773. using type_list_diff_t = typename type_list_diff<List...>::type;
  76774. /*! @brief Primary template isn't defined on purpose. */
  76775. template<typename, template<typename...> class>
  76776. struct type_list_transform;
  76777. /**
  76778. * @brief Applies a given _function_ to a type list and generate a new list.
  76779. * @tparam Type Types provided by the type list.
  76780. * @tparam Op Unary operation as template class with a type member named `type`.
  76781. */
  76782. template<typename... Type, template<typename...> class Op>
  76783. struct type_list_transform<type_list<Type...>, Op> {
  76784. /*! @brief Resulting type list after applying the transform function. */
  76785. // NOLINTNEXTLINE(modernize-type-traits)
  76786. using type = type_list<typename Op<Type>::type...>;
  76787. };
  76788. /**
  76789. * @brief Helper type.
  76790. * @tparam List Type list.
  76791. * @tparam Op Unary operation as template class with a type member named `type`.
  76792. */
  76793. template<typename List, template<typename...> class Op>
  76794. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  76795. /**
  76796. * @brief A class to use to push around lists of constant values, nothing more.
  76797. * @tparam Value Values provided by the value list.
  76798. */
  76799. template<auto... Value>
  76800. struct value_list {
  76801. /*! @brief Value list type. */
  76802. using type = value_list;
  76803. /*! @brief Compile-time number of elements in the value list. */
  76804. static constexpr auto size = sizeof...(Value);
  76805. };
  76806. /*! @brief Primary template isn't defined on purpose. */
  76807. template<std::size_t, typename>
  76808. struct value_list_element;
  76809. /**
  76810. * @brief Provides compile-time indexed access to the values of a value list.
  76811. * @tparam Index Index of the value to return.
  76812. * @tparam Value First value provided by the value list.
  76813. * @tparam Other Other values provided by the value list.
  76814. */
  76815. template<std::size_t Index, auto Value, auto... Other>
  76816. struct value_list_element<Index, value_list<Value, Other...>>
  76817. : value_list_element<Index - 1u, value_list<Other...>> {};
  76818. /**
  76819. * @brief Provides compile-time indexed access to the types of a type list.
  76820. * @tparam Value First value provided by the value list.
  76821. * @tparam Other Other values provided by the value list.
  76822. */
  76823. template<auto Value, auto... Other>
  76824. struct value_list_element<0u, value_list<Value, Other...>> {
  76825. /*! @brief Searched type. */
  76826. using type = decltype(Value);
  76827. /*! @brief Searched value. */
  76828. static constexpr auto value = Value;
  76829. };
  76830. /**
  76831. * @brief Helper type.
  76832. * @tparam Index Index of the type to return.
  76833. * @tparam List Value list to search into.
  76834. */
  76835. template<std::size_t Index, typename List>
  76836. using value_list_element_t = typename value_list_element<Index, List>::type;
  76837. /**
  76838. * @brief Helper type.
  76839. * @tparam Index Index of the value to return.
  76840. * @tparam List Value list to search into.
  76841. */
  76842. template<std::size_t Index, typename List>
  76843. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  76844. /*! @brief Primary template isn't defined on purpose. */
  76845. template<auto, typename>
  76846. struct value_list_index;
  76847. /**
  76848. * @brief Provides compile-time type access to the values of a value list.
  76849. * @tparam Value Value to look for and for which to return the index.
  76850. * @tparam First First value provided by the value list.
  76851. * @tparam Other Other values provided by the value list.
  76852. */
  76853. template<auto Value, auto First, auto... Other>
  76854. struct value_list_index<Value, value_list<First, Other...>> {
  76855. /*! @brief Unsigned integer type. */
  76856. using value_type = std::size_t;
  76857. /*! @brief Compile-time position of the given value in the sublist. */
  76858. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  76859. };
  76860. /**
  76861. * @brief Provides compile-time type access to the values of a value list.
  76862. * @tparam Value Value to look for and for which to return the index.
  76863. * @tparam Other Other values provided by the value list.
  76864. */
  76865. template<auto Value, auto... Other>
  76866. struct value_list_index<Value, value_list<Value, Other...>> {
  76867. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  76868. /*! @brief Unsigned integer type. */
  76869. using value_type = std::size_t;
  76870. /*! @brief Compile-time position of the given value in the sublist. */
  76871. static constexpr value_type value = 0u;
  76872. };
  76873. /**
  76874. * @brief Provides compile-time type access to the values of a value list.
  76875. * @tparam Value Value to look for and for which to return the index.
  76876. */
  76877. template<auto Value>
  76878. struct value_list_index<Value, value_list<>> {
  76879. /*! @brief Unsigned integer type. */
  76880. using value_type = std::size_t;
  76881. /*! @brief Compile-time position of the given type in the sublist. */
  76882. static constexpr value_type value = 0u;
  76883. };
  76884. /**
  76885. * @brief Helper variable template.
  76886. * @tparam List Value list.
  76887. * @tparam Value Value to look for and for which to return the index.
  76888. */
  76889. template<auto Value, typename List>
  76890. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  76891. /**
  76892. * @brief Concatenates multiple value lists.
  76893. * @tparam Value Values provided by the first value list.
  76894. * @tparam Other Values provided by the second value list.
  76895. * @return A value list composed by the values of both the value lists.
  76896. */
  76897. template<auto... Value, auto... Other>
  76898. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  76899. return {};
  76900. }
  76901. /*! @brief Primary template isn't defined on purpose. */
  76902. template<typename...>
  76903. struct value_list_cat;
  76904. /*! @brief Concatenates multiple value lists. */
  76905. template<>
  76906. struct value_list_cat<> {
  76907. /*! @brief A value list composed by the values of all the value lists. */
  76908. using type = value_list<>;
  76909. };
  76910. /**
  76911. * @brief Concatenates multiple value lists.
  76912. * @tparam Value Values provided by the first value list.
  76913. * @tparam Other Values provided by the second value list.
  76914. * @tparam List Other value lists, if any.
  76915. */
  76916. template<auto... Value, auto... Other, typename... List>
  76917. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  76918. /*! @brief A value list composed by the values of all the value lists. */
  76919. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  76920. };
  76921. /**
  76922. * @brief Concatenates multiple value lists.
  76923. * @tparam Value Values provided by the value list.
  76924. */
  76925. template<auto... Value>
  76926. struct value_list_cat<value_list<Value...>> {
  76927. /*! @brief A value list composed by the values of all the value lists. */
  76928. using type = value_list<Value...>;
  76929. };
  76930. /**
  76931. * @brief Helper type.
  76932. * @tparam List Value lists to concatenate.
  76933. */
  76934. template<typename... List>
  76935. using value_list_cat_t = typename value_list_cat<List...>::type;
  76936. /*! @brief Primary template isn't defined on purpose. */
  76937. template<typename>
  76938. struct value_list_unique;
  76939. /**
  76940. * @brief Removes duplicates values from a value list.
  76941. * @tparam Value One of the values provided by the given value list.
  76942. * @tparam Other The other values provided by the given value list.
  76943. */
  76944. template<auto Value, auto... Other>
  76945. struct value_list_unique<value_list<Value, Other...>> {
  76946. /*! @brief A value list without duplicate types. */
  76947. using type = std::conditional_t<
  76948. ((Value == Other) || ...),
  76949. typename value_list_unique<value_list<Other...>>::type,
  76950. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  76951. };
  76952. /*! @brief Removes duplicates values from a value list. */
  76953. template<>
  76954. struct value_list_unique<value_list<>> {
  76955. /*! @brief A value list without duplicate types. */
  76956. using type = value_list<>;
  76957. };
  76958. /**
  76959. * @brief Helper type.
  76960. * @tparam Type A value list.
  76961. */
  76962. template<typename Type>
  76963. using value_list_unique_t = typename value_list_unique<Type>::type;
  76964. /**
  76965. * @brief Provides the member constant `value` to true if a value list contains
  76966. * a given value, false otherwise.
  76967. * @tparam List Value list.
  76968. * @tparam Value Value to look for.
  76969. */
  76970. template<typename List, auto Value>
  76971. struct value_list_contains;
  76972. /**
  76973. * @copybrief value_list_contains
  76974. * @tparam Value Values provided by the value list.
  76975. * @tparam Other Value to look for.
  76976. */
  76977. template<auto... Value, auto Other>
  76978. struct value_list_contains<value_list<Value...>, Other>
  76979. : std::bool_constant<((Value == Other) || ...)> {};
  76980. /**
  76981. * @brief Helper variable template.
  76982. * @tparam List Value list.
  76983. * @tparam Value Value to look for.
  76984. */
  76985. template<typename List, auto Value>
  76986. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  76987. /*! @brief Primary template isn't defined on purpose. */
  76988. template<typename...>
  76989. struct value_list_diff;
  76990. /**
  76991. * @brief Computes the difference between two value lists.
  76992. * @tparam Value Values provided by the first value list.
  76993. * @tparam Other Values provided by the second value list.
  76994. */
  76995. template<auto... Value, auto... Other>
  76996. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  76997. /*! @brief A value list that is the difference between the two value lists. */
  76998. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  76999. };
  77000. /**
  77001. * @brief Helper type.
  77002. * @tparam List Value lists between which to compute the difference.
  77003. */
  77004. template<typename... List>
  77005. using value_list_diff_t = typename value_list_diff<List...>::type;
  77006. /*! @brief Same as std::is_invocable, but with tuples. */
  77007. template<typename, typename>
  77008. struct is_applicable: std::false_type {};
  77009. /**
  77010. * @copybrief is_applicable
  77011. * @tparam Func A valid function type.
  77012. * @tparam Tuple Tuple-like type.
  77013. * @tparam Args The list of arguments to use to probe the function type.
  77014. */
  77015. template<typename Func, template<typename...> class Tuple, typename... Args>
  77016. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  77017. /**
  77018. * @copybrief is_applicable
  77019. * @tparam Func A valid function type.
  77020. * @tparam Tuple Tuple-like type.
  77021. * @tparam Args The list of arguments to use to probe the function type.
  77022. */
  77023. template<typename Func, template<typename...> class Tuple, typename... Args>
  77024. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  77025. /**
  77026. * @brief Helper variable template.
  77027. * @tparam Func A valid function type.
  77028. * @tparam Args The list of arguments to use to probe the function type.
  77029. */
  77030. template<typename Func, typename Args>
  77031. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  77032. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  77033. template<typename, typename, typename>
  77034. struct is_applicable_r: std::false_type {};
  77035. /**
  77036. * @copybrief is_applicable_r
  77037. * @tparam Ret The type to which the return type of the function should be
  77038. * convertible.
  77039. * @tparam Func A valid function type.
  77040. * @tparam Args The list of arguments to use to probe the function type.
  77041. */
  77042. template<typename Ret, typename Func, typename... Args>
  77043. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  77044. /**
  77045. * @brief Helper variable template.
  77046. * @tparam Ret The type to which the return type of the function should be
  77047. * convertible.
  77048. * @tparam Func A valid function type.
  77049. * @tparam Args The list of arguments to use to probe the function type.
  77050. */
  77051. template<typename Ret, typename Func, typename Args>
  77052. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  77053. /**
  77054. * @brief Provides the member constant `value` to true if a given type is
  77055. * complete, false otherwise.
  77056. * @tparam Type The type to test.
  77057. */
  77058. template<typename Type, typename = void>
  77059. struct is_complete: std::false_type {};
  77060. /*! @copydoc is_complete */
  77061. template<typename Type>
  77062. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  77063. /**
  77064. * @brief Helper variable template.
  77065. * @tparam Type The type to test.
  77066. */
  77067. template<typename Type>
  77068. inline constexpr bool is_complete_v = is_complete<Type>::value;
  77069. /**
  77070. * @brief Provides the member constant `value` to true if a given type is an
  77071. * iterator, false otherwise.
  77072. * @tparam Type The type to test.
  77073. */
  77074. template<typename Type, typename = void>
  77075. struct is_iterator: std::false_type {};
  77076. /*! @cond TURN_OFF_DOXYGEN */
  77077. namespace internal {
  77078. template<typename, typename = void>
  77079. struct has_iterator_category: std::false_type {};
  77080. template<typename Type>
  77081. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  77082. } // namespace internal
  77083. /*! @endcond */
  77084. /*! @copydoc is_iterator */
  77085. template<typename Type>
  77086. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  77087. : internal::has_iterator_category<Type> {};
  77088. /**
  77089. * @brief Helper variable template.
  77090. * @tparam Type The type to test.
  77091. */
  77092. template<typename Type>
  77093. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  77094. /**
  77095. * @brief Provides the member constant `value` to true if a given type is both
  77096. * an empty and non-final class, false otherwise.
  77097. * @tparam Type The type to test
  77098. */
  77099. template<typename Type>
  77100. struct is_ebco_eligible
  77101. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  77102. /**
  77103. * @brief Helper variable template.
  77104. * @tparam Type The type to test.
  77105. */
  77106. template<typename Type>
  77107. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  77108. /**
  77109. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  77110. * is valid and denotes a type, false otherwise.
  77111. * @tparam Type The type to test.
  77112. */
  77113. template<typename Type, typename = void>
  77114. struct is_transparent: std::false_type {};
  77115. /*! @copydoc is_transparent */
  77116. template<typename Type>
  77117. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  77118. /**
  77119. * @brief Helper variable template.
  77120. * @tparam Type The type to test.
  77121. */
  77122. template<typename Type>
  77123. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  77124. /*! @cond TURN_OFF_DOXYGEN */
  77125. namespace internal {
  77126. template<typename, typename = void>
  77127. struct has_tuple_size_value: std::false_type {};
  77128. template<typename Type>
  77129. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  77130. template<typename, typename = void>
  77131. struct has_value_type: std::false_type {};
  77132. template<typename Type>
  77133. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  77134. template<typename>
  77135. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  77136. template<typename Type, std::size_t... Index>
  77137. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  77138. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  77139. }
  77140. template<typename>
  77141. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  77142. return false;
  77143. }
  77144. template<typename Type>
  77145. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  77146. return true;
  77147. }
  77148. template<typename Type>
  77149. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  77150. // NOLINTBEGIN(modernize-use-transparent-functors)
  77151. if constexpr(std::is_array_v<Type>) {
  77152. return false;
  77153. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  77154. if constexpr(has_tuple_size_value<Type>::value) {
  77155. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  77156. } else {
  77157. return maybe_equality_comparable<Type>(0);
  77158. }
  77159. } else if constexpr(has_value_type<Type>::value) {
  77160. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  77161. return maybe_equality_comparable<Type>(0);
  77162. } else {
  77163. return false;
  77164. }
  77165. } else {
  77166. return maybe_equality_comparable<Type>(0);
  77167. }
  77168. // NOLINTEND(modernize-use-transparent-functors)
  77169. }
  77170. } // namespace internal
  77171. /*! @endcond */
  77172. /**
  77173. * @brief Provides the member constant `value` to true if a given type is
  77174. * equality comparable, false otherwise.
  77175. * @tparam Type The type to test.
  77176. */
  77177. template<typename Type>
  77178. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  77179. /*! @copydoc is_equality_comparable */
  77180. template<typename Type>
  77181. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  77182. /**
  77183. * @brief Helper variable template.
  77184. * @tparam Type The type to test.
  77185. */
  77186. template<typename Type>
  77187. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  77188. /**
  77189. * @brief Transcribes the constness of a type to another type.
  77190. * @tparam To The type to which to transcribe the constness.
  77191. * @tparam From The type from which to transcribe the constness.
  77192. */
  77193. template<typename To, typename From>
  77194. struct constness_as {
  77195. /*! @brief The type resulting from the transcription of the constness. */
  77196. using type = std::remove_const_t<To>;
  77197. };
  77198. /*! @copydoc constness_as */
  77199. template<typename To, typename From>
  77200. struct constness_as<To, const From> {
  77201. /*! @brief The type resulting from the transcription of the constness. */
  77202. using type = const To;
  77203. };
  77204. /**
  77205. * @brief Alias template to facilitate the transcription of the constness.
  77206. * @tparam To The type to which to transcribe the constness.
  77207. * @tparam From The type from which to transcribe the constness.
  77208. */
  77209. template<typename To, typename From>
  77210. using constness_as_t = typename constness_as<To, From>::type;
  77211. /**
  77212. * @brief Extracts the class of a non-static member object or function.
  77213. * @tparam Member A pointer to a non-static member object or function.
  77214. */
  77215. template<typename Member>
  77216. class member_class {
  77217. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  77218. template<typename Class, typename Ret, typename... Args>
  77219. static Class *clazz(Ret (Class::*)(Args...));
  77220. template<typename Class, typename Ret, typename... Args>
  77221. static Class *clazz(Ret (Class::*)(Args...) const);
  77222. template<typename Class, typename Type>
  77223. static Class *clazz(Type Class::*);
  77224. public:
  77225. /*! @brief The class of the given non-static member object or function. */
  77226. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  77227. };
  77228. /**
  77229. * @brief Helper type.
  77230. * @tparam Member A pointer to a non-static member object or function.
  77231. */
  77232. template<typename Member>
  77233. using member_class_t = typename member_class<Member>::type;
  77234. /**
  77235. * @brief Extracts the n-th argument of a _callable_ type.
  77236. * @tparam Index The index of the argument to extract.
  77237. * @tparam Candidate A valid _callable_ type.
  77238. */
  77239. template<std::size_t Index, typename Candidate>
  77240. class nth_argument {
  77241. template<typename Ret, typename... Args>
  77242. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  77243. template<typename Ret, typename Class, typename... Args>
  77244. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  77245. template<typename Ret, typename Class, typename... Args>
  77246. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  77247. template<typename Type, typename Class>
  77248. static constexpr type_list<Type> pick_up(Type Class ::*);
  77249. template<typename Type>
  77250. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  77251. public:
  77252. /*! @brief N-th argument of the _callable_ type. */
  77253. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  77254. };
  77255. /**
  77256. * @brief Helper type.
  77257. * @tparam Index The index of the argument to extract.
  77258. * @tparam Candidate A valid function, member function or data member type.
  77259. */
  77260. template<std::size_t Index, typename Candidate>
  77261. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  77262. } // namespace entt
  77263. template<typename... Type>
  77264. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  77265. template<std::size_t Index, typename... Type>
  77266. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  77267. template<auto... Value>
  77268. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  77269. template<std::size_t Index, auto... Value>
  77270. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  77271. #endif
  77272. // #include "fwd.hpp"
  77273. #ifndef ENTT_CONTAINER_FWD_HPP
  77274. #define ENTT_CONTAINER_FWD_HPP
  77275. #include <functional>
  77276. #include <memory>
  77277. #include <utility>
  77278. #include <vector>
  77279. namespace entt {
  77280. template<
  77281. typename Key,
  77282. typename Type,
  77283. typename = std::hash<Key>,
  77284. typename = std::equal_to<>,
  77285. typename = std::allocator<std::pair<const Key, Type>>>
  77286. class dense_map;
  77287. template<
  77288. typename Type,
  77289. typename = std::hash<Type>,
  77290. typename = std::equal_to<>,
  77291. typename = std::allocator<Type>>
  77292. class dense_set;
  77293. template<typename...>
  77294. class basic_table;
  77295. /**
  77296. * @brief Alias declaration for the most common use case.
  77297. * @tparam Type Element types.
  77298. */
  77299. template<typename... Type>
  77300. using table = basic_table<std::vector<Type>...>;
  77301. } // namespace entt
  77302. #endif
  77303. namespace entt {
  77304. /*! @cond TURN_OFF_DOXYGEN */
  77305. namespace internal {
  77306. static constexpr std::size_t dense_map_placeholder_position = (std::numeric_limits<std::size_t>::max)();
  77307. template<typename Key, typename Type>
  77308. struct dense_map_node final {
  77309. using value_type = std::pair<Key, Type>;
  77310. template<typename... Args>
  77311. dense_map_node(const std::size_t pos, Args &&...args)
  77312. : next{pos},
  77313. element{std::forward<Args>(args)...} {}
  77314. template<typename Allocator, typename... Args>
  77315. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const std::size_t pos, Args &&...args)
  77316. : next{pos},
  77317. element{entt::make_obj_using_allocator<value_type>(allocator, std::forward<Args>(args)...)} {}
  77318. template<typename Allocator>
  77319. dense_map_node(std::allocator_arg_t, const Allocator &allocator, const dense_map_node &other)
  77320. : next{other.next},
  77321. element{entt::make_obj_using_allocator<value_type>(allocator, other.element)} {}
  77322. template<typename Allocator>
  77323. dense_map_node(std::allocator_arg_t, const Allocator &allocator, dense_map_node &&other)
  77324. : next{other.next},
  77325. element{entt::make_obj_using_allocator<value_type>(allocator, std::move(other.element))} {}
  77326. std::size_t next;
  77327. value_type element;
  77328. };
  77329. template<typename It>
  77330. class dense_map_iterator final {
  77331. template<typename>
  77332. friend class dense_map_iterator;
  77333. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  77334. using second_type = decltype((std::declval<It>()->element.second));
  77335. public:
  77336. using value_type = std::pair<first_type, second_type>;
  77337. using pointer = input_iterator_pointer<value_type>;
  77338. using reference = value_type;
  77339. using difference_type = std::ptrdiff_t;
  77340. using iterator_category = std::input_iterator_tag;
  77341. using iterator_concept = std::random_access_iterator_tag;
  77342. constexpr dense_map_iterator() noexcept
  77343. : it{} {}
  77344. constexpr dense_map_iterator(const It iter) noexcept
  77345. : it{iter} {}
  77346. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  77347. constexpr dense_map_iterator(const dense_map_iterator<Other> &other) noexcept
  77348. : it{other.it} {}
  77349. constexpr dense_map_iterator &operator++() noexcept {
  77350. return ++it, *this;
  77351. }
  77352. constexpr dense_map_iterator operator++(int) noexcept {
  77353. const dense_map_iterator orig = *this;
  77354. return ++(*this), orig;
  77355. }
  77356. constexpr dense_map_iterator &operator--() noexcept {
  77357. return --it, *this;
  77358. }
  77359. constexpr dense_map_iterator operator--(int) noexcept {
  77360. const dense_map_iterator orig = *this;
  77361. return operator--(), orig;
  77362. }
  77363. constexpr dense_map_iterator &operator+=(const difference_type value) noexcept {
  77364. it += value;
  77365. return *this;
  77366. }
  77367. constexpr dense_map_iterator operator+(const difference_type value) const noexcept {
  77368. dense_map_iterator copy = *this;
  77369. return (copy += value);
  77370. }
  77371. constexpr dense_map_iterator &operator-=(const difference_type value) noexcept {
  77372. return (*this += -value);
  77373. }
  77374. constexpr dense_map_iterator operator-(const difference_type value) const noexcept {
  77375. return (*this + -value);
  77376. }
  77377. [[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
  77378. return {it[value].element.first, it[value].element.second};
  77379. }
  77380. [[nodiscard]] constexpr pointer operator->() const noexcept {
  77381. return operator*();
  77382. }
  77383. [[nodiscard]] constexpr reference operator*() const noexcept {
  77384. return operator[](0);
  77385. }
  77386. template<typename Lhs, typename Rhs>
  77387. friend constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  77388. template<typename Lhs, typename Rhs>
  77389. friend constexpr bool operator==(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  77390. template<typename Lhs, typename Rhs>
  77391. friend constexpr bool operator<(const dense_map_iterator<Lhs> &, const dense_map_iterator<Rhs> &) noexcept;
  77392. private:
  77393. It it;
  77394. };
  77395. template<typename Lhs, typename Rhs>
  77396. [[nodiscard]] constexpr std::ptrdiff_t operator-(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  77397. return lhs.it - rhs.it;
  77398. }
  77399. template<typename Lhs, typename Rhs>
  77400. [[nodiscard]] constexpr bool operator==(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  77401. return lhs.it == rhs.it;
  77402. }
  77403. template<typename Lhs, typename Rhs>
  77404. [[nodiscard]] constexpr bool operator!=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  77405. return !(lhs == rhs);
  77406. }
  77407. template<typename Lhs, typename Rhs>
  77408. [[nodiscard]] constexpr bool operator<(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  77409. return lhs.it < rhs.it;
  77410. }
  77411. template<typename Lhs, typename Rhs>
  77412. [[nodiscard]] constexpr bool operator>(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  77413. return rhs < lhs;
  77414. }
  77415. template<typename Lhs, typename Rhs>
  77416. [[nodiscard]] constexpr bool operator<=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  77417. return !(lhs > rhs);
  77418. }
  77419. template<typename Lhs, typename Rhs>
  77420. [[nodiscard]] constexpr bool operator>=(const dense_map_iterator<Lhs> &lhs, const dense_map_iterator<Rhs> &rhs) noexcept {
  77421. return !(lhs < rhs);
  77422. }
  77423. template<typename It>
  77424. class dense_map_local_iterator final {
  77425. template<typename>
  77426. friend class dense_map_local_iterator;
  77427. using first_type = decltype(std::as_const(std::declval<It>()->element.first));
  77428. using second_type = decltype((std::declval<It>()->element.second));
  77429. public:
  77430. using value_type = std::pair<first_type, second_type>;
  77431. using pointer = input_iterator_pointer<value_type>;
  77432. using reference = value_type;
  77433. using difference_type = std::ptrdiff_t;
  77434. using iterator_category = std::input_iterator_tag;
  77435. using iterator_concept = std::forward_iterator_tag;
  77436. constexpr dense_map_local_iterator() noexcept = default;
  77437. constexpr dense_map_local_iterator(It iter, const std::size_t pos) noexcept
  77438. : it{iter},
  77439. offset{pos} {}
  77440. template<typename Other, typename = std::enable_if_t<!std::is_same_v<It, Other> && std::is_constructible_v<It, Other>>>
  77441. constexpr dense_map_local_iterator(const dense_map_local_iterator<Other> &other) noexcept
  77442. : it{other.it},
  77443. offset{other.offset} {}
  77444. constexpr dense_map_local_iterator &operator++() noexcept {
  77445. return (offset = it[static_cast<typename It::difference_type>(offset)].next), *this;
  77446. }
  77447. constexpr dense_map_local_iterator operator++(int) noexcept {
  77448. const dense_map_local_iterator orig = *this;
  77449. return ++(*this), orig;
  77450. }
  77451. [[nodiscard]] constexpr pointer operator->() const noexcept {
  77452. return operator*();
  77453. }
  77454. [[nodiscard]] constexpr reference operator*() const noexcept {
  77455. const auto idx = static_cast<typename It::difference_type>(offset);
  77456. return {it[idx].element.first, it[idx].element.second};
  77457. }
  77458. [[nodiscard]] constexpr std::size_t index() const noexcept {
  77459. return offset;
  77460. }
  77461. private:
  77462. It it{};
  77463. std::size_t offset{dense_map_placeholder_position};
  77464. };
  77465. template<typename Lhs, typename Rhs>
  77466. [[nodiscard]] constexpr bool operator==(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  77467. return lhs.index() == rhs.index();
  77468. }
  77469. template<typename Lhs, typename Rhs>
  77470. [[nodiscard]] constexpr bool operator!=(const dense_map_local_iterator<Lhs> &lhs, const dense_map_local_iterator<Rhs> &rhs) noexcept {
  77471. return !(lhs == rhs);
  77472. }
  77473. } // namespace internal
  77474. /*! @endcond */
  77475. /**
  77476. * @brief Associative container for key-value pairs with unique keys.
  77477. *
  77478. * Internally, elements are organized into buckets. Which bucket an element is
  77479. * placed into depends entirely on the hash of its key. Keys with the same hash
  77480. * code appear in the same bucket.
  77481. *
  77482. * @tparam Key Key type of the associative container.
  77483. * @tparam Type Mapped type of the associative container.
  77484. * @tparam Hash Type of function to use to hash the keys.
  77485. * @tparam KeyEqual Type of function to use to compare the keys for equality.
  77486. * @tparam Allocator Type of allocator used to manage memory and elements.
  77487. */
  77488. template<typename Key, typename Type, typename Hash, typename KeyEqual, typename Allocator>
  77489. class dense_map {
  77490. static constexpr float default_threshold = 0.875f;
  77491. static constexpr std::size_t minimum_capacity = 8u;
  77492. static constexpr std::size_t placeholder_position = internal::dense_map_placeholder_position;
  77493. using node_type = internal::dense_map_node<Key, Type>;
  77494. using alloc_traits = std::allocator_traits<Allocator>;
  77495. static_assert(std::is_same_v<typename alloc_traits::value_type, std::pair<const Key, Type>>, "Invalid value type");
  77496. using sparse_container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
  77497. using packed_container_type = std::vector<node_type, typename alloc_traits::template rebind_alloc<node_type>>;
  77498. template<typename Other>
  77499. [[nodiscard]] std::size_t key_to_bucket(const Other &key) const noexcept {
  77500. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  77501. return fast_mod(static_cast<size_type>(sparse.second()(key)), bucket_count());
  77502. }
  77503. template<typename Other>
  77504. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) {
  77505. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  77506. if(packed.second()(packed.first()[offset].element.first, key)) {
  77507. return begin() + static_cast<typename iterator::difference_type>(offset);
  77508. }
  77509. }
  77510. return end();
  77511. }
  77512. template<typename Other>
  77513. [[nodiscard]] auto constrained_find(const Other &key, const std::size_t bucket) const {
  77514. for(auto offset = sparse.first()[bucket]; offset != placeholder_position; offset = packed.first()[offset].next) {
  77515. if(packed.second()(packed.first()[offset].element.first, key)) {
  77516. return cbegin() + static_cast<typename const_iterator::difference_type>(offset);
  77517. }
  77518. }
  77519. return cend();
  77520. }
  77521. template<typename Other, typename... Args>
  77522. [[nodiscard]] auto insert_or_do_nothing(Other &&key, Args &&...args) {
  77523. const auto index = key_to_bucket(key);
  77524. if(auto it = constrained_find(key, index); it != end()) {
  77525. return std::make_pair(it, false);
  77526. }
  77527. packed.first().emplace_back(sparse.first()[index], std::piecewise_construct, std::forward_as_tuple(std::forward<Other>(key)), std::forward_as_tuple(std::forward<Args>(args)...));
  77528. sparse.first()[index] = packed.first().size() - 1u;
  77529. rehash_if_required();
  77530. return std::make_pair(--end(), true);
  77531. }
  77532. template<typename Other, typename Arg>
  77533. [[nodiscard]] auto insert_or_overwrite(Other &&key, Arg &&value) {
  77534. const auto index = key_to_bucket(key);
  77535. if(auto it = constrained_find(key, index); it != end()) {
  77536. it->second = std::forward<Arg>(value);
  77537. return std::make_pair(it, false);
  77538. }
  77539. packed.first().emplace_back(sparse.first()[index], std::forward<Other>(key), std::forward<Arg>(value));
  77540. sparse.first()[index] = packed.first().size() - 1u;
  77541. rehash_if_required();
  77542. return std::make_pair(--end(), true);
  77543. }
  77544. void move_and_pop(const std::size_t pos) {
  77545. if(const auto last = size() - 1u; pos != last) {
  77546. size_type *curr = &sparse.first()[key_to_bucket(packed.first().back().element.first)];
  77547. packed.first()[pos] = std::move(packed.first().back());
  77548. for(; *curr != last; curr = &packed.first()[*curr].next) {}
  77549. *curr = pos;
  77550. }
  77551. packed.first().pop_back();
  77552. }
  77553. void rehash_if_required() {
  77554. if(const auto bc = bucket_count(); size() > static_cast<size_type>(static_cast<float>(bc) * max_load_factor())) {
  77555. rehash(bc * 2u);
  77556. }
  77557. }
  77558. public:
  77559. /*! @brief Allocator type. */
  77560. using allocator_type = Allocator;
  77561. /*! @brief Key type of the container. */
  77562. using key_type = Key;
  77563. /*! @brief Mapped type of the container. */
  77564. using mapped_type = Type;
  77565. /*! @brief Key-value type of the container. */
  77566. using value_type = std::pair<const Key, Type>;
  77567. /*! @brief Unsigned integer type. */
  77568. using size_type = std::size_t;
  77569. /*! @brief Signed integer type. */
  77570. using difference_type = std::ptrdiff_t;
  77571. /*! @brief Type of function to use to hash the keys. */
  77572. using hasher = Hash;
  77573. /*! @brief Type of function to use to compare the keys for equality. */
  77574. using key_equal = KeyEqual;
  77575. /*! @brief Input iterator type. */
  77576. using iterator = internal::dense_map_iterator<typename packed_container_type::iterator>;
  77577. /*! @brief Constant input iterator type. */
  77578. using const_iterator = internal::dense_map_iterator<typename packed_container_type::const_iterator>;
  77579. /*! @brief Input iterator type. */
  77580. using local_iterator = internal::dense_map_local_iterator<typename packed_container_type::iterator>;
  77581. /*! @brief Constant input iterator type. */
  77582. using const_local_iterator = internal::dense_map_local_iterator<typename packed_container_type::const_iterator>;
  77583. /*! @brief Default constructor. */
  77584. dense_map()
  77585. : dense_map{minimum_capacity} {}
  77586. /**
  77587. * @brief Constructs an empty container with a given allocator.
  77588. * @param allocator The allocator to use.
  77589. */
  77590. explicit dense_map(const allocator_type &allocator)
  77591. : dense_map{minimum_capacity, hasher{}, key_equal{}, allocator} {}
  77592. /**
  77593. * @brief Constructs an empty container with a given allocator and user
  77594. * supplied minimal number of buckets.
  77595. * @param cnt Minimal number of buckets.
  77596. * @param allocator The allocator to use.
  77597. */
  77598. dense_map(const size_type cnt, const allocator_type &allocator)
  77599. : dense_map{cnt, hasher{}, key_equal{}, allocator} {}
  77600. /**
  77601. * @brief Constructs an empty container with a given allocator, hash
  77602. * function and user supplied minimal number of buckets.
  77603. * @param cnt Minimal number of buckets.
  77604. * @param hash Hash function to use.
  77605. * @param allocator The allocator to use.
  77606. */
  77607. dense_map(const size_type cnt, const hasher &hash, const allocator_type &allocator)
  77608. : dense_map{cnt, hash, key_equal{}, allocator} {}
  77609. /**
  77610. * @brief Constructs an empty container with a given allocator, hash
  77611. * function, compare function and user supplied minimal number of buckets.
  77612. * @param cnt Minimal number of buckets.
  77613. * @param hash Hash function to use.
  77614. * @param equal Compare function to use.
  77615. * @param allocator The allocator to use.
  77616. */
  77617. explicit dense_map(const size_type cnt, const hasher &hash = hasher{}, const key_equal &equal = key_equal{}, const allocator_type &allocator = allocator_type{})
  77618. : sparse{allocator, hash},
  77619. packed{allocator, equal} {
  77620. rehash(cnt);
  77621. }
  77622. /*! @brief Default copy constructor. */
  77623. dense_map(const dense_map &) = default;
  77624. /**
  77625. * @brief Allocator-extended copy constructor.
  77626. * @param other The instance to copy from.
  77627. * @param allocator The allocator to use.
  77628. */
  77629. dense_map(const dense_map &other, const allocator_type &allocator)
  77630. : sparse{std::piecewise_construct, std::forward_as_tuple(other.sparse.first(), allocator), std::forward_as_tuple(other.sparse.second())},
  77631. packed{std::piecewise_construct, std::forward_as_tuple(other.packed.first(), allocator), std::forward_as_tuple(other.packed.second())},
  77632. threshold{other.threshold} {}
  77633. /*! @brief Default move constructor. */
  77634. dense_map(dense_map &&) noexcept = default;
  77635. /**
  77636. * @brief Allocator-extended move constructor.
  77637. * @param other The instance to move from.
  77638. * @param allocator The allocator to use.
  77639. */
  77640. dense_map(dense_map &&other, const allocator_type &allocator)
  77641. : sparse{std::piecewise_construct, std::forward_as_tuple(std::move(other.sparse.first()), allocator), std::forward_as_tuple(std::move(other.sparse.second()))},
  77642. packed{std::piecewise_construct, std::forward_as_tuple(std::move(other.packed.first()), allocator), std::forward_as_tuple(std::move(other.packed.second()))},
  77643. threshold{other.threshold} {}
  77644. /*! @brief Default destructor. */
  77645. ~dense_map() = default;
  77646. /**
  77647. * @brief Default copy assignment operator.
  77648. * @return This container.
  77649. */
  77650. dense_map &operator=(const dense_map &) = default;
  77651. /**
  77652. * @brief Default move assignment operator.
  77653. * @return This container.
  77654. */
  77655. dense_map &operator=(dense_map &&) noexcept = default;
  77656. /**
  77657. * @brief Exchanges the contents with those of a given container.
  77658. * @param other Container to exchange the content with.
  77659. */
  77660. void swap(dense_map &other) noexcept {
  77661. using std::swap;
  77662. swap(sparse, other.sparse);
  77663. swap(packed, other.packed);
  77664. swap(threshold, other.threshold);
  77665. }
  77666. /**
  77667. * @brief Returns the associated allocator.
  77668. * @return The associated allocator.
  77669. */
  77670. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  77671. return sparse.first().get_allocator();
  77672. }
  77673. /**
  77674. * @brief Returns an iterator to the beginning.
  77675. *
  77676. * If the array is empty, the returned iterator will be equal to `end()`.
  77677. *
  77678. * @return An iterator to the first instance of the internal array.
  77679. */
  77680. [[nodiscard]] const_iterator cbegin() const noexcept {
  77681. return packed.first().begin();
  77682. }
  77683. /*! @copydoc cbegin */
  77684. [[nodiscard]] const_iterator begin() const noexcept {
  77685. return cbegin();
  77686. }
  77687. /*! @copydoc begin */
  77688. [[nodiscard]] iterator begin() noexcept {
  77689. return packed.first().begin();
  77690. }
  77691. /**
  77692. * @brief Returns an iterator to the end.
  77693. * @return An iterator to the element following the last instance of the
  77694. * internal array.
  77695. */
  77696. [[nodiscard]] const_iterator cend() const noexcept {
  77697. return packed.first().end();
  77698. }
  77699. /*! @copydoc cend */
  77700. [[nodiscard]] const_iterator end() const noexcept {
  77701. return cend();
  77702. }
  77703. /*! @copydoc end */
  77704. [[nodiscard]] iterator end() noexcept {
  77705. return packed.first().end();
  77706. }
  77707. /**
  77708. * @brief Checks whether a container is empty.
  77709. * @return True if the container is empty, false otherwise.
  77710. */
  77711. [[nodiscard]] bool empty() const noexcept {
  77712. return packed.first().empty();
  77713. }
  77714. /**
  77715. * @brief Returns the number of elements in a container.
  77716. * @return Number of elements in a container.
  77717. */
  77718. [[nodiscard]] size_type size() const noexcept {
  77719. return packed.first().size();
  77720. }
  77721. /**
  77722. * @brief Returns the maximum possible number of elements.
  77723. * @return Maximum possible number of elements.
  77724. */
  77725. [[nodiscard]] size_type max_size() const noexcept {
  77726. return packed.first().max_size();
  77727. }
  77728. /*! @brief Clears the container. */
  77729. void clear() noexcept {
  77730. sparse.first().clear();
  77731. packed.first().clear();
  77732. rehash(0u);
  77733. }
  77734. /**
  77735. * @brief Inserts an element into the container, if the key does not exist.
  77736. * @param value A key-value pair eventually convertible to the value type.
  77737. * @return A pair consisting of an iterator to the inserted element (or to
  77738. * the element that prevented the insertion) and a bool denoting whether the
  77739. * insertion took place.
  77740. */
  77741. std::pair<iterator, bool> insert(const value_type &value) {
  77742. return insert_or_do_nothing(value.first, value.second);
  77743. }
  77744. /*! @copydoc insert */
  77745. std::pair<iterator, bool> insert(value_type &&value) {
  77746. return insert_or_do_nothing(std::move(value.first), std::move(value.second));
  77747. }
  77748. /**
  77749. * @copydoc insert
  77750. * @tparam Arg Type of the key-value pair to insert into the container.
  77751. */
  77752. template<typename Arg>
  77753. std::enable_if_t<std::is_constructible_v<value_type, Arg &&>, std::pair<iterator, bool>>
  77754. insert(Arg &&value) {
  77755. return insert_or_do_nothing(std::forward<Arg>(value).first, std::forward<Arg>(value).second);
  77756. }
  77757. /**
  77758. * @brief Inserts elements into the container, if their keys do not exist.
  77759. * @tparam It Type of input iterator.
  77760. * @param first An iterator to the first element of the range of elements.
  77761. * @param last An iterator past the last element of the range of elements.
  77762. */
  77763. template<typename It>
  77764. void insert(It first, It last) {
  77765. for(; first != last; ++first) {
  77766. insert(*first);
  77767. }
  77768. }
  77769. /**
  77770. * @brief Inserts an element into the container or assigns to the current
  77771. * element if the key already exists.
  77772. * @tparam Arg Type of the value to insert or assign.
  77773. * @param key A key used both to look up and to insert if not found.
  77774. * @param value A value to insert or assign.
  77775. * @return A pair consisting of an iterator to the element and a bool
  77776. * denoting whether the insertion took place.
  77777. */
  77778. template<typename Arg>
  77779. std::pair<iterator, bool> insert_or_assign(const key_type &key, Arg &&value) {
  77780. return insert_or_overwrite(key, std::forward<Arg>(value));
  77781. }
  77782. /*! @copydoc insert_or_assign */
  77783. template<typename Arg>
  77784. std::pair<iterator, bool> insert_or_assign(key_type &&key, Arg &&value) {
  77785. return insert_or_overwrite(std::move(key), std::forward<Arg>(value));
  77786. }
  77787. /**
  77788. * @brief Constructs an element in-place, if the key does not exist.
  77789. *
  77790. * The element is also constructed when the container already has the key,
  77791. * in which case the newly constructed object is destroyed immediately.
  77792. *
  77793. * @tparam Args Types of arguments to forward to the constructor of the
  77794. * element.
  77795. * @param args Arguments to forward to the constructor of the element.
  77796. * @return A pair consisting of an iterator to the inserted element (or to
  77797. * the element that prevented the insertion) and a bool denoting whether the
  77798. * insertion took place.
  77799. */
  77800. template<typename... Args>
  77801. std::pair<iterator, bool> emplace([[maybe_unused]] Args &&...args) {
  77802. if constexpr(sizeof...(Args) == 0u) {
  77803. return insert_or_do_nothing(key_type{});
  77804. } else if constexpr(sizeof...(Args) == 1u) {
  77805. return insert_or_do_nothing(std::forward<Args>(args).first..., std::forward<Args>(args).second...);
  77806. } else if constexpr(sizeof...(Args) == 2u) {
  77807. return insert_or_do_nothing(std::forward<Args>(args)...);
  77808. } else {
  77809. auto &node = packed.first().emplace_back(packed.first().size(), std::forward<Args>(args)...);
  77810. const auto index = key_to_bucket(node.element.first);
  77811. if(auto it = constrained_find(node.element.first, index); it != end()) {
  77812. packed.first().pop_back();
  77813. return std::make_pair(it, false);
  77814. }
  77815. std::swap(node.next, sparse.first()[index]);
  77816. rehash_if_required();
  77817. return std::make_pair(--end(), true);
  77818. }
  77819. }
  77820. /**
  77821. * @brief Inserts in-place if the key does not exist, does nothing if the
  77822. * key exists.
  77823. * @tparam Args Types of arguments to forward to the constructor of the
  77824. * element.
  77825. * @param key A key used both to look up and to insert if not found.
  77826. * @param args Arguments to forward to the constructor of the element.
  77827. * @return A pair consisting of an iterator to the inserted element (or to
  77828. * the element that prevented the insertion) and a bool denoting whether the
  77829. * insertion took place.
  77830. */
  77831. template<typename... Args>
  77832. std::pair<iterator, bool> try_emplace(const key_type &key, Args &&...args) {
  77833. return insert_or_do_nothing(key, std::forward<Args>(args)...);
  77834. }
  77835. /*! @copydoc try_emplace */
  77836. template<typename... Args>
  77837. std::pair<iterator, bool> try_emplace(key_type &&key, Args &&...args) {
  77838. return insert_or_do_nothing(std::move(key), std::forward<Args>(args)...);
  77839. }
  77840. /**
  77841. * @brief Removes an element from a given position.
  77842. * @param pos An iterator to the element to remove.
  77843. * @return An iterator following the removed element.
  77844. */
  77845. iterator erase(const_iterator pos) {
  77846. const auto diff = pos - cbegin();
  77847. erase(pos->first);
  77848. return begin() + diff;
  77849. }
  77850. /**
  77851. * @brief Removes the given elements from a container.
  77852. * @param first An iterator to the first element of the range of elements.
  77853. * @param last An iterator past the last element of the range of elements.
  77854. * @return An iterator following the last removed element.
  77855. */
  77856. iterator erase(const_iterator first, const_iterator last) {
  77857. const auto dist = first - cbegin();
  77858. for(auto from = last - cbegin(); from != dist; --from) {
  77859. erase(packed.first()[static_cast<size_type>(from) - 1u].element.first);
  77860. }
  77861. return (begin() + dist);
  77862. }
  77863. /**
  77864. * @brief Removes the element associated with a given key.
  77865. * @param key A key value of an element to remove.
  77866. * @return Number of elements removed (either 0 or 1).
  77867. */
  77868. size_type erase(const key_type &key) {
  77869. for(size_type *curr = &sparse.first()[key_to_bucket(key)]; *curr != placeholder_position; curr = &packed.first()[*curr].next) {
  77870. if(packed.second()(packed.first()[*curr].element.first, key)) {
  77871. const auto index = *curr;
  77872. *curr = packed.first()[*curr].next;
  77873. move_and_pop(index);
  77874. return 1u;
  77875. }
  77876. }
  77877. return 0u;
  77878. }
  77879. /**
  77880. * @brief Accesses a given element with bounds checking.
  77881. * @param key A key of an element to find.
  77882. * @return A reference to the mapped value of the requested element.
  77883. */
  77884. [[nodiscard]] mapped_type &at(const key_type &key) {
  77885. auto it = find(key);
  77886. ENTT_ASSERT(it != end(), "Invalid key");
  77887. return it->second;
  77888. }
  77889. /*! @copydoc at */
  77890. [[nodiscard]] const mapped_type &at(const key_type &key) const {
  77891. auto it = find(key);
  77892. ENTT_ASSERT(it != cend(), "Invalid key");
  77893. return it->second;
  77894. }
  77895. /**
  77896. * @brief Accesses a given element with bounds checking.
  77897. * @tparam Other Type of the key of an element to find.
  77898. * @param key A key of an element to find.
  77899. * @return A reference to the mapped value of the requested element.
  77900. */
  77901. template<typename Other>
  77902. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type const &>>
  77903. at(const Other &key) const {
  77904. auto it = find(key);
  77905. ENTT_ASSERT(it != cend(), "Invalid key");
  77906. return it->second;
  77907. }
  77908. /*! @copydoc at */
  77909. template<typename Other>
  77910. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, mapped_type &>>
  77911. at(const Other &key) {
  77912. auto it = find(key);
  77913. ENTT_ASSERT(it != end(), "Invalid key");
  77914. return it->second;
  77915. }
  77916. /**
  77917. * @brief Accesses or inserts a given element.
  77918. * @param key A key of an element to find or insert.
  77919. * @return A reference to the mapped value of the requested element.
  77920. */
  77921. [[nodiscard]] mapped_type &operator[](const key_type &key) {
  77922. return insert_or_do_nothing(key).first->second;
  77923. }
  77924. /**
  77925. * @brief Accesses or inserts a given element.
  77926. * @param key A key of an element to find or insert.
  77927. * @return A reference to the mapped value of the requested element.
  77928. */
  77929. [[nodiscard]] mapped_type &operator[](key_type &&key) {
  77930. return insert_or_do_nothing(std::move(key)).first->second;
  77931. }
  77932. /**
  77933. * @brief Returns the number of elements matching a key (either 1 or 0).
  77934. * @param key Key value of an element to search for.
  77935. * @return Number of elements matching the key (either 1 or 0).
  77936. */
  77937. [[nodiscard]] size_type count(const key_type &key) const {
  77938. return find(key) != end();
  77939. }
  77940. /**
  77941. * @brief Returns the number of elements matching a key (either 1 or 0).
  77942. * @tparam Other Type of the key value of an element to search for.
  77943. * @param key Key value of an element to search for.
  77944. * @return Number of elements matching the key (either 1 or 0).
  77945. */
  77946. template<typename Other>
  77947. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, size_type>>
  77948. count(const Other &key) const {
  77949. return find(key) != end();
  77950. }
  77951. /**
  77952. * @brief Finds an element with a given key.
  77953. * @param key Key value of an element to search for.
  77954. * @return An iterator to an element with the given key. If no such element
  77955. * is found, a past-the-end iterator is returned.
  77956. */
  77957. [[nodiscard]] iterator find(const key_type &key) {
  77958. return constrained_find(key, key_to_bucket(key));
  77959. }
  77960. /*! @copydoc find */
  77961. [[nodiscard]] const_iterator find(const key_type &key) const {
  77962. return constrained_find(key, key_to_bucket(key));
  77963. }
  77964. /**
  77965. * @brief Finds an element with a key that compares _equivalent_ to a given
  77966. * key.
  77967. * @tparam Other Type of the key value of an element to search for.
  77968. * @param key Key value of an element to search for.
  77969. * @return An iterator to an element with the given key. If no such element
  77970. * is found, a past-the-end iterator is returned.
  77971. */
  77972. template<typename Other>
  77973. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, iterator>>
  77974. find(const Other &key) {
  77975. return constrained_find(key, key_to_bucket(key));
  77976. }
  77977. /*! @copydoc find */
  77978. template<typename Other>
  77979. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, const_iterator>>
  77980. find(const Other &key) const {
  77981. return constrained_find(key, key_to_bucket(key));
  77982. }
  77983. /**
  77984. * @brief Returns a range containing all elements with a given key.
  77985. * @param key Key value of an element to search for.
  77986. * @return A pair of iterators pointing to the first element and past the
  77987. * last element of the range.
  77988. */
  77989. [[nodiscard]] std::pair<iterator, iterator> equal_range(const key_type &key) {
  77990. const auto it = find(key);
  77991. return {it, it + !(it == end())};
  77992. }
  77993. /*! @copydoc equal_range */
  77994. [[nodiscard]] std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const {
  77995. const auto it = find(key);
  77996. return {it, it + !(it == cend())};
  77997. }
  77998. /**
  77999. * @brief Returns a range containing all elements that compare _equivalent_
  78000. * to a given key.
  78001. * @tparam Other Type of an element to search for.
  78002. * @param key Key value of an element to search for.
  78003. * @return A pair of iterators pointing to the first element and past the
  78004. * last element of the range.
  78005. */
  78006. template<typename Other>
  78007. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<iterator, iterator>>>
  78008. equal_range(const Other &key) {
  78009. const auto it = find(key);
  78010. return {it, it + !(it == end())};
  78011. }
  78012. /*! @copydoc equal_range */
  78013. template<typename Other>
  78014. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, std::pair<const_iterator, const_iterator>>>
  78015. equal_range(const Other &key) const {
  78016. const auto it = find(key);
  78017. return {it, it + !(it == cend())};
  78018. }
  78019. /**
  78020. * @brief Checks if the container contains an element with a given key.
  78021. * @param key Key value of an element to search for.
  78022. * @return True if there is such an element, false otherwise.
  78023. */
  78024. [[nodiscard]] bool contains(const key_type &key) const {
  78025. return (find(key) != cend());
  78026. }
  78027. /**
  78028. * @brief Checks if the container contains an element with a key that
  78029. * compares _equivalent_ to a given value.
  78030. * @tparam Other Type of the key value of an element to search for.
  78031. * @param key Key value of an element to search for.
  78032. * @return True if there is such an element, false otherwise.
  78033. */
  78034. template<typename Other>
  78035. [[nodiscard]] std::enable_if_t<is_transparent_v<hasher> && is_transparent_v<key_equal>, std::conditional_t<false, Other, bool>>
  78036. contains(const Other &key) const {
  78037. return (find(key) != cend());
  78038. }
  78039. /**
  78040. * @brief Returns an iterator to the beginning of a given bucket.
  78041. * @param index An index of a bucket to access.
  78042. * @return An iterator to the beginning of the given bucket.
  78043. */
  78044. [[nodiscard]] const_local_iterator cbegin(const size_type index) const {
  78045. return {packed.first().begin(), sparse.first()[index]};
  78046. }
  78047. /**
  78048. * @brief Returns an iterator to the beginning of a given bucket.
  78049. * @param index An index of a bucket to access.
  78050. * @return An iterator to the beginning of the given bucket.
  78051. */
  78052. [[nodiscard]] const_local_iterator begin(const size_type index) const {
  78053. return cbegin(index);
  78054. }
  78055. /**
  78056. * @brief Returns an iterator to the beginning of a given bucket.
  78057. * @param index An index of a bucket to access.
  78058. * @return An iterator to the beginning of the given bucket.
  78059. */
  78060. [[nodiscard]] local_iterator begin(const size_type index) {
  78061. return {packed.first().begin(), sparse.first()[index]};
  78062. }
  78063. /**
  78064. * @brief Returns an iterator to the end of a given bucket.
  78065. * @param index An index of a bucket to access.
  78066. * @return An iterator to the end of the given bucket.
  78067. */
  78068. [[nodiscard]] const_local_iterator cend([[maybe_unused]] const size_type index) const {
  78069. return {};
  78070. }
  78071. /**
  78072. * @brief Returns an iterator to the end of a given bucket.
  78073. * @param index An index of a bucket to access.
  78074. * @return An iterator to the end of the given bucket.
  78075. */
  78076. [[nodiscard]] const_local_iterator end(const size_type index) const {
  78077. return cend(index);
  78078. }
  78079. /**
  78080. * @brief Returns an iterator to the end of a given bucket.
  78081. * @param index An index of a bucket to access.
  78082. * @return An iterator to the end of the given bucket.
  78083. */
  78084. [[nodiscard]] local_iterator end([[maybe_unused]] const size_type index) {
  78085. return {};
  78086. }
  78087. /**
  78088. * @brief Returns the number of buckets.
  78089. * @return The number of buckets.
  78090. */
  78091. [[nodiscard]] size_type bucket_count() const {
  78092. return sparse.first().size();
  78093. }
  78094. /**
  78095. * @brief Returns the maximum number of buckets.
  78096. * @return The maximum number of buckets.
  78097. */
  78098. [[nodiscard]] size_type max_bucket_count() const {
  78099. return sparse.first().max_size();
  78100. }
  78101. /**
  78102. * @brief Returns the number of elements in a given bucket.
  78103. * @param index The index of the bucket to examine.
  78104. * @return The number of elements in the given bucket.
  78105. */
  78106. [[nodiscard]] size_type bucket_size(const size_type index) const {
  78107. return static_cast<size_type>(std::distance(begin(index), end(index)));
  78108. }
  78109. /**
  78110. * @brief Returns the bucket for a given key.
  78111. * @param key The value of the key to examine.
  78112. * @return The bucket for the given key.
  78113. */
  78114. [[nodiscard]] size_type bucket(const key_type &key) const {
  78115. return key_to_bucket(key);
  78116. }
  78117. /**
  78118. * @brief Returns the average number of elements per bucket.
  78119. * @return The average number of elements per bucket.
  78120. */
  78121. [[nodiscard]] float load_factor() const {
  78122. return static_cast<float>(size()) / static_cast<float>(bucket_count());
  78123. }
  78124. /**
  78125. * @brief Returns the maximum average number of elements per bucket.
  78126. * @return The maximum average number of elements per bucket.
  78127. */
  78128. [[nodiscard]] float max_load_factor() const {
  78129. return threshold;
  78130. }
  78131. /**
  78132. * @brief Sets the desired maximum average number of elements per bucket.
  78133. * @param value A desired maximum average number of elements per bucket.
  78134. */
  78135. void max_load_factor(const float value) {
  78136. ENTT_ASSERT(value > 0.f, "Invalid load factor");
  78137. threshold = value;
  78138. rehash(0u);
  78139. }
  78140. /**
  78141. * @brief Reserves at least the specified number of buckets and regenerates
  78142. * the hash table.
  78143. * @param cnt New number of buckets.
  78144. */
  78145. void rehash(const size_type cnt) {
  78146. auto value = cnt > minimum_capacity ? cnt : minimum_capacity;
  78147. const auto cap = static_cast<size_type>(static_cast<float>(size()) / max_load_factor());
  78148. value = value > cap ? value : cap;
  78149. if(const auto sz = next_power_of_two(value); sz != bucket_count()) {
  78150. sparse.first().resize(sz);
  78151. for(auto &&elem: sparse.first()) {
  78152. elem = placeholder_position;
  78153. }
  78154. for(size_type pos{}, last = size(); pos < last; ++pos) {
  78155. const auto index = key_to_bucket(packed.first()[pos].element.first);
  78156. packed.first()[pos].next = std::exchange(sparse.first()[index], pos);
  78157. }
  78158. }
  78159. }
  78160. /**
  78161. * @brief Reserves space for at least the specified number of elements and
  78162. * regenerates the hash table.
  78163. * @param cnt New number of elements.
  78164. */
  78165. void reserve(const size_type cnt) {
  78166. packed.first().reserve(cnt);
  78167. rehash(static_cast<size_type>(std::ceil(static_cast<float>(cnt) / max_load_factor())));
  78168. }
  78169. /**
  78170. * @brief Returns the function used to hash the keys.
  78171. * @return The function used to hash the keys.
  78172. */
  78173. [[nodiscard]] hasher hash_function() const {
  78174. return sparse.second();
  78175. }
  78176. /**
  78177. * @brief Returns the function used to compare keys for equality.
  78178. * @return The function used to compare keys for equality.
  78179. */
  78180. [[nodiscard]] key_equal key_eq() const {
  78181. return packed.second();
  78182. }
  78183. private:
  78184. compressed_pair<sparse_container_type, hasher> sparse;
  78185. compressed_pair<packed_container_type, key_equal> packed;
  78186. float threshold{default_threshold};
  78187. };
  78188. } // namespace entt
  78189. /*! @cond TURN_OFF_DOXYGEN */
  78190. namespace std {
  78191. template<typename Key, typename Value, typename Allocator>
  78192. struct uses_allocator<entt::internal::dense_map_node<Key, Value>, Allocator>
  78193. : std::true_type {};
  78194. } // namespace std
  78195. /*! @endcond */
  78196. #endif
  78197. // #include "../core/compressed_pair.hpp"
  78198. #ifndef ENTT_CORE_COMPRESSED_PAIR_HPP
  78199. #define ENTT_CORE_COMPRESSED_PAIR_HPP
  78200. #include <cstddef>
  78201. #include <tuple>
  78202. #include <type_traits>
  78203. #include <utility>
  78204. // #include "fwd.hpp"
  78205. // #include "type_traits.hpp"
  78206. #ifndef ENTT_CORE_TYPE_TRAITS_HPP
  78207. #define ENTT_CORE_TYPE_TRAITS_HPP
  78208. #include <cstddef>
  78209. #include <iterator>
  78210. #include <tuple>
  78211. #include <type_traits>
  78212. #include <utility>
  78213. // #include "../config/config.h"
  78214. // #include "fwd.hpp"
  78215. namespace entt {
  78216. /**
  78217. * @brief Utility class to disambiguate overloaded functions.
  78218. * @tparam N Number of choices available.
  78219. */
  78220. template<std::size_t N>
  78221. struct choice_t
  78222. // unfortunately, doxygen cannot parse such a construct
  78223. : /*! @cond TURN_OFF_DOXYGEN */ choice_t<N - 1> /*! @endcond */
  78224. {};
  78225. /*! @copybrief choice_t */
  78226. template<>
  78227. struct choice_t<0> {};
  78228. /**
  78229. * @brief Variable template for the choice trick.
  78230. * @tparam N Number of choices available.
  78231. */
  78232. template<std::size_t N>
  78233. inline constexpr choice_t<N> choice{};
  78234. /**
  78235. * @brief Identity type trait.
  78236. *
  78237. * Useful to establish non-deduced contexts in template argument deduction
  78238. * (waiting for C++20) or to provide types through function arguments.
  78239. *
  78240. * @tparam Type A type.
  78241. */
  78242. template<typename Type>
  78243. struct type_identity {
  78244. /*! @brief Identity type. */
  78245. using type = Type;
  78246. };
  78247. /**
  78248. * @brief Helper type.
  78249. * @tparam Type A type.
  78250. */
  78251. template<typename Type>
  78252. using type_identity_t = typename type_identity<Type>::type;
  78253. /**
  78254. * @brief A type-only `sizeof` wrapper that returns 0 where `sizeof` complains.
  78255. * @tparam Type The type of which to return the size.
  78256. */
  78257. template<typename Type, typename = void>
  78258. struct size_of: std::integral_constant<std::size_t, 0u> {};
  78259. /*! @copydoc size_of */
  78260. template<typename Type>
  78261. struct size_of<Type, std::void_t<decltype(sizeof(Type))>>
  78262. // NOLINTNEXTLINE(bugprone-sizeof-expression)
  78263. : std::integral_constant<std::size_t, sizeof(Type)> {};
  78264. /**
  78265. * @brief Helper variable template.
  78266. * @tparam Type The type of which to return the size.
  78267. */
  78268. template<typename Type>
  78269. inline constexpr std::size_t size_of_v = size_of<Type>::value;
  78270. /**
  78271. * @brief Using declaration to be used to _repeat_ the same type a number of
  78272. * times equal to the size of a given parameter pack.
  78273. * @tparam Type A type to repeat.
  78274. */
  78275. template<typename Type, typename>
  78276. using unpack_as_type = Type;
  78277. /**
  78278. * @brief Helper variable template to be used to _repeat_ the same value a
  78279. * number of times equal to the size of a given parameter pack.
  78280. * @tparam Value A value to repeat.
  78281. */
  78282. template<auto Value, typename>
  78283. inline constexpr auto unpack_as_value = Value;
  78284. /**
  78285. * @brief Wraps a static constant.
  78286. * @tparam Value A static constant.
  78287. */
  78288. template<auto Value>
  78289. using integral_constant = std::integral_constant<decltype(Value), Value>;
  78290. /**
  78291. * @brief Alias template to facilitate the creation of named values.
  78292. * @tparam Value A constant value at least convertible to `id_type`.
  78293. */
  78294. template<id_type Value>
  78295. using tag = integral_constant<Value>;
  78296. /**
  78297. * @brief A class to use to push around lists of types, nothing more.
  78298. * @tparam Type Types provided by the type list.
  78299. */
  78300. template<typename... Type>
  78301. struct type_list {
  78302. /*! @brief Type list type. */
  78303. using type = type_list;
  78304. /*! @brief Compile-time number of elements in the type list. */
  78305. static constexpr auto size = sizeof...(Type);
  78306. };
  78307. /*! @brief Primary template isn't defined on purpose. */
  78308. template<std::size_t, typename>
  78309. struct type_list_element;
  78310. /**
  78311. * @brief Provides compile-time indexed access to the types of a type list.
  78312. * @tparam Index Index of the type to return.
  78313. * @tparam First First type provided by the type list.
  78314. * @tparam Other Other types provided by the type list.
  78315. */
  78316. template<std::size_t Index, typename First, typename... Other>
  78317. struct type_list_element<Index, type_list<First, Other...>>
  78318. : type_list_element<Index - 1u, type_list<Other...>> {};
  78319. /**
  78320. * @brief Provides compile-time indexed access to the types of a type list.
  78321. * @tparam First First type provided by the type list.
  78322. * @tparam Other Other types provided by the type list.
  78323. */
  78324. template<typename First, typename... Other>
  78325. struct type_list_element<0u, type_list<First, Other...>> {
  78326. /*! @brief Searched type. */
  78327. using type = First;
  78328. };
  78329. /**
  78330. * @brief Helper type.
  78331. * @tparam Index Index of the type to return.
  78332. * @tparam List Type list to search into.
  78333. */
  78334. template<std::size_t Index, typename List>
  78335. using type_list_element_t = typename type_list_element<Index, List>::type;
  78336. /*! @brief Primary template isn't defined on purpose. */
  78337. template<typename, typename>
  78338. struct type_list_index;
  78339. /**
  78340. * @brief Provides compile-time type access to the types of a type list.
  78341. * @tparam Type Type to look for and for which to return the index.
  78342. * @tparam First First type provided by the type list.
  78343. * @tparam Other Other types provided by the type list.
  78344. */
  78345. template<typename Type, typename First, typename... Other>
  78346. struct type_list_index<Type, type_list<First, Other...>> {
  78347. /*! @brief Unsigned integer type. */
  78348. using value_type = std::size_t;
  78349. /*! @brief Compile-time position of the given type in the sublist. */
  78350. static constexpr value_type value = 1u + type_list_index<Type, type_list<Other...>>::value;
  78351. };
  78352. /**
  78353. * @brief Provides compile-time type access to the types of a type list.
  78354. * @tparam Type Type to look for and for which to return the index.
  78355. * @tparam Other Other types provided by the type list.
  78356. */
  78357. template<typename Type, typename... Other>
  78358. struct type_list_index<Type, type_list<Type, Other...>> {
  78359. static_assert(type_list_index<Type, type_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  78360. /*! @brief Unsigned integer type. */
  78361. using value_type = std::size_t;
  78362. /*! @brief Compile-time position of the given type in the sublist. */
  78363. static constexpr value_type value = 0u;
  78364. };
  78365. /**
  78366. * @brief Provides compile-time type access to the types of a type list.
  78367. * @tparam Type Type to look for and for which to return the index.
  78368. */
  78369. template<typename Type>
  78370. struct type_list_index<Type, type_list<>> {
  78371. /*! @brief Unsigned integer type. */
  78372. using value_type = std::size_t;
  78373. /*! @brief Compile-time position of the given type in the sublist. */
  78374. static constexpr value_type value = 0u;
  78375. };
  78376. /**
  78377. * @brief Helper variable template.
  78378. * @tparam List Type list.
  78379. * @tparam Type Type to look for and for which to return the index.
  78380. */
  78381. template<typename Type, typename List>
  78382. inline constexpr std::size_t type_list_index_v = type_list_index<Type, List>::value;
  78383. /**
  78384. * @brief Concatenates multiple type lists.
  78385. * @tparam Type Types provided by the first type list.
  78386. * @tparam Other Types provided by the second type list.
  78387. * @return A type list composed by the types of both the type lists.
  78388. */
  78389. template<typename... Type, typename... Other>
  78390. constexpr type_list<Type..., Other...> operator+(type_list<Type...>, type_list<Other...>) {
  78391. return {};
  78392. }
  78393. /*! @brief Primary template isn't defined on purpose. */
  78394. template<typename...>
  78395. struct type_list_cat;
  78396. /*! @brief Concatenates multiple type lists. */
  78397. template<>
  78398. struct type_list_cat<> {
  78399. /*! @brief A type list composed by the types of all the type lists. */
  78400. using type = type_list<>;
  78401. };
  78402. /**
  78403. * @brief Concatenates multiple type lists.
  78404. * @tparam Type Types provided by the first type list.
  78405. * @tparam Other Types provided by the second type list.
  78406. * @tparam List Other type lists, if any.
  78407. */
  78408. template<typename... Type, typename... Other, typename... List>
  78409. struct type_list_cat<type_list<Type...>, type_list<Other...>, List...> {
  78410. /*! @brief A type list composed by the types of all the type lists. */
  78411. using type = typename type_list_cat<type_list<Type..., Other...>, List...>::type;
  78412. };
  78413. /**
  78414. * @brief Concatenates multiple type lists.
  78415. * @tparam Type Types provided by the type list.
  78416. */
  78417. template<typename... Type>
  78418. struct type_list_cat<type_list<Type...>> {
  78419. /*! @brief A type list composed by the types of all the type lists. */
  78420. using type = type_list<Type...>;
  78421. };
  78422. /**
  78423. * @brief Helper type.
  78424. * @tparam List Type lists to concatenate.
  78425. */
  78426. template<typename... List>
  78427. using type_list_cat_t = typename type_list_cat<List...>::type;
  78428. /*! @cond TURN_OFF_DOXYGEN */
  78429. namespace internal {
  78430. template<typename...>
  78431. struct type_list_unique;
  78432. template<typename First, typename... Other, typename... Type>
  78433. struct type_list_unique<type_list<First, Other...>, Type...>
  78434. : std::conditional_t<(std::is_same_v<First, Type> || ...), type_list_unique<type_list<Other...>, Type...>, type_list_unique<type_list<Other...>, Type..., First>> {};
  78435. template<typename... Type>
  78436. struct type_list_unique<type_list<>, Type...> {
  78437. using type = type_list<Type...>;
  78438. };
  78439. } // namespace internal
  78440. /*! @endcond */
  78441. /**
  78442. * @brief Removes duplicates types from a type list.
  78443. * @tparam List Type list.
  78444. */
  78445. template<typename List>
  78446. struct type_list_unique {
  78447. /*! @brief A type list without duplicate types. */
  78448. using type = typename internal::type_list_unique<List>::type;
  78449. };
  78450. /**
  78451. * @brief Helper type.
  78452. * @tparam List Type list.
  78453. */
  78454. template<typename List>
  78455. using type_list_unique_t = typename type_list_unique<List>::type;
  78456. /**
  78457. * @brief Provides the member constant `value` to true if a type list contains a
  78458. * given type, false otherwise.
  78459. * @tparam List Type list.
  78460. * @tparam Type Type to look for.
  78461. */
  78462. template<typename List, typename Type>
  78463. struct type_list_contains;
  78464. /**
  78465. * @copybrief type_list_contains
  78466. * @tparam Type Types provided by the type list.
  78467. * @tparam Other Type to look for.
  78468. */
  78469. template<typename... Type, typename Other>
  78470. struct type_list_contains<type_list<Type...>, Other>
  78471. : std::bool_constant<(std::is_same_v<Type, Other> || ...)> {};
  78472. /**
  78473. * @brief Helper variable template.
  78474. * @tparam List Type list.
  78475. * @tparam Type Type to look for.
  78476. */
  78477. template<typename List, typename Type>
  78478. inline constexpr bool type_list_contains_v = type_list_contains<List, Type>::value;
  78479. /*! @brief Primary template isn't defined on purpose. */
  78480. template<typename...>
  78481. struct type_list_diff;
  78482. /**
  78483. * @brief Computes the difference between two type lists.
  78484. * @tparam Type Types provided by the first type list.
  78485. * @tparam Other Types provided by the second type list.
  78486. */
  78487. template<typename... Type, typename... Other>
  78488. struct type_list_diff<type_list<Type...>, type_list<Other...>> {
  78489. /*! @brief A type list that is the difference between the two type lists. */
  78490. using type = type_list_cat_t<std::conditional_t<type_list_contains_v<type_list<Other...>, Type>, type_list<>, type_list<Type>>...>;
  78491. };
  78492. /**
  78493. * @brief Helper type.
  78494. * @tparam List Type lists between which to compute the difference.
  78495. */
  78496. template<typename... List>
  78497. using type_list_diff_t = typename type_list_diff<List...>::type;
  78498. /*! @brief Primary template isn't defined on purpose. */
  78499. template<typename, template<typename...> class>
  78500. struct type_list_transform;
  78501. /**
  78502. * @brief Applies a given _function_ to a type list and generate a new list.
  78503. * @tparam Type Types provided by the type list.
  78504. * @tparam Op Unary operation as template class with a type member named `type`.
  78505. */
  78506. template<typename... Type, template<typename...> class Op>
  78507. struct type_list_transform<type_list<Type...>, Op> {
  78508. /*! @brief Resulting type list after applying the transform function. */
  78509. // NOLINTNEXTLINE(modernize-type-traits)
  78510. using type = type_list<typename Op<Type>::type...>;
  78511. };
  78512. /**
  78513. * @brief Helper type.
  78514. * @tparam List Type list.
  78515. * @tparam Op Unary operation as template class with a type member named `type`.
  78516. */
  78517. template<typename List, template<typename...> class Op>
  78518. using type_list_transform_t = typename type_list_transform<List, Op>::type;
  78519. /**
  78520. * @brief A class to use to push around lists of constant values, nothing more.
  78521. * @tparam Value Values provided by the value list.
  78522. */
  78523. template<auto... Value>
  78524. struct value_list {
  78525. /*! @brief Value list type. */
  78526. using type = value_list;
  78527. /*! @brief Compile-time number of elements in the value list. */
  78528. static constexpr auto size = sizeof...(Value);
  78529. };
  78530. /*! @brief Primary template isn't defined on purpose. */
  78531. template<std::size_t, typename>
  78532. struct value_list_element;
  78533. /**
  78534. * @brief Provides compile-time indexed access to the values of a value list.
  78535. * @tparam Index Index of the value to return.
  78536. * @tparam Value First value provided by the value list.
  78537. * @tparam Other Other values provided by the value list.
  78538. */
  78539. template<std::size_t Index, auto Value, auto... Other>
  78540. struct value_list_element<Index, value_list<Value, Other...>>
  78541. : value_list_element<Index - 1u, value_list<Other...>> {};
  78542. /**
  78543. * @brief Provides compile-time indexed access to the types of a type list.
  78544. * @tparam Value First value provided by the value list.
  78545. * @tparam Other Other values provided by the value list.
  78546. */
  78547. template<auto Value, auto... Other>
  78548. struct value_list_element<0u, value_list<Value, Other...>> {
  78549. /*! @brief Searched type. */
  78550. using type = decltype(Value);
  78551. /*! @brief Searched value. */
  78552. static constexpr auto value = Value;
  78553. };
  78554. /**
  78555. * @brief Helper type.
  78556. * @tparam Index Index of the type to return.
  78557. * @tparam List Value list to search into.
  78558. */
  78559. template<std::size_t Index, typename List>
  78560. using value_list_element_t = typename value_list_element<Index, List>::type;
  78561. /**
  78562. * @brief Helper type.
  78563. * @tparam Index Index of the value to return.
  78564. * @tparam List Value list to search into.
  78565. */
  78566. template<std::size_t Index, typename List>
  78567. inline constexpr auto value_list_element_v = value_list_element<Index, List>::value;
  78568. /*! @brief Primary template isn't defined on purpose. */
  78569. template<auto, typename>
  78570. struct value_list_index;
  78571. /**
  78572. * @brief Provides compile-time type access to the values of a value list.
  78573. * @tparam Value Value to look for and for which to return the index.
  78574. * @tparam First First value provided by the value list.
  78575. * @tparam Other Other values provided by the value list.
  78576. */
  78577. template<auto Value, auto First, auto... Other>
  78578. struct value_list_index<Value, value_list<First, Other...>> {
  78579. /*! @brief Unsigned integer type. */
  78580. using value_type = std::size_t;
  78581. /*! @brief Compile-time position of the given value in the sublist. */
  78582. static constexpr value_type value = 1u + value_list_index<Value, value_list<Other...>>::value;
  78583. };
  78584. /**
  78585. * @brief Provides compile-time type access to the values of a value list.
  78586. * @tparam Value Value to look for and for which to return the index.
  78587. * @tparam Other Other values provided by the value list.
  78588. */
  78589. template<auto Value, auto... Other>
  78590. struct value_list_index<Value, value_list<Value, Other...>> {
  78591. static_assert(value_list_index<Value, value_list<Other...>>::value == sizeof...(Other), "Non-unique type");
  78592. /*! @brief Unsigned integer type. */
  78593. using value_type = std::size_t;
  78594. /*! @brief Compile-time position of the given value in the sublist. */
  78595. static constexpr value_type value = 0u;
  78596. };
  78597. /**
  78598. * @brief Provides compile-time type access to the values of a value list.
  78599. * @tparam Value Value to look for and for which to return the index.
  78600. */
  78601. template<auto Value>
  78602. struct value_list_index<Value, value_list<>> {
  78603. /*! @brief Unsigned integer type. */
  78604. using value_type = std::size_t;
  78605. /*! @brief Compile-time position of the given type in the sublist. */
  78606. static constexpr value_type value = 0u;
  78607. };
  78608. /**
  78609. * @brief Helper variable template.
  78610. * @tparam List Value list.
  78611. * @tparam Value Value to look for and for which to return the index.
  78612. */
  78613. template<auto Value, typename List>
  78614. inline constexpr std::size_t value_list_index_v = value_list_index<Value, List>::value;
  78615. /**
  78616. * @brief Concatenates multiple value lists.
  78617. * @tparam Value Values provided by the first value list.
  78618. * @tparam Other Values provided by the second value list.
  78619. * @return A value list composed by the values of both the value lists.
  78620. */
  78621. template<auto... Value, auto... Other>
  78622. constexpr value_list<Value..., Other...> operator+(value_list<Value...>, value_list<Other...>) {
  78623. return {};
  78624. }
  78625. /*! @brief Primary template isn't defined on purpose. */
  78626. template<typename...>
  78627. struct value_list_cat;
  78628. /*! @brief Concatenates multiple value lists. */
  78629. template<>
  78630. struct value_list_cat<> {
  78631. /*! @brief A value list composed by the values of all the value lists. */
  78632. using type = value_list<>;
  78633. };
  78634. /**
  78635. * @brief Concatenates multiple value lists.
  78636. * @tparam Value Values provided by the first value list.
  78637. * @tparam Other Values provided by the second value list.
  78638. * @tparam List Other value lists, if any.
  78639. */
  78640. template<auto... Value, auto... Other, typename... List>
  78641. struct value_list_cat<value_list<Value...>, value_list<Other...>, List...> {
  78642. /*! @brief A value list composed by the values of all the value lists. */
  78643. using type = typename value_list_cat<value_list<Value..., Other...>, List...>::type;
  78644. };
  78645. /**
  78646. * @brief Concatenates multiple value lists.
  78647. * @tparam Value Values provided by the value list.
  78648. */
  78649. template<auto... Value>
  78650. struct value_list_cat<value_list<Value...>> {
  78651. /*! @brief A value list composed by the values of all the value lists. */
  78652. using type = value_list<Value...>;
  78653. };
  78654. /**
  78655. * @brief Helper type.
  78656. * @tparam List Value lists to concatenate.
  78657. */
  78658. template<typename... List>
  78659. using value_list_cat_t = typename value_list_cat<List...>::type;
  78660. /*! @brief Primary template isn't defined on purpose. */
  78661. template<typename>
  78662. struct value_list_unique;
  78663. /**
  78664. * @brief Removes duplicates values from a value list.
  78665. * @tparam Value One of the values provided by the given value list.
  78666. * @tparam Other The other values provided by the given value list.
  78667. */
  78668. template<auto Value, auto... Other>
  78669. struct value_list_unique<value_list<Value, Other...>> {
  78670. /*! @brief A value list without duplicate types. */
  78671. using type = std::conditional_t<
  78672. ((Value == Other) || ...),
  78673. typename value_list_unique<value_list<Other...>>::type,
  78674. value_list_cat_t<value_list<Value>, typename value_list_unique<value_list<Other...>>::type>>;
  78675. };
  78676. /*! @brief Removes duplicates values from a value list. */
  78677. template<>
  78678. struct value_list_unique<value_list<>> {
  78679. /*! @brief A value list without duplicate types. */
  78680. using type = value_list<>;
  78681. };
  78682. /**
  78683. * @brief Helper type.
  78684. * @tparam Type A value list.
  78685. */
  78686. template<typename Type>
  78687. using value_list_unique_t = typename value_list_unique<Type>::type;
  78688. /**
  78689. * @brief Provides the member constant `value` to true if a value list contains
  78690. * a given value, false otherwise.
  78691. * @tparam List Value list.
  78692. * @tparam Value Value to look for.
  78693. */
  78694. template<typename List, auto Value>
  78695. struct value_list_contains;
  78696. /**
  78697. * @copybrief value_list_contains
  78698. * @tparam Value Values provided by the value list.
  78699. * @tparam Other Value to look for.
  78700. */
  78701. template<auto... Value, auto Other>
  78702. struct value_list_contains<value_list<Value...>, Other>
  78703. : std::bool_constant<((Value == Other) || ...)> {};
  78704. /**
  78705. * @brief Helper variable template.
  78706. * @tparam List Value list.
  78707. * @tparam Value Value to look for.
  78708. */
  78709. template<typename List, auto Value>
  78710. inline constexpr bool value_list_contains_v = value_list_contains<List, Value>::value;
  78711. /*! @brief Primary template isn't defined on purpose. */
  78712. template<typename...>
  78713. struct value_list_diff;
  78714. /**
  78715. * @brief Computes the difference between two value lists.
  78716. * @tparam Value Values provided by the first value list.
  78717. * @tparam Other Values provided by the second value list.
  78718. */
  78719. template<auto... Value, auto... Other>
  78720. struct value_list_diff<value_list<Value...>, value_list<Other...>> {
  78721. /*! @brief A value list that is the difference between the two value lists. */
  78722. using type = value_list_cat_t<std::conditional_t<value_list_contains_v<value_list<Other...>, Value>, value_list<>, value_list<Value>>...>;
  78723. };
  78724. /**
  78725. * @brief Helper type.
  78726. * @tparam List Value lists between which to compute the difference.
  78727. */
  78728. template<typename... List>
  78729. using value_list_diff_t = typename value_list_diff<List...>::type;
  78730. /*! @brief Same as std::is_invocable, but with tuples. */
  78731. template<typename, typename>
  78732. struct is_applicable: std::false_type {};
  78733. /**
  78734. * @copybrief is_applicable
  78735. * @tparam Func A valid function type.
  78736. * @tparam Tuple Tuple-like type.
  78737. * @tparam Args The list of arguments to use to probe the function type.
  78738. */
  78739. template<typename Func, template<typename...> class Tuple, typename... Args>
  78740. struct is_applicable<Func, Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  78741. /**
  78742. * @copybrief is_applicable
  78743. * @tparam Func A valid function type.
  78744. * @tparam Tuple Tuple-like type.
  78745. * @tparam Args The list of arguments to use to probe the function type.
  78746. */
  78747. template<typename Func, template<typename...> class Tuple, typename... Args>
  78748. struct is_applicable<Func, const Tuple<Args...>>: std::is_invocable<Func, Args...> {};
  78749. /**
  78750. * @brief Helper variable template.
  78751. * @tparam Func A valid function type.
  78752. * @tparam Args The list of arguments to use to probe the function type.
  78753. */
  78754. template<typename Func, typename Args>
  78755. inline constexpr bool is_applicable_v = is_applicable<Func, Args>::value;
  78756. /*! @brief Same as std::is_invocable_r, but with tuples for arguments. */
  78757. template<typename, typename, typename>
  78758. struct is_applicable_r: std::false_type {};
  78759. /**
  78760. * @copybrief is_applicable_r
  78761. * @tparam Ret The type to which the return type of the function should be
  78762. * convertible.
  78763. * @tparam Func A valid function type.
  78764. * @tparam Args The list of arguments to use to probe the function type.
  78765. */
  78766. template<typename Ret, typename Func, typename... Args>
  78767. struct is_applicable_r<Ret, Func, std::tuple<Args...>>: std::is_invocable_r<Ret, Func, Args...> {};
  78768. /**
  78769. * @brief Helper variable template.
  78770. * @tparam Ret The type to which the return type of the function should be
  78771. * convertible.
  78772. * @tparam Func A valid function type.
  78773. * @tparam Args The list of arguments to use to probe the function type.
  78774. */
  78775. template<typename Ret, typename Func, typename Args>
  78776. inline constexpr bool is_applicable_r_v = is_applicable_r<Ret, Func, Args>::value;
  78777. /**
  78778. * @brief Provides the member constant `value` to true if a given type is
  78779. * complete, false otherwise.
  78780. * @tparam Type The type to test.
  78781. */
  78782. template<typename Type, typename = void>
  78783. struct is_complete: std::false_type {};
  78784. /*! @copydoc is_complete */
  78785. template<typename Type>
  78786. struct is_complete<Type, std::void_t<decltype(sizeof(Type))>>: std::true_type {};
  78787. /**
  78788. * @brief Helper variable template.
  78789. * @tparam Type The type to test.
  78790. */
  78791. template<typename Type>
  78792. inline constexpr bool is_complete_v = is_complete<Type>::value;
  78793. /**
  78794. * @brief Provides the member constant `value` to true if a given type is an
  78795. * iterator, false otherwise.
  78796. * @tparam Type The type to test.
  78797. */
  78798. template<typename Type, typename = void>
  78799. struct is_iterator: std::false_type {};
  78800. /*! @cond TURN_OFF_DOXYGEN */
  78801. namespace internal {
  78802. template<typename, typename = void>
  78803. struct has_iterator_category: std::false_type {};
  78804. template<typename Type>
  78805. struct has_iterator_category<Type, std::void_t<typename std::iterator_traits<Type>::iterator_category>>: std::true_type {};
  78806. } // namespace internal
  78807. /*! @endcond */
  78808. /*! @copydoc is_iterator */
  78809. template<typename Type>
  78810. struct is_iterator<Type, std::enable_if_t<!std::is_void_v<std::remove_const_t<std::remove_pointer_t<Type>>>>>
  78811. : internal::has_iterator_category<Type> {};
  78812. /**
  78813. * @brief Helper variable template.
  78814. * @tparam Type The type to test.
  78815. */
  78816. template<typename Type>
  78817. inline constexpr bool is_iterator_v = is_iterator<Type>::value;
  78818. /**
  78819. * @brief Provides the member constant `value` to true if a given type is both
  78820. * an empty and non-final class, false otherwise.
  78821. * @tparam Type The type to test
  78822. */
  78823. template<typename Type>
  78824. struct is_ebco_eligible
  78825. : std::bool_constant<std::is_empty_v<Type> && !std::is_final_v<Type>> {};
  78826. /**
  78827. * @brief Helper variable template.
  78828. * @tparam Type The type to test.
  78829. */
  78830. template<typename Type>
  78831. inline constexpr bool is_ebco_eligible_v = is_ebco_eligible<Type>::value;
  78832. /**
  78833. * @brief Provides the member constant `value` to true if `Type::is_transparent`
  78834. * is valid and denotes a type, false otherwise.
  78835. * @tparam Type The type to test.
  78836. */
  78837. template<typename Type, typename = void>
  78838. struct is_transparent: std::false_type {};
  78839. /*! @copydoc is_transparent */
  78840. template<typename Type>
  78841. struct is_transparent<Type, std::void_t<typename Type::is_transparent>>: std::true_type {};
  78842. /**
  78843. * @brief Helper variable template.
  78844. * @tparam Type The type to test.
  78845. */
  78846. template<typename Type>
  78847. inline constexpr bool is_transparent_v = is_transparent<Type>::value;
  78848. /*! @cond TURN_OFF_DOXYGEN */
  78849. namespace internal {
  78850. template<typename, typename = void>
  78851. struct has_tuple_size_value: std::false_type {};
  78852. template<typename Type>
  78853. struct has_tuple_size_value<Type, std::void_t<decltype(std::tuple_size<const Type>::value)>>: std::true_type {};
  78854. template<typename, typename = void>
  78855. struct has_value_type: std::false_type {};
  78856. template<typename Type>
  78857. struct has_value_type<Type, std::void_t<typename Type::value_type>>: std::true_type {};
  78858. template<typename>
  78859. [[nodiscard]] constexpr bool dispatch_is_equality_comparable();
  78860. template<typename Type, std::size_t... Index>
  78861. [[nodiscard]] constexpr bool unpack_maybe_equality_comparable(std::index_sequence<Index...>) {
  78862. return (dispatch_is_equality_comparable<std::tuple_element_t<Index, Type>>() && ...);
  78863. }
  78864. template<typename>
  78865. [[nodiscard]] constexpr bool maybe_equality_comparable(char) {
  78866. return false;
  78867. }
  78868. template<typename Type>
  78869. [[nodiscard]] constexpr auto maybe_equality_comparable(int) -> decltype(std::declval<Type>() == std::declval<Type>()) {
  78870. return true;
  78871. }
  78872. template<typename Type>
  78873. [[nodiscard]] constexpr bool dispatch_is_equality_comparable() {
  78874. // NOLINTBEGIN(modernize-use-transparent-functors)
  78875. if constexpr(std::is_array_v<Type>) {
  78876. return false;
  78877. } else if constexpr(is_complete_v<std::tuple_size<std::remove_const_t<Type>>>) {
  78878. if constexpr(has_tuple_size_value<Type>::value) {
  78879. return maybe_equality_comparable<Type>(0) && unpack_maybe_equality_comparable<Type>(std::make_index_sequence<std::tuple_size<Type>::value>{});
  78880. } else {
  78881. return maybe_equality_comparable<Type>(0);
  78882. }
  78883. } else if constexpr(has_value_type<Type>::value) {
  78884. if constexpr(is_iterator_v<Type> || std::is_same_v<typename Type::value_type, Type> || dispatch_is_equality_comparable<typename Type::value_type>()) {
  78885. return maybe_equality_comparable<Type>(0);
  78886. } else {
  78887. return false;
  78888. }
  78889. } else {
  78890. return maybe_equality_comparable<Type>(0);
  78891. }
  78892. // NOLINTEND(modernize-use-transparent-functors)
  78893. }
  78894. } // namespace internal
  78895. /*! @endcond */
  78896. /**
  78897. * @brief Provides the member constant `value` to true if a given type is
  78898. * equality comparable, false otherwise.
  78899. * @tparam Type The type to test.
  78900. */
  78901. template<typename Type>
  78902. struct is_equality_comparable: std::bool_constant<internal::dispatch_is_equality_comparable<Type>()> {};
  78903. /*! @copydoc is_equality_comparable */
  78904. template<typename Type>
  78905. struct is_equality_comparable<const Type>: is_equality_comparable<Type> {};
  78906. /**
  78907. * @brief Helper variable template.
  78908. * @tparam Type The type to test.
  78909. */
  78910. template<typename Type>
  78911. inline constexpr bool is_equality_comparable_v = is_equality_comparable<Type>::value;
  78912. /**
  78913. * @brief Transcribes the constness of a type to another type.
  78914. * @tparam To The type to which to transcribe the constness.
  78915. * @tparam From The type from which to transcribe the constness.
  78916. */
  78917. template<typename To, typename From>
  78918. struct constness_as {
  78919. /*! @brief The type resulting from the transcription of the constness. */
  78920. using type = std::remove_const_t<To>;
  78921. };
  78922. /*! @copydoc constness_as */
  78923. template<typename To, typename From>
  78924. struct constness_as<To, const From> {
  78925. /*! @brief The type resulting from the transcription of the constness. */
  78926. using type = const To;
  78927. };
  78928. /**
  78929. * @brief Alias template to facilitate the transcription of the constness.
  78930. * @tparam To The type to which to transcribe the constness.
  78931. * @tparam From The type from which to transcribe the constness.
  78932. */
  78933. template<typename To, typename From>
  78934. using constness_as_t = typename constness_as<To, From>::type;
  78935. /**
  78936. * @brief Extracts the class of a non-static member object or function.
  78937. * @tparam Member A pointer to a non-static member object or function.
  78938. */
  78939. template<typename Member>
  78940. class member_class {
  78941. static_assert(std::is_member_pointer_v<Member>, "Invalid pointer type to non-static member object or function");
  78942. template<typename Class, typename Ret, typename... Args>
  78943. static Class *clazz(Ret (Class::*)(Args...));
  78944. template<typename Class, typename Ret, typename... Args>
  78945. static Class *clazz(Ret (Class::*)(Args...) const);
  78946. template<typename Class, typename Type>
  78947. static Class *clazz(Type Class::*);
  78948. public:
  78949. /*! @brief The class of the given non-static member object or function. */
  78950. using type = std::remove_pointer_t<decltype(clazz(std::declval<Member>()))>;
  78951. };
  78952. /**
  78953. * @brief Helper type.
  78954. * @tparam Member A pointer to a non-static member object or function.
  78955. */
  78956. template<typename Member>
  78957. using member_class_t = typename member_class<Member>::type;
  78958. /**
  78959. * @brief Extracts the n-th argument of a _callable_ type.
  78960. * @tparam Index The index of the argument to extract.
  78961. * @tparam Candidate A valid _callable_ type.
  78962. */
  78963. template<std::size_t Index, typename Candidate>
  78964. class nth_argument {
  78965. template<typename Ret, typename... Args>
  78966. static constexpr type_list<Args...> pick_up(Ret (*)(Args...));
  78967. template<typename Ret, typename Class, typename... Args>
  78968. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...));
  78969. template<typename Ret, typename Class, typename... Args>
  78970. static constexpr type_list<Args...> pick_up(Ret (Class ::*)(Args...) const);
  78971. template<typename Type, typename Class>
  78972. static constexpr type_list<Type> pick_up(Type Class ::*);
  78973. template<typename Type>
  78974. static constexpr decltype(pick_up(&Type::operator())) pick_up(Type &&);
  78975. public:
  78976. /*! @brief N-th argument of the _callable_ type. */
  78977. using type = type_list_element_t<Index, decltype(pick_up(std::declval<Candidate>()))>;
  78978. };
  78979. /**
  78980. * @brief Helper type.
  78981. * @tparam Index The index of the argument to extract.
  78982. * @tparam Candidate A valid function, member function or data member type.
  78983. */
  78984. template<std::size_t Index, typename Candidate>
  78985. using nth_argument_t = typename nth_argument<Index, Candidate>::type;
  78986. } // namespace entt
  78987. template<typename... Type>
  78988. struct std::tuple_size<entt::type_list<Type...>>: std::integral_constant<std::size_t, entt::type_list<Type...>::size> {};
  78989. template<std::size_t Index, typename... Type>
  78990. struct std::tuple_element<Index, entt::type_list<Type...>>: entt::type_list_element<Index, entt::type_list<Type...>> {};
  78991. template<auto... Value>
  78992. struct std::tuple_size<entt::value_list<Value...>>: std::integral_constant<std::size_t, entt::value_list<Value...>::size> {};
  78993. template<std::size_t Index, auto... Value>
  78994. struct std::tuple_element<Index, entt::value_list<Value...>>: entt::value_list_element<Index, entt::value_list<Value...>> {};
  78995. #endif
  78996. namespace entt {
  78997. /*! @cond TURN_OFF_DOXYGEN */
  78998. namespace internal {
  78999. template<typename Type, std::size_t, typename = void>
  79000. struct compressed_pair_element {
  79001. using reference = Type &;
  79002. using const_reference = const Type &;
  79003. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  79004. // NOLINTNEXTLINE(modernize-use-equals-default)
  79005. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<Type>) {}
  79006. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  79007. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<Type, Arg>)
  79008. : value{std::forward<Arg>(arg)} {}
  79009. template<typename... Args, std::size_t... Index>
  79010. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<Type, Args...>)
  79011. : value{std::forward<Args>(std::get<Index>(args))...} {}
  79012. [[nodiscard]] constexpr reference get() noexcept {
  79013. return value;
  79014. }
  79015. [[nodiscard]] constexpr const_reference get() const noexcept {
  79016. return value;
  79017. }
  79018. private:
  79019. Type value{};
  79020. };
  79021. template<typename Type, std::size_t Tag>
  79022. struct compressed_pair_element<Type, Tag, std::enable_if_t<is_ebco_eligible_v<Type>>>: Type {
  79023. using reference = Type &;
  79024. using const_reference = const Type &;
  79025. using base_type = Type;
  79026. template<typename Dummy = Type, typename = std::enable_if_t<std::is_default_constructible_v<Dummy>>>
  79027. constexpr compressed_pair_element() noexcept(std::is_nothrow_default_constructible_v<base_type>)
  79028. : base_type{} {}
  79029. template<typename Arg, typename = std::enable_if_t<!std::is_same_v<std::remove_const_t<std::remove_reference_t<Arg>>, compressed_pair_element>>>
  79030. constexpr compressed_pair_element(Arg &&arg) noexcept(std::is_nothrow_constructible_v<base_type, Arg>)
  79031. : base_type{std::forward<Arg>(arg)} {}
  79032. template<typename... Args, std::size_t... Index>
  79033. constexpr compressed_pair_element(std::tuple<Args...> args, std::index_sequence<Index...>) noexcept(std::is_nothrow_constructible_v<base_type, Args...>)
  79034. : base_type{std::forward<Args>(std::get<Index>(args))...} {}
  79035. [[nodiscard]] constexpr reference get() noexcept {
  79036. return *this;
  79037. }
  79038. [[nodiscard]] constexpr const_reference get() const noexcept {
  79039. return *this;
  79040. }
  79041. };
  79042. } // namespace internal
  79043. /*! @endcond */
  79044. /**
  79045. * @brief A compressed pair.
  79046. *
  79047. * A pair that exploits the _Empty Base Class Optimization_ (or _EBCO_) to
  79048. * reduce its final size to a minimum.
  79049. *
  79050. * @tparam First The type of the first element that the pair stores.
  79051. * @tparam Second The type of the second element that the pair stores.
  79052. */
  79053. template<typename First, typename Second>
  79054. class compressed_pair final
  79055. : internal::compressed_pair_element<First, 0u>,
  79056. internal::compressed_pair_element<Second, 1u> {
  79057. using first_base = internal::compressed_pair_element<First, 0u>;
  79058. using second_base = internal::compressed_pair_element<Second, 1u>;
  79059. public:
  79060. /*! @brief The type of the first element that the pair stores. */
  79061. using first_type = First;
  79062. /*! @brief The type of the second element that the pair stores. */
  79063. using second_type = Second;
  79064. /**
  79065. * @brief Default constructor, conditionally enabled.
  79066. *
  79067. * This constructor is only available when the types that the pair stores
  79068. * are both at least default constructible.
  79069. *
  79070. * @tparam Dummy Dummy template parameter used for internal purposes.
  79071. */
  79072. template<bool Dummy = true, typename = std::enable_if_t<Dummy && std::is_default_constructible_v<first_type> && std::is_default_constructible_v<second_type>>>
  79073. constexpr compressed_pair() noexcept(std::is_nothrow_default_constructible_v<first_base> && std::is_nothrow_default_constructible_v<second_base>)
  79074. : first_base{},
  79075. second_base{} {}
  79076. /**
  79077. * @brief Copy constructor.
  79078. * @param other The instance to copy from.
  79079. */
  79080. constexpr compressed_pair(const compressed_pair &other) = default;
  79081. /**
  79082. * @brief Move constructor.
  79083. * @param other The instance to move from.
  79084. */
  79085. constexpr compressed_pair(compressed_pair &&other) noexcept = default;
  79086. /**
  79087. * @brief Constructs a pair from its values.
  79088. * @tparam Arg Type of value to use to initialize the first element.
  79089. * @tparam Other Type of value to use to initialize the second element.
  79090. * @param arg Value to use to initialize the first element.
  79091. * @param other Value to use to initialize the second element.
  79092. */
  79093. template<typename Arg, typename Other>
  79094. constexpr compressed_pair(Arg &&arg, Other &&other) noexcept(std::is_nothrow_constructible_v<first_base, Arg> && std::is_nothrow_constructible_v<second_base, Other>)
  79095. : first_base{std::forward<Arg>(arg)},
  79096. second_base{std::forward<Other>(other)} {}
  79097. /**
  79098. * @brief Constructs a pair by forwarding the arguments to its parts.
  79099. * @tparam Args Types of arguments to use to initialize the first element.
  79100. * @tparam Other Types of arguments to use to initialize the second element.
  79101. * @param args Arguments to use to initialize the first element.
  79102. * @param other Arguments to use to initialize the second element.
  79103. */
  79104. template<typename... Args, typename... Other>
  79105. constexpr compressed_pair(std::piecewise_construct_t, std::tuple<Args...> args, std::tuple<Other...> other) noexcept(std::is_nothrow_constructible_v<first_base, Args...> && std::is_nothrow_constructible_v<second_base, Other...>)
  79106. : first_base{std::move(args), std::index_sequence_for<Args...>{}},
  79107. second_base{std::move(other), std::index_sequence_for<Other...>{}} {}
  79108. /*! @brief Default destructor. */
  79109. ~compressed_pair() = default;
  79110. /**
  79111. * @brief Copy assignment operator.
  79112. * @param other The instance to copy from.
  79113. * @return This compressed pair object.
  79114. */
  79115. constexpr compressed_pair &operator=(const compressed_pair &other) = default;
  79116. /**
  79117. * @brief Move assignment operator.
  79118. * @param other The instance to move from.
  79119. * @return This compressed pair object.
  79120. */
  79121. constexpr compressed_pair &operator=(compressed_pair &&other) noexcept = default;
  79122. /**
  79123. * @brief Returns the first element that a pair stores.
  79124. * @return The first element that a pair stores.
  79125. */
  79126. [[nodiscard]] constexpr first_type &first() noexcept {
  79127. return static_cast<first_base &>(*this).get();
  79128. }
  79129. /*! @copydoc first */
  79130. [[nodiscard]] constexpr const first_type &first() const noexcept {
  79131. return static_cast<const first_base &>(*this).get();
  79132. }
  79133. /**
  79134. * @brief Returns the second element that a pair stores.
  79135. * @return The second element that a pair stores.
  79136. */
  79137. [[nodiscard]] constexpr second_type &second() noexcept {
  79138. return static_cast<second_base &>(*this).get();
  79139. }
  79140. /*! @copydoc second */
  79141. [[nodiscard]] constexpr const second_type &second() const noexcept {
  79142. return static_cast<const second_base &>(*this).get();
  79143. }
  79144. /**
  79145. * @brief Swaps two compressed pair objects.
  79146. * @param other The compressed pair to swap with.
  79147. */
  79148. constexpr void swap(compressed_pair &other) noexcept {
  79149. using std::swap;
  79150. swap(first(), other.first());
  79151. swap(second(), other.second());
  79152. }
  79153. /**
  79154. * @brief Extracts an element from the compressed pair.
  79155. * @tparam Index An integer value that is either 0 or 1.
  79156. * @return Returns a reference to the first element if `Index` is 0 and a
  79157. * reference to the second element if `Index` is 1.
  79158. */
  79159. template<std::size_t Index>
  79160. [[nodiscard]] constexpr decltype(auto) get() noexcept {
  79161. if constexpr(Index == 0u) {
  79162. return first();
  79163. } else {
  79164. static_assert(Index == 1u, "Index out of bounds");
  79165. return second();
  79166. }
  79167. }
  79168. /*! @copydoc get */
  79169. template<std::size_t Index>
  79170. [[nodiscard]] constexpr decltype(auto) get() const noexcept {
  79171. if constexpr(Index == 0u) {
  79172. return first();
  79173. } else {
  79174. static_assert(Index == 1u, "Index out of bounds");
  79175. return second();
  79176. }
  79177. }
  79178. };
  79179. /**
  79180. * @brief Deduction guide.
  79181. * @tparam Type Type of value to use to initialize the first element.
  79182. * @tparam Other Type of value to use to initialize the second element.
  79183. */
  79184. template<typename Type, typename Other>
  79185. compressed_pair(Type &&, Other &&) -> compressed_pair<std::decay_t<Type>, std::decay_t<Other>>;
  79186. /**
  79187. * @brief Swaps two compressed pair objects.
  79188. * @tparam First The type of the first element that the pairs store.
  79189. * @tparam Second The type of the second element that the pairs store.
  79190. * @param lhs A valid compressed pair object.
  79191. * @param rhs A valid compressed pair object.
  79192. */
  79193. template<typename First, typename Second>
  79194. constexpr void swap(compressed_pair<First, Second> &lhs, compressed_pair<First, Second> &rhs) noexcept {
  79195. lhs.swap(rhs);
  79196. }
  79197. } // namespace entt
  79198. namespace std {
  79199. /**
  79200. * @brief `std::tuple_size` specialization for `compressed_pair`s.
  79201. * @tparam First The type of the first element that the pair stores.
  79202. * @tparam Second The type of the second element that the pair stores.
  79203. */
  79204. template<typename First, typename Second>
  79205. struct tuple_size<entt::compressed_pair<First, Second>>: integral_constant<size_t, 2u> {};
  79206. /**
  79207. * @brief `std::tuple_element` specialization for `compressed_pair`s.
  79208. * @tparam Index The index of the type to return.
  79209. * @tparam First The type of the first element that the pair stores.
  79210. * @tparam Second The type of the second element that the pair stores.
  79211. */
  79212. template<size_t Index, typename First, typename Second>
  79213. struct tuple_element<Index, entt::compressed_pair<First, Second>>: conditional<Index == 0u, First, Second> {
  79214. static_assert(Index < 2u, "Index out of bounds");
  79215. };
  79216. } // namespace std
  79217. #endif
  79218. // #include "../core/fwd.hpp"
  79219. #ifndef ENTT_CORE_FWD_HPP
  79220. #define ENTT_CORE_FWD_HPP
  79221. #include <cstddef>
  79222. #include <cstdint>
  79223. // #include "../config/config.h"
  79224. namespace entt {
  79225. /*! @brief Possible modes of an any object. */
  79226. enum class any_policy : std::uint8_t {
  79227. /*! @brief Default mode, no element available. */
  79228. empty,
  79229. /*! @brief Owning mode, dynamically allocated element. */
  79230. dynamic,
  79231. /*! @brief Owning mode, embedded element. */
  79232. embedded,
  79233. /*! @brief Aliasing mode, non-const reference. */
  79234. ref,
  79235. /*! @brief Const aliasing mode, const reference. */
  79236. cref
  79237. };
  79238. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  79239. template<std::size_t Len = sizeof(double[2]), std::size_t = alignof(double[2])>
  79240. class basic_any;
  79241. /*! @brief Alias declaration for type identifiers. */
  79242. using id_type = ENTT_ID_TYPE;
  79243. /*! @brief Alias declaration for the most common use case. */
  79244. using any = basic_any<>;
  79245. template<typename, typename>
  79246. class compressed_pair;
  79247. template<typename>
  79248. class basic_hashed_string;
  79249. /*! @brief Aliases for common character types. */
  79250. using hashed_string = basic_hashed_string<char>;
  79251. /*! @brief Aliases for common character types. */
  79252. using hashed_wstring = basic_hashed_string<wchar_t>;
  79253. // NOLINTNEXTLINE(bugprone-forward-declaration-namespace)
  79254. struct type_info;
  79255. } // namespace entt
  79256. #endif
  79257. // #include "../core/type_info.hpp"
  79258. #ifndef ENTT_CORE_TYPE_INFO_HPP
  79259. #define ENTT_CORE_TYPE_INFO_HPP
  79260. #include <string_view>
  79261. #include <type_traits>
  79262. #include <utility>
  79263. // #include "../config/config.h"
  79264. // #include "fwd.hpp"
  79265. // #include "hashed_string.hpp"
  79266. #ifndef ENTT_CORE_HASHED_STRING_HPP
  79267. #define ENTT_CORE_HASHED_STRING_HPP
  79268. #include <cstddef>
  79269. #include <cstdint>
  79270. // #include "fwd.hpp"
  79271. namespace entt {
  79272. /*! @cond TURN_OFF_DOXYGEN */
  79273. namespace internal {
  79274. template<typename = id_type>
  79275. struct fnv_1a_params;
  79276. template<>
  79277. struct fnv_1a_params<std::uint32_t> {
  79278. static constexpr auto offset = 2166136261;
  79279. static constexpr auto prime = 16777619;
  79280. };
  79281. template<>
  79282. struct fnv_1a_params<std::uint64_t> {
  79283. static constexpr auto offset = 14695981039346656037ull;
  79284. static constexpr auto prime = 1099511628211ull;
  79285. };
  79286. template<typename Char>
  79287. struct basic_hashed_string {
  79288. using value_type = Char;
  79289. using size_type = std::size_t;
  79290. using hash_type = id_type;
  79291. const value_type *repr{};
  79292. hash_type hash{fnv_1a_params<>::offset};
  79293. size_type length{};
  79294. };
  79295. } // namespace internal
  79296. /*! @endcond */
  79297. /**
  79298. * @brief Zero overhead unique identifier.
  79299. *
  79300. * A hashed string is a compile-time tool that allows users to use
  79301. * human-readable identifiers in the codebase while using their numeric
  79302. * counterparts at runtime.<br/>
  79303. * Because of that, a hashed string can also be used in constant expressions if
  79304. * required.
  79305. *
  79306. * @warning
  79307. * This class doesn't take ownership of user-supplied strings nor does it make a
  79308. * copy of them.
  79309. *
  79310. * @tparam Char Character type.
  79311. */
  79312. template<typename Char>
  79313. class basic_hashed_string: internal::basic_hashed_string<Char> {
  79314. using base_type = internal::basic_hashed_string<Char>;
  79315. using params = internal::fnv_1a_params<>;
  79316. struct const_wrapper {
  79317. // non-explicit constructor on purpose
  79318. constexpr const_wrapper(const typename base_type::value_type *str) noexcept
  79319. : repr{str} {}
  79320. const typename base_type::value_type *repr;
  79321. };
  79322. public:
  79323. /*! @brief Character type. */
  79324. using value_type = typename base_type::value_type;
  79325. /*! @brief Unsigned integer type. */
  79326. using size_type = typename base_type::size_type;
  79327. /*! @brief Unsigned integer type. */
  79328. using hash_type = typename base_type::hash_type;
  79329. /**
  79330. * @brief Returns directly the numeric representation of a string view.
  79331. * @param str Human-readable identifier.
  79332. * @param len Length of the string to hash.
  79333. * @return The numeric representation of the string.
  79334. */
  79335. [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
  79336. return basic_hashed_string{str, len};
  79337. }
  79338. /**
  79339. * @brief Returns directly the numeric representation of a string.
  79340. * @tparam N Number of characters of the identifier.
  79341. * @param str Human-readable identifier.
  79342. * @return The numeric representation of the string.
  79343. */
  79344. template<std::size_t N>
  79345. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  79346. [[nodiscard]] static ENTT_CONSTEVAL hash_type value(const value_type (&str)[N]) noexcept {
  79347. return basic_hashed_string{str};
  79348. }
  79349. /**
  79350. * @brief Returns directly the numeric representation of a string.
  79351. * @param wrapper Helps achieving the purpose by relying on overloading.
  79352. * @return The numeric representation of the string.
  79353. */
  79354. [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
  79355. return basic_hashed_string{wrapper};
  79356. }
  79357. /*! @brief Constructs an empty hashed string. */
  79358. constexpr basic_hashed_string() noexcept
  79359. : basic_hashed_string{nullptr, 0u} {}
  79360. /**
  79361. * @brief Constructs a hashed string from a string view.
  79362. * @param str Human-readable identifier.
  79363. * @param len Length of the string to hash.
  79364. */
  79365. constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
  79366. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  79367. : base_type{str} {
  79368. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  79369. for(; base_type::length < len; ++base_type::length) {
  79370. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  79371. }
  79372. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  79373. }
  79374. /**
  79375. * @brief Constructs a hashed string from an array of const characters.
  79376. * @tparam N Number of characters of the identifier.
  79377. * @param str Human-readable identifier.
  79378. */
  79379. template<std::size_t N>
  79380. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  79381. ENTT_CONSTEVAL basic_hashed_string(const value_type (&str)[N]) noexcept
  79382. // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
  79383. : base_type{str} {
  79384. for(; str[base_type::length]; ++base_type::length) {
  79385. base_type::hash = (base_type::hash ^ static_cast<id_type>(str[base_type::length])) * params::prime;
  79386. }
  79387. }
  79388. /**
  79389. * @brief Explicit constructor on purpose to avoid constructing a hashed
  79390. * string directly from a `const value_type *`.
  79391. *
  79392. * @warning
  79393. * The lifetime of the string is not extended nor is it copied.
  79394. *
  79395. * @param wrapper Helps achieving the purpose by relying on overloading.
  79396. */
  79397. explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
  79398. : base_type{wrapper.repr} {
  79399. // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  79400. for(; wrapper.repr[base_type::length]; ++base_type::length) {
  79401. base_type::hash = (base_type::hash ^ static_cast<id_type>(wrapper.repr[base_type::length])) * params::prime;
  79402. }
  79403. // NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  79404. }
  79405. /**
  79406. * @brief Returns the size of a hashed string.
  79407. * @return The size of the hashed string.
  79408. */
  79409. [[nodiscard]] constexpr size_type size() const noexcept {
  79410. return base_type::length;
  79411. }
  79412. /**
  79413. * @brief Returns the human-readable representation of a hashed string.
  79414. * @return The string used to initialize the hashed string.
  79415. */
  79416. [[nodiscard]] constexpr const value_type *data() const noexcept {
  79417. return base_type::repr;
  79418. }
  79419. /**
  79420. * @brief Returns the numeric representation of a hashed string.
  79421. * @return The numeric representation of the hashed string.
  79422. */
  79423. [[nodiscard]] constexpr hash_type value() const noexcept {
  79424. return base_type::hash;
  79425. }
  79426. /*! @copydoc data */
  79427. [[nodiscard]] explicit constexpr operator const value_type *() const noexcept {
  79428. return data();
  79429. }
  79430. /**
  79431. * @brief Returns the numeric representation of a hashed string.
  79432. * @return The numeric representation of the hashed string.
  79433. */
  79434. [[nodiscard]] constexpr operator hash_type() const noexcept {
  79435. return value();
  79436. }
  79437. };
  79438. /**
  79439. * @brief Deduction guide.
  79440. * @tparam Char Character type.
  79441. * @param str Human-readable identifier.
  79442. * @param len Length of the string to hash.
  79443. */
  79444. template<typename Char>
  79445. basic_hashed_string(const Char *str, std::size_t len) -> basic_hashed_string<Char>;
  79446. /**
  79447. * @brief Deduction guide.
  79448. * @tparam Char Character type.
  79449. * @tparam N Number of characters of the identifier.
  79450. * @param str Human-readable identifier.
  79451. */
  79452. template<typename Char, std::size_t N>
  79453. // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays, modernize-avoid-c-arrays)
  79454. basic_hashed_string(const Char (&str)[N]) -> basic_hashed_string<Char>;
  79455. /**
  79456. * @brief Compares two hashed strings.
  79457. * @tparam Char Character type.
  79458. * @param lhs A valid hashed string.
  79459. * @param rhs A valid hashed string.
  79460. * @return True if the two hashed strings are identical, false otherwise.
  79461. */
  79462. template<typename Char>
  79463. [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  79464. return lhs.value() == rhs.value();
  79465. }
  79466. /**
  79467. * @brief Compares two hashed strings.
  79468. * @tparam Char Character type.
  79469. * @param lhs A valid hashed string.
  79470. * @param rhs A valid hashed string.
  79471. * @return True if the two hashed strings differ, false otherwise.
  79472. */
  79473. template<typename Char>
  79474. [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  79475. return !(lhs == rhs);
  79476. }
  79477. /**
  79478. * @brief Compares two hashed strings.
  79479. * @tparam Char Character type.
  79480. * @param lhs A valid hashed string.
  79481. * @param rhs A valid hashed string.
  79482. * @return True if the first element is less than the second, false otherwise.
  79483. */
  79484. template<typename Char>
  79485. [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  79486. return lhs.value() < rhs.value();
  79487. }
  79488. /**
  79489. * @brief Compares two hashed strings.
  79490. * @tparam Char Character type.
  79491. * @param lhs A valid hashed string.
  79492. * @param rhs A valid hashed string.
  79493. * @return True if the first element is less than or equal to the second, false
  79494. * otherwise.
  79495. */
  79496. template<typename Char>
  79497. [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  79498. return !(rhs < lhs);
  79499. }
  79500. /**
  79501. * @brief Compares two hashed strings.
  79502. * @tparam Char Character type.
  79503. * @param lhs A valid hashed string.
  79504. * @param rhs A valid hashed string.
  79505. * @return True if the first element is greater than the second, false
  79506. * otherwise.
  79507. */
  79508. template<typename Char>
  79509. [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  79510. return rhs < lhs;
  79511. }
  79512. /**
  79513. * @brief Compares two hashed strings.
  79514. * @tparam Char Character type.
  79515. * @param lhs A valid hashed string.
  79516. * @param rhs A valid hashed string.
  79517. * @return True if the first element is greater than or equal to the second,
  79518. * false otherwise.
  79519. */
  79520. template<typename Char>
  79521. [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
  79522. return !(lhs < rhs);
  79523. }
  79524. inline namespace literals {
  79525. /**
  79526. * @brief User defined literal for hashed strings.
  79527. * @param str The literal without its suffix.
  79528. * @return A properly initialized hashed string.
  79529. */
  79530. [[nodiscard]] ENTT_CONSTEVAL hashed_string operator""_hs(const char *str, std::size_t) noexcept {
  79531. return hashed_string{str};
  79532. }
  79533. /**
  79534. * @brief User defined literal for hashed wstrings.
  79535. * @param str The literal without its suffix.
  79536. * @return A properly initialized hashed wstring.
  79537. */
  79538. [[nodiscard]] ENTT_CONSTEVAL hashed_wstring operator""_hws(const wchar_t *str, std::size_t) noexcept {
  79539. return hashed_wstring{str};
  79540. }
  79541. } // namespace literals
  79542. } // namespace entt
  79543. #endif
  79544. namespace entt {
  79545. /*! @cond TURN_OFF_DOXYGEN */
  79546. namespace internal {
  79547. struct ENTT_API type_index final {
  79548. [[nodiscard]] static id_type next() noexcept {
  79549. static ENTT_MAYBE_ATOMIC(id_type) value{};
  79550. return value++;
  79551. }
  79552. };
  79553. template<typename Type>
  79554. [[nodiscard]] constexpr const char *pretty_function() noexcept {
  79555. #if defined ENTT_PRETTY_FUNCTION
  79556. return static_cast<const char *>(ENTT_PRETTY_FUNCTION);
  79557. #else
  79558. return "";
  79559. #endif
  79560. }
  79561. template<typename Type>
  79562. [[nodiscard]] constexpr auto stripped_type_name() noexcept {
  79563. #if defined ENTT_PRETTY_FUNCTION
  79564. const std::string_view full_name{pretty_function<Type>()};
  79565. auto first = full_name.find_first_not_of(' ', full_name.find_first_of(ENTT_PRETTY_FUNCTION_PREFIX) + 1);
  79566. auto value = full_name.substr(first, full_name.find_last_of(ENTT_PRETTY_FUNCTION_SUFFIX) - first);
  79567. return value;
  79568. #else
  79569. return std::string_view{};
  79570. #endif
  79571. }
  79572. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  79573. [[nodiscard]] constexpr std::string_view type_name(int) noexcept {
  79574. constexpr auto value = stripped_type_name<Type>();
  79575. return value;
  79576. }
  79577. template<typename Type>
  79578. [[nodiscard]] std::string_view type_name(char) noexcept {
  79579. static const auto value = stripped_type_name<Type>();
  79580. return value;
  79581. }
  79582. template<typename Type, auto = stripped_type_name<Type>().find_first_of('.')>
  79583. [[nodiscard]] constexpr id_type type_hash(int) noexcept {
  79584. constexpr auto stripped = stripped_type_name<Type>();
  79585. constexpr auto value = hashed_string::value(stripped.data(), stripped.size());
  79586. return value;
  79587. }
  79588. template<typename Type>
  79589. [[nodiscard]] id_type type_hash(char) noexcept {
  79590. static const auto value = [](const auto stripped) {
  79591. return hashed_string::value(stripped.data(), stripped.size());
  79592. }(stripped_type_name<Type>());
  79593. return value;
  79594. }
  79595. } // namespace internal
  79596. /*! @endcond */
  79597. /**
  79598. * @brief Type sequential identifier.
  79599. * @tparam Type Type for which to generate a sequential identifier.
  79600. */
  79601. template<typename Type, typename = void>
  79602. struct ENTT_API type_index final {
  79603. /**
  79604. * @brief Returns the sequential identifier of a given type.
  79605. * @return The sequential identifier of a given type.
  79606. */
  79607. [[nodiscard]] static id_type value() noexcept {
  79608. static const id_type value = internal::type_index::next();
  79609. return value;
  79610. }
  79611. /*! @copydoc value */
  79612. [[nodiscard]] constexpr operator id_type() const noexcept {
  79613. return value();
  79614. }
  79615. };
  79616. /**
  79617. * @brief Type hash.
  79618. * @tparam Type Type for which to generate a hash value.
  79619. */
  79620. template<typename Type, typename = void>
  79621. struct type_hash final {
  79622. /**
  79623. * @brief Returns the numeric representation of a given type.
  79624. * @return The numeric representation of the given type.
  79625. */
  79626. #if defined ENTT_PRETTY_FUNCTION
  79627. [[nodiscard]] static constexpr id_type value() noexcept {
  79628. return internal::type_hash<Type>(0);
  79629. #else
  79630. [[nodiscard]] static constexpr id_type value() noexcept {
  79631. return type_index<Type>::value();
  79632. #endif
  79633. }
  79634. /*! @copydoc value */
  79635. [[nodiscard]] constexpr operator id_type() const noexcept {
  79636. return value();
  79637. }
  79638. };
  79639. /**
  79640. * @brief Type name.
  79641. * @tparam Type Type for which to generate a name.
  79642. */
  79643. template<typename Type, typename = void>
  79644. struct type_name final {
  79645. /**
  79646. * @brief Returns the name of a given type.
  79647. * @return The name of the given type.
  79648. */
  79649. [[nodiscard]] static constexpr std::string_view value() noexcept {
  79650. return internal::type_name<Type>(0);
  79651. }
  79652. /*! @copydoc value */
  79653. [[nodiscard]] constexpr operator std::string_view() const noexcept {
  79654. return value();
  79655. }
  79656. };
  79657. /*! @brief Implementation specific information about a type. */
  79658. struct type_info final {
  79659. /**
  79660. * @brief Constructs a type info object for a given type.
  79661. * @tparam Type Type for which to construct a type info object.
  79662. */
  79663. template<typename Type>
  79664. // NOLINTBEGIN(modernize-use-transparent-functors)
  79665. constexpr type_info(std::in_place_type_t<Type>) noexcept
  79666. : seq{type_index<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  79667. identifier{type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value()},
  79668. alias{type_name<std::remove_const_t<std::remove_reference_t<Type>>>::value()} {}
  79669. // NOLINTEND(modernize-use-transparent-functors)
  79670. /**
  79671. * @brief Type index.
  79672. * @return Type index.
  79673. */
  79674. [[nodiscard]] constexpr id_type index() const noexcept {
  79675. return seq;
  79676. }
  79677. /**
  79678. * @brief Type hash.
  79679. * @return Type hash.
  79680. */
  79681. [[nodiscard]] constexpr id_type hash() const noexcept {
  79682. return identifier;
  79683. }
  79684. /**
  79685. * @brief Type name.
  79686. * @return Type name.
  79687. */
  79688. [[nodiscard]] constexpr std::string_view name() const noexcept {
  79689. return alias;
  79690. }
  79691. private:
  79692. id_type seq;
  79693. id_type identifier;
  79694. std::string_view alias;
  79695. };
  79696. /**
  79697. * @brief Compares the contents of two type info objects.
  79698. * @param lhs A type info object.
  79699. * @param rhs A type info object.
  79700. * @return True if the two type info objects are identical, false otherwise.
  79701. */
  79702. [[nodiscard]] constexpr bool operator==(const type_info &lhs, const type_info &rhs) noexcept {
  79703. return lhs.hash() == rhs.hash();
  79704. }
  79705. /**
  79706. * @brief Compares the contents of two type info objects.
  79707. * @param lhs A type info object.
  79708. * @param rhs A type info object.
  79709. * @return True if the two type info objects differ, false otherwise.
  79710. */
  79711. [[nodiscard]] constexpr bool operator!=(const type_info &lhs, const type_info &rhs) noexcept {
  79712. return !(lhs == rhs);
  79713. }
  79714. /**
  79715. * @brief Compares two type info objects.
  79716. * @param lhs A valid type info object.
  79717. * @param rhs A valid type info object.
  79718. * @return True if the first element is less than the second, false otherwise.
  79719. */
  79720. [[nodiscard]] constexpr bool operator<(const type_info &lhs, const type_info &rhs) noexcept {
  79721. return lhs.index() < rhs.index();
  79722. }
  79723. /**
  79724. * @brief Compares two type info objects.
  79725. * @param lhs A valid type info object.
  79726. * @param rhs A valid type info object.
  79727. * @return True if the first element is less than or equal to the second, false
  79728. * otherwise.
  79729. */
  79730. [[nodiscard]] constexpr bool operator<=(const type_info &lhs, const type_info &rhs) noexcept {
  79731. return !(rhs < lhs);
  79732. }
  79733. /**
  79734. * @brief Compares two type info objects.
  79735. * @param lhs A valid type info object.
  79736. * @param rhs A valid type info object.
  79737. * @return True if the first element is greater than the second, false
  79738. * otherwise.
  79739. */
  79740. [[nodiscard]] constexpr bool operator>(const type_info &lhs, const type_info &rhs) noexcept {
  79741. return rhs < lhs;
  79742. }
  79743. /**
  79744. * @brief Compares two type info objects.
  79745. * @param lhs A valid type info object.
  79746. * @param rhs A valid type info object.
  79747. * @return True if the first element is greater than or equal to the second,
  79748. * false otherwise.
  79749. */
  79750. [[nodiscard]] constexpr bool operator>=(const type_info &lhs, const type_info &rhs) noexcept {
  79751. return !(lhs < rhs);
  79752. }
  79753. /**
  79754. * @brief Returns the type info object associated to a given type.
  79755. *
  79756. * The returned element refers to an object with static storage duration.<br/>
  79757. * The type doesn't need to be a complete type. If the type is a reference, the
  79758. * result refers to the referenced type. In all cases, top-level cv-qualifiers
  79759. * are ignored.
  79760. *
  79761. * @tparam Type Type for which to generate a type info object.
  79762. * @return A reference to a properly initialized type info object.
  79763. */
  79764. template<typename Type>
  79765. [[nodiscard]] const type_info &type_id() noexcept {
  79766. if constexpr(std::is_same_v<Type, std::remove_const_t<std::remove_reference_t<Type>>>) {
  79767. static const type_info instance{std::in_place_type<Type>};
  79768. return instance;
  79769. } else {
  79770. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  79771. }
  79772. }
  79773. /*! @copydoc type_id */
  79774. template<typename Type>
  79775. // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward)
  79776. [[nodiscard]] const type_info &type_id(Type &&) noexcept {
  79777. return type_id<std::remove_const_t<std::remove_reference_t<Type>>>();
  79778. }
  79779. } // namespace entt
  79780. #endif
  79781. // #include "../core/utility.hpp"
  79782. #ifndef ENTT_CORE_UTILITY_HPP
  79783. #define ENTT_CORE_UTILITY_HPP
  79784. #include <type_traits>
  79785. #include <utility>
  79786. namespace entt {
  79787. /*! @brief Identity function object (waiting for C++20). */
  79788. struct identity {
  79789. /*! @brief Indicates that this is a transparent function object. */
  79790. using is_transparent = void;
  79791. /**
  79792. * @brief Returns its argument unchanged.
  79793. * @tparam Type Type of the argument.
  79794. * @param value The actual argument.
  79795. * @return The submitted value as-is.
  79796. */
  79797. template<typename Type>
  79798. [[nodiscard]] constexpr Type &&operator()(Type &&value) const noexcept {
  79799. return std::forward<Type>(value);
  79800. }
  79801. };
  79802. /**
  79803. * @brief Constant utility to disambiguate overloaded members of a class.
  79804. * @tparam Type Type of the desired overload.
  79805. * @tparam Class Type of class to which the member belongs.
  79806. * @param member A valid pointer to a member.
  79807. * @return Pointer to the member.
  79808. */
  79809. template<typename Type, typename Class>
  79810. [[nodiscard]] constexpr auto overload(Type Class::*member) noexcept {
  79811. return member;
  79812. }
  79813. /**
  79814. * @brief Constant utility to disambiguate overloaded functions.
  79815. * @tparam Func Function type of the desired overload.
  79816. * @param func A valid pointer to a function.
  79817. * @return Pointer to the function.
  79818. */
  79819. template<typename Func>
  79820. [[nodiscard]] constexpr auto overload(Func *func) noexcept {
  79821. return func;
  79822. }
  79823. /**
  79824. * @brief Helper type for visitors.
  79825. * @tparam Func Types of function objects.
  79826. */
  79827. template<typename... Func>
  79828. struct overloaded: Func... {
  79829. using Func::operator()...;
  79830. };
  79831. /**
  79832. * @brief Deduction guide.
  79833. * @tparam Func Types of function objects.
  79834. */
  79835. template<typename... Func>
  79836. overloaded(Func...) -> overloaded<Func...>;
  79837. /**
  79838. * @brief Basic implementation of a y-combinator.
  79839. * @tparam Func Type of a potentially recursive function.
  79840. */
  79841. template<typename Func>
  79842. struct y_combinator {
  79843. /**
  79844. * @brief Constructs a y-combinator from a given function.
  79845. * @param recursive A potentially recursive function.
  79846. */
  79847. constexpr y_combinator(Func recursive) noexcept(std::is_nothrow_move_constructible_v<Func>)
  79848. : func{std::move(recursive)} {}
  79849. /**
  79850. * @brief Invokes a y-combinator and therefore its underlying function.
  79851. * @tparam Args Types of arguments to use to invoke the underlying function.
  79852. * @param args Parameters to use to invoke the underlying function.
  79853. * @return Return value of the underlying function, if any.
  79854. */
  79855. template<typename... Args>
  79856. constexpr decltype(auto) operator()(Args &&...args) const noexcept(std::is_nothrow_invocable_v<Func, const y_combinator &, Args...>) {
  79857. return func(*this, std::forward<Args>(args)...);
  79858. }
  79859. /*! @copydoc operator()() */
  79860. template<typename... Args>
  79861. constexpr decltype(auto) operator()(Args &&...args) noexcept(std::is_nothrow_invocable_v<Func, y_combinator &, Args...>) {
  79862. return func(*this, std::forward<Args>(args)...);
  79863. }
  79864. private:
  79865. Func func;
  79866. };
  79867. } // namespace entt
  79868. #endif
  79869. // #include "fwd.hpp"
  79870. // #include "sigh.hpp"
  79871. #ifndef ENTT_SIGNAL_SIGH_HPP
  79872. #define ENTT_SIGNAL_SIGH_HPP
  79873. #include <cstddef>
  79874. #include <memory>
  79875. #include <type_traits>
  79876. #include <utility>
  79877. #include <vector>
  79878. // #include "delegate.hpp"
  79879. #ifndef ENTT_SIGNAL_DELEGATE_HPP
  79880. #define ENTT_SIGNAL_DELEGATE_HPP
  79881. #include <cstddef>
  79882. #include <functional>
  79883. #include <tuple>
  79884. #include <type_traits>
  79885. #include <utility>
  79886. // #include "../config/config.h"
  79887. // #include "../core/type_traits.hpp"
  79888. // #include "fwd.hpp"
  79889. namespace entt {
  79890. /*! @cond TURN_OFF_DOXYGEN */
  79891. namespace internal {
  79892. template<typename Ret, typename... Args>
  79893. constexpr auto function_pointer(Ret (*)(Args...)) -> Ret (*)(Args...);
  79894. template<typename Ret, typename Type, typename... Args, typename Other>
  79895. constexpr auto function_pointer(Ret (*)(Type, Args...), Other &&) -> Ret (*)(Args...);
  79896. template<typename Class, typename Ret, typename... Args, typename... Other>
  79897. constexpr auto function_pointer(Ret (Class::*)(Args...), Other &&...) -> Ret (*)(Args...);
  79898. template<typename Class, typename Ret, typename... Args, typename... Other>
  79899. constexpr auto function_pointer(Ret (Class::*)(Args...) const, Other &&...) -> Ret (*)(Args...);
  79900. template<typename Class, typename Type, typename... Other, typename = std::enable_if_t<std::is_member_object_pointer_v<Type Class::*>>>
  79901. constexpr auto function_pointer(Type Class::*, Other &&...) -> Type (*)();
  79902. template<typename... Type>
  79903. using function_pointer_t = decltype(function_pointer(std::declval<Type>()...));
  79904. template<typename... Class, typename Ret, typename... Args>
  79905. [[nodiscard]] constexpr auto index_sequence_for(Ret (*)(Args...)) {
  79906. return std::index_sequence_for<Class..., Args...>{};
  79907. }
  79908. } // namespace internal
  79909. /*! @endcond */
  79910. /**
  79911. * @brief Basic delegate implementation.
  79912. *
  79913. * Primary template isn't defined on purpose. All the specializations give a
  79914. * compile-time error unless the template parameter is a function type.
  79915. */
  79916. template<typename>
  79917. class delegate;
  79918. /**
  79919. * @brief Utility class to use to send around functions and members.
  79920. *
  79921. * Unmanaged delegate for function pointers and members. Users of this class are
  79922. * in charge of disconnecting instances before deleting them.
  79923. *
  79924. * A delegate can be used as a general purpose invoker without memory overhead
  79925. * for free functions possibly with payloads and bound or unbound members.
  79926. *
  79927. * @tparam Ret Return type of a function type.
  79928. * @tparam Args Types of arguments of a function type.
  79929. */
  79930. template<typename Ret, typename... Args>
  79931. class delegate<Ret(Args...)> {
  79932. using return_type = std::remove_const_t<Ret>;
  79933. using delegate_type = return_type(const void *, Args...);
  79934. template<auto Candidate, std::size_t... Index>
  79935. [[nodiscard]] auto wrap(std::index_sequence<Index...>) noexcept {
  79936. return [](const void *, Args... args) -> return_type {
  79937. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  79938. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  79939. return static_cast<Ret>(std::invoke(Candidate, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  79940. };
  79941. }
  79942. template<auto Candidate, typename Type, std::size_t... Index>
  79943. [[nodiscard]] auto wrap(Type &, std::index_sequence<Index...>) noexcept {
  79944. return [](const void *payload, Args... args) -> return_type {
  79945. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  79946. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  79947. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type &, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  79948. return static_cast<Ret>(std::invoke(Candidate, *curr, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  79949. };
  79950. }
  79951. template<auto Candidate, typename Type, std::size_t... Index>
  79952. [[nodiscard]] auto wrap(Type *, std::index_sequence<Index...>) noexcept {
  79953. return [](const void *payload, Args... args) -> return_type {
  79954. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  79955. [[maybe_unused]] const auto arguments = std::forward_as_tuple(std::forward<Args>(args)...);
  79956. [[maybe_unused]] constexpr auto offset = !std::is_invocable_r_v<Ret, decltype(Candidate), Type *, type_list_element_t<Index, type_list<Args...>>...> * (sizeof...(Args) - sizeof...(Index));
  79957. return static_cast<Ret>(std::invoke(Candidate, curr, std::forward<type_list_element_t<Index + offset, type_list<Args...>>>(std::get<Index + offset>(arguments))...));
  79958. };
  79959. }
  79960. public:
  79961. /*! @brief Function type of the contained target. */
  79962. using function_type = Ret(const void *, Args...);
  79963. /*! @brief Function type of the delegate. */
  79964. using type = Ret(Args...);
  79965. /*! @brief Return type of the delegate. */
  79966. using result_type = Ret;
  79967. /*! @brief Default constructor. */
  79968. delegate() noexcept = default;
  79969. /**
  79970. * @brief Constructs a delegate with a given object or payload, if any.
  79971. * @tparam Candidate Function or member to connect to the delegate.
  79972. * @tparam Type Type of class or type of payload, if any.
  79973. * @param value_or_instance Optional valid object that fits the purpose.
  79974. */
  79975. template<auto Candidate, typename... Type>
  79976. delegate(connect_arg_t<Candidate>, Type &&...value_or_instance) noexcept {
  79977. connect<Candidate>(std::forward<Type>(value_or_instance)...);
  79978. }
  79979. /**
  79980. * @brief Constructs a delegate and connects an user defined function with
  79981. * optional payload.
  79982. * @param function Function to connect to the delegate.
  79983. * @param payload User defined arbitrary data.
  79984. */
  79985. delegate(function_type *function, const void *payload = nullptr) noexcept {
  79986. connect(function, payload);
  79987. }
  79988. /**
  79989. * @brief Connects a free function or an unbound member to a delegate.
  79990. * @tparam Candidate Function or member to connect to the delegate.
  79991. */
  79992. template<auto Candidate>
  79993. void connect() noexcept {
  79994. instance = nullptr;
  79995. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Args...>) {
  79996. fn = [](const void *, Args... args) -> return_type {
  79997. return Ret(std::invoke(Candidate, std::forward<Args>(args)...));
  79998. };
  79999. } else if constexpr(std::is_member_pointer_v<decltype(Candidate)>) {
  80000. fn = wrap<Candidate>(internal::index_sequence_for<type_list_element_t<0, type_list<Args...>>>(internal::function_pointer_t<decltype(Candidate)>{}));
  80001. } else {
  80002. fn = wrap<Candidate>(internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate)>{}));
  80003. }
  80004. }
  80005. /**
  80006. * @brief Connects a free function with payload or a bound member to a
  80007. * delegate.
  80008. *
  80009. * The delegate isn't responsible for the connected object or the payload.
  80010. * Users must always guarantee that the lifetime of the instance overcomes
  80011. * the one of the delegate.<br/>
  80012. * When used to connect a free function with payload, its signature must be
  80013. * such that the instance is the first argument before the ones used to
  80014. * define the delegate itself.
  80015. *
  80016. * @tparam Candidate Function or member to connect to the delegate.
  80017. * @tparam Type Type of class or type of payload.
  80018. * @param value_or_instance A valid reference that fits the purpose.
  80019. */
  80020. template<auto Candidate, typename Type>
  80021. void connect(Type &value_or_instance) noexcept {
  80022. instance = &value_or_instance;
  80023. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type &, Args...>) {
  80024. fn = [](const void *payload, Args... args) -> return_type {
  80025. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  80026. return Ret(std::invoke(Candidate, *curr, std::forward<Args>(args)...));
  80027. };
  80028. } else {
  80029. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  80030. }
  80031. }
  80032. /**
  80033. * @brief Connects a free function with payload or a bound member to a
  80034. * delegate.
  80035. *
  80036. * @sa connect(Type &)
  80037. *
  80038. * @tparam Candidate Function or member to connect to the delegate.
  80039. * @tparam Type Type of class or type of payload.
  80040. * @param value_or_instance A valid pointer that fits the purpose.
  80041. */
  80042. template<auto Candidate, typename Type>
  80043. void connect(Type *value_or_instance) noexcept {
  80044. instance = value_or_instance;
  80045. if constexpr(std::is_invocable_r_v<Ret, decltype(Candidate), Type *, Args...>) {
  80046. fn = [](const void *payload, Args... args) -> return_type {
  80047. Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
  80048. return Ret(std::invoke(Candidate, curr, std::forward<Args>(args)...));
  80049. };
  80050. } else {
  80051. fn = wrap<Candidate>(value_or_instance, internal::index_sequence_for(internal::function_pointer_t<decltype(Candidate), Type>{}));
  80052. }
  80053. }
  80054. /**
  80055. * @brief Connects an user defined function with optional payload to a
  80056. * delegate.
  80057. *
  80058. * The delegate isn't responsible for the connected object or the payload.
  80059. * Users must always guarantee that the lifetime of an instance overcomes
  80060. * the one of the delegate.<br/>
  80061. * The payload is returned as the first argument to the target function in
  80062. * all cases.
  80063. *
  80064. * @param function Function to connect to the delegate.
  80065. * @param payload User defined arbitrary data.
  80066. */
  80067. void connect(function_type *function, const void *payload = nullptr) noexcept {
  80068. ENTT_ASSERT(function != nullptr, "Uninitialized function pointer");
  80069. instance = payload;
  80070. fn = function;
  80071. }
  80072. /**
  80073. * @brief Resets a delegate.
  80074. *
  80075. * After a reset, a delegate cannot be invoked anymore.
  80076. */
  80077. void reset() noexcept {
  80078. instance = nullptr;
  80079. fn = nullptr;
  80080. }
  80081. /**
  80082. * @brief Returns a pointer to the stored callable function target, if any.
  80083. * @return An opaque pointer to the stored callable function target.
  80084. */
  80085. [[nodiscard]] function_type *target() const noexcept {
  80086. return fn;
  80087. }
  80088. /**
  80089. * @brief Returns the instance or the payload linked to a delegate, if any.
  80090. * @return An opaque pointer to the underlying data.
  80091. */
  80092. [[nodiscard]] const void *data() const noexcept {
  80093. return instance;
  80094. }
  80095. /**
  80096. * @brief Triggers a delegate.
  80097. *
  80098. * The delegate invokes the underlying function and returns the result.
  80099. *
  80100. * @warning
  80101. * Attempting to trigger an invalid delegate results in undefined
  80102. * behavior.
  80103. *
  80104. * @param args Arguments to use to invoke the underlying function.
  80105. * @return The value returned by the underlying function.
  80106. */
  80107. Ret operator()(Args... args) const {
  80108. ENTT_ASSERT(static_cast<bool>(*this), "Uninitialized delegate");
  80109. return fn(instance, std::forward<Args>(args)...);
  80110. }
  80111. /**
  80112. * @brief Checks whether a delegate actually stores a listener.
  80113. * @return False if the delegate is empty, true otherwise.
  80114. */
  80115. [[nodiscard]] explicit operator bool() const noexcept {
  80116. // no need to also test instance
  80117. return !(fn == nullptr);
  80118. }
  80119. /**
  80120. * @brief Compares the contents of two delegates.
  80121. * @param other Delegate with which to compare.
  80122. * @return False if the two contents differ, true otherwise.
  80123. */
  80124. [[nodiscard]] bool operator==(const delegate<Ret(Args...)> &other) const noexcept {
  80125. return fn == other.fn && instance == other.instance;
  80126. }
  80127. private:
  80128. const void *instance{};
  80129. delegate_type *fn{};
  80130. };
  80131. /**
  80132. * @brief Compares the contents of two delegates.
  80133. * @tparam Ret Return type of a function type.
  80134. * @tparam Args Types of arguments of a function type.
  80135. * @param lhs A valid delegate object.
  80136. * @param rhs A valid delegate object.
  80137. * @return True if the two contents differ, false otherwise.
  80138. */
  80139. template<typename Ret, typename... Args>
  80140. [[nodiscard]] bool operator!=(const delegate<Ret(Args...)> &lhs, const delegate<Ret(Args...)> &rhs) noexcept {
  80141. return !(lhs == rhs);
  80142. }
  80143. /**
  80144. * @brief Deduction guide.
  80145. * @tparam Candidate Function or member to connect to the delegate.
  80146. */
  80147. template<auto Candidate>
  80148. delegate(connect_arg_t<Candidate>) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate)>>>;
  80149. /**
  80150. * @brief Deduction guide.
  80151. * @tparam Candidate Function or member to connect to the delegate.
  80152. * @tparam Type Type of class or type of payload.
  80153. */
  80154. template<auto Candidate, typename Type>
  80155. delegate(connect_arg_t<Candidate>, Type &&) -> delegate<std::remove_pointer_t<internal::function_pointer_t<decltype(Candidate), Type>>>;
  80156. /**
  80157. * @brief Deduction guide.
  80158. * @tparam Ret Return type of a function type.
  80159. * @tparam Args Types of arguments of a function type.
  80160. */
  80161. template<typename Ret, typename... Args>
  80162. delegate(Ret (*)(const void *, Args...), const void * = nullptr) -> delegate<Ret(Args...)>;
  80163. } // namespace entt
  80164. #endif
  80165. // #include "fwd.hpp"
  80166. namespace entt {
  80167. /**
  80168. * @brief Sink class.
  80169. *
  80170. * Primary template isn't defined on purpose. All the specializations give a
  80171. * compile-time error unless the template parameter is a function type.
  80172. *
  80173. * @tparam Type A valid signal handler type.
  80174. */
  80175. template<typename Type>
  80176. class sink;
  80177. /**
  80178. * @brief Unmanaged signal handler.
  80179. *
  80180. * Primary template isn't defined on purpose. All the specializations give a
  80181. * compile-time error unless the template parameter is a function type.
  80182. *
  80183. * @tparam Type A valid function type.
  80184. * @tparam Allocator Type of allocator used to manage memory and elements.
  80185. */
  80186. template<typename Type, typename Allocator>
  80187. class sigh;
  80188. /**
  80189. * @brief Unmanaged signal handler.
  80190. *
  80191. * It works directly with references to classes and pointers to member functions
  80192. * as well as pointers to free functions. Users of this class are in charge of
  80193. * disconnecting instances before deleting them.
  80194. *
  80195. * This class serves mainly two purposes:
  80196. *
  80197. * * Creating signals to use later to notify a bunch of listeners.
  80198. * * Collecting results from a set of functions like in a voting system.
  80199. *
  80200. * @tparam Ret Return type of a function type.
  80201. * @tparam Args Types of arguments of a function type.
  80202. * @tparam Allocator Type of allocator used to manage memory and elements.
  80203. */
  80204. template<typename Ret, typename... Args, typename Allocator>
  80205. class sigh<Ret(Args...), Allocator> {
  80206. friend class sink<sigh<Ret(Args...), Allocator>>;
  80207. using alloc_traits = std::allocator_traits<Allocator>;
  80208. using delegate_type = delegate<Ret(Args...)>;
  80209. using container_type = std::vector<delegate_type, typename alloc_traits::template rebind_alloc<delegate_type>>;
  80210. public:
  80211. /*! @brief Allocator type. */
  80212. using allocator_type = Allocator;
  80213. /*! @brief Unsigned integer type. */
  80214. using size_type = std::size_t;
  80215. /*! @brief Sink type. */
  80216. using sink_type = sink<sigh<Ret(Args...), Allocator>>;
  80217. /*! @brief Default constructor. */
  80218. sigh() noexcept(noexcept(allocator_type{}))
  80219. : sigh{allocator_type{}} {}
  80220. /**
  80221. * @brief Constructs a signal handler with a given allocator.
  80222. * @param allocator The allocator to use.
  80223. */
  80224. explicit sigh(const allocator_type &allocator) noexcept
  80225. : calls{allocator} {}
  80226. /**
  80227. * @brief Copy constructor.
  80228. * @param other The instance to copy from.
  80229. */
  80230. sigh(const sigh &other)
  80231. : calls{other.calls} {}
  80232. /**
  80233. * @brief Allocator-extended copy constructor.
  80234. * @param other The instance to copy from.
  80235. * @param allocator The allocator to use.
  80236. */
  80237. sigh(const sigh &other, const allocator_type &allocator)
  80238. : calls{other.calls, allocator} {}
  80239. /**
  80240. * @brief Move constructor.
  80241. * @param other The instance to move from.
  80242. */
  80243. sigh(sigh &&other) noexcept
  80244. : calls{std::move(other.calls)} {}
  80245. /**
  80246. * @brief Allocator-extended move constructor.
  80247. * @param other The instance to move from.
  80248. * @param allocator The allocator to use.
  80249. */
  80250. sigh(sigh &&other, const allocator_type &allocator)
  80251. : calls{std::move(other.calls), allocator} {}
  80252. /*! @brief Default destructor. */
  80253. ~sigh() = default;
  80254. /**
  80255. * @brief Copy assignment operator.
  80256. * @param other The instance to copy from.
  80257. * @return This signal handler.
  80258. */
  80259. sigh &operator=(const sigh &other) {
  80260. calls = other.calls;
  80261. return *this;
  80262. }
  80263. /**
  80264. * @brief Move assignment operator.
  80265. * @param other The instance to move from.
  80266. * @return This signal handler.
  80267. */
  80268. sigh &operator=(sigh &&other) noexcept {
  80269. swap(other);
  80270. return *this;
  80271. }
  80272. /**
  80273. * @brief Exchanges the contents with those of a given signal handler.
  80274. * @param other Signal handler to exchange the content with.
  80275. */
  80276. void swap(sigh &other) noexcept {
  80277. using std::swap;
  80278. swap(calls, other.calls);
  80279. }
  80280. /**
  80281. * @brief Returns the associated allocator.
  80282. * @return The associated allocator.
  80283. */
  80284. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  80285. return calls.get_allocator();
  80286. }
  80287. /**
  80288. * @brief Number of listeners connected to the signal.
  80289. * @return Number of listeners currently connected.
  80290. */
  80291. [[nodiscard]] size_type size() const noexcept {
  80292. return calls.size();
  80293. }
  80294. /**
  80295. * @brief Returns false if at least a listener is connected to the signal.
  80296. * @return True if the signal has no listeners connected, false otherwise.
  80297. */
  80298. [[nodiscard]] bool empty() const noexcept {
  80299. return calls.empty();
  80300. }
  80301. /**
  80302. * @brief Triggers a signal.
  80303. *
  80304. * All the listeners are notified. Order isn't guaranteed.
  80305. *
  80306. * @param args Arguments to use to invoke listeners.
  80307. */
  80308. void publish(Args... args) const {
  80309. for(auto pos = calls.size(); pos; --pos) {
  80310. calls[pos - 1u](args...);
  80311. }
  80312. }
  80313. /**
  80314. * @brief Collects return values from the listeners.
  80315. *
  80316. * The collector must expose a call operator with the following properties:
  80317. *
  80318. * * The return type is either `void` or such that it's convertible to
  80319. * `bool`. In the second case, a true value will stop the iteration.
  80320. * * The list of parameters is empty if `Ret` is `void`, otherwise it
  80321. * contains a single element such that `Ret` is convertible to it.
  80322. *
  80323. * @tparam Func Type of collector to use, if any.
  80324. * @param func A valid function object.
  80325. * @param args Arguments to use to invoke listeners.
  80326. */
  80327. template<typename Func>
  80328. void collect(Func func, Args... args) const {
  80329. for(auto pos = calls.size(); pos; --pos) {
  80330. if constexpr(std::is_void_v<Ret> || !std::is_invocable_v<Func, Ret>) {
  80331. calls[pos - 1u](args...);
  80332. if constexpr(std::is_invocable_r_v<bool, Func>) {
  80333. if(func()) {
  80334. break;
  80335. }
  80336. } else {
  80337. func();
  80338. }
  80339. } else {
  80340. if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
  80341. if(func(calls[pos - 1u](args...))) {
  80342. break;
  80343. }
  80344. } else {
  80345. func(calls[pos - 1u](args...));
  80346. }
  80347. }
  80348. }
  80349. }
  80350. private:
  80351. container_type calls;
  80352. };
  80353. /**
  80354. * @brief Connection class.
  80355. *
  80356. * Opaque object the aim of which is to allow users to release an already
  80357. * estabilished connection without having to keep a reference to the signal or
  80358. * the sink that generated it.
  80359. */
  80360. class connection {
  80361. template<typename>
  80362. friend class sink;
  80363. connection(delegate<void(void *)> fn, void *ref)
  80364. : disconnect{fn}, signal{ref} {}
  80365. public:
  80366. /*! @brief Default constructor. */
  80367. connection()
  80368. : signal{} {}
  80369. /**
  80370. * @brief Checks whether a connection is properly initialized.
  80371. * @return True if the connection is properly initialized, false otherwise.
  80372. */
  80373. [[nodiscard]] explicit operator bool() const noexcept {
  80374. return static_cast<bool>(disconnect);
  80375. }
  80376. /*! @brief Breaks the connection. */
  80377. void release() {
  80378. if(disconnect) {
  80379. disconnect(signal);
  80380. disconnect.reset();
  80381. }
  80382. }
  80383. private:
  80384. delegate<void(void *)> disconnect;
  80385. void *signal;
  80386. };
  80387. /**
  80388. * @brief Scoped connection class.
  80389. *
  80390. * Opaque object the aim of which is to allow users to release an already
  80391. * estabilished connection without having to keep a reference to the signal or
  80392. * the sink that generated it.<br/>
  80393. * A scoped connection automatically breaks the link between the two objects
  80394. * when it goes out of scope.
  80395. */
  80396. struct scoped_connection {
  80397. /*! @brief Default constructor. */
  80398. scoped_connection() = default;
  80399. /**
  80400. * @brief Constructs a scoped connection from a basic connection.
  80401. * @param other A valid connection object.
  80402. */
  80403. scoped_connection(const connection &other)
  80404. : conn{other} {}
  80405. /*! @brief Default copy constructor, deleted on purpose. */
  80406. scoped_connection(const scoped_connection &) = delete;
  80407. /**
  80408. * @brief Move constructor.
  80409. * @param other The scoped connection to move from.
  80410. */
  80411. scoped_connection(scoped_connection &&other) noexcept
  80412. : conn{std::exchange(other.conn, {})} {}
  80413. /*! @brief Automatically breaks the link on destruction. */
  80414. ~scoped_connection() {
  80415. conn.release();
  80416. }
  80417. /**
  80418. * @brief Default copy assignment operator, deleted on purpose.
  80419. * @return This scoped connection.
  80420. */
  80421. scoped_connection &operator=(const scoped_connection &) = delete;
  80422. /**
  80423. * @brief Move assignment operator.
  80424. * @param other The scoped connection to move from.
  80425. * @return This scoped connection.
  80426. */
  80427. scoped_connection &operator=(scoped_connection &&other) noexcept {
  80428. conn = std::exchange(other.conn, {});
  80429. return *this;
  80430. }
  80431. /**
  80432. * @brief Acquires a connection.
  80433. * @param other The connection object to acquire.
  80434. * @return This scoped connection.
  80435. */
  80436. scoped_connection &operator=(connection other) {
  80437. conn = other;
  80438. return *this;
  80439. }
  80440. /**
  80441. * @brief Checks whether a scoped connection is properly initialized.
  80442. * @return True if the connection is properly initialized, false otherwise.
  80443. */
  80444. [[nodiscard]] explicit operator bool() const noexcept {
  80445. return static_cast<bool>(conn);
  80446. }
  80447. /*! @brief Breaks the connection. */
  80448. void release() {
  80449. conn.release();
  80450. }
  80451. private:
  80452. connection conn;
  80453. };
  80454. /**
  80455. * @brief Sink class.
  80456. *
  80457. * A sink is used to connect listeners to signals and to disconnect them.<br/>
  80458. * The function type for a listener is the one of the signal to which it
  80459. * belongs.
  80460. *
  80461. * The clear separation between a signal and a sink permits to store the former
  80462. * as private data member without exposing the publish functionality to the
  80463. * users of the class.
  80464. *
  80465. * @warning
  80466. * Lifetime of a sink must not overcome that of the signal to which it refers.
  80467. * In any other case, attempting to use a sink results in undefined behavior.
  80468. *
  80469. * @tparam Ret Return type of a function type.
  80470. * @tparam Args Types of arguments of a function type.
  80471. * @tparam Allocator Type of allocator used to manage memory and elements.
  80472. */
  80473. template<typename Ret, typename... Args, typename Allocator>
  80474. class sink<sigh<Ret(Args...), Allocator>> {
  80475. using signal_type = sigh<Ret(Args...), Allocator>;
  80476. using delegate_type = typename signal_type::delegate_type;
  80477. using difference_type = typename signal_type::container_type::difference_type;
  80478. template<auto Candidate, typename Type>
  80479. static void release(Type value_or_instance, void *signal) {
  80480. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
  80481. }
  80482. template<auto Candidate>
  80483. static void release(void *signal) {
  80484. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>();
  80485. }
  80486. template<typename Func>
  80487. void disconnect_if(Func callback) {
  80488. auto &ref = signal_or_assert();
  80489. for(auto pos = ref.calls.size(); pos; --pos) {
  80490. if(auto &elem = ref.calls[pos - 1u]; callback(elem)) {
  80491. elem = std::move(ref.calls.back());
  80492. ref.calls.pop_back();
  80493. }
  80494. }
  80495. }
  80496. [[nodiscard]] auto &signal_or_assert() const noexcept {
  80497. ENTT_ASSERT(signal != nullptr, "Invalid pointer to signal");
  80498. return *signal;
  80499. }
  80500. public:
  80501. /*! @brief Constructs an invalid sink. */
  80502. sink() noexcept
  80503. : signal{} {}
  80504. /**
  80505. * @brief Constructs a sink that is allowed to modify a given signal.
  80506. * @param ref A valid reference to a signal object.
  80507. */
  80508. sink(sigh<Ret(Args...), Allocator> &ref) noexcept
  80509. : signal{&ref} {}
  80510. /**
  80511. * @brief Returns false if at least a listener is connected to the sink.
  80512. * @return True if the sink has no listeners connected, false otherwise.
  80513. */
  80514. [[nodiscard]] bool empty() const noexcept {
  80515. return signal_or_assert().calls.empty();
  80516. }
  80517. /**
  80518. * @brief Connects a free function or an unbound member to a signal.
  80519. * @tparam Candidate Function or member to connect to the signal.
  80520. * @return A properly initialized connection object.
  80521. */
  80522. template<auto Candidate>
  80523. connection connect() {
  80524. disconnect<Candidate>();
  80525. delegate_type call{};
  80526. call.template connect<Candidate>();
  80527. signal_or_assert().calls.push_back(std::move(call));
  80528. delegate<void(void *)> conn{};
  80529. conn.template connect<&release<Candidate>>();
  80530. return {conn, signal};
  80531. }
  80532. /**
  80533. * @brief Connects a free function with payload or a bound member to a
  80534. * signal.
  80535. *
  80536. * The signal isn't responsible for the connected object or the payload.
  80537. * Users must always guarantee that the lifetime of the instance overcomes
  80538. * the one of the signal.<br/>
  80539. * When used to connect a free function with payload, its signature must be
  80540. * such that the instance is the first argument before the ones used to
  80541. * define the signal itself.
  80542. *
  80543. * @tparam Candidate Function or member to connect to the signal.
  80544. * @tparam Type Type of class or type of payload.
  80545. * @param value_or_instance A valid reference that fits the purpose.
  80546. * @return A properly initialized connection object.
  80547. */
  80548. template<auto Candidate, typename Type>
  80549. connection connect(Type &value_or_instance) {
  80550. disconnect<Candidate>(value_or_instance);
  80551. delegate_type call{};
  80552. call.template connect<Candidate>(value_or_instance);
  80553. signal_or_assert().calls.push_back(std::move(call));
  80554. delegate<void(void *)> conn{};
  80555. conn.template connect<&release<Candidate, Type &>>(value_or_instance);
  80556. return {conn, signal};
  80557. }
  80558. /**
  80559. * @brief Connects a free function with payload or a bound member to a
  80560. * signal.
  80561. *
  80562. * @sa connect(Type &)
  80563. *
  80564. * @tparam Candidate Function or member to connect to the signal.
  80565. * @tparam Type Type of class or type of payload.
  80566. * @param value_or_instance A valid pointer that fits the purpose.
  80567. * @return A properly initialized connection object.
  80568. */
  80569. template<auto Candidate, typename Type>
  80570. connection connect(Type *value_or_instance) {
  80571. disconnect<Candidate>(value_or_instance);
  80572. delegate_type call{};
  80573. call.template connect<Candidate>(value_or_instance);
  80574. signal_or_assert().calls.push_back(std::move(call));
  80575. delegate<void(void *)> conn{};
  80576. conn.template connect<&release<Candidate, Type *>>(value_or_instance);
  80577. return {conn, signal};
  80578. }
  80579. /**
  80580. * @brief Disconnects a free function or an unbound member from a signal.
  80581. * @tparam Candidate Function or member to disconnect from the signal.
  80582. */
  80583. template<auto Candidate>
  80584. void disconnect() {
  80585. delegate_type call{};
  80586. call.template connect<Candidate>();
  80587. disconnect_if([&call](const auto &elem) { return elem == call; });
  80588. }
  80589. /**
  80590. * @brief Disconnects a free function with payload or a bound member from a
  80591. * signal.
  80592. *
  80593. * The signal isn't responsible for the connected object or the payload.
  80594. * Users must always guarantee that the lifetime of the instance overcomes
  80595. * the one of the signal.<br/>
  80596. * When used to connect a free function with payload, its signature must be
  80597. * such that the instance is the first argument before the ones used to
  80598. * define the signal itself.
  80599. *
  80600. * @tparam Candidate Function or member to disconnect from the signal.
  80601. * @tparam Type Type of class or type of payload, if any.
  80602. * @param value_or_instance A valid reference that fits the purpose.
  80603. */
  80604. template<auto Candidate, typename Type>
  80605. void disconnect(Type &value_or_instance) {
  80606. delegate_type call{};
  80607. call.template connect<Candidate>(value_or_instance);
  80608. disconnect_if([&call](const auto &elem) { return elem == call; });
  80609. }
  80610. /**
  80611. * @brief Disconnects a free function with payload or a bound member from a
  80612. * signal.
  80613. *
  80614. * @sa disconnect(Type &)
  80615. *
  80616. * @tparam Candidate Function or member to disconnect from the signal.
  80617. * @tparam Type Type of class or type of payload, if any.
  80618. * @param value_or_instance A valid pointer that fits the purpose.
  80619. */
  80620. template<auto Candidate, typename Type>
  80621. void disconnect(Type *value_or_instance) {
  80622. delegate_type call{};
  80623. call.template connect<Candidate>(value_or_instance);
  80624. disconnect_if([&call](const auto &elem) { return elem == call; });
  80625. }
  80626. /**
  80627. * @brief Disconnects free functions with payload or bound members from a
  80628. * signal.
  80629. * @param value_or_instance A valid object that fits the purpose.
  80630. */
  80631. void disconnect(const void *value_or_instance) {
  80632. ENTT_ASSERT(value_or_instance != nullptr, "Invalid value or instance");
  80633. disconnect_if([value_or_instance](const auto &elem) { return elem.data() == value_or_instance; });
  80634. }
  80635. /*! @brief Disconnects all the listeners from a signal. */
  80636. void disconnect() {
  80637. signal_or_assert().calls.clear();
  80638. }
  80639. /**
  80640. * @brief Returns true if a sink is correctly initialized, false otherwise.
  80641. * @return True if a sink is correctly initialized, false otherwise.
  80642. */
  80643. [[nodiscard]] explicit operator bool() const noexcept {
  80644. return signal != nullptr;
  80645. }
  80646. private:
  80647. signal_type *signal;
  80648. };
  80649. /**
  80650. * @brief Deduction guide.
  80651. *
  80652. * It allows to deduce the signal handler type of a sink directly from the
  80653. * signal it refers to.
  80654. *
  80655. * @tparam Ret Return type of a function type.
  80656. * @tparam Args Types of arguments of a function type.
  80657. * @tparam Allocator Type of allocator used to manage memory and elements.
  80658. */
  80659. template<typename Ret, typename... Args, typename Allocator>
  80660. sink(sigh<Ret(Args...), Allocator> &) -> sink<sigh<Ret(Args...), Allocator>>;
  80661. } // namespace entt
  80662. #endif
  80663. namespace entt {
  80664. /*! @cond TURN_OFF_DOXYGEN */
  80665. namespace internal {
  80666. struct basic_dispatcher_handler {
  80667. virtual ~basic_dispatcher_handler() = default;
  80668. virtual void publish() = 0;
  80669. virtual void disconnect(void *) = 0;
  80670. virtual void clear() noexcept = 0;
  80671. [[nodiscard]] virtual std::size_t size() const noexcept = 0;
  80672. };
  80673. template<typename Type, typename Allocator>
  80674. class dispatcher_handler final: public basic_dispatcher_handler {
  80675. static_assert(std::is_same_v<Type, std::decay_t<Type>>, "Invalid type");
  80676. using alloc_traits = std::allocator_traits<Allocator>;
  80677. using signal_type = sigh<void(Type &), Allocator>;
  80678. using container_type = std::vector<Type, typename alloc_traits::template rebind_alloc<Type>>;
  80679. public:
  80680. using allocator_type = Allocator;
  80681. dispatcher_handler(const allocator_type &allocator)
  80682. : signal{allocator},
  80683. events{allocator} {}
  80684. void publish() override {
  80685. const auto length = events.size();
  80686. for(std::size_t pos{}; pos < length; ++pos) {
  80687. signal.publish(events[pos]);
  80688. }
  80689. events.erase(events.cbegin(), events.cbegin() + static_cast<typename container_type::difference_type>(length));
  80690. }
  80691. void disconnect(void *instance) override {
  80692. bucket().disconnect(instance);
  80693. }
  80694. void clear() noexcept override {
  80695. events.clear();
  80696. }
  80697. [[nodiscard]] auto bucket() noexcept {
  80698. return typename signal_type::sink_type{signal};
  80699. }
  80700. void trigger(Type event) {
  80701. signal.publish(event);
  80702. }
  80703. template<typename... Args>
  80704. void enqueue(Args &&...args) {
  80705. if constexpr(std::is_aggregate_v<Type> && (sizeof...(Args) != 0u || !std::is_default_constructible_v<Type>)) {
  80706. events.push_back(Type{std::forward<Args>(args)...});
  80707. } else {
  80708. events.emplace_back(std::forward<Args>(args)...);
  80709. }
  80710. }
  80711. [[nodiscard]] std::size_t size() const noexcept override {
  80712. return events.size();
  80713. }
  80714. private:
  80715. signal_type signal;
  80716. container_type events;
  80717. };
  80718. } // namespace internal
  80719. /*! @endcond */
  80720. /**
  80721. * @brief Basic dispatcher implementation.
  80722. *
  80723. * A dispatcher can be used either to trigger an immediate event or to enqueue
  80724. * events to be published all together once per tick.<br/>
  80725. * Listeners are provided in the form of member functions. For each event of
  80726. * type `Type`, listeners are such that they can be invoked with an argument of
  80727. * type `Type &`, no matter what the return type is.
  80728. *
  80729. * The dispatcher creates instances of the `sigh` class internally. Refer to the
  80730. * documentation of the latter for more details.
  80731. *
  80732. * @tparam Allocator Type of allocator used to manage memory and elements.
  80733. */
  80734. template<typename Allocator>
  80735. class basic_dispatcher {
  80736. template<typename Type>
  80737. using handler_type = internal::dispatcher_handler<Type, Allocator>;
  80738. using key_type = id_type;
  80739. // std::shared_ptr because of its type erased allocator which is useful here
  80740. using mapped_type = std::shared_ptr<internal::basic_dispatcher_handler>;
  80741. using alloc_traits = std::allocator_traits<Allocator>;
  80742. using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const key_type, mapped_type>>;
  80743. using container_type = dense_map<key_type, mapped_type, identity, std::equal_to<>, container_allocator>;
  80744. template<typename Type>
  80745. [[nodiscard]] handler_type<Type> &assure(const id_type id) {
  80746. static_assert(std::is_same_v<Type, std::decay_t<Type>>, "Non-decayed types not allowed");
  80747. auto &&ptr = pools.first()[id];
  80748. if(!ptr) {
  80749. const auto &allocator = get_allocator();
  80750. ptr = std::allocate_shared<handler_type<Type>>(allocator, allocator);
  80751. }
  80752. return static_cast<handler_type<Type> &>(*ptr);
  80753. }
  80754. template<typename Type>
  80755. [[nodiscard]] const handler_type<Type> *assure(const id_type id) const {
  80756. static_assert(std::is_same_v<Type, std::decay_t<Type>>, "Non-decayed types not allowed");
  80757. if(auto it = pools.first().find(id); it != pools.first().cend()) {
  80758. return static_cast<const handler_type<Type> *>(it->second.get());
  80759. }
  80760. return nullptr;
  80761. }
  80762. public:
  80763. /*! @brief Allocator type. */
  80764. using allocator_type = Allocator;
  80765. /*! @brief Unsigned integer type. */
  80766. using size_type = std::size_t;
  80767. /*! @brief Default constructor. */
  80768. basic_dispatcher()
  80769. : basic_dispatcher{allocator_type{}} {}
  80770. /**
  80771. * @brief Constructs a dispatcher with a given allocator.
  80772. * @param allocator The allocator to use.
  80773. */
  80774. explicit basic_dispatcher(const allocator_type &allocator)
  80775. : pools{allocator, allocator} {}
  80776. /*! @brief Default copy constructor, deleted on purpose. */
  80777. basic_dispatcher(const basic_dispatcher &) = delete;
  80778. /**
  80779. * @brief Move constructor.
  80780. * @param other The instance to move from.
  80781. */
  80782. basic_dispatcher(basic_dispatcher &&other) noexcept
  80783. : pools{std::move(other.pools)} {}
  80784. /**
  80785. * @brief Allocator-extended move constructor.
  80786. * @param other The instance to move from.
  80787. * @param allocator The allocator to use.
  80788. */
  80789. basic_dispatcher(basic_dispatcher &&other, const allocator_type &allocator)
  80790. : pools{container_type{std::move(other.pools.first()), allocator}, allocator} {
  80791. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a dispatcher is not allowed");
  80792. }
  80793. /*! @brief Default destructor. */
  80794. ~basic_dispatcher() = default;
  80795. /**
  80796. * @brief Default copy assignment operator, deleted on purpose.
  80797. * @return This dispatcher.
  80798. */
  80799. basic_dispatcher &operator=(const basic_dispatcher &) = delete;
  80800. /**
  80801. * @brief Move assignment operator.
  80802. * @param other The instance to move from.
  80803. * @return This dispatcher.
  80804. */
  80805. basic_dispatcher &operator=(basic_dispatcher &&other) noexcept {
  80806. ENTT_ASSERT(alloc_traits::is_always_equal::value || get_allocator() == other.get_allocator(), "Copying a dispatcher is not allowed");
  80807. swap(other);
  80808. return *this;
  80809. }
  80810. /**
  80811. * @brief Exchanges the contents with those of a given dispatcher.
  80812. * @param other Dispatcher to exchange the content with.
  80813. */
  80814. void swap(basic_dispatcher &other) noexcept {
  80815. using std::swap;
  80816. swap(pools, other.pools);
  80817. }
  80818. /**
  80819. * @brief Returns the associated allocator.
  80820. * @return The associated allocator.
  80821. */
  80822. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  80823. return pools.second();
  80824. }
  80825. /**
  80826. * @brief Returns the number of pending events for a given type.
  80827. * @tparam Type Type of event for which to return the count.
  80828. * @param id Name used to map the event queue within the dispatcher.
  80829. * @return The number of pending events for the given type.
  80830. */
  80831. template<typename Type>
  80832. [[nodiscard]] size_type size(const id_type id = type_hash<Type>::value()) const noexcept {
  80833. const auto *cpool = assure<std::decay_t<Type>>(id);
  80834. return cpool ? cpool->size() : 0u;
  80835. }
  80836. /**
  80837. * @brief Returns the total number of pending events.
  80838. * @return The total number of pending events.
  80839. */
  80840. [[nodiscard]] size_type size() const noexcept {
  80841. size_type count{};
  80842. for(auto &&cpool: pools.first()) {
  80843. count += cpool.second->size();
  80844. }
  80845. return count;
  80846. }
  80847. /**
  80848. * @brief Returns a sink object for the given event and queue.
  80849. *
  80850. * A sink is an opaque object used to connect listeners to events.
  80851. *
  80852. * The function type for a listener is _compatible_ with:
  80853. *
  80854. * @code{.cpp}
  80855. * void(Type &);
  80856. * @endcode
  80857. *
  80858. * The order of invocation of the listeners isn't guaranteed.
  80859. *
  80860. * @sa sink
  80861. *
  80862. * @tparam Type Type of event of which to get the sink.
  80863. * @param id Name used to map the event queue within the dispatcher.
  80864. * @return A temporary sink object.
  80865. */
  80866. template<typename Type>
  80867. [[nodiscard]] auto sink(const id_type id = type_hash<Type>::value()) {
  80868. return assure<Type>(id).bucket();
  80869. }
  80870. /**
  80871. * @brief Triggers an immediate event of a given type.
  80872. * @tparam Type Type of event to trigger.
  80873. * @param value An instance of the given type of event.
  80874. */
  80875. template<typename Type>
  80876. void trigger(Type &&value = {}) {
  80877. trigger(type_hash<std::decay_t<Type>>::value(), std::forward<Type>(value));
  80878. }
  80879. /**
  80880. * @brief Triggers an immediate event on a queue of a given type.
  80881. * @tparam Type Type of event to trigger.
  80882. * @param value An instance of the given type of event.
  80883. * @param id Name used to map the event queue within the dispatcher.
  80884. */
  80885. template<typename Type>
  80886. void trigger(const id_type id, Type &&value = {}) {
  80887. assure<std::decay_t<Type>>(id).trigger(std::forward<Type>(value));
  80888. }
  80889. /**
  80890. * @brief Enqueues an event of the given type.
  80891. * @tparam Type Type of event to enqueue.
  80892. * @tparam Args Types of arguments to use to construct the event.
  80893. * @param args Arguments to use to construct the event.
  80894. */
  80895. template<typename Type, typename... Args>
  80896. void enqueue(Args &&...args) {
  80897. enqueue_hint<Type>(type_hash<Type>::value(), std::forward<Args>(args)...);
  80898. }
  80899. /**
  80900. * @brief Enqueues an event of the given type.
  80901. * @tparam Type Type of event to enqueue.
  80902. * @param value An instance of the given type of event.
  80903. */
  80904. template<typename Type>
  80905. void enqueue(Type &&value) {
  80906. enqueue_hint(type_hash<std::decay_t<Type>>::value(), std::forward<Type>(value));
  80907. }
  80908. /**
  80909. * @brief Enqueues an event of the given type.
  80910. * @tparam Type Type of event to enqueue.
  80911. * @tparam Args Types of arguments to use to construct the event.
  80912. * @param id Name used to map the event queue within the dispatcher.
  80913. * @param args Arguments to use to construct the event.
  80914. */
  80915. template<typename Type, typename... Args>
  80916. void enqueue_hint(const id_type id, Args &&...args) {
  80917. assure<Type>(id).enqueue(std::forward<Args>(args)...);
  80918. }
  80919. /**
  80920. * @brief Enqueues an event of the given type.
  80921. * @tparam Type Type of event to enqueue.
  80922. * @param id Name used to map the event queue within the dispatcher.
  80923. * @param value An instance of the given type of event.
  80924. */
  80925. template<typename Type>
  80926. void enqueue_hint(const id_type id, Type &&value) {
  80927. assure<std::decay_t<Type>>(id).enqueue(std::forward<Type>(value));
  80928. }
  80929. /**
  80930. * @brief Utility function to disconnect everything related to a given value
  80931. * or instance from a dispatcher.
  80932. * @tparam Type Type of class or type of payload.
  80933. * @param value_or_instance A valid object that fits the purpose.
  80934. */
  80935. template<typename Type>
  80936. void disconnect(Type &value_or_instance) {
  80937. disconnect(&value_or_instance);
  80938. }
  80939. /**
  80940. * @brief Utility function to disconnect everything related to a given value
  80941. * or instance from a dispatcher.
  80942. * @tparam Type Type of class or type of payload.
  80943. * @param value_or_instance A valid object that fits the purpose.
  80944. */
  80945. template<typename Type>
  80946. void disconnect(Type *value_or_instance) {
  80947. for(auto &&cpool: pools.first()) {
  80948. cpool.second->disconnect(value_or_instance);
  80949. }
  80950. }
  80951. /**
  80952. * @brief Discards all the events stored so far in a given queue.
  80953. * @tparam Type Type of event to discard.
  80954. * @param id Name used to map the event queue within the dispatcher.
  80955. */
  80956. template<typename Type>
  80957. void clear(const id_type id = type_hash<Type>::value()) {
  80958. assure<Type>(id).clear();
  80959. }
  80960. /*! @brief Discards all the events queued so far. */
  80961. void clear() noexcept {
  80962. for(auto &&cpool: pools.first()) {
  80963. cpool.second->clear();
  80964. }
  80965. }
  80966. /**
  80967. * @brief Delivers all the pending events of a given queue.
  80968. * @tparam Type Type of event to send.
  80969. * @param id Name used to map the event queue within the dispatcher.
  80970. */
  80971. template<typename Type>
  80972. void update(const id_type id = type_hash<Type>::value()) {
  80973. assure<Type>(id).publish();
  80974. }
  80975. /*! @brief Delivers all the pending events. */
  80976. void update() const {
  80977. for(auto &&cpool: pools.first()) {
  80978. cpool.second->publish();
  80979. }
  80980. }
  80981. private:
  80982. compressed_pair<container_type, allocator_type> pools;
  80983. };
  80984. } // namespace entt
  80985. #endif
  80986. // #include "signal/emitter.hpp"
  80987. #ifndef ENTT_SIGNAL_EMITTER_HPP
  80988. #define ENTT_SIGNAL_EMITTER_HPP
  80989. #include <functional>
  80990. #include <type_traits>
  80991. #include <utility>
  80992. // #include "../container/dense_map.hpp"
  80993. // #include "../core/compressed_pair.hpp"
  80994. // #include "../core/fwd.hpp"
  80995. // #include "../core/type_info.hpp"
  80996. // #include "../core/utility.hpp"
  80997. // #include "fwd.hpp"
  80998. namespace entt {
  80999. /**
  81000. * @brief General purpose event emitter.
  81001. *
  81002. * To create an emitter type, derived classes must inherit from the base as:
  81003. *
  81004. * @code{.cpp}
  81005. * struct my_emitter: emitter<my_emitter> {
  81006. * // ...
  81007. * }
  81008. * @endcode
  81009. *
  81010. * Handlers for the different events are created internally on the fly. It's not
  81011. * required to specify in advance the full list of accepted events.<br/>
  81012. * Moreover, whenever an event is published, an emitter also passes a reference
  81013. * to itself to its listeners.
  81014. *
  81015. * @tparam Derived Emitter type.
  81016. * @tparam Allocator Type of allocator used to manage memory and elements.
  81017. */
  81018. template<typename Derived, typename Allocator>
  81019. class emitter {
  81020. using key_type = id_type;
  81021. using mapped_type = std::function<void(void *)>;
  81022. using alloc_traits = std::allocator_traits<Allocator>;
  81023. using container_allocator = typename alloc_traits::template rebind_alloc<std::pair<const key_type, mapped_type>>;
  81024. using container_type = dense_map<key_type, mapped_type, identity, std::equal_to<>, container_allocator>;
  81025. public:
  81026. /*! @brief Allocator type. */
  81027. using allocator_type = Allocator;
  81028. /*! @brief Unsigned integer type. */
  81029. using size_type = std::size_t;
  81030. /*! @brief Default constructor. */
  81031. emitter()
  81032. : emitter{allocator_type{}} {}
  81033. /**
  81034. * @brief Constructs an emitter with a given allocator.
  81035. * @param allocator The allocator to use.
  81036. */
  81037. explicit emitter(const allocator_type &allocator)
  81038. : handlers{allocator, allocator} {}
  81039. /*! @brief Default copy constructor, deleted on purpose. */
  81040. emitter(const emitter &) = delete;
  81041. /**
  81042. * @brief Move constructor.
  81043. * @param other The instance to move from.
  81044. */
  81045. emitter(emitter &&other) noexcept
  81046. : handlers{std::move(other.handlers)} {}
  81047. /**
  81048. * @brief Allocator-extended move constructor.
  81049. * @param other The instance to move from.
  81050. * @param allocator The allocator to use.
  81051. */
  81052. emitter(emitter &&other, const allocator_type &allocator)
  81053. : handlers{container_type{std::move(other.handlers.first()), allocator}, allocator} {
  81054. ENTT_ASSERT(alloc_traits::is_always_equal::value || handlers.second() == other.handlers.second(), "Copying an emitter is not allowed");
  81055. }
  81056. /*! @brief Default destructor. */
  81057. virtual ~emitter() {
  81058. static_assert(std::is_base_of_v<emitter<Derived, Allocator>, Derived>, "Invalid emitter type");
  81059. }
  81060. /**
  81061. * @brief Default copy assignment operator, deleted on purpose.
  81062. * @return This emitter.
  81063. */
  81064. emitter &operator=(const emitter &) = delete;
  81065. /**
  81066. * @brief Move assignment operator.
  81067. * @param other The instance to move from.
  81068. * @return This emitter.
  81069. */
  81070. emitter &operator=(emitter &&other) noexcept {
  81071. ENTT_ASSERT(alloc_traits::is_always_equal::value || handlers.second() == other.handlers.second(), "Copying an emitter is not allowed");
  81072. swap(other);
  81073. return *this;
  81074. }
  81075. /**
  81076. * @brief Exchanges the contents with those of a given emitter.
  81077. * @param other Emitter to exchange the content with.
  81078. */
  81079. void swap(emitter &other) noexcept {
  81080. using std::swap;
  81081. swap(handlers, other.handlers);
  81082. }
  81083. /**
  81084. * @brief Returns the associated allocator.
  81085. * @return The associated allocator.
  81086. */
  81087. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  81088. return handlers.second();
  81089. }
  81090. /**
  81091. * @brief Publishes a given event.
  81092. * @tparam Type Type of event to trigger.
  81093. * @param value An instance of the given type of event.
  81094. */
  81095. template<typename Type>
  81096. void publish(Type value) {
  81097. if(const auto id = type_id<Type>().hash(); handlers.first().contains(id)) {
  81098. handlers.first()[id](&value);
  81099. }
  81100. }
  81101. /**
  81102. * @brief Registers a listener with the event emitter.
  81103. * @tparam Type Type of event to which to connect the listener.
  81104. * @param func The listener to register.
  81105. */
  81106. template<typename Type>
  81107. void on(std::function<void(Type &, Derived &)> func) {
  81108. handlers.first().insert_or_assign(type_id<Type>().hash(), [func = std::move(func), this](void *value) {
  81109. func(*static_cast<Type *>(value), static_cast<Derived &>(*this));
  81110. });
  81111. }
  81112. /**
  81113. * @brief Disconnects a listener from the event emitter.
  81114. * @tparam Type Type of event of the listener.
  81115. */
  81116. template<typename Type>
  81117. void erase() {
  81118. handlers.first().erase(type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value());
  81119. }
  81120. /*! @brief Disconnects all the listeners. */
  81121. void clear() noexcept {
  81122. handlers.first().clear();
  81123. }
  81124. /**
  81125. * @brief Checks if there are listeners registered for the specific event.
  81126. * @tparam Type Type of event to test.
  81127. * @return True if there are no listeners registered, false otherwise.
  81128. */
  81129. template<typename Type>
  81130. [[nodiscard]] bool contains() const {
  81131. return handlers.first().contains(type_hash<std::remove_const_t<std::remove_reference_t<Type>>>::value());
  81132. }
  81133. /**
  81134. * @brief Checks if there are listeners registered with the event emitter.
  81135. * @return True if there are no listeners registered, false otherwise.
  81136. */
  81137. [[nodiscard]] bool empty() const noexcept {
  81138. return handlers.first().empty();
  81139. }
  81140. private:
  81141. compressed_pair<container_type, allocator_type> handlers;
  81142. };
  81143. } // namespace entt
  81144. #endif
  81145. // #include "signal/sigh.hpp"
  81146. #ifndef ENTT_SIGNAL_SIGH_HPP
  81147. #define ENTT_SIGNAL_SIGH_HPP
  81148. #include <cstddef>
  81149. #include <memory>
  81150. #include <type_traits>
  81151. #include <utility>
  81152. #include <vector>
  81153. // #include "delegate.hpp"
  81154. // #include "fwd.hpp"
  81155. namespace entt {
  81156. /**
  81157. * @brief Sink class.
  81158. *
  81159. * Primary template isn't defined on purpose. All the specializations give a
  81160. * compile-time error unless the template parameter is a function type.
  81161. *
  81162. * @tparam Type A valid signal handler type.
  81163. */
  81164. template<typename Type>
  81165. class sink;
  81166. /**
  81167. * @brief Unmanaged signal handler.
  81168. *
  81169. * Primary template isn't defined on purpose. All the specializations give a
  81170. * compile-time error unless the template parameter is a function type.
  81171. *
  81172. * @tparam Type A valid function type.
  81173. * @tparam Allocator Type of allocator used to manage memory and elements.
  81174. */
  81175. template<typename Type, typename Allocator>
  81176. class sigh;
  81177. /**
  81178. * @brief Unmanaged signal handler.
  81179. *
  81180. * It works directly with references to classes and pointers to member functions
  81181. * as well as pointers to free functions. Users of this class are in charge of
  81182. * disconnecting instances before deleting them.
  81183. *
  81184. * This class serves mainly two purposes:
  81185. *
  81186. * * Creating signals to use later to notify a bunch of listeners.
  81187. * * Collecting results from a set of functions like in a voting system.
  81188. *
  81189. * @tparam Ret Return type of a function type.
  81190. * @tparam Args Types of arguments of a function type.
  81191. * @tparam Allocator Type of allocator used to manage memory and elements.
  81192. */
  81193. template<typename Ret, typename... Args, typename Allocator>
  81194. class sigh<Ret(Args...), Allocator> {
  81195. friend class sink<sigh<Ret(Args...), Allocator>>;
  81196. using alloc_traits = std::allocator_traits<Allocator>;
  81197. using delegate_type = delegate<Ret(Args...)>;
  81198. using container_type = std::vector<delegate_type, typename alloc_traits::template rebind_alloc<delegate_type>>;
  81199. public:
  81200. /*! @brief Allocator type. */
  81201. using allocator_type = Allocator;
  81202. /*! @brief Unsigned integer type. */
  81203. using size_type = std::size_t;
  81204. /*! @brief Sink type. */
  81205. using sink_type = sink<sigh<Ret(Args...), Allocator>>;
  81206. /*! @brief Default constructor. */
  81207. sigh() noexcept(noexcept(allocator_type{}))
  81208. : sigh{allocator_type{}} {}
  81209. /**
  81210. * @brief Constructs a signal handler with a given allocator.
  81211. * @param allocator The allocator to use.
  81212. */
  81213. explicit sigh(const allocator_type &allocator) noexcept
  81214. : calls{allocator} {}
  81215. /**
  81216. * @brief Copy constructor.
  81217. * @param other The instance to copy from.
  81218. */
  81219. sigh(const sigh &other)
  81220. : calls{other.calls} {}
  81221. /**
  81222. * @brief Allocator-extended copy constructor.
  81223. * @param other The instance to copy from.
  81224. * @param allocator The allocator to use.
  81225. */
  81226. sigh(const sigh &other, const allocator_type &allocator)
  81227. : calls{other.calls, allocator} {}
  81228. /**
  81229. * @brief Move constructor.
  81230. * @param other The instance to move from.
  81231. */
  81232. sigh(sigh &&other) noexcept
  81233. : calls{std::move(other.calls)} {}
  81234. /**
  81235. * @brief Allocator-extended move constructor.
  81236. * @param other The instance to move from.
  81237. * @param allocator The allocator to use.
  81238. */
  81239. sigh(sigh &&other, const allocator_type &allocator)
  81240. : calls{std::move(other.calls), allocator} {}
  81241. /*! @brief Default destructor. */
  81242. ~sigh() = default;
  81243. /**
  81244. * @brief Copy assignment operator.
  81245. * @param other The instance to copy from.
  81246. * @return This signal handler.
  81247. */
  81248. sigh &operator=(const sigh &other) {
  81249. calls = other.calls;
  81250. return *this;
  81251. }
  81252. /**
  81253. * @brief Move assignment operator.
  81254. * @param other The instance to move from.
  81255. * @return This signal handler.
  81256. */
  81257. sigh &operator=(sigh &&other) noexcept {
  81258. swap(other);
  81259. return *this;
  81260. }
  81261. /**
  81262. * @brief Exchanges the contents with those of a given signal handler.
  81263. * @param other Signal handler to exchange the content with.
  81264. */
  81265. void swap(sigh &other) noexcept {
  81266. using std::swap;
  81267. swap(calls, other.calls);
  81268. }
  81269. /**
  81270. * @brief Returns the associated allocator.
  81271. * @return The associated allocator.
  81272. */
  81273. [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
  81274. return calls.get_allocator();
  81275. }
  81276. /**
  81277. * @brief Number of listeners connected to the signal.
  81278. * @return Number of listeners currently connected.
  81279. */
  81280. [[nodiscard]] size_type size() const noexcept {
  81281. return calls.size();
  81282. }
  81283. /**
  81284. * @brief Returns false if at least a listener is connected to the signal.
  81285. * @return True if the signal has no listeners connected, false otherwise.
  81286. */
  81287. [[nodiscard]] bool empty() const noexcept {
  81288. return calls.empty();
  81289. }
  81290. /**
  81291. * @brief Triggers a signal.
  81292. *
  81293. * All the listeners are notified. Order isn't guaranteed.
  81294. *
  81295. * @param args Arguments to use to invoke listeners.
  81296. */
  81297. void publish(Args... args) const {
  81298. for(auto pos = calls.size(); pos; --pos) {
  81299. calls[pos - 1u](args...);
  81300. }
  81301. }
  81302. /**
  81303. * @brief Collects return values from the listeners.
  81304. *
  81305. * The collector must expose a call operator with the following properties:
  81306. *
  81307. * * The return type is either `void` or such that it's convertible to
  81308. * `bool`. In the second case, a true value will stop the iteration.
  81309. * * The list of parameters is empty if `Ret` is `void`, otherwise it
  81310. * contains a single element such that `Ret` is convertible to it.
  81311. *
  81312. * @tparam Func Type of collector to use, if any.
  81313. * @param func A valid function object.
  81314. * @param args Arguments to use to invoke listeners.
  81315. */
  81316. template<typename Func>
  81317. void collect(Func func, Args... args) const {
  81318. for(auto pos = calls.size(); pos; --pos) {
  81319. if constexpr(std::is_void_v<Ret> || !std::is_invocable_v<Func, Ret>) {
  81320. calls[pos - 1u](args...);
  81321. if constexpr(std::is_invocable_r_v<bool, Func>) {
  81322. if(func()) {
  81323. break;
  81324. }
  81325. } else {
  81326. func();
  81327. }
  81328. } else {
  81329. if constexpr(std::is_invocable_r_v<bool, Func, Ret>) {
  81330. if(func(calls[pos - 1u](args...))) {
  81331. break;
  81332. }
  81333. } else {
  81334. func(calls[pos - 1u](args...));
  81335. }
  81336. }
  81337. }
  81338. }
  81339. private:
  81340. container_type calls;
  81341. };
  81342. /**
  81343. * @brief Connection class.
  81344. *
  81345. * Opaque object the aim of which is to allow users to release an already
  81346. * estabilished connection without having to keep a reference to the signal or
  81347. * the sink that generated it.
  81348. */
  81349. class connection {
  81350. template<typename>
  81351. friend class sink;
  81352. connection(delegate<void(void *)> fn, void *ref)
  81353. : disconnect{fn}, signal{ref} {}
  81354. public:
  81355. /*! @brief Default constructor. */
  81356. connection()
  81357. : signal{} {}
  81358. /**
  81359. * @brief Checks whether a connection is properly initialized.
  81360. * @return True if the connection is properly initialized, false otherwise.
  81361. */
  81362. [[nodiscard]] explicit operator bool() const noexcept {
  81363. return static_cast<bool>(disconnect);
  81364. }
  81365. /*! @brief Breaks the connection. */
  81366. void release() {
  81367. if(disconnect) {
  81368. disconnect(signal);
  81369. disconnect.reset();
  81370. }
  81371. }
  81372. private:
  81373. delegate<void(void *)> disconnect;
  81374. void *signal;
  81375. };
  81376. /**
  81377. * @brief Scoped connection class.
  81378. *
  81379. * Opaque object the aim of which is to allow users to release an already
  81380. * estabilished connection without having to keep a reference to the signal or
  81381. * the sink that generated it.<br/>
  81382. * A scoped connection automatically breaks the link between the two objects
  81383. * when it goes out of scope.
  81384. */
  81385. struct scoped_connection {
  81386. /*! @brief Default constructor. */
  81387. scoped_connection() = default;
  81388. /**
  81389. * @brief Constructs a scoped connection from a basic connection.
  81390. * @param other A valid connection object.
  81391. */
  81392. scoped_connection(const connection &other)
  81393. : conn{other} {}
  81394. /*! @brief Default copy constructor, deleted on purpose. */
  81395. scoped_connection(const scoped_connection &) = delete;
  81396. /**
  81397. * @brief Move constructor.
  81398. * @param other The scoped connection to move from.
  81399. */
  81400. scoped_connection(scoped_connection &&other) noexcept
  81401. : conn{std::exchange(other.conn, {})} {}
  81402. /*! @brief Automatically breaks the link on destruction. */
  81403. ~scoped_connection() {
  81404. conn.release();
  81405. }
  81406. /**
  81407. * @brief Default copy assignment operator, deleted on purpose.
  81408. * @return This scoped connection.
  81409. */
  81410. scoped_connection &operator=(const scoped_connection &) = delete;
  81411. /**
  81412. * @brief Move assignment operator.
  81413. * @param other The scoped connection to move from.
  81414. * @return This scoped connection.
  81415. */
  81416. scoped_connection &operator=(scoped_connection &&other) noexcept {
  81417. conn = std::exchange(other.conn, {});
  81418. return *this;
  81419. }
  81420. /**
  81421. * @brief Acquires a connection.
  81422. * @param other The connection object to acquire.
  81423. * @return This scoped connection.
  81424. */
  81425. scoped_connection &operator=(connection other) {
  81426. conn = other;
  81427. return *this;
  81428. }
  81429. /**
  81430. * @brief Checks whether a scoped connection is properly initialized.
  81431. * @return True if the connection is properly initialized, false otherwise.
  81432. */
  81433. [[nodiscard]] explicit operator bool() const noexcept {
  81434. return static_cast<bool>(conn);
  81435. }
  81436. /*! @brief Breaks the connection. */
  81437. void release() {
  81438. conn.release();
  81439. }
  81440. private:
  81441. connection conn;
  81442. };
  81443. /**
  81444. * @brief Sink class.
  81445. *
  81446. * A sink is used to connect listeners to signals and to disconnect them.<br/>
  81447. * The function type for a listener is the one of the signal to which it
  81448. * belongs.
  81449. *
  81450. * The clear separation between a signal and a sink permits to store the former
  81451. * as private data member without exposing the publish functionality to the
  81452. * users of the class.
  81453. *
  81454. * @warning
  81455. * Lifetime of a sink must not overcome that of the signal to which it refers.
  81456. * In any other case, attempting to use a sink results in undefined behavior.
  81457. *
  81458. * @tparam Ret Return type of a function type.
  81459. * @tparam Args Types of arguments of a function type.
  81460. * @tparam Allocator Type of allocator used to manage memory and elements.
  81461. */
  81462. template<typename Ret, typename... Args, typename Allocator>
  81463. class sink<sigh<Ret(Args...), Allocator>> {
  81464. using signal_type = sigh<Ret(Args...), Allocator>;
  81465. using delegate_type = typename signal_type::delegate_type;
  81466. using difference_type = typename signal_type::container_type::difference_type;
  81467. template<auto Candidate, typename Type>
  81468. static void release(Type value_or_instance, void *signal) {
  81469. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>(value_or_instance);
  81470. }
  81471. template<auto Candidate>
  81472. static void release(void *signal) {
  81473. sink{*static_cast<signal_type *>(signal)}.disconnect<Candidate>();
  81474. }
  81475. template<typename Func>
  81476. void disconnect_if(Func callback) {
  81477. auto &ref = signal_or_assert();
  81478. for(auto pos = ref.calls.size(); pos; --pos) {
  81479. if(auto &elem = ref.calls[pos - 1u]; callback(elem)) {
  81480. elem = std::move(ref.calls.back());
  81481. ref.calls.pop_back();
  81482. }
  81483. }
  81484. }
  81485. [[nodiscard]] auto &signal_or_assert() const noexcept {
  81486. ENTT_ASSERT(signal != nullptr, "Invalid pointer to signal");
  81487. return *signal;
  81488. }
  81489. public:
  81490. /*! @brief Constructs an invalid sink. */
  81491. sink() noexcept
  81492. : signal{} {}
  81493. /**
  81494. * @brief Constructs a sink that is allowed to modify a given signal.
  81495. * @param ref A valid reference to a signal object.
  81496. */
  81497. sink(sigh<Ret(Args...), Allocator> &ref) noexcept
  81498. : signal{&ref} {}
  81499. /**
  81500. * @brief Returns false if at least a listener is connected to the sink.
  81501. * @return True if the sink has no listeners connected, false otherwise.
  81502. */
  81503. [[nodiscard]] bool empty() const noexcept {
  81504. return signal_or_assert().calls.empty();
  81505. }
  81506. /**
  81507. * @brief Connects a free function or an unbound member to a signal.
  81508. * @tparam Candidate Function or member to connect to the signal.
  81509. * @return A properly initialized connection object.
  81510. */
  81511. template<auto Candidate>
  81512. connection connect() {
  81513. disconnect<Candidate>();
  81514. delegate_type call{};
  81515. call.template connect<Candidate>();
  81516. signal_or_assert().calls.push_back(std::move(call));
  81517. delegate<void(void *)> conn{};
  81518. conn.template connect<&release<Candidate>>();
  81519. return {conn, signal};
  81520. }
  81521. /**
  81522. * @brief Connects a free function with payload or a bound member to a
  81523. * signal.
  81524. *
  81525. * The signal isn't responsible for the connected object or the payload.
  81526. * Users must always guarantee that the lifetime of the instance overcomes
  81527. * the one of the signal.<br/>
  81528. * When used to connect a free function with payload, its signature must be
  81529. * such that the instance is the first argument before the ones used to
  81530. * define the signal itself.
  81531. *
  81532. * @tparam Candidate Function or member to connect to the signal.
  81533. * @tparam Type Type of class or type of payload.
  81534. * @param value_or_instance A valid reference that fits the purpose.
  81535. * @return A properly initialized connection object.
  81536. */
  81537. template<auto Candidate, typename Type>
  81538. connection connect(Type &value_or_instance) {
  81539. disconnect<Candidate>(value_or_instance);
  81540. delegate_type call{};
  81541. call.template connect<Candidate>(value_or_instance);
  81542. signal_or_assert().calls.push_back(std::move(call));
  81543. delegate<void(void *)> conn{};
  81544. conn.template connect<&release<Candidate, Type &>>(value_or_instance);
  81545. return {conn, signal};
  81546. }
  81547. /**
  81548. * @brief Connects a free function with payload or a bound member to a
  81549. * signal.
  81550. *
  81551. * @sa connect(Type &)
  81552. *
  81553. * @tparam Candidate Function or member to connect to the signal.
  81554. * @tparam Type Type of class or type of payload.
  81555. * @param value_or_instance A valid pointer that fits the purpose.
  81556. * @return A properly initialized connection object.
  81557. */
  81558. template<auto Candidate, typename Type>
  81559. connection connect(Type *value_or_instance) {
  81560. disconnect<Candidate>(value_or_instance);
  81561. delegate_type call{};
  81562. call.template connect<Candidate>(value_or_instance);
  81563. signal_or_assert().calls.push_back(std::move(call));
  81564. delegate<void(void *)> conn{};
  81565. conn.template connect<&release<Candidate, Type *>>(value_or_instance);
  81566. return {conn, signal};
  81567. }
  81568. /**
  81569. * @brief Disconnects a free function or an unbound member from a signal.
  81570. * @tparam Candidate Function or member to disconnect from the signal.
  81571. */
  81572. template<auto Candidate>
  81573. void disconnect() {
  81574. delegate_type call{};
  81575. call.template connect<Candidate>();
  81576. disconnect_if([&call](const auto &elem) { return elem == call; });
  81577. }
  81578. /**
  81579. * @brief Disconnects a free function with payload or a bound member from a
  81580. * signal.
  81581. *
  81582. * The signal isn't responsible for the connected object or the payload.
  81583. * Users must always guarantee that the lifetime of the instance overcomes
  81584. * the one of the signal.<br/>
  81585. * When used to connect a free function with payload, its signature must be
  81586. * such that the instance is the first argument before the ones used to
  81587. * define the signal itself.
  81588. *
  81589. * @tparam Candidate Function or member to disconnect from the signal.
  81590. * @tparam Type Type of class or type of payload, if any.
  81591. * @param value_or_instance A valid reference that fits the purpose.
  81592. */
  81593. template<auto Candidate, typename Type>
  81594. void disconnect(Type &value_or_instance) {
  81595. delegate_type call{};
  81596. call.template connect<Candidate>(value_or_instance);
  81597. disconnect_if([&call](const auto &elem) { return elem == call; });
  81598. }
  81599. /**
  81600. * @brief Disconnects a free function with payload or a bound member from a
  81601. * signal.
  81602. *
  81603. * @sa disconnect(Type &)
  81604. *
  81605. * @tparam Candidate Function or member to disconnect from the signal.
  81606. * @tparam Type Type of class or type of payload, if any.
  81607. * @param value_or_instance A valid pointer that fits the purpose.
  81608. */
  81609. template<auto Candidate, typename Type>
  81610. void disconnect(Type *value_or_instance) {
  81611. delegate_type call{};
  81612. call.template connect<Candidate>(value_or_instance);
  81613. disconnect_if([&call](const auto &elem) { return elem == call; });
  81614. }
  81615. /**
  81616. * @brief Disconnects free functions with payload or bound members from a
  81617. * signal.
  81618. * @param value_or_instance A valid object that fits the purpose.
  81619. */
  81620. void disconnect(const void *value_or_instance) {
  81621. ENTT_ASSERT(value_or_instance != nullptr, "Invalid value or instance");
  81622. disconnect_if([value_or_instance](const auto &elem) { return elem.data() == value_or_instance; });
  81623. }
  81624. /*! @brief Disconnects all the listeners from a signal. */
  81625. void disconnect() {
  81626. signal_or_assert().calls.clear();
  81627. }
  81628. /**
  81629. * @brief Returns true if a sink is correctly initialized, false otherwise.
  81630. * @return True if a sink is correctly initialized, false otherwise.
  81631. */
  81632. [[nodiscard]] explicit operator bool() const noexcept {
  81633. return signal != nullptr;
  81634. }
  81635. private:
  81636. signal_type *signal;
  81637. };
  81638. /**
  81639. * @brief Deduction guide.
  81640. *
  81641. * It allows to deduce the signal handler type of a sink directly from the
  81642. * signal it refers to.
  81643. *
  81644. * @tparam Ret Return type of a function type.
  81645. * @tparam Args Types of arguments of a function type.
  81646. * @tparam Allocator Type of allocator used to manage memory and elements.
  81647. */
  81648. template<typename Ret, typename... Args, typename Allocator>
  81649. sink(sigh<Ret(Args...), Allocator> &) -> sink<sigh<Ret(Args...), Allocator>>;
  81650. } // namespace entt
  81651. #endif
  81652. // IWYU pragma: end_exports